Intersection Observer API
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2019.
Die Intersection Observer API bietet eine Möglichkeit, Änderungen im Schnittpunkt eines Ziel-Elements mit einem Vorgänger-Element oder mit dem Viewport eines obersten Dokuments asynchron zu beobachten.
Historisch gesehen war das Erkennen der Sichtbarkeit eines Elements oder der relativen Sichtbarkeit von zwei Elementen im Verhältnis zueinander eine schwierige Aufgabe, für die Lösungen unzuverlässig waren und dazu neigten, den Browser sowie die von den Benutzern aufgerufenen Websites zu verlangsamen. Mit der Reifung des Webs ist der Bedarf an dieser Art von Informationen gewachsen. Schnittstelleninformationen sind aus vielen Gründen erforderlich, wie zum Beispiel:
- Lazy-Loading von Bildern oder anderen Inhalten, während eine Seite gescrollt wird.
- Implementierung von "unendlichem Scrollen" auf Websites, bei denen immer mehr Inhalte geladen und gerendert werden, während Sie scrollen, sodass der Benutzer nicht durch Seiten blättern muss.
- Meldung der Sichtbarkeit von Anzeigen, um Werbeeinnahmen zu berechnen.
- Entscheidung, ob Aufgaben oder Animationsprozesse durchgeführt werden sollen, basierend darauf, ob der Benutzer das Ergebnis sehen wird oder nicht.
Die Implementierung der Schnittstellenerkennung in der Vergangenheit umfasste Event-Handler und Schleifen, die Methoden wie Element.getBoundingClientRect()
aufriefen, um die erforderlichen Informationen für jedes betroffene Element zu sammeln. Da der gesamte Code im Haupt-Thread ausgeführt wird, kann selbst einer davon zu Leistungsproblemen führen. Wenn eine Website mit diesen Tests geladen ist, können die Dinge richtig hässlich werden.
Betrachten Sie eine Webseite, die unendliches Scrollen verwendet. Sie verwendet eine von einem Anbieter bereitgestellte Bibliothek, um die Anzeigen zu verwalten, die regelmäßig auf der Seite platziert werden, hat an verschiedenen Stellen animierte Grafiken und verwendet eine benutzerdefinierte Bibliothek, die Benachrichtigungsboxen und dergleichen zeichnet. Jede dieser Funktionen hat ihre eigenen Routinen zur Schnittstellenerkennung, die alle im Haupt-Thread ablaufen. Der Websiteautor ist sich dessen möglicherweise nicht einmal bewusst, da er möglicherweise sehr wenig über die Funktionsweise der beiden von ihm verwendeten Bibliotheken weiß. Wenn der Benutzer die Seite scrollt, werden diese Routinen zur Schnittstellenerkennung ständig im Scroll-Steuerungscode ausgelöst, was zu einem Erlebnis führt, das den Benutzer mit dem Browser, der Website und seinem Computer frustriert zurücklässt.
Die Intersection Observer API erlaubt es, eine Callback-Funktion zu registrieren, die ausgeführt wird, wann immer ein bestimmtes Element eine Schnittstelle mit einem anderen Element (oder dem Viewport) betritt oder verlässt, oder wenn sich die Schnittstelle zwischen zwei Elementen um einen bestimmten Betrag ändert. Auf diese Weise müssen Websites nichts mehr im Haupt-Thread tun, um diese Art von Element-Schnittstelle zu überwachen, und der Browser kann das Management von Schnittstellen nach eigenem Ermessen optimieren.
Eine Sache, die die Intersection Observer API nicht tun kann: Logik basierend auf der genauen Anzahl von überlappenden Pixeln auslösen oder spezifisch auf welche. Sie löst nur den gängigen Anwendungsfall "Wenn sie sich um ungefähr N% überschneiden, muss ich etwas tun."
Intersection Observer-Konzepte und -Nutzung
Die Intersection Observer API ermöglicht es Ihnen, einen Callback zu konfigurieren, der aufgerufen wird, wenn eine der folgenden Bedingungen eintritt:
- Ein Ziel-Element schneidet entweder den Viewport des Geräts oder ein angegebenes Element. Dieses angegebene Element wird für die Zwecke der Intersection Observer API als Root-Element oder Root bezeichnet.
- Das erste Mal, wenn der Observer zunächst gebeten wird, ein Ziel-Element zu überwachen.
Normalerweise möchten Sie die Schnittstellenänderungen in Bezug auf den nächsten scrollbaren Vorgänger des Ziel-Elements oder, wenn das Ziel-Element nicht Nachkomme eines scrollbaren Elements ist, den Viewport des Geräts beobachten. Um die Schnittstelle relativ zum Viewport des Geräts zu überwachen, geben Sie null
für die root
-Option an. Lesen Sie weiter für eine detailliertere Erklärung der Intersection Observer-Optionen.
Unabhängig davon, ob Sie den Viewport oder ein anderes Element als Root verwenden, funktioniert die API auf die gleiche Weise und führt eine von Ihnen bereitgestellte Callback-Funktion aus, wann immer sich die Sichtbarkeit des Ziel-Elements ändert, sodass es gewünschte Schnittstellenmengen mit dem Root überschreitet.
Der Grad der Schnittstelle zwischen dem Ziel-Element und seinem Root ist das Schnittstellenverhältnis. Dies ist eine Darstellung des Prozentsatzes des Ziel-Elements, der als Wert zwischen 0,0 und 1,0 sichtbar ist.
Erstellen eines Intersection Observers
Erstellen Sie den Intersection Observer, indem Sie seinen Konstruktor aufrufen und ihm eine Callback-Funktion übergeben, die ausgeführt wird, wann immer ein Schwellenwert in die eine oder andere Richtung überschritten wird:
const options = {
root: document.querySelector("#scrollArea"),
rootMargin: "0px",
threshold: 1.0,
};
const observer = new IntersectionObserver(callback, options);
Ein Schwellenwert von 1,0 bedeutet, dass die Callback-Funktion aufgerufen wird, wenn 100% des Ziels innerhalb des durch die root
-Option angegebenen Elements sichtbar sind.
Intersection Observer-Optionen
Das options
-Objekt, das an den IntersectionObserver()
-Konstruktor übergeben wird, ermöglicht es Ihnen, die Umstände zu steuern, unter denen der Callback des Observers aufgerufen wird. Es hat die folgenden Felder:
root
-
Das Element, das als Viewport verwendet wird, um die Sichtbarkeit des Ziels zu überprüfen. Muss der Vorgänger des Ziels sein. Standardmäßig ist dies der Browser-Viewport, wenn nicht angegeben oder wenn
null
. rootMargin
-
Rand um den Root. Ein String von einem bis vier Werten, ähnlich der CSS
margin
-Eigenschaft, z.B."10px 20px 30px 40px"
(oben, rechts, unten, links). Die Werte können nur absolute Längen oder Prozentsätze sein. Diese Werte dienen dazu, jede Seite des Begrenzungsrahmens des Root-Elements vor der Berechnung der Schnittstellen zu vergrößern oder zu verkleinern. Negative Werte verkleinern den Begrenzungsrahmen des Root-Elements und positive Werte vergrößern ihn. Der Standardwert, wenn nicht angegeben, ist"0px 0px 0px 0px"
. threshold
-
Entweder eine einzelne Zahl oder ein Array von Zahlen, die angeben, bei welchem Prozentsatz der Sichtbarkeit des Ziels die Callback-Funktion des Observers ausgeführt werden soll. Wenn Sie nur erkennen möchten, wann die Sichtbarkeit die 50%-Marke überschreitet, können Sie einen Wert von 0,5 verwenden. Wenn Sie die Callback-Funktion jedes Mal ausführen möchten, wenn die Sichtbarkeit um weitere 25% überschreitet, würden Sie das Array [0, 0.25, 0.5, 0.75, 1] angeben. Der Standardwert ist 0 (was bedeutet, dass die Callback-Funktion ausgeführt wird, sobald auch nur ein Pixel sichtbar ist). Ein Wert von 1,0 bedeutet, dass der Schwellenwert erst als überschritten betrachtet wird, wenn jedes Pixel sichtbar ist.
Callbacks für Schnittstellenänderungen
Der Callback, der an den IntersectionObserver()
-Konstruktor übergeben wird, erhält eine Liste von IntersectionObserverEntry
-Objekten und den Observer:
const callback = (entries, observer) => {
entries.forEach((entry) => {
// Each entry describes an intersection change for one observed
// target element:
// entry.boundingClientRect
// entry.intersectionRatio
// entry.intersectionRect
// entry.isIntersecting
// entry.rootBounds
// entry.target
// entry.time
});
};
Die Liste der Einträge, die vom Callback empfangen wird, enthält einen Eintrag für jedes Schwellenwert-Ereignis — mehrere Einträge können gleichzeitig empfangen werden, entweder von mehreren Zielen oder von einem einzigen Ziel, das in kurzer Zeit mehrere Schwellenwerte überquert. Die Einträge werden in einer Warteschlange versandt, sie sollten also nach der Zeit, zu der sie generiert wurden, sortiert sein, aber Sie sollten vorzugsweise IntersectionObserverEntry.time
verwenden, um sie korrekt zu ordnen.
Jeder Eintrag in der Liste der Schwellenwerte ist ein IntersectionObserverEntry
-Objekt, das einen Schwellenwert beschreibt, der überschritten wurde; das heißt, jeder Eintrag beschreibt, wie viel eines bestimmten Elements mit dem Root-Element schneidet, ob das Element als schneidend betrachtet wird oder nicht usw. Der Eintrag enthält nur Informationen über diesen bestimmten Augenblick — wenn Sie Informationen benötigen, die eine Verfolgung über die Zeit erfordern, wie die Scrollrichtung und -geschwindigkeit, müssen Sie diese möglicherweise selbst berechnen, indem Sie vorherige Einträge speichern.
Beachten Sie, dass Ihr Callback im Haupt-Thread ausgeführt wird. Es sollte so schnell wie möglich arbeiten; wenn etwas Zeitaufwändiges zu erledigen ist, verwenden Sie Window.requestIdleCallback()
.
Der untenstehende Code-Schnipsel zeigt einen Callback, der einen Zähler führt, wie oft Elemente von nicht schneidend zur Mindest-Schnittmenge von 75% wechseln. Bei einem Schwellenwert von 0,0 (Standardwert) wird der Callback etwa bei Übergang des booleschen Wertes von isIntersecting
aufgerufen. Der Schnipsel überprüft daher zuerst, dass der Übergang ein positiver ist, und bestimmt dann, ob das intersectionRatio
über 75% liegt, wobei es in diesem Fall den Zähler erhöht.
const intersectionCallback = (entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let elem = entry.target;
if (entry.intersectionRatio >= 0.75) {
intersectionCounter++;
}
}
});
};
Anvisieren eines zu beobachtenden Elements
Sobald Sie den Observer erstellt haben, müssen Sie ihm ein Ziel-Element zum Überwachen geben:
const target = document.querySelector("#listItem");
observer.observe(target);
// the callback we set up for the observer will be executed now for the first time
// it waits until we assign a target to our observer (even if the target is currently not visible)
Wann immer das Ziel einen für den IntersectionObserver
angegebenen Schwellenwert erreicht, wird der Callback aufgerufen.
Beachten Sie auch, dass, wenn Sie die root
-Option angegeben haben, das Ziel ein Nachkomme des Root-Elements sein muss.
Wie die Schnittstelle berechnet wird
Alle von der Intersection Observer API betrachteten Bereiche sind Rechtecke; Elemente, die unregelmäßig geformt sind, werden als das kleinste Rechteck betrachtet, das alle Teile des Elements umschließt. Ähnlich, wenn der sichtbare Teil eines Elements nicht rechteckig ist, wird das Schnittstellenrechteck des Elements als das kleinste Rechteck betrachtet, das alle sichtbaren Teile des Elements enthält.
Es ist nützlich, ein wenig darüber zu verstehen, wie die verschiedenen von IntersectionObserverEntry
bereitgestellten Eigenschaften eine Schnittstelle beschreiben.
Die Schnittstelle-Root und Root-Rand
Bevor wir die Schnittstelle eines Elements mit einem Container verfolgen können, müssen wir wissen, was dieser Container ist. Dieser Container ist die Schnittstelle-Root oder Root-Element. Dies kann entweder ein bestimmtes Element im Dokument sein, das ein Vorgänger des zu beobachtenden Elements ist, oder null
, um den Viewport des Dokuments als Container zu verwenden.
Das Schnittstelle-Root-Rechteck ist das Rechteck, das zur Überprüfung der Ziel- oder Ziele verwendet wird. Dieses Rechteck wird wie folgt bestimmt:
- Wenn die Schnittstelle-Root die implizite Root ist (d.h. das oberste
Document
), ist das Schnittstelle-Root-Rechteck das Rechteck des Viewports. - Wenn die Schnittstelle-Root einen Überlauf-Clip hat, ist das Schnittstelle-Root-Rechteck der Inhaltsbereich des Root-Elements.
- Andernfalls ist das Schnittstelle-Root-Rechteck das Begrenzungsrechteck des Schnittstelle-Roots (wie durch Aufruf von
getBoundingClientRect()
darauf zurückgegeben).
Das Schnittstelle-Root-Rechteck kann weiter durch Festlegen des Root-Rands, rootMargin
, beim Erstellen des IntersectionObserver
angepasst werden. Die Werte in rootMargin
definieren Offsets, die zu jeder Seite des Begrenzungsrahmens der Schnittstelle-Root hinzugefügt werden, um die endgültigen Schnittstelle-Root-Grenzen zu erstellen (die in IntersectionObserverEntry.rootBounds
bekanntgegeben werden, wenn der Callback ausgeführt wird). Positive Werte vergrößern die Box, während negative sie verkleinern.
Im folgenden Beispiel haben wir eine scrollbare Box und ein Element, das zunächst unsichtbar ist. Sie können den Root-Rechtsrand anpassen und sehen, dass:
- Wenn der Rand negativ ist, dann wird, auch wenn das rote Element sichtbar zu werden beginnt, es immer noch nicht als schneidend mit der Root betrachtet, weil der Begrenzungsrahmen der Root verkleinert wird.
- Wenn der Rand positiv ist, wird das rote Element als schneidend mit der Root betrachtet, selbst wenn es nicht sichtbar ist, weil es mit dem Randbereich der Root schneidet.
Schwellenwerte
Anstatt jede winzige Änderung darin zu melden, wie viel ein Ziel-Element sichtbar ist, nutzt die Intersection Observer API Schwellenwerte. Wenn Sie einen Observer erstellen, können Sie eine oder mehrere numerische Werte bereitstellen, die Prozentsätze des sichtbaren Ziel-Elements repräsentieren. Dann meldet die API nur Änderungen der Sichtbarkeit, die diese Schwellenwerte überschreiten.
Zum Beispiel, wenn Sie über jedes Vor- oder Zurückgehen eines Ziels über jede Marke von 25% informiert werden möchten, würden Sie das Array [0, 0.25, 0.5, 0.75, 1] als Liste der Schwellenwerte bei Erstellung des Observers angeben.
Wenn der Callback aufgerufen wird, erhält er eine Liste von IntersectionObserverEntry
-Objekten, eines für jedes beobachtete Ziel, bei dem sich der Grad, in dem es mit der Root schneidet, derart geändert hat, dass die Menge der freigelegten Bereiche über einen der Schwellenwerte in eine Richtung überschreitet.
Sie können sehen, ob das Ziel derzeit die Root schneidet, indem Sie die isIntersecting
-Eigenschaft des Eintrags prüfen; wenn der Wert true
ist, schneidet das Ziel mindestens teilweise das Root-Element oder Dokument. Dies ermöglicht Ihnen, festzustellen, ob der Eintrag einen Übergang vom Schneiden zu nicht Schrittschneiden oder einen Übergang vom Nichtschneiden zu Schneiden darstellt.
Beachten Sie, dass es möglich ist, ein Schnittstellenrechteck mit dem Wert Null zu haben, was passieren kann, wenn die Schnittstelle genau an der Grenze zwischen den beiden liegt oder der Bereich von boundingClientRect
Null ist. Dieser Zustand, in dem das Ziel und die Root eine Grenzlinie teilen, wird nicht als ausreichend angesehen, um in einen schneidenden Zustand überzugehen.
Um ein Gefühl dafür zu bekommen, wie Schwellenwerte funktionieren, versuchen Sie, die Box unten herumzuscrollen. Jede farbige Box innerhalb zeigt den Prozentsatz von sich selbst in allen vier Ecken an, sodass Sie sehen können, wie sich diese Verhältnisse im Laufe der Zeit ändern, während Sie den Container scrollen. Jede Box hat eine unterschiedliche Menge an Schwellenwerten:
- Die erste Box hat eine Schwelle für jeden Prozentpunkt der Sichtbarkeit; das heißt, das
IntersectionObserver.thresholds
-Array ist[0.00, 0.01, 0.02, /*…,*/ 0.99, 1.00]
. - Die zweite Box hat eine einzige Schwelle bei der Marke von 50%.
- Die dritte Box hat Schwellenwerte alle 10% der Sichtbarkeit (0%, 10%, 20%, usw.).
- Die letzte Box hat Schwellenwerte alle 25%.
Clipping und das Schnittstellenrechteck
Der Browser berechnet das endgültige Schnittstellenrechteck wie folgt; dies wird alles für Sie erledigt, aber es kann hilfreich sein, diese Schritte zu verstehen, um genau zu begreifen, wann Schnittstellen auftreten werden.
- Das Begrenzungsrechteck des Ziel-Elements (das heißt, das kleinste Rechteck, das die Begrenzungsboxen jeder Komponente bildet, aus denen das Element besteht), wird durch Aufrufen von
getBoundingClientRect()
auf das Ziel erhalten. Dies ist das größte, was das Schnittstellenrechteck sein kann. Die verbleibenden Schritte entfernen alle Teile, die nicht schneiden. - Beginnend mit dem unmittelbaren Elternelement des Ziels und nach außen durchlaufend, wird das Clipping (falls vorhanden) jedes enthaltenen Blocks auf das Schnittstellenrechteck angewendet. Das Clipping eines Blocks wird basierend auf der Schnittstelle der beiden Blocks und dem Clipping-Modus (falls vorhanden), der durch die
overflow
-Eigenschaft festgelegt ist, bestimmt. Das Setzen vonoverflow
auf etwas anderes alsvisible
verursacht Clipping. - Wenn eines der enthaltenen Elemente die Root eines verschachtelten Browsing-Kontextes ist (wie das Dokument, das in einem
<iframe>
enthalten ist), wird das Schnittstellenrechteck auf den Viewport des enthaltenen Kontextes zugeschnitten und die Rekursion nach oben durch die Container geht mit dem übergeordneten Block des Containers weiter. Wenn also das oberste<iframe>
erreicht wird, wird das Schnittstellenrechteck auf den Viewport des Rahmens zugeschnitten, dann ist das Elternelement des Rahmens der nächste Block, der in Richtung der Schnittstelle-Root rekursiert wird. - Wenn die Rekursion nach oben die Schnittstelle-Root erreicht, wird das resultierende Rechteck in den Koordinatenbereich der Schnittstelle-Root abgebildet.
- Das resultierende Rechteck wird dann aktualisiert, indem es mit dem Schnittstelle-Root-Rechteck verschränkt wird.
- Dieses Rechteck wird schließlich in den Koordinatenbereich des
Dokuments
des Ziels abgebildet.
Schnittstellen
IntersectionObserver
-
Die primäre Schnittstelle für die Intersection Observer API. Bietet Methoden zum Erstellen und Verwalten eines Observers, der jede Anzahl von Ziel-Elementen für dieselbe Schnittstellenkonfiguration beobachten kann. Jeder Observer kann Änderungen in der Schnittstelle zwischen einem oder mehreren Ziel-Elementen und einem gemeinsamen Vorfahren-Element oder mit ihrem obersten
Document
Viewport asynchron beobachten. Der Vorfahre oder der Viewport wird als Root bezeichnet. IntersectionObserverEntry
-
Beschreibt die Schnittstelle zwischen dem Ziel-Element und seinem Root-Container zu einem bestimmten Zeitpunkt des Übergangs. Objekte dieses Typs können nur auf zwei Arten erhalten werden: als Eingabe für Ihre
IntersectionObserver
-Callback-Funktion oder durch Aufrufen vonIntersectionObserver.takeRecords()
.
Ein einfaches Beispiel
Dieses einfache Beispiel lässt ein Ziel-Element seine Farbe und Transparenz ändern, wenn es mehr oder weniger sichtbar wird. Unter Timing element visibility with the Intersection Observer API finden Sie ein umfangreicheres Beispiel, das zeigt, wie Sie die Zeit messen können, wie lange eine Gruppe von Elementen (wie Anzeigen) für den Benutzer sichtbar sind, und auf diese Informationen reagieren, indem Statistiken aufgezeichnet oder Elemente aktualisiert werden.
HTML
Das HTML für dieses Beispiel ist sehr kurz, mit einem Hauptelement, das die Box ist, die wir anvisieren (mit der kreativen ID "box"
) und einigen Inhalten innerhalb der Box.
<div id="box">
<div class="vertical">Welcome to <strong>The Box!</strong></div>
</div>
CSS
Das CSS ist für die Zwecke dieses Beispiels nicht besonders wichtig; es legt das Element aus und legt fest, dass die background-color
- und die border
-Attribute an CSS-Übergängen teilnehmen können, die wir verwenden werden, um die Änderungen am Element zu beeinflussen, während es mehr oder weniger verdeckt wird.
#box {
background-color: rgb(40 40 190 / 100%);
border: 4px solid rgb(20 20 120);
transition:
background-color 1s,
border 1s;
width: 350px;
height: 350px;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.vertical {
color: white;
font: 32px "Arial";
}
.extra {
width: 350px;
height: 350px;
margin-top: 10px;
border: 4px solid rgb(20 20 120);
text-align: center;
padding: 20px;
}
JavaScript
Schließlich werfen wir einen Blick auf den JavaScript-Code, der die Intersection Observer API nutzt, um Dinge geschehen zu lassen.
Einrichtung
Zuerst müssen wir einige Variablen vorbereiten und den Observer installieren.
const numSteps = 20.0;
let boxElement;
let prevRatio = 0.0;
let increasingColor = "rgb(40 40 190 / ratio)";
let decreasingColor = "rgb(190 40 40 / ratio)";
// Set things up
window.addEventListener(
"load",
(event) => {
boxElement = document.querySelector("#box");
createObserver();
},
false,
);
Die Konstanten und Variablen, die wir hier einrichten, sind:
numSteps
-
Eine Konstante, die angibt, wie viele Schwellenwerte wir zwischen einem Sichtbarkeitsverhältnis von 0,0 und 1,0 haben möchten.
prevRatio
-
Diese Variable wird verwendet, um zu verzeichnen, wie das Sichtbarkeitsverhältnis beim letzten Überschreiten eines Schwellenwerts war; dies ermöglicht es uns herauszufinden, ob das Ziel-Element mehr oder weniger sichtbar wird.
increasingColor
-
Ein String, der eine Farbe definiert, die wir auf das Ziel-Element anwenden, wenn das Sichtbarkeitsverhältnis steigt. Das Wort "ratio" in diesem String wird durch das aktuelle Sichtbarkeitsverhältnis des Ziels ersetzt, sodass sich das Element nicht nur farblich ändert, sondern auch zunehmend undurchsichtiger wird, wenn es weniger verdeckt wird.
decreasingColor
-
Ebenso ist dies ein String, der eine Farbe definiert, die wir bei sinkendem Sichtbarkeitsverhältnis anwenden werden.
Wir rufen Window.addEventListener()
auf, um zu beginnen, das load
-Event zu lauschen; sobald die Seite geladen ist, erhalten wir eine Referenz zu dem Element mit der ID "box"
mit querySelector()
und rufen dann die createObserver()
-Methode auf, die wir gleich erstellen werden, um den Aufbau und die Installation des Intersection Observers zu handhaben.
Erstellen des Intersection Observers
Die createObserver()
-Methode wird nach Abschluss des Seitenladens aufgerufen, um tatsächlich den neuen IntersectionObserver
zu erstellen und den Prozess der Beobachtung des Ziel-Elements zu starten.
function createObserver() {
let observer;
let options = {
root: null,
rootMargin: "0px",
threshold: buildThresholdList(),
};
observer = new IntersectionObserver(handleIntersect, options);
observer.observe(boxElement);
}
Dies beginnt mit der Einrichtung eines options
-Objekts, das die Einstellungen für den Observer enthält. Wir möchten Änderungen in der Sichtbarkeit des Ziel-Elements relativ zum Viewport des Dokuments beobachten, daher ist root
null
. Wir benötigen keinen Rand, daher wird der Rand-Offset rootMargin
als "0px" angegeben. Dies führt dazu, dass der Observer die Schnittstelle zwischen den Begrenzungen des Ziel-Elements und denen des Viewports überwacht, ohne zusätzlichen (oder subtrahierten) Raum.
Die Liste der Schwellenwerte für das Sichtbarkeitsverhältnis, threshold
, wird von der Funktion buildThresholdList()
konstruiert. Die Schwellenwertliste wird in diesem Beispiel programmgesteuert erstellt, da es eine Anzahl von ihnen gibt und die Anzahl anpassbar sein soll.
Sobald options
bereit ist, erstellen wir den neuen Observer und rufen den IntersectionObserver()
-Konstruktor auf, wobei wir eine Funktion angeben, die aufgerufen werden soll, wenn die Schnittstelle einen unserer Schwellenwerte überschreitet, handleIntersect()
, und unser Set von Optionen. Wir rufen dann observe()
auf dem zurückgegebenen Observer auf, indem wir das gewünschte Ziel-Element übergeben.
Wir könnten optional mehrere Elemente überwachen, um Sichtbarkeitsänderungen der Schnittstelle im Hinblick auf den Viewport zu beobachten, indem wir für jedes dieser Elemente Observer.observe()
aufrufen, wenn wir dies tun möchten.
Erstellen der Schwellenwert-Ratio-Array
Die buildThresholdList()
-Funktion, die die Liste der Schwellenwerte erstellt, sieht so aus:
function buildThresholdList() {
let thresholds = [];
let numSteps = 20;
for (let i = 1.0; i <= numSteps; i++) {
let ratio = i / numSteps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
Diese erstellt das Array der Schwellenwerte — jede davon ist ein Verhältnis zwischen 0,0 und 1,0, indem die Werte i/numSteps
für jede ganze Zahl i
zwischen 1 und numSteps
in das thresholds
-Array eingefügt werden. Es wird auch 0 eingefügt, um diesen Wert einzuschließen. Das Ergebnis, unter Berücksichtigung des Standardwerts von numSteps
(20), ist folgende Liste von Schwellenwerten:
# | Verhältnis | # | Verhältnis |
---|---|---|---|
0 | 0.05 | 11 | 0.6 |
1 | 0.1 | 12 | 0.65 |
2 | 0.15 | 13 | 0.7 |
3 | 0.2 | 14 | 0.75 |
4 | 0.25 | 15 | 0.8 |
5 | 0.3 | 16 | 0.85 |
6 | 0.35 | 17 | 0.9 |
7 | 0.4 | 18 | 0.95 |
8 | 0.45 | 19 | 1 |
9 | 0.5 | 20 | 0 |
10 | 0.55 |
Wir könnten natürlich das Array der Schwellenwerte in unseren Code fest codieren, und oft werden Sie genau das tun. Aber in diesem Beispiel wird Raum gelassen, um Steuerungen hinzuzufügen, um die Granularität anzupassen, beispielsweise.
Handhabung von Schnittstellenänderungen
Wenn der Browser erkennt, dass das Ziel-Element (in unserem Fall das mit der ID "box"
) so enthüllt oder verdeckt wurde, dass sein Sichtbarkeitsverhältnis einen unserer Schwellenwerte in der Liste überschreitet, ruft es unsere Handler-Funktion handleIntersect()
auf:
function handleIntersect(entries, observer) {
entries.forEach((entry) => {
if (entry.intersectionRatio > prevRatio) {
entry.target.style.backgroundColor = increasingColor.replace(
"ratio",
entry.intersectionRatio,
);
} else {
entry.target.style.backgroundColor = decreasingColor.replace(
"ratio",
entry.intersectionRatio,
);
}
prevRatio = entry.intersectionRatio;
});
}
Für jede IntersectionObserverEntry
in der Liste entries
sehen wir nach, ob das intersectionRatio
des Eintrags steigt; wenn dies der Fall ist, setzen wir die background-color
des Ziels auf den String in increasingColor
(denken Sie daran, es ist "rgb(40 40 190 / ratio)"
), ersetzen aber das Wort "ratio" durch das intersectionRatio
des Eintrags. Das Ergebnis: Nicht nur ändert sich die Farbe, sondern auch die Transparenz des Ziel-Elements ändert sich; wenn das Schnittstellenverhältnis sinkt, sinkt auch der Alpha-Wert der Hintergrundfarbe, was zu einem Element führt, das durchsichtiger wird.
Ebenso verwenden wir, wenn das intersectionRatio
sinkt, den String decreasingColor
und ersetzen das Wort "ratio" durch das intersectionRatio
, bevor wir die background-color
des Ziel-Elements setzen.
Schließlich, um zu verfolgen, ob das Schnittstellenverhältnis steigt oder fällt, speichern wir das aktuelle Verhältnis in der Variable prevRatio
.
Ergebnis
Unten ist der resultierende Inhalt zu sehen. Scrollen Sie diese Seite auf und ab und bemerken Sie, wie sich das Aussehen der Box währenddessen verändert.
Ein noch ausführlicheres Beispiel gibt es unter Timing element visibility with the Intersection Observer API.
Spezifikationen
Specification |
---|
Intersection Observer # intersection-observer-interface |
Browser-Kompatibilität
BCD tables only load in the browser