结论:设 shade: 0 且 shadeClose: false、closeBtn: 0,再于 success 中设 document.body.style.pointerEvents = 'none',end 中恢复,并拦截 Esc/Tab;因 shade: 0 会移除遮罩并自动解除底层锁定,必须手动补全禁用逻辑。
layer.open 怎么关掉遮罩层但保留禁用底层交互
直接说结论:shade 设为 0,同时必须加 shadeclose: false 和 closebtn: 0(可选),否则点空白处或按 esc 会意外关闭弹层。layui 的遮罩层和底层禁用是绑定的,不是两个独立开关——关了遮罩,底层默认就可操作;想“没遮罩但底层仍锁住”,得靠 css 遮罩层视觉隐藏 + js 行为拦截。
为什么 shade: 0 不够用
很多人试过 shade: 0,发现底部能点了,以为失效。其实这是预期行为:shade: 0 不仅隐藏遮罩 DOM,还会移除 layui-layer-shade 元素,并自动解除 body 的 overflow: hidden 锁定和 pointer-events: none 禁用。所以必须手动补上底层锁定逻辑:
-
shade: 0是前提,否则遮罩层 DOM 还在,透明度为 0 也占位、挡事件 - 用
success回调给body加style="pointer-events: none" - 弹层关闭时,记得在
end回调里恢复body.style.pointer-events = "" - 别忘了键盘焦点:按 Tab 或 Esc 仍可能激活底层元素,需监听
keydown拦截
完整可运行配置示例
以下是最小可靠写法,兼容 Layui 2.8+:
layer.open({
type: 1,
content: '<div>我是无遮罩但底层锁死的弹层</div>',
shade: 0,
shadeClose: false,
closeBtn: 0,
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() {
document.body.style.pointerEvents = '';
}
});
容易被忽略的坑
真实项目里这几个点经常翻车:
-
pointer-events: none在 iOS Safari 下对<input>和<select></select>失效,需额外加touchstart阻止 - 如果页面本身有
position: fixed的导航栏或弹窗,body锁定后它们可能仍可交互,得单独处理这些元素 - Layui 弹层关闭动画期间(约 200ms),
end回调还没触发,此时用户快速点击底层,可能抢到事件——建议加个setTimeout延迟恢复 - 多个弹层嵌套时,只锁一层
body不够,得计数管理锁定状态
真正难的不是关遮罩,而是让“看不见的锁”在各种设备、各种交互路径下都稳住。别信一次配置走天下。










