Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional class not always triggers on Angular 2

Tags:

angular

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;
}
like image 614
Gerald Hughes Avatar asked Feb 13 '26 03:02

Gerald Hughes


1 Answers

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.

like image 74
Günter Zöchbauer Avatar answered Feb 14 '26 15:02

Günter Zöchbauer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!