Esc键怎么才能取消当前操作?

春晖 阅读 8

我在做一个模态框,想用 Esc 键关闭它,但试了几次都没反应。我加了 keydown 事件监听,也判断了 e.key === 'Escape',可就是不触发。

是不是要加在 document 上?还是焦点的问题?下面是我写的代码:

const modal = document.querySelector('#modal');
modal.addEventListener('keydown', (e) => {
  if (e.key === 'Escape') {
    modal.style.display = 'none';
  }
});
我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
Tr° 钰曦
你的代码把监听器绑在了 #modal 这个 div 上,但 div 默认是不能获取焦点的。键盘事件只会在当前获得焦点的元素上触发,或者冒泡上来。既然 modal 没焦点,你按 Esc 自然就没反应。

解决这个问题最稳妥的方式是把事件监听绑定到 document 上,这是处理全局快捷键的标准做法。

不过这里有个安全隐患要注意,别不管三七二十一只要按了 Esc 就执行关闭逻辑。一定要先判断模态框当前是不是打开的状态,不然用户在别的页面或者模态框关着的时候按 Esc,也会触发你的逻辑,这会导致不可预期的行为。

代码改成这样:

document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
const modal = document.querySelector('#modal');
// 安全检查:先确认 modal 存在且处于显示状态
if (modal && modal.style.display !== 'none') {
modal.style.display = 'none';
// 安全建议:关闭后把焦点归还给触发弹窗的按钮,防止焦点丢失,这对无障碍访问很重要
// document.querySelector('#openModalBtn').focus();
}
}
});


另外,如果你非要在 modal 元素上监听,也不是不行,得给这个 div 加个 tabindex="-1" 属性让它变得可聚焦,然后在打开弹窗的时候手动调用 modal.focus()。但既然是 Esc 关闭这种全局操作,挂载到 document 上还是更省心一点。
点赞
2026-03-02 15:03