我需要删除窗口上设置的事件监听器,但它不起作用,监听器继续触发滚动。我试图设置有和没有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();
});
}
我已记录了每一步,我无法找到原因。有人可以帮忙吗?
旁注:是否有更好的方法来处理滚动事件,而不是一直删除和添加监听器?
答案 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
方法,但我不建议你这样做。