必须在 layui.open 的 success 回调中动态插入 loading,因 DOM 此时已挂载;禁用 layer.load() 叠加,避免遮罩错位、关闭不同步及移动端兼容问题;异步加载需手动发请求并确保 .always() 清理 loading;移动端需设 pointer-events: none 并保证父容器 position: relative。
直接在 layui.open 的 content 里无法直接放入 loading:此时弹出层仍在渲染,dom 尚未挂载,document.getelementbyid 无法找到目标节点。应依靠 success 回调——动画尚未开始、弹窗 dom 已经插入页面的这一刻才会触发;内容区域只能在此时安全操作。
常见错误是将 loading 直接写死在 content 字符串中,导致弹出层瞬间闪过,loading 根本来不及显示;还有人使用 setTimeout 延迟执行,但时间难以控制,网络较快时可能尚未加载便被隐藏。
success 回调取得弹窗 body 节点:$(this).find('.layui-layer-content') 或者原生 this.querySelector('.layui-layer-content')
<div class="layui-layer-loading"></div>(Layui 自带样式)layer.closeLoading() 或手动删除 loading 元素layer.load() 它属于独立浮层,z-index 默认低于 layer.open() 低,目标弹窗也不会与它绑定。遮罩错位、点击穿透和关闭不同步,都是两个浮层相互叠加后常见的问题——open 弹窗带 shadeClose: true时,load 会随遮罩点击而关闭,open 却继续存在,空白弹窗因此被留下。
兼容性问题更为棘手:Layui 2.8+ 调整了 layer.load() 调整过的 z-index 会让老项目在升级后突然失效;遮罩层在移动端 Safari 中还可能接收不到 touch 事件。
layer.load() 和 layer.open()
layer.msg('加载中...', {icon: 16, time: 0}) 并手动控制关闭,但要注意它不会遮罩当 content 为 URL(例如 content: ['xxx.html', 'get'])后,弹窗不会等待响应:Layui 自动请求的同时先呈现空弹窗,内容则在返回后填入。这时 success 回调取得的是空容器,必须先放入 loading,待 AJAX 完成后再删除。
关键是 Layui 没有开放内部请求状态,无法监听“加载完成”,所以只能自行接管请求。否则 loading 可能过早消失(内容仍未渲染),也可能因忘记清除而一直存在。
content 改为函数形式:content: function() { return '<div class="loading">...</div>'; }
success 回调中手动发起 AJAX,并使用 $.get() 或者 fetch,请求成功后使用 $(layero).find('.layui-layer-content').html(data) 进行替换.always() 或者 finally 中清理 loading,以免发生异常时残留loading 遮罩铺满弹窗内容区以后,外侧半透明部分在某些机型上无法点击,iOS 微信内置浏览器尤为常见 shade 区域无响应,原因并非 Layui bug,而在于 loading 元素采用了 position: absolute 却没有设置 pointer-events: none,从而阻止点击穿透至底层 shade。
另一个常见问题是自定义 loading 使用了 height: 100% 但父容器没有设置 position: relative,使遮罩高度塌陷,实际上未能覆盖全屏。
style="pointer-events: none;",保证 shade 可以点击position: relative
vh 用 vh 单位控制 loading 高度时,弹窗内的数值在 iOS Safari 中会被错误计算,需要换成 100% 或通过 JS 动态赋值