真实多标签页预览应单页内模拟,用dom切换+iframe隔离渲染,每个标签对应一个iframe(src设为about:blank并write写入内容),配合data-tab-id控制激活态,切换时用visibility:hidden规避safari白屏问题,并通过sandbox="allow-scripts allow-same-origin"启用脚本执行,每次切换前replace('about:blank')清空上下文防内存泄漏。

用 window.open() 模拟多标签页预览,但别真开一堆窗口
直接调用 window.open() 多次会触发浏览器弹窗拦截,且每个新窗口都是独立上下文,无法共享编辑状态或实时同步。真实可行的“多标签页预览”,本质是单页面内模拟标签行为,靠 DOM 切换 + iframe 隔离渲染环境。
- 每个预览页对应一个
<iframe></iframe>,src设为about:blank或动态写入 HTML 字符串(用iframe.contentDocument.write()) - 标签栏用
<div> + <code>data-tab-id控制激活态,点击切换时仅显示对应iframe,其余display: none - 避免用
srcdoc属性在旧版 Safari(≤15.6)中不支持 script 执行的问题
iframe 内执行 JS 需绕过同源限制,但本地开发可启用 allow-same-origin
若 HTML 预览内容含内联 <script></script> 或需调用 console.log,iframe 默认沙箱策略会禁用脚本。必须显式设置 sandbox 属性:
<iframe sandbox="allow-scripts allow-same-origin"></iframe>
注意:allow-same-origin 仅在 iframe src 为 about:blank 或同域时生效;若用 data: URL 加载,该 flag 会被忽略 —— 所以坚持用 about:blank + write() 方式最可控。
切换标签时 iframe 不重载?得手动清理 document 避免内存泄漏
反复切换标签若只改 display,iframe 的 JS 上下文和事件监听器会持续驻留。尤其用户频繁修改代码再预览,旧 iframe 可能保留定时器、未解绑的 click 监听器,导致行为错乱。
- 每次切换前,先执行
iframe.contentWindow.location.replace('about:blank')强制清空 - 或更稳妥:销毁旧 iframe 节点,
document.createElement('iframe')新建一个 - 若需保留控制台输出,可在主页面用
postMessage拦截 iframe 内的console.*调用,统一输出到主页面开发者工具
移动端 Safari 标签切换卡顿?优先用 CSS visibility: hidden 替代 display: none
iOS Safari 对 display: none 的 iframe 有渲染优化 Bug:切回时 iframe 内容白屏或脚本不执行,尤其含 Canvas 或 Web Components 时。实测 visibility: hidden + position: absolute 定位可规避此问题,性能差异几乎不可感。
- 激活标签的 iframe 设
visibility: visible; z-index: 2 - 非激活的设
visibility: hidden; z-index: 1,并确保父容器overflow: hidden防止布局溢出 - 不要依赖
opacity: 0,它仍会触发重绘,且部分 SVG 渲染异常
srcdoc 行为、Android WebView 的 sandbox 兼容性、iframe 内 fetch 的 referrer 丢失——这些细节一旦漏掉,用户在某个设备上点一下就“预览消失”,很难排查。











