HTML表格数据按需过滤:JavaScript控制TR显隐
先聊几句表格按需过滤这个需求,看起来是个基础活儿,但不少人踩过的坑还真不少。核心无非是用JS控制的显示隐藏,但漏了声明、没处理空搜索恢复、不trim文本、或者只查第一列——这些小细节没到位,功能往往会失灵。 为什么必须显式声明? 浏览器会自动补全表格结构,但querySelectorAll('tr'
先聊几句表格按需过滤这个需求,看起来是个基础活儿,但不少人踩过的坑还真不少。核心无非是用JS控制 浏览器会自动补全表格结构,但 常见的错误是只查 用户清空输入框内容后,如果代码没重置 每次输入都重新读取DOM,500行表格、每行5个 最后说一个极易被忽略的点:的显示隐藏,但漏了 声明、没处理空搜索恢复、不trim文本、或者只查第一列——这些小细节没到位,功能往往会失灵。

为什么必须显式声明
?
querySelectorAll('tr')很容易把里的表头行也抓进来,当成普通数据行处理。更糟的是,在IE和旧版Safari里,如果HTML里没有,table.getElementsByTagName('tr')返回的顺序居然还不稳定。所以,务必手动包裹数据行:。过滤时,只操作... document.querySelectorAll('tbody tr'),就能干净地避开表头干扰。如果已经有个现成的表格结构,没写,用JS动态包一层也是个更稳妥的选择,比硬改HTML要省事。
filterTable() 函数里该遍历哪些 ?
tr.getElementsByTagName('td')[0]——用户搜“北京”,却找不到“地址:北京市朝阳区”这一行。多列过滤,不是简单加几列判断,而是要对当前行的所有逐个检查。
row.querySelectorAll('td')获取该行的全部单元格。td都要先调用textContent.trim(),否则前后空格会直接导致匹配失败。td匹配关键词,整行就保留;全都不匹配,才设为row.style.display = 'none'。innerText,这个属性受CSS visibility影响,在某些浏览器中还可能返回空字符串。空搜索时怎么恢复所有行?
display,那些隐藏的行就永远消失了。这算不上bug,但属于逻辑上的遗漏。
filterTable()开头加个判断:if (!filter.trim()) { rows.forEach(r => r.style.display = '') }。r.style.display = 'table-row'——如果原始HTML里某行的display是flex或其他值,这样硬设会覆盖原有样式。''最稳妥,浏览器会回退到默认的table-row,兼容性也最好。row.hidden = true,对应的恢复操作就是row.hidden = false,语义上更清晰。500行以上表格卡顿?缓存rowData是关键
,加起来就是2500次DOM访问。在手机上,掉帧会非常明显。
const rowData = Array.from(document.querySelectorAll('tbody tr')).map(tr => Array.from(tr.querySelectorAll('td')).map(td => td.textContent.trim()))。rowData这个数组,匹配结果后,再批量操作DOM。input事件监听与closest('tr')的使用
input事件监听比keyup更可靠——粘贴、自动填充、语音输入这些操作都不会漏掉;而用closest('tr')比parentNode.parentNode更健壮,尤其是当里嵌了 时。
