Solna Centrum, Stockholm, Sweden, Dimosthenis Papamichail on Unsplash Solna Centrum, Stockholm, Sweden, Dimosthenis Papamichail on Unsplash

Directive personnalisée scroll-to-top avec Angular CLI

Les directives dans Angular sont des class JS déclarées par le décorateur @Directive. On peut définir ses propres directives pour attribuer des comportements spécifiques à des éléments du DOM. Voici un exemple de directive personnalisée pour instancier un scroll-to-top avec Angular CLI.

Pré-requis

Vous devez disposer d'un environnement Angular CLI.

Génération de la directive

Dans la console, saisir la commande suivante :

$ ng generate directive scroll-to-top

2 fichiers sont créés :

  • scroll-to-top.directive.ts
  • scroll-to-top.directive.spec.ts

Et la directive est ajoutée au fichier app.modules.ts.
Voici le fichier scroll-to-top.directive.ts généré :

import { Directive } from "@angular/core";

@Directive({
selector: "[appScrollToTop]"
})
export class ScrollToTopDirective {
constructor() {}
}

Codage de la directive

On importe ElementRef pour pouvoir atteindre l'élément choisi et le décorateur @HostListener pour positionner les écouteurs.

import { Directive, HostListener, ElementRef } from "@angular/core";

On utilise le constructor pour définir le comportement du bouton scrolltop.
La variable position est exprimée en pixels. C'est la distance de scroll du body à partir de laquelle va apparaître le bouton.

private position = 167;

constructor(private elementView: ElementRef) {
if (document.documentElement.scrollTop > this.position || document.body.scrollTop > this.position) {
this.elementView.nativeElement.style.opacity = 1;
} else {
this.elementView.nativeElement.style.opacity = 0;
}
}

On met en place maintenant les écouteurs sur les événements click et window:scroll.
Notre fichier complet :

// scroll-to-top.directive.ts
import { Directive, HostListener, ElementRef } from "@angular/core";

@Directive({
selector: "[appScrollToTop]"
})
export class ScrollToTopDirective {
private position = 167;

constructor(private elementView: ElementRef) {
if (
document.documentElement.scrollTop > this.position ||
document.body.scrollTop > this.position
) {
this.elementView.nativeElement.style.opacity = 1;
} else {
this.elementView.nativeElement.style.opacity = 0;
}
}

@HostListener("click") onclick() {
document.body.scrollTop = 0; // For Safari
document.documentElement.scrollTo({
top: 0,
behavior: "smooth"
}); // For Chrome, Firefox, IE and Opera
}

@HostListener("window:scroll") scrolling() {
if (
document.documentElement.scrollTop > this.position ||
document.body.scrollTop > this.position
) {
this.elementView.nativeElement.style.opacity = 1;
} else {
this.elementView.nativeElement.style.opacity = 0;
}
}
}

Il faut maintenant définir quelques propriétés CSS à minima : positionnement, z-index et transition.

/* CSS */
.btn_scroll-top {
bottom: 64px;
position: fixed;
right: 1rem;
transition: opacity 0.25s ease-in-out;
z-index: 1000;
}

Maintenant nous pouvons utiliser cette directive dans le template HTML en appliquant le selecteur à l'élément choisi.

<!-- HTML -->
<a appScrollToTop class="btn_scroll-top" title="Haut de page">top</a>

Liens