2023-11-09 10:10 Temps de lecture : 9 min

Comment implémenter le défilement infini dans une application Web

Défilement infini : Une expérience de navigation fluide

Le défilement infini, contrairement à la pagination classique, permet un chargement continu du contenu au fur et à mesure que l'utilisateur explore la page. Cette technique améliore l'expérience utilisateur, en particulier sur les appareils mobiles, en offrant une navigation plus intuitive et sans interruption.

Ce guide vous expliquera comment intégrer le défilement infini à l'aide de HTML, CSS et JavaScript.

Mise en place de la structure HTML

Pour commencer, définissons la structure HTML de base qui accueillera votre contenu. Voici un exemple :

<div class="products__list">
    <img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg" />
    <img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg" />
    <img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg" />
    <img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg" />
    <img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg" />
    <img src="https://fakestoreapi.com/img/71li-ujtlUL._AC_UX679_.jpg" />
</div>

Ce fragment HTML affiche une série d'images de substitution et fait référence à un fichier CSS pour la mise en page et un fichier JavaScript pour la fonctionnalité de défilement infini. Ces liens vers des ressources externes sont retirés, étant donné qu'il s'agit d'une démonstration de code.

Stylisation CSS du contenu à défilement

Pour organiser les images dans une grille, nous appliquons les styles CSS suivants. Ces règles définissent l'aspect visuel des éléments, notamment la mise en page en grille, les marges et l'indicateur de chargement :

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  font-size: 62.5%;
}

body {
  font-family: Cambria, Times, "Times New Roman", serif;
}

h1 {
  text-align: center;
  font-size: 5rem;
  padding: 2rem;
}

img {
  width: 100%;
  display: block;
}

.products__list {
  display: flex;
  flex-wrap: wrap;
  gap: 2rem;
  justify-content: center;
}

.products__list > * {
  width: calc(33% - 2rem);
}

.loading-indicator {
  display: none;
  position: absolute;
  bottom: 30px;
  left: 50%;
  background: #333;
  padding: 1rem 2rem;
  color: #fff;
  border-radius: 10px;
  transform: translateX(-50%);
}

Après l'application de ces styles, la page devrait afficher une grille d'images centrée.

Implémentation JavaScript de base

Pour activer le défilement infini, le script JavaScript doit détecter quand l'utilisateur atteint le bas de la page. Voici comment procéder :

"use strict";

window.addEventListener("scroll", () => {
  if (
    window.scrollY + window.innerHeight >=
    document.documentElement.scrollHeight - 100
  ) {
    fetchMoreContent();
  }
});

Ensuite, créons une fonction pour obtenir de nouvelles données. Nous utiliserons l'API fakestoreapi pour obtenir des images de démonstration :

async function fetchMoreContent() {
  try {
    let response = await fetch("https://fakestoreapi.com/products?limit=3");

    if (!response.ok) {
      throw new Error("La requête réseau a échoué");
    }

    let data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("Erreur lors de la récupération du contenu :", error);
  } finally {
    console.log("Fonction fetch exécutée");
  }
}

La console affichera les données récupérées lors du défilement. Pour éviter de surcharger le navigateur avec des requêtes multiples, nous introduisons une variable de contrôle de l'état :

 let isFetching = false; 

Nous modifions la fonction `fetchMoreContent` pour que les données soient récupérées seulement une fois une requête précédente terminée :

async function fetchMoreContent() {
  if (isFetching) return;

  isFetching = true;

  try {
    let response = await fetch("https://fakestoreapi.com/products?limit=3");

    if (!response.ok) {
      throw new Error("La requête réseau a échoué");
    }

    let data = await response.json();
  } catch (error) {
    console.error("Erreur lors de la récupération du contenu :", error);
  } finally {
    console.log("Fonction fetch exécutée");
    isFetching = false;
  }
}

Afficher le nouveau contenu

Pour afficher les nouvelles images lors du défilement, ajoutons une fonction qui les ajoute au conteneur parent :

 const productsList = document.querySelector(".products__list"); 

Voici la fonction d'ajout du contenu :

function displayNewContent(data) {
  data.forEach((item) => {
    const imgElement = document.createElement("img");
    imgElement.src = item.image;
    imgElement.alt = item.title;
    productsList.appendChild(imgElement);
  });
}

Nous mettons à jour la fonction fetch pour appeler cette fonction :

async function fetchMoreContent() {
  if (isFetching) return;

  isFetching = true;

  try {
    let response = await fetch("https://fakestoreapi.com/products?limit=3");

    if (!response.ok) {
      throw new Error("La requête réseau a échoué");
    }

    let data = await response.json();
    displayNewContent(data);
  } catch (error) {
    console.error("Erreur lors de la récupération du contenu :", error);
  } finally {
    console.log("Fonction fetch exécutée");
    isFetching = false;
  }
}

Le défilement infini est maintenant fonctionnel.

Pour améliorer l'expérience utilisateur, ajoutons un indicateur de chargement.

 <h1 class="loading-indicator">Chargement...</h1> 

Sélectionnez l'indicateur :

 const loadingIndicator = document.querySelector(".loading-indicator"); 

Créons deux fonctions pour gérer l'affichage de l'indicateur :

function showLoadingIndicator() {
  loadingIndicator.style.display = "block";
  console.log("Chargement...");
}

function hideLoadingIndicator() {
  loadingIndicator.style.display = "none";
  console.log("Chargement terminé.");
}

Enfin, intégrons ces fonctions à la fonction fetch :

async function fetchMoreContent() {
  if (isFetching) return;

  isFetching = true;
  showLoadingIndicator();

  try {
    let response = await fetch("https://fakestoreapi.com/products?limit=3");

    if (!response.ok) {
      throw new Error("La requête réseau a échoué");
    }

    let data = await response.json();
    displayNewContent(data);
  } catch (error) {
    console.error("Erreur lors de la récupération du contenu :", error);
  } finally {
    console.log("Fonction fetch exécutée");
    hideLoadingIndicator();
    isFetching = false;
  }
}

Voici quelques recommandations :

  • Évitez de charger trop d'éléments en même temps pour ne pas surcharger le navigateur.
  • Utilisez une fonction de "debounce" pour retarder légèrement le chargement lors du défilement, réduisant ainsi les requêtes réseau inutiles.
  • Proposez une option de pagination classique en plus du défilement infini.
  • Informez clairement l'utilisateur lorsqu'il n'y a plus de contenu à charger.

Maîtriser le chargement fluide du contenu

Le défilement infini améliore l'expérience utilisateur, en particulier sur les appareils mobiles. En appliquant les conseils ci-dessus, vous pourrez facilement intégrer cette fonctionnalité sur vos sites Web. N'oubliez pas de toujours placer l'expérience utilisateur au premier plan, en fournissant des retours visuels clairs à chaque étape du chargement.

Auteur
France

Rédacteur tech, guides pratiques et astuces numériques.