You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript中实现键盘按键触发对应鼓点音效的功能

问题描述

我已经实现了鼠标点击按钮播放鼓点音效的功能,但还需要添加按下键盘按键触发对应音效的功能,尝试后没成功。以下是我的代码:

HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@1,700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="style.css">
    <title>DrumKit Project</title>
</head>
<body>
    <header>
        <h1 class="container_h1">JavaScript Drum Kit</h1>
    </header>

    <section class="container_header">
        <div class="header__key_mapping">
            <h2 class="container_h2">Key Mapping</h2>
            <ul class="keys__mapping">
                <li class="keys__mapping_key"><p class="keys text">E</p> Crash</li>
                <li class="keys__mapping_key"><p class="keys text">R</p> Ride</li>
                <li class="keys__mapping_key"><p class="keys text">F</p>Floor tom</li>
                <li class="keys__mapping_key"><p class="keys text">G</p>Mid tom</li>
                <li class="keys__mapping_key"><p class="keys text">H</p>High tom</li>
                <li class="keys__mapping_key"><p class="keys text">V</p><p class="keys text">B</p>Kick</li>
                <li class="keys__mapping_key"><p class="keys text">J</p>Snare</li>
                <li class="keys__mapping_key"><p class="keys text">I</p> Hi-Hat Open</li>
                <li class="keys__mapping_key"><p class="keys text">K</p>Hi-Hat Closed</li>
            </ul>
        </div>
    </section>

    <main class="container__main"> 
        <img src="assets/drum-img.png" alt="drum image" class="container__header_img">        
        <div class="container__main_btns">
            <button class="btn key_crash" onclick="onclick()" id="">E</button>
            <button class="btn key_ride" >R</button>
            <button class="btn key_floor-tom" >F</button>
            <button class="btn key_mid-tom" >G</button>
            <button class="btn key_high-tom" >H</button>
            <button class="btn key_kick" >V</button>
            <button class="btn key_kick2" >B</button>
            <button class="btn key_share" >J</button>
            <button class="btn key_hit-hat-open" >I</button>
            <button class="btn key_hit-hat-closed" >K</button>
        </div>
 
        <audio id="btn-key_crash" src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/crash.wav"></audio>
        <audio id="btn-key_ride" src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/ride.wav"></audio>
        <audio id="btn-key_floor-tom"  src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/tom-low.wav"></audio>
        <audio id="btn-key_mid-tom" src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/tom-mid.wav"></audio>
        <audio id="btn-key_high-tom" src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/tom-high.wav"></audio>
        <audio id="btn-key_kick" src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/kick.wav"></audio>
        <audio id="btn-key_kick2" src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/kick.wav"></audio>
        <audio id="btn-key_share" src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/snare.wav"></audio>
        <audio id="btn-key_hit-hat-open" src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/hihat-open.wav"></audio>
        <audio id="btn-key_hit-hat-closed"  src="https://raw.githubusercontent.com/ArunMichaelDsouza/javascript-30-course/master/src/01-javascript-drum-kit/sounds/hihat-close.wav"></audio>
    </main>
<footer></footer>
    <script src="main.js"></script>
</body>
</html>

JavaScript代码

function playKey(idKey) {
  const element = document.querySelector(idKey);
  if (element) {
    element.play();
  } else {
    console.error('element not found')
  }
}

const btns = document.querySelectorAll('.btn')
for (i = 0; i < btns.length; i++) {
  const key = btns[i];
  const keyCode = key.classList[1];
  const idKey = `#btn-${keyCode}`;

  key.onclick = function() {
    playKey(idKey);
  }
}

解决方案

要实现键盘触发音效,需监听键盘keydown事件,同时建立按键字符与对应音频ID的映射。以下是修改后的完整JavaScript代码:

function playKey(idKey) {
  const element = document.querySelector(idKey);
  if (element) {
    // 重置音频播放位置,支持连续按键重复播放
    element.currentTime = 0;
    element.play();
  } else {
    console.error('element not found')
  }
}

// 保留原有鼠标点击逻辑
const btns = document.querySelectorAll('.btn')
for (let i = 0; i < btns.length; i++) {
  const key = btns[i];
  const keyCode = key.classList[1];
  const idKey = `#btn-${keyCode}`;

  key.onclick = function() {
    playKey(idKey);
  }
}

// 建立按键与音频ID的映射表
const keyToAudioMap = {
  'E': '#btn-key_crash',
  'R': '#btn-key_ride',
  'F': '#btn-key_floor-tom',
  'G': '#btn-key_mid-tom',
  'H': '#btn-key_high-tom',
  'V': '#btn-key_kick',
  'B': '#btn-key_kick2',
  'J': '#btn-key_share',
  'I': '#btn-key_hit-hat-open',
  'K': '#btn-key_hit-hat-closed'
};

// 监听键盘按下事件
document.addEventListener('keydown', function(event) {
  // 转为大写,兼容小写输入
  const pressedKey = event.key.toUpperCase();
  const audioId = keyToAudioMap[pressedKey];
  if (audioId) {
    playKey(audioId);
    // 可选:给对应按钮添加短暂激活动画(需在CSS中定义.active样式)
    const btn = document.querySelector(`.btn.${audioId.replace('#btn-key_', '')}`);
    if (btn) {
      btn.classList.add('active');
      setTimeout(() => btn.classList.remove('active'), 100);
    }
  }
});

关键修改说明

  • 添加键盘事件监听:监听文档的keydown事件,捕获用户按键动作。
  • 按键映射表:明确每个按键对应的音频ID,逻辑清晰,避免DOM遍历查找。
  • 音频重置:增加element.currentTime = 0,连续按同一键时音频会立即重新播放。
  • 大小写兼容:将捕获的按键转为大写,用户按小写字母也能触发对应音效。
  • 交互反馈:可选给对应按钮添加短暂激活样式,提升用户体验(需在CSS中定义.active类,例如transform: scale(1.1)或背景色变化)。

另外,HTML中第一个按钮的onclick="onclick()"属性无效,建议删除避免冲突。

内容的提问来源于stack exchange,提问作者Samuel Charles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 08:25:57