如何在JS中使用for循环创建事件侦听器

时间:2018-04-06 02:23:13

标签: javascript for-loop navigation

我正在尝试为纯JS下拉菜单创建事件侦听器。当我尝试使用for循环创建监听器时,我收到错误并且它不起作用,但是当我使用数组手动创建它们时,它们完美地工作。我错过了什么?

var dropDown  = document.getElementsByClassName('nav-sub__mobile-dropdown');
var subNavList  = document.getElementsByClassName('nav-sub__list');


for ( i = 0; i < dropDown.length; i++) {

    dropDown[i].addEventListener('click', function() {
        subNavList[i].classList.toggle('nav-sub__list--active');
    });
}

上述方法不起作用,但如果我使用数组手动创建事件监听器,它确实有效。

dropDown[0].addEventListener('click', function() {
    subNavList[0].classList.toggle('nav-sub__list--active');
});

dropDown[1].addEventListener('click', function() {
    subNavList[1].classList.toggle('nav-sub__list--active');
});

dropDown[2].addEventListener('click', function() {
    subNavList[2].classList.toggle('nav-sub__list--active');
});

当我使用for循环时,我在控制台中收到以下错误代码。

Uncaught TypeError: Cannot read property 'classList' of undefined

更新已解决的问题

我能够解决这个问题,感谢Ben McCormick的评论: JavaScript closure inside loops – simple practical example

解决方案是在for循环中使用let。

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

1 个答案:

答案 0 :(得分:0)

因为当调用click函数时,变量i具有它所持有的最后一个值dropDown.length,而不是调用addEventListener时的循环值。

你想要的是这样的:

for ( i = 0; i < dropDown.length; i++) {
    function addListener(n) {
        dropDown[n].addEventListener('click', function() {
            subNavList[n].classList.toggle('nav-sub__list--active');
        });
    }
    addListener(i);
}