Layui 集成 Unity WebGL 时 Tab 切换黑屏的解决方案
在 Web 应用中集成 Unity WebGL 内容时,如果将其嵌入 Layui 的 Tab 组件中,经常会遇到一个棘手的问题:切换 Tab 后,Unity 渲染区域直接变黑,只有点击该区域才能恢复显示。

这通常是因为 WebGL 上下文在 Tab 隐藏时被挂起,或者 Canvas 元素失去了焦点。要解决这个问题,核心思路是在 Layui 触发 Tab 切换事件时,强制让目标 Tab 内的 Unity Canvas 重新获取焦点。
核心实现逻辑
我们不需要复杂的轮询或浏览器事件监听,直接利用 Layui 提供的 tab 事件即可。关键在于找到当前激活 Tab 对应的 iframe,并访问其内部的 Canvas 元素调用 focus()。
代码实现
下面是一个完整的示例,展示了如何挂载监听器并处理焦点恢复。
layui.use(['element'], function() {
var element = layui.element;
// 监听 Tab 切换事件,注意这里的 'xbs_tab' 需替换为你实际的 Tab 模块名
element.on('tab(xbs_tab)', function(data) {
// 获取当前选中的 Tab 索引
var activeTabId = data.index;
// 根据索引定位到对应的 iframe 容器
// 假设你的 iframe 类名为 .x-iframe
var iframe = $('.x-iframe').eq(activeTabId);
// 尝试获取 iframe 内部的 Unity Canvas 元素
// 注意跨域限制,确保 iframe 同源或已配置 CORS
var unityCanvas = iframe.contents().find('#unity-canvas')[0];
if (unityCanvas) {
// 关键一步:强制获取焦点,唤醒渲染
unityCanvas.focus();
}
});
});
关键点解析
- 模块加载:确保
element模块被正确加载,这是 Layui 处理 Tab 交互的基础。 - 事件命名:
tab(xbs_tab)中的xbs_tab必须对应你 HTML 中lay-filter的值,否则监听不会生效。 - DOM 遍历:通过
iframe.contents()进入子文档查找 Canvas。这里依赖 iframe 已经加载完成,且没有跨域阻碍。 - 焦点恢复:
focus()是唤醒 WebGL 的关键。很多浏览器策略会在页面不可见时暂停 GPU 渲染,重新聚焦能触发重绘。
优化建议
如果在某些场景下切换后仍有延迟,可以尝试以下调整:
- 等待加载完成:不要立即执行
focus(),可以监听iframe的load事件,确保内部资源就绪。 - 增加微小延迟:偶尔需要给浏览器一点时间更新 DOM 状态,可以在回调中加入
setTimeout(..., 0)。 - 检查 ID 匹配:确认
#unity-canvas与你打包生成的 Unity WebGL 项目中的 Canvas ID 一致,默认通常是unity-canvas。
通过上述方案,基本可以覆盖绝大多数 Layui 与 Unity WebGL 结合时的黑屏问题。实际项目中保持代码简洁,优先保证焦点机制的正确性即可。

