JavaScript钢琴开发求助:按键按压样式实现遇contains函数报错
问题解决思路与修正代码
核心问题分析
报错whiteKey.contains is not a function的原因很明确:
document.getElementsByClassName('white')返回的是HTMLCollection元素集合,不是单个DOM元素,直接给集合调用contains/add方法,浏览器无法识别。- 你写的
whiteKeyDown/blackKeyDown函数没接收具体的按键元素,且判断类名、添加类的方法用错了——要使用DOM元素的classList对象下的contains()和add()方法。 - 调用函数时,你把
document.getElementById('low-c').play()的结果传进去了,完全没必要,音频播放和样式设置要分开处理。
修正后的完整代码
// 样式操作函数接收具体按键元素作为参数 function whiteKeyDown(element) { if (!element.classList.contains('white-pushed')) { element.classList.add('white-pushed'); } } function blackKeyDown(element) { if (!element.classList.contains('black-pushed')) { element.classList.add('black-pushed'); } } // 新增按键抬起时的样式恢复函数 function whiteKeyUp(element) { element.classList.remove('white-pushed'); } function blackKeyUp(element) { element.classList.remove('black-pushed'); } document.addEventListener('keydown', (playNote) => { if (playNote.repeat) return; if (playNote.key === 'c') { if (playNote.ctrlKey) { // 先获取对应黑键元素 const targetKey = document.getElementById('low-c#'); // 分开执行音频播放和样式设置 targetKey.play(); blackKeyDown(targetKey); } else { const targetKey = document.getElementById('low-c'); targetKey.play(); whiteKeyDown(targetKey); } } }); // 绑定keyup事件,按键抬起时恢复默认样式 document.addEventListener('keyup', (playNote) => { if (playNote.key === 'c') { if (playNote.ctrlKey) { const targetKey = document.getElementById('low-c#'); blackKeyUp(targetKey); } else { const targetKey = document.getElementById('low-c'); whiteKeyUp(targetKey); } } });
关键修改点
- 样式函数改为接收单个DOM元素参数,针对具体按键处理样式,而非操作整个元素集合。
- 使用
element.classList.contains()判断类名,element.classList.add()/remove()添加或移除类,这是操作DOM类名的标准方式。 - 把音频播放和样式设置分开执行,避免逻辑混淆。
- 新增
keyup事件监听,解决按键按下后样式无法恢复的问题,让交互更符合真实钢琴的操作逻辑。
内容的提问来源于stack exchange,提问作者kolbykiernan
相关产品推荐
相关产品推荐

