我将这个点击事件附加到每个按钮上,当我点击每个按钮时,它会打印出第三个按钮的输出。我不确定发生了什么。
<!DOCTYPE html>
<html>
<head>
<title>JS Bin</title>
</head>
<body>
<button>test1</button>
<button>test2</button>
<button>test3</button>
</body>
<script>
var nodes = document.getElementsByTagName('button');
for (var i = 0; i < nodes.length; i++) {
nodes[i].addEventListener('click', function() {
console.log('You clicked element #' + i);
});
}
</script>
</html>
当我点击任何按钮时,它正在打印
"You clicked element #3"
答案 0 :(得分:3)
对此的简单解决方案:
<!DOCTYPE html>
<html>
<head>
<title>JS Bin</title>
</head>
<body>
<button>test1</button>
<button>test2</button>
<button>test3</button>
</body>
<script>
var nodes = document.getElementsByTagName('button');
console.log(nodes);
for (var i = 0; i < nodes.length; i++) {
//converted click function into an IIFE so it executes then and
there only
nodes[i].addEventListener('click', (function(j) {
return function(){
console.log('You clicked element #' + j);
}
})(i));
}
</script>
</html>
你应该通过两个概念来理解这个东西
1)闭包
2)Javascript是单线程和同步的。那么它如何处理事件?
以下是您的代码中发生的事情:
==&GT; for循环同步执行,因为它是javascript处理事件队列的javascript引擎帖子的一部分,这是一个FIFO(先进先出)
==&GT;当for循环结束时,i的值为3,它保留在内存中直到其内部的函数执行
==&GT;每次取值3并打印出来。
答案 1 :(得分:1)
这是一个循环问题中的函数闭包。
JavaScript closure inside loops – simple practical example
注意这一点!
附注:在访谈中经常会询问有关此问题的问题,以证明对JS的熟练程度。
答案 2 :(得分:1)
当此button
正在侦听事件时,i
的值为nodes.length
-1,即2
。因为循环已经完成了它的执行并且已将i
的值设置为2。
所以它正在安慰You clicked element #3
。
由于scope
&amp; closure
创建IIFE并传递i
。
希望此代码段有用
var nodes = document.getElementsByTagName('button');
for (var i = 0; i < nodes.length; i++) {
(function(i){
nodes[i].addEventListener('click', function() {
console.log('You clicked element #' + i);
});
}(i))
}
选中此jsfiddle
答案 3 :(得分:1)
这是使用jQuery的其他方式。
$("button").each(function(e) {
$(this).data("number", e);
}).bind("click", function(e) {
console.log("You clicked element #" + $(this).data("number"));
});