Signatur
Beschreibung
Das Ereignis scrollsnapchanging wird auf einem Scroll-Container mit scroll-snap-type ausgelöst, wenn der Browser feststellt, dass ein neues Snap-Ziel aussteht. Das heißt: Würde die aktuelle Scroll-Geste jetzt enden, würde der Container auf ein anderes Element einrasten als bisher. Das Ereignis feuert also schon während des Scrollens bzw. Ziehens, oft mehrfach, und nicht erst am Ende.
Genau das unterscheidet es von scrollsnapchange. Dieses Ereignis feuert erst, wenn der Scroll-Vorgang abgeschlossen ist und ein neues Snap-Ziel tatsächlich übernommen wurde. scrollsnapchanging eignet sich daher für sofortiges visuelles Feedback. Beispiele sind ein vorläufig hervorgehobenes Karussell-Element, eine Vorschau der aktiven Seite in einer Paginierung oder ein Vorladen von Inhalten.
Der Handler erhält ein SnapEvent. Dessen Eigenschaften snapTargetBlock und snapTargetInline verweisen auf das ausstehende Snap-Ziel in der jeweiligen Achse. Gibt es in einer Achse kein Ziel, ist der Wert null. Das Ereignis lässt sich nicht abbrechen. Es blubbert (bubbles) nur, wenn es auf dem Document ausgelöst wird, auf Elementen dagegen nicht.
Du kannst den Handler per addEventListener("scrollsnapchanging", …) oder über die Eigenschaft onscrollsnapchanging registrieren. Scrollt die Seite selbst (Wurzel-Scroller), wird das Ereignis auf dem document bzw. über window ausgelöst.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "scrollsnapchanging". |
|
| $handler Pflicht | (event: SnapEvent) => void | Callback, der ein SnapEvent mit snapTargetBlock und snapTargetInline erhält (jeweils Element | null). |
|
| $options | boolean | AddEventListenerOptions | false | Übliche Listener-Optionen wie passive, once oder signal. |
Beispiele
Ausstehendes Karussell-Element vorläufig hervorheben
// CSS: .carousel { overflow-x: auto; scroll-snap-type: x mandatory; }
// .carousel > .slide { scroll-snap-align: center; }
const carousel = document.querySelector('.carousel');
carousel.addEventListener('scrollsnapchanging', (event) => {
// Vorherige Markierung entfernen
carousel.querySelector('.pending')?.classList.remove('pending');
// Neues ausstehendes Ziel markieren
const target = event.snapTargetInline;
if (target) {
target.classList.add('pending');
console.log('Ausstehend:', target.dataset.index);
}
});
Zusammenspiel mit scrollsnapchange (vorläufig vs. endgültig)
const list = document.querySelector('#pages');
const indicator = document.querySelector('#indicator');
// Sofortiges Feedback während der Geste
list.addEventListener('scrollsnapchanging', ({ snapTargetBlock }) => {
if (snapTargetBlock) indicator.textContent = `→ Seite ${snapTargetBlock.dataset.page}`;
});
// Endgültiger Zustand nach Ende des Scrollens
list.addEventListener('scrollsnapchange', ({ snapTargetBlock }) => {
if (snapTargetBlock) {
indicator.textContent = `Seite ${snapTargetBlock.dataset.page}`;
history.replaceState(null, '', `#page-${snapTargetBlock.dataset.page}`);
}
});
Registrierung über onscrollsnapchanging mit Feature-Erkennung
const gallery = document.querySelector('.gallery');
if ('onscrollsnapchanging' in window) {
gallery.onscrollsnapchanging = (event) => {
console.log('Block:', event.snapTargetBlock?.id ?? null,
'Inline:', event.snapTargetInline?.id ?? null);
};
} else {
console.log('scrollsnapchanging wird nicht unterstützt – Fallback per IntersectionObserver');
}
// Handler wieder entfernen
// gallery.onscrollsnapchanging = null;
// Wichtig · Fallstricke
- Kompatibilität: Bisher nur in Chromium-Browsern verfügbar (Chrome/Edge 129+). Firefox und Safari unterstützen das Ereignis nicht. Prüfe die Unterstützung mit
'onscrollsnapchanging' in windowund sieh einen Fallback vor, etwa mitIntersectionObserveroderscrollend. - Das Ereignis feuert nur, wenn der Container tatsächlich Scroll-Snapping nutzt. Dafür braucht der Container
scroll-snap-typeund die Kindelemente brauchenscroll-snap-align. - Während einer Geste kann das Ereignis mehrfach auslösen, z. B. wenn der Nutzer hin und her zieht. Das zuletzt gemeldete Ziel muss nicht das endgültige sein. Dauerhafte Aktionen wie Analytics, URL-Updates oder Datenabrufe gehören daher in
scrollsnapchange. - Halte den Handler schlank und vermeide Layout-auslösende Zugriffe wie
getBoundingClientRectin schneller Folge. Sonst kann das Scrollen ruckeln. snapTargetBlockbzw.snapTargetInlinekönnennullsein, wenn in der jeweiligen Achse kein Snapping stattfindet. Prüfe den Wert immer vor dem Zugriff.- Beim Scrollen des gesamten Dokuments wird das Ereignis am
documentausgelöst und nicht andocument.documentElement.