Signatur
Beschreibung
Die Eigenschaft intersectionRect einer IntersectionObserverEntry liefert ein DOMRectReadOnly. Es ist das kleinste Rechteck, das den ganzen Teil des Zielelements umschließt, der gerade mit dem Root-Bereich überlappt, also mit dem Viewport oder dem als root angegebenen Element (einschließlich rootMargin). Die Koordinaten beziehen sich auf den Viewport, genau wie bei getBoundingClientRect().
Berechnet wird das Rechteck so: Man nimmt boundingClientRect des Ziels und schneidet es mit allen Clipping-Vorfahren (Elemente mit overflow ungleich visible) und am Ende mit rootBounds. Ist das Ziel nicht sichtbar, sind Breite und Höhe 0.
Brauchbar ist die Eigenschaft immer dann, wenn eine Ja/Nein-Antwort (isIntersecting) oder ein Anteil (intersectionRatio) nicht reicht und man wissen will, welcher Bereich sichtbar ist. Typische Fälle: sichtbare Pixel messen (zum Beispiel für Werbe-Sichtbarkeit), feststellen, ob ein Element oben oder unten angeschnitten ist, oder Hervorhebungen und Overlays nur über dem sichtbaren Teil platzieren.
Rückgabewert
x, y, width, height, top, right, bottom und left in CSS-Pixeln, relativ zum Viewport. Ohne Überschneidung sind width und height 0.Beispiele
Sichtbare Pixelfläche eines Werbebanners messen
const banner = document.querySelector('#ad-banner');
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
const { width, height } = entry.intersectionRect;
const sichtbarePixel = Math.round(width * height);
console.log(`Sichtbar: ${sichtbarePixel} px² (${Math.round(entry.intersectionRatio * 100)} %)`);
}
}, { threshold: [0, 0.25, 0.5, 0.75, 1] });
observer.observe(banner);
Erkennen, ob ein Element oben oder unten angeschnitten ist
const card = document.querySelector('.card');
const observer = new IntersectionObserver(([entry]) => {
if (!entry.isIntersecting) {
console.log('Nicht sichtbar');
return;
}
const box = entry.boundingClientRect;
const sichtbar = entry.intersectionRect;
if (sichtbar.top > box.top) console.log('Oben abgeschnitten');
if (sichtbar.bottom < box.bottom) console.log('Unten abgeschnitten');
if (entry.intersectionRatio === 1) console.log('Vollständig sichtbar');
}, { threshold: Array.from({ length: 11 }, (_, i) => i / 10) });
observer.observe(card);
Overlay auf den sichtbaren Teil innerhalb eines Scroll-Containers legen
const container = document.querySelector('#scroller');
const target = document.querySelector('#item-42');
const overlay = document.querySelector('#overlay');
const observer = new IntersectionObserver(([entry]) => {
const r = entry.intersectionRect;
if (r.width === 0 || r.height === 0) {
overlay.hidden = true;
return;
}
// Koordinaten beziehen sich auf den Viewport -> position: fixed
Object.assign(overlay.style, {
position: 'fixed',
left: `${r.left}px`,
top: `${r.top}px`,
width: `${r.width}px`,
height: `${r.height}px`
});
overlay.hidden = false;
}, { root: container, threshold: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1] });
observer.observe(target);
// Wichtig · Fallstricke
- Nur ein Schnappschuss: Das Rechteck gilt für den Moment, in dem der Eintrag erzeugt wurde. Es wird nicht bei jedem Scroll-Pixel aktualisiert, sondern nur, wenn ein
thresholdüberschritten wird. Wer feinere Werte will, muss mehr Schwellenwerte angeben. - Koordinatensystem: Die Werte beziehen sich auf den Viewport des obersten Dokuments. Das gilt auch dann, wenn ein eigenes
root-Element gesetzt ist. Um mit Dokumentkoordinaten zu rechnen,window.scrollXundwindow.scrollYaddieren. - Kein sicherer Sichtbarkeitsnachweis: CSS-Transformationen,
opacity,visibilityund Überdeckung durch andere Elemente fließen nicht ein. Ein Rechteck größer 0 heißt also nicht, dass das Element wirklich zu sehen ist. Dafür gibt es IntersectionObserver v2 mittrackVisibility(bisher nur in Chromium). - Iframes über Ursprungsgrenzen: Liegt das Ziel in einem Iframe mit anderem Ursprung, ist
rootBoundsaus Datenschutzgründennull.intersectionRectwird trotzdem berechnet. - Kompatibilität: Wird von allen modernen Browsern unterstützt (Chrome 51+, Firefox 55+, Safari 12.1+, Edge 15+). Der Internet Explorer braucht ein Polyfill.