How to get on scroll events?

HtmlCssAngularTypescriptScrollbar

Html Problem Overview


I need to get scroll events from a div with overflow: scroll in my Angular 2 app.

It seems onscroll event do not works on Angular 2.

How could I achieve that?

Html Solutions


Solution 1 - Html

// @HostListener('scroll', ['$event']) // for scroll events of the current element
@HostListener('window:scroll', ['$event']) // for window scroll events
onScroll(event) {
  ...
}

or

<div (scroll)="onScroll($event)"></div>

Solution 2 - Html

You could use a @HostListener decorator. Works with Angular 4 and up.

import { HostListener } from '@angular/core';

@HostListener("window:scroll", []) onWindowScroll() {
    // do some stuff here when the window is scrolled
    const verticalOffset = window.pageYOffset 
          || document.documentElement.scrollTop 
          || document.body.scrollTop || 0;
}

Solution 3 - Html

for angular 4, the working solution was to do inside the component

@HostListener('window:scroll', ['$event']) onScrollEvent($event){
  console.log($event);
  console.log("scrolling");
} 

Solution 4 - Html

Listen to window:scroll event for window/document level scrolling and element's scroll event for element level scrolling.

window:scroll

@HostListener('window:scroll', ['$event'])
onWindowScroll($event) {

}

or

<div (window:scroll)="onWindowScroll($event)">

scroll

@HostListener('scroll', ['$event'])
onElementScroll($event) {

}

or

<div (scroll)="onElementScroll($event)">

@HostListener('scroll', ['$event']) won't work if the host element itself is not scroll-able.

Examples

Solution 5 - Html

Alternative to @HostListener and scroll output on the element I would suggest using fromEvent from RxJS since you can chain it with filter() and distinctUntilChanges() and can easily skip flood of potentially redundant events (and change detections).

Here is a simple example:

// {static: true} can be omitted if you don't need this element/listener in ngOnInit
@ViewChild('elementId', {static: true}) el: ElementRef;

// ...

fromEvent(this.el.nativeElement, 'scroll')
  .pipe(
    // Is elementId scrolled for more than 50 from top?
    map((e: Event) => (e.srcElement as Element).scrollTop > 50),
    // Dispatch change only if result from map above is different from previous result
    distinctUntilChanged());

Solution 6 - Html

To capture scroll events and see which of the scroll event is being called, you have to use host listener who will observe the scroll behavior and then this thing will be detected in the function below the host listener.

currentPosition = window.pageYOffset;
@HostListener('window:scroll', ['$event.target']) // for window scroll events
scroll(e) {
  let scroll = e.scrollingElement.scrollTop;
  console.log("this is the scroll position", scroll)
  if (scroll > this.currentPosition) {
    console.log("scrollDown");
  } else {
    console.log("scrollUp");
  }
  this.currentPosition = scroll;
}

Solution 7 - Html

Check the multiple examples as mention on this URL.

I will recommend the method 3,

https://itnext.io/4-ways-to-listen-to-page-scrolling-for-dynamic-ui-in-angular-ft-rxjs-5a83f91ee487

    @Component({
        selector       : 'ngx-root',
        templateUrl    : './app.component.html',
        styleUrls      : [ './app.component.scss' ],
        changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class AppComponent implements OnDestroy {
        
        destroy = new Subject();
        
            destroy$ = this.destroy.asObservable();
        
        constructor() {
            fromEvent(window, 'scroll').pipe(takeUntil(this.destroy$))
                .subscribe((e: Event) => console.log(this.getYPosition(e)));
            }
        
            getYPosition(): number {
            return (e.target as Element).scrollTop;
            }

        ngOnDestroy(): void {
            this.destroy.next();
        }
        
    }

However Method 4 is not bad.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNatanaelView Question on Stackoverflow
Solution 1 - HtmlGünter ZöchbauerView Answer on Stackoverflow
Solution 2 - HtmlUliana PavelkoView Answer on Stackoverflow
Solution 3 - HtmlThomas DucrotView Answer on Stackoverflow
Solution 4 - HtmlkodebotView Answer on Stackoverflow
Solution 5 - HtmlmetodribicView Answer on Stackoverflow
Solution 6 - HtmlAsad FiazView Answer on Stackoverflow
Solution 7 - HtmljcdsrView Answer on Stackoverflow