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 März 2019.
* Some parts of this feature may have varying levels of support.
Die Intersection Observer API bietet eine Möglichkeit, Änderungen in der Überschneidung eines Zielelements mit einem übergeordneten Element oder mit dem Viewport eines obersten Dokuments asynchron zu beobachten.
Übersicht
Historisch gesehen war das Erkennen der Sichtbarkeit eines Elements oder der relativen Sichtbarkeit zweier Elemente zueinander eine schwierige Aufgabe, für die Lösungen unzuverlässig waren und dazu neigten, den Browser und die von den Benutzern aufgerufenen Websites träge zu machen. Da sich das Web weiterentwickelt hat, ist der Bedarf an dieser Art von Information gewachsen. Überlappungsinformationen werden aus vielen Gründen benötigt, wie zum Beispiel:
- Lazy-Loading von Bildern oder anderen Inhalten, wenn eine Seite gescrollt wird.
- Implementierung von "unendlichen" Scroll-Websites, bei denen immer mehr Inhalte geladen und gerendert werden, während Sie scrollen, sodass der Benutzer keine Seiten umblättern muss.
- Berichterstattung über die Sichtbarkeit von Anzeigen, um die Werbeeinnahmen zu berechnen.
- Entscheidung, ob Aufgaben oder Animationsprozesse ausgeführt werden sollen, basierend darauf, ob der Benutzer das Ergebnis sehen wird oder nicht.
In der Vergangenheit beinhaltete die Implementierung der Überschneidungserkennung Ereignishandler und Schleifen, die Methoden wie Element.getBoundingClientRect() aufrufen, um die benötigten Informationen für jedes betroffene Element zu sammeln. Da all dieser Code im Hauptthread läuft, kann selbst einer dieser Vorgänge Leistungsprobleme verursachen. Wenn eine Website mit diesen Tests geladen ist, kann es ziemlich hässlich werden.
Stellen Sie sich eine Webseite vor, die unendliches Scrollen verwendet. Sie verwendet eine vom Anbieter bereitgestellte Bibliothek, um die Anzeigen zu verwalten, die periodisch auf der Seite platziert werden, hat hier und da animierte Grafiken und verwendet eine benutzerdefinierte Bibliothek, die Benachrichtigungsfenster und dergleichen zeichnet. Jeder von ihnen hat seine eigenen Routinen zur Erkennung von Überschneidungen, die alle im Hauptthread ausgeführt werden. Der Autor der Website bemerkt möglicherweise nicht einmal, dass dies passiert, da er möglicherweise sehr wenig über die inneren Abläufe der beiden von ihm verwendeten Bibliotheken weiß. Während der Benutzer die Seite scrollt, werden diese Routinen zur Erkennung von Überschneidungen ständig während des Scroll-Handlings ausgeführt, was zu einer Erfahrung führt, die den Benutzer mit dem Browser, der Website und seinem Computer frustriert zurücklässt.
Die Intersection Observer API ermöglicht es dem Code, eine Callback-Funktion zu registrieren, die jedes Mal ausgeführt wird, wenn ein bestimmtes Element eine Überschneidung mit einem anderen Element (oder dem Viewport) eingeht oder verlässt, oder wenn sich die Überschneidung zwischen zwei Elementen um einen bestimmten Betrag ändert. Auf diese Weise müssen Seiten nichts im Hauptthread tun, um auf diese Art von Elementüberschneidung zu achten, und der Browser ist frei, die Verwaltung von Überschneidungen zu optimieren, wie es ihm beliebt.
Eine Sache, die die Intersection Observer API nicht tun kann: Logik basierend auf der genauen Anzahl der überlappenden Pixel auslösen oder explizit auf welche sie sind. Sie löst nur den allgemeinen Anwendungsfall "Wenn sie sich um etwa N% überschneiden, muss ich etwas tun."
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 Zielelement schneidet entweder den Viewport des Geräts oder ein angegebenes Element. Für die Zwecke der Intersection Observer API wird dieses angegebene Element als Wurzelelement oder Root bezeichnet.
- Das erste Mal, wenn der Observer ursprünglich aufgefordert wird, ein Zielelement zu beobachten.
Typischerweise möchten Sie Überschneidungsänderungen in Bezug auf den nächsten scrollbaren Vorfahren des Zielelements beobachten, oder, wenn das Zielelement kein Nachkomme eines scrollbaren Elements ist, den Viewport des Geräts. Um die Überschneidung relativ zum Viewport des Geräts zu beobachten, geben Sie null für die root-Option an. Lesen Sie weiter für eine detailliertere Erklärung der Optionen für den Intersection Observer.
Unabhängig davon, ob Sie den Viewport oder ein anderes Element als Root verwenden, funktioniert die API auf die gleiche Weise, indem sie eine von Ihnen bereitgestellte Callback-Funktion ausführt, wann immer sich die Sichtbarkeit des Zielelements so ändert, dass es gewünschte Mengen der Überschneidung mit dem Root überschreitet.
Der Grad der Überschneidung zwischen dem Zielelement und seinem Root ist das Überschneidungsverhältnis. Dies ist eine Darstellung des Prozentsatzes des Zielelements, der als Wert zwischen 0,0 und 1,0 sichtbar ist.
Erstellen eines Intersection Observers
Erstellen Sie den Intersection Observer, indem Sie dessen Konstruktor aufrufen und ihm eine Callback-Funktion übergeben, die jedes Mal ausgeführt wird, wenn ein Schwellenwert in eine oder die andere Richtung überschritten wird:
const options = { root: document.querySelector("#scrollArea"), rootMargin: "0px", scrollMargin: "0px", threshold: 1.0, }; const observer = new IntersectionObserver(callback, options); Ein Schwellenwert von 1,0 bedeutet, dass, wenn 100 % des Ziels im innerhalb des durch die root-Option angegebenen Elements sichtbar ist, der Callback aufgerufen wird.
Optionen für den Intersection Observer
Das options-Objekt, das dem Konstruktor IntersectionObserver() übergeben wird, ermöglicht es Ihnen, die Umstände zu kontrollieren, unter denen der Callback des Observers aufgerufen wird. Es hat die folgenden Felder:
root-
Das Element, das als Viewport zur Überprüfung der Sichtbarkeit des Ziels verwendet wird. Muss ein Vorfahre des Ziels sein. Standardmäßig wird der Browser-Viewport verwendet, wenn nicht angegeben oder wenn
null. rootMargin-
Rand um den Root. Ein String aus einem bis vier Werten, ähnlich der CSS-Eigenschaft
margin, z. B."10px 20px 30px 40px"(oben, rechts, unten, links). Die Werte können nur in Pixeln (px) oder Prozent (%) angegeben werden. Dieses Set von Werten dient zum Wachsen oder Schrumpfen jeder Seite des Begrenzungsrahmens des Root-Elements, bevor Überschneidungen berechnet werden. Negative Werte verkleinern den Begrenzungsrahmen des Root-Elements und positive Werte vergrößern ihn. Der Standardwert, wenn nicht angegeben, ist"0px 0px 0px 0px". scrollMargin-
Rand um verschachtelte scrollbare Container, der die gleichen Werte hat wie
rootMargin. Die Ränder werden auf verschachtelte scrollbare Container angewendet, bevor Überschneidungen berechnet werden. Positive Werte vergrößern das Ausschnittrechteck des Containers, sodass Ziele zu schneiden beginnen, bevor sie sichtbar werden, während negative Werte das Ausschnittrechteck verkleinern. threshold-
Entweder eine einzelne Zahl oder ein Array von Zahlen, die angeben, bei welchem Prozentsatz der Sichtbarkeit des Ziels der Callback 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 möchten, dass der Callback jedes Mal ausgeführt wird, 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 der Callback ausgeführt wird, sobald das Zielelement die Grenze des Root schneidet oder berührt, auch wenn noch keine Pixel sichtbar sind). Ein Wert von 1,0 bedeutet, dass der Schwellenwert erst dann als überschritten gilt, wenn jedes Pixel sichtbar ist.
delayExperimentell-
Beim Verfolgen der Sichtbarkeit des Ziels (trackVisibility ist
true) kann dies verwendet werden, um die Mindestverzögerung in Millisekunden zwischen Benachrichtigungen von diesem Observer festzulegen. Die Begrenzung der Benachrichtigungsrate ist wünschenswert, da die Sichtbarkeitsberechnung rechnerisch intensiv ist. Wenn die Sichtbarkeit verfolgt wird, wird der Wert für jeden Wert unter 100 auf 100 gesetzt, und Sie sollten den größten tolerierbaren Wert verwenden. Der Wert ist standardmäßig 0. trackVisibilityExperimentell-
Ein Boolescher Wert, der angibt, ob dieser
IntersectionObserverÄnderungen in der Sichtbarkeit eines Ziels verfolgt.Wenn
false, meldet der Browser Überschneidungen, wenn das Zielelement in den Viewport des Wurzelelements gescrollt wird. Wenntrue, überprüft der Browser zusätzlich, ob das Ziel tatsächlich sichtbar ist und nicht von anderen Elementen verdeckt oder möglicherweise durch einen Filter, reduzierte Deckkraft oder eine Transformation verzerrt oder verborgen wurde. Der Wert ist standardmäßigfalse, da die Verfolgung der Sichtbarkeit rechnerisch intensiv ist. Wenn dies festgelegt ist, sollte auch eindelayfestgelegt werden.
Callbacks für Überschneidungsänderungen
Der Callback, der dem Konstruktor IntersectionObserver() ü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 von Callback erhaltenen Einträge enthält ein IntersectionObserverEntry-Objekt für jedes Überschneidungsereignis – mehrere Einträge können gleichzeitig empfangen werden, entweder von mehreren Zielen oder von einem einzelnen Ziel, das in kurzer Zeit mehrere Schwellenwerte überschreitet. Die Einträge werden über eine Warteschlange verteilt, sodass sie in der Reihenfolge generiert werden sollten, aber Sie sollten vorzugsweise IntersectionObserverEntry.time verwenden, um sie richtig zu ordnen. Jeder Eintrag beschreibt, wie viel von einem gegebenen Element sich mit dem Root-Element überschneidet, ob das Element als sich überschneidend betrachtet wird oder nicht usw. Der Eintrag enthält nur Informationen über diesen bestimmten Moment – wenn Sie Informationen suchen, die über die Zeit hinweg verfolgt werden müssen, wie die Scrollrichtung und -geschwindigkeit, müssen Sie diese möglicherweise selbst berechnen, indem Sie sich zuvor erhaltene Einträge merken.
Beachten Sie, dass Ihr Callback im Haupt-Thread ausgeführt wird. Er sollte so schnell wie möglich arbeiten; wenn etwas zeitaufwändiges erledigt werden muss, verwenden Sie Window.requestIdleCallback().
Der folgende Codeausschnitt zeigt einen Callback, der einen Zähler führt, wie oft Elemente vom Nicht-Überschneiden des Root zum Überschneiden um mindestens 75% übergehen. Bei einem Schwellenwert von 0,0 (Standardwert) wird der Callback etwa beim Übergang des Booleschen Werts von isIntersecting aufgerufen. Der Schnappschuss prüft daher zuerst, dass der Übergang ein positiver ist, und bestimmt dann, ob intersectionRatio über 75 % liegt, in welchem Fall der Zähler erhöht wird.
const intersectionCallback = (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { let elem = entry.target; if (entry.intersectionRatio >= 0.75) { intersectionCounter++; } } }); }; Ein Ziel für die Beobachtung anvisieren
Sobald Sie den Observer erstellt haben, müssen Sie ihm ein Zielelement zur Beobachtung 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 angeben, das Ziel ein Nachkomme des Wurzelelements sein muss.
Wie Überschneidung berechnet wird
Alle von der Intersection Observer API betrachteten Bereiche sind Rechtecke; Elemente, die unregelmäßig geformt sind, gelten als das kleinste Rechteck, das alle Teile des Elements umschließt. Ebenso ist, wenn der sichtbare Teil eines Elements nicht rechteckig ist, das Überschneidungsrechteck des Elements das kleinste Rechteck, 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 Überschneidung beschreiben.
Das Überschneidungsroot und der Root-Margin
Bevor wir die Überschneidung eines Elements mit einem Container verfolgen können, müssen wir wissen, was dieser Container ist. Dieser Container ist das Überschneidungsroot oder Wurzelelement. Dies kann entweder ein spezifisches Element im Dokument sein, das ein Vorfahre des zu beobachtenden Elements ist, oder null, um den Viewport des Dokuments als Container zu verwenden.
Das Wurzelüberschneidungsrechteck ist das Rechteck, das zum Überprüfen gegen das Ziel oder die Ziele verwendet wird. Dieses Rechteck wird wie folgt bestimmt:
- Wenn das Überschneidungsroot das implizite Root ist (das heißt das top-level
Document), ist das Wurzelüberschneidungsrechteck das Rechteck des Viewports. - Wenn das Überschneidungsroot über einen Überlaufclip verfügt, ist das Wurzelüberschneidungsrechteck der Inhaltsbereich des Rootelements.
- Andernfalls ist das Wurzelüberschneidungsrechteck das Begrenzungsrahmen des Überschneidungsroots (wie zurückgegeben, indem
getBoundingClientRect()aufgerufen wird).
Das Wurzelüberschneidungsrechteck kann weiter angepasst werden, indem der Root-Margin, rootMargin, beim Erstellen des IntersectionObserver festgelegt wird. Die Werte in rootMargin legen Offsets fest, die auf jede Seite des Begrenzungsrahmens des Überschneidungsroots hinzugefügt werden, um die endgültigen Grenzen des Wurzelüberschneidungsrechts zu erstellen (die bei Ausführung des Callbacks in IntersectionObserverEntry.rootBounds angezeigt werden). Positive Werte vergrößern das Rechteck, während negative Werte es verkleinern. Jeder Offset-Wert kann nur in Pixeln (px) oder als Prozentsatz (%) ausgedrückt werden.
Der Effekt, das Rechteck mithilfe der Root-Margin zu vergrößern, besteht darin, überlaufende Ziele mit dem Root nicht schneiden zu lassen, bevor sie sichtbar werden. Dies kann beispielsweise verwendet werden, um Bilder zu laden, kurz bevor sie angezeigt werden, anstatt in dem Moment, in dem sie sichtbar werden.
Im Beispiel unten haben wir ein scrollbares Feld und ein Element, das sich zunächst außerhalb der Sicht befindet. Sie können den rechten Rand der Wurzel anpassen und feststellen, dass:
- Wenn der Rand positiv ist, wird das rote Element als sich mit dem Root überschneidend betrachtet, auch wenn es nicht sichtbar ist, da es sich mit dem Randbereich des Roots überschneidet.
- Wenn der Rand negativ ist, wird das rote Element, selbst wenn es beginnt sichtbar zu werden, immer noch nicht als sich mit dem Root überschneidend betrachtet, da das Begrenzungsfeld des Roots verkleinert ist.
Das Überschneidungsroot und der Scroll-Margin
Betrachten Sie den Fall, dass Sie ein Wurzelelement haben, das verschachtelte scrollbare Container enthält, und Sie möchten Überschneidungen mit einem Ziel innerhalb eines dieser scrollbaren Container beobachten. Überschneidungen mit dem Zielelement sind standardmäßig beobachtbar, wenn das Ziel innerhalb des durch den Root definierten Bereichs sichtbar ist; mit anderen Worten, wenn der Container im Root sichtbar gemacht wird und das Ziel im Ausschnittrechteck seines Containers sichtbar gemacht wird.
Sie können einen Scroll-Margin verwenden, um Überschneidungen zu beobachten, bevor oder nachdem das Ziel innerhalb seines Scrollcontainers sichtbar gemacht wird. Der Margin wird allen verschachtelten scrollbaren Containern im Root hinzugefügt, einschließlich dem Wurzelelement, wenn es auch ein scrollbarer Container ist, und hat den Effekt, die zum Berechnen von Überschneidungen verwendete Ausschnittregion entweder zu vergrößern (positive Ränder) oder zu verkleinern (negative Ränder).
Hinweis: Sie könnten einen Intersection Observer für jeden Scrollcontainer erstellen, für den Sie einen Scroll-Margin wünschen, und die Root-Margin-Eigenschaft verwenden, um einen ähnlichen Effekt zu erzielen. Die Verwendung von Scroll-Margin ist ergonomischer, da Sie in den meisten Fällen nur einen Intersection Observer für alle verschachtelten Ziele haben können.
Im folgenden Beispiel haben wir ein scrollbares Feld und ein Bilderkarussell, das sich zunächst außerhalb der Sicht befindet. Ein Observer auf dem Wurzelelement beobachtet die Bildelementziele innerhalb des Karussells. Wenn ein Bildelement beginnt, sich mit dem Wurzelelement zu überschneiden, wird das Bild geladen, die Überschneidung protokolliert und der Observer entfernt.
Scrollen Sie nach unten, um das Karussell anzuzeigen. Die sichtbaren Bilder sollten sofort geladen werden. Wenn Sie das Karussell scrollen, sollten Sie beobachten können, dass die Bilder geladen werden, sobald das Element sichtbar wird.
Nachdem Sie das Beispiel zurückgesetzt haben, können Sie die bereitgestellte Steuerung verwenden, um den Scroll-Margin-Prozentsatz zu ändern. Wenn Sie einen positiven Wert wie 20 % setzen, wird das Clipping-Rechteck des Scrollcontainers um 20 % vergrößert, und Sie sollten beobachten können, dass Bilder erkannt und geladen werden, bevor sie sichtbar werden. Ebenso bewirkt ein negativer Wert, dass die Überschneidung erkannt wird, sobald die Bilder bereits sichtbar sind.
Schwellenwerte
Anstatt jede kleinste Änderung darüber, wie viel von einem Zielelement sichtbar ist, zu melden, verwendet die Intersection Observer API Schwellenwerte. Wenn Sie einen Observer erstellen, können Sie einen oder mehrere Zahlenwerte angeben, die Prozentsätze des sichtbaren Zielelements darstellen. Die API informiert dann nur über Sichtbarkeitsänderungen, die diese Schwellen überschreiten.
Wenn Sie beispielsweise jedes Mal informiert werden möchten, wenn die Sichtbarkeit eines Ziels vorwärts oder rückwärts jede 25%-Marke überschreitet, würden Sie das Array [0, 0.25, 0.5, 0.75, 1] als Liste der Schwellenwerte angeben, wenn Sie den Observer erstellen.
Wenn der Callback aufgerufen wird, erhält er eine Liste von IntersectionObserverEntry-Objekten, eines für jedes beobachtete Ziel, dessen Grad der Überschneidung mit dem Root sich so geändert hat, dass die Menge, die freigelegt wird, einen der Schwellenwerte in einer Richtung überschreitet.
Sie können sehen, ob das Ziel aktuell den Root überschneidet, indem Sie die isIntersecting-Eigenschaft des Eintrags betrachten; ist deren Wert true, schneidet das Ziel zumindest teilweise das Root-Element oder das Dokument. Dies erlaubt Ihnen festzustellen, ob der Eintrag einen Übergang vom Überschneiden der Elemente zum Nicht-Überschneiden oder einen Übergang vom Nicht-Überschneiden zum Überschneiden repräsentiert.
Beachten Sie, dass es möglich ist, ein Null-Überschneidungsrechteck zu haben, das passieren kann, wenn die Überschneidung genau entlang der Grenze zwischen den beiden oder der Bereich von boundingClientRect null ist. Dieser Zustand des gemeinsamen Grenzlinien von Ziel und Root wird nicht als ausreichend angesehen, um als Übergang in einen sich überschneidenden Zustand betrachtet zu werden.
Um ein Gefühl dafür zu bekommen, wie Schwellenwerte funktionieren, versuchen Sie im folgenden Beispiel, den Kasten hin und her zu scrollen. Jedes Farbfeld innerhalb zeigt den Prozentsatz seiner Sichtbarkeit in allen vier Ecken an, sodass Sie diese Verhältnisse über die Zeit hinweg sehen können, während sich der Container bewegt. Jedes Kästchen hat eine andere Reihe von Schwellenwerten:
- Das erste Kästchen hat einen Schwellenwert für jeden Prozentsatz der Sichtbarkeit; das heißt, das
IntersectionObserver.thresholds-Array ist[0.00, 0.01, 0.02, /*…,*/ 0.99, 1.00]. - Das zweite Kästchen hat nur einen Schwellenwert, bei der 50%-Marke.
- Das dritte Kästchen hat Schwellenwerte alle 10 % der Sichtbarkeit (0 %, 10 %, 20 % usw.).
- Das letzte Kästchen hat Schwellenwerte alle 25 %.
Sichtbarkeitsverfolgung und Verzögerung
Standardmäßig liefert der Observer Benachrichtigungen, wenn das Zielelement in den Viewport des Wurzelelements gescrollt wird. Während dies in vielen Situationen alles ist, was benötigt wird, ist es manchmal wichtig, dass Überschneidungen nicht gemeldet werden, wenn das Ziel "visuell beeinträchtigt" wurde. Zum Beispiel ist es wichtig, dass bei der Messung von Analysen oder Anzeigenimpressionen die Zielelemente nicht verdeckt oder verfälscht sind, ganz oder teilweise.
Die trackVisibility-Einstellung teilt dem Observer mit, dass er Überschneidungen nur für Ziele melden soll, die der Browser nicht als visuell beeinträchtigt ansieht, z. B. durch Ändern der Deckkraft oder Anwenden eines Filters oder einer Transform. Der Algorithmus ist konservativ und kann Elemente weglassen, die technisch sichtbar sind, wie z. B. solche mit nur einer geringfügigen Opazitätsreduktion.
Die Sichtbarkeitsberechnung ist rechnerisch aufwendig und sollte nur bei Bedarf verwendet worden. Wenn die Sichtbarkeit verfolgt wird, sollte auch ein delay festgelegt werden, um die Mindestberichtsperiode zu begrenzen. Es wird empfohlen, die Verzögerung auf den größten tolerierbaren Wert zu setzen (die Mindestverzögerung bei der Verfolgung der Sichtbarkeit beträgt 100 Millisekunden).
Ausschneiden und das Überschneidungsrechteck
Der Browser berechnet das endgültige Überschneidungsrechteck wie folgt; dies wird alles für Sie erledigt, aber es kann hilfreich sein, diese Schritte zu verstehen, um besser zu begreifen, wann genau Überschneidungen auftreten.
- Das Begrenzungsrechteck des Zielelements (das kleinste Rechteck, das die Begrenzungsrahmen aller Komponenten umfasst, die das Element ausmachen) wird durch Aufrufen von
getBoundingClientRect()auf dem Ziel erhalten. Dies ist das größte Überschneidungsrechteck kann. Die verbleibenden Schritte entfernen alle Teile, die nicht sich überschneiden. - Beginnend beim unmittelbaren Elternelement des Ziels und aufwärts gehend, wird das Clipping (falls vorhanden) jedes enthaltenen Blocks auf das Überschneidungsrechteck angewendet. Das Clipping eines Blocks wird basierend auf der Überschneidung der beiden Blöcke und dem (falls vorhanden) durch die
overflow-Eigenschaft spezifizierten Clipping-Modus bestimmt. Das Setzen vonoverflowauf alles außervisibleführt zu Clipping. - Wenn eines der enthaltenen Elemente die Wurzel eines verschachtelten Browserkontexts ist (z. B. das im
<iframe>enthaltene Dokument), wird das Überschneidungsrechteck auf den Viewport des enthaltenen Kontexts zugeschnitten, und Rekursion wird durch den Container mit dem Container als nächstem Block fortgesetzt. Wenn also das oberste Level einer<iframe>erreicht ist, wird das Überschneidungsrechteck auf den Viewport des Frames zugeschnitten, dann ist das Elternelement des Frames der nächste Block, der nach oben rekursiv durch die Container zurückgeht. - Wenn die Rekursion nach oben das Überschneidungsroot erreicht, wird das resultierende Rechteck in den Koordinatenraum des Überschneidungsroots abgebildet.
- Das resultierende Rechteck wird dann weiter aktualisiert, indem es mit dem Wurzelüberschneidungsrechteck geschnitten wird.
- Dieses Rechteck wird schließlich in den Koordinatenraum des
documentsdes Ziels abgebildet.
Schnittstellen
IntersectionObserver-
Das primäre Interface für die Intersection Observer API. Bietet Methoden zum Erstellen und Verwalten eines Observers, der eine beliebige Anzahl von Zielenlementen für dieselbe Überschneidungskonfiguration beobachten kann. Jeder Observer kann asynchron Änderungen in der Überschneidung zwischen einem oder mehreren Zielelementen und einem gemeinsamen Vorfahrenelement oder mit dem Viewport ihres obersten Dokuments beobachten. Der Vorfahre oder Viewport wird als root bezeichnet.
IntersectionObserverEntry-
Beschreibt die Überschneidung zwischen dem Zielelement und seinem Root-Container an einem bestimmten Moment des Übergangs. Objekte dieses Typs können nur auf zwei Arten erhalten werden: als Eingabe für Ihren
IntersectionObserver-Callback oder durch Aufrufen vonIntersectionObserver.takeRecords().
Ein einfaches Beispiel
Dieses einfache Beispiel führt dazu, dass ein Zielelement seine Farbe und Transparenz ändert, je nachdem, wie sichtbar es wird. Bei Timing element visibility with the Intersection Observer API finden Sie ein noch umfangreicheres Beispiel, das zeigt, wie lange eine Reihe von Elementen (z. B. Anzeigen) für den Benutzer sichtbar sind und wie Sie auf diese Informationen reagieren können, indem Sie Statistiken aufzeichnen oder Elemente aktualisieren.
HTML
Das HTML für dieses Beispiel ist sehr kurz, mit einem Hauptelement, das die Box ist, auf die wir abzielen (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 allzu wichtig; es legt das Element aus und stellt sicher, dass die Attribute background-color und border an CSS-Übergängen teilnehmen können, die wir verwenden werden, um die Änderungen am Element zu bewirken, wenn 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 verwendet, um Dinge geschehen zu lassen.
Einrichtung
Zuerst müssen wir einige Variablen vorbereiten und den Observer installieren.
const numSteps = 20.0; const boxElement = document.querySelector("#box"); let prevRatio = 0.0; let increasingColor = "rgb(40 40 190 / ratio)"; let decreasingColor = "rgb(190 40 40 / ratio)"; createObserver(); 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 festzuhalten, wie hoch das Sichtbarkeitsverhältnis war, als das letzte Mal ein Schwellenwert überschritten wurde; dies ermöglicht es uns herauszufinden, ob das Zielelement mehr oder weniger sichtbar wird.
increasingColor-
Eine Zeichenfolge, die eine Farbe definiert, die wir auf das Zielelement anwenden, wenn das Sichtbarkeitsverhältnis steigt. Das Wort "ratio" in dieser Zeichenfolge 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 eine Zeichenfolge, die eine Farbe definiert, die wir anwenden, wenn das Sichtbarkeitsverhältnis abnimmt.
Wir erhalten eine Referenz auf das Element mit der ID "box" mithilfe von querySelector(), rufen dann die Methode createObserver() auf, die wir gleich erstellen werden, um den Aufbau und die Installation des Intersection Observers zu handhaben.
Erstellen des Intersection Observers
Die Methode createObserver() wird einmal nach dem Laden der Seite aufgerufen, um den neuen IntersectionObserver tatsächlich zu erstellen und den Vorgang der Beobachtung des Zielelements zu starten.
function createObserver() { const options = { root: null, rootMargin: "0px", threshold: buildThresholdList(), }; const observer = new IntersectionObserver(handleIntersect, options); observer.observe(boxElement); } Dies beginnt mit dem Einrichten eines options-Objekts, das die Einstellungen für den Observer enthält. Wir möchten Änderungen der Sichtbarkeit des Zielelements relativ zum Viewport des Dokuments beobachten, daher ist root null. Wir benötigen keine Ränder, daher ist der Randabstand, rootMargin, auf "0px" festgelegt. Dies veranlasst den Observer, Änderungen in der Überschneidung zwischen den Grenzen des Zielelements und denen des Viewports zu beobachten, ohne zusätzlichen (oder abgezogenen) Raum.
Die Liste der Sichtbarkeitsverhältnis-Schwellenwerte, threshold, wird durch die Funktion buildThresholdList() erstellt. Die Schwellenwerteliste wird in diesem Beispiel programmgesteuert erstellt, da es eine Anzahl davon gibt und die Anzahl eingestellt werden soll, um variabel zu sein.
Sobald options bereit ist, erstellen wir den neuen Observer, indem wir den IntersectionObserver()-Konstruktor aufrufen, eine Funktion angeben, die aufgerufen wird, wenn die Überschneidung einen unserer Schwellenwerte überschreitet, handleIntersect(), und unsere Einstellung von Optionen. Wir rufen dann observe() auf dem zurückgegebenen Observer auf, indem wir ihm das gewünschte Zielelement übergeben.
Wir könnten entscheiden, den Sichtbarkeitsübergang mehrerer Elemente relativ zum Viewport zu überwachen, indem wir observer.observe() für jedes dieser Elemente aufrufen, wenn wir dies tun möchten.
Erstellen des Arrays der Schwellenwerte-Verhältnisse
Die Funktion buildThresholdList(), die die Schwellenwerteliste erstellt, sieht so aus:
function buildThresholdList() { const thresholds = []; const numSteps = 20; for (let i = 1.0; i <= numSteps; i++) { const ratio = i / numSteps; thresholds.push(ratio); } thresholds.push(0); return thresholds; } Dies erstellt das Array von Schwellenwerten - jede davon ist ein Verhältnis zwischen 0.0 und 1.0, indem der Wert i/numSteps für jedes ganzzahlige i zwischen 1 und numSteps auf das thresholds-Array geschoben wird. Es schiebt auch 0, um diesen Wert einzuschließen. Das Ergebnis, gegeben mit dem Standardwert von numSteps (20), ergibt die 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 wird es das sein, was Sie tun werden. Aber dieses Beispiel lässt Raum für das Hinzufügen von Konfigurationssteuerungen, um die Granularität zum Beispiel anzupassen.
Umgang mit Überschneidungsänderungen
Wenn der Browser erkennt, dass das Zielelement (in unserem Fall das, das die ID "box" hat) so freigelegt oder verdeckt wurde, dass sein Sichtbarkeitsverhältnis einer unserer Schwellenwerte in der Liste überschreitet, ruft es unsere Handlerfunktion 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 jeden IntersectionObserverEntry in der Liste entries überprüfen wir, ob das intersectionRatio des Eintrags steigt; wenn dies der Fall ist, setzen wir die background-color des Ziels auf die Zeichenfolge in increasingColor (denken Sie daran, es ist "rgb(40 40 190 / ratio)"), ersetzt das Wort "ratio" mit dem intersectionRatio des Eintrags. Das Ergebnis: nicht nur die Farbe ändert sich, sondern auch die Transparenz des Zielelements ändert sich; wenn das Überschneidungsverhältnis sinkt, sinkt der Alphawert der Hintergrundfarbe, was zu einem transparenteren Element führt.
Ebenso verwenden wir im Fall, dass das intersectionRatio abnimmt, die Zeichenfolge decreasingColor und ersetzen dabei das Wort "ratio" durch das intersectionRatio, bevor wir die background-color des Zielelements setzen.
Schließlich merken wir uns, um zu ermitteln, ob das Überschneidungsverhältnis steigt oder fällt, das aktuelle Verhältnis in der Variable prevRatio.
Ergebnis
Unten sehen Sie den resultierenden Inhalt. Scrollen Sie diese Seite hoch und runter und beachten Sie, wie sich das Erscheinungsbild der Box ändert, während Sie dies tun.
Ein noch umfangreicheres Beispiel finden Sie unter Timing element visibility with the Intersection Observer API.
Spezifikationen
| Specification |
|---|
| Intersection Observer> # intersection-observer-interface> |