厕所打你 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条)

报告相同问题?

悬赏问题

  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应