Signatur
Beschreibung
Die Eigenschaft snapTargetBlock des Interfaces SnapEvent gibt das Element zurück, das in Block-Richtung das Snap-Ziel ist. In horizontalen Schreibweisen wie Deutsch oder Englisch ist das die vertikale Achse. Verfügbar ist die Eigenschaft in den Ereignissen scrollsnapchange und scrollsnapchanging, die auf einem Scroll-Snap-Container ausgelöst werden.
Welches Element zurückkommt, hängt vom Ereignis ab:
- Bei
scrollsnapchangeist es das Element, auf das nach Ende des Scrollvorgangs eingerastet wurde. - Bei
scrollsnapchangingist es das Element, auf das der Browser voraussichtlich einrasten wird. Das Ereignis kommt schon während der Geste, etwa während der Finger noch auf dem Bildschirm liegt.
Typische Einsatzfälle sind Karussells, vertikale Story-Ansichten, Vollbild-Abschnitte oder Paginierungs-Punkte, die zum gerade sichtbaren Abschnitt passen sollen. Früher brauchte man dafür IntersectionObserver oder eigene Rechnungen im scroll-Handler. Rastet der Container in Block-Richtung nicht ein, zum Beispiel bei scroll-snap-type: x mandatory, ist der Wert null. Für die Inline-Richtung gibt es die Schwester-Eigenschaft snapTargetInline.
Rückgabewert
null.Beispiele
Aktiven Abschnitt nach dem Einrasten markieren
// CSS: .feed { overflow-y: scroll; scroll-snap-type: y mandatory; }
// .feed > section { scroll-snap-align: start; }
const feed = document.querySelector('.feed');
feed.addEventListener('scrollsnapchange', (event) => {
const target = event.snapTargetBlock;
if (!target) return;
feed.querySelectorAll('section').forEach((s) =>
s.classList.toggle('is-active', s === target)
);
console.log('Eingerastet auf:', target.id);
});
Vorschau schon während der Scroll-Geste (scrollsnapchanging)
const feed = document.querySelector('.feed');
const onChanging = (event) => {
const next = event.snapTargetBlock;
// Nächsten Abschnitt schon während des Wischens hervorheben
document.querySelectorAll('.feed > section.preview')
.forEach((s) => s.classList.remove('preview'));
next?.classList.add('preview');
};
feed.addEventListener('scrollsnapchanging', onChanging);
// Später wieder entfernen, z. B. beim Abbau der Komponente
// feed.removeEventListener('scrollsnapchanging', onChanging);
Paginierungs-Punkte mit Feature-Erkennung und Rückfall
const feed = document.querySelector('.feed');
const sections = [...feed.children];
const dots = [...document.querySelectorAll('.dots button')];
const setActive = (el) => {
const index = sections.indexOf(el);
dots.forEach((d, i) => d.toggleAttribute('aria-current', i === index));
};
if ('onscrollsnapchange' in window) {
feed.onscrollsnapchange = (e) => setActive(e.snapTargetBlock);
} else {
// Rückfall für Browser ohne SnapEvent
const io = new IntersectionObserver((entries) => {
entries.filter((e) => e.isIntersecting).forEach((e) => setActive(e.target));
}, { root: feed, threshold: 0.6 });
sections.forEach((s) => io.observe(s));
}
Beide Achsen in einem 2D-Raster auswerten
// CSS: .grid { overflow: scroll; scroll-snap-type: both mandatory; }
const grid = document.querySelector('.grid');
grid.addEventListener('scrollsnapchange', ({ snapTargetBlock, snapTargetInline }) => {
console.log('Zeile:', snapTargetBlock?.dataset.row ?? '–',
'Spalte:', snapTargetInline?.dataset.col ?? '–');
});
// Wichtig · Fallstricke
- Experimentelle API: Bisher nur in Chromium-Browsern (ab Chrome/Edge 129). Firefox und Safari unterstützen
SnapEventnoch nicht. Prüfe die Unterstützung vorher, etwa mit'onscrollsnapchange' in window, und sieh einen Rückfall mitIntersectionObservervor. - Nur schreibgeschützt: Eine Zuweisung an
snapTargetBlockwird ignoriert. Um auf ein Element einzurasten, scrollst du den Container, zum Beispiel mitelement.scrollIntoView(). - Auf
nullprüfen: Hat der Container kein Einrasten in Block-Richtung (etwa beiscroll-snap-type: x …), ist der Wertnull. Dann hilft optionale Verkettung (?.). - Block-Richtung hängt von der Schreibweise ab: Bei
writing-mode: vertical-rlist die Block-Richtung horizontal. In diesem Fall enthältsnapTargetBlockdas horizontale Snap-Ziel. - Ereignisse auf dem richtigen Element abhören: Die Ereignisse werden auf dem Scroll-Container ausgelöst. Scrollt das ganze Dokument, hörst du auf
documentab (bzw. aufwindowüber die on-Property). scrollsnapchangingist nur vorläufig: Das Ereignis kann während einer Geste mehrmals kommen, und das gemeldete Ziel ist nicht endgültig. Aufwendige Arbeit wie Netzwerkanfragen gehört deshalb inscrollsnapchange.