Intersection Observer éléments de piste défilant dans la vue

«Observateur d'intersection» permet d'observer de manière asynchrone les changements d'intersection (chevauchement) d'éléments. Cela peut être en relation avec d'autres éléments ou la fenêtre. Dans cet article, nous examinerons quelques démos et discuterons de la pertinence future d'Intersection Observer pour les développeurs Web. Je partagerai également des exemples de code pour vous aider à démarrer pour ces sessions d'expérimentation tardives. Plongeons dedans!

Que peut faire l'observateur d'intersection??

le IntersectionObserver L'API vous permet d'enregistrer une fonction de rappel qui est exécutée chaque fois qu'un élément surveillé entre ou sort d'un autre élément ou de la fenêtre de visualisation.. 

Ce document explicatif du W3C sur GitHub regorge d’idées et de suggestions, mais Intersection Observer peut être utile pour créer de manière native des fonctionnalités telles que:

  • Chargement paresseux
  • Défilé interminable
  • Rapport de visibilité / emplacement
  • Exécution d'animations

Regardez cette démo de Dan Callahan pour clarifier ce dont nous parlons:

Pour commencer avec IntersectionObserver explorons les étapes de codage appropriées requises. Vous pouvez toujours vous assurer que vos navigateurs / appareils prévus prennent en charge l'API IO en référençant caniuse. Nous allons commencer par créer un observateur et discuter de la manière dont il peut être utilisé pour surveiller les composants.

Créer un observateur

 IntersectionObserver commence par exiger un groupe d'options défini en tant que littéral d'objet et transmis en tant qu'argument à votre objet observateur défini.

let options = root: null, // par rapport à la fenêtre de visualisation du document rootMargin: '0px', // marge autour de la racine. Les valeurs sont similaires à la propriété css. Valeurs sans unité non autorisées seuil: 1.0 // quantité visible d'élément affichée par rapport à la racine; let observer = new IntersectionObserver (rappel, options);

Ces options de l'observateur sur les lignes 2 à 4 dicteront quelques détails importants en ce qui concerne la détection de la visibilité d'un élément cible par rapport à la racine. Le premier argument de l'objet observateur (dernière ligne) représente un rappel (fonction) exécuté lorsque les conditions requises sont remplies par votre observateur. Le deuxième argument fait référence à notre littéral d'objet contenant les options de l'observateur et accepte les propriétés suivantes:

  • racine: L'élément que vous souhaitez tester l'intersection. Une valeur de nul fait référence à la fenêtre d'affichage du navigateur. Vous pouvez également transmettre des méthodes de sélecteur DOM telles que document.querySelector ('# mytargetobject').
  • racine de marge: Si vous devez agrandir ou réduire la taille effective de l’élément racine avant de calculer les intersections. Ces valeurs transmises sont similaires au CSS marge propriété. Si la racine l'élément est spécifié, les valeurs peuvent être des pourcentages.
  • seuil: Soit un nombre unique, soit un tableau de nombres indiquant le pourcentage de visibilité de la cible qui déclenche le rappel de l'observateur. Une valeur de 1,0 signifie que le seuil n'est considéré comme dépassé que lorsque tous les pixels sont visibles, alors que 0 signifie que l'élément est complètement invisible..

Comme je l'ai déjà mentionné, vous allez gérer l'argument de rappel en créant une fonction contenant une logique personnalisée en fonction des besoins de votre projet. Cette logique est exécutée chaque fois qu'un ou plusieurs éléments observés sont visibles par rapport à l'élément racine défini..

function onChange (modifications, observateur) // la logique va ici let observateur = nouvel IntersectionObserver (onChange, options);

La logique de la fonction de votre observateur peut être constituée d'événements tels que le chargement d'images, l'ajout / la suppression de classes ou le contrôle de visibilité, mais vous pouvez choisir ce qui peut être fait de l'intérieur en fonction de vos besoins et de vos objectifs..

Chaque fois que l'observateur détecte un changement, un changements événement est rapporté (un peu comme un une fonction() signaler un objet événement) à partir du rappel de l'observateur. En utilisant cet événement déclenché, nous pouvons vérifier la visibilité de notre élément par rapport à la racine avant d'exécuter toute logique supplémentaire en détectant des propriétés sur le disque. changement un événement. Certains développeurs vont remplacer changements avec le mot les entrées au lieu de cela, mais les deux approches fonctionnent de la même manière.

function onChange (changements, observateur) changes.forEach (change => if (change.intersectionRatio> 0) // votre logique d'observateur); 

Cette boucle indique "Pour chaque changement détecté, vérifiez si l'élément cible est actuellement visible (supérieur à 0) par rapport à la racine définie." Le rapport d'intersection aide à indiquer le pourcentage d'éléments visibles visible en utilisant une valeur comprise entre 0.0 (non visible) et 1.0 (entièrement visible). Vous pouvez penser au rapport d'intersection comme le seuil propriété définie dans les options de votre observateur.

La méthode Observe

Jusqu'à présent, nous avons créé un objet options, une fonction de rappel et défini un objet observateur, mais nous n'avons toujours rien à observer. C’est là que la méthode Observer entrera en service.

let images = document.querySelectorAll ('img'); images.forEach (img => observateur.observer (img));

Cette méthode ajoute un élément à l’ensemble des éléments cibles surveillés par le IntersectionObserver. Dans cet exemple, j'observe chaque image de la page à l'aide des résultats obtenus à partir du images référence du sélecteur. le observer() La méthode continuera à surveiller une cible jusqu’à ce que l’une des situations suivantes se produise: inaperçu () ou déconnecter () les méthodes sont appelées avec l'élément cible ou la racine de l'intersection supprimé. Si vous n’avez plus besoin d’observer un élément, appelez le inaperçu () et passez votre cible comme argument.

Condition de support

Si vous avez besoin de tester le support de cette API, vous pouvez tout inclure dans une si/autre déclaration conditionnelle comme ceci:

if ('IntersectionObserver' dans la fenêtre) // pris en charge sinon // non pris en charge

Étant donné que l’API Intersection Observer se trouve toujours à un stade de travail préliminaire, je vous encourage à détecter les la fenêtre objet, ou vous pouvez également trouver des polyfills si vous préférez.

Exemples en direct

La démo suivante contient tout le code dont j'ai parlé jusqu'à présent avec quelques ajustements supplémentaires. Cette démo paresseuse charge les images lorsqu'elles affichent 50% de leur visibilité par rapport à la fenêtre d'affichage..

Vous remarquerez peut-être un comportement différent en ce qui concerne le image éléments par rapport à la img éléments dans Chrome et Firefox. Les deux navigateurs se chargent image éléments parfaitement, mais image ignore notre seuil même avec des contraintes de taille absolue définies. Ils semblent se charger lorsqu'ils sont à environ 10% en vue par rapport au seuil de 50% défini dans la démo. Laissez un commentaire ci-dessous si vous remarquez cette anomalie ou si vous avez rencontré des problèmes avec IntersectionObserver et image Plus précisément.

Voici une autre démonstration créant un scénario de défilement infini dans lequel lazy charge l'imagerie en utilisant Ajax pour charger l'imagerie au besoin.

Dans ce scénario, j'insère une sentinelle dans le DOM en tant que cible observée. Cette sentinelle est placée à côté du dernier élément du défilement infini. Lorsque la sentinelle apparaît, le rappel charge les données, crée le ou les éléments suivants, les attache au DOM et les repositionne. Si vous recyclez correctement la sentinelle, aucun appel supplémentaire à observer() sont requis. Voici un excellent diagramme de l'équipe de développeurs Google pour vous aider à expliquer visuellement cette approche..

Une note sur l'imagerie

Quand un img élément avec une contrainte de largeur maximale: 100% est observé, il ne parviendra pas à charger. Cela signifie que toute image chargée paresseusement doit avoir des contraintes définies dans le CSS ou en ligne en conséquence. image les éléments dépourvus de contraintes sont la taille zéro avant le chargement de leur contenu; ce qui signifie qu'ils intersectent la fenêtre simultanément lorsque vous faites défiler. Je soupçonne getBoundingClientRect () fait partie de la raison car c'est l'une des méthodes principales pour obtenir les coordonnées et les contraintes d'un élément.

Conclusion

Utilises-tu IntersectionObserver dans votre propre travail juste cette minute? Êtes-vous enthousiasmé par cette fonctionnalité et ses possibilités? Pourrait IntersectionObserver remplacer le besoin de fonctionnalités événementielles telles que position: collant? Personnellement, j'estime que cette nouvelle API est un ajout solide à nos spécifications et j'attends avec impatience sa croissance continue au cours des prochaines années.. 

J'ai inclus quelques liens utiles ci-dessous et vous encourage à plonger plus profondément dans votre temps libre. Chaque lien vous aidera à mieux comprendre le fonctionnement et les fonctions de cette nouvelle API. Si vous avez des conseils ou des astuces pour les autres lecteurs, laissez-les dans les commentaires ci-dessous. Comme toujours, codage heureux!

Liens

  • LazyLoad (vanilla-lazyload)
  • Exemples d'observateur d'intersection
  • Chargement paresseux d'images à l'aide d'un observateur d'intersection par Dean Hume
  • Exemple IntersectionObserver
  • Intersection Observer API sur mozilla.org
  • Chargement paresseux d'images avec Intersection Observer par Cory Dowdy
  • Utilisation de l'API Intersection Observer pour déclencher des animations et des transitions sur Alligator.io
  • IntersectionObserver's View par Surma