Start · Sprachen · JavaScript · Referenz · Document: scrollend

Document: scrollend

Ereignis

Wird am <code>Document</code> ausgelöst, sobald das Scrollen der Dokumentansicht vollständig beendet ist, also nach Nutzer-Interaktion, Trägheitsbewegung oder programmatischem Smooth-Scroll.

seit JavaScript Chrome/Edge 114, Firefox 109; Safari erst ab 26.2 Kategorie: webapi

Signatur

document.addEventListener("scrollend", handler)

Beschreibung

Das scrollend-Ereignis zeigt an, dass eine Scroll-Bewegung der Dokumentansicht komplett abgeschlossen ist. Das heißt: Der Nutzer hat Finger, Mausrad oder Scrollbalken losgelassen, eine eventuelle Trägheitsbewegung (Momentum-Scrolling) ist ausgelaufen, das Einrasten per CSS Scroll Snap ist fertig, und ein programmatischer Aufruf wie window.scrollTo({ behavior: "smooth" }) hat sein Ziel erreicht.

Früher musste man das Ende eines Scroll-Vorgangs mit scroll-Events und einem Timeout nachbauen (Debouncing). Das war ungenau und reagierte entweder zu spät oder zu früh, zum Beispiel wenn der Finger noch auf dem Touchscreen lag. scrollend ersetzt diesen Trick durch ein verlässliches Signal des Browsers. Typische Anwendungsfälle sind das Speichern der Scroll-Position, das Nachladen von Inhalten, Analytics („bis wohin wurde gelesen?“) und das Aktualisieren von Navigations- oder Karussell-Zuständen.

Das Ereignis ist weder abbrechbar noch löst es aus, wenn sich die Scroll-Position gar nicht geändert hat. Am Document steigt es nicht auf (kein Bubbling), wird aber an window weitergereicht. Man kann es per addEventListener("scrollend", …) oder über die Eigenschaft document.onscrollend abonnieren. Für scrollbare Einzelelemente gibt es das gleichnamige Ereignis auf Element.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "scrollend".
$handler Pflicht (event: Event) => void Callback, das ein generisches Event erhält. Es gibt keine zusätzlichen Eigenschaften, die aktuelle Position liest man über window.scrollY bzw. document.documentElement.scrollTop.
$options boolean | AddEventListenerOptions false Optionen wie { once: true }, { passive: true } oder { signal } zum späteren Entfernen über einen AbortController.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler bekommt ein Event-Objekt mit bubbles: false und cancelable: false.

Beispiele

Scroll-Position nach Scroll-Ende speichern

// Position erst speichern, wenn der Nutzer fertig gescrollt hat
document.addEventListener("scrollend", () => {
  sessionStorage.setItem("scrollY", String(window.scrollY));
  console.log(`Gespeichert: ${window.scrollY}px`);
});

// Beim Laden wiederherstellen
const saved = Number(sessionStorage.getItem("scrollY") ?? 0);
window.scrollTo(0, saved);
Gespeichert: 1240px

Über die on-Property und nach Smooth-Scroll reagieren

const button = document.querySelector("#nach-oben");

button.addEventListener("click", () => {
  window.scrollTo({ top: 0, behavior: "smooth" });
});

// Wird erst ausgelöst, wenn die Animation fertig ist
document.onscrollend = () => {
  if (window.scrollY === 0) {
    document.querySelector("h1")?.focus();
    console.log("Oben angekommen");
  }
};
Oben angekommen

Listener mit AbortController wieder entfernen

const controller = new AbortController();

const onScrollEnd = () => {
  const doc = document.documentElement;
  const progress = Math.round(
    (window.scrollY / (doc.scrollHeight - window.innerHeight)) * 100
  );
  console.log(`Lesefortschritt: ${progress}%`);
  if (progress >= 90) {
    console.log("Artikel gelesen, Listener wird entfernt");
    controller.abort(); // entspricht removeEventListener
  }
};

document.addEventListener("scrollend", onScrollEnd, { signal: controller.signal });
// Alternativ: document.removeEventListener("scrollend", onScrollEnd);
Lesefortschritt: 45% Lesefortschritt: 92% Artikel gelesen, Listener wird entfernt

Fallback mit Debounce für Browser ohne Unterstützung

const onScrollEnd = (callback, delay = 150) => {
  if ("onscrollend" in window) {
    document.addEventListener("scrollend", callback);
    return;
  }
  // Fallback: scroll-Events entprellen
  let timer;
  document.addEventListener("scroll", (event) => {
    clearTimeout(timer);
    timer = setTimeout(() => callback(event), delay);
  }, { passive: true });
};

onScrollEnd(() => console.log("Scrollen beendet bei", window.scrollY));
Scrollen beendet bei 800

// Wichtig · Fallstricke

  • Browser-Unterstützung: Chrome/Edge ab 114 und Firefox ab 109 unterstützen das Ereignis. Safari unterstützt es erst ab Version 26.2, ältere Safari-Versionen und damit viele iOS-Geräte nicht. Prüfe die Unterstützung mit "onscrollend" in window und sieh einen Debounce-Fallback vor.
  • Das Ereignis löst nicht aus, wenn sich die Scroll-Position nicht geändert hat, etwa bei scrollTo() auf die aktuelle Position oder wenn der Nutzer schon am Seitenende ist.
  • Solange der Nutzer den Finger auf dem Touchscreen oder die Maus auf dem Scrollbalken gedrückt hält, gilt das Scrollen als nicht beendet, auch wenn sich nichts bewegt.
  • Am Document gibt es kein Bubbling. Scrollt ein inneres Element mit overflow: auto, wird scrollend nur an diesem Element ausgelöst, nicht am document. Der Listener muss dann direkt am Element hängen.
  • Eine laufende Smooth-Scroll-Animation, die von einer neuen unterbrochen wird, löst in der Regel nur ein einziges scrollend am Ende aus.