首页 > 解决方案 > 单击 div 发出声音,并且同一个 div 链接到键盘声音...有可能吗?

问题描述

我正在制作架子鼓。关键功能是您必须能够单击屏幕上的 div 才能产生鼓声。同时,这个 div 应该响应按下发出相同声音的键。

我只能做其中之一。我想知道我编写的当前代码是否可以具有附加功能。

function playSound(e) {
  const audio = this.document.querySelector(`audio[data-key="${e.keyCode}"]`);
  const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);
  if (!audio) return; //stop function from running altogether
  audio.currentTime = 0; //rewind to the start
  audio.play();
  key.classList.add('playing');
}

function removeTransition(e) {
  if (e.propertyName !== 'transform') return; //skip it if its not a transform
  this.classList.remove('playing')
}
const keys = document.querySelectorAll('.key');
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
window.addEventListener('keydown', playSound);
.key {
  border: 4px solid black;
  border-radius: 5px;
  margin: 1rem;
  font-size: 1.4rem;
  padding: 1rem .5rem;
  transition: all 0.07s;
  width: 100px;
  text-align: center;
  color: white;
  background: rgba(0, 0, 0, 0.4);
  text-shadow: 0 0 5px black;
}

.playing {
  transform: scale(1.1);
  border-color: yellow;
  box-shadow: 0 0 10px yellow;
}
<div class='keys'>
  <div data-key='65' class="key">
    <kbd>A</kbd>
    <span class="sound">clap</span>
  </div>

  <div data-key="83" class="key">
    <kbd>S</kbd>
    <span class="sound">hihat</span>
  </div>

  <div data-key="68" class="key">
    <kbd>D</kbd>
    <span class="sound">kick</span>
  </div>

  <div data-key="70" class="key">
    <kbd>F</kbd>
    <span class="sound">openhat</span>
  </div>

  <div data-key="71" class="key">
    <kbd>G</kbd>
    <span class="sound">boom</span>
  </div>
</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>
<script src="app.js"></script>

我希望能够单击每个 div 以产生与按下它所链接的键相同的声音。

标签: javascripthtmlfrontend

解决方案


我会将“click”事件侦听器添加到您的 Keys(您已经循环通过的关键元素)并将其分配给您的播放声音功能......但是您需要更好地处理 playSound 功能中的更改。我不会在 playSound 中限制条件,而是将代码拆分为多个函数。

就是这样:

function onKeyClicked(e) {
  playSound(e.getAttribute("data-key"));
}

function onKeyPressed(e) {
  playSound(e.keyCode);
}

function playSound(keyCode) {
  const audio = document.querySelector(`audio[data-key="${keyCode}"]`);
  const key = document.querySelector(`.key[data-key="${keyCode}"]`);
  if (!audio) return; //stop function from running altogether
  audio.currentTime = 0; //rewind to the start
  audio.play();
  key.classList.add('playing');
}

function removeTransition(e) {
  if (e.propertyName !== 'transform') return; //skip it if its not a transform
  this.classList.remove('playing')
}
const keys = document.querySelectorAll('.key');
keys.forEach(key => {
  key.addEventListener('transitionend', removeTransition);
  key.addEventListener('click', function() {
    onKeyClicked(key)
  });
});
window.addEventListener('keydown', onKeyPressed);
.key {
    border: 4px solid black;
    border-radius: 5px;
    margin:1rem;
    font-size: 1.4rem;
    padding: 1rem .5rem;
    transition: all 0.07s;
    width: 100px;
    text-align: center;
    color: white;
    background: rgba(0,0,0,0.4);
    text-shadow: 0 0 5px black;
}

.playing {
    transform: scale(1.1);
    border-color: yellow;
    box-shadow: 0 0 10px yellow;
}
<div>
  <div data-key='65' class="key">
    <kbd>A</kbd>
    <span class="sound">clap</span>
  </div>

  <div data-key="83" class="key">
    <kbd>S</kbd>
    <span class="sound">hihat</span>
  </div>

  <div data-key="68" class="key">
    <kbd>D</kbd>
    <span class="sound">kick</span>
  </div>

  <div data-key="70" class="key">
    <kbd>F</kbd>
    <span class="sound">openhat</span>
  </div>

  <div data-key="71" class="key">
    <kbd>G</kbd>
    <span class="sound">boom</span>
  </div>
</div>

<audio data-key='65' src="http://soundbible.com/grab.php?id=1971&type=wav"></audio>
<audio data-key="83" src="http://soundbible.com/grab.php?id=818&type=wav"></audio>
<audio data-key="68" src="http://soundbible.com/grab.php?id=2218&type=wav"></audio>
<audio data-key="70" src="http://soundbible.com/grab.php?id=1455&type=wav"></audio>
<audio data-key="71" src="http://soundbible.com/grab.php?id=1446&type=wav"></audio>

...包括一些声音:-)


推荐阅读