纯HTML可构建高效数据过滤系统,关键在于结构设计:用details/summary实现可访问筛选区,checkbox name/value严格映射data属性,CSS :checked + ~ 同级选择器驱动显隐,表格数据预存JS数组避免DOM遍历。

纯 HTML 能构建出高效的数据过滤系统,但必须绕开“用 JS 控显隐”这个思维惯性——真正高效的起点是结构设计,不是逻辑补丁。
details + summary 做筛选区,别碰 display: none
很多人一上来就写 div 配 onclick 切 class,结果要维护 open 状态、防重复触发、还要手动加 ARIA。其实 details 原生支持折叠/展开、键盘可访问、自带 open 属性控制初始状态。
- 每个筛选维度(如“语言”“状态”)单独包进一个
details,summary作标题 -
summary里可以放<small>显示已选数量,但计数逻辑可交由 JS 单独处理,不影响过滤主干 - 绝对不要给
details设display: none—— 这会让它彻底退出可访问性树,屏幕阅读器读不到
checkbox 的 name/value 必须能批量映射 data 属性
过滤靠的是 DOM 节点自动响应勾选状态,所以 value 不是随便起的字符串,而是直接对应目标元素的 data-* 值。
- 错误写法:
value="Python"匹配data-language="python"→ 大小写不一致,过滤失效 - 错误写法:
name="lang"和name="language"混用 → 后续 CSS 选择器无法统一读取 - 推荐写法:
<input type="checkbox" name="filter-language" value="javascript">,对应数据节点<div data-language="javascript">
CSS :checked + ~ 实现无 JS 过滤,但结构必须严格对齐
CSS 无法跨父级选择,所以 checkbox 和待过滤项必须处于同一父容器内,且 checkbox 在前、内容在后,才能用兄弟选择器驱动显隐。
立即学习“前端免费学习笔记(深入)”;
- 所有
input[type="checkbox"]放在最外层容器顶部(比如<main>开头),后面紧跟所有.item - 错误规则:
input[name="filter-language"]:checked ~ [data-language="python"]→~只匹配后续同级元素,不能嵌套匹配 - 正确写法示例:
input[value="python"]:checked ~ .item:not([data-language="python"]) { display: none; },前提是所有.item是input的同级后续元素 - 如果结构不允许同级(比如卡片嵌套深),就改用
hidden属性 + CSS 控制,比display: none更安全
表格过滤优先存 JS 数组,别遍历 DOM 提取文本
把原始数据存在 JS 变量里,而不是靠 tr[i].getElementsByTagName("td")[0] 实时扒 DOM,这是性能分水岭。
- DOM 查询慢,且容易被空格、换行、隐藏列干扰;建议初始化时就把表格数据转成数组:
tableData = [{name: "张三", dept: "前端"}, ...] - 搜索时只操作这个数组,渲染用模板字符串或
innerHTML一次性写入,别逐行appendChild - 搜索字段做成配置项,如
searchFields = ["name", "dept"],方便扩展 - 空值必须提前判断,否则
row[field].toLowerCase()会报错;无结果时插入带colspan的提示行,别清空tbody
最常被忽略的不是怎么写 filter,而是数据源与视图的同步时机:过滤后若没更新导出按钮的数据源,用户点导出就会拿到全部原始数据,而不是当前筛选结果。



















