Découvrez "IntersectionObserver"

Les IntersectionObservers vous indiquent quand un élément observé entre ou sort de la fenêtre d'affichage du navigateur.

Navigateurs pris en charge

  • Chrome: 51
  • Edge: 15
  • Firefox : 55.
  • Safari : 12.1.

Source

Imaginons que vous souhaitiez effectuer le suivi du moment où un élément de votre DOM entre dans la fenêtre d'affichage visible. Vous pouvez le faire pour charger les images de manière différée au bon moment ou parce que vous devez savoir si l'utilisateur regarde réellement une certaine bannière publicitaire. Pour ce faire, associez l'événement de défilement ou utilisez un minuteur périodique et appelez getBoundingClientRect() sur cet élément.

Toutefois, cette approche est extrêmement lente, car chaque appel à getBoundingClientRect() oblige le navigateur à recomposer l'intégralité de la page et introduit des à-coups considérables sur votre site Web. Les litiges sont presque impossibles lorsque vous savez que votre site est chargé dans un iFrame et que vous voulez savoir quand l'utilisateur peut voir un élément. Le modèle d'origine unique et le navigateur ne vous permettent pas d'accéder aux données de la page Web contenant l'iFrame. Il s'agit d'un problème courant pour les annonces, par exemple, qui sont fréquemment chargées à l'aide d'iFrames.

C'est pour rendre ce test de visibilité plus efficace que IntersectionObserver a été conçu. Il est disponible dans tous les navigateurs modernes. IntersectionObserver vous indique quand un élément observé entre ou sort de la fenêtre d'affichage du navigateur.

Visibilité de l'iFrame

Créer une IntersectionObserver

L'API est plutôt petite et se décrit mieux à l'aide d'un exemple :

const io = new IntersectionObserver(entries => {
  console.log(entries);
}, {
  /* Using default options. Details below */
});

// Start observing an element
io.observe(element);

// Stop observing an element
// io.unobserve(element);

// Disable entire IntersectionObserver
// io.disconnect();

Avec les options par défaut de IntersectionObserver, votre rappel est appelé à la fois lorsque l'élément apparaît partiellement et lorsqu'il quitte complètement la fenêtre d'affichage.

Si vous avez besoin d'observer plusieurs éléments, il est possible et conseillé d'observer plusieurs éléments à l'aide de la même instance IntersectionObserver en appelant observe() plusieurs fois.

Un paramètre entries est transmis à votre rappel, qui est un tableau d'objets IntersectionObserverEntry. Chacun de ces objets contient des données d'intersection mises à jour pour l'un de vos éléments observés.

🔽[IntersectionObserverEntry]
    time: 3893.92
    🔽rootBounds: ClientRect
        bottom: 920
        height: 1024
        left: 0
        right: 1024
        top: 0
        width: 920
    🔽boundingClientRect: ClientRect
    // ...
    🔽intersectionRect: ClientRect
    // ...
    intersectionRatio: 0.54
    🔽target: div#observee
    // ...

rootBounds est le résultat de l'appel de getBoundingClientRect() sur l'élément racine, qui est la fenêtre d'affichage par défaut. boundingClientRect est le résultat de l'appel getBoundingClientRect() sur l'élément observé. intersectionRect est l'intersection de ces deux rectangles. Il indique quelle partie de l'élément observé est visible. intersectionRatio est étroitement lié et indique la quantité de l'élément visible. Grâce à ces informations, vous pouvez désormais implémenter des fonctionnalités telles que le chargement juste-à-temps des éléments avant qu'ils ne deviennent visibles à l'écran. efficacement.

Rapport d'intersection.

Les IntersectionObserver transmettent leurs données de manière asynchrone, et votre code de rappel s'exécute dans le thread principal. De plus, la spécification indique que les implémentations IntersectionObserver doivent utiliser requestIdleCallback(). Cela signifie que l'appel de votre rappel fourni est de faible priorité et sera effectué par le navigateur pendant les périodes d'inactivité. Il s'agit d'une décision de conception consciente.

Éléments div à défilement

Je n'aime pas trop le défilement dans un élément, mais je ne suis pas là pour juger, et IntersectionObserver non plus. L'objet options accepte une option root qui vous permet de définir une alternative au viewport comme racine. Il est important de garder à l'esprit que root doit être un ancêtre de tous les éléments observés.

Intersecter tous les éléments

Non ! Mauvais développeur ! Ce n'est pas une utilisation réfléchie des cycles de processeur de vos utilisateurs. Prenons l'exemple d'un conteneur à défilement infini: dans ce cas, il est vivement conseillé d'ajouter des sentinelles au DOM et de les observer (et de les recycler !) Vous devez ajouter un élément sentinelle près du dernier élément du défilement infini. Lorsque cette balise apparaît, vous pouvez utiliser le rappel pour charger les données, créer les éléments suivants, les associer au DOM et repositionner la balise en conséquence. Si vous recyclez correctement la sentinelle, aucun appel supplémentaire à observe() n'est nécessaire. Le IntersectionObserver continue de fonctionner.

Scroller infini

Plus d'informations, s'il vous plaît

Comme indiqué précédemment, le rappel ne sera déclenché qu'une seule fois lorsque l'élément observé apparaîtra partiellement et une autre fois lorsqu'il quittera la fenêtre d'affichage. IntersectionObserver vous donne ainsi la réponse à la question "L'élément X est-il visible ?". Toutefois, dans certains cas d'utilisation, cela peut s'avérer insuffisant.

C'est là que l'option threshold entre en jeu. Il vous permet de définir un tableau de seuils intersectionRatio. Votre rappel est appelé chaque fois que intersectionRatio croise l'une de ces valeurs. La valeur par défaut de threshold est [0], ce qui explique le comportement par défaut. Si nous remplaçons threshold par [0, 0.25, 0.5, 0.75, 1], nous recevons une notification chaque fois qu'un quart supplémentaire de l'élément devient visible :

Animation de seuil.

Avez-vous d'autres options ?

Pour le moment, il n'existe qu'une seule option supplémentaire par rapport à celles listées ci-dessus. rootMargin vous permet de spécifier les marges pour la racine, ce qui vous permet d'augmenter ou de réduire la zone utilisée pour les intersections. Ces marges sont spécifiées à l'aide d'une chaîne de style CSS (à la "10px 20px 30px 40px"), en spécifiant respectivement les marges supérieure, droite, inférieure et gauche. Pour résumer, la struct d'options IntersectionObserver propose les options suivantes :

new IntersectionObserver(entries => {/* … */}, {
  // The root to use for intersection.
  // If not provided, use the top-level document's viewport.
  root: null,
  // Same as margin, can be 1, 2, 3 or 4 components, possibly negative lengths.
  // If an explicit root element is specified, components may be percentages of the
  // root element size.  If no explicit root element is specified, using a
  // percentage is an error.
  rootMargin: "0px",
  // Threshold(s) at which to trigger callback, specified as a ratio, or list of
  // ratios, of (visible area / total area) of the observed element (hence all
  // entries must be in the range [0, 1]).  Callback will be invoked when the
  // visible ratio of the observed element crosses a threshold in the list.
  threshold: [0],
});

Magie <iframe>

Les IntersectionObserver ont été conçus spécifiquement pour les services publicitaires et les widgets de réseaux sociaux, qui utilisent fréquemment des éléments <iframe> et peuvent avoir besoin de savoir s'ils sont visibles. Si un <iframe> observe l'un de ses éléments, le défilement de l'<iframe> et le défilement de la fenêtre contenant l'<iframe> déclenchent le rappel aux moments appropriés. Dans le dernier cas, cependant, rootBounds sera défini sur null pour éviter les fuites de données entre les origines.

Quel sujet ne concerne pas IntersectionObserver ?

Il convient de garder à l'esprit que IntersectionObserver n'est pas intentionnellement parfait ni une faible latence. Les utiliser pour implémenter des tâches telles que des animations dépendant du défilement sont vouées à l'échec, car les données seront, à proprement parler, obsolètes au moment où vous les utiliserez. La vidéo explicative fournit plus d'informations sur les cas d'utilisation d'origine de IntersectionObserver.

Quelle quantité de travail puis-je effectuer dans le rappel ?

Court 'n Sweet: si vous passez trop de temps dans le rappel, votre application sera retardée. Toutes les pratiques courantes s'appliquent.

Avance et croise tes éléments

La compatibilité des navigateurs avec IntersectionObserver est bonne, car elle est disponible dans tous les navigateurs modernes. Si nécessaire, un polyfill peut être utilisé dans les anciens navigateurs et est disponible dans le dépôt de la W3C. Évidemment, vous ne bénéficierez pas des avantages de performances que vous auriez avec une implémentation native.

Vous pouvez commencer à utiliser IntersectionObserver dès maintenant. Dites-nous ce que vous avez trouvé.