【问题标题】:addEventListener is not a function even though array returns nodes?即使数组返回节点,addEventListener 也不是函数?
【发布时间】:2020-12-04 19:46:31
【问题描述】:

我知道还有其他类似标题的问题,但我遇到了一些非常奇怪的问题。

在下面的代码中,我得到一个节点数组并遍历该数组以添加事件:

   activateButtons = () => {
   let catButtons = document.getElementsByClassName('catalogItem')
   for(i in catButtons){
     console.log(catButtons[i])
     catButtons[i].addEventListener('click', () => {
       catButtons[i].classList.toggle('active')
       if(catButtons[i].nextElementSibling){
         catButtons[i].nextElementSibling.classList.toggle('show')
      }
    })
  }
}

无论我使用 ('click', e => 还是 ('click', () =>),我都会得到相同的结果。稍后的函数使用 ('click', () => 并且在按钮时工作得很好已创建。

我正在那里记录数组以确保它被捕获(在构造 dom 元素的另一个函数之后调用activateButtons,该部分工作正常。在日志中我得到:

根据其他答案,我这样做是正确的 - 我将事件侦听器分配给数组中的节点,而不是数组本身。阵列显然正在组装。那么为什么会出现这个错误呢?

在代码的其他地方,当最初创建一个新按钮时,该函数包含几乎完全相同的代码,除了我创建按钮 (document.createElement) 然后立即将其分配给按钮,而不需要一个数组。

在加载时,已经制作的按钮从 json 文件中重新实例化,当我尝试 addEventListener 时,我没有收到错误,也没有收到事件,所以我决定在创建按钮后一次添加所有事件。我在这里错过了什么?

【问题讨论】:

  • 记录的20 是它尝试调用addEventListener 的内容。

标签: javascript html


【解决方案1】:

for..in 遍历原型链中任何位置的所有可枚举属性。对于 HTMLCollection,这会导致 除了 数字属性:

for (const i in document.getElementsByClassName('catalogItem')) {
  console.log(i);
}

lengthitemnamedItem - 每个属性的值都不是元素(因此在它们上调用 addEventListener 会失败)。

改用for..of 来调用HTMLCollection 的迭代器,它只为您提供元素:

for (const button of catButtons) {
  button.addEventListener('click', () => {
    // ...
  });
}

由于您在循环中添加侦听器,因此请确保声明迭代变量(ibutton) - 使用 const;使用for(i 会导致i 只有一个全局绑定,如果您发现要检查侦听器内部的变量,则会出现问题。 (见closure inside loops问题)

【讨论】:

  • 好吧,我无法在接下来的 9 分钟内接受答案,但确实如此。谢谢!在旧版本的函数中,我根据按钮的 json 索引通过单独的 ID 获取每个元素,这似乎是多余的代码。考虑到有多少其他地方需要做这种事情,你为我省去了很多麻烦!
猜你喜欢
  • 2021-10-29
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-28
  • 1970-01-01
  • 2014-02-12
  • 2021-01-29
相关资源
最近更新 更多