<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Drum Keyboard</title>
  <link rel="stylesheet" href="./css/style.css">
</head>
<body>
  <div class="keys">
    <button class="key" data-key="65">
      <span class="letter">A</span>
      <span class="sound">clap</span>
    </button>
    <button class="key" data-key="83">
      <span class="letter">S</span>
      <span class="sound">hihat</span>
    </button>
    <button class="key" data-key="68">
      <span class="letter">D</span>
      <span class="sound">kick</span>
    </button>
    <button class="key" data-key="70">
      <span class="letter">F</span>
      <span class="sound">openhat</span>
    </button>
    <button class="key" data-key="71">
      <span class="letter">G</span>
      <span class="sound">boom</span>
    </button>
    <button class="key" data-key="72">
      <span class="letter">H</span>
      <span class="sound">ride</span>
    </button>
    <button class="key" data-key="74">
      <span class="letter">J</span>
      <span class="sound">snare</span>
    </button>
    <button class="key" data-key="75">
      <span class="letter">K</span>
      <span class="sound">tom</span>
    </button>
    <button class="key" data-key="76">
      <span class="letter">L</span>
      <span class="sound">tink</span>
    </button>
  </div>

  <audio data-key="65" src="./sounds/clap.wav"></audio>
  <audio data-key="83" src="./sounds/hihat.wav"></audio>
  <audio data-key="68" src="./sounds/kick.wav"></audio>
  <audio data-key="70" src="./sounds/openhat.wav"></audio>
  <audio data-key="71" src="./sounds/boom.wav"></audio>
  <audio data-key="72" src="./sounds/ride.wav"></audio>
  <audio data-key="74" src="./sounds/snare.wav"></audio>
  <audio data-key="75" src="./sounds/tom.wav"></audio>
  <audio data-key="76" src="./sounds/tink.wav"></audio>
</body>
<script>
  // keydown
  window.addEventListener('keydown', function(e){
    console.log('e', e.keyCode)
    const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`)
    if (!audio) {
      return console.log('stop')
    }
    audio.currentTime = 0 // 以秒的形式返回音頻播放位置
    audio.play()

    // css style
    const key = document.querySelector(`.key[data-key="${e.keyCode}"]`)
    key.classList.add('playing')
    const keys = document.querySelectorAll('.key')
    // 利用 forEach 方法讀取 NodeList 並為每一個元素監聽 transitionend 事件
    keys.forEach(item => {
      item.addEventListener('transitionend', function(e){
        console.log('ssss',e.target)
        e.target.classList.remove('playing')
      })
    })
  })


  // click
  window.addEventListener('click', function(e){
    // 只有選到 button ,裡面的文字不會選到
    console.log('c', e.target.dataset.key)
    // closest 抓最近的元素
    console.log('target', e.target.closest('button').dataset.key)
    // data attribute 取得元素
    const audio = document.querySelector(`audio[data-key="${e.target.closest('button').dataset.key}"]`)
    if (!audio) {
      return console.log('stop')
    }
    audio.currentTime = 0 // 以秒的形式返回音頻播放位置
    audio.play()
  })
</script>
</html>
.keys {
  display: flex;
  flex: 1;
  min-height: 100vh;
  align-items: center;
  justify-content: center;
  .key {
    border: .3rem solid rgb(53, 53, 53);
    border-radius: .5rem;
    margin: 1rem;
    font-size: 1.5rem;
    padding: 1rem .5rem;
    transition: all .07s ease;
    width: 10rem;
    text-align: center;
    color: white;
    background: rgba(0,0,0,0.4);
    text-shadow: 0 0 .5rem black;
  }
  .letter {
    display: block;
    font-size: 4rem;
  }
  .sound {
    font-size: 1.2rem;
    text-transform: uppercase;
    letter-spacing: .1rem;
    color: #ffc600;
  }
  .playing {
    transform: scale(1.1);
    border-color: #ffc600;
    box-shadow: 0 0 1rem #ffc600;
  }
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.