Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

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, asynchron Änderungen der Überschneidung eines Zielelements mit einem übergeordneten Element oder mit dem Viewport eines obersten Dokuments 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 vom Nutzer aufgerufenen Websites träge zu machen. Mit der Reife des Webs ist das Bedürfnis nach solchen Informationen gewachsen. Informationen über Überschneidungen werden aus vielen Gründen benötigt, wie zum Beispiel:

  • Lazy-Loading von Bildern oder anderen Inhalten, während eine Seite gescrollt wird.
  • Implementierung von Websites mit "unendlichem Scrollen", bei denen immer mehr Inhalte geladen und gerendert werden, während man scrollt, damit der Nutzer nicht durch Seiten blättern muss.
  • Berichterstattung über die Sichtbarkeit von Anzeigen, um die Werbeeinnahmen zu berechnen.
  • Entscheidung darüber, ob Aufgaben oder Animationsprozesse ausgeführt werden sollen, basierend darauf, ob der Nutzer das Ergebnis sehen wird.

Das Implementieren der Überschneidungserkennung in der Vergangenheit beinhaltete Event-Handler und Schleifen, die Methoden wie Element.getBoundingClientRect() aufriefen, um die benötigten Informationen für jedes betroffene Element aufzubauen. Da all dieser Code im Hauptthread läuft, kann sogar einer dieser Prozesse zu Leistungsproblemen führen. Wenn eine Seite mit diesen Tests geladen ist, kann es regelrecht hässlich werden.

Betrachten Sie eine Webseite, die unendliches Scrollen verwendet. Sie benutzt eine von einem Anbieter bereitgestellte Bibliothek, um die periodisch auf der Seite platzierten Anzeigen zu verwalten, hat hier und da animierte Grafiken und nutzt eine benutzerdefinierte Bibliothek, die Benachrichtigungsboxen und dergleichen zeichnet. Jede dieser Routinen zur Überschneidungserkennung läuft im Hauptthread. Der Autor der Website könnte sich dessen nicht einmal bewusst sein, da er möglicherweise nur sehr wenig über das Innenleben der beiden Bibliotheken weiß, die er verwendet. Während der Nutzer die Seite scrollt, werden diese Routinen zur Überschneidungserkennung ständig während des Scrollvorgangs ausgelöst, was zu einer Erfahrung führt, die den Nutzer frustriert mit dem Browser, der Website und seinem Computer zurücklässt.

Die Intersection Observer API lässt den Code eine Callback-Funktion registrieren, die immer dann ausgeführt wird, wenn ein bestimmtes Element ein- oder aus einer Überschneidung mit einem anderen Element (oder dem Viewport) eintritt oder verlässt, oder wenn sich die Überschneidung zwischen zwei Elementen um einen bestimmten Betrag ändert. Auf diese Weise müssen Websites nichts mehr im Hauptthread tun, um diese Art von Elementüberschneidung zu beobachten, und der Browser ist frei, die Verwaltung von Überschneidungen nach eigenem Ermessen zu optimieren.

Eine Sache, die die Intersection Observer API nicht kann: Logik basierend auf der genauen Anzahl der überlappenden Pixel auslösen oder spezifisch darauf, welche es sind. Sie löst nur den allgemeinen Anwendungsfall „Wenn sie sich mit irgendwo um N% überschneiden, muss ich etwas tun“ aus.

Konzepte und Anwendung

Die Intersection Observer API ermöglicht es Ihnen, einen Callback zu konfigurieren, der aufgerufen wird, wenn eine der folgenden Bedingungen eintritt:

  • Ein Zielelement überschneidet entweder den Geräte-Viewport oder ein angegebenes Element. Dieses angegebene Element wird zu Zwecken der Intersection Observer API als Wurzelelement oder Wurzel bezeichnet.
  • Das erste Mal, wenn der Observer ursprünglich gebeten wird, ein Zielelement zu beobachten.

Typischerweise möchten Sie Änderungen der Überschneidung in Bezug auf den nächsten scrollbaren Vorfahren des Zielelements beobachten, oder, wenn das Zielelement kein Nachkomme eines scrollbaren Elements ist, den Geräte-Viewport. Um die Überschneidung relativ zum Geräte-Viewport zu beobachten, geben Sie null für die root-Option an. Lesen Sie weiter für eine detailliertere Erklärung zu den Optionen des Intersection Observer.

Ob Sie den Viewport oder ein anderes Element als Wurzel verwenden, die API funktioniert 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 an Überschneidung mit der Wurzel überschreitet.

Der Grad der Überschneidung zwischen dem Zielelement und seiner Wurzel ist das Überschneidungsverhältnis. Dies ist eine Darstellung des Prozentsatzes des Zielelements, der als Wert zwischen 0,0 und 1,0 sichtbar ist.

Erstellung eines Intersection Observer

Erstellen Sie den Intersection Observer, indem Sie dessen Konstruktor aufrufen und eine Callback-Funktion übergeben, die jedes Mal ausgeführt wird, wenn ein Schwellenwert in die eine oder andere Richtung überschritten wird:

js
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 innerhalb des durch die root-Option angegebenen Elements sichtbar sind, der Callback aufgerufen wird.

Optionen des Intersection Observer

Das an den Konstruktor IntersectionObserver() übergebene options-Objekt 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 zur Überprüfung der Sichtbarkeit des Ziels verwendet wird. Muss der Vorfahre des Ziels sein. Standardmäßig wird der Browser-Viewport verwendet, wenn nicht angegeben oder wenn null.

rootMargin

Rand um die Wurzel. Ein String mit einem bis vier Werten, ähnlich der CSS-margin-Eigenschaft, z. B. "10px 20px 30px 40px" (oben, rechts, unten, links). Die Werte können nur in Pixeln (px) oder Prozent (%) angegeben werden. Diese Wertemenge dient dazu, jede Seite des Begrenzungsrahmens der Wurzel zu vergrößern oder zu verkleinern, bevor Überschneidungen berechnet werden. Negative Werte verkleinern den Begrenzungsrahmen des Wurzelelements und positive Werte vergrößern ihn. Der Standardwert, wenn nicht angegeben, ist "0px 0px 0px 0px".

scrollMargin

Rand um geschachtelte Scrollcontainer, der dieselben Werte annimmt und denselben Standard hat wie rootMargin. Die Ränder werden auf geschachtelte scrollbare Container angewendet, bevor Überschneidungen berechnet werden. Positive Werte vergrößern das Clipping-Rechteck des Containers, sodass Ziele früher überschneiden können, während negative Werte das Clipping-Rechteck 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, wenn die Sichtbarkeit die 50 %-Marke überschreitet, können Sie einen Wert von 0,5 verwenden. Wenn der Callback jedes Mal ausgeführt werden soll, wenn die Sichtbarkeit um weitere 25 % variiert, würden Sie das Array [0, 0.25, 0.5, 0.75, 1] angeben. Der Standard ist 0 (was bedeutet, dass der Callback ausgeführt wird, sobald das Zielelement die Grenze der Wurzel schneidet oder berührt, auch wenn noch keine Pixel sichtbar sind). Ein Wert von 1,0 bedeutet, dass der Schwellenwert nicht als überschritten betrachtet wird, bis jedes Pixel sichtbar ist.

delay Experimentell

Wenn die Sichtbarkeit des Ziels verfolgt wird (trackVisibility ist true), kann diese Option verwendet werden, um die minimale Verzögerung in Millisekunden zwischen Benachrichtigungen von diesem Observer festzulegen. Das Begrenzen der Benachrichtigungsrate ist wünschenswert, da die Sichtbarkeitsberechnung rechnerisch intensiv ist. Wenn Sie die Sichtbarkeit verfolgen, wird der Wert auf 100 gesetzt für jeden Wert unter 100 und Sie sollten den größten tolerierbaren Wert verwenden. Der Wert ist standardmäßig 0.

trackVisibility Experimentell

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 scrollt. Wenn true, ü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 Standardwert ist false, da das Verfolgen der Sichtbarkeit rechnerisch intensiv ist. Wenn dies gesetzt ist, sollte auch eine delay eingestellt werden.

Callbacks für Überschneidungsänderungen

Der an den Konstruktor IntersectionObserver() übergebene Callback erhält eine Liste von IntersectionObserverEntry-Objekten und den Observer:

js
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 vom Callback empfangenen Einträge enthält ein IntersectionObserverEntry-Objekt für jedes Schwellenwert-Überschreitungsereignis — es können mehrere Einträge gleichzeitig empfangen werden, entweder von mehreren Zielen oder von einem einzelnen Ziel, das in kurzer Zeit mehrere Schwellenwerte überschreitet. Die Einträge werden in einer Warteschlange versendet, daher sollten sie in der Reihenfolge des Generierens geordnet sein, aber Sie sollten vorzugsweise IntersectionObserverEntry.time verwenden, um sie korrekt zu ordnen. Jeder Eintrag beschreibt, wie viel von einem bestimmten Element mit dem Wurzelelement ü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 benötigen, die eine Verfolgung über die Zeit erfordern, wie die Scrollrichtung und -geschwindigkeit, müssen Sie das möglicherweise selbst berechnen, indem Sie zuvor empfangene Einträge speichern.

Beachten Sie, dass Ihr Callback im Hauptthread ausgeführt wird. Es sollte so schnell wie möglich arbeiten; wenn etwas zeitaufwändiges getan werden muss, verwenden Sie Window.requestIdleCallback().

Der folgende Codeausschnitt zeigt einen Callback, der zählt, wie oft Elemente vom Nichtüberschneiden der Wurzel zum Überschneiden mit mindestens 75 % übergehen. Bei einem Schwellenwert von 0,0 (Standard) wird der Callback ungefähr beim Übergang des booleschen Werts von isIntersecting aufgerufen. Der Ausschnitt prüft also zuerst, ob der Übergang ein positiver ist, und bestimmt dann, ob intersectionRatio über 75 % liegt, in diesem Fall erhöht er den Zähler.

js
const intersectionCallback = (entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      let elem = entry.target;

      if (entry.intersectionRatio >= 0.75) {
        intersectionCounter++;
      }
    }
  });
};

Ein Element zum Beobachten anvisieren

Sobald Sie den Observer erstellt haben, müssen Sie ihm ein Zielelement zum Beobachten angeben:

js
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)

Immer wenn das Ziel einen für den IntersectionObserver angegebenen Schwellenwert erreicht, wird der Callback ausgeführt.

Beachten Sie auch, dass das Ziel ein Nachkomme des Wurzelelements sein muss, wenn Sie die Option root angegeben haben.

Wie die Überschneidung 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 umfasst. Ähnlich verhält es sich, wenn der sichtbare Teil eines Elements nicht rechteckig ist, das Überschneidungsrechteck des Elements wird 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 Überschneidung beschreiben.

Die Wurzel der Überschneidung und der Wurzelabstand

Bevor wir die Überschneidung eines Elements mit einem Container verfolgen können, müssen wir wissen, was dieser Container ist. Dieser Container ist die Überlappungswurzel oder das Wurzelelement. Dies kann entweder ein bestimmtes Element im Dokument sein, das ein Vorfahre des zu beobachtenden Elements ist, oder null, um den Dokumentenviewport als den Container zu verwenden.

Das Wurzel-Überlappungsrechteck ist das Rechteck, das zur Überprüfung gegenüber dem Ziel oder den Zielen verwendet wird. Dieses Rechteck wird wie folgt bestimmt:

  • Wenn die Überlappungswurzel die implizite Wurzel ist (d.h. das oberste Dokument), ist das Wurzel-Überlappungsrechteck das Rechteck des Viewports.
  • Wenn die Überlappungswurzel einen Überlaufausschnitt hat, ist das Wurzel-Überlappungsrechteck der Inhaltsbereich des Wurzelelements.
  • Andernfalls ist das Wurzel-Überlappungsrechteck das Begrenzungsrechteck der Überlappungswurzel (wie durch den Aufruf von getBoundingClientRect() darauf zurückgegeben).

Das Wurzel-Überlappungsrechteck kann weiter durch Festlegen des Wurzelabstands, rootMargin, beim Erstellen des IntersectionObserver angepasst werden. Die Werte in rootMargin definieren Offsets, die zu jeder Seite des Begrenzungsrahmens der Überlappungswurzel hinzugefügt werden, um die endgültigen Wurzel-Überlappungsgrenzen zu erzeugen (die in IntersectionObserverEntry.rootBounds offengelegt werden, wenn der Callback ausgeführt wird). Positive Werte vergrößern den Rahmen, während negative Werte ihn verkleinern. Jeder Offsetwert kann nur in Pixeln (px) oder Prozent (%) ausgedrückt werden.

Der Effekt, den Rahmen durch den Wurzelabstand zu vergrößern, besteht darin, Überlaufziele zu ermöglichen, mit der Wurzel zu überschneiden, bevor sie sichtbar werden. Dies kann beispielsweise verwendet werden, um mit dem Laden von Bildern kurz bevor sie in den Sichtbereich kommen zu beginnen, anstatt zu dem Zeitpunkt, an dem sie sichtbar werden.

Im folgenden Beispiel haben wir ein scrollbares Feld und ein Element, das zunächst nicht sichtbar ist. Sie können den rechten Wurzelabstand anpassen und sehen, dass:

  • Wenn der Abstand positiv ist, wird das rote Element als mit der Wurzel überschneidend angesehen, auch wenn es nicht sichtbar ist, da es mit dem Bereich des Wurzelabstands überschneidet.
  • Wenn der Abstand negativ ist, wird das rote Element, auch wenn es beginnt sichtbar zu werden, immer noch nicht als mit der Wurzel überschneidend angesehen, weil das Begrenzungsrechteck der Wurzel verkleinert wird.

Die Überlappungswurzel und der Scrollabstand

Betrachten Sie den Fall, in dem Sie ein Wurzelelement haben, das geschachtelte Scrollcontainer enthält und Sie Überschneidungen mit einem Ziel innerhalb eines dieser scrollbaren Container beobachten möchten. Überschneidungen mit dem Zielelement sind standardmäßig beobachtbar, wenn das Ziel innerhalb des durch die Wurzel definierten Bereichs sichtbar ist; mit anderen Worten, wenn der Container in der Wurzel in den Sichtbereich gescrollt wird und das Ziel innerhalb des Clipping-Rechtecks seines Containers in den Sichtbereich gescrollt wird.

Sie können einen Scrollabstand verwenden, um Überschneidungen zu beginnen, bevor oder nachdem das Ziel innerhalb seines Scrollcontainers in den Sichtbereich gescrollt wird. Der Abstand wird zu allen geschachtelten Scrollcontainern in der Wurzel hinzugefügt, einschließlich des Wurzelelements, wenn es auch ein Scrollcontainer ist, und hat den Effekt, entweder die Clippingregion (positive Abstände) zu vergrößern oder zu verkleinern (negative Abstände), die zum Berechnen von Überschneidungen verwendet wird.

Hinweis: Sie könnten einen Intersection Observer an jedem Scrollcontainer erstellen, für den Sie einen Scrollabstand haben möchten, und die Rootmargin-Eigenschaft verwenden, um einen ähnlichen Effekt zu erzielen. Das Verwenden eines Scrollabstands ist ergonomischer, da Sie in den meisten Fällen nur einen Intersection Observer für alle geschachtelten Ziele haben können.

Im folgenden Beispiel haben wir ein scrollbares Feld und ein Bildkarussell, das zunächst aus dem Sichtbereich ist. Ein Beobachter auf dem Wurzelelement beobachtet die Bildzielobjekte innerhalb des Karussells. Wenn ein Bildelement beginnt, sich mit dem Wurzelelement zu überschneiden, wird das Bild geladen, die Überschneidung protokolliert und der Beobachter entfernt.

Scrollen Sie nach unten, um das Karussell anzuzeigen. Die sichtbaren Bilder sollten sofort geladen werden. Wenn Sie das Karussell scrollen, sollten Sie feststellen, dass die Bilder geladen werden, sobald das Element sichtbar wird.

Nach dem Zurücksetzen des Beispiels können Sie die bereitgestellte Kontrolle verwenden, um den Prozentsatz des Scrollabstands zu ändern. Wenn Sie einen positiven Wert wie 20 % einstellen, wird das Clip-Rechteck des Scrollcontainers um 20 % vergrößert und Sie sollten beobachten, dass Bilder erkannt und geladen werden, bevor sie in den Sichtbereich kommen. Ebenso bedeutet ein negativer Wert, dass die Überschneidung erkannt wird, sobald Bilder bereits im Sichtbereich sind.

Schwellenwerte

Anstatt jede minimale Änderung in der Sichtbarkeit eines Zielelements zu melden, verwendet die Intersection Observer API Schwellenwerte. Wenn Sie einen Beobachter erstellen, können Sie einen oder mehrere numerische Werte angeben, die den Prozentsatz des Zielelements darstellen, der sichtbar ist. Die API meldet dann nur Änderungen der Sichtbarkeit, die diese Schwellenwerte überschreiten.

Wenn Sie beispielsweise jedes Mal informiert werden möchten, wenn die Sichtbarkeit eines Ziels rückwärts oder vorwärts durch jeden 25 %-Marke geht, würden Sie das Array [0, 0.25, 0.5, 0.75, 1] als die Liste der Schwellenwerte angeben, wenn Sie den Beobachter erstellen.

Wenn der Callback aufgerufen wird, erhält er eine Liste von IntersectionObserverEntry-Objekten, eines für jedes beobachtete Ziel, dessen Grad an Überschneidung mit der Wurzel sich so geändert hat, dass der freigelegte Anteil einen der Schwellenwerte in irgendeine Richtung überschreitet.

Sie können sehen, ob das Ziel derzeit die Wurzel überschneidet, indem Sie die isIntersecting-Eigenschaft des Eintrags betrachten; wenn sein Wert true ist, überschneidet das Ziel mindestens teilweise das Wurzelelement oder Dokument. Auf diese Weise können Sie feststellen, ob der Eintrag einen Übergang von der Überschneidung der Elemente zum Nicht-Überschneiden oder einen Übergang vom Nicht-Überschneiden zur Überschneidung darstellt.

Beachten Sie, dass es möglich ist, ein Null-Überschneidungsrechteck zu haben, was passieren kann, wenn die Überschneidung genau entlang der Grenze zwischen den beiden liegt oder die Fläche von boundingClientRect Null ist. Dieser Zustand, dass das Ziel und die Wurzel eine Grenzlinie teilen, wird nicht als ausreichend betrachtet, um als Übergang in einen sich überschneidenden Zustand betrachtet zu werden.

Um ein Gefühl dafür zu bekommen, wie Schwellenwerte funktionieren, versuchen Sie, die Box unten herum zu scrollen. Jede farbige Box darin zeigt den Prozentsatz ihrer selbst, der in allen vier Ecken ihrer sichtbar ist, 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 andere Menge an Schwellenwerten:

  • Die erste Box hat einen Schwellenwert für jeden Prozentpunkt an Sichtbarkeit; das heißt das IntersectionObserver.thresholds Array ist [0.00, 0.01, 0.02, /*…,*/ 0.99, 1.00].
  • Die zweite Box hat einen einzigen Schwellenwert, bei der 50 %-Marke.
  • Die dritte Box hat Schwellenwerte alle 10 % Sichtbarkeit (0 %, 10 %, 20 % usw.).
  • Die letzte Box hat jeweils 25 % Schwellenwerte.

Sichtbarkeit verfolgen und verzögern

Standardmäßig liefert der Beobachter 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 "optisch kompromittiert" wurde. Beispielsweise ist es wichtig, bei der Messung von Analysen oder Werbesichtungen, dass Zielelemente nicht versteckt oder verzerrt werden, ganz oder teilweise.

Die Option trackVisibility sagt dem Beobachter, nur Überschneidungen für Ziele zu melden, die der Browser nicht für optisch kompromittiert hält, wie durch das Ändern der Deckkraft oder das Anwenden eines Filters oder einer Transformation. Der Algorithmus ist konservativ und kann Elemente weglassen, die technisch sichtbar sind, wie die mit nur einer geringfügigen Deckkraftreduzierung.

Die Sichtbarkeitsberechnung ist rechnerisch teuer und sollte nur verwendet werden, wenn sie benötigt wird. Beim Verfolgen der Sichtbarkeit sollte auch eine delay eingestellt werden, um die minimale Berichtsperiode zu begrenzen. Die Empfehlung ist, die Verzögerung auf den größten tolerierbaren Wert einzustellen (die minimale Verzögerung beim Verfolgen der Sichtbarkeit beträgt 100 Millisekunden).

Clipping 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 Überschneidungen auftreten werden.

  1. Das Begrenzungsrechteck des Zielelements (das heißt, das kleinste Rechteck, das die Begrenzungsrahmen jeder Komponente, die das Element bildet, vollständig einschließt) wird durch den Aufruf von getBoundingClientRect() auf dem Ziel abgerufen. Dies ist das größte, das das Überschneidungsrechteck sein kann. Die verbleibenden Schritte werden alle nicht überschneidenden Anteile entfernen.
  2. Beginnend beim unmittelbaren übergeordneten Block des Ziels und nach außen gehend wird jede enthaltene Block-Clipping (falls vorhanden) auf das Überschneidungsrechteck angewendet. Ein Block-Clipping wird basierend auf der Überschneidung der beiden Blöcke und dem Clipping-Modus (falls vorhanden), der durch die overflow-Eigenschaft angegeben wird, bestimmt. Das Setzen von overflow auf alles außer visible führt zum Clipping.
  3. Wenn eines der enthaltenden Elemente die Wurzel eines geschachtelten Browsing-Kontexts ist (wie das Dokument, das in einem <iframe> enthalten ist), wird das Überschneidungsrechteck auf den Viewport des enthaltenden Kontexts zugeschnitten, und die Rekursion nach oben durch die Container wird mit dem enthaltenen Block des Containers fortgesetzt. Wenn also die oberste Ebene eines <iframe> erreicht wird, wird das Überschneidungsrechteck auf den Viewport des Rahmens zugeschnitten, dann ist das übergeordnete Element des Rahmens der nächste Block, der rekursiv zur Überlappungswurzel durchlaufen wird.
  4. Wenn die Rekursion nach oben die Überlappungswurzel erreicht, wird das resultierende Rechteck in den Koordinatenraum der Überlappungswurzel abgebildet.
  5. Das resultierende Rechteck wird dann aktualisiert, indem es mit dem Wurzel-Überlappungsrechteck überschneidet.
  6. Dieses Rechteck wird schließlich in den Koordinatenraum des Dokuments des Ziels abgebildet.

Schnittstellen

IntersectionObserver

Die primäre Schnittstelle für die Intersection Observer API. Bietet Methoden zum Erstellen und Verwalten eines Beobachters, der Änderungen in der Überschneidung zwischen einem oder mehreren Zielelementen und einem gemeinsamen Vorfahrenelement oder dem Viewport ihres obersten Dokuments asynchron beobachten kann. Der Vorfahre oder der Viewport wird als Wurzel bezeichnet.

IntersectionObserverEntry

Beschreibt die Überschneidung zwischen dem Zielelement und seinem Wurzelcontainer zu einem bestimmten Übergangsmoment. Objekte dieses Typs können nur auf zwei Arten abgerufen werden: als Eingabe für Ihren IntersectionObserver-Callback oder durch den Aufruf von IntersectionObserver.takeRecords().

Ein einfaches Beispiel

Dieses einfache Beispiel lässt ein Zielelement seine Farbe und Transparenz ändern, wenn es mehr oder weniger sichtbar wird. Bei Timing der Elementsichtbarkeit mit der Intersection Observer API finden Sie ein ausführlicheres Beispiel, das zeigt, wie lange ein Satz von Elementen (wie Anzeigen) für den Benutzer sichtbar ist, und darauf reagiert, indem Statistiken aufzeichnen oder Elemente aktualisiert werden.

HTML

Das HTML für dieses Beispiel ist sehr kurz, mit einem primären Element, das die Box ist, die wir anvisieren werden (mit der kreativen ID "box"), und einigen Inhalten innerhalb der Box.

html
<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 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.

css
#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.

js
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 zu erfassen, was das Sichtbarkeitsverhältnis beim letzten Überschreiten eines Schwellenwerts war; dies ermöglicht es uns herauszufinden, ob das Zielelement mehr oder weniger sichtbar wird.

increasingColor

Ein String, der eine Farbe definiert, die wir auf das Zielelement anwenden werden, wenn das Sichtbarkeitsverhältnis steigt. Das Wort "ratio" in diesem String wird durch das aktuelle Sichtbarkeitsverhältnis des Ziels ersetzt, damit das Element nicht nur die Farbe ändert, sondern auch zunehmend deckend wird, wenn es weniger verdeckt wird.

decreasingColor

Ebenso ist dies ein String, der eine Farbe definiert, die wir anwenden, wenn das Sichtbarkeitsverhältnis sinkt.

Wir erhalten eine Referenz auf das Element mit der ID "box" mit querySelector() und rufen dann die Methode createObserver() auf, die wir gleich erstellen werden, um die Erstellung und Installation des Intersection Observer zu behandeln.

Den Intersection Observer erstellen

Die Methode createObserver() wird nach dem Laden der Seite einmal aufgerufen, um den neuen IntersectionObserver tatsächlich zu erstellen und den Beobachtungsprozess für das Zielelement zu starten.

js
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-Objektes, das die Einstellungen für den Observer enthält. Wir möchten Änderungen der Sichtbarkeit des Zielelements relativ zum Dokumentenviewport beobachten, also ist root null. Wir benötigen keine Marge, daher wird die Margenverschiebung, rootMargin, als "0px" angegeben. Dies führt dazu, dass der Beobachter Änderungen in der Überschneidung zwischen den Grenzen des Zielelements und denen des Viewports beobachtet, ohne dass zusätzlicher (oder subtrahierter) Platz entsteht.

Die Liste der Schwellenwerte für das Sichtbarkeitsverhältnis, threshold, wird durch die Funktion buildThresholdList() erstellt. Die Schwellenwertliste wird in diesem Beispiel programmgesteuert erstellt, da es mehrere davon gibt und die Anzahl anpassbar sein soll.

Sobald options bereit ist, erstellen wir den neuen Beobachter, indem wir den Konstruktor IntersectionObserver() aufrufen und eine Funktion spezifizieren, die aufgerufen wird, wenn eine Überschneidung einen unserer Schwellenwerte überschreitet, handleIntersect(), und unser Set von Optionen. Dann rufen wir observe() auf dem zurückgegebenen Beobachter auf und übergeben ihm das gewünschte Zielelement.

Wir könnten uns entscheiden, mehrere Elemente auf Sichtbarkeitsüberschneidungsänderungen im Hinblick auf den Viewport zu überwachen, indem wir observer.observe() für jedes dieser Elemente aufrufen, wenn wir dies tun wollten.

Das Array von Schwellenwertverhältnissen aufbauen

Die Funktion buildThresholdList(), die die Liste der Schwellenwerte erstellt, sieht so aus:

js
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 baut das Array der Schwellenwerte auf — jeder davon ist ein Verhältnis zwischen 0,0 und 1,0, indem der Wert i/numSteps für jede ganze Zahl i zwischen 1 und numSteps in das thresholds-Array eingefügt wird. Es wird auch 0 hinzugefügt, um diesen Wert zu enthalten. Das Ergebnis, angesichts des Standardwerts von numSteps (20), ist 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 einprogrammieren, und oft werden Sie genau das tun. Aber dieses Beispiel lässt Raum für das Hinzufügen von Steuerungen zur Anpassung der Granularität, zum Beispiel.

Umgang mit Überschneidungsänderungen

Wenn der Browser erkennt, dass das Zielelement (in unserem Fall das mit der ID "box") enthüllt oder verdeckt wurde, sodass sein Sichtbarkeitsverhältnis einen unserer Schwellenwerte in unserer Liste überschreitet, ruft er unsere Handlerfunktion handleIntersect() auf:

js
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 jedes IntersectionObserverEntry in der Liste entries schauen wir, ob das intersectionRatio des Eintrags steigt. Wenn es steigt, setzen wir die background-color des Ziels auf den String in increasingColor (denken Sie daran, es ist "rgb(40 40 190 / ratio)"), ersetzen das Wort "ratio" mit dem intersectionRatio des Eintrags. Das Ergebnis: Das Ziel ändert nicht nur die Farbe, sondern auch die Transparenz; wenn das Überschneidungsverhältnis sinkt, sinkt der Alphawert der Hintergrundfarbe, was zu einem Element führt, das mehr transparent wird.

Ebenso, wenn das intersectionRatio sinkt, verwenden wir den String decreasingColor und ersetzen das Wort "ratio" durch das intersectionRatio, bevor wir die background-color des Zielelements setzen.

Schließlich merken wir uns, um zu verfolgen, ob das Überschneidungsverhältnis steigt oder sinkt, das aktuelle Verhältnis in der Variable prevRatio.

Ergebnis

Unten ist das resultierende Inhalt. Scrollen Sie diese Seite nach oben und unten und bemerken Sie, wie sich das Erscheinungsbild der Box verändert, während Sie dies tun.

Es gibt ein noch umfangreicheres Beispiel bei Timing der Elementsichtbarkeit mit der Intersection Observer API.

Spezifikationen

Specification
Intersection Observer
# intersection-observer-interface

Browser-Kompatibilität

Siehe auch