Escuchar el evento scroll en Angular es más sencillo de lo que parece. Te voy a explicar las distintas maneras que te ofrece Angular para conseguirlo con apenas 2 líneas de código.
Scroll dentro de un componente
Imagina que tienes un elemento cuyo contenido es mayor que su altura, de forma que puedes hacer scroll en su interior. Vamos a llamar a este elemento <scrollable-component>
.
Angular te ofrece 2 formas muy sencillas para atender a ese evento scroll del componente.
Tip: Para que un componente entienda que se está haciendo scroll en su interior, es necesario que su propiedad CSS
display
sea tipo block-level, es decir:block
,inline-block
,grid
oflex
.
1) suscripción externa, desde el template padre
Puedes atender ese evento de scroll desde fuera del componente, es decir, desde su componente padre.
Solo necesitas usar un event binding sobre su propiedad scroll, como si de un click se tratara. Así:
<scrollable-component (scroll)="doSomethingOnScroll($event)">
<item></item>
<item></item>
<!-- some more items -->
</scrollable-component>
De este modo, cuando estés haciendo scroll dentro de <scrollable-component>
, se llamará al método doSomethingOnScroll()
del componente que lo contiene.
2) suscripción interna, desde el componente
Puedes suscribirte al evento de scroll del componente desde su propio controlador, usando un HostListener
. Así:
import { Component, HostListener } from '@angular/core';
@Component({
selector: 'scrollable-component',
templateUrl: './scrollable.component.html',
styleUrls: ['./scrollable.component.css']
})
export class ScrollableComponent {
@HostListener("scroll", ['$event'])
doSomethingOnInternalScroll($event:Event){
let scrollOffset = $event.srcElement.scrollTop;
console.log("scroll: ", scrollOffset);
}}
}
De este modo, a cada evento de scroll del componente ScrollableComponent, se ejecutará el método doSomethingOnInternalScroll()
.
Componentes Angular Nivel PRO
Evento scroll global
Hasta ahora veías como suscribirte a un evento de scroll limitado a un componente, pero por supuesto, podrías querer escuchar el evento scroll global, el típico window.scroll
, para que nos entendamos.
Angular te da acceso al evento scroll global de forma análoga a los dos ejemplos anteriores, mediante
window:scroll
.
De este modo puedes:
1) Suscribirte a window:scroll
desde el template
Se me hace un poco extraño, pero puedes suscribirte desde un elemento cualquiera del template, así:
<div (window:scroll)="doSomethingOnWindowScroll($event)">
</div>
<!-- some more stuff -->
2) Suscribirte a window:scroll
desde el componente
Para mi esta opción tiene bastante más sentido: Suscribirte con un @HostListener
desde el componente en que quieres escuchar el evento de scroll global:
import { Component, HostListener } from '@angular/core';
@Component({
selector: 'my-component',
templateUrl: './my.component.html',
styleUrls: ['./my.component.css']
})
export class MyComponent {
@HostListener("window:scroll", ['$event'])
doSomethingOnWindowsScroll($event:Event){
let scrollOffset = $event.srcElement.children[0].scrollTop;
console.log("window scroll: ", scrollOffset);
}
}
Reflexiones personales
Angular te ofrece de partida unos mecanismos muy sencillos para escuchar eventos de scroll. ¿Pero que pasa si quieres reducir la frecuencia con la que se llama el evento? Ahí amigo, la cosa se complica.
En próximos artículos explicaré como crear un servicio de scroll con debouncing para evitar interrupciones demasiado frecuentes durante el scroll.
¿Te ha gustado este artículo? No te cortes, déjame un comentario y ayúdame a compartirlo 😉