Start · Sprachen · JavaScript · Referenz · Element: transitionstart

Element: transitionstart

Ereignis

Wird ausgelöst, wenn eine CSS-Transition tatsächlich beginnt, also nach Ablauf eines eventuellen <code>transition-delay</code>.

seit JavaScript Baseline: alle modernen Browser (seit 2020) Kategorie: webapi

Signatur

element.addEventListener("transitionstart", handler)

Beschreibung

Das Ereignis transitionstart wird an einem Element ausgelöst, sobald eine CSS-Transition tatsächlich zu animieren beginnt. Ist ein transition-delay gesetzt, feuert es erst nach dieser Verzögerung. Im Unterschied dazu tritt transitionrun bereits ein, wenn die Transition angelegt wird, also noch vor der Verzögerung.

Registriert wird das Ereignis mit element.addEventListener("transitionstart", handler) oder über die Eigenschaft element.ontransitionstart = handler. Der Handler bekommt ein TransitionEvent. Wichtige Eigenschaften davon sind propertyName (die animierte CSS-Eigenschaft), elapsedTime (Laufzeit in Sekunden, beim Start meist 0) und pseudoElement (zum Beispiel "::before" oder ein leerer String).

Das Ereignis ist nützlich, um JavaScript-Logik genau mit dem sichtbaren Beginn einer Animation abzustimmen. Beispiele sind Ladezustände, Barrierefreiheits-Hinweise wie aria-busy, Messungen oder das Sperren von Bedienelementen, solange eine Animation läuft. Das Ereignis steigt im DOM auf (Bubbling) und lässt sich daher auch zentral an einem Elternelement abfangen. Abbrechen lässt es sich nicht.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignistyp, hier immer "transitionstart".
$handler Pflicht (event: TransitionEvent) => void Callback, das ein TransitionEvent mit propertyName, elapsedTime und pseudoElement erhält.
$options boolean | AddEventListenerOptions false Optionen wie once, capture, passive oder signal (zum Entfernen über einen AbortController).

Beispiele

Start einer Transition mit addEventListener protokollieren

// CSS: .box { transition: transform 0.5s ease 1s; }  .box.moved { transform: translateX(200px); }
const box = document.querySelector('.box');

box.addEventListener('transitionrun', (e) => {
  console.log(`run: ${e.propertyName}, Verzögerung läuft`);
});

box.addEventListener('transitionstart', (e) => {
  console.log(`start: ${e.propertyName}, elapsedTime=${e.elapsedTime}`);
});

box.classList.add('moved');
run: transform, Verzögerung läuft start: transform, elapsedTime=0 (ca. 1 s später)

Button während der Animation sperren (on-Property)

const panel = document.querySelector('#panel');
const toggle = document.querySelector('#toggle');

panel.ontransitionstart = (e) => {
  if (e.propertyName !== 'height') return; // andere Eigenschaften ignorieren
  toggle.disabled = true;
  panel.setAttribute('aria-busy', 'true');
};

panel.ontransitionend = (e) => {
  if (e.propertyName !== 'height') return;
  toggle.disabled = false;
  panel.removeAttribute('aria-busy');
};

toggle.addEventListener('click', () => panel.classList.toggle('open'));

Listener einmalig nutzen und wieder entfernen

const card = document.querySelector('.card');

const onStart = (e) => {
  console.log('Erste Transition gestartet:', e.propertyName);
  card.removeEventListener('transitionstart', onStart);
};

card.addEventListener('transitionstart', onStart);
// Alternative: card.addEventListener('transitionstart', onStart, { once: true });

requestAnimationFrame(() => card.classList.add('highlight'));
Erste Transition gestartet: background-color

Zentrale Behandlung per Event-Delegation

const list = document.querySelector('ul.menu');

list.addEventListener('transitionstart', (e) => {
  const item = e.target.closest('li');
  if (!item) return;
  const ziel = e.pseudoElement ? `${item.id}${e.pseudoElement}` : item.id;
  console.log(`Transition von ${e.propertyName} startet an ${ziel}`);
});
Transition von opacity startet an item-3

// Wichtig · Fallstricke

  • Ein Ereignis pro Eigenschaft: Werden mehrere Eigenschaften animiert (etwa bei transition: all), feuert transitionstart für jede einzeln. Filtere deshalb nach e.propertyName. Kurzschreibweisen wie padding werden in Einzeleigenschaften wie padding-top aufgeteilt.
  • Bubbling: Das Ereignis steigt auch von Kindelementen auf. Mit e.target === e.currentTarget lässt sich prüfen, ob es vom Element selbst stammt.
  • Wird abgebrochen, bevor es startet: Wird die Transition während des transition-delay abgebrochen (Klasse entfernt, display: none, Element entfernt), gibt es zwar transitionrun und transitioncancel, aber kein transitionstart.
  • Keine Transition, kein Ereignis: Ändert sich der berechnete Wert nicht, ist die Dauer 0s oder ist die Eigenschaft nicht animierbar, feuert nichts. Eine Stiländerung direkt nach dem Einfügen ins DOM wird oft ohne Transition übernommen. Hier hilft requestAnimationFrame oder ein erzwungener Reflow.
  • Nicht abbrechbar: preventDefault() hat keine Wirkung.
  • Kompatibilität: Wird von Chrome/Edge 87+, Firefox 53+ und Safari 13.1+ unterstützt. Ältere Browser kennen oft nur transitionend. Die Eigenschaft ontransitionstart ist inzwischen ebenfalls überall verfügbar.