javascript - 关于js批量绑定事件的问题
迷茫
迷茫 2017-04-11 12:04:54
[JavaScript讨论组]
<body>  
<ul id="list">  
<li>1</li>  
<li>2</li>  
<li>3</li>  
<li>4</li>  
<li>5</li>  
</ul>  
<script>  
var list_obj = document.getElementsByTagName('li');  
for (var i = 0; i <= list_obj.length; i++) {        
  list_obj[i].onclick = function() {      
    alert(i);      
  }  
}  
</script>  
</body>  

for循环绑定完事件最后执行的时候都是最后一个事件相同,点击的时候弹出的不是0 1 2 3 4,而是5,这是为什么呢 如何解决

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回复(7)
巴扎黑

当调用onclick事件的时候,会向上找到i对象的值。这个时候,由于已经循环完毕,所以i的值是5

解决方法:

闭包

for (var i = 0; i <= list_obj.length; i++) {
  list_obj[i].onclick = (function(i){
    return function() {  alert(i); }
  })(i);  
} 

ES6

for (let i = 0; i <= list_obj.length; i++) {        
  list_obj[i].onclick = function() {      
    alert(i);      
  }  
}  
PHP中文网

js闭包问题,当上述代码执行完时,i的值为5,因为鼠标点击事件是异步的,发生在代码执行之后,此时执行回调函数时,函数并没有保存i这个变量的值,它会通过闭包即作用域链向上获取i值,所以得到的都是5
如果想弹出0,1,2,3,4,可将使用匿名函数创建作用域,代码如下:

 list_obj[i].onclick = (function(x) {      
    alert(x);      
 })(i)  
巴扎黑

用闭包把绑定时的i值hold住就能解决这个问题了...这是JS中常出错的典型问题...

阿神

楼主好好看一下 JavaScript 中的闭包

巴扎黑

因为是触发onclick事件的时候才回去执行function,而此时的function等同于

function(){
    //此时的i为5,所以
    alert("5")
}
天蓬老师

http://es6.ruanyifeng.com/#do...

天蓬老师

for (var i = 0; i <= list_obj.length; i++)

TO

for (let i = 0; i <= list_obj.length; i++)

给你举个例子,最好自己复制下试试。

<html>
<head></head>
<body>

<p name="dvTest" style="width: 100px; height: 50px; background-color: #ff0000"></p> 
<p name="dvTest" style="width: 100px; height: 50px; background-color: #00ff00"></p> 
<p name="dvTest" style="width: 100px; height: 50px; background-color: #0000ff"></p> 
<p></p>
<p name="dvTest2" style="width: 100px; height: 50px; background-color: #ff0000"></p> 
<p name="dvTest2" style="width: 100px; height: 50px; background-color: #00ff00"></p> 
<p name="dvTest2" style="width: 100px; height: 50px; background-color: #0000ff"></p> 

<script>
    var dvTest = document.getElementsByName('dvTest');
    var dvTest2 = document.getElementsByName('dvTest2');

    for(let i=0; i<dvTest.length; i++)
    {
        dvTest[i].onmouseover=function()
        {
             console.log(i);
         }
    }


    for(var k=0; k<dvTest2.length; k++)
    {
        dvTest2[k].onmouseover=function()
        {
             console.log(k);
         }
    }



</script>
</body>
</html>

你比较一下let和var来定义for中变量的不同。鼠标滑过前三个色块,看浏览器调试窗口的输出。再滑过后三个色块看看输出什么。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号