Signatur
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');
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'));
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}`);
});
// Wichtig · Fallstricke
- Ein Ereignis pro Eigenschaft: Werden mehrere Eigenschaften animiert (etwa bei
transition: all), feuerttransitionstartfür jede einzeln. Filtere deshalb nache.propertyName. Kurzschreibweisen wiepaddingwerden in Einzeleigenschaften wiepadding-topaufgeteilt. - Bubbling: Das Ereignis steigt auch von Kindelementen auf. Mit
e.target === e.currentTargetlässt sich prüfen, ob es vom Element selbst stammt. - Wird abgebrochen, bevor es startet: Wird die Transition während des
transition-delayabgebrochen (Klasse entfernt,display: none, Element entfernt), gibt es zwartransitionrunundtransitioncancel, aber keintransitionstart. - Keine Transition, kein Ereignis: Ändert sich der berechnete Wert nicht, ist die Dauer
0soder ist die Eigenschaft nicht animierbar, feuert nichts. Eine Stiländerung direkt nach dem Einfügen ins DOM wird oft ohne Transition übernommen. Hier hilftrequestAnimationFrameoder 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 Eigenschaftontransitionstartist inzwischen ebenfalls überall verfügbar.