按下Esc关闭confirm对话框后页面文本框无法输入的问题修复咨询
修复Chrome/Edge(Chromium)中Esc关闭confirm弹窗后无法输入的问题
我之前也踩过这个Chromium内核浏览器的坑!当用Esc键关闭原生confirm弹窗后,页面里的文本输入框居然没法唤起光标、输入内容,折腾了好一会儿才搞明白原因,下面给你详细拆解和解决办法:
问题复现
先贴一下能快速复现问题的代码:
<html> <head></head> <body> <input type="text"> <script> window.confirm('hogehoge') </script> </body> </html>
复现步骤:
- 打开这个HTML文件,页面会弹出
confirm对话框 - 按下Esc键关闭对话框
- 点击文本输入框尝试输入,会发现完全没反应,连光标都出不来
补充说明:这个问题只在Chrome/Edge(Chromium内核)+ Windows 10环境下出现,FireFox里完全正常;而且只要把浏览器窗口切出去再切回来,问题就会自动消失——这也侧面说明是焦点状态出了问题。
问题根源
这其实是Chromium内核的一个小bug:当用Esc键关闭原生confirm弹窗时,浏览器没有正确把页面的焦点状态恢复正常,导致页面元素没法响应焦点请求,自然也就没法输入内容了。
可行的修复方案
这里给你三种不同的解决思路,按需选择:
方案1:简单粗暴重置页面焦点
在confirm执行完之后,用setTimeout延迟一小会儿,手动让页面的body元素获取焦点,强制把异常的焦点状态拉回来:
<html> <head></head> <body> <input type="text"> <script> window.confirm('hogehoge'); // 延迟10ms执行,确保弹窗完全关闭后再操作 setTimeout(() => { document.body.focus(); }, 10); </script> </body> </html>
这个方案最简单,不需要改太多代码,基本能解决问题。
方案2:直接让目标输入框获取焦点
如果页面有明确需要用户输入的输入框,可以直接在confirm之后让这个输入框获取焦点,同样加一点延迟确保弹窗已经关闭:
<html> <head></head> <body> <input type="text" id="inputBox"> <script> window.confirm('hogehoge'); setTimeout(() => { document.getElementById('inputBox').focus(); }, 10); </script> </body> </html>
这个方案更精准,用户关闭弹窗后直接就能输入,体验更好。
方案3:用自定义弹窗替代原生confirm
如果想要彻底避免这类原生API的坑,最稳妥的方式就是自己写一个模态弹窗(或者用UI库的弹窗组件),完全掌控弹窗的关闭逻辑和焦点处理:
<html> <head> <style> /* 简单的弹窗样式 */ .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 999; } .modal { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 20px; background: white; border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.2); z-index: 1000; } .modal button { margin: 0 8px 0 0; padding: 6px 12px; } </style> </head> <body> <input type="text" id="inputBox"> <!-- 自定义弹窗结构 --> <div class="modal-overlay" id="overlay" style="display: none"></div> <div class="modal" id="customConfirm" style="display: none"> <p>hogehoge</p> <button id="okBtn">确定</button> <button id="cancelBtn">取消</button> </div> <script> // 显示弹窗 const showConfirm = () => { document.getElementById('overlay').style.display = 'block'; document.getElementById('customConfirm').style.display = 'block'; }; // 关闭弹窗并恢复输入框焦点 const closeConfirm = () => { document.getElementById('overlay').style.display = 'none'; document.getElementById('customConfirm').style.display = 'none'; document.getElementById('inputBox').focus(); }; // 绑定按钮事件 document.getElementById('okBtn').addEventListener('click', closeConfirm); document.getElementById('cancelBtn').addEventListener('click', closeConfirm); // 绑定Esc键关闭弹窗 document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { closeConfirm(); } }); // 初始化显示弹窗 showConfirm(); </script> </body> </html>
这个方案虽然代码多一点,但完全不会受原生API的bug影响,而且还能自定义弹窗样式,体验更统一。
内容的提问来源于stack exchange,提问作者Kozo
相关产品推荐
相关产品推荐

