窗口上的事件侦听器不会删除

时间:2015-09-28 23:21:36

标签: javascript event-listener

我需要删除窗口上设置的事件监听器,但它不起作用,监听器继续触发滚动。我试图设置有和没有lodash的油门的听众,但它没有任何区别。这是我的代码:

setupListener() {
    window.addEventListener('resize', _.throttle(this.handler.bind(this), 750));
    window.addEventListener('scroll', _.throttle(this.handler.bind(this), 750));
}

removeListener() {
    window.removeEventListener('resize', _.throttle(this.handler.bind(this), 750));
    window.removeEventListener('scroll', _.throttle(this.handler.bind(this), 750));
    window.addEventListener('load', this.handler.bind(this), false);
}

static isElementInViewport (el) {
    let rect = el.getBoundingClientRect();
    return (
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
}

handler() {
    if (this.options.url === undefined) {throw new Error('no url specified');}
    if (InfiniteScroll.isElementInViewport(this.elementToWatch)) {
        this.removeListener();
        this[this.options.transport]();
    }
}

我也试图宣传删除:

handler() {
    if (this.options.url === undefined) {throw new Error('no url specified');}
    if (InfiniteScroll.isElementInViewport(this.elementToWatch)) {
        Promise.resolve(this.removeListener())
            .then(val => {
                this[this.options.transport]();
            });
    }
}

也没有任何区别。

稍后在代码中,我想重新分配监听器:

handleResponse(data) {
        console.log('handleResponse' + data);
        Promise.resolve(this.addElementsToDOM(data))
            .delay(1000)
            .then(() => {
                this.page++;
                this.elementToWatch = document.getElementById(this.element).rows[document.getElementById(this.element).rows.length - this.options.loadTiming];
                //this.setupListener();
            });
    }

我已记录了每一步,我无法找到原因。有人可以帮忙吗?

旁注:是否有更好的方法来处理滚动事件,而不是一直删除和添加监听器?

1 个答案:

答案 0 :(得分:5)

事情是:当您添加事件监听器时,浏览器会将其保存为其关键字&#39;您作为参数传递的function引用。因此,当您想要删除它时,您必须发送该引用。

有两种方法可以解决您的问题。第一个是创建命名函数:

setupListener() {
  this.listener = function() {
    _.throttle(this.handler.bind(this), 750);
  }.bind(this);

  window.addEventListener('resize', this.listener);
  window.addEventListener('scroll', this.listener);
}

removeListener() {
  window.removeEventListener('resize', this.listener);
  window.removeEventListener('scroll', this.listener);
  window.addEventListener('load', this.handler.bind(this), false);
}

另一种方法是覆盖Window的addEventListener方法,但我不建议你这样做。