Scrollend, un nouvel événement JavaScript

Supprimez vos fonctions de délai avant expiration et débarrassez-vous de leurs bugs. Voici l'événement dont vous avez vraiment besoin : "scrollend".

Adam Argyle
Adam Argyle

Avant l'événement scrollend, il n'existait aucun moyen fiable de détecter qu'un défilement était terminé. Cela signifiait que les événements se déclenchaient tardivement ou alors que le doigt de l'utilisateur était toujours sur l'écran. Cette imprécision pour savoir quand le défilement a réellement pris fin a entraîné des bugs et une mauvaise expérience pour l'utilisateur.

Avant
document.onscroll = event => {
  clearTimeout(window.scrollEndTimer)
  window.scrollEndTimer = setTimeout(callback, 100)
}

Le mieux que cette stratégie setTimeout() puisse faire est de savoir si le défilement s'est arrêté pour 100ms. Il s'agit donc plus d'un événement de défilement mis en pause que d'un événement de défilement terminé.

Après l'événement scrollend, le navigateur effectue toutes ces évaluations difficiles à votre place.

Après
document.onscrollend = event => {…}

C'est bien. Ils sont parfaitement synchronisés et remplis de conditions pertinentes avant d'être émis.

Navigateurs pris en charge

  • Chrome: 114.
  • Edge: 114.
  • Firefox: 109.
  • Safari: non compatible.

Source

Essayer

Détails de l'événement

L'événement scrollend se déclenche lorsque : - Le navigateur n'anime plus ni ne traduit plus le défilement. - Le contact de l'utilisateur a été relâché. - Le pointeur de l'utilisateur a relâché le curseur de défilement. - La touche de l'utilisateur a été relâchée. - Le défilement jusqu'au fragment est terminé. - L'ancrage de défilement est terminé. - scrollTo() est terminée. - L'utilisateur a fait défiler la fenêtre d'affichage visuelle.

L'événement scrollend ne se déclenche pas dans les cas suivants : - Le geste d'un utilisateur n'a pas entraîné de modification de la position de défilement (aucune traduction n'a été effectuée). - scrollTo() n'a généré aucune traduction.

La raison pour laquelle cet événement a mis si longtemps à arriver sur la plate-forme Web est due aux nombreux petits détails qui nécessitaient des spécifications détaillées. L'un des aspects les plus complexes a été d'articuler les détails scrollend pour le Visual Viewport par rapport au document. Imaginons une page Web sur laquelle vous faites un zoom avant. Vous pouvez faire défiler l'écran dans cet état de zoom, mais cela ne fait pas nécessairement défiler le document. Sachez que même cette interaction de défilement visuelle pilotée par l'utilisateur émettra l'événement scrollend une fois terminée.

Utiliser l'événement

Comme pour les autres événements de défilement, vous pouvez enregistrer des écouteurs de plusieurs manières.

addEventListener("scrollend", (event) => {
  // scroll ended
});

aScrollingElement.addEventListener("scrollend", (event) => {
  // scroll ended
});

Vous pouvez également utiliser la propriété d'événement:

document.onscrollend = (event) => {
  // scroll ended
};

aScrollingElement.onscrollend = (event) => {
  // scroll ended
};

Polyfills et amélioration progressive

Si vous souhaitez utiliser ce nouvel événement dès maintenant, voici nos meilleurs conseils. Vous pouvez continuer à utiliser votre stratégie de fin de défilement actuelle (si vous en avez une) et au début, vérifier la compatibilité avec:

'onscrollend' in window
// true, if available

La valeur renvoyée sera "true" ou "false" selon que le navigateur propose l'événement. Avec cette vérification, vous pouvez créer une branche de code:

if ('onscrollend' in window) {
  document.onscrollend = callback
}
else {
  document.onscroll = event => {
    clearTimeout(window.scrollEndTimer)
    window.scrollEndTimer = setTimeout(callback, 100)
  }
}

C'est un bon début pour améliorer progressivement votre événement scrollend lorsqu'il sera disponible. Vous pouvez également essayer un polyfill (NPM) que j'ai créé pour que le navigateur fonctionne au mieux:

import {scrollend} from "scrollyfills"

// then use scrollend as if it's existed this whole time
document.onscrollend = callback

Le polyfill s'améliorera progressivement pour utiliser l'événement scrollend intégré au navigateur, le cas échéant. Si elle n'est pas disponible, le script surveille les événements de pointeur et le défilement pour obtenir la meilleure estimation possible de la fin de l'événement.

Cas d'utilisation

Il est recommandé d'éviter les tâches de calcul lourdes pendant le défilement. Cette pratique garantit que le défilement peut utiliser autant de mémoire et de traitement que possible pour assurer une expérience fluide. L'utilisation d'un événement scrollend est le moment idéal pour appeler et effectuer le travail difficile, car le défilement ne se produit plus.

L'événement scrollend peut être utilisé pour déclencher différentes actions. Un cas d'utilisation courant consiste à synchroniser les éléments d'interface utilisateur associés avec la position à laquelle le défilement s'est arrêté. Par exemple : - Synchronisation de la position de défilement d'un carrousel avec un indicateur en forme de point. - Synchroniser un élément de galerie avec ses métadonnées. - Récupération de données après qu'un utilisateur a fait défiler un nouvel onglet.

Imaginons qu'un utilisateur balaie un e-mail. Une fois le balayage terminé, vous pouvez effectuer l'action en fonction de l'endroit où l'utilisateur a fait défiler l'écran.

Vous pouvez également utiliser cet événement pour la synchronisation après un défilement programmatique ou utilisateur, ou pour des actions telles que la journalisation des données analytiques.

Voici un bon exemple où plusieurs éléments tels que les flèches, les points et la sélection doivent être mis à jour en fonction de la position de défilement. Découvrez comment j'ai créé ce carrousel sur YouTube. Vous pouvez également essayer la démo en direct.

Merci à Mehdi Kazemi pour son travail d'ingénierie et à Robert Flack pour ses conseils sur l'API et l'implémentation.