除Esc关闭外 如何实现点击dialog外部区域关闭弹窗
原生dialog点击外部区域关闭实现方案
原生<dialog>元素默认自带Esc键关闭模态弹窗的能力,要额外增加点击外部关闭的效果,只需要给dialog绑定点击事件判断落点即可,不会影响原有默认行为。
核心逻辑
调用showModal()打开模态弹窗时,弹窗外部的遮罩是dialog自带的::backdrop伪元素,点击遮罩的事件会冒泡到dialog元素上。我们只需要判断点击位置是否落在弹窗内容区域范围外,满足条件时调用dialog的close()方法就能实现效果。
推荐实现(坐标判断法,无布局兼容问题)
在原有代码基础上,给dialog元素增加点击监听即可,完整代码如下:
<!DOCTYPE html> <html> <body> <p>点击按钮显示对话框。</p> <button onclick="myFunction()">显示对话框</button> <p><b>注意:</b> 可通过“Esc”键关闭模态弹窗,也可点击弹窗外部区域关闭。</p> <p><b>注意:</b> dialog元素仅支持Chrome 37+、Safari 6+和Opera 24+版本浏览器。</p> <dialog id="myDialog">这是一个对话框窗口</dialog> <script> const dialog = document.getElementById("myDialog"); // 点击外部关闭逻辑 dialog.addEventListener("click", (e) => { const dialogRect = dialog.getBoundingClientRect(); // 判断点击坐标是否超出弹窗内容区域 const clickOutSide = e.clientX < dialogRect.left || e.clientX > dialogRect.right || e.clientY < dialogRect.top || e.clientY > dialogRect.bottom; if (clickOutSide) { dialog.close(); } }) function myFunction() { dialog.showModal(); } </script> </body> </html>
简便写法(适合简单场景)
如果弹窗内部结构简单,没有元素会填满dialog整个内容区域,可以直接用事件目标判断,代码更短:
dialog.addEventListener("click", (e) => { if (e.target === dialog) { dialog.close(); } })
注意:如果dialog内部存在绝对定位、撑满整个dialog区域的子元素,点击这类子元素时可能出现判断失效,优先用坐标判断法更稳妥。
内容的提问来源于stack exchange,提问作者Rod
相关产品推荐
相关产品推荐

