如何处理Angular 4中的窗口滚动事件?
我似乎无法捕捉到窗口滚动事件。在角4.2.2经常如何处理Angular 4中的窗口滚动事件?
@HostListener("window:scroll", [])
onWindowScroll() {
console.log("Scrolling!");
}
的片断来自第2版。这似乎不工作(再): 在几个网站,我发现类似这样的代码。如果我用“window:touchmove”替换“window:scroll”,然后touchmove事件处理正常。
有谁知道我错过了什么?非常感谢你!
也许你的document
不滚动,但它内部是div
。如果从document
调用该滚动事件,则该滚动事件仅起泡至window
。另外,如果您从document
中捕获事件并拨打stopPropagation
之类的东西,则您将不会收到window
中的事件。
如果你想捕捉你的应用程序内的所有滚动事件,这也将是从微小的滚动容器,你必须使用默认的addEventListener
法useCapture
设置为true
。
这会在事件发生时触发DOM
而不是泡泡阶段。不幸的是,很坦率地说大小姐,角度不提供一个选项,在事件监听器选项传递,所以你必须使用addEventListener
:
export class WindowScrollDirective {
ngOnInit() {
window.addEventListener('scroll', this.scroll, true); //third parameter
}
ngOnDestroy() {
window.removeEventListener('scroll', this.scroll, true);
}
scroll =(): void => {
//handle your scroll here
//notice the 'odd' function assignment to a class field
//this is used to be able to remove the event listener
};
}
现在,这是不是所有有它,因为所有的主要的浏览器(IE和Edge除外)已经实现了新的addEventListener
规范,这使得可以传递一个对象为third parameter。
使用此对象可以将事件侦听器标记为passive
。这是一个推荐的事情,这个事件会触发很多时间,这会干扰UI性能,例如滚动事件。要实现这一点,你应该首先检查当前浏览器是否支持这个功能。在mozilla.org上,他们发布了一个方法passiveSupported
,您可以使用它来检查浏览器支持。你只能使用这个,当你确定你不打算使用event.preventDefault()
在我告诉你如何做到这一点之前,还有另一个你可以想到的性能特征。为防止运行中发生变化检测(每次在区域内发生异步事件时都会调用DoCheck
,就像事件触发一样),您应该在区域外运行事件侦听器,并且只有在真正有必要时才会输入事件侦听器。所以,让我们结合所有这些东西:
export class WindowScrollDirective {
private eventOptions: boolean|{capture?: boolean, passive?: boolean};
constructor(private ngZone: NgZone) {}
ngOnInit() {
if (passiveSupported()) { //use the implementation on mozilla
this._eventOptions = {
capture: true,
passive: true
};
} else {
this.eventOptions = true;
}
this.ngZone.runOutsideAngular(() => {
window.addEventListener('scroll', this.scroll, <any>this.eventOptions);
});
}
ngOnDestroy() {
window.removeEventListener('scroll', this.scroll, <any>this.eventOptions);
//unfortunately the compiler doesn't know yet about this object, so cast to any
}
scroll =(): void => {
if (somethingMajorHasHappenedTimeToTellAngular) {
this.ngZone.run(() => {
this.tellAngular();
});
}
};
}
非常感谢你,这似乎按预期工作!我认为这个问题的确是文件本身不会在我的情况下滚动。 – Robert
@Robert我已经用更多信息更新了我的答案:) – PierreDuc
第二个代码块中的侦听器中的内容是否与拦截事件相关?此外,如何确定滚动的方向? –