Mettre en place un Scroll infini en Javascript
3 décembre 2022
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 !