您可以在角度区域之外运行此功能,以防止冗余的变化检测循环。
为此,我将覆盖 EventManager 以将侦听器保持在区域之外。
custom-event-manager.ts
import { Injectable, Inject, NgZone } from '@angular/core';
import { EVENT_MANAGER_PLUGINS, EventManager } from '@angular/platform-browser';
@Injectable()
export class CustomEventManager extends EventManager {
constructor(@Inject(EVENT_MANAGER_PLUGINS) plugins: any[], private zone: NgZone) {
super(plugins, zone);
}
addGlobalEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
if(eventName.endsWith('out-zone')) {
eventName = eventName.split('.')[0];
return this.zone.runOutsideAngular(() =>
super.addGlobalEventListener(element, eventName, handler));
}
return super.addGlobalEventListener(element, eventName, handler);
}
}
app.module.ts
...
providers: [
{ provide: EventManager, useClass: CustomEventManager }
]
})
export class AppModule {}
并且只能通过调用changeDetector.detectChanges来更新视图
@HostListener('window:scroll.out-zone', []) // notice out-zone
onWindowScroll() {
const scrolledPercent = /* some logic to calculate the percentage scrolled */
if ( condition1 && condition2 .... ) {
this.cd.detectChanges();
}
}
Plunker Example
另见