【问题标题】:event listener on window doesn't remove [duplicate]窗口上的事件侦听器不会删除[重复]
【发布时间】:2015-12-26 07:15:26
【问题描述】:

我需要删除在窗口上设置的事件侦听器,但它不起作用,侦听器在滚动时不断触发。我试图设置监听器有和没有 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();
            });
    }

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

旁注:有没有比一直删除和添加监听器更好的方法来处理滚动事件?

【问题讨论】:

  • 谢谢@Amit,我已经看到了这个问题和答案。我想我已经在使用命名函数了 - 还是我错过了什么?
  • 是的,你肯定没有抓住重点。你需要remove完全added,也就是说,不是从bind()返回的值,然后包装在另一个调用中。
  • 你试过我的回答了吗,@J.Doe?
  • 哇,谢谢。现在我懂了。 @阿米特。我会关闭它。

标签: javascript event-listener


【解决方案1】:

问题是:当您添加事件侦听器时,浏览器会将您作为参数传递的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 方法,但我不建议您这样做。

【讨论】:

  • 致反对者:您能发表评论解释为什么会这样吗?
  • 可能是因为这个问题应该被关闭,而不是回答。另外,最后一点是覆盖addEventListener,建议不要这样做,所以不要朝自己的脑袋开枪,但最好一开始就不要提及这些想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
  • 2012-07-18
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 2018-09-04
相关资源
最近更新 更多