【问题标题】:Javascript Looping over an array of object and adding eventListener has a weird behaviorJavascript循环对象数组并添加eventListener有一个奇怪的行为
【发布时间】:2021-09-25 03:28:36
【问题描述】:

我不懂 Javascript 中的概念。首先,我创建了一个箭头函数 init(),它遍历一个对象数组并初始化一个附加了 eventListener 的图像标签。

init: () => {
        let catsContainer = document.getElementById('catsContainer')
        for (let cat of data.cats) {
            let element = `<img src="img/${cat.image}" catName="${cat.name}" alt="catImage" id="catOneImage" width="50" height="50">`;
            element = octopus.htmlToElement(element)
            catsContainer.appendChild(element)
            element.addEventListener('click', ((elementCopy) => {
                return () => {
                    view.loadImage(elementCopy)
                }
            })(element));
        }
    }

单击该图像时,将通过 loadImage() 函数加载新的大图像(更改 src 属性)。

loadImage: function (el) {
        let catBigImage = document.getElementById('catBigImage');
        let catName = document.getElementById('catName');
        catBigImage.setAttribute('src', el.getAttribute('src'))
        catName.innerHTML = el.getAttribute('catName')
        catBigImage.addEventListener('click', () => {
            let obj = data.cats.find(o => o.name === el.getAttribute('catName'));
            console.log(`obj:: ${obj}`)
            octopus.incrementCounter(obj)
            console.log(obj)
        });
    }

通常当您单击该大图像时,所选对象的计数属性必须增加。问题是当加载新图像时,我的代码会保留最后加载的对象并增加其计数器。直到现在我才真正理解这种行为。

您可以在上传的屏幕截图中看到,在第三次单击新加载的图像 (cat4) 时,我的代码还会增加最后加载的图像 (cat2),从而产生 4 个 console.log 行。

【问题讨论】:

  • 那是因为addEventListener 没有替换监听器,它添加它。所以你在同一个元素上累积事件处理程序。

标签: javascript closures


【解决方案1】:

发生这种情况是因为这段代码:

    catBigImage.addEventListener('click', () => {
        let obj = data.cats.find(o => o.name === el.getAttribute('catName'));
        console.log(`obj:: ${obj}`)
        octopus.incrementCounter(obj)
        console.log(obj)
    });

...添加一个事件处理程序每​​次执行。它不会替换之前绑定的事件处理程序。

您应该将此代码移出loadImage 函数,并且只执行一次。

根据经验,当在处理事件的函数中添加事件侦听器时,这是一种代码异味。

【讨论】:

  • 谢谢@trincot。如果可行,我会尝试并接受答案。
  • 它就像一个魅力,感谢您的建议,我认为我的代码现在更有条理了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多