取消文件输入时dialog意外关闭,添加cancel事件阻止默认无效求助
解决Dialog中File Input导致的意外关闭问题
你遇到的问题是:包含file类型input的dialog弹窗,在用户取消文件选择或选择同一文件时会意外关闭,且监听dialog的cancel事件并调用e.preventDefault()无效。
问题原因
这个关闭行为并非由cancel事件触发(cancel事件通常由按下ESC键或点击dialog背景触发),而是文件选择器关闭后,浏览器的焦点交互逻辑导致dialog被意外触发关闭,此时cancel事件并未触发,所以你的监听代码不会生效。
解决方案
方案一:通过标志控制Dialog关闭权限
仅允许用户主动点击关闭按钮时关闭dialog,其他触发关闭的行为都被阻止:
<button id="openDialogButton">Open dialog</button> <dialog id="dialog"> <h1>Hi, I'm a dialog !</h1> <input type='file'> <p><button id="closeDialogButton">Close dialog</button></p> </dialog>
const buttonOpen = document.querySelector("#openDialogButton"); const buttonClose = document.querySelector("#closeDialogButton"); const dialog = document.querySelector("#dialog"); let allowClose = false; buttonOpen.addEventListener("click", () => { allowClose = false; dialog.showModal(); }); buttonClose.addEventListener("click", () => { allowClose = true; dialog.close(); }); dialog.addEventListener("close", (e) => { if (!allowClose) { e.preventDefault(); dialog.showModal(); } }); // 保留ESC键和背景点击的阻止逻辑 dialog.addEventListener("cancel", (e) => { e.preventDefault(); });
方案二:阻止File Input的默认交互行为
直接针对file input处理,阻止其触发导致dialog关闭的浏览器默认逻辑:
<button id="openDialogButton">Open dialog</button> <dialog id="dialog"> <h1>Hi, I'm a dialog !</h1> <input type='file'> <p><button id="closeDialogButton">Close dialog</button></p> </dialog>
const buttonOpen = document.querySelector("#openDialogButton"); const buttonClose = document.querySelector("#closeDialogButton"); const dialog = document.querySelector("#dialog"); const fileInput = document.querySelector('input[type="file"]'); buttonOpen.addEventListener("click", () => { dialog.showModal(); }); buttonClose.addEventListener("click", () => { dialog.close(); }); dialog.addEventListener("cancel", (e) => { e.preventDefault(); }); // 关键代码:阻止file input的mousedown默认行为,避免触发dialog意外关闭 fileInput.addEventListener('mousedown', (e) => { e.preventDefault(); fileInput.click(); });
方案二更轻量化,直接针对问题根源处理,推荐使用。
内容的提问来源于stack exchange,提问作者Catif
相关产品推荐
相关产品推荐

