Intersection Observer v2 permet non seulement d'observer les intersections en tant que telle, mais aussi détecter si l'élément concerné était visible au moment de l'intersection.
Intersection Observer v1 est l'une de ces API
probablement appréciées par tous. Maintenant que
Safari le prend aussi en charge.
il est également utilisable universellement
dans tous les principaux navigateurs. Pour vous rafraîchir la mémoire sur l'API,
Je vous conseille de regarder Surma
Micro-pointe surélevée sur une intersection
Observer v1 intégré ci-dessous.
Vous pouvez également lire
le document détaillé de Surma
.
Intersection Observer v1 a été utilisé dans de nombreux cas d'utilisation, par exemple :
le chargement différé d'images et de vidéos,
être averti lorsque des éléments atteignent position: sticky
;
déclencher des événements d'analyse,
et bien d'autres encore.
Pour en savoir plus, consultez le Documentation d'Intersection Observer sur MDN Pour rappel, voici à quoi ressemble la version 1 de l'API Intersection Observer dans les cas de base:
const onIntersection = (entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
console.log(entry);
}
}
};
const observer = new IntersectionObserver(onIntersection);
observer.observe(document.querySelector('#some-target'));
Quels sont les défis liés à Intersection Observer v1 ?
En clair, Intersection Observer v1 est un outil formidable, mais il n'est pas parfait. Il y a
dans certains cas particuliers
où l'API n'est pas à la hauteur. Voyons cela de plus près.
L'API Intersection Observer v1 peut vous indiquer quand l'utilisateur fait défiler un élément vers l'intérieur
fenêtre d'affichage de la fenêtre, mais elle n'indique pas si l'élément est recouvert
par tout autre contenu de la page (c'est-à-dire, lorsque l'élément est masqué) ou si
l'affichage visuel de l'élément a été modifié par des effets visuels tels que transform
, opacity
,
filter
, etc., qui peuvent efficacement le rendre invisible.
Pour un élément du document de premier niveau, ces informations peuvent être déterminées en analysant
le DOM via JavaScript, par exemple via
DocumentOrShadowRoot.elementFromPoint()
puis à creuser plus profondément.
En revanche, il est impossible d'obtenir les mêmes informations si l'élément en question est
situées dans un iFrame tiers.
Pourquoi la visibilité réelle est-elle si importante ?
Internet est malheureusement un endroit qui attire les acteurs malintentionnés aux pires intentions.
Par exemple, un éditeur louche qui diffuse des annonces au paiement par clic sur un site de contenu peut être incité.
pour inciter les internautes à cliquer sur leurs annonces afin d'augmenter les revenus publicitaires de l'éditeur (au moins
pendant une courte période, jusqu'à ce que le réseau publicitaire les détecte).
Généralement, ces annonces sont diffusées dans des cadres iFrame.
Si l'éditeur souhaite que les internautes cliquent sur ce type d'annonce, il peut créer des cadres iFrame
une transparence totale en appliquant une règle CSS iframe { opacity: 0; }
et en superposant les cadres iFrame.
par-dessus un élément attrayant, comme une vidéo de chat sur laquelle les utilisateurs voudraient cliquer.
C'est ce qu'on appelle le détournement de clic.
Vous pouvez voir une telle attaque de détournement de clic
en action dans la section supérieure de ce
demo (essayez de regarder la vidéo de chat)
et activez le "mode astuce").
Vous remarquerez que l'annonce contenue dans l'iFrame "pense" la page a enregistré des clics légitimes,
de façon transparente lorsque vous cliquez dessus (cela se fait involontairement).
Comment Intersection Observer v2 résout-il ce problème ?
Intersection Observer v2 introduit le suivi de la "visibilité" réelle d'une cible
en tant qu'être humain le définirait.
Définissez une option dans le
Constructeur IntersectionObserver
intersections
IntersectionObserverEntry
instances contiendra alors un nouveau champ booléen nommé isVisible
.
Une valeur true
pour isVisible
est une bonne garantie de l'implémentation sous-jacente
l'élément cible ne doit pas être masqué par d'autres contenus.
et ne comporte aucun effet visuel qui modifierait
ou déformer son affichage à l'écran.
En revanche, une valeur false
signifie que l'implémentation ne peut pas fournir cette garantie.
Un détail important de la
caractéristiques
est que l'implémentation est autorisée à signaler des faux négatifs (autrement dit, en définissant isVisible
à false
, même lorsque l'élément cible est entièrement visible et inchangé).
Pour des raisons de performances ou pour d'autres raisons, les navigateurs se limitent à utiliser les limites.
et la géométrie rectiligne, ils n'essaient pas d'obtenir
des résultats au pixel près pour
des modifications comme border-radius
.
Toutefois, les faux positifs ne sont pas autorisés, quelles que soient les circonstances (par exemple, si vous définissez
isVisible
à true
lorsque l'élément cible n'est pas entièrement visible et n'est pas modifié).
En pratique, à quoi ressemble le nouveau code ?
Le constructeur IntersectionObserver
prend désormais deux propriétés de configuration supplémentaires: delay
et trackVisibility
.
Le delay
est un nombre indiquant le délai minimal en millisecondes entre les notifications des
l'observateur pour une cible donnée.
trackVisibility
est une valeur booléenne indiquant si l'observateur va suivre les modifications de la stratégie d'enchères
visibilité.
Il est important de noter ici que lorsque trackVisibility
est défini sur true
, delay
doit être situé à
100
minimum (c'est-à-dire, pas plus d'une notification toutes les 100 ms).
Comme indiqué précédemment, la visibilité est coûteuse à calculer, et cette exigence constitue une précaution
dégradation des performances
et de l'utilisation de la batterie. Le développeur responsable utilisera
plus grande valeur tolérable pour le retard.
Selon la version actuelle spec, la visibilité est calculé comme suit:
Si l'attribut
trackVisibility
de l'observateur estfalse
, la cible est considérée comme visible. Cela correspond au comportement actuel de la version 1.Si la cible dispose d'une matrice de transformation efficace autre qu'une traduction en 2D ou 2D proportionnelle, la cible est considérée comme invisible.
Si la cible ou tout élément de la chaîne de blocs qui la contient a une opacité effective autre que 1.0, la cible est considérée comme invisible.
Si des filtres sont appliqués à la cible ou à tout élément de la chaîne de bloc qui la contient, alors la cible est considérée comme invisible.
Si l'implémentation ne peut pas garantir que la cible n'est pas complètement masquée par une autre page contenu, la cible est considérée comme invisible.
Cela signifie que les implémentations actuelles sont assez conservatrices et garantissent la visibilité.
Par exemple, appliquer un filtre en nuances de gris presque invisible comme filter: grayscale(0.01%)
ou définir une transparence presque invisible avec opacity: 0.99
affichera tous l'élément
invisibles.
Vous trouverez ci-dessous un exemple de code abrégé qui illustre les nouvelles fonctionnalités de l'API. Vous pouvez voir le suivi des clics la logique en action dans la deuxième section de la démonstration (mais maintenant, essayez de "regarder" la vidéo du chiot). N'oubliez pas d'activer le "mode astuce" à nouveau pour transformez-vous en éditeur douteux et découvrez comment Intersection Observer v2 empêche les clics non légitimes sur les annonces. Cette fois-ci, Intersection Observer v2 est là pour vous ! 🎉
<!DOCTYPE html>
<!-- This is the ad running in the iframe -->
<button id="callToActionButton">Buy now!</button>
// This is code running in the iframe.
// The iframe must be visible for at least 800ms prior to an input event
// for the input event to be considered valid.
const minimumVisibleDuration = 800;
// Keep track of when the button transitioned to a visible state.
let visibleSince = 0;
const button = document.querySelector('#callToActionButton');
button.addEventListener('click', (event) => {
if ((visibleSince > 0) &&
(performance.now() - visibleSince >= minimumVisibleDuration)) {
trackAdClick();
} else {
rejectAdClick();
}
});
const observer = new IntersectionObserver((changes) => {
for (const change of changes) {
// ⚠️ Feature detection
if (typeof change.isVisible === 'undefined') {
// The browser doesn't support Intersection Observer v2, falling back to v1 behavior.
change.isVisible = true;
}
if (change.isIntersecting && change.isVisible) {
visibleSince = change.time;
} else {
visibleSince = 0;
}
}
}, {
threshold: [1.0],
// 🆕 Track the actual visibility of the element
trackVisibility: true,
// 🆕 Set a minimum delay between notifications
delay: 100
}));
// Require that the entire iframe be visible.
observer.observe(document.querySelector('#ad'));
Liens associés
- Dernier brouillon de l'éditeur de Spécification Intersection Observer.
- Intersection Observer v2 activé État de la plate-forme Chrome
- Bug Chromium d'Intersection Observer v2.
- Clignotement Projet d'implémentation de la publication.
Remerciements
Merci à Simeon Vincent, Yoav Weiss et Mathias Bynens d'avoir consulté cet article, et aussi Stefan Zager. pour examiner et implémenter la fonctionnalité dans Chrome. Image héros de Sergey Semin sur Unsplash.