Start · Sprachen · JavaScript · Referenz · SnapEvent.snapTargetBlock

SnapEvent.snapTargetBlock

Eigenschaft

Schreibgeschützte Eigenschaft, die das Element liefert, auf das ein Scroll-Snap-Container in Block-Richtung eingerastet ist (oder gerade einrasten wird).

seit JavaScript Experimentell: Chrome/Edge 129+, noch nicht in Fir Kategorie: webapi

Signatur

SnapEvent.snapTargetBlock

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 scrollsnapchange ist es das Element, auf das nach Ende des Scrollvorgangs eingerastet wurde.
  • Bei scrollsnapchanging ist 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

Typ
Element | null
Beschreibung
Das Element, das in Block-Richtung das Snap-Ziel ist. Ist das eigentliche Ziel ein Pseudo-Element, kommt das Element zurück, zu dem es gehört. Ohne Einrasten in Block-Richtung ist der Wert 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);
});
Eingerastet auf: kapitel-2

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 ?? '–');
});
Zeile: 3 Spalte: 1

// Wichtig · Fallstricke

  • Experimentelle API: Bisher nur in Chromium-Browsern (ab Chrome/Edge 129). Firefox und Safari unterstützen SnapEvent noch nicht. Prüfe die Unterstützung vorher, etwa mit 'onscrollsnapchange' in window, und sieh einen Rückfall mit IntersectionObserver vor.
  • Nur schreibgeschützt: Eine Zuweisung an snapTargetBlock wird ignoriert. Um auf ein Element einzurasten, scrollst du den Container, zum Beispiel mit element.scrollIntoView().
  • Auf null prüfen: Hat der Container kein Einrasten in Block-Richtung (etwa bei scroll-snap-type: x …), ist der Wert null. Dann hilft optionale Verkettung (?.).
  • Block-Richtung hängt von der Schreibweise ab: Bei writing-mode: vertical-rl ist die Block-Richtung horizontal. In diesem Fall enthält snapTargetBlock das 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 document ab (bzw. auf window über die on-Property).
  • scrollsnapchanging ist 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 in scrollsnapchange.