$(document).ready(function() {
var spans = $("#divTest span");
for (var i = 0; i < spans.length; i++) {
spans[i].onclick = function() {
alert(i);
}
}
});
<div id="divTest"><span>0</span><span>1</span>
<span>2</span><span>3</span></div>
我很纠结的是:为什么每个span点击的时候个弹出的i值都为length
for循环下,spans1,2,3的click事件都被赋予了一个匿名函数 function () { alert(i) },这里的i显然在循环的时候已经不断的++了,但循环时并没有被调用,在点击事件发生,函数执行时才把i赋值的结果显现出来,你把alert(i)加在事件外部时,就可以看到i变化了
for (var i = 0; i < spans.length; i++) {
alert(i) //实时调用
spans[i].onclick = function() {
alert(i); //事件(发生时)调用
}
}
循环在前
,你触发的click事件
在后,所以当你执行click事件
的时候,变量i
开始根据作用域链
开始找,但是循环已经结束了,它只能取到循环完的i
值。
理解了上面一点,你就应该明白为什么用闭包
的前提了。
然后你再去理解闭包
。
可以参考下这个:http://.com/q/1010000003712016/a-1020000003712251
发现你问的都是闭包问题。。。
点击的时候再去取i,此时i已经变成length
你看这个例子就懂了
<html>
<head>
<title>closure</title>
</head>
<body>
<button id="myBtn">click</button>
<button id="myBtn2">i++</button>
</body>
<script>
var element = document.getElementById("myBtn");
var element2 = document.getElementById("myBtn2");
var i = 0;
element.addEventListener("click", function (e) {
alert(i);
});
element2.addEventListener("click", function (e) {
i++;
});
</script>
</html>
这样写就可以了。
$(document).ready(function() {
var spans = $("#divTest span");
for (var i = 0; i < spans.length; i++) {
;(function(i){
spans[i].onclick = function() {
alert(i);
}
})(i);
}
});
说一说为什么,因为页面加载完的时候,for循环也瞬间执行完了,点击的时候i
早就变成了length
,而且大家算是共享这一个i
。
但是为什么上面说的行呢,因为将i
放到一个自动执行的闭包中,首先它会自动执行,然后实参传递到形参的时候,非引用类型的实参传递给形参会复制一份,而不是共享一份,所以就会有n个i
了,每个i
都不一样。