data-category 是筛选按钮与内容联动的唯一可靠纽带,必须统一使用小写无空格无符号的值,通过 e.target.closest('[data-category]') 获取触发源,配合语义化 button、aria-pressed 状态、set 管理多选、display 切换防闪动、hash 同步及键盘导航支持。

data-category 是筛选按钮与内容联动的唯一可靠纽带
别用 class 或 id 做筛选标识——class="region-beijing" 会导致多选冲突,id="beijing" 强制唯一,无法支持“北京+上海”叠加筛选。所有按钮和对应内容块必须统一使用 data-category,值小写、无空格、无符号:data-category="beijing",而不是 data-category="Beijing" 或 data-category="beijing shanghai"。
点击事件监听必须用 e.target.closest('[data-category]') 获取触发源。否则点到按钮里的图标或文字时,e.target.dataset.category 会是 undefined,筛选直接失效。
按钮结构要语义化且无障碍友好
用 <button></button> 包裹标签文字,别用 <div onclick> 或 <code><a href="#"></a>。前者无键盘焦点,后者会触发页面跳转。
-
<ul class="tag-cloud"><li><button data-category="electronics">电子产品</button></li></ul>是推荐结构 - 每个按钮加
aria-pressed="false",选中时 JS 改为"true",屏幕阅读器能感知状态 - 多选场景下,用
Set管理当前激活的data-category值,避免反复操作classList触发重排
筛选逻辑执行时防闪动、保一致性
用户点一个新按钮,不能先显示再隐藏——视觉上会“闪一下”。正确做法是:筛选前先把所有内容块设为 display: none,再用 document.querySelectorAll('[data-category="beijing"]') 找到匹配项,逐个设回 display: block(或你实际用的布局方式)。
URL hash 同步不能靠浏览器自动:点击后得手动拼接 location.hash = '#filter=beijing,shanghai';页面加载时也要解析 hash 并反向激活对应按钮,否则刷新后筛选状态丢失。
大屏看板里按钮聚焦与键盘支持常被忽略
如果看板要支持键盘导航(比如运营人员用遥控器操作大屏),光有 data-category 不够。按钮必须可聚焦:
- 确保按钮不是
disabled,且没被tabindex="-1"锁死 - 监听
keydown,只响应Enter和(空格字符),空格触发时必须e.preventDefault(),否则页面会滚动 - 若按钮是多选开关,按空格应切换状态;若是单选,则需清空其他同组按钮的
aria-pressed
最易漏的一点:按钮本身没交互反馈样式。记得加 :focus-visible 和 [aria-pressed="true"] 的 CSS 规则,否则键盘用户根本看不出当前聚焦的是哪个筛选项。











