为何仅Firefox中点击模态框内嵌表单的select下拉会关闭模态框?
Firefox中Modal内Select下拉框触发弹窗关闭的问题及修复
问题详情
- 环境:Windows 10 + Firefox 119
- 现象:点击Modal对话框内的select下拉框时,弹窗会立即关闭,无法正常提交表单;Chrome、Edge浏览器无此问题
- 以下是简化后的复现代码:
原始HTML代码
<button id="launch-modal"> Open modal </button> <dialog id="modal" class="modal"> <div class="modal-content"> <form id="form"> <div class="word-phrase"> <label for="term" class="term">Word</label> <input id="term" type="text"> </div> <div> <label for="definition">Definition </label> <textarea id="definition" rows="5" cols="50"></textarea> </div> <div> <label for="language-select">Choose language</label> <select id="language-select" name="language-select"> <option value="en">English</option> <option value="fr">French</option> <option value="de">German</option> <option value="it">Italian</option> <option value="la">Latin</option> <option value="es">Spanish</option> <option value="und">Other</option> </select> </div> <div> <button>Submit</button> </div> </form> </div> </dialog>
原始CSS代码
/*Form */ form, form>div { display: flex; flex-direction: column; gap: 1rem; } /** Modal */ .modal { z-index: 50; padding: 4rem; margin: auto; border-radius: 0.2rem; border: 0; } .modal-content { display: flex; flex-direction: column; gap: 2rem; align-items: flex-end; } .modal::backdrop { background-color: rgba(9, 9, 70, 0.8); z-index: 40; cursor: pointer; }
原始JS代码
/** Form **/ const form = document.getElementById("form") form.addEventListener("submit", e => { e.preventDefault() e.target.reset() modal.close() }) /** Modal **/ const launchModalBtn = document.getElementById("launch-modal") const modal = document.getElementById("modal") launchModalBtn.addEventListener("click", () => { modal.showModal() }) /* modal backdrop */ modal.addEventListener("click", (e) => { const modalDimensions = modal.getBoundingClientRect() if ( e.clientX < modalDimensions.left || e.clientX > modalDimensions.right || e.clientY < modalDimensions.top || e.clientY > modalDimensions.bottom ) { form.reset() modal.close() } })
问题原因
Firefox中,select下拉菜单会被渲染在modal元素外部,导致点击下拉选项时,事件坐标落在modal边界外,触发了原本仅针对backdrop的关闭逻辑;而Chrome、Edge会将下拉菜单的点击事件正确归属为modal内部元素的事件。
修复方案
替换坐标判断逻辑,直接检查点击目标是否为modal元素本身(即点击了backdrop区域):
修复后的JS代码
/** Form **/ const form = document.getElementById("form") form.addEventListener("submit", e => { e.preventDefault() e.target.reset() modal.close() }) /** Modal **/ const launchModalBtn = document.getElementById("launch-modal") const modal = document.getElementById("modal") launchModalBtn.addEventListener("click", () => { modal.showModal() }) /* modal backdrop */ modal.addEventListener("click", (e) => { // 仅在点击modal本身(backdrop)时关闭弹窗 if (e.target === modal) { form.reset() modal.close() } })
此方案通过精准区分backdrop和内部元素的点击事件,彻底解决跨浏览器兼容性问题。
内容的提问来源于stack exchange,提问作者Naj
相关产品推荐
相关产品推荐

