首页 > 解决方案 > index.js:66 未捕获的类型错误:无法在 HTMLDivElement 处读取未定义的属性(读取“innerText”)。(index.js:66)

问题描述

我试图创建一个鼓槌网站作为#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>

标签: javascriptweb

解决方案


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

不是附加所有这些侦听器,而是使用事件委托并将一个侦听器附加到.keys元素。

然后,您可以找到前一个标签的文本(请注意,由于 HTML 中的空白,我们在此处使用了 previousSibling 两次,并将其记录下来。

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

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>


推荐阅读