js for循环中点击事件中无法获取每一个i值的问题
好像是第二次遇到这个问题,必须要总结一下!!
- 1 <!DOCTYPE html>
- 2 <html>
- 3 <head>
- 4 <meta charset="utf-8">
- 5 <title></title>
- 6 </head>
- 7 <style type="text/css">
- 8 li{
- 9 width: 100px;
- 10 height: 50px;
- 11 background-color: red;
- 12 margin-bottom: 10px;
- 13 }
- 14 </style>
- 15 <body>
- 16 <ul id="ulList">
- 17 <li></li>
- 18 <li></li>
- 19 <li></li>
- 20 <li></li>
- 21 </ul>
- 22 <script>
- 23 var lis = document.getElementById("ulList").getElementsByTagName("li");
- 24 for(var i=0;i<lis.length;i++){
- 25 lis[i].onclick = function(){
console.log(i);
}30 }- 31 </script>
- 32 </body>
- 33 </html>
如果按照以上方法,无论点击哪一个li标签,i的值都会是4,并不能像我们所想的那样打印出0,1,2,3,原因是什么呢?
暂时也不太清楚,好像涉及闭包,因为也没学到,就参考别人回答总结一下。
for循环是一个外部闭包,依次绑定的点击事件是一个函数实例,也产生了一个闭包域,它引用了外部闭包的变量i,外部闭包域中i的最终值为4,点击事件触发时引用外部闭包变量i(此时i=4),所以输出的值全为4。
暂时先写两种自己能掌握的解决方法:
方法一:在for循环中点击事件外套一个自执行的匿名函数,将索引变量i保存到匿名函数的形参中
- 1 <script>
- 2 var lis = document.getElementById("ulList").getElementsByTagName("li");
- 3 for(var i=0;i<lis.length;i++){
- 4 (function(arg){
- 5 lis[i].onclick = function(){
- 6 console.log(arg);
- 7 }
- 8 })(i);
- 9 }
- 10 </script>
方法二:在for循环中,为每一个要点击的对象创建属性用来保存索引变量i
- 1 <script>
- 2 var lis = document.getElementById("ulList").getElementsByTagName("li");
- 3 for(var i=0;i<lis.length;i++){
- 4 lis[i].i = i; //创建属性保存变量i
- 5 lis[i].onclick = function(){
- 6 console.log(this.i);
- 7 // console.log(lis[i].i);绝对不能这样写,要不然 Uncaught TypeError: Cannot read property 'i' of undefined
- 8 }
- 9 }
- 10 </script>