Javascript 将事件添加到新节点
我一直在尝试使用for循环将Javascript 将事件添加到新节点,javascript,addeventlistener,Javascript,Addeventlistener,我一直在尝试使用for循环将click事件添加到一系列div。div是动态创建和加载的。每个div都应该调用自己的回调函数。但似乎每个div都连接到最终事件侦听器并调用最终事件侦听器的回调函数 下面是我的基本代码: for(index=0; index<divs.length; index++) { divs[index].addEventListener("click", function(){console.log(divs[index].getAttribute("id"));}
click
事件添加到一系列div
。div
是动态创建和加载的。每个div都应该调用自己的回调函数。但似乎每个div都连接到最终事件侦听器并调用最终事件侦听器的回调函数
下面是我的基本代码:
for(index=0; index<divs.length; index++) {
divs[index].addEventListener("click", function(){console.log(divs[index].getAttribute("id"));}, true); //capture click event
}
for(index=0;index这是因为您在事件处理程序中使用了divs[index]
,循环完成后,它被设置为最后一个元素
使用this
。此外,您可以使用一个事件处理程序,而不是创建一组相同的闭包,例如
function logId(e) {
console.log(this.getAttribute("id"));
}
…在你的循环中
divs[index].addEventListener("click", logId, false);
请参见这是因为您在事件处理程序中使用了divs[index]
,循环完成后,该事件处理程序被设置为最后一个元素
使用this
。此外,您可以使用一个事件处理程序,而不是创建一组相同的闭包,例如
function logId(e) {
console.log(this.getAttribute("id"));
}
…在你的循环中
divs[index].addEventListener("click", logId, false);
参见您可以使用@phil指出的这个
关键字
但是,要解释你的问题是什么,考虑一下这个闭包:
for(index=0; index<divs.length; index++) {
(function(index){
divs[index].addEventListener("click", function(){
console.log(divs[index].getAttribute("id"));
}, true);
})(index);
}
for(index=0;index您可以使用@phil指出的this
关键字
但是,要解释你的问题是什么,考虑一下这个闭包:
for(index=0; index<divs.length; index++) {
(function(index){
divs[index].addEventListener("click", function(){
console.log(divs[index].getAttribute("id"));
}, true);
})(index);
}
for(index=0;index为您发布的特定代码(+1)提供了一个很好的解决方案,但没有解释原始代码的问题所在
问题是,事件处理程序闭包获得了对索引
变量的持久引用,而不是创建时的副本。因此,它们都可以看到索引
的最终值(divs.length
)。例如,此代码
for (index = 0; index < 4; ++index) {
setTimeout(function() {
console.log(index);
}, 100);
}
for(索引=0;索引<4;++index){
setTimeout(函数(){
控制台日志(索引);
}, 100);
}
…将在超时发生时记录“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"));
};
}
for(index=0;index为您发布的特定代码(+1)提供了一个很好的解决方案,但没有解释原始代码的问题所在
问题是,事件处理程序闭包获得了对索引
变量的持久引用,而不是创建时的副本。因此,它们都可以看到索引
的最终值(divs.length
)。例如,此代码
for (index = 0; index < 4; ++index) {
setTimeout(function() {
console.log(index);
}, 100);
}
for(索引=0;索引<4;++index){
setTimeout(函数(){
控制台日志(索引);
}, 100);
}
…将在超时发生时记录“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"));
};
}
for(index=0;indexread关于javascript闭包的内容,并编辑您的代码。这是一个可变范围的问题。read关于javascript闭包的内容,并编辑您的代码。这是一个可变范围的问题。+1用于伟大的问题描述。您的createHandler
方法也适用于IE的(<9)attachEvent
,而我的方法则不适用(this
attachEvent
支持被破坏)@T.J.Crowder闭包很有趣,对于伟大的问题描述,thanx+1。你的createHandler
方法也可以在IE的(<9)attachEvent
中工作,而我的方法不会(此
支持被破坏)@T.J.Crowder闭包很有趣,thanx你的说明也很有效,但是我仍然不明白什么是(函数(arg){statements})(arg),thanx对于你的帮助你的说明也很有效,但是我仍然不明白什么是(函数(arg){statements})(arg),thanx对于你的帮助