Start · Sprachen · JavaScript · Referenz · ShadowRoot.getAnimations()

ShadowRoot.getAnimations()

Methode

Gibt ein Array aller aktuell wirksamen <code>Animation</code>-Objekte zurück, deren Zielelemente Nachkommen des Shadow-Baums sind.

seit JavaScript Baseline 2020: Chrome 84+, Firefox 75+, Safari 14+ Kategorie: webapi

Signatur

ShadowRoot.prototype.getAnimations()

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

Typ
Animation[]
Beschreibung
Ein neues Array von 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);
});
1 "pulse" 0

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'));
Dialog entfernt

// 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 bei mode: "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 hat ShadowRoot.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 finished und ohne fill-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.prototype sinnvoll.