0

I am trying to create event listeners for a pure JS dropdown menu. When I try to create the listeners using a for loop I get an error and it doesn't work, but when I create them manually using arrays they work perfectly. What am I missing?

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');
    });
}

The above doesn't work, but if I create the event listeners manually using the arrays it does work.

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');
});

When I use the for loop I get the following error code in my console.

Uncaught TypeError: Cannot read property 'classList' of undefined

UPDATE SOLVED PROBLEM

I was able to solve the problem using let thanks to Ben McCormick's comment here: JavaScript closure inside loops – simple practical example

The solution was to simply use let in the for loop.

for (let i = 0; i < dropDown.length; i++) {
zcleft
  • 103
  • 2
  • 8
  • Put your eventlistener code in function(i) {} block for ( i = 0; i < dropDown.length; i++) { function (i) { dropDown[i].addEventListener('click', function() { subNavList[i].classList.toggle('nav-sub__list--active'); }); } } – Sivakumar Tadisetti Apr 06 '18 at 02:41

1 Answers1

0

Because when the click function is called, the variable i has the last value it held, dropDown.length, not the loop value at the time addEventListener was called.

What you want is something like this:

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);
}
kshetline
  • 12,547
  • 4
  • 37
  • 73