要关掉遮罩但锁住底层点击,需设 shade: 0、shadeClose: false,并在 success 中执行 document.body.style.pointerEvents = 'none',end 中恢复;因 shade: 0 会彻底移除遮罩并解除 body 锁定,故必须手动干预 pointer-events。

layer.msg 怎么关掉遮罩但锁住底层点击
直接结论:shade: 0 不够,必须配合 shadeClose: false、success 中手动禁用 document.body.style.pointerEvents,以及 end 中恢复——否则点背景照样能触发按钮、输入框等交互。
为什么 shade: 0 后底层还能点
Layui 的 shade: 0 不是“透明遮罩”,而是彻底移除遮罩 DOM 元素,并自动解除对 body 的锁定(包括 overflow: hidden 和 pointer-events: none)。所以它本质是「无遮罩 + 底层自由」,和你要的「无遮罩 + 底层锁死」完全相反。
-
shade: false或shade: 0效果一致,都会删掉.layui-layer-shade节点 - 不加额外控制时,Tab 切换焦点、Esc 关闭、鼠标点击 input/select 都会穿透生效
- iOS Safari 下
pointer-events: none对原生<select>和软键盘唤起的<input>失效,需补touchstart阻止
layer.msg 实际可用的最小配置
以下写法在 Layui 2.8+ 经实测可靠,适用于 layer.msg 场景(注意:msg 默认 type 是 0,不支持 success 回调,得改用 layer.open 模拟):
layer.open({
type: 0,
content: '操作已提交',
shade: 0,
shadeClose: false,
closeBtn: 0,
time: 2000,
anim: -1,
skin: 'msg',
success: function(layero) {
document.body.style.pointerEvents = 'none';
// 简单拦截 Esc 和 Tab
layero.onkeydown = function(e) {
if (e.key === 'Escape' || e.key === 'Tab') e.preventDefault();
};
},
end: function() {
// 动画结束才恢复,避免关闭过程中抢事件
setTimeout(() => {
document.body.style.pointerEvents = '';
}, 200);
}
});多个 msg 嵌套或页面有 fixed 元素时怎么处理
真实项目里,单靠锁 body 很容易翻车:
- 导航栏、toast、底部 tabbar 若是
position: fixed,它们不在body流内,pointer-events: none对它们无效,得单独加style="pointer-events: none" - 连续调用多次
layer.msg,可能前一个还没end,后一个又锁了一次body,导致最终只解一次锁——建议用计数器管理锁定状态 - 移动端快速连点,200ms 动画窗口期仍可能触发底层,可考虑加 class 锁屏(如
document.body.classList.add('layer-locked'))并配 CSSbody.layer-locked * { pointer-events: none !important; }
真正难的不是让遮罩消失,而是让那个“看不见的锁”在 iOS、Android、PC、多弹层、fixed 元素、键盘唤起等各种路径下都不漏风。别指望一套配置打天下。


















