How to get on scroll events?
Solution 1
// @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
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
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
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
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());
Related videos on Youtube
Natanael
Updated on November 10, 2021Comments
-
Natanael over 2 years
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?
-
AT82 over 7 yearsQuite often you can apply events that as onclick, onsubmit etc. In angular the equivalent is usually just removing the 'on' and adding () from event names. e.g (click), (submit) etc... :)
-
-
Natanael over 7 years(scroll)="onScroll($event)" solved my problem well. Do you know if there's a equivalent binding to onresize of a element?
-
Günter Zöchbauer over 7 yearsNo, browsers don't provide events for resize of elements, only for window resize (
'window:resize'
). You could implementngDoCheck()
and poll the size there. This can be expensive though, therefore if you can rely on less frequent events for polling the size using such an event instead would be preferred. -
gtzinos almost 7 yearsHello, i just used your code in my component and last i added a (scroll)="onScrollEvent($event)" but i doesn't work.
-
Thomas Ducrot almost 7 years(scroll)="onScrollEvent($event)" doesn't work, but my code is currently working on angular version 4.0.0, It triggers the scroll event
-
Katana24 over 6 years@GünterZöchbauer Can you tell from the event which direction the scroll is going? That is without examining and comparing the div scrollY value to the previous?
-
Günter Zöchbauer over 6 yearsdeveloper.mozilla.org/en-US/docs/Web/Events/scroll lists the information provided by the event, which doesn't include anything about direction.
-
blueprintchris almost 6 yearsthis works fine, no need to add
(scroll)="onScrollEvent($event)
in the HTML with this. -
Günay Gültekin over 5 yearsIn addition, This one is worked in Angular 6 --> stackoverflow.com/a/42547136/621951
-
Günter Zöchbauer over 5 years@GünayGültekin this one is to listen to scroll evens from an element, the one you linked to is for scroll events of the page/window.
-
Günter Zöchbauer over 5 years@Dmitry Grinko you don't always want window scroll events. Often you want scroll events from the current component. For example if you build a scrollable list or table component.
-
Mike D3ViD Tyson over 4 yearsremember to add import:
import { HostListener } from '@angular/core';
-
Dominik about 4 yearsHow to listen to an element scroll or "scrollTop" of an element? For example in a directive. Instead of "window". Window scroll only works on the body html scroll.
-
Günter Zöchbauer about 4 yearsSee the last line in my answer above ;-)
-
Nick09 about 4 years
<div (window:scroll)="onWindowScroll($event)">
, clear, easy and works like a charm for me. Thanks mate! -
Sir Papilonius almost 4 yearsHow does setting a constant to a set of or statements work?
-
Stack Underflow about 3 years@SirPapilonius the first one that's not falsy (0 or undefined etc.) will be used as the value.
-
Sir Papilonius about 3 years@StackUnderflow Ah, of course, that makes sense. Didn't think of that. Clever!
-
jcdsr over 2 yearsHowever, is hostlistener the best to use? HostListener leads to excessive change detection as mentioned here. github.com/angular/angular/issues/16986 I do see a performance impact by using hostlistener, is not another way?
-
jcdsr over 2 yearsHostListener leads to excessive change detection as mentioned here. github.com/angular/angular/issues/16986 I do see a performance impact by using hostlistener, is not another way?
-
jcdsr over 2 yearsHostListener leads to excessive change detection as mentioned here. github.com/angular/angular/issues/16986 I do see a performance impact by using hostlistener, is not another way?
-
Günter Zöchbauer over 2 years@jcdsr without diving deeper into the issue and it's a long time ago I answered - usually you want change detection after an event, the main issue is the high frequency of scroll events (or resize events). If you use rxjs, you can use rate limiting and stuff which you can't with
@HostListener()
-
jcdsr over 2 yearsHostListener leads to excessive change detection as mentioned here. github.com/angular/angular/issues/16986 I do see a performance impact by using hostlistener, is not another way?