Issue
I have the following snippet which works fine on Chrome, Edge, but no so well on some versions of IE 11 and Firefox.
On some versions of IE 11, not always the class gets set, and on Firefox it has some delay.
Any ideas how to do this better?
// TS
this.scrollYSub = Observable.fromEvent(window, 'scroll')
.throttleTime(5)
.subscribe(e => {
this.scrollY = window.scrollY || document.documentElement.scrollTop;
});
// HTML
<nav id="nav" [class.fixednav]="scrollY >= 245">
/* CSS */
.fixednav {
position: fixed;
top: 95px;
}
Solution
As far as I know the scroll event doesn't run inside Angulars zone in all browsers because of limitations of the polyfills.
constructor(private cdRef:ChangeDetectorRef /* or private zone:NgZone */) {}
this.scrollYSub = Observable.fromEvent(window, 'scroll')
.throttleTime(5)
.subscribe(e => {
this.scrollY = window.scrollY || document.documentElement.scrollTop;
this.cdRef.detectChanges();
// or
/*
this.zone.run(() {
this.scrollY = window.scrollY || document.documentElement.scrollTop;
});
*/
});
If the code only changes local properties of the current component, this.cdRef.detectChanges();
is usually the better way.
If the code also calls methods that cause changes in other components or services the zone.run(...)
approach is preferred because it runs change detection in the whole application, instead of only the current component.
An alternative way would be
scroll = new Subject();
@HostListener('window:scroll', ['$event'])
onScroll(event) {
this.scroll.next(event);
}
because this way ensures the event handler is executed inside Angulars zone.
Answered By - Günter Zöchbauer
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.