Start · Sprachen · JavaScript · Referenz · IntersectionObserver.observe()

IntersectionObserver.observe()

Methode

Fügt ein Element der Menge der Ziel-Elemente hinzu, deren Sichtbarkeit (Schnittmenge mit dem Root) der <code>IntersectionObserver</code> überwacht.

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

Signatur

IntersectionObserver.prototype.observe(target)

Beschreibung

Mit observe() legst du fest, welches Element ein IntersectionObserver überwachen soll. Ein Observer kann beliebig viele Ziel-Elemente gleichzeitig beobachten. Ändert sich das Verhältnis, in dem sich ein Ziel mit dem Root-Element (standardmäßig dem Viewport) überschneidet, und wird dabei einer der konfigurierten threshold-Werte überschritten, ruft der Browser den Callback mit einem IntersectionObserverEntry für dieses Element auf.

Typische Einsatzfälle sind Lazy Loading von Bildern und Komponenten, Infinite Scrolling, das Auslösen von Einblend-Animationen, das Messen von Sichtbarkeit (z. B. für Werbe-Impressions) oder das Hervorheben des aktuell sichtbaren Abschnitts in einem Inhaltsverzeichnis.

Wichtig: Direkt nach dem Aufruf von observe() liefert der Observer asynchron einen ersten Eintrag mit dem aktuellen Zustand des Elements – auch wenn es gar nicht sichtbar ist (dann mit isIntersecting === false). Dein Callback sollte daher immer entry.isIntersecting bzw. entry.intersectionRatio prüfen. Wird ein bereits beobachtetes Element erneut übergeben, passiert nichts.

Parameter

Name Typ Default Beschreibung
$target Pflicht Element Das zu beobachtende Element. Ist ein root gesetzt, muss target ein Nachfahre dieses Root-Elements sein, damit Schnittmengen erkannt werden.

Beispiele

Lazy Loading von Bildern

// <img data-src="bild.jpg" class="lazy" alt="...">
const observer = new IntersectionObserver((entries, obs) => {
  entries.forEach((entry) => {
    if (!entry.isIntersecting) return;
    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));

Einblend-Animation beim Scrollen

const revealObserver = new IntersectionObserver((entries) => {
  for (const entry of entries) {
    entry.target.classList.toggle('sichtbar', entry.isIntersecting);
    console.log(entry.target.id, entry.isIntersecting, entry.intersectionRatio.toFixed(2));
  }
}, { threshold: [0, 0.5, 1] });

document.querySelectorAll('section').forEach((section) => revealObserver.observe(section));
intro true 1.00 features false 0.00 kontakt false 0.00

Infinite Scrolling mit Sentinel-Element

const liste = document.querySelector('#liste');
const sentinel = document.querySelector('#sentinel');
let seite = 1;
let laedt = false;

const ladeMehr = async () => {
  laedt = true;
  const res = await fetch(`/api/artikel?seite=${seite++}`);
  const artikel = await res.json();
  for (const a of artikel) {
    const li = document.createElement('li');
    li.textContent = a.titel;
    liste.append(li);
  }
  if (artikel.length === 0) scrollObserver.disconnect();
  laedt = false;
};

const scrollObserver = new IntersectionObserver(([entry]) => {
  if (entry.isIntersecting && !laedt) ladeMehr();
});

scrollObserver.observe(sentinel);

// Wichtig · Fallstricke

  • Erster Callback sofort: Nach observe() wird der Callback für jedes Ziel einmal mit dem Ausgangszustand aufgerufen – auch bei nicht sichtbaren Elementen. Immer isIntersecting prüfen.
  • Kein Element: Wird kein Element übergeben (z. B. null aus einem fehlgeschlagenen querySelector), wirft der Aufruf einen TypeError.
  • Root-Beziehung: Ist target kein Nachfahre des konfigurierten root, liefert der Observer nie eine Schnittmenge.
  • Aufräumen: Beobachtete Elemente mit unobserve() abmelden bzw. den Observer mit disconnect() beenden (z. B. beim Entfernen einer Komponente), um unnötige Arbeit und Speicherlecks zu vermeiden.
  • Performance: Einen Observer für viele Elemente wiederzuverwenden ist günstiger, als pro Element einen eigenen zu erzeugen.
  • Kompatibilität: In allen modernen Browsern verfügbar (Chrome 51+, Firefox 55+, Safari 12.1+, Edge 15+). Für native Bild-Lazy-Loading reicht oft auch loading=\"lazy\".