必须在HTML的开头静态插入全屏loading遮罩,用top/left/right/bottom四边撑开并设z-index≥999999;移除时机须绑定layui.config({done:...})回调,确保Layui基础模块就绪后立即执行。
页面刚打开时就显示全屏 loading,必须在 HTML 顶部插入 DOM
靠 layui.use 或 layer.load() 都来不及——它们执行时页面早已渲染完毕,用户会看到白屏闪一下再转圈。真正有效的做法,是把遮罩写死在 html 最开头,纯静态、同步、不依赖任何 js 加载。
直接在 开头插入:
<div id="loading-mask" style="position:fixed;top:0;left:0;right:0;bottom:0;background:#fff;z-index:999999;display:flex;align-items:center;justify-content:center;"> <i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate"></i> </div>
- 必须用
top:0;left:0;right:0;bottom:0四边撑开,比width:100%;height:100%更可靠,能覆盖滚动区域 -
z-index至少设为999999,确保压过所有 layui 组件(table 默认 z-index 是 100,layer 默认约 1989) - 不要等
layui.css加载完再插——它可能还没解析,图标会 fallback 成方块;确保layui.css已提前引入在里
什么时候移除遮罩?用 layui.config({ done }),不是 $(document).ready
$(document).ready 太早,Layui 还没初始化;window.onload 又太晚,遮罩可能已卡住几秒。唯一安全的时机是 layui.config 的 done 回调——它在 Layui 基础模块(jQuery、layer 等)就绪后立即触发,且早于所有 layui.use。
在引入 layui.js 后立刻写:
layui.config({
done: function() {
var mask = document.getElementById('loading-mask');
if (mask) mask.remove();
}
});
- 别在
done里再调layui.use(['layer'], ...)去删遮罩——绕远路,还可能因异步导致时序错乱 - 如果用了
layui.extend或自定义模块,done仍会等全部注册完成才执行,放心用 - 确保这段代码紧跟在
layui.js的<script></script>标签后面,不要包在其他函数或延迟逻辑里
为什么不用 layer.load() 做首屏遮罩
layer.load(2) 看似方便,但它本质是动态生成的浮层:依赖 layer 模块加载完成、z-index 不够高、默认挂载位置不可控,移动端常被截断或错位。用户想“一打开就转圈”,结果只看到右上角一个小图标,或者遮罩一闪就消失。
-
layer.load()的 DOM 插入时机不可控,而首屏遮罩必须是静态、同步、高 z-index 的 - 它的遮罩层(shade)默认透明度 0.3、颜色 #000,无法铺满整个 viewport,尤其在 iOS Safari 中易出问题
- 若项目启用了 iframe 或局部滚动容器,
layer.load()更容易错位,且无法和页面生命周期对齐
移动端滚动时遮罩要拦截操作,别加 pointer-events: none
有人照搬“loading 遮罩要透传点击”的经验,给遮罩加 pointer-events: none,这是错的——首屏遮罩的目的就是阻断用户交互,防止误点空白页上的按钮或链接。
- 遮罩默认
pointer-events: auto,正好满足阻断需求,无需额外设置 - 真正要注意的是:遮罩父容器(比如
)不能有overflow: hidden或position: relative,否则在某些安卓 WebView 下会导致遮罩偏移 - 如果页面本身有 fixed 定位的导航栏或 footer,遮罩需确保
z-index高于它们,否则会被盖住
layui.js 执行前就存在,且移除逻辑必须绑定到 layui.config.done——这两个时间点稍有偏差,就会出现闪白屏或遮罩残留。细节看似简单,但顺序和时机才是关键。











