IntersectionObserver en JavaScript : savoir quand un élément entre à l'écran

IntersectionObserver prévient quand un élément entre dans l'écran ou en sort, sans écouter le défilement. Le navigateur fait le calcul à votre place.
3 min de lecture
Believemy logo

Révéler une carte quand elle arrive à l'écran, charger une image au dernier moment, compter les sections réellement lues : trois besoins qui reviennent sur presque toutes les pages longues.

La méthode historique consistait à écouter le défilement et à mesurer des positions à chaque pixel parcouru. Coûteuse, imprécise, et responsable de bien des saccades. Le navigateur sait faire ce calcul lui-même.


Définition

IntersectionObserver surveille le croisement entre un élément et une zone de référence, la fenêtre par défaut. Il appelle une fonction de rappel quand cet élément entre dans la zone ou en sort, sans qu'aucun écouteur de défilement soit nécessaire.

JAVASCRIPT
const observateur = new IntersectionObserver((entrees) => {
  for (const entree of entrees) {
    if (entree.isIntersecting) {
      entree.target.classList.add("visible");
      observateur.unobserve(entree.target);
    }
  }
}, { threshold: 0.25 });

document.querySelectorAll(".carte").forEach((carte) => {
  observateur.observe(carte);
});

Un seul observateur suit autant d'éléments qu'on lui en confie. L'appel à unobserve retire la carte de la surveillance une fois révélée : une animation d'apparition n'a pas à se rejouer.


Les trois options

Le second argument du constructeur règle la sensibilité. Le tableau décrit ses trois options sur trois colonnes : l'option, sa valeur par défaut, et ce qu'elle commande.

OptionPar défautCe qu'elle règle
rootnullLa zone de référence. Vide, c'est la fenêtre du navigateur
rootMargin"0px"Une marge qui agrandit ou rétrécit cette zone
threshold0La part visible de l'élément qui déclenche l'appel

Une marge de "200px 0px" déclenche l'appel deux cents pixels avant l'arrivée réelle, ce qui laisse à une image le temps de se charger. Un seuil accepte aussi un tableau, [0, 0.5, 1], pour être prévenu à plusieurs paliers.


Ce que contient chaque entrée

La fonction de rappel reçoit un tableau, jamais un élément seul : plusieurs éléments peuvent franchir la limite dans la même image.

  • isIntersecting : un Boolean (booléen) qui dit si l'élément croise la zone.
  • target : l'élément concerné, indispensable puisque le tableau en mélange plusieurs.
  • intersectionRatio : la part visible, de 0 à 1.
  • boundingClientRect : les dimensions mesurées, déjà calculées par le navigateur.
Bon à savoir

Les seuils se comparent à la surface visible, pas à la hauteur. Un élément plus grand que la fenêtre n'atteindra jamais un seuil de 1, et l'appel attendu ne viendra pas.


Questions fréquentes

Question

Pourquoi la fonction se déclenche-t-elle dès le chargement ?

Parce que l'observateur signale l'état initial de chaque élément qu'on lui confie, y compris ceux qui sont hors de l'écran. Ces premiers appels portent un isIntersecting à faux, d'où l'importance de tester cette propriété plutôt que de supposer qu'un appel signifie une entrée à l'écran.


Question

Faut-il encore s'en servir pour charger les images ?

Plus vraiment : l'attribut loading="lazy" couvre le cas des images et des cadres intégrés, en une ligne de HTML et sans script. L'observateur garde tout son intérêt pour les animations d'apparition, le défilement infini et la mesure des sections réellement vues.


Question

Comment arrêter la surveillance ?

unobserve retire un élément, disconnect arrête tout d'un coup. Le second appel est indispensable quand un composant disparaît de la page : sans lui, l'observateur garde une référence vers des éléments retirés, qui ne peuvent plus être libérés de la mémoire.

Termes connexes

Découvrez notre glossaire JavaScript

Tous les mots de JavaScript expliqués simplement : mots-clés, objets natifs, méthodes, erreurs et concepts. Définitions claires et exemples qui tournent, pour apprendre et pour se dépanner.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.