Retour aux articles

Mettre en place un Scroll infini en Javascript

Le scroll infini est une mauvaise expérience d’un point de vue UX design, utilisé principalement par les réseaux sociaux. Cependant, pour des sites ou des applications plus communes, il peut être pertinent de mettre en place le même mécanisme pour des raisons de performance et de temps de chargement. L’API Intersection Observer est désormais supportée par la plupart des navigateurs modernes et permet de mettre cela en place très facilement :

Mise en place du HTML et CSS

Le conteneur est l’élément dans lequel nous rajouterons des articles à chaque fois que l’utilisateur atteindra le bas de la page. Ici nous lui donnons la classe main-scroll.

<main>
  <div class="main-scroll" id="main-scroll">
  </div>
  <div class="main-bottom" id="main-bottom">
  </div>
</main>

L’élément main est positionné en relative et l’élément main-bottom en absolute, en bas de son parent main.

main {
 width: 100%;
 max-width: 500px;
 margin-inline: auto;
 position: relative;
}
.main-scroll {
 padding: 0.5rem;
 display: flex;
 flex-direction: column;
 gap: 0.5rem;
}
.main-bottom {
 position: absolute;
 bottom: 0;
 width: 50%;
 background: transparent;
 height: 200vh;
}

Le but es de déclencher l’ajout de plusieurs articles en bas de main-scroll dès que l’on détecte main-bottom dans la fenêtre ( le viewport ). main-bottom étant positionné en absolute, en bas de main et avec une hauteur de 200vh (200% de la hauteur du viewport ), cette détection aura lieu lorsque l’on se trouve à « 2 hauteurs d’écran » ou moins du bas de main. En faisant comme ça, on ajoute les articles supplémentaires bien avant que l’utilisateur n’atteigne réellement le bas de page, et il ne voit pas les éléments se rajouter, c’est le principe de l’infinite scroll.

Pour mettre en place la détection de main-bottom dans la fenêtre, on utilisera l’API Intersection Observer.

Récupérer des articles

Il faut d’abord mettre en place la fonction asynchrone qui récupèrera des article. Celle-ci sera utilisée par l’observer à chaque détection du bas de page. Ici notre fonction récupère un seule article via un endpoint /article sur le serveur, construit une petite vignette avec les données de l’article et l’ajoute en bas de main-scroll.

const scrollContainer = document.getElementById('main-scroll');

let fetchOneArticle = () =>{
 fetch('/article')
 .then((response) => response.json())
 .then((article) => {
   scrollContainer.innerHTML += '' +
   '<div class="card">' +
     '<img src="' + article.img + '">' +
     '<h2>' + article.title + '</h2>' +
     '<p>' + article.description + '</p>' +
   '</div>';
 })
}

Mettre en place l’observer

Il ne reste plus qu’à mettre en place l’objet observer pour détecter les intersections de la fenêtre et de l’élément main-bottom.


let observer = new IntersectionObserver(
 () => {
  for (let index = 0; index < 5; index++) {
   fetchOneArticle() 
  }
 },
 {threshold: [.1]}
);

const scrollBottom = document.getElementById('main-bottom');
observer.observe(scrollBottom);

L’objet observer prend en premier argument une fonction callback à déclencher à chaque intersection avec l’élément cible, et en deuxième argument un objet de paramètres. Ici, le callback consiste à ajouter 5 articles en bas de main-scroll avec la fonction fetchOneArticle. Le paramètre threshold permet de définir à quels paliers de la détection de l’élément cible le callback doit se déclencher ( ici, il se déclenche lorsqu’il détecte 10% de main-bottom ).

Pour activer l’observer, on appelle la méthode .observe sur l’élément cible. Et voila !