Start · Sprachen · JavaScript · Referenz · Element: scrollend

Element: scrollend

Ereignis

Das <code>scrollend</code>-Ereignis wird ausgelöst, wenn das Scrollen eines Elements vollständig abgeschlossen ist – inklusive Snap- und Smooth-Scroll-Animationen.

seit JavaScript Chrome/Edge 114, Firefox 109, Safari 26 (noch kein Kategorie: webapi

Signatur

element.addEventListener("scrollend", handler)

Beschreibung

Das scrollend-Ereignis feuert einmal, sobald ein Scrollvorgang eines Elements beendet ist. Das gilt, wenn der Nutzer nicht mehr aktiv scrollt (Finger losgelassen, Mausrad ruht, Taste losgelassen) und alle nachlaufenden Bewegungen wie Trägheitsscrollen, scroll-snap-Einrasten oder eine per scrollTo({ behavior: "smooth" }) gestartete Animation fertig sind.

Bisher musste man das Ende des Scrollens mit einem entprellten scroll-Handler und setTimeout erraten. Das war ungenau und verzögert. scrollend ersetzt dieses Muster. Typische Anwendungen sind: die Scrollposition speichern, Inhalte nachladen, sobald die Liste ruht, in Karussells mit Scroll-Snap den aktiven Slide bestimmen oder aufwendige Berechnungen erst nach dem Scrollen ausführen.

Registrieren kann man den Handler mit element.addEventListener("scrollend", handler) oder über die Eigenschaft element.onscrollend = handler. Das Ereignis ist ein einfaches Event, steigt nicht auf (kein Bubbling) und lässt sich nicht abbrechen. Für das Scrollen des ganzen Dokuments hört man auf document oder window (dort steigt das Ereignis zum window auf).

Hat sich die Scrollposition gar nicht geändert, zum Beispiel weil scrollTo() die aktuelle Position als Ziel hatte oder der Nutzer am Rand weiterscrollt, wird kein scrollend ausgelöst.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignistyp, hier immer "scrollend".
$handler Pflicht (event: Event) => void | EventListenerObject Die Rückruffunktion. Sie erhält ein einfaches Event-Objekt ohne Positionsdaten, deshalb liest man die Position über event.target.scrollTop bzw. scrollLeft.
$options boolean | AddEventListenerOptions false Optionale Einstellungen wie once, passive, signal oder capture.

Rückgabewert

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

Beispiele

Scrollposition nach dem Scrollen speichern

const liste = document.querySelector('#artikel-liste');

// Gespeicherte Position wiederherstellen
liste.scrollTop = Number(sessionStorage.getItem('listePos') ?? 0);

liste.addEventListener('scrollend', (event) => {
  const pos = event.target.scrollTop;
  sessionStorage.setItem('listePos', String(pos));
  console.log(`Position gespeichert: ${pos}px`);
});
Position gespeichert: 840px

Aktiven Slide im Scroll-Snap-Karussell bestimmen (on-Property)

const karussell = document.querySelector('.karussell');
const anzeige = document.querySelector('#slide-nr');

karussell.onscrollend = () => {
  const breite = karussell.clientWidth;
  const index = Math.round(karussell.scrollLeft / breite);
  anzeige.textContent = `Slide ${index + 1}`;
  console.log('Eingerastet auf Slide', index + 1);
};

// Handler wieder entfernen:
// karussell.onscrollend = null;
Eingerastet auf Slide 3

Auf Ende eines Smooth-Scrolls warten (Promise) und Listener entfernen

const scrollUndWarten = (el, top) => new Promise((resolve) => {
  if (el.scrollTop === top) return resolve(); // kein scrollend zu erwarten
  const fertig = () => {
    el.removeEventListener('scrollend', fertig);
    resolve();
  };
  el.addEventListener('scrollend', fertig);
  el.scrollTo({ top, behavior: 'smooth' });
});

const main = document.querySelector('main');
await scrollUndWarten(main, 1200);
console.log('Animation beendet, Element fokussieren');
document.querySelector('#kapitel-3')?.focus();
Animation beendet, Element fokussieren

Fallback mit Entprellung für ältere Browser

const onScrollEnde = (el, callback) => {
  if ('onscrollend' in window) {
    el.addEventListener('scrollend', callback);
    return;
  }
  let timer;
  el.addEventListener('scroll', (e) => {
    clearTimeout(timer);
    timer = setTimeout(() => callback(e), 150);
  }, { passive: true });
};

onScrollEnde(document, () => console.log('Scrollen beendet'));
Scrollen beendet

// Wichtig · Fallstricke

  • Browserunterstützung: Chrome/Edge ab 114 und Firefox ab 109 unterstützen das Ereignis. Safari unterstützt es erst in sehr neuen Versionen (26). Deshalb die Unterstützung mit 'onscrollend' in window prüfen und bei Bedarf auf einen entprellten scroll-Handler zurückfallen.
  • Kein Bubbling: Auf einem Elternelement kommen scrollend-Ereignisse von Kind-Scrollcontainern nicht an. Wer sie trotzdem zentral abfangen will, registriert den Listener in der Capture-Phase ({ capture: true }).
  • Keine Änderung, kein Ereignis: Bleibt die Scrollposition gleich, feuert nichts. Promise-basierte Wrapper sollten diesen Fall selbst abfangen, sonst warten sie ewig.
  • Das Ereignis wartet, bis der Nutzer loslässt. Solange ein Finger auf dem Touchscreen liegt oder die Scrollleiste gezogen wird, kommt kein scrollend, auch wenn die Position gerade ruht.
  • Für Aktualisierungen während des Scrollens (z. B. Fortschrittsbalken) ist weiterhin scroll gedacht, für Sichtbarkeit von Elementen besser IntersectionObserver.