<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>for与onclick配合</title>
<script type="text/javascript">
window.onload=function(){
var btn=document.getElementsByTagName("input");
for(var i=0;i<btn.length;i++){
btn[i].onclick=function(){
alert(this.value);
}
}
}
</script>
</head>
<body>
<input type="button" value="for循环"/>
<input type="button" value="事件处理"/>
<input type="button" value="弹窗显示"/>
</body>
</html>
这段程序在点击了相应的按钮后会显示相应的value值。
但是为什么把alert里改成i后,不管点哪个都显示3,而不是对应的0,1,2呢?
既然i值都是3,那是怎么能正常显示出对应的value的。
this就是当前的button对象,直接alert i只能得到for循环后的,要做闭包指向当前执行到的i值
window.onload = function () {
var btn = document.getElementsByTagName("input");
for (var i = 0; i < btn.length; i++) {
btn[i].onclick = (function (i) {
return function () { alert(this.value+"|"+i); }
})(i);
}
}
<!DOCTYPE html>
var btn=document.getElementsByTagName("input");这句话有问题,页面里有三个input,由于js不知道你要执行哪一个,js会依次执行所有的input,每当执行下一个的时候就会把上一个覆盖掉,所以当你执行到最后一个的时候就会把前面的全部覆盖掉,正常情况下你应该给这些input分别设置id,这些id可以有规律。然后
document.getElementsById("想要执行的input的id")就行了
for (var i = 0; i < btn.length; i++) { } <====> var i = 0; for(i;i<btn.length;i++){ }
在onload里面,你可以把for循环中的i当做一个局部全局变量,i在栈内存中有下面的变化:
在栈中寻找是否存在值为0的指针,如果有,让i指向这个地址,如果没有,创建一个,然后
让i指向它,当循环一次向后执行时,i依次指向了不同的值,但是这个变化过程中i只是引用
着不同的地址,当循环执行完,当然,i保存了3, alert(i);当然会弹出3,为了解决它,可以
使用闭包:
btn[i].onclick = (function (i) {
return function () { alert(this.value+"|"+i); }
})(i);
首次,你要明白作用域的问题,alert中的这个this指向的是什么,这里的this指向的就是botton,其次,你要明白匿名函数什么时候执行,你的这段
代码中的匿名函数是在整段代码执行完了之后才执行的,所以i不会是当前你点击的这个i,最后,你要明白for循环的执行机制,这个i为什么是3,因为for(var i=0;i<btn.length;i++)的最后一次i++让i变成了3,所以你alert的那个时候i已经变成了3。
解决方法上面已经有人做出了回答,这个是经典的闭包问题,试着自己理解一下
理解this和执行时机 这个问题就解决了;还有啊好像在es6之前js没有块级作用域
for(var i=0;i<btn.length;i++){
(function(i){ btn[i].onclick=function(){
alert(i);
}})(i)
}