Signatur
Beschreibung
Die schreibgeschützte Eigenschaft intersectionRatio eines IntersectionObserverEntry sagt, wie viel vom beobachteten Element gerade sichtbar ist. Berechnet wird das Verhältnis der Fläche von intersectionRect zur Fläche von boundingClientRect. Ist das Element vollständig sichtbar, liegt der Wert bei 1.0, ist es gar nicht sichtbar, bei 0.0.
Typische Anwendungsfälle sind Sichtbarkeits-Tracking (z. B. eine Werbeanzeige gilt erst ab 50 % Sichtbarkeit als gesehen), Scroll-Animationen, bei denen die Deckkraft oder Skalierung vom Sichtbarkeitsgrad abhängt, und Autoplay von Videos, sobald ein Großteil des Players im Viewport ist.
Wichtig: Der Callback wird nicht bei jedem Scroll-Pixel aufgerufen, sondern nur, wenn einer der in der Option threshold festgelegten Schwellenwerte überschritten wird. Wer einen feinen Verlauf braucht, muss ein Array mit vielen Schwellenwerten übergeben (z. B. 0, 0.01, 0.02 … 1).
Rückgabewert
0.0 und 1.0: der sichtbare Anteil des Zielelements relativ zu seiner Gesamtfläche.Beispiele
Sichtbarkeit in Prozent protokollieren
const box = document.querySelector('#box');
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
const prozent = Math.round(entry.intersectionRatio * 100);
console.log(`${entry.target.id}: ${prozent} % sichtbar`);
}
}, { threshold: [0, 0.25, 0.5, 0.75, 1] });
observer.observe(box);
Deckkraft an Sichtbarkeit koppeln (Fade-in beim Scrollen)
// 101 Schwellenwerte für einen gleichmäßigen Verlauf
const thresholds = Array.from({ length: 101 }, (_, i) => i / 100);
const observer = new IntersectionObserver((entries) => {
entries.forEach(({ target, intersectionRatio }) => {
target.style.opacity = intersectionRatio.toFixed(2);
});
}, { threshold: thresholds });
document.querySelectorAll('.fade').forEach((el) => observer.observe(el));
Video ab 50 % Sichtbarkeit abspielen
const video = document.querySelector('video');
const observer = new IntersectionObserver(([entry]) => {
if (entry.intersectionRatio >= 0.5) {
video.play().catch(() => {}); // Autoplay kann blockiert werden
} else {
video.pause();
}
}, { threshold: 0.5 });
observer.observe(video);
Anzeige-Impression erst ab 50 % zählen
const zaehleImpression = (id) => console.log(`Impression für ${id}`);
const observer = new IntersectionObserver((entries, obs) => {
entries.forEach((entry) => {
if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {
zaehleImpression(entry.target.dataset.adId);
obs.unobserve(entry.target); // nur einmal zählen
}
});
}, { threshold: 0.5 });
document.querySelectorAll('[data-ad-id]').forEach((ad) => observer.observe(ad));
// Wichtig · Fallstricke
- Kein kontinuierlicher Wert: Der Callback läuft nur beim Überschreiten der
threshold-Werte. Der gemeldete Wert liegt deshalb oft knapp über oder unter dem Schwellenwert (z. B.0.4987statt0.5). Vergleiche darum mit>=und etwas Spielraum, nie mit===. 0heißt nicht zwingend „nicht sichtbar“: Berührt das Element die Wurzel nur an der Kante oder hat es die Fläche 0 (z. B.height: 0), kannintersectionRatio0sein, obwohlisIntersectingtrueist. Um das Betreten zu erkennen, nimmisIntersecting.- Große Elemente: Ist das Element größer als der Viewport, kann es nie
1.0erreichen. Schwellenwerte wie1lösen dann nie aus. - Werte wie
rootMarginund die Optionrootverändern die Berechnung, weil sie die Schnittfläche beeinflussen. - Kompatibilität: wird von allen modernen Browsern unterstützt (Chrome 51+, Firefox 55+, Safari 12.1+, Edge 15+), aber nicht vom Internet Explorer. Für alte Browser gibt es einen Polyfill.