Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript ES6 addEventListener inside Class

I am learning ES6 and I don't understand why my addEventListener not working (trigger only one time) when I use a function like this :

// Trigger only one time
window.addEventListener("scroll", this.scroll() );

But when I do this :

// working !!
window.addEventListener("scroll", (e) => {
    let top = window.pageYOffset;

    console.log(top + " vs " + this.offsetTop)

    if (top >= this.offsetTop) {
        this.el.classList.add('is-sticky');
    } else {
        this.el.classList.remove('is-sticky');
    }

});

The full code can be find here : https://codepen.io/paallaire/pen/GQLzmg/?editors=0010#0

like image 660
Lofka Avatar asked Mar 04 '18 03:03

Lofka


1 Answers

The statement:

window.addEventListener("scroll", this.scroll() );

Binds to the event the result of this.scroll(), which is a function call. Such invocation returns undefined, because the scroll method has no return statement:

scroll() {
    let top = window.pageYOffset;
    console.log(top + " vs " + this.offsetTop);

    if (top >= this.offsetTop) {
        this.el.classList.add('is-sticky');
    } else {
        this.el.classList.remove('is-sticky');
    }
}

Correct way

Do NOT use:

window.addEventListener("scroll", this.scroll);

The code above will bind the this to window when the event triggers.

The CORRECT way to use is really:

window.addEventListener("scroll", (e) => {
   this.scroll();
});

Or

window.addEventListener("scroll", this.scroll.bind(this));

Which, when the event is triggered, will have the code inside this.scroll have the this point to the current class (Sticky) instance.


Removing the event listener

To remove the event, call window.removeEventListener, but there's a caveat: removeEventListener must be called with the exact same argument used in addEventListener to remove the listener. In other words, to be able to remove you will have to do:

// save the function that will be bound to the event, so you can remove it later
this.scrollBoundFunction = this.scroll.bind(this);
window.addEventListener("scroll", this.scrollBoundFunction);

// and later
window.removeEventListener("scroll", this.scrollBoundFunction);
like image 93
acdcjunior Avatar answered Sep 19 '22 10:09

acdcjunior