如何扩展前端表格多筛选器的JavaScript逻辑?
多筛选器表格的可扩展筛选逻辑优化问题
我正在构建一个包含多个筛选器的表格,目前已实现两个可联动的筛选器,筛选值来自如下拉框所示的选择器(暂未加入“Org Type”筛选器):

以下是当前实现筛选的JavaScript代码:
function filterTable_all() { filter = [] // get filter 1 values and push to array var input = document.getElementById("KCPWinner"); var values = getSelectValues(input); filter.push(values.toString().toUpperCase().split(",")); // get filter 2 values and push to array var input = document.getElementById("yearFounded"); var values = getSelectValues(input); filter.push(values.toString().toUpperCase().split(",")); // get table var table = document.getElementById("mytableID"); var tr = table.getElementsByTagName("tr"); // loop through rows for filtering for (var i = 1; i < tr.length; i++) { for (var j = 0; j < filter.length; j++) { // if both filters are selected if (filter[0] != "" && filter[1] != "") { if (filter[0].includes(tr[i].children[5].textContent.toUpperCase().trim()) && filter[1].includes(tr[i].children[4].textContent.toUpperCase().trim())){ tr[i].style.display = "block"; } } // if one filter is selected else if (filter[0] != "" && filter[1] == "") { if (filter[0].includes(tr[i].children[5].textContent.toUpperCase().trim())){ tr[i].style.display = "block"; } } // if the other filter is selected else if (filter[0] == "" && filter[1] != "") { if (filter[1].includes(tr[i].children[4].textContent.toUpperCase().trim())) { tr[i].style.display = "block"; } } } } }
当前逻辑仅支持两个筛选器,但新增筛选器会让if语句数量指数级增长,无法良好扩展。请问如何优化该筛选逻辑以实现可扩展性?
触发filterTable_all()函数的select按钮(基于Django渲染):
<select class="submarket" style="" onchange='filterTable_all()' multiple name="yearFounded" id="yearFounded"> {% for year in filter_options.year_founded %} {% if year|toStr in liveFilters.year_founded %} <option class="submarketText checkedClass" value="{{ year }}" selected>{{ year }}</option> {% else %} <option class="submarketText" value="{{ year }}">{{ year }}</option> {% endif %} {% endfor %} </select>
注:所有筛选逻辑均为前端JavaScript实现
优化方案
核心思路是把每个筛选器的规则抽象成配置对象,让筛选逻辑通用化,新增筛选器只需要添加配置,不用修改核心判断代码。
1. 定义筛选规则配置
先创建一个数组,每个元素对应一个筛选器的配置,包含筛选器ID、对应表格列的索引,以及匹配规则(这里默认用包含匹配):
// 筛选规则配置,新增筛选器只需要往这里加条目 const filterConfigs = [ { filterId: "KCPWinner", columnIndex: 5, matchFn: (filterValues, cellValue) => filterValues.includes(cellValue) }, { filterId: "yearFounded", columnIndex: 4, matchFn: (filterValues, cellValue) => filterValues.includes(cellValue) }, // 新增Org Type筛选器时,直接加这一条 // { // filterId: "OrgType", // columnIndex: 2, // 替换成对应列的实际索引 // matchFn: (filterValues, cellValue) => filterValues.includes(cellValue) // } ];
2. 重构筛选函数
把原来的硬编码逻辑改成基于配置的通用逻辑,逻辑更清晰且易于扩展:
// 封装获取多选下拉框选中值的工具函数 function getSelectValues(select) { return Array.from(select.selectedOptions).map(option => option.value.trim()); } function filterTable_all() { // 1. 收集所有筛选器的选中值(空数组表示未筛选) const activeFilters = filterConfigs.map(config => { const selectElement = document.getElementById(config.filterId); const selectedValues = getSelectValues(selectElement); return selectedValues.length > 0 ? selectedValues.map(val => val.toUpperCase().trim()) : []; }); // 2. 获取表格行(跳过表头) const table = document.getElementById("mytableID"); const rows = table.querySelectorAll("tr:not(:first-child)"); // 3. 遍历每一行,判断是否符合所有筛选规则 rows.forEach(row => { let isMatch = true; // 逐个校验筛选规则 for (let i = 0; i < filterConfigs.length; i++) { const config = filterConfigs[i]; const filterValues = activeFilters[i]; const cellValue = row.children[config.columnIndex].textContent.toUpperCase().trim(); // 如果当前筛选器有选中值,且单元格值不满足匹配规则,标记为不匹配 if (filterValues.length > 0 && !config.matchFn(filterValues, cellValue)) { isMatch = false; break; // 只要有一个筛选不通过,直接跳出循环 } } // 根据匹配结果控制行的显示 row.style.display = isMatch ? "block" : "none"; }); }
3. 新增筛选器的操作
当需要添加新的筛选器(比如Org Type)时,只需要做两件事:
- 在
filterConfigs数组中添加对应的配置条目,指定筛选器ID和对应表格列索引; - 新增对应的
<select>元素(和现有yearFounded的Django渲染逻辑一致),确保ID和配置中的filterId完全匹配。
额外优化说明
- 修复了原代码中
filter变量未声明导致的全局变量问题; - 使用
querySelectorAll替代getElementsByTagName,返回静态集合,避免遍历过程中DOM变化引发的异常; - 匹配函数可自定义:如果需要精确匹配,只需调整
matchFn逻辑;如果需要范围匹配,也可以自定义判断规则; - 代码结构更清晰,后续维护和扩展成本极低。
内容的提问来源于stack exchange,提问作者Daniel Johnson
相关产品推荐
相关产品推荐

