我正在尝试为纯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++) {
答案 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);
}