类内的Javascript ES6 addEventListener

Lof*_*fka 2 javascript dom-events ecmascript-6 es6-class

我正在学习ES6,但我不明白为什么当我使用这样的函数时,为什么addEventListener不起作用(仅触发一次):

// Trigger only one time
window.addEventListener("scroll", this.scroll() );
Run Code Online (Sandbox Code Playgroud)

但是当我这样做时:

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

});
Run Code Online (Sandbox Code Playgroud)

完整的代码可以在这里找到:https : //codepen.io/paallaire/pen/GQLzmg/?editors=0010#0

acd*_*ior 5

该声明:

window.addEventListener("scroll", this.scroll() );
Run Code Online (Sandbox Code Playgroud)

将事件的结果绑定到事件this.scroll(),这是一个函数调用。此类调用返回undefined,因为该scroll方法没有return语句:

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');
    }
}
Run Code Online (Sandbox Code Playgroud)

正确的方法

不使用:

window.addEventListener("scroll", this.scroll);
Run Code Online (Sandbox Code Playgroud)

上面的代码将在事件触发时将绑定thiswindow

正确的使用方法实际上是:

window.addEventListener("scroll", (e) => {
   this.scroll();
});
Run Code Online (Sandbox Code Playgroud)

要么

window.addEventListener("scroll", this.scroll.bind(this));
Run Code Online (Sandbox Code Playgroud)

当事件触发时,其中的代码this.scrollthis指向当前的class(Sticky)实例。


删除事件监听器

要删除该事件,请致电window.removeEventListener,但有一个警告:removeEventListener必须使用addEventListener与删除侦听器相同的参数来调用它。换句话说,要删除您必须执行以下操作:

// 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);
Run Code Online (Sandbox Code Playgroud)