js 循环监听

为什么取不到id

<body>
    <ul>
        <li id="li_8" style="border: 1px solid red;">1</li>
        <li id="li_5" style="border: 1px solid red;">2</li>
        <li id="li_10" style="border: 1px solid red;">3</li>
    </ul>
</body>
<script>
    var li = document.querySelectorAll("li");
    for(var i = 0; i < li.length; i++){
        li[i].addEventListener('click',function(){
            alert(li[i].getAttribute('id'));
        });
    }
</script>
阅读 6.1k
10 个回答

别用for 用foreach

[].forEach.call(document.querySelectorAll("li"),function(elem,i){
    elem.addEventListener('click',function(){
        console.log(this.getAttribute('id'));
    });
});

楼主可以试下打印出i哈哈!

同楼上,建议foeach

var lis = document.querySelectorAll("li");
lis.forEach(function(item,index) {
    item.onclick = function() {
        alert(index);    
    }
})    

经典的闭包问题

var li = document.querySelectorAll("li");
for(var i = 0; i < li.length; i++){
    li[i].addEventListener('click', (function(){
        return function(){alert(li[i].getAttribute('id'));}
    })());
}

var li = document.querySelectorAll("li");
for(var i = 0; i < li.length; i++){
    li[i].addEventListener('click',function(){
        alert(this.getAttribute('id'));
    });
}

你给每个li添加了一个事件监听并委托了一个处理函数,问题就出在这个处理函数上。

这个函数体内使用了外面定义的变量i,i是很尴尬的,它被这个函数需要,所以不能销毁,所以它就一直在原地等待那个需要它的函数来调用它,但是等这些函数需要它的时候,它已经不是那时的它了。因为它是会变的!

简单来说,这里的事件处理程序直到点击事件的发生才会执行。需要闭包。
建议看一编《javascript高级程序设计》

这是一个典型的变量提升问题,通过闭包解决,楼上提到的forEachAPI实际上就创造了一个闭包

哎,请用事件委托好嘛,这就是典型的不该用闭包非要用闭包的例子。

最后的i等于li的长度,但是li数组里面没有下标为它的长度的元素,因此获取不到.

使用闭包解决

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题