最直接方案是用 display 切换,但需先遍历隐藏所有面板再显示目标;hidden 属性更优,可暂停媒体资源并提升无障碍支持;:target 和 radio+checked 是纯 CSS 替代方案,需配合 ARIA 与键盘导航实现合规标签页。

用 display 切换最直接,但必须先清空再显目标
点击标签后只让对应内容区可见,其余全隐藏——这是核心逻辑。常见错误是只设 targetEl.style.display = "block",却没遍历所有面板统一设为 "none",结果多个内容同时显示,或全空白(尤其首次加载时)。
实操建议:
- 所有内容区初始加
style="display: none;"或统一 class 如.tab-pane { display: none; } - 每个按钮加
data-tab属性,如 - JS 中先执行
document.querySelectorAll('.tab-pane').forEach(p => p.style.display = 'none'),再查document.getElementById('panel-' + tab)并设display = 'block' - 务必检查
tab值是否存在、对应元素是否找到,否则会报Cannot set property 'display' of null
用 hidden 属性比 display: none 更稳妥
hidden 不只是视觉隐藏:它会暂停内部 、、 的运行,自动处理焦点和可访问性状态,语义也更准确。而 display: none 只是脱离渲染流,资源可能仍在后台加载(Safari 下 就常继续缓冲)。
实操建议:
- 内容区用
hidden属性初始化,如- 默认面板首次加载时,必须手动移除
hidden,否则白屏- 切换逻辑只需两步:
document.querySelectorAll('[role="tabpanel"]').forEach(p => p.hidden = true),再设目标p.hidden = false- 不支持 IE,需降级:CSS 中补
[hidden] { display: none !important; }纯 CSS 方案选
:target还是radio + :checked?:target适合静态文档页,URL 锚点可分享;radio + :checked能做动画、有默认选中、结构可控,但无法键盘空格切换,也不支持 URL 同步。实操建议:
- 用
:target:内容区加id,CSS 写.tab-content { display: none; } .tab-content:target { display: block; },首屏靠.tab-content:first-of-type { display: block; } - 用
radio:所有必须同名;label必须正确绑定(for或包裹);内容区用~兄弟选择器定位,如#tab1:checked ~ #content1 { display: block; } - 两者都需注意:内容区初始必须统一设
display: none,否则首屏闪出多个
别漏掉 ARIA 和键盘导航支持
仅靠视觉切换的标签页对屏幕阅读器用户基本不可用。Tab 键进不去、方向键切不了、焦点丢失、滚动归零——这些不是边缘问题,是合规硬要求。
实操建议:
- 外层容器加
role="tablist",每个按钮加role="tab"、tabindex="0"(当前激活项设tabindex="-1") - 内容区加
role="tabpanel",并用aria-labelledby指向对应按钮的id - 监听
keydown,对ArrowLeft/ArrowRight实现横向切换 - 含
的面板切走后,再切回需手动恢复焦点和滚动位置
切换逻辑本身很简单,真正复杂的是状态同步、资源控制和无障碍细节。多数人卡在“为什么点完没反应”或“切回去输入框空了”,问题往往不在 JS 写错,而在
hidden没初始化、tabindex没更新、或video在后台偷偷加载。 - 默认面板首次加载时,必须手动移除
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











