按键事件取消按键重复

时间:2019-03-14 11:14:29

标签: javascript event-listener keydown keyup

此代码是30天香草JS挑战赛的一部分。

如果按住声音键,声音会继续播放,而不会注意到“ D”和“ L”以外的“结束”事件(取消了“播放”类),因为声音持续时间太短(〜分别为0.16s和〜0.04s)。

但是有两件事我不太了解:

  1. 按下“ A”并按下另一个声音键(并保持 (向下)),先前按下的键('A')停止“循环播放”并等待 新的声音键在再次“循环”在一起之前结束。但 从我编写的代码来看,如果键按下(在keyStatus映射中) 应该播放声音
  2. 如果我按下一个或几个键,声音会“循环”,但 一旦我触发了一个按键,其他所有仍然按下的按键就会停止 触发他们的事件。 JS如何处理这些情况?

我希望我足够清楚

const allAudio = document.querySelectorAll('audio');
    allAudio.forEach(audio => audio.addEventListener('ended', () => {
      let dataKey = audio.getAttribute('data-key');
      document.querySelector(`.key[data-key="${dataKey}"]`).classList.remove('playing');
    }));
    
    let keyStatus = {};

    window.addEventListener('keyup', e => handleKeyPress(e));

    window.addEventListener('keydown', e => handleKeyPress(e));

    function handleKeyPress(event) {
      console.log(event);
      if(event.key === undefined)
        return;
      
      keyStatus[event.key] = event.type === "keydown";

      for(key in keyStatus) {
        if(keyStatus[key])
          playSound(key);
      }
    }

    function playSound(dataKey) {
      let key = document.querySelector(`.key[data-key="${dataKey}"]`);
      let audio = document.querySelector(`audio[data-key="${dataKey}"]`);

      if(key) {
        key.classList.add('playing');
      }

      if(audio) {
        audio.play();
      }
    }
html {
  font-size: 10px;
  background: url(http://i.imgur.com/b9r5sEL.jpg) bottom center;
  background-size: cover;
}

body,html {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
}

.keys {
  display: flex;
  flex: 1;
  min-height: 100vh;
  align-items: center;
  justify-content: center;
}

.key {
  border: .4rem solid black;
  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;
}

.playing {
  transform: scale(1.1);
  border-color: #ffc600;
  box-shadow: 0 0 1rem #ffc600;
}

kbd {
  display: block;
  font-size: 4rem;
}

.sound {
  font-size: 1.2rem;
  text-transform: uppercase;
  letter-spacing: .1rem;
  color: #ffc600;
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JS Drum Kit</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="keys">
    <div data-key="a" class="key">
      <kbd>A</kbd>
      <span class="sound">clap</span>
    </div>
    <div data-key="s" class="key">
      <kbd>S</kbd>
      <span class="sound">hihat</span>
    </div>
    <div data-key="d" class="key">
      <kbd>D</kbd>
      <span class="sound">kick</span>
    </div>
    <div data-key="f" class="key">
      <kbd>F</kbd>
      <span class="sound">openhat</span>
    </div>
    <div data-key="g" class="key">
      <kbd>G</kbd>
      <span class="sound">boom</span>
    </div>
    <div data-key="h" class="key">
      <kbd>H</kbd>
      <span class="sound">ride</span>
    </div>
    <div data-key="j" class="key">
      <kbd>J</kbd>
      <span class="sound">snare</span>
    </div>
    <div data-key="k" class="key">
      <kbd>K</kbd>
      <span class="sound">tom</span>
    </div>
    <div data-key="l" class="key">
      <kbd>L</kbd>
      <span class="sound">tink</span>
    </div>
  </div>

  <audio data-key="a" src="sounds/clap.wav"></audio>
  <audio data-key="s" src="sounds/hihat.wav"></audio>
  <audio data-key="d" src="sounds/kick.wav"></audio>
  <audio data-key="f" src="sounds/openhat.wav"></audio>
  <audio data-key="g" src="sounds/boom.wav"></audio>
  <audio data-key="h" src="sounds/ride.wav"></audio>
  <audio data-key="j" src="sounds/snare.wav"></audio>
  <audio data-key="k" src="sounds/tom.wav"></audio>
  <audio data-key="l" src="sounds/tink.wav"></audio>
</body>
</html>

0 个答案:

没有答案