【问题标题】:index.js:66 Uncaught TypeError: Cannot read properties of undefined (reading 'innerText') at HTMLDivElement.<anonymous> (index.js:66)index.js:66 未捕获的类型错误:无法在 HTMLDivElement.<anonymous> 处读取未定义的属性(读取“innerText”)(index.js:66)
【发布时间】:2021-11-07 11:57:11
【问题描述】:

我试图创建一个鼓槌网站作为 #javascript30 挑战的一部分,但我收到以下错误:

index.js:66 未捕获类型错误:无法读取 HTMLDivElement 处未定义的属性(读取“innerText”)。 (index.js:66)

function playAudio(key) {
  switch (key) {
    case 'a':
    case 'A':
      var clap = new Audio("sounds/clap.wav");
      clap.play();
      break;

    case 's':
    case 'S':
      var clap = new Audio("sounds/clap.wav");
      clap.play();
      break;

    case 'd':
    case 'D':
      var clap = new Audio("sounds/clap.wav");
      clap.play();
      break;

    case 'f':
    case 'F':
      var clap = new Audio("sounds/clap.wav");
      clap.play();
      break;

    case 'g':
    case 'G':
      var clap = new Audio("sounds/clap.wav");
      clap.play();
      break;

    case 'h':
    case 'H':
      var clap = new Audio("sounds/clap.wav");
      clap.play();
      break;

    case 'j':
    case 'J':
      var clap = new Audio("sounds/clap.wav");
      clap.play();
      break;

    case 'k':
    case 'K':
      var clap = new Audio("sounds/clap.wav");
      clap.play();
      break;

    case 'l':
    case 'L':
      var clap = new Audio("sounds/clap.wav");
      clap.play();
      break;
    default:
      console.log(key);
  }
}

// To produce sound when the drum is CLICKED
for (var i = 0; i < document.querySelectorAll(".key").length; ++i) {
  // console.log(i);

  document.querySelectorAll(".key")[i].addEventListener("click", function() {
    var keyPress = document.getElementsByTagName("kbd")[i].innerText; //  !!problem in this line!!
    playAudio(keyPress);
    buttonAnimation(keyPress);
  });

}

// To produce sound when the drum key is pressed
document.addEventListener("keypress", function(event) { //call back funtion passes back evt obj
  playAudio(event.key);
  buttonAnimation(event.key);
});



function buttonAnimation(currentKey) {
  try {
    document.querySelector("." + currentKey.toUpperCase()).classList.add("playing");
    setTimeout(function() {
      document.querySelector("." + currentKey.toUpperCase()).classList.remove("playing");
    }, 100);
  } catch (err) {
    console.log(err.message);
  }

}

for (var i = 0; i < document.querySelectorAll(".key").length; ++i) {
  // console.log(i);

  document.querySelectorAll(".key")[i].addEventListener("click", function() {
    var keyPress = document.getElementsByTagName("kbd")[i].innerText; //  !!problem in this line!!
    playAudio(keyPress);
    buttonAnimation(keyPress);
  });

}
<div class="keys">
  <div class="A key">
    <kbd>A</kbd>
    <span class="sound">clap</span>
  </div>
  <div class="S key">
    <kbd>S</kbd>
    <span class="sound">hihat</span>
  </div>
  <div class="D key">
    <kbd>D</kbd>
    <span class="sound">kick</span>
  </div>
  <div class="F key">
    <kbd>F</kbd>
    <span class="sound">openhat</span>
  </div>
  <div class="G key">
    <kbd>G</kbd>
    <span class="sound">boom</span>
  </div>
  <div class="H key">
    <kbd>H</kbd>
    <span class="sound">ride</span>
  </div>
  <div class="J key">
    <kbd>J</kbd>
    <span class="sound">snare</span>
  </div>
  <div class="K key">
    <kbd>K</kbd>
    <span class="sound">tom</span>
  </div>
  <div class="L key">
    <kbd>L</kbd>
    <span class="sound">tink</span>
  </div>
</div>

【问题讨论】:

    标签: javascript web


    【解决方案1】:

    我认为问题在于尝试遍历querySelectorAll 给出的节点列表两次,将所有这些侦听器添加到循环中的元素,然后尝试获取kbd使用该索引的元素。

    使用event delegation 而不是附加所有这些侦听器并将一个 侦听器附加到.keys 元素。

    然后你可以找到前一个标签的文本(注意we use previousSibling twice here because of the whitespace in the HTML,并记录下来。

    这是您的代码的简化示例。

    function playAudio(key) {
      console.log(key);
    }
    
    const keys = document.querySelector('.keys');
    keys.addEventListener('click', handleClick, false);
    
    function handleClick(e) {
      const kbd = e.target.previousSibling.previousSibling;
      const key = kbd.textContent;
      playAudio(key);
    }
    .key { cursor: pointer; }
    .key:hover { color: red; }
    <div class="keys">
      <div class="A key">
        <kbd>A</kbd>
        <span class="sound">clap</span>
      </div>
      <div class="S key">
        <kbd>S</kbd>
        <span class="sound">hihat</span>
      </div>
      <div class="D key">
        <kbd>D</kbd>
        <span class="sound">kick</span>
      </div>
      <div class="F key">
        <kbd>F</kbd>
        <span class="sound">openhat</span>
      </div>
      <div class="G key">
        <kbd>G</kbd>
        <span class="sound">boom</span>
      </div>
    </div>

    【讨论】:

    • 但是如果我将 eventListener 添加到“keys”类中,它也会以容器为目标。另外,您能否详细说明一下:“我认为问题在于尝试迭代 querySelectorAll 给出的节点列表两次,将所有这些侦听器添加到循环中的元素,然后尝试使用该索引获取 kbd 元素。”
    • 另外,我已经使用这个过程建立了另一个鼓槌网站,但在那个网站上,我没有使用 标签。这个标签会不会是造成问题的标签。
    猜你喜欢
    • 2015-04-21
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 2021-12-22
    • 2020-11-07
    • 2021-12-25
    • 2021-11-24
    • 2021-10-31
    相关资源
    最近更新 更多