好像是第二次遇到这个问题,必须要总结一下!!

  1. 1 <!DOCTYPE html>
  2. 2 <html>
  3. 3 <head>
  4. 4 <meta charset="utf-8">
  5. 5 <title></title>
  6. 6 </head>
  7. 7 <style type="text/css">
  8. 8 li{
  9. 9 width: 100px;
  10. 10 height: 50px;
  11. 11 background-color: red;
  12. 12 margin-bottom: 10px;
  13. 13 }
  14. 14 </style>
  15. 15 <body>
  16. 16 <ul id="ulList">
  17. 17 <li></li>
  18. 18 <li></li>
  19. 19 <li></li>
  20. 20 <li></li>
  21. 21 </ul>
  22. 22 <script>
  23. 23 var lis = document.getElementById("ulList").getElementsByTagName("li");
  24. 24 for(var i=0;i<lis.length;i++){
  25. 25 lis[i].onclick = function(){
                  console.log(i);  
                }30 }
  26. 31 </script>
  27. 32 </body>
  28. 33 </html>

如果按照以上方法,无论点击哪一个li标签,i的值都会是4,并不能像我们所想的那样打印出0,1,2,3,原因是什么呢?

暂时也不太清楚,好像涉及闭包,因为也没学到,就参考别人回答总结一下。

for循环是一个外部闭包,依次绑定的点击事件是一个函数实例,也产生了一个闭包域,它引用了外部闭包的变量i,外部闭包域中i的最终值为4,点击事件触发时引用外部闭包变量i(此时i=4),所以输出的值全为4。

暂时先写两种自己能掌握的解决方法:

方法一:在for循环中点击事件外套一个自执行的匿名函数,将索引变量i保存到匿名函数的形参中

  1. 1 <script>
  2. 2 var lis = document.getElementById("ulList").getElementsByTagName("li");
  3. 3 for(var i=0;i<lis.length;i++){
  4. 4 (function(arg){
  5. 5 lis[i].onclick = function(){
  6. 6 console.log(arg);
  7. 7 }
  8. 8 })(i);
  9. 9 }
  10. 10 </script>

方法二:在for循环中,为每一个要点击的对象创建属性用来保存索引变量i

  1. 1 <script>
  2. 2 var lis = document.getElementById("ulList").getElementsByTagName("li");
  3. 3 for(var i=0;i<lis.length;i++){
  4. 4 lis[i].i = i; //创建属性保存变量i
  5. 5 lis[i].onclick = function(){
  6. 6 console.log(this.i);
  7. 7 // console.log(lis[i].i);绝对不能这样写,要不然 Uncaught TypeError: Cannot read property 'i' of undefined
  8. 8 }
  9. 9 }
  10. 10 </script>

 

posted on 2019-02-20 10:55 Ryan_Yue 阅读() 评论() 编辑 收藏
版权声明:本文为Ryan777原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Ryan777/p/10405262.html