使用 forEach 遍历 querySelectorAll 的多个元素

Iterate through multiple elements of querySelectorAll with forEach

问题如下:我创建了一个单独的JS文件,我想在其中遍历属于某个class audioz的元素。在我的 JS 代码的第二行中,我在 item 上使用 addEventListener,但是代码似乎不适用于 item,只有当我输入 document 时,但是结果仍然存在缺陷。我在迭代中做错了什么?

JS:

document.querySelectorAll('.audioz').forEach(item => {
    item.addEventListener('keydown', function(e) {
        const ss = document.querySelector(`audio[data-key="${e.keyCode}"]`);
        console.log(ss);
        ss.play();
    })
})

HTML:

<audio class="audioz" data-key="65" src="sounds/clap.wav"></audio>
<audio class="audioz" data-key="83" src="sounds/hihat.wav"></audio>
<audio class="audioz" data-key="68" src="sounds/kick.wav"></audio>
<audio class="audioz" data-key="70" src="sounds/openhat.wav"></audio>
<audio class="audioz" data-key="71" src="sounds/boom.wav"></audio>
<audio class="audioz" data-key="72" src="sounds/ride.wav"></audio>
<audio class="audioz" data-key="74" src="sounds/snare.wav"></audio>
<audio class="audioz" data-key="75" src="sounds/tom.wav"></audio>
<audio class="audioz" data-key="76" src="sounds/tink.wav"></audio>

您当前正在为每个 audio 标签添加一个 keydown 事件侦听器。但是,audio 标记是隐藏的,因此您无法在其上执行 keydown 事件。因此,您的代码将不起作用。

改为将事件侦听器添加到文档。

document.addEventListener('keydown', function(e) {
  const ss = document.querySelector(`audio[data-key="${e.keyCode}"]`);
  console.log(ss);
  ss.play();
})
<audio class="audioz" data-key="65" src="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3"></audio> press the A key

您可以将侦听器附加到每个 <audio> 的父元素。这避免了文档级别的一些事件污染。

const audiozResults = document.getElementsByClassName("audioz");
for (const result of audiozResults) {
  const dataKey = +result.getAttribute("data-key");
  result.parentElement.addEventListener("keydown", evt => {
    if (evt.keyCode === dataKey) {
      result.play();
    }
  });
}
<audio class="audioz" data-key="65" src="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3"></audio> press the A key