Signatur
Beschreibung
Die schreibgeschützte Eigenschaft isIntersecting eines IntersectionObserverEntry gibt an, ob sich das Ziel-Element zum Zeitpunkt der Meldung mit dem Root-Element überschneidet. Standardmäßig ist das der Viewport. Bei true ist das Element in den Überschneidungszustand eingetreten, bei false hat es ihn verlassen.
Mit dieser Eigenschaft unterscheidet man im Callback am einfachsten und zuverlässigsten, ob ein Element ins Bild kommt oder das Bild verlässt. Typische Einsatzfälle sind:
- Lazy Loading von Bildern und iframes
- Infinite Scrolling mit einem „Sentinel“-Element am Listenende
- Animationen oder Videos starten und stoppen
- Sichtbarkeits-Tracking, etwa für Impressionen in Statistiken
Wichtig: isIntersecting ist auch dann true, wenn sich Ziel und Root nur an einer Kante berühren und die Schnittfläche null ist (intersectionRatio === 0). Deshalb sollte man isIntersecting einer Prüfung auf intersectionRatio > 0 vorziehen. Wann eine Meldung ausgelöst wird, hängt außerdem von den Optionen threshold und rootMargin des Observers ab.
Rückgabewert
true, wenn das Ziel den Root (inklusive rootMargin) schneidet oder berührt, sonst false.Beispiele
Lazy Loading von Bildern
// <img data-src="foto.jpg" class="lazy" alt="">
const observer = new IntersectionObserver((entries, obs) => {
for (const entry of entries) {
if (!entry.isIntersecting) continue;
const img = entry.target;
img.src = img.dataset.src;
obs.unobserve(img); // nur einmal laden
console.log(`Geladen: ${img.dataset.src}`);
}
}, { rootMargin: '200px 0px' }); // 200px im Voraus laden
document.querySelectorAll('img.lazy').forEach((img) => observer.observe(img));
Video beim Ein- und Austreten starten/pausieren
const video = document.querySelector('video');
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
video.play().catch(() => {}); // Autoplay kann blockiert sein
console.log('Video sichtbar – läuft');
} else {
video.pause();
console.log('Video außer Sicht – pausiert');
}
}, { threshold: 0.5 });
observer.observe(video);
Infinite Scrolling mit Sentinel-Element
const list = document.querySelector('#liste');
const sentinel = document.querySelector('#ende');
let page = 1;
let loading = false;
const loadMore = async () => {
loading = true;
const res = await fetch(`/api/items?page=${page++}`);
const items = await res.json();
for (const item of items) {
const li = document.createElement('li');
li.textContent = item.title;
list.append(li);
}
loading = false;
};
new IntersectionObserver(([entry]) => {
if (entry.isIntersecting && !loading) loadMore();
}).observe(sentinel);
// Wichtig · Fallstricke
- Erster Callback: Direkt nach
observe()wird der Callback einmal mit dem Ausgangszustand aufgerufen, auch wenn das Element nicht sichtbar ist. Dann giltisIntersecting === false. Fragen Sie deshalb immer den Wert ab, statt jeden Aufruf als „sichtbar“ zu behandeln. - Kantenberührung: Berührt das Ziel den Root nur an einer Kante, ist der Wert
true, währendintersectionRatio0ist. Nutzen Sie alsoisIntersectingstattintersectionRatio > 0. - Threshold-Verhalten: Bei einem
thresholdgrößer 0 (etwa0.5) kommen Meldungen nur, wenn die Schwelle überschritten wird.isIntersectingkann dabeitruesein, obwohl das Element weniger als 50 % sichtbar ist, etwa beim Herausscrollen. Prüfen Sie für exakte Schwellen zusätzlichintersectionRatio >= 0.5. - Sichtbarkeit:
isIntersectingsagt nichts darüber aus, ob das Element tatsächlich zu sehen ist. Verdeckung,opacity: 0odervisibility: hiddenfließen nicht ein. Für echte Sichtbarkeit gibt es IntersectionObserver v2 mitisVisible(nur in Chromium-Browsern). - Kompatibilität: Die Eigenschaft wird in allen modernen Browsern unterstützt. Ältere Versionen von Edge (15) und Safari (bis 12.0) kannten sie nicht; dort half nur ein Fallback über
intersectionRatio > 0. - Performance: Rufen Sie für einmalige Aktionen wie Lazy Loading
unobserve()auf, damit keine unnötigen Callbacks mehr ausgelöst werden.