如何点击模态框外部关闭弹窗,同时支持方向键切换单选按钮?
点击
我需要实现点击模态框外部时关闭弹窗的功能,目前用以下代码能实现需求,但会破坏可访问性:用户用键盘上下方向键导航模态框内的单选按钮时,模态框会意外关闭。
现有实现代码:
const googleMissingInfoModal = document.getElementById('recommended-changes-modal'); googleMissingInfoModal.addEventListener('click', (e) => { const dialogDimensions = googleMissingInfoModal.getBoundingClientRect(); if (e.clientX < dialogDimensions.left || e.clientX > dialogDimensions.right || e.clientY < dialogDimensions.top || e.clientY > dialogDimensions.bottom) { googleMissingInfoModal.close(); } });
我试过其他点击外部关闭模态框的方案,但都无效。我的模态框结构如下:
<dialog id="recommended-changes-modal" class="google-validation-modal"> <span class="google-modal-close">×</span> <form method="dialog" class="modal-form"> <fieldset class="google-modal-fieldset"> <legend> <span class="google-modal-title">Confirm your address</span> Review the recommended changes </legend> <div class="modal-radio-container"> <input type="radio" id="user-entered-address" name="address" /> <label for="user-entered-address" class="modal-label">What you entered:</label> <div id="patient-address-content" class="modal-address"> <div id="user-address-street"></div> <div id="user-address-city-state-zip"></div> </div> </div> <div class="modal-radio-container"> <input type="radio" id="recommended-address" name="address" /> <label for="recommended-address" class="modal-label">Recommended:</label> <div id="google-address-content" class="modal-address"> <div id="google-address-street"></div> <div id="google-address-city-state-zip"></div> </div> </div> </fieldset> <div class="google-validation-messages"> <p class="red-text">Please select an address</p> </div> <div class="button-container"> <button type="button" id="confirm-address-button" class="confirm-address-button">Confirm</button> </div> </form> </dialog>
解决方案
你用的是原生<dialog>元素,直接通过判断点击事件的目标是否为dialog本身即可实现需求,同时完全保留键盘导航的可访问性:
const googleMissingInfoModal = document.getElementById('recommended-changes-modal'); googleMissingInfoModal.addEventListener('click', (e) => { // 仅当点击的是dialog遮罩区域(外部)时关闭 if (e.target === googleMissingInfoModal) { googleMissingInfoModal.close(); } });
方案说明
- 原生
<dialog>调用showModal()打开后,点击外部遮罩层时,事件的target就是<dialog>元素本身;点击内部任何内容时,target是对应的内部元素(比如表单、单选按钮、标签等)。 - 这个方案不会干扰键盘操作:方向键导航单选按钮不会触发
click事件,因此不会误关闭模态框,完美解决了可访问性问题。 - 相比通过坐标判断的方案,这种方式更可靠,也符合原生
<dialog>的设计逻辑。
内容的提问来源于stack exchange,提问作者dev_in_training
相关产品推荐
相关产品推荐

