【Javascript】for循环中的绑定事件为什么要用this

先来看一段代码:

<div class="box">
    <ul>
        <li>
            <img src="images/4.jpg" alt="">
        </li>
        <li>
            <img src="images/9.jpg" alt="">
        </li>
        <li>
            <img src="images/11.jpg" alt="">
        </li>
    </ul>
</div>
var lis = document.querySelector('.box').querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
    lis[i].onclick = function () {
        //console.log(i);
        console.log(lis[i]);
    }
}

按照我们书写的逻辑,应该点击哪个li标签,就在控制台打印对应的标签,但是不论我们点击哪一个标签,控制台都打印undefined

我们把console.log(lis[i]); 注释掉,换成 console.log(i); 发现:不论我们点击哪一个标签,控制台都打印3。这是为什么呢?

分析一下代码执行过程:

因为JS中点击事件为异步函数,JS会先执行那些非异步函数(同步函数)。也就是说,for循环会先循环三次,分别给第0,1,2个li标签注册了一个onlick事件。第四遍循环开始时i=3,不符合i<3的条件,因此终止循环。

注意: 此时只是注册了一个空事件,并不会执行点击事件,也就是并没有执行后面的function部分,而是会等待点击事件触发时才执行。也就是说,当我们点击按钮,触发点击事件的时候,for循环已经进行了三次,i值已经变成了3,且i值在整个for循环里都有效。

此时当我们点击某个标签时,触发了对应的事件执行程序,也就是执行后面function的内容console.log(i);,比如当点击第一个li标签时,执行的其实是:

lis[0].onclick = function () {
    console.log(i);
}

而这个时候i值等于3,所以控制台打印的是3,而不论点击哪个标签,事件执行程序都是console.log(i);,这时i值一直等于3,所以不论我们点击哪一个标签,控制台都打印3

同理,事件执行程序为console.log(lis[i]); 时,lis数组没有lis[3],数组溢出,所以打印undefined

循环只是给每个标签注册了一个空的onclick事件,并不负责执行部分(因为一开始没有点击),当点击标签时执行对应的事件程序,这时候已经和for循环没关系了

将lis[i]改为this:

var lis = document.querySelector('.box').querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
    lis[i].onclick = function () {
        console.log(this);
    }
}

this指向的是当前事件函数的调用者,用this的话,才能保证点击事件是指向当前标签的。比如当点击第一个li标签时,执行的其实是:

lis[0].onclick = function () {
    console.log(this);
}

此时this指向的就是lis[0],从而可以进行相应的操作。

分别点击每个li标签,控制台打印情况如下:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值