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

这通常是因为 Unity 渲染上下文在 Tab 失去焦点时被暂停,或者 Canvas 元素未能及时重新获得输入焦点。对于混合开发场景来说,这种体验断裂非常影响可用性。
解决思路
核心在于确保每次切换到包含 Unity WebGL 的 Tab 时,强制让 Canvas 元素重新获取焦点,从而唤醒渲染循环。具体步骤如下:
- 监听 Tab 事件:利用 Layui 的
element模块监听 Tab 切换动作。 - 定位 Canvas:通过 DOM 操作找到当前激活 Tab 内 iframe 中的 Unity canvas 元素。
- 触发焦点:调用 JavaScript 的
focus()方法强制刷新渲染状态。
代码实现
下面是完整的处理逻辑,直接嵌入到你的 Layui 初始化脚本中即可。
layui.use(['element'], function() {
var element = layui.element;
// 监听 Tab 切换事件
// 注意:这里的 'xbs_tab' 需替换为你实际 Tab 组件的 name 属性值
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 获取焦点
}
});
});
关键点说明
- 模块加载:必须确保
element模块已正确加载,否则事件无法绑定。 - 选择器匹配:
$('.x-iframe')和#unity-canvas需要根据你实际的 HTML 结构调整。如果你的 iframe 没有 class 名,可能需要用 ID 或其他方式定位。 - 跨域限制:如果 iframe 是跨域的,
contents()可能会报错,此时需要确保同源策略允许访问内部 DOM。
优化建议
在实际项目中,有时会遇到切换后仍有短暂延迟的情况,可以尝试以下优化:
- 延迟执行:在切换事件回调中加入微小的延时(如
setTimeout),等待 iframe 完全加载后再执行 focus。 - 加载状态监听:给 iframe 绑定
load事件,确保内容就绪后再尝试获取焦点。
总结
通过监听 Layui 的 Tab 切换事件并主动调用 Canvas 的 focus() 方法,可以有效解决 Unity WebGL 在 Tab 切换时的黑屏问题。这种方法不依赖浏览器的 visibilitychange 事件,兼容性更好,适合多 Tab 布局下的混合开发场景。


