var的作用域:全局,并且var声明会提前。
<body>
<button>button</button>
<button>button</button>
<button>button</button>
<button>button</button>
<button>button</button>
<script>
const btns = document.getElementsByTagName('button');
for(var i=0;i<btns.length;i++){
Btns[i].addEventListener('click',function(){
console.log("you click the "+ i);
})
}
<!--点击第一个按钮输出的是 you click the 5-->
</script>
</body>
for是同步执行的,先循环绑定 每个btn都绑定了单击事件console.log("you click the "+ i); 但是按钮点击,btn执行响应时,此时i已经是5了。
var i;
for( i=0;i<btns.length;i++){
btns[i].addEventListener('click',function(){
console.log("you click the "+ i);
})
console.log(i);//5
for只是循环为每个按钮绑定事件,为每个按钮绑定了单击事件console.log("you click the "+ i);,此时log里的i是个变量,不是1或者2或者3,就是一个变量i,不是一个固定的值。 每当按钮点击时,事件响应,这个时候他再来获取一下i,完成控制台日志的输出
1、可以用闭包解决,因为函数的作用于是块级的
<script>
const btns = document.getElementsByTagName("button");
for(var i=0;i<btns.length;i++){
(function(num){
btns[i].addEventListener('click',()=>{
console.log('你点击了按钮'+ (num+1) );
})
})(i)<!--将i传给了num-->
}
</script>
2、或者将var改为let,也可以解决问题,因为let的作用域也是块级的
<script>
const btns = document.getElementsByTagName('button');
for(let i=0;i<btns.length;i++){
Btns[i].addEventListener('click',function(){
console.log("you click the "+ i);
})
}
</script>
|