Découvrez "IntersectionObserver"

IntersectionObservers vous permet de savoir quand un élément observé entre dans la fenêtre d'affichage du navigateur ou en sort.

Navigateurs pris en charge

  • 51
  • 15
  • 55
  • 12.1

Source

Supposons que vous souhaitiez savoir quand un élément de votre DOM entre dans la fenêtre d'affichage visible. Cela peut être utile pour charger des images juste à temps ou pour savoir si l'utilisateur consulte réellement une bannière publicitaire donnée. Pour ce faire, vous pouvez associer l'événement de défilement ou utiliser un minuteur périodique et appeler getBoundingClientRect() sur cet élément.

Cependant, cette approche est terriblement lente, car chaque appel à getBoundingClientRect() oblige le navigateur à remettre en page la page entière, ce qui entraîne des à-coups considérables sur votre site Web. Les litiges sont quasiment impossibles lorsque vous savez que votre site est chargé dans un iFrame et que vous souhaitez savoir quand l'utilisateur peut voir un élément. Le modèle d'origine unique et le navigateur ne vous permettent d'accéder à aucune donnée de la page Web contenant l'iFrame. Il s'agit d'un problème courant pour les annonces qui sont fréquemment chargées à l'aide de cadres iFrame.

IntersectionObserver a été conçu pour améliorer l'efficacité de ce test de visibilité. Il est disponible dans tous les navigateurs récents. IntersectionObserver vous indique quand un élément observé entre dans la fenêtre d'affichage du navigateur ou en sort.

Visibilité des cadres iFrame

Créer une IntersectionObserver

L'API est relativement petite. Nous vous la recommandons à 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é lorsque l'élément est partiellement visible et qu'il quitte complètement la fenêtre d'affichage.

Si vous avez besoin d'observer plusieurs éléments, il est possible et conseillé d'en observer plusieurs à 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 des é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 de la fonction getBoundingClientRect() sur l'élément observé. intersectionRect est l'intersection de ces deux rectangles et vous indique efficacement quelle partie de l'élément observé est visible. intersectionRatio est étroitement lié et indique quelle partie de l'élément est visible. Grâce à ces informations, vous pouvez désormais mettre en œuvre des fonctionnalités comme le chargement juste à temps des assets avant qu'ils ne soient visibles à l'écran. de manière efficace.

Ratio d'intersection

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

Balises div de défilement

Je n'aime pas beaucoup faire défiler un élément, mais je ne suis pas ici pour en juger, et IntersectionObserver non plus. L'objet options utilise une option root qui vous permet de définir une alternative à la fenêtre d'affichage en tant que racine. Il est important de garder à l'esprit que root doit être l'ancêtre de tous les éléments observés.

Entrecroisez toutes les choses !

Non ! Mauvais développeur ! Il ne s'agit pas d'une utilisation consciente des cycles de processeur de l'utilisateur. Prenons l'exemple d'un conteneur de défilement infini. Dans ce cas, il est fortement conseillé d'ajouter des sentinelles au DOM, puis de les observer (et de les recycler). Vous devez ajouter une sentinelle proche du dernier élément de la zone de défilement infinie. Lorsque cette sentinelle apparaît, vous pouvez utiliser le rappel pour charger des données, créer les éléments suivants, les associer au DOM et repositionner la sentinelle en conséquence. Si vous recyclez correctement la sentinelle, aucun appel supplémentaire à observe() n'est nécessaire. IntersectionObserver continue de fonctionner.

Défilement infini

Plus d'informations s'il vous plaît

Comme indiqué précédemment, le rappel est déclenché une seule fois lorsque l'élément observé est partiellement visible et une autre fois lorsqu'il a quitté la fenêtre d'affichage. De cette façon, IntersectionObserver répond à la question "L'élément X est-il visible ?". Toutefois, dans certains cas d'utilisation, cela peut ne pas suffire.

C'est là que l'option threshold entre en jeu. Elle 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 vous remplacez threshold par [0, 0.25, 0.5, 0.75, 1], nous serons avertis chaque fois qu'un quart supplémentaire de l'élément deviendra visible:

Animation de seuil.

Avez-vous d'autres options ?

Pour l'instant, il n'existe qu'une seule option supplémentaire par rapport à celles listées ci-dessus. rootMargin vous permet de spécifier les marges de la racine, ce qui vous permet d'agrandir 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, "10px 20px 30px 40px", en spécifiant les marges supérieure, droite, inférieure et gauche respectivement. En résumé, la structure 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],
});

<iframe> magique

Les IntersectionObserver ont été conçus spécifiquement pour les services publicitaires et les widgets de réseaux sociaux, car ils utilisent fréquemment des éléments <iframe> et il serait utile de savoir s'ils sont visibles. Si un <iframe> observe l'un de ses éléments, le fait de faire défiler le <iframe> et de faire défiler la fenêtre contenant le <iframe> déclenchera le rappel aux moments appropriés. Toutefois, dans le dernier cas, rootBounds est défini sur null pour éviter les fuites de données entre les origines.

Qu'est-ce que IntersectionObserver ne sert pas ?

Notez que IntersectionObserver n'offre intentionnellement ni la précision du pixel, ni une faible latence. Leur utilisation pour implémenter des activités telles que les animations dépendantes du défilement risque d'échouer, car les données seront, pour résumer, obsolètes au moment où vous les utiliserez. Vous trouverez plus d'informations sur les premiers cas d'utilisation de IntersectionObserver dans l'explication.

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

Short 'n Sweet: votre application ralentit si vous passez trop de temps dans le rappel. Toutes les pratiques courantes s'appliquent.

Allez-y et croisez vos éléments

La compatibilité de IntersectionObserver avec le navigateur est satisfaisante, car elle est disponible dans tous les navigateurs récents. Si nécessaire, un polyfill peut être utilisé dans les navigateurs plus anciens et est disponible dans le référentiel du WICG. Évidemment, vous n'obtiendrez pas les avantages de performances d'utilisation de ce polyfill qu'une implémentation native vous apporterait.

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