← Dialog / Popover · 浮层与「关闭」的现代解法 / 关闭的学问:closedby 与 light dismiss 待审核 2 / 9
close · closedby / cancel

关闭的学问:closedby 与 light dismiss

「点对话框外侧的遮罩即关闭」——这个再常见不过的交互,从前要自己监听 ::backdrop 区域的点击(还得计算坐标判断是否点在内容上)。现在一个属性即可实现:<dialog closedby="…">。它有三个值,精确控制对话框能被哪些操作关闭

不写 closedby 时浏览器按默认(auto)处理:showModal() 打开 ≈ closerequest(仅 Esc 可关),show() 打开 ≈ none。下面选择一个值、打开对话框,逐一尝试「点遮罩」和「按 Esc」。

1 · close() vs requestClose():把 cancel 接进流程

Esc / 点遮罩 这类「用户想关」的动作,在真正关闭之前会先派发一个 cancel 事件。在其中调用 preventDefault() 即可拦下关闭——这正是「尚未保存,确定要关吗?」的实现点。而 dialog.close()强制关闭、经过 cancel;dialog.requestClose() 则是程序化地走一遍「用户请求关闭」流程(先发 cancel,没被拦才关)。

小结:closedby 管「谁能触发关闭」(遮罩/Esc/代码),cancel 事件管「关闭前能不能拦」。两者正交:即便 closedby="any" 让点遮罩可关,仍可用 cancel + preventDefault() 在脏状态下挽留用户。

延伸阅读:HTML dialog 元素 closedby 属性 · 张鑫旭——closedby="any|closerequest|none" 三个枚举值各自允许哪些关闭方式,以及「原生点遮罩关闭」的最简写法。