厕所打你 2021-01-18 22:21 采纳率: 25%
浏览 15
已采纳

这个问题不好描述,哪位大佬进来看一下?

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>test</title>
  </head>
  <body>
    <button>1111</button>
    <button>2222</button>
    <button>3333</button>
  </body>
  <script>
    for(var i=0;i<3;i++){
      document.getElementsByTagName("button")[i].onclick=function(){
        alert(i);
      }
    }
  </script>
</html>

为什么点击每个按钮都会弹出3??

  • 写回答

3条回答 默认 最新

  • 天际的海浪 2021-01-18 22:43
    关注

    因为你需要在事件内使用事件外的循环变量i。
    当事件触发时,那个循环早就结束了,那时的i的值已经是循环最大值加1了。
    所以需要用一些方式保存住当前循环的i的值。

    #### 方案一:用闭包保存住当前循环的i的值
    for (var i = 0; i < arr.length; i++) {
        (function(i){
            arr[i].onclick = function () {
                alert(i);
            }
        })(i);
    }

    #### 方案二:用let块作用域变量
    for (var i = 0; i < arr.length; i++) {
        let k = i;
        arr[i].onclick = function () {
            alert(k);
        }
    }
    ps:IE11中在for语的()内声明的let是整个循环体中共用的,只有在{}内声明的let才是每次循环都独立的。
    非ie的浏览器中可以在中在for语的()内声明let
    for (let i = 0; i < arr.length; i++)

    方案三:为事件元素设置一个index属性,在事件函数内通过this获取当前对象并访问index属性。
    for (var i = 0; i < arr.length; i++) {
        arr[i].index = i;
        arr[i].onclick = function () {
            alert(this.index);
        }
    }
     

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?