javascripthtmlcss

Can't use for variable in addEventListener


I have two images of a cat and when I click on the first one the pointer of the first image should switch from pointer to none.

let elements = document.querySelectorAll('.cat');
for (var i = 0; i < elements.length; i++) {

    if (i == 0) {
        elements[i].addEventListener('click', function(event) {
            console.log('Cursor switched');
            document.getElementsByClassName('cat')[0].style.pointerEvents = 'none';
        });
    }

}
.cat {
    height: 100px;
    cursor: pointer;
}
<img class="cat" src="https://i.pinimg.com/564x/c7/83/16/c78316ef3e89429ff0f3dad0265d0da8.jpg">
<img class="cat" src="https://i.pinimg.com/564x/c7/83/16/c78316ef3e89429ff0f3dad0265d0da8.jpg">

It works. But my question is why I can't use document.getElementsByClassName('cat')[i] instead of document.getElementsByClassName('cat')[0] or should I use a completely different code for this?


Solution

  • This is happening because of closures in Javascript. Whenever you define a function i.e., in this case function that is attached on the event listener then it remembers the scope of the function. To fix, you can use let i which is lexical scoped

    let elements = document.querySelectorAll('.cat');
    for (let i = 0; i < elements.length; i++) {
    
        if (i == 0) {
            elements[i].addEventListener('click', (event) => {
                console.log('Cursor switched');
                document.getElementsByClassName('cat')[i].style.pointerEvents = 'none';
            });
        }
    
    }
    .cat {
        height: 100px;
        cursor: pointer;
    }
    <img class="cat" src="https://i.pinimg.com/564x/c7/83/16/c78316ef3e89429ff0f3dad0265d0da8.jpg">
    <img class="cat" src="https://i.pinimg.com/564x/c7/83/16/c78316ef3e89429ff0f3dad0265d0da8.jpg">