JavaScript-说说为啥循环闭包只显示最后一个i的值

循环闭包
不知道这个问题大家有没有遇到过这种情况,for循环过程中永远输出最后一个值。反正我当年初学js的过程中遇到了,当时菜的时候问度娘,博客都差不多,就是看不懂。手动再见。

下面要实现的是,点击两个盒子,点击显示"这是第i个盒子"。
QAQ结果显示无论点击哪个盒子都是"这是第2个盒子"。

//html
<body>
    <div></div>
    <div></div>
</body>

//css
div {
      background: pink;
      width: 100px;
      height: 100px;
      margin-bottom: 10px;
}

//js
var divs = document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
    divs[i].addEventListener("click", function() {
        alert("这是第" + i + "个盒子");
    }, false);
}

在这里插入图片描述

上文代码 - 运行结果

其实仔细看看,就会发现问题。我们点击 div 触发事件,当代码执行到循环的时候,i = 0,1.. 到2跳出循环 这个时候相当于现在 i = 2

问题来了!!!

我只有点击div的时候才能触发alert("这是第" + i + "个盒子");啊! 所以,你无论怎么循环都是没有用的啊~
因为我们没点击啊~

当你点击 div的时候,alert("这是第" + i + "个盒子");中的i就不是循环的时候变量i啊,就只是一个普通的i=2变量啊!

就是说整段for循环就跟我点击事件没太大关系啊~~
我就是给你提供了i=2啊~~

解决办法
1、立即执行函数

var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
    (function(num) {
        divs[i].addEventListener('click', function() {
            alert("这是第" + num + "个盒子");
        }, false);
    })(i);
}

加入一个立即执行函数,注意for (var i = 0; i < divs.length; i++)后面的代码的写法(立即执行函数的写法)。

首先解释一下立即执行函数。

(function(){})();
简写(......)();
第一对括号内是一个函数体(表达式),这对括号仅用于划定表达式的范围;
第二对括号内是一个操作符,表示立即执行上面的表达式;而第二对括号内的值(如果有的话),就是执行上面表达式所需要的参数(也分实参、形参)。

为什么可以这么解决呢~道理就是循环的时候,每次循环都调用了 alert("这是第" + num + "个盒子");事件啊~ 感觉就像提前定义好了,点击哪个div,就弹出对应的。当我真正点击的时候,与之对应的弹出内容就来了,这就是我个人理解的观点。

现在大多数人的博客讲的都很深,对于菜鸟来说确实挺不好理解的。。

比如一个立即执行函数,我第一百度这个问题看到这个解决办法,一头雾水。。

其实写成下面这样应该会稍稍好理解一点。对我是这样子的~
点击事件封装成函数,调用函数。然后效果同上哈哈哈~

var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
    function ss(num) {
        divs[i].addEventListener('click', function() {
            alert(num);
        }, false)
    }
    ss(i);
}

在这里插入图片描述

解决之后随便点击哈哈哈

当然解决办法不光这一种,理解原因之后,一切都好办~

猜你喜欢

转载自blog.csdn.net/weixin_43863327/article/details/89675626