Esc键默认不触发cancel回调,需在success中手动绑定keyup事件并显式调用cancel函数,再执行layer.close(index),且须在end中解绑以避免内存泄漏。
ESC键默认不触发 cancel 回调
直接按 esc 关闭弹层时,cancel 回调不会自动执行——这是很多人踩坑的第一点。layui 的 cancel 只响应右上角关闭按钮或点击遮罩层(当 shadeclose: true 时),esc 是通过全局 keyup 监听后调用 layer.close(index) 实现的,它绕过了 cancel 的触发逻辑。
手动绑定 keyup 并显式调用 cancel
要让 Esc 行为和点击关闭按钮一致,必须在 success 回调里绑定事件,并在触发时手动调用 cancel 函数:
- 先保存传入的
cancel回调引用(因为layer.open参数中它可能是匿名函数) - 在
success中监听document的keyup,判断e.which === 27 - 调用
cancel(index, layero),再执行layer.close(index)(或由cancel内部决定是否关闭)
示例:
var userCancel = function(index, layero) {
console.log('用户取消操作');
// 这里可做清理、还原状态等
};
layer.open({
content: '确认删除?',
yes: function(index) { layer.close(index); },
cancel: userCancel,
success: function(layero, index) {
var $doc = $(document);
var escHandler = function(e) {
if (e.which === 27) {
userCancel(index, layero);
layer.close(index);
}
};
$doc.on('keyup.esc-' + index, escHandler);
// 注意:需在 end 回调里解绑,避免内存泄漏
},
end: function() {
$(document).off('keyup.esc-' + layer.index);
}
});
layer.closeAll() 会跳过所有回调
别用 $(document).keyup(function(e){ if(e.which===27) layer.closeAll(); }); 这种写法——它会直接销毁所有层,cancel、end 全部不执行,状态无法同步,数据可能残留。
-
layer.closeAll()是粗暴清空,适合页面级强制退出场景 - 单层 ESC 关闭必须精确到
index,才能走通生命周期 - 如果弹层是 iframe 类型,还要注意 iframe 内部焦点可能拦截
keyup,需在 iframe 加载完成后延迟绑定
多个弹层共存时的 index 管理
当页面可能同时打开多个 layer(比如嵌套弹窗、tab 页内独立弹层),layer.index 是全局递增的,不能直接用它代替当前层索引。
- 务必在
layer.open()返回值中捕获index,并透传到事件处理闭包中 - 不要依赖
layer.index,它只表示「最新创建的层」,不是「当前激活层」 - 若需支持多层 ESC 分层关闭,建议用
layer.getFrameIndex(name)配合自定义name参数管理
真正容易被忽略的是:Esc 关闭的语义是「放弃当前操作」,它应该和用户点击取消按钮的行为完全等价——包括回调执行顺序、状态还原时机、是否允许阻止关闭。这些都得靠手动对齐,Layui 不会帮你补全。











