正确做法是用 document.querySelectorAll('tbody tr') 遍历并匹配 textContent(忽略大小写),监听 input 事件配合防抖,清空时重置 display,无结果时动态插入 colspan 匹配表头的提示行。

用 querySelectorAll 找到所有 tr 行再逐行匹配文本
核心思路是:不依赖后端,直接在 DOM 中遍历 tr 元素,检查其文本内容是否包含搜索关键词,然后控制 style.display 显示或隐藏。注意必须从 tbody 里取 tr,否则可能误操作表头(thead tr)或页脚(tfoot tr)。
常见错误是写成 document.querySelectorAll('tr') —— 这会把 thead 里的标题行也纳入过滤,一搜就“消失”,用户立刻懵了。
- 正确做法:
document.querySelectorAll('tbody tr') - 匹配时建议用
textContent.toLowerCase().includes(keyword.toLowerCase()),避免大小写敏感问题 - 别用
innerText,它受 CSS 影响(比如display: none的子元素内容可能被忽略) - 如果表格有合并单元格(
rowspan/colspan),不影响,textContent仍能读取全部可见文本
输入框实时监听要用 input 事件,不是 change
change 只在失焦时触发,用户打完字点别处才过滤,体验卡顿;input 是每敲一个键就触发,响应及时。但要注意防抖——否则快速连打会频繁重绘,尤其表格行数多时(比如 500+ 行)容易卡顿。
- 简单防抖可加个
setTimeout+clearTimeout,延迟 200ms 再执行过滤 - 别用
keyup,它捕获不到粘贴、语音输入等非键盘操作 - 清空搜索框时,要显式恢复所有
tr的display,不能只靠 CSS 类切换——因为之前可能被内联样式锁死
过滤后记得处理“无结果”状态,否则用户以为卡了
纯前端过滤不会自动显示“未找到”,得手动加提示行。最稳妥的方式是:先隐藏所有 tbody tr,再把匹配的显示出来,最后判断是否一个都没显示,如果是,就插入一个带 colspan 的提示 tr。
立即学习“前端免费学习笔记(深入)”;
- 插入提示行前,先检查是否存在旧的提示行:
document.querySelector('tbody tr.no-results'),有就remove() - 提示行的
colspan值必须等于表头th或第一行td的单元格数,硬编码易出错,建议用document.querySelector('thead th, thead td').length动态获取 - 别用
visibility: hidden或opacity: 0隐藏提示行——它们仍占布局空间,会导致空白错位
移动端输入法回车键可能不触发 input,需兼容 search 类型
部分安卓输入法在 type="text" 下按搜索键(放大镜图标)不会发 input 事件,但换成 type="search" 就可以,且原生支持清除按钮(X 图标),点击后自动清空并触发 input。
- HTML 中写:
<input type="search" id="filter-input"> - CSS 可用
input[type="search"]::-webkit-search-cancel-button自定义清除按钮样式(仅 WebKit) - iOS Safari 对
search类型支持良好,无需额外 polyfill - 如果必须用
text类型(比如设计规范限制),那就额外监听search事件:input.addEventListener('search', handleFilter)
colspan 计算逻辑,提示行就错位到看不见。



















