Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why undefined in the function of addEventListener? [duplicate]

I'm trying to add a mouseenter event listener to elements to change their childnodes' opacity. I use for to add the listener, and can output the childnodes properly, but in the function it's "undefined". I have no idea why.

HTML:

<article class="index-image-article rel">
    <section class="index-image-info">
        // some elements
     </section>
     <div class="index-image-excerpt mask table">
         // some elements
     </div>
</article>

Javascript:

var indexImageArticle = document.querySelectorAll(".index-image-article");
var indexImageInfo = document.querySelectorAll(".index-image-info");
var indexImageExcerpt = document.querySelectorAll(".index-image-excerpt");

for(var i = 0; i < indexImageArticle.length; i++) {
    console.log(indexImageInfo[i]); // output properly
    indexImageArticle[i].addEventListener("mouseenter", function() {
        indexImageInfo[i].style.opacity = 1;
        indexImageExcerpt[i].style.opacity = 0;
    });
}

the output of console.log is:

<section class=​"index-image-info">​…​</section>​
<section class=​"index-image-info">​…​</section>​
<section class=​"index-image-info">​…​</section>​
<section class=​"index-image-info">​…​</section>

and the error:

Uncaught TypeError: Cannot read property 'style' of undefined(anonymous function)

​the undefined point to the indexImageInfo[i]

like image 558
Brick Yang Avatar asked Oct 28 '25 18:10

Brick Yang


1 Answers

This is one of those strange nuances of variable scoping rules in javascript.

Really this boils down to one thing, at the point of adding the event handler, i has the right value. At the point of executing the event handler i has been incremented up to indexImageArticle.length, and is therefore outside of the bounds of the array.

It can be fixed by using a block which maintains the scope of the variable, a IIFE is one way:

for(var i = 0; i < indexImageArticle.length; i++) {
    console.log(indexImageInfo[i]); // output properly
    (function(x){
        indexImageArticle[x].addEventListener("mouseenter", function() {
            indexImageInfo[x].style.opacity = 1;
            indexImageExcerpt[x].style.opacity = 0;
        });
    })(i)
}
like image 59
Jamiec Avatar answered Oct 31 '25 09:10

Jamiec



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!