Les IntersectionObservers vous avertissent lorsqu'un élément observé entre dans la fenêtre d'affichage du navigateur ou en sort.
Imaginons que vous souhaitiez effectuer le suivi du moment où un élément de votre DOM entre dans la fenêtre d'affichage visible. Cela peut être utile afin de pouvoir charger des images de manière différée, juste à temps, ou parce que vous avez besoin de savoir si l'utilisateur est réellement en train de regarder une bannière publicitaire en particulier. 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.
Toutefois, cette approche est extrêmement lente, car chaque appel de getBoundingClientRect()
oblige le navigateur à remettre en page la page entière, ce qui entraîne des à-coups considérables sur votre site Web. Lorsque vous savez que votre site est chargé dans un iFrame et que vous voulez savoir quand l'utilisateur peut voir un élément, cela devient presque impossible. Le modèle d'origine unique et le navigateur ne vous permettent pas d'accéder aux données de la page Web qui contient l'iFrame. Il s'agit d'un problème courant pour les annonces fréquemment chargées à l'aide de cadres iFrame.
IntersectionObserver
a été conçu pour rendre ce test de visibilité plus efficace. 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é de l'iFrame](https://web.developers.google.cn/static/articles/intersectionobserver/image/iframe-visibility-45640aaa99537.gif?authuser=6&hl=fr)
Créer un IntersectionObserver
L'API est assez petite et peut être décrite à 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();
En utilisant les options par défaut pour IntersectionObserver
, votre rappel est appelé à la fois lorsque l'élément apparaît partiellement dans la vue et lorsqu'il quitte complètement la fenêtre d'affichage.
Si vous devez observer plusieurs éléments, il est possible et recommandé 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 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 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. L'élément intersectionRatio
est étroitement lié et vous indique la proportion de l'élément qui est visible. Grâce à ces informations, vous pouvez désormais implémenter des fonctionnalités comme le chargement juste-à-temps d'éléments avant qu'ils ne soient visibles à l'écran. Efficacement.
![Taux d'intersections.](https://web.developers.google.cn/static/articles/intersectionobserver/image/intersection-ratio-cc2e11cc70559.png?authuser=6&hl=fr)
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 au rappel fourni est de faible priorité et sera effectué par le navigateur pendant la période d'inactivité. Il s'agit d'une décision de conception consciente.
DIV défilants
Je n'aime pas trop faire défiler un élément, mais je ne suis pas ici pour juger, ni IntersectionObserver
non plus. L'objet options
accepte 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 un ancêtre de tous les éléments observés.
Croisez tout le contenu !
Non ! Mauvais développeur ! Ce n'est pas une utilisation consciente des cycles de processeur de l'utilisateur. 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 une sentinelle proche du dernier élément du conteneur de défilement infini. Lorsque cette sentinelle s'affiche, 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 autre appel à observe()
n'est nécessaire. IntersectionObserver
continue de fonctionner.
![Défilement infini](https://web.developers.google.cn/static/articles/intersectionobserver/image/infinite-scroller-f23f2b90aa6bd.png?authuser=6&hl=fr)
En savoir plus
Comme indiqué précédemment, le rappel est déclenché une fois lorsque l'élément observé apparaît partiellement dans la vue et une autre fois lorsqu'il quitte la fenêtre d'affichage. De cette façon, IntersectionObserver
vous donne 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. Elle vous permet de définir un tableau de seuils intersectionRatio
. Votre rappel sera 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 en informerons chaque fois qu'un quart supplémentaire de l'élément devient visible:
![Animation de seuil.](https://web.developers.google.cn/static/articles/intersectionobserver/image/threshold-animation-818bf785c4e2d.gif?authuser=6&hl=fr)
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 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 (à la "10px 20px 30px 40px"
), en spécifiant respectivement les marges supérieure, droite, inférieure et gauche. En résumé, le 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],
});
<iframe>
magique
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 auraient tout intérêt à savoir s'ils sont bien visibles. Si un <iframe>
observe l'un de ses éléments, le défilement de l'élément <iframe>
et le défilement de la fenêtre contenant <iframe>
déclencheront le rappel aux moments appropriés. Dans ce dernier cas, rootBounds
sera défini sur null
afin d'é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. Leur utilisation pour mettre en œuvre des activités telles que les animations dépendantes du défilement échouera forcément, car les données seront à proprement parler obsolètes au moment où vous pourrez les utiliser. L'explication fournit plus de détails sur les cas d'utilisation d'origine de IntersectionObserver
.
Quelle quantité de travail puis-je effectuer dans le rappel ?
Short 'n Sweet: si vous passez trop de temps dans le rappel, votre application sera retardée. Toutes les pratiques courantes s'appliquent.
Allez et croisez vos éléments
La compatibilité avec IntersectionObserver
est satisfaisante, car tous les navigateurs récents y sont compatibles. Si nécessaire, un polyfill peut être utilisé dans les anciens navigateurs. Il est disponible dans le dépôt WICG. Évidemment, ce polyfill ne vous offrira pas les avantages en termes de performances qu'une implémentation native vous apporterait.
Vous pouvez commencer à utiliser IntersectionObserver
dès maintenant ! Dites-nous ce que vous avez imaginé.