应使用 data-tab 关联 + hidden 属性控制标签页显隐;因 display: none 不暂停视频、不释放 iframe、不重置焦点,而 hidden 具备语义化暂停、上下文清理和无障碍支持。

直接用 data-tab 关联 + hidden 属性控制显隐,是最轻量、最稳妥的方案。别碰 display: none,它不暂停视频、不释放 iframe、不重置表单焦点,看似简单,实则埋雷。
为什么不能只用 display: none 切换标签页
很多人写完 JS 一跑通就收工,结果在 Safari 里 还在后台缓冲, 仍在加载第三方脚本,用户切走再切回, 焦点没了、滚动位置归零、定时器断了——这不是 bug,是 display: none 的设计行为。
-
hidden是语义化属性:浏览器会主动暂停媒体、丢弃 iframe 上下文、忽略 tab 键导航 - 它天然支持 CSS 选择器
[hidden],样式可统一控制 - 无障碍支持开箱即用:屏幕阅读器自动跳过
hidden元素,无需手动设aria-hidden="true"
data-tab 和 id 怎么配才不冲突
别用 getElementById() 直接查,ID 必须全局唯一,但组件可能复用多次;改用 data-tab 做映射,解耦更干净。
- 按钮写
- 对应面板写 ...>(注意前缀一致)
- JS 中用
document.querySelector(`#panel-${tab}`)查找,比拼 ID 字符串更安全- 首次加载时必须手动移除默认面板的
hidden,否则首屏白屏键盘导航和无障碍怎么补全
纯鼠标点击的标签页,在键盘用户或屏幕阅读器下等于不可用。必须补三样东西:
- 外层容器加
role="tablist" - 每个按钮加
role="tab"、tabindex="0",激活项设tabindex="-1" - 每个面板加
role="tabpanel",并用aria-labelledby="btn-home"指向对应按钮的id - 监听
keydown,对ArrowLeft/ArrowRight实现方向键切换
框架里用
v-if或{show &&就错了} Vue 的
v-if、React 的条件渲染,本质是销毁/重建组件实例。表单输入清空、useEffect重跑、Canvas 动画中断——这些不是性能问题,是状态丢失。- 框架中应改用
v-show(Vue)或style={{ display: show ? 'block' : 'none' }}(React),等价于hidden的语义 - 更推荐封装成自定义 Hook / Composable,把
hidden切换逻辑抽出来,避免重复判断 - 如果内容含 Web Components 或第三方库初始化逻辑,务必检查其是否支持“隐藏后恢复”
真正难的不是让标签页动起来,而是让 iframe 不偷跑、让表单不丢值、让键盘用户能按 Tab 进来、按方向键切换——这些细节不处理,功能就算“能用”,也算不上可用。
- JS 中用
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











