Asu*_*sur 1 javascript addeventlistener
我一直在尝试使用for循环click向一系列事件添加事件divs.该divs动态创建和加载.每个div都应该调用自己的回调函数.但似乎每个div都附加到最终事件监听器并调用最终事件监听器的回调函数.
以下是我的基本代码:
for(index=0; index<divs.length; index++) {
divs[index].addEventListener("click", function(){console.log(divs[index].getAttribute("id"));}, true); //capture click event
}
Run Code Online (Sandbox Code Playgroud)
点击时,每个div只显示最终div的id.
Phil的回答为您发布的特定代码(+1)提供了一个很好的解决方案,但没有解释您的原始代码存在什么问题.
问题是事件处理程序闭包获得了对变量的持久引用index,而不是它们创建时的副本.所以他们都看到了最终的值index(divs.length).例如,这段代码
for (index = 0; index < 4; ++index) {
setTimeout(function() {
console.log(index);
}, 100);
}
Run Code Online (Sandbox Code Playgroud)
...当超时发生时,将记录"4"四次,而不是"0","1","2"和"3".
要在您希望确保处理程序关闭特定值的一般情况下更正它,请使用为您生成事件处理函数的工厂函数,其中事件处理程序关闭您为工厂函数提供的参数而不是循环变量:
for(index=0; index<divs.length; index++) {
divs[index].addEventListener("click", createHandler(divs[index], true); //capture click event
}
function createHandler(div) {
return function(){
console.log(div.getAttribute("id"));
};
}
Run Code Online (Sandbox Code Playgroud)
在那里,事件处理程序关闭div,不会改变.
闭包是JavaScript最强大的功能之一.一旦你理解它们是如何工作的(它们实际上比人们想象的要简单得多),你就可以使用它们来达到很好的效果.更多:关闭并不复杂