Start · Sprachen · JavaScript · Referenz · Element: transitionrun

Element: transitionrun

Ereignis

Wird ausgelöst, sobald ein CSS-Übergang erstellt wird – also schon vor einer eventuellen <code>transition-delay</code>-Wartezeit.

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

Signatur

element.addEventListener("transitionrun", handler)

Beschreibung

Das Ereignis transitionrun tritt ein, wenn für ein Element ein CSS-Übergang (transition) angelegt wird. Das passiert, sobald sich eine animierbare Eigenschaft ändert, für die ein Übergang definiert ist. Der Zeitpunkt liegt vor einer mit transition-delay festgelegten Verzögerung. Deshalb unterscheidet es sich von transitionstart, das erst nach Ablauf der Verzögerung feuert, wenn die Animation tatsächlich losläuft.

Registrieren lässt sich das Ereignis per element.addEventListener("transitionrun", handler) oder über die Eigenschaft element.ontransitionrun = handler. Der Handler bekommt ein TransitionEvent mit den Eigenschaften propertyName, elapsedTime und pseudoElement. Das Ereignis steigt im DOM auf (bubbles) und lässt sich nicht abbrechen (nicht cancelable).

Typische Einsatzfälle sind Zustände, die sofort beim Auslösen gelten sollen, auch wenn die sichtbare Animation noch wartet. Beispiele: Schaltflächen sperren, eine CSS-Klasse wie is-animating setzen, Protokoll oder Analyse starten. Zusammen mit transitionstart, transitionend und transitioncancel lässt sich der komplette Ablauf eines Übergangs verfolgen.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "transitionrun".
$handler Pflicht (event: TransitionEvent) => void Callback, der ein TransitionEvent erhält. Wichtige Eigenschaften: propertyName (z. B. "opacity"), elapsedTime (Sekunden, bei transitionrun normalerweise 0, außer bei negativem Delay) und pseudoElement (z. B. "::before" oder "").
$options boolean | AddEventListenerOptions false Optionen wie once, capture, passive oder signal zum späteren Entfernen.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler bekommt ein TransitionEvent-Objekt.

Beispiele

transitionrun vs. transitionstart bei Verzögerung

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

box.addEventListener('transitionrun', (e) => {
  console.log(`run: ${e.propertyName} (${performance.now().toFixed(0)} ms)`);
});
box.addEventListener('transitionstart', (e) => {
  console.log(`start: ${e.propertyName} (${performance.now().toFixed(0)} ms)`);
});
box.addEventListener('transitionend', (e) => {
  console.log(`end: ${e.propertyName}`);
});

box.classList.add('moved');
run: transform (1203 ms) start: transform (1705 ms) end: transform

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

// CSS: .panel { transition: height 400ms 200ms; }
const panel = document.querySelector('.panel');
const toggle = document.querySelector('#toggle');

// Sperren schon beim Anlegen, nicht erst nach dem Delay
panel.ontransitionrun = () => {
  toggle.disabled = true;
};
const unlock = () => { toggle.disabled = false; };
panel.ontransitionend = unlock;
panel.ontransitioncancel = unlock;

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

Listener mit AbortController wieder entfernen

const card = document.querySelector('.card');
const controller = new AbortController();

const onRun = (e) => {
  // Nur auf die eigene opacity-Transition reagieren, nicht auf aufsteigende Ereignisse von Kindelementen
  if (e.target !== card || e.propertyName !== 'opacity') return;
  card.classList.add('is-animating');
  console.log('Fade angelegt, pseudoElement:', JSON.stringify(e.pseudoElement));
};

card.addEventListener('transitionrun', onRun, { signal: controller.signal });

// Später: alle damit registrierten Listener entfernen
// controller.abort();
// Alternativ: card.removeEventListener('transitionrun', onRun);
Fade angelegt, pseudoElement: ""

// Wichtig · Fallstricke

  • Ein Ereignis pro Eigenschaft: Bei transition: all oder mehreren Eigenschaften feuert transitionrun für jede animierte Eigenschaft einzeln. Filtern Sie deshalb über e.propertyName. Kurzschreibweisen wie padding werden in Einzeleigenschaften wie padding-top usw. zerlegt.
  • Aufsteigen (Bubbling): Übergänge von Kindelementen lösen den Handler am Elternelement ebenfalls aus. Prüfen Sie e.target === element.
  • Kein Ereignis ohne Übergang: Ändert sich der Wert nicht, ist die Dauer 0s oder die Eigenschaft nicht animierbar, wird kein Übergang angelegt und es kommt kein Ereignis. Das Gleiche gilt, wenn der Stil vor dem nächsten Style-Recalc zweimal geändert wird.
  • Abbruch: Wird der Übergang abgebrochen, bevor er fertig ist (z. B. durch Entfernen der Klasse, display: none oder das Entfernen des Elements), folgt transitioncancel statt transitionend. Ohne Verzögerung feuern transitionrun und transitionstart praktisch gleichzeitig.
  • Kompatibilität: Unterstützt in Chrome/Edge 74+, Firefox 53+ und Safari 13.1+. Sehr alte WebKit-Versionen kennen das Ereignis nicht, Präfix-Varianten gibt es dafür nicht.
  • Bei prefers-reduced-motion entfernen viele Stylesheets die Übergänge. Dann fehlt das Ereignis, und Logik, die sich darauf verlässt, braucht einen Rückfallweg.