Signatur
Beschreibung
Die Eigenschaft boundingClientRect eines IntersectionObserverEntry beschreibt das kleinste Rechteck, das das gesamte Zielelement umschließt. Der Wert wird genauso berechnet wie bei Element.getBoundingClientRect(), nur eben zu dem Zeitpunkt, an dem der Observer die Änderung registriert hat. Die Koordinaten beziehen sich auf den Viewport.
Nützlich ist die Eigenschaft, wenn man neben der Information ob ein Element sichtbar ist auch wissen will, wo es sich befindet. Typische Fälle sind z. B. die Scrollrichtung erkennen (verlässt das Element den Viewport oben oder unten?), Position-abhängige Animationen oder die Unterscheidung, ob ein Sticky-Header gerade „angeheftet“ ist.
Weil der Browser den Wert bereits im Rahmen der Schnittpunkt-Berechnung ermittelt hat, spart man sich einen zusätzlichen Aufruf von getBoundingClientRect() im Callback. Der würde ein synchrones Layout erzwingen (Layout Thrashing) und könnte außerdem schon einen anderen Wert liefern als zum Beobachtungszeitpunkt.
Rückgabewert
x, y, width, height, top, right, bottom und left in CSS-Pixeln, bezogen auf den Viewport.Beispiele
Position des Zielelements ausgeben
const target = document.querySelector('#banner');
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
const { top, left, width, height } = entry.boundingClientRect;
console.log(`Banner: top=${Math.round(top)}, left=${Math.round(left)}, ${width}×${height}`);
}
});
observer.observe(target);
Erkennen, ob das Element oben oder unten den Viewport verlässt
const section = document.querySelector('.kapitel');
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
console.log('Kapitel sichtbar');
return;
}
// Liegt die Oberkante oberhalb der Root, wurde nach unten weggescrollt
const rootTop = entry.rootBounds ? entry.rootBounds.top : 0;
const richtung = entry.boundingClientRect.top < rootTop ? 'oben' : 'unten';
console.log(`Kapitel hat den Viewport nach ${richtung} verlassen`);
});
observer.observe(section);
Sticky-Header erkennen mit Sentinel-Element
// <div id="sentinel"></div> steht direkt über dem Header mit position: sticky
const sentinel = document.querySelector('#sentinel');
const header = document.querySelector('header');
const observer = new IntersectionObserver(([entry]) => {
// Sentinel ist oberhalb des Viewports verschwunden => Header klebt
const istAngeheftet = !entry.isIntersecting && entry.boundingClientRect.bottom <= 0;
header.classList.toggle('is-stuck', istAngeheftet);
console.log('angeheftet:', istAngeheftet);
}, { threshold: [0] });
observer.observe(sentinel);
// Wichtig · Fallstricke
- Der Wert ist eine Momentaufnahme zum Zeitpunkt
entry.time. Scrollt der Nutzer weiter, wird er nicht aktualisiert. Der nächste Wert kommt erst mit dem nächsten Callback, und der wird nur beim Überschreiten eines Schwellenwerts (threshold) ausgelöst. boundingClientRectist nicht der sichtbare Anteil. Den liefertintersectionRect. Das Verhältnis beider Werte steht inintersectionRatio.- Die Koordinaten beziehen sich immer auf den Viewport, auch wenn eine eigene
rootangegeben ist. Zum Vergleich mit der Root verwendet manentry.rootBounds. Dieser Wert kann bei Zielen in Cross-Origin-iframesnullsein. - CSS-Transformationen fließen in das Rechteck ein, genau wie bei
getBoundingClientRect(). - Das Objekt ist schreibgeschützt (
DOMRectReadOnly). Wer es verändern möchte, kopiert es, z. B. mitDOMRect.fromRect(entry.boundingClientRect). - Browser-Unterstützung: Chrome 51+, Edge 15+, Firefox 55+, Safari 12.1+. Für sehr alte Browser gibt es ein Polyfill von W3C/Google.