作者:苦蔷薇1988 | 来源:互联网 | 2023-06-23 08:33
我意识到还有其他类似标题的问题,但我遇到了一些非常奇怪的问题。
在下面的代码中,我得到一个节点数组并遍历该数组以添加事件:
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', () => 并且在创建按钮时工作正常。
我在那里记录数组以确保它被捕获( activateButtons 在另一个构造 dom 元素的函数之后调用,该部分工作正常。在日志中我得到:
根据其他答案,我这样做是正确的 - 我将事件侦听器分配给数组中的节点,而不是数组本身。阵列显然正在组装。那么为什么我会收到这个错误呢?
在代码的其他地方,当最初创建一个新按钮时,该函数包含几乎完全相同的代码,除了我创建按钮 (document.createElement) 然后立即将其分配给按钮,而不是需要一个数组。
在加载时,已经创建的按钮从 json 文件重新实例化,当我尝试添加事件监听器时,我没有收到错误,但也没有收到事件,所以我决定添加创建按钮后,所有事件一次全部完成。我在这里缺少什么?
回答
for..in
迭代原型链中任何位置的所有可枚举属性。对于 HTMLCollection,除了数字属性之外,这还会导致:
for (const i in document.getElementsByClassName('catalogItem')) {
console.log(i);
}
length
, item
, namedItem
- 每个属性的值都不是元素(因此调用addEventListener
它们会失败)。
for..of
改为使用来调用 HTMLCollection 的迭代器,它只为您提供元素:
for (const button of catButtons) {
button.addEventListener('click', () => {
// ...
});
}
由于您要在循环中添加侦听器,请确保声明迭代变量 (i
或button
) - 使用const
; usingfor(i
结果只有一个全局绑定 for i
,如果您发现要检查侦听器内的变量,这将导致问题。(请参阅循环内的闭包问题)