Supprimez vos fonctions de délai avant expiration et éliminez leurs bugs. Voici l'événement dont vous avez vraiment besoin : scrollend.
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 lorsque le doigt de l'utilisateur était encore sur l'écran. Cette incertitude quant à la fin du défilement a entraîné des bugs et une mauvaise expérience pour l'utilisateur.
document.onscroll = event => { clearTimeout(window.scrollEndTimer) window.scrollEndTimer = setTimeout(callback, 100) }
Le mieux que puisse faire cette stratégie setTimeout() est de savoir si le défilement s'est arrêté pour 100ms. Il s'agit davantage d'un événement de pause du défilement que d'un événement de fin du défilement.
Après l'événement scrollend, le navigateur effectue toute cette évaluation difficile pour vous.
document.onscrollend = event => {…}
C'est ce qu'il faut. Parfaitement synchronisé et rempli de conditions significatives avant l'émission.
Essayer
Détails de l'événement
L'événement scrollend se déclenche lorsque :
- le navigateur n'anime ni ne traduit plus le défilement ;
- le défilement est terminé.
- L'utilisateur a relâché l'écran.
- Le pointeur de l'utilisateur a relâché le pouce de défilement.
- L'utilisateur a relâché la touche.
- Le défilement jusqu'au fragment est terminé.
- L'alignement sur les points d'arrêt de défilement est terminé.
- scrollTo() est terminé.
- 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 entraîné aucune modification de la position de défilement (aucune translation n'a eu lieu).
- scrollTo() n'a donné lieu à aucune traduction.
L'une des raisons pour lesquelles cet événement a mis autant de temps à arriver sur la plate-forme Web est qu'il fallait spécifier de nombreux petits détails. L'un des domaines les plus complexes consistait à articuler les détails de scrollend pour la fenêtre d'affichage visuelle par rapport au document. Prenons l'exemple d'une page Web sur laquelle vous effectuez un zoom avant. Vous pouvez faire défiler l'écran dans cet état de zoom, mais il ne s'agit pas nécessairement du défilement du document. Sachez que même cette interaction de défilement pilotée par l'utilisateur dans la fenêtre d'affichage visuelle é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
});
ou utilisez 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 vérifier la compatibilité au début de celle-ci avec :
'onscrollend' in window
// true, if available
La valeur "true" ou "false" s'affiche selon que le navigateur propose l'événement. Avec cette vérification, vous pouvez créer une branche du 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éé et qui fait de son mieux pour le navigateur :
import {scrollend} from "scrollyfills"
// then use scrollend as if it's existed this whole time
document.onscrollend = callback
Le polyfill améliorera progressivement l'utilisation de l'événement scrollend intégré au navigateur, le cas échéant. S'il n'est pas disponible, le script surveille les événements de pointeur et le défilement pour estimer au mieux la fin de l'événement.
Cas d'utilisation
Il est recommandé d'éviter les tâches gourmandes en ressources de calcul pendant le défilement. Cette pratique garantit que le défilement est libre d'utiliser autant de mémoire et de traitement que possible pour que l'expérience reste fluide. L'utilisation d'un événement scrollend est le moment idéal pour appeler et effectuer le travail difficile, car le défilement n'a plus lieu.
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 :
- Synchroniser la position de défilement d'un carrousel avec un indicateur de point.
- Synchroniser un élément de galerie avec ses métadonnées.
- Récupération des données après qu'un utilisateur a fait défiler l'écran vers un nouvel onglet.
Imaginez un scénario dans lequel un utilisateur supprime un e-mail en balayant l'écran. 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 mise au point doivent être mis à jour en fonction de la position de défilement. Regardez 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.