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

这通常是因为 Tab 切换导致 WebGL 上下文失去焦点或暂停了渲染循环。要解决这个问题,核心思路是在 Tab 激活时强制让 Unity 的 Canvas 元素重新获得焦点。
解决方案
监听 Tab 切换事件
Layui 的 element 模块提供了 tab 事件,我们可以利用它来捕获 Tab 切换动作。当切换发生时,我们需要识别当前激活的是哪个 Tab,并找到其中包含 Unity 内容的 iframe。
强制获取焦点
一旦定位到目标 iframe,通过 jQuery 访问其内部 DOM,找到 Unity 生成的 canvas 元素(通常是 #unity-canvas),然后调用 focus() 方法。这一步能唤醒被挂起的渲染器。
代码实现
layui.use(['element'], function() {
var element = layui.element;
// 监听 Tab 切换事件
element.on('tab(xbs_tab)', function(data) {
// 获取当前选中的 tab 对应的 iframe
var activeTabId = data.index;
var iframe = $('.x-iframe').eq(activeTabId);
// 获取 iframe 中的 Unity canvas 元素,若存在,则主动获取焦点
var unityCanvas = iframe.contents().find('#unity-canvas')[0];
if (unityCanvas) {
unityCanvas.focus(); // 强制 Unity canvas 获取焦点
}
});
});
注意事项
- 同源策略:上述代码依赖
iframe.contents(),要求 iframe 与父页面同源。如果是跨域 iframe,浏览器安全策略会阻止访问内部 DOM,此时需要配合 postMessage 通信由子页面主动触发刷新。 - 加载时机:如果 iframe 内容尚未完全加载,直接操作可能无效。可以在
iframe的load事件中做二次检查,或者在切换时增加微小的延时。
总结
通过监听 Layui 的 Tab 切换事件并在激活时强制调用 Canvas 的 focus 方法,可以有效解决 Unity WebGL 在 Tab 切换后的黑屏问题。这种方法不依赖浏览器的 visibilitychange 事件,逻辑简单且稳定,适合大多数混合开发场景。


