用 hidden 属性控制显隐最稳妥,它能暂停媒体、处理焦点和可访问性;现代浏览器均支持,ie需降级;须避免与 display: none 混用,防止语义冲突和辅助技术异常。

用 hidden 属性控制显隐最稳妥
直接操作 hidden 属性比改 style.display 更可靠——它不只是视觉隐藏,还会暂停内部 <video></video>、<audio></audio>、<iframe></iframe>,自动处理焦点和可访问性状态。现代浏览器(Chrome/Firefox/Safari/Edge)都支持,IE 不支持需降级。
实操要点:
- 所有面板初始加
hidden属性:<section id="panel-home" hidden>...</section> - 首次加载必须手动移除默认面板的
hidden,否则白屏:document.getElementById('panel-home').removeAttribute('hidden') - 切换时统一设
element.hidden = true,再对目标设false,避免多显或全空 - 别混用
hidden和display: none,语义冲突会导致屏幕阅读器行为异常
为什么不能只靠 display: none 切换?
display: none 会完全脱离渲染流,但它不暂停媒体播放、不重置焦点、不通知辅助技术。比如一个含自动轮播图的 tab 被切走,display: none 后轮播仍在后台运行;用户切回来再按 Tab 键,焦点可能卡在不可见区域。
常见错误现象:
- 切换后
<video></video>继续播放但画面黑屏 - 表单输入框失去焦点,回切时光标不在原位置
- 屏幕阅读器读到隐藏内容,或跳过本该读的活跃面板
- 移动端双击缩放失效(因元素被移出布局流)
补救方式:若必须用 display,得手动加 JS 暂停媒体、保存 scrollTop、重设 tabindex。
data-tab 映射比 ID 关联更安全
用按钮的 data-tab="settings" 和面板的 id="panel-settings" 硬绑定,容易因 ID 冲突或 DOM 顺序变动失效。推荐用 data-tab 双向映射,解耦结构与逻辑。
使用场景:
- 同一页面多个标签组共存(如侧边栏设置 + 主内容区导航)
- 动态生成面板(如从 API 渲染 tab),ID 不稳定
- 服务端渲染(SSR)需保证首屏 HTML 与客户端 JS 状态一致
示例逻辑:
const btn = event.target;
const tabId = btn.dataset.tab;
document.querySelectorAll('[data-tab]').forEach(el => el.hidden = true);
document.querySelector(`[data-tab="${tabId}"]`).hidden = false;
切换时防重复触发和空 target 报错
用户快速连点标签,或误点无 data-tab 的按钮,JS 容易执行到 document.getElementById(null) 或对 null 元素调 .hidden = false,报错 Cannot set property 'hidden' of null。
关键检查点:
- 点击前先校验
btn.dataset.tab是否存在且非空字符串 - 用
document.querySelector(`[data-tab="${tabId}"]`)替代getElementById,避免依赖 ID 命名规则 - 查不到目标面板时,不抛错,而是静默 fallback 到默认 tab(如第一个可用的)
- 加节流:监听
transitionend或用classList.toggle('is-transitioning', true)锁定状态
真正难的不是“怎么切”,而是“切完之后,视频有没有停、表单有没有丢、盲人用户能不能顺滑读下去”——这些细节没处理,hidden 也白加。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











