不能直接用 hidden 控制预览层级切换,因其不支持过渡动画、强制移除元素导致状态丢失、且无法维持 dom 共存;应改用 data-active + css 类切换 + 显式状态同步。

直接用 hidden 属性管理多层预览内容不可靠——它不支持过渡、不能叠加控制、且切换时会强制退出渲染树,导致 DOM 重排和状态丢失。真正在预览切换中稳定控制多层可见性,得靠 data-active + CSS 类切换 + 显式状态同步。
为什么不能直接用 hidden 控制预览层级切换
hidden 是二值语义开关,不是视觉状态控制器。预览场景常见多个区块(如“草稿视图”“发布视图”“对比视图”)需共存、按需激活,而 hidden 强制移除元素于渲染树外,带来三个硬伤:
- 无法做淡入/滑动/高度过渡——
hidden不触发transition,设了opacity或max-height也无效 - 同一时刻只能有一个区块“存在”,其他全被剔除;若想保留 DOM 结构(比如维持表单输入值、滚动位置、Canvas 状态),
hidden会让这些全部重置 - JS 检查
el.hidden返回true时,el.offsetHeight立即为 0,但你可能正依赖这个值做尺寸计算或动画起始判断
用 data-active + classList.toggle() 替代 hidden 实现可预测切换
把“当前激活哪一层”这个状态从 DOM 属性解耦出来,统一由 data-active 标记,并用 CSS 类控制呈现。这样既保有语义可读性,又不牺牲控制力:
- CSS 中定义:
[data-active="draft"] .preview-draft, [data-active="live"] .preview-live { display: block; },其余默认display: none - 切换时只改容器的
dataset.active:root.dataset.active = 'live',无需遍历子元素设hidden - 所有预览区块始终在 DOM 中,
input值、scrollTop、canvas.getContext('2d')状态全保留 - 配合
transition: opacity 0.2s, transform 0.2s可轻松实现淡入+位移组合动效
必须手动同步 hidden 和 data-active 的少数场景
仅当需要向辅助技术明确声明“某预览块当前完全不适用”时,才在 JS 切换后补一句 el.hidden = !el.matches('[data-active]')。但要注意:
- 不能反过来:别用
el.hidden变化去驱动data-active,因为hidden触发不了transitionend,也监听不到中间状态 - 服务端渲染(SSR)中,若首屏已带
hidden,客户端 hydration 前必须确保[hidden] { display: none !important; }已加载,否则闪现 - 表单内含
<input hidden>的预览字段,提交时会被忽略——真要隐藏但参与提交,得用position: absolute; left: -9999px而非hidden
预览切换的本质是状态映射,不是显隐开关。hidden 只适合“这个东西现在不存在”的绝对语义,而预览层之间是“互斥但共存”的关系——这点一旦混淆,后续加动画、保状态、适配屏幕阅读器都会卡在同一个地方。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











