JavaScript:循环绑定事件-封装函数、闭包解决

提出问题

  1. <ul>
  2. <li>测试1</li>
  3. <li>测试2</li>
  4. <li>测试3</li>
  5. </ul>
  6. <script>
  7. var lis = document.getElementsByTagName("li")
  8. for(var i = 0;i<lis.length;i++){
  9. lis[i].onclick = function(){
  10. alert(i) // 全部都显示3
  11. }
  12. }
  13. </script>

执行结果:点击 li 标签,全部都显示 3

原因:因为js的函数是调用时触发,绑定事件的时候 i 值并没有被传入执行函数里。触发事件时,循环已经结束,此时的 i 值为 索引最大值

解决

方式一:封装函数

  1. // 定义函数
  2. function f(dom,value){ // 此时value的值就确定了,不会随着变量i的值改变
  3. dom.onclick = function(){
  4. alert(value)
  5. }
  6. }
  7. var lis = document.getElementsByTagName("li")
  8. for(var i = 0;i<lis.length;i++){
  9. f(lis[i],i)// 调用函数,传入变量i
  10. }

方式二:闭包

使用闭包函数存储i值

  1. function f(value){// 此时value的值就确定了,不会随着变量i的值改变
  2. return function(){
  3. alert(value)
  4. }
  5. }
  6. var lis = document.getElementsByTagName("li")
  7. for(var i = 0;i<lis.length;i++){
  8. // 调用函数,传入变量i
  9. lis[i].onclick = f(i)
  10. }

原文出处:https://malaoshi.top/show_1IX3noRog4lm.html