为何给div绑定keydown事件无响应,需绑定到window?
问题解答
为什么.key盒子接收不到keydown事件?
- div默认不可聚焦:只有原生可聚焦元素(如
<input>、<button>)或设置了tabindex属性的元素,才能获得焦点并接收键盘事件。你的.key是普通div,默认无法获得焦点,因此绑定在它身上的keydown事件永远不会触发。 - 键盘事件的触发规则:按下按键时,浏览器仅会把键盘事件发送给当前拥有焦点的元素。如果页面无任何元素聚焦,事件会冒泡至
window/document,而非目标div。
为什么要将keydown绑定到window?
- 全局捕获按键操作:绑定到
window可以捕获所有键盘按键事件,无论页面中是否有元素聚焦,都能响应按键——这完全符合鼓组应用的需求:用户无需先点击盒子,直接按键盘就能触发对应效果。 - 逻辑更简洁:通过
window监听后,可利用事件对象的key/keyCode属性定位到对应的.key元素,再为其添加playing类,无需处理每个div的焦点问题。
修正后的代码示例
JavaScript
function handleKeyDown(e) { // 用data-key快速定位元素(需先给.key添加该属性) const keyElement = document.querySelector(`.key[data-key="${e.key.toUpperCase()}"]`); if (!keyElement) return; keyElement.classList.add('playing'); // 自动移除过渡类,避免残留 setTimeout(() => keyElement.classList.remove('playing'), 70); } window.addEventListener('keydown', handleKeyDown); // 保留点击事件逻辑 document.querySelectorAll('.key').forEach(key => { key.addEventListener('click', () => { key.classList.add('playing'); setTimeout(() => key.classList.remove('playing'), 70); }); });
补充HTML(添加data-key属性)
给每个.key元素添加对应按键的属性,方便快速查找:
<div class="key" data-key="A"> <kbd>A</kbd> <span class="sound">clap</span> </div> <div class="key" data-key="S"> <kbd>S</kbd> <span class="sound">hihat</span> </div> <!-- 其余.key元素同理添加data-key -->
内容的提问来源于stack exchange,提问作者Omar Shawky
相关产品推荐
相关产品推荐

