如何用JavaScript编写可复用的HTML表格多列内容过滤函数
可复用HTML表格内容过滤函数实现方案
原代码问题定位
你写的代码仅第二列生效的核心原因是内层循环逻辑错误:遍历当前行所有单元格时,每一个单元格的匹配结果都会直接覆盖整行的显示状态,前面列的匹配结果会被后面列的结果覆盖,最终只有最后一列的判断生效。如果后续新增第三列,就会变成只有第三列的过滤生效。
最优可复用实现
下面的函数适配任意列数的表格,支持自定义绑定输入框和表格、可选指定仅搜索指定列、输入防抖优化,不需要写死DOM ID,可直接复用到项目的所有表格场景:
/** * 表格内容过滤函数 * @param {string} inputSelector 搜索输入框的选择器 * @param {string} tableSelector 要过滤的表格选择器 * @param {object} options 配置项 * @param {number[]} options.searchColumns 可选,指定要搜索的列下标(从0开始),默认全列搜索 * @param {boolean} options.ignoreHeader 可选,是否忽略表头行,默认true * @param {number} options.debounceTime 可选,输入防抖间隔(毫秒),默认300 */ function tableFilter(inputSelector, tableSelector, options = {}) { // 合并默认配置 const config = Object.assign({ searchColumns: null, ignoreHeader: true, debounceTime: 300 }, options); const input = document.querySelector(inputSelector); const table = document.querySelector(tableSelector); if (!input || !table) return; let trList = Array.from(table.getElementsByTagName('tr')); // 忽略表头行 if (config.ignoreHeader) { trList = trList.slice(1); } // 输入防抖处理,避免频繁触发过滤 let timer = null; input.addEventListener('input', function() { clearTimeout(timer); timer = setTimeout(() => { const filter = this.value.trim().toUpperCase(); trList.forEach(tr => { const tdList = Array.from(tr.getElementsByTagName('td')); let isMatch = false; // 遍历指定搜索列,无指定则遍历全部列 const columns = config.searchColumns || tdList.map((_, idx) => idx); for (const colIdx of columns) { if (!tdList[colIdx]) continue; const txt = (tdList[colIdx].textContent || tdList[colIdx].innerText || '').toUpperCase(); if (txt.includes(filter)) { isMatch = true; break; // 只要有一列匹配就直接跳出循环 } } tr.style.display = isMatch ? '' : 'none'; }); }, config.debounceTime); }); } // 初始化当前表格过滤,直接调用即可 tableFilter('#myInput', '#myTable'); // 如果后续只想搜索指定列,比如仅搜索第0列(名称列)可这么写: // tableFilter('#myInput', '#myTable', {searchColumns: [0]});
配套代码调整
HTML代码
不需要再给输入框绑定onkeyup事件,修改后如下:
<input type="text" id="myInput" placeholder="搜索名称或国家.." title="输入搜索内容"> <table id="myTable"> <tr class="header"> <th style="width:60%;">名称</th> <th style="width:40%;">国家</th> </tr> <tr> <td>Alfreds Futterkiste</td> <td>德国</td> </tr> <tr> <td>Berglunds snabbkop</td> <td>瑞典</td> </tr> <tr> <td>Island Trading</td> <td>英国</td> </tr> <tr> <td>Koniglich Essen</td> <td>德国</td> </tr> <tr> <td>Laughing Bacchus Winecellars</td> <td>加拿大</td> </tr> <tr> <td>Magazzini Alimentari Riuniti</td> <td>意大利</td> </tr> <tr> <td>North/South</td> <td>英国</td> </tr> <tr> <td>Paris specialites</td> <td>法国</td> </tr> </table>
CSS代码
原有CSS无需修改,保留即可:
* { box-sizing: border-box; } #myInput { background-image: url('/css/searchicon.png'); background-position: 10px 10px; background-repeat: no-repeat; width: 100%; font-size: 16px; padding: 12px 20px 12px 40px; border: 1px solid #ddd; margin-bottom: 12px; } #myTable { border-collapse: collapse; width: 100%; border: 1px solid #ddd; font-size: 18px; } #myTable th, #myTable td { text-align: left; padding: 12px; } #myTable tr { border-bottom: 1px solid #ddd; } #myTable tr.header, #myTable tr:hover { background-color: #f1f1f1; }
复用方式
如果后续有其他表格需要加过滤功能,只需要新增对应输入框和表格的ID,再调用一次tableFilter函数传入对应选择器即可,不需要重复写逻辑。
内容的提问来源于stack exchange,提问作者JAVA_CAT
相关产品推荐
相关产品推荐

