Signatur
Beschreibung
Die Methode getAnimations() des ShadowRoot-Interfaces stammt aus dem Mixin DocumentOrShadowRoot und gehört zur Web Animations API. Sie liefert alle Animationen, die gerade wirksam sind, also laufen, pausiert sind, auf ihren Start warten oder durch fill: "forwards" bzw. "both" weiterhin einen Stil anwenden. Die Zielelemente dieser Animationen liegen innerhalb des Shadow-Baums.
Dazu zählen CSS-Animationen (CSSAnimation), CSS-Übergänge (CSSTransition) und Animationen, die per Skript mit Element.animate() oder new Animation() erzeugt wurden. Mit dem Ergebnis kann eine Web Component alle eigenen Animationen auf einmal pausieren, abbrechen, beschleunigen oder auf ihr Ende warten, ohne jedes Element einzeln abzufragen.
Wichtig ist die Kapselung: document.getAnimations() gibt keine Animationen aus Shadow-Bäumen zurück. Umgekehrt enthält shadowRoot.getAnimations() nur Animationen dieses einen Shadow-Baums. Animationen in verschachtelten Shadow-Roots oder an geslotteten Elementen aus dem Light DOM sind nicht enthalten. Die Einträge sind nach ihrer zusammengesetzten Reihenfolge (Composite Order) sortiert.
Rückgabewert
Animation-Objekten, darunter auch CSSAnimation und CSSTransition. Ist gerade keine Animation wirksam, ist das Array leer.Beispiele
Animationen einer Web Component auflisten
class PulseBadge extends HTMLElement {
constructor() {
super();
const root = this.attachShadow({ mode: 'open' });
root.innerHTML = `
<style>
@keyframes pulse { from { opacity: 1; } to { opacity: .3; } }
.dot { width: 10px; height: 10px; background: red; animation: pulse 1s infinite alternate; }
</style>
<div class="dot"></div>`;
}
}
customElements.define('pulse-badge', PulseBadge);
const badge = document.createElement('pulse-badge');
document.body.append(badge);
requestAnimationFrame(() => {
const anims = badge.shadowRoot.getAnimations();
console.log(anims.length, anims[0].animationName);
// Das Dokument sieht die gekapselte Animation nicht:
console.log(document.getAnimations().length);
});
Alle Animationen im Shadow-Baum pausieren und fortsetzen
const host = document.querySelector('my-widget');
const root = host.shadowRoot;
const pauseAll = () => root.getAnimations().forEach((a) => a.pause());
const resumeAll = () => root.getAnimations().forEach((a) => a.play());
// Rücksicht auf Nutzer, die weniger Bewegung wünschen
const mq = matchMedia('(prefers-reduced-motion: reduce)');
if (mq.matches) pauseAll();
mq.addEventListener('change', (e) => (e.matches ? pauseAll() : resumeAll()));
Warten, bis alle Animationen beendet sind
const closeDialog = async (host) => {
const root = host.shadowRoot;
root.querySelector('.panel').classList.add('closing'); // löst CSS-Übergang aus
// Einen Frame warten, damit der Übergang erzeugt wird
await new Promise(requestAnimationFrame);
await Promise.all(root.getAnimations().map((a) => a.finished));
host.remove();
console.log('Dialog entfernt');
};
closeDialog(document.querySelector('fancy-dialog'));
// Wichtig · Fallstricke
- Kapselung:
document.getAnimations()gibt keine Animationen aus Shadow-Bäumen zurück. Wer alle Animationen der Seite braucht, muss die Shadow-Roots rekursiv durchlaufen. Das geht nur beimode: "open"oder über eine intern gespeicherte Referenz auf eine geschlossene Root. - Geslottete Inhalte gehören zum Light DOM. Ihre Animationen tauchen in
document.getAnimations()bzw. in der Root des Hosts auf, nicht in der Shadow-Root, in die sie projiziert werden. - Eine Liste für alle Nachfahren gibt es auch über
element.getAnimations({ subtree: true }). Anders als dort hatShadowRoot.getAnimations()keine Optionen. - Der Aufruf kann einen Stil-Neuberechnung erzwingen, damit ausstehende CSS-Animationen und -Übergänge erfasst werden. Das kostet Leistung, deshalb nicht in engen Schleifen oder in jedem Frame aufrufen.
- Direkt nach einer Klassenänderung ist ein neuer CSS-Übergang mitunter erst nach der Stilberechnung sichtbar. Im Zweifel einen Frame abwarten.
- Animationen mit dem Zustand
finishedund ohnefill-Modus zählen nicht als wirksam und fehlen im Ergebnis. - Das Array ist eine Momentaufnahme, keine Live-Liste.
- Kompatibilität: Chrome/Edge 84+, Firefox 75+, Safari 14+. Die Methode fehlt in sehr alten Browsern, dort ist eine Funktionsprüfung mit
'getAnimations' in ShadowRoot.prototypesinnvoll.