如何用原生Javascript对PHP生成的表格实现多搜索输入联合筛选
原代码问题根因
- 每次筛选仅读取当前触发输入事件的输入框值,未收集所有搜索框的筛选条件,导致多个输入框时后触发的筛选逻辑会直接覆盖前一个的判断,无法做多条件校验
- 未做关键词拆分逻辑,单个输入框输入多个空格分隔的关键词时,只会把所有输入内容作为一个完整字符串匹配,自然找不到对应结果
改造方案
第一步:调整HTML结构(可选,用于精准匹配字段避免误判)
给表格单元格加上对应字段标识,避免姓名等其他字段的内容命中筛选关键词:
<!-- 两个独立筛选框示例 --> <input type="text" class="search" data-table="staff-table" data-filter-field="dept" placeholder="筛选部门"> <input type="text" class="search" data-table="staff-table" data-filter-field="role" placeholder="筛选角色"> <!-- 单个筛选框示例(不需要上面两个框的话用这个即可) --> <!-- <input type="text" class="search" data-table="staff-table" placeholder="多个关键词用空格分隔"> --> <table class="staff-table"> <thead> <tr> <th>ID</th> <th>姓名</th> <th>部门</th> <th>角色</th> </tr> </thead> <tbody> <!-- PHP渲染行示例 --> <tr> <td>1</td> <td>张三</td> <td data-field="dept">marketing</td> <td data-field="role">team lead</td> </tr> </tbody> </table>
第二步:替换为改造后的JS代码
(function(document) { var filter = (function(qArr) { // 收集所有有效筛选条件 function _getAllFilters(tableClass) { var filters = []; var allInputs = document.getElementsByClassName('search'); qArr.forEach.call(allInputs, function(input) { // 只取绑定当前表格、且有输入内容的筛选框 if (input.getAttribute('data-table') === tableClass && input.value.trim()) { var field = input.getAttribute('data-filter-field'); // 按空格拆分多个关键词,过滤空值 var keywords = input.value.toLowerCase().trim().split(/\s+/).filter(k => k); filters.push({ field: field, keywords: keywords }); } }); return filters; } function _onInputSearch(e) { var targetInput = e.target; var tableClass = targetInput.getAttribute('data-table'); var dataTable = document.getElementsByClassName(tableClass); var allFilters = _getAllFilters(tableClass); qArr.forEach.call(dataTable, function(table) { qArr.forEach.call(table.tBodies, function(tbody) { qArr.forEach.call(tbody.rows, function(row) { var isMatch = true; // 遍历所有筛选条件,全部满足才显示 for (var i = 0; i < allFilters.length; i++) { var filter = allFilters[i]; var matchContent; if (filter.field) { // 精准匹配对应字段的内容 matchContent = row.querySelector(`[data-field="${filter.field}"]`).textContent.toLowerCase(); } else { // 没有指定字段则匹配整行内容 matchContent = row.textContent.toLowerCase(); } // 单个筛选框的多个关键词也要全部满足 var keywordMatch = filter.keywords.every(keyword => matchContent.indexOf(keyword) > -1); if (!keywordMatch) { isMatch = false; break; } } row.style.display = isMatch ? '' : 'none'; }); }); }); } return { init: function() { var inputs = document.getElementsByClassName('search'); qArr.forEach.call(inputs, function(input) { input.oninput = _onInputSearch; }); } }; })(Array.prototype); document.addEventListener('readystatechange', function() { if (document.readyState === 'complete') { filter.init(); } }); })(document);
适配说明
- 多输入框场景下,自动收集所有非空输入框的条件做AND判断,比如部门输入
marketing、角色输入team lead,只会返回同时满足两个条件的行 - 单个输入框场景下,输入多个空格分隔的关键词会自动做AND匹配,比如输入
marketing team lead就会返回同时命中两个关键词的行 - 如果不需要精准匹配字段,直接删掉单元格的
data-field属性和输入框的data-filter-field属性即可,默认按整行内容匹配
内容的提问来源于stack exchange,提问作者mathisfun1234
相关产品推荐
相关产品推荐

