Signatur
Beschreibung
Ein IntersectionObserver sammelt erkannte Änderungen der Sichtbarkeit zunächst in einer internen Warteschlange und ruft den Callback erst später asynchron auf. Mit takeRecords() holst du diese anstehenden Einträge sofort und synchron ab. Danach ist die Warteschlange leer, und die abgeholten Einträge werden dem Callback nicht mehr übergeben.
Gebraucht wird das vor allem, bevor du einen Observer mit disconnect() beendest. disconnect() verwirft noch nicht zugestellte Einträge nämlich ohne Rückmeldung. Wenn du etwa Sichtbarkeiten für Analytics oder Werbeeinblendungen misst, rufst du vorher takeRecords() auf und verarbeitest den Rest selbst, damit keine Messung verloren geht.
Die Methode prüft die Überschneidungen nicht neu. Sie gibt nur zurück, was der Browser bei seiner letzten Prüfung schon erkannt, aber noch nicht zugestellt hat. In den meisten Fällen bekommst du deshalb ein leeres Array zurück, weil der Callback die Einträge schon verarbeitet hat.
Rückgabewert
IntersectionObserverEntry-Objekten, jeweils eines pro erkannter Änderung eines beobachteten Elements. Ist nichts angefallen, ist das Array leer.Beispiele
Anstehende Einträge vor dem Trennen verarbeiten
const handleEntries = (entries) => {
entries.forEach((entry) => {
console.log(entry.target.id, entry.isIntersecting ? 'sichtbar' : 'unsichtbar');
});
};
const observer = new IntersectionObserver(handleEntries, { threshold: 0.5 });
document.querySelectorAll('.card').forEach((el) => observer.observe(el));
// Später, z. B. beim Verlassen der Ansicht:
const stopObserving = () => {
const pending = observer.takeRecords();
if (pending.length > 0) handleEntries(pending); // nichts geht verloren
observer.disconnect();
};
stopObserving();
Sichtbarkeit für Analytics beim Verlassen der Seite erfassen
const seen = new Set();
const record = (entries) => {
for (const entry of entries) {
if (entry.isIntersecting) seen.add(entry.target.dataset.adId);
}
};
const adObserver = new IntersectionObserver(record, { threshold: 1.0 });
document.querySelectorAll('[data-ad-id]').forEach((ad) => adObserver.observe(ad));
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
record(adObserver.takeRecords());
navigator.sendBeacon('/api/impressions', JSON.stringify([...seen]));
}
});
Rückgabewert prüfen: meist ein leeres Array
const io = new IntersectionObserver(() => {});
io.observe(document.body);
// Synchron direkt nach observe(): die erste Prüfung ist noch nicht gelaufen
const records = io.takeRecords();
console.log(Array.isArray(records), records.length);
// Wichtig · Fallstricke
- Einträge werden nur einmal ausgeliefert: Was
takeRecords()zurückgibt, kommt nicht mehr beim Callback an. Verarbeite die Einträge deshalb mit derselben Logik wie im Callback, sonst fehlen dir Daten. - Keine neue Prüfung: Die Methode erzwingt keine Neuberechnung der Überschneidungen. Wenn du den aktuellen Zustand direkt nach
observe()brauchst, bekommst du so keine verlässlichen Daten. Greife dann zum Beispiel aufgetBoundingClientRect()zurück. - Reihenfolge mit
disconnect(): RufetakeRecords()immer vordisconnect()auf.disconnect()verwirft anstehende Einträge. - Kompatibilität: Wird von allen modernen Browsern unterstützt (Chrome 58+, Firefox 55+, Safari 12.1+, Edge 16+). Im Internet Explorer brauchst du ein Polyfill. Ältere Polyfills setzen
takeRecords()teilweise nur unvollständig um.