Signatur
Beschreibung
SnapEvent ist das Ereignisobjekt für die beiden Scroll-Snap-Events der CSS Scroll Snap Module Level 2. Ein Scroll-Container, dessen Kinder per scroll-snap-type und scroll-snap-align Einrastpunkte festlegen, löst diese Events aus:
scrollsnapchangingfeuert während der Scrollgeste, sobald der Browser ein anderes Element als künftiges Einrastziel erwartet. So lässt sich schon beim Wischen eine Vorschau zeigen, etwa ein Punkt in der Seitennavigation eines Karussells.scrollsnapchangefeuert nach dem Scrollvorgang, wenn ein neues Einrastziel feststeht. Das passiert kurz vorscrollend. Hier gehören endgültige Zustandsänderungen hin, etwa „aktive Folie“, Nachladen von Inhalten oder Statistik.
Neben den von Event geerbten Eigenschaften hat SnapEvent zwei nur lesbare Eigenschaften: snapTargetBlock nennt das Element, auf das in Block-Richtung eingerastet wird (bei horizontaler Schreibweise also vertikal). snapTargetInline nennt das Element in Inline-Richtung (horizontal). Ist in einer Richtung kein Einrasten eingestellt oder gibt es kein Ziel, ist der Wert null.
Vorher musste man Scrollpositionen mit scroll-Listenern, IntersectionObserver oder getBoundingClientRect() selbst auswerten. Das Einrastziel war damit nur geschätzt. SnapEvent meldet dagegen direkt das Ziel, das die Rendering-Engine tatsächlich gewählt hat. Die Events werden am Scroll-Container ausgelöst. Scrollt das gesamte Dokument, kommen sie am document an und steigen bis zum window auf.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Konstruktor-Parameter: Name des Events, "scrollsnapchanging" oder "scrollsnapchange". |
|
| $options | object | {} | Konstruktor-Parameter: ein Objekt mit allen Optionen von EventInit (bubbles, cancelable, composed) und zusätzlich snapTargetBlock und snapTargetInline. Beide sind vom Typ Node | null, Standardwert null. |
| $snapTargetBlock | Node | null | null | Nur lesbare Instanz-Eigenschaft: das Element, auf das in Block-Richtung eingerastet wird bzw. werden soll. |
| $snapTargetInline | Node | null | null | Nur lesbare Instanz-Eigenschaft: das Element, auf das in Inline-Richtung eingerastet wird bzw. werden soll. |
Rückgabewert
new SnapEvent(type, options) gibt ein neues SnapEvent-Objekt zurück. Im Normalfall erzeugt der Browser die Instanzen selbst und übergibt sie an die Event-Handler.Beispiele
Aktive Folie eines horizontalen Karussells markieren
// CSS: .carousel { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; }
// .slide { flex: 0 0 100%; scroll-snap-align: center; }
const carousel = document.querySelector('.carousel');
carousel.addEventListener('scrollsnapchange', (event) => {
const slide = event.snapTargetInline; // horizontal = Inline-Richtung
if (!slide) return;
carousel.querySelectorAll('.slide').forEach((el) =>
el.classList.toggle('active', el === slide)
);
console.log('Aktive Folie:', slide.dataset.index);
});
Vorschau während der Wischgeste mit scrollsnapchanging
const list = document.querySelector('.vertical-list'); // scroll-snap-type: y mandatory
const dots = [...document.querySelectorAll('.pager-dot')];
const onSnapChanging = (event) => {
const target = event.snapTargetBlock; // vertikal = Block-Richtung
const index = [...list.children].indexOf(target);
dots.forEach((dot, i) => dot.classList.toggle('preview', i === index));
};
list.addEventListener('scrollsnapchanging', onSnapChanging);
// Alternativ über die on-Eigenschaft:
// list.onscrollsnapchanging = onSnapChanging;
// Später wieder abmelden:
// list.removeEventListener('scrollsnapchanging', onSnapChanging);
Unterstützung prüfen und Event selbst erzeugen
const supported = 'onscrollsnapchange' in window;
console.log('SnapEvent unterstützt:', supported);
if (typeof SnapEvent === 'function') {
const container = document.querySelector('.carousel');
const slide = container.firstElementChild;
container.addEventListener('scrollsnapchange', (e) => {
console.log(e instanceof SnapEvent, e.snapTargetInline === slide, e.snapTargetBlock);
});
// z. B. für Tests: synthetisches Event auslösen
container.dispatchEvent(
new SnapEvent('scrollsnapchange', { snapTargetInline: slide })
);
}
// Wichtig · Fallstricke
- Browserunterstützung: Die API gibt es bislang nur in Chromium-Browsern (Chrome/Edge ab 129). Firefox und Safari unterstützen sie noch nicht. Die Unterstützung lässt sich mit
'onscrollsnapchange' in windowprüfen. Als Rückfallebene eignet sichscrollendzusammen mitIntersectionObserver. - Block oder Inline: Welche Achse Block und welche Inline ist, hängt von
writing-modeab. Bei normaler horizontaler Schreibweise liefert ein horizontales Karussell sein Ziel insnapTargetInline, eine vertikale Liste insnapTargetBlock. Die jeweils andere Eigenschaft ist dannnull. - Nur bei Wechsel des Ziels:
scrollsnapchangefeuert nur, wenn sich das Einrastziel tatsächlich ändert. Rastet der Container nach einem kurzen Scrollen wieder am selben Element ein, kommt kein Event. scrollsnapchangingist vorläufig: Das gemeldete Ziel kann sich während der Geste mehrfach ändern und muss am Ende nicht das tatsächliche Ziel sein. Aufwendige Arbeit wie Netzwerkanfragen daher erst inscrollsnapchangeerledigen.- Beide Events lassen sich nicht abbrechen.
preventDefault()hat keine Wirkung. - Das Ziel kann auch ein Pseudo-Element sein, zum Beispiel
::scroll-marker-Konstrukte in neueren Spezifikationen. Deshalb ist der TypNodeund nichtElement. Vor dem Zugriff aufdatasetund Ähnliches sollte man den Typ prüfen.