javascript函数,为什么for循环遍历dom节点,监听被点击对象,输出都是一样的呢?
 我想通过for循环内嵌一个事件监听,捕获我点击的是哪个个区域,执行对应函数。可是为什么点击第一个或第二个区域,输出都是2呢?
不是应该对应 0 和 1 吗


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>为什么</title>
    <style type="text/css">
        .container{
            width: 100px;
            height: 100px;
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <div class="container">container1</div>
    <div class="container">container2</div>

    <script type="text/javascript">
        var container = document.getElementsByClassName("container");
        console.log(container.length);          //2
        for (var i = 0; i < container.length; i++) {
            container[i].onmouseup = function(){
                console.log(i)                  //2 (不明白为什么,不是应该0或1吗)
            }
        }
    </script>
</body>
</html>

图片说明

6个回答

绑定结束时,i的值就是2,跳出循环,这时候i的值就是2,而不是你触发这个事件时,才绑定的,才执行这个函数,而是文档流加载完以后,就一直是2,所以你触发输出i就一直是2,你把两个标签的内容换一下,就能看到,i还是2,但触发标签是不同的

qq_29594393
当作看不见 不是突破循环限制,绑定第一个事件的时候i为1 ,没错,但这时候你没有输出i,它会继续绑定第二个事件,这时候i为2,事件绑定完了,i的值就是2,然后接下来就是你的鼠标触发事件了,触发一次,他会去找i,但是这时候i的值已经是2了,你输出的i是一个变量,(是当前i的值)而不是绑定的时候i的值,绑定的时候是1
3 年多之前 回复
Spotlight_mar
Spotlight_mar 回复当作看不见: 事件绑定是在for循环里面呀?这样也能突破循环条件的限制到达2?
3 年多之前 回复
qq_29594393
当作看不见 你给两个都加一个ID console.log(this.id)就能看到你触发的还是两个不同的元素,但i一直是2
3 年多之前 回复

在for循环中,你给每个container的mouseup事件绑定一个函数,因为是绑定的是函数,他不是立即执行,而是延迟执行的,也就是在真正事件触发的时候才绑定变量。在函数内部调用了变量i,而函数内部没有定义变量i,而且也没有传入参数i,按照Javascript的规则,他会从最近原则查找i,直到找到位置,或者报错未定义变量。虽然循环中止执行了i=0和1,但i其实最后的值是2,因为等于2之后,i < container.length为false,才停止了i++的计算,退出了循环。
所以mouseup事件执行console.log(i) 且i=2

设计到闭包,。。。

       var container = document.getElementsByClassName("container"); 
        console.log(container.length);          //2
        for (var i = 0; i < container.length; i++) {
            container[i].onmouseup = (function (i) {
                return function () {
                    console.log(container)
                    console.log(i)             
                }
            })(i)
        }
Spotlight_mar
Spotlight_mar 外包一层函数是一种可行的方法。不过还是不太明白为什么能大于for循环的限制
3 年多之前 回复

这个类似于函数闭包,i的值在执行完绑定函数后就一直为2,所以触发是都输出2,你改为输出this.innerHTML,会发现不同,但i还是2

首先你是在dom文档中定义的var,所以属于GO链也就是说var定义的基础类型在本方法和子方法中中间无论你改变多少次只会有一个储存起来的也会跟着变化,定义引用的不同,和储存内存有关。你这个代码可以有两种方法改,一种把var改成let,还有一种用闭包在事件和循环外面加一个方法,都可以。let定义的变量只在本循环有效每次循环会自动帮你重新定义一个。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问