Start · Sprachen · JavaScript · Referenz · IntersectionObserverEntry

IntersectionObserverEntry

Schnittstelle

Beschreibt die Überschneidung eines beobachteten Zielelements mit seinem Wurzel-Container zu einem bestimmten Übergangszeitpunkt.

seit JavaScript Baseline: alle modernen Browser (seit 2019) Kategorie: webapi

Signatur

interface IntersectionObserverEntry

Beschreibung

IntersectionObserverEntry-Objekte werden nicht selbst erzeugt. Der Browser übergibt sie als Array an den Callback eines IntersectionObserver, sobald ein beobachtetes Element einen der festgelegten Schwellenwerte (threshold) überschreitet. Außerdem entsteht direkt nach observe() ein erster Eintrag mit dem Anfangszustand. Einträge lassen sich auch synchron über observer.takeRecords() abholen.

Jeder Eintrag ist eine Momentaufnahme und enthält nur lesbare Eigenschaften:

  • target: das beobachtete Element.
  • isIntersecting: true, wenn sich das Ziel mit der Wurzel überschneidet (auch bei einer Überschneidung der Fläche 0 an der Kante).
  • intersectionRatio: Anteil des sichtbaren Bereichs am Ziel, zwischen 0.0 und 1.0.
  • boundingClientRect: das Begrenzungsrechteck des Ziels als DOMRectReadOnly.
  • intersectionRect: das sichtbare Schnittrechteck.
  • rootBounds: das Rechteck der Wurzel inklusive rootMargin. Bei ursprungsübergreifenden iframes kann es null sein.
  • time: ein DOMHighResTimeStamp mit dem Zeitpunkt der Überschneidung, relativ zur Entstehungszeit des Dokuments.

Typische Einsatzfälle sind Lazy Loading von Bildern, endloses Scrollen, Messen der Sichtbarkeit von Werbeflächen, Einblende-Animationen beim Scrollen und das Pausieren von Videos außerhalb des Viewports. Anders als Scroll-Handler mit getBoundingClientRect() läuft die Berechnung asynchron und blockiert den Haupt-Thread nicht.

Parameter

Name Typ Default Beschreibung
$target Pflicht Element Nur lesbar: das Element, dessen Überschneidung sich geändert hat.
$isIntersecting Pflicht boolean Nur lesbar: true, wenn das Ziel in den Überschneidungszustand übergeht oder sich darin befindet.
$intersectionRatio Pflicht number Nur lesbar: Verhältnis von intersectionRect zu boundingClientRect (0.0 bis 1.0).
$boundingClientRect Pflicht DOMRectReadOnly Nur lesbar: das Begrenzungsrechteck des Zielelements.
$intersectionRect Pflicht DOMRectReadOnly Nur lesbar: der sichtbare Schnittbereich von Ziel und Wurzel.
$rootBounds Pflicht DOMRectReadOnly | null Nur lesbar: das Rechteck der Wurzel inklusive rootMargin. null bei ursprungsübergreifenden Zielen.
$time Pflicht DOMHighResTimeStamp Nur lesbar: Zeitstempel der Überschneidungsänderung in Millisekunden.

Rückgabewert

Typ
IntersectionObserverEntry
Beschreibung
Wird vom Browser als Element des entries-Arrays an den Observer-Callback übergeben oder von takeRecords() zurückgegeben.

Beispiele

Lazy Loading von Bildern

// <img data-src="foto.jpg" class="lazy">
const observer = new IntersectionObserver((entries, obs) => {
  for (const entry of entries) {
    if (!entry.isIntersecting) continue;
    const img = entry.target;
    img.src = img.dataset.src;
    img.classList.remove('lazy');
    obs.unobserve(img); // nur einmal laden
  }
}, { rootMargin: '200px 0px' });

document.querySelectorAll('img.lazy').forEach((img) => observer.observe(img));

Eigenschaften eines Eintrags auswerten

const box = document.querySelector('#box');

const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    console.log({
      id: entry.target.id,
      sichtbar: entry.isIntersecting,
      anteil: entry.intersectionRatio.toFixed(2),
      hoeheSichtbar: Math.round(entry.intersectionRect.height),
      zeit: Math.round(entry.time)
    });
  });
}, { threshold: [0, 0.5, 1] });

observer.observe(box);
{ id: 'box', sichtbar: true, anteil: '0.50', hoeheSichtbar: 150, zeit: 1234 }

Sichtbarkeit einer Werbefläche messen (≥ 50 %)

const ad = document.querySelector('.ad');
let sichtbarSeit = null;
let gesamt = 0;

const observer = new IntersectionObserver(([entry]) => {
  if (entry.intersectionRatio >= 0.5) {
    sichtbarSeit ??= entry.time;
  } else if (sichtbarSeit !== null) {
    gesamt += entry.time - sichtbarSeit;
    sichtbarSeit = null;
    console.log(`Sichtbar insgesamt: ${Math.round(gesamt)} ms`);
  }
}, { threshold: [0, 0.5] });

observer.observe(ad);
Sichtbar insgesamt: 3120 ms

Scroll-Richtung über boundingClientRect erkennen

let letztesY = 0;

const observer = new IntersectionObserver(([entry]) => {
  const y = entry.boundingClientRect.y;
  const richtung = y < letztesY ? 'nach unten' : 'nach oben';
  letztesY = y;
  if (entry.isIntersecting) console.log(`Abschnitt betreten, Scrollrichtung: ${richtung}`);
});

observer.observe(document.querySelector('section'));
Abschnitt betreten, Scrollrichtung: nach unten

// Wichtig · Fallstricke

  • Erster Aufruf: Direkt nach observe() wird der Callback einmal mit dem Anfangszustand aufgerufen, auch wenn das Element nicht sichtbar ist. Deshalb immer isIntersecting prüfen.
  • isIntersecting statt intersectionRatio > 0: Ein Element, das die Wurzel nur an der Kante berührt, hat den Anteil 0, gilt aber trotzdem als überschneidend. Auch Elemente ohne Fläche (Höhe 0) haben immer den Anteil 0.
  • Keine Echtzeitwerte: Der Eintrag ist eine Momentaufnahme. Die Benachrichtigung kommt asynchron und nur, wenn ein Schwellenwert überschritten wird, nicht bei jedem gescrollten Pixel. Für pixelgenaue Animationen ist das ungeeignet.
  • rootBounds kann null sein: Das passiert, wenn das Ziel in einem ursprungsübergreifenden iframe liegt und keine explizite Wurzel angegeben ist. Aus Datenschutzgründen wird dann auch rootMargin ignoriert.
  • Mehrere Einträge: Das entries-Array kann mehrere Einträge für dasselbe Ziel enthalten. Ist nur der aktuelle Zustand wichtig, zählt der letzte Eintrag.
  • Browser-Kompatibilität: Wird von allen modernen Browsern unterstützt (Chrome 58+, Firefox 55+, Safari 12.1+). isIntersecting kam in manchen Browsern später dazu. Für sehr alte Umgebungen gibt es ein Polyfill.
  • Die Eigenschaften isVisible und trackVisibility gehören zu Intersection Observer v2 und gibt es nur in Chromium-Browsern.