我在做一个模态框,想用 Esc 键关闭它,但试了几次都没反应。我加了 keydown 事件监听,也判断了 e.key === 'Escape',可就是不触发。
是不是要加在 document 上?还是焦点的问题?下面是我写的代码:
const modal = document.querySelector('#modal');
modal.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
modal.style.display = 'none';
}
});
#modal这个 div 上,但 div 默认是不能获取焦点的。键盘事件只会在当前获得焦点的元素上触发,或者冒泡上来。既然 modal 没焦点,你按 Esc 自然就没反应。解决这个问题最稳妥的方式是把事件监听绑定到
document上,这是处理全局快捷键的标准做法。不过这里有个安全隐患要注意,别不管三七二十一只要按了 Esc 就执行关闭逻辑。一定要先判断模态框当前是不是打开的状态,不然用户在别的页面或者模态框关着的时候按 Esc,也会触发你的逻辑,这会导致不可预期的行为。
代码改成这样:
另外,如果你非要在 modal 元素上监听,也不是不行,得给这个 div 加个
tabindex="-1"属性让它变得可聚焦,然后在打开弹窗的时候手动调用modal.focus()。但既然是 Esc 关闭这种全局操作,挂载到 document 上还是更省心一点。