前端实时筛选适合≤1000行小数据,直接遍历DOM显隐元素最快;超量则需防抖(200ms)、统一事件监听、dataset取值、数值转换比较、语义化结构。

前端实时筛选适合小数据量(≤1000 行)
直接用 JavaScript 遍历 DOM 并显隐 关键实操点: 只要数据来自 API、需分页、含权限控制或关联查询,就必须把筛选逻辑交给后端。前端只负责收集、校验、拼参并发起请求,别在浏览器里硬扛全量数据。 常见错误现象: 推荐做法: 不能对同一数据集反复 正确结构是:遍历每一项时,为每个非空条件单独计算布尔值,最后用 用户敲字是连续行为, 简单防抖实现(无依赖): 容易被忽略的细节:
实际项目里最常被绕开的是「结构语义化」——不用 或 input 事件每触发一次就全量遍历,CPU 和重排压力都会上升。
input 或 change 事件,共用一个 filterTable() 回调,避免多次遍历或状态覆盖true(即“不限制”),空值不参与逻辑判断,防止漏行 —— 错误写法:if (name && dept) { ... };正确写法:const matchName = !nameVal || cellText.includes(nameVal); const matchDept = !deptVal || dataDept === deptVal; if (matchName && matchDept) { ... }
dataset 属性(如 data-category)而非 textContent,避免因格式空格、HTML 标签或富文本干扰匹配parseFloat() 或 parseInt() 转换再比较,字符串比较 '200' 会返回
true后端驱动筛选才是真实业务的标配
document.querySelectorAll('[name]') 手动遍历表单字段 —— 一旦加了动态渲染的筛选项(比如异步加载的部门下拉),name 漏写或大小写不一致,整个参数就丢name="brand[]" 当通用写法 —— 这是 PHP 特有语法,FormData 不识别方括号,后端收不到数组encodeURIComponent —— 容易漏转义、出错,应直接用 URLSearchParams 或 new FormData(form)
里,name 严格对齐后端接收字段名(如 price_min、status)const params = Object.fromEntries(new FormData(form).entries()) 一键提取干净键值对,空值自动被忽略fetch(`/api/items?${new URLSearchParams(params)}`),安全、简洁、可书签多条件“与”逻辑必须单次合并判断
.filter(),也不能嵌套 if (a) { if (b) { if (c) { ... } } }。前者性能差、中间数组浪费内存;后者容易漏掉组合分支,比如某条件为空时逻辑跳过,导致本该显示的行被隐藏。&& 合并:const rows = Array.from(document.querySelectorAll('#my-table tbody tr'));
rows.forEach(row => {
const nameMatch = !nameVal || row.cells[0].textContent?.trim().toLowerCase().includes(nameVal.toLowerCase());
const deptMatch = !deptVal || row.cells[1].dataset.dept === deptVal;
const priceMatch = !priceVal || parseFloat(row.cells[2].dataset.price)
<p>注意点:</p>
Array.from() 把 NodeList 转成数组,避免边遍历边修改 DOM 引发索引错乱dataset 值天然小写,data-price-max 对应 row.dataset.pricemax,命名时避开驼峰和连字符歧义trim().toLowerCase(),避免大小写或首尾空格导致失败防抖不是可选项,是必选项
input 事件在中文输入法下还会高频触发(比如拼音选词过程)。不加防抖,每按一个键就执行一次全量过滤,移动端尤其卡顿,还可能触发竞态:后一次过滤还没完,前一次的 DOM 修改就被覆盖。let filterTimer;
function onFilterChange() {
clearTimeout(filterTimer);
filterTimer = setTimeout(() => {
// 这里放真正的过滤逻辑
filterTable();
}, 200);
}
document.getElementById('filter-name').addEventListener('input', onFilterChange);
document.getElementById('filter-dept').addEventListener('change', onFilterChange);
clearTimeout(filterTimer),否则可能执行旧回调、乱起 name、靠 class 或 innerText 匹配,短期能跑,后期加个分页、同步 URL 参数或对接新后端字段,就得重写一半 JS。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











