Start · Sprachen · JavaScript · Referenz · UserActivation

UserActivation

Schnittstelle

Gibt an, ob der Benutzer gerade mit der Seite interagiert (transiente Aktivierung) oder seit dem Laden schon einmal interagiert hat (Sticky-Aktivierung).

seit JavaScript Baseline 2023: Chrome 72+, Edge 79+, Firefox 120+, Kategorie: webapi

Signatur

interface UserActivation

Beschreibung

Das Interface UserActivation beschreibt den Aktivierungszustand durch den Benutzer in einem Fenster. Man greift darüber auf navigator.userActivation zu, einen eigenen Konstruktor gibt es nicht. Browser erlauben viele sensible APIs nur, wenn eine echte Benutzeraktion vorliegt, etwa Pop-ups (window.open()), den Vollbildmodus, navigator.clipboard.write(), Audio-Autoplay oder navigator.vibrate().

Das Interface hat zwei schreibgeschützte Eigenschaften vom Typ Boolean:

  • hasBeenActive: Sticky-Aktivierung. Ist true, sobald der Benutzer seit dem Laden der Seite mindestens einmal interagiert hat, und bleibt danach true.
  • isActive: Transiente Aktivierung. Ist nur kurz nach einer aktivierenden Aktion true, z. B. nach keydown, mousedown, pointerdown oder pointerup bei Maus und touchend. Nach einem vom Browser festgelegten Zeitfenster von einigen Sekunden erlischt sie wieder. Manche APIs „verbrauchen“ sie auch sofort, z. B. window.open().

Typische Anwendungsfälle: Vor dem Aufruf einer eingeschränkten API prüfen, ob sie überhaupt klappen kann. Die Oberfläche anpassen, etwa einen Hinweis „Klicken zum Aktivieren des Tons“ anzeigen. Oder in Code prüfen, der später läuft (Timer, Nachrichten von einem iframe), ob die auslösende Benutzeraktion noch gilt.

Rückgabewert

Typ
UserActivation
Beschreibung
Erreichbar über navigator.userActivation. Das Objekt ist live, seine Eigenschaften zeigen immer den aktuellen Zustand.

Beispiele

Zugriff auf das Objekt und Auslesen des Zustands

const activation = navigator.userActivation;

console.log(activation instanceof UserActivation);
console.log('Schon einmal aktiv:', activation.hasBeenActive);
console.log('Gerade aktiv:', activation.isActive);
true Schon einmal aktiv: false Gerade aktiv: false

Autoplay-Hinweis nur ohne bisherige Interaktion anzeigen

const video = document.querySelector('video');
const hint = document.querySelector('#sound-hint');

const startWithSound = async () => {
  if (navigator.userActivation?.hasBeenActive) {
    video.muted = false;
    await video.play();
    hint.hidden = true;
  } else {
    // Ohne Interaktion nur stumm abspielen
    video.muted = true;
    await video.play();
    hint.hidden = false;
  }
};

startWithSound();
document.addEventListener('pointerdown', startWithSound, { once: true });

Pop-up nur bei gültiger transienter Aktivierung öffnen

const button = document.querySelector('#share');

button.addEventListener('click', async () => {
  const data = await fetch('/api/share-url').then((r) => r.json());

  // Nach dem await kann die transiente Aktivierung abgelaufen sein
  if (navigator.userActivation.isActive) {
    window.open(data.url, '_blank', 'width=600,height=400');
  } else {
    console.warn('Aktivierung abgelaufen – Link stattdessen anzeigen');
    document.querySelector('#fallback-link').href = data.url;
  }
});
Aktivierung abgelaufen – Link stattdessen anzeigen (nur bei langsamer Antwort)

Aktivierungszustand an ein iframe weitergeben

// Im übergeordneten Dokument
const frame = document.querySelector('iframe');

document.addEventListener('keydown', () => {
  frame.contentWindow.postMessage(
    { type: 'ping' },
    { targetOrigin: 'https://widget.example', includeUserActivation: true }
  );
});

// Im iframe (nur Chromium: includeUserActivation)
window.addEventListener('message', (event) => {
  console.log('Aktivierung beim Absender:', event.userActivation?.isActive);
});
Aktivierung beim Absender: true

// Wichtig · Fallstricke

  • Nur lesbar: Eine Aktivierung lässt sich nicht künstlich erzeugen. Mit element.click() oder dispatchEvent() erzeugte Ereignisse lösen keine Aktivierung aus, weil isTrusted dann false ist.
  • Zeitfenster: isActive gilt nur für eine vom Browser festgelegte kurze Zeit, in Chromium etwa 5 Sekunden. Lange await-Ketten, z. B. mit fetch, können sie ablaufen lassen. Rufe eingeschränkte APIs darum möglichst synchron im Event-Handler auf.
  • Verbrauch: APIs wie window.open() oder PaymentRequest.show() verbrauchen die transiente Aktivierung. Danach ist isActive sofort false.
  • Nicht jedes Ereignis zählt: mousemove, scroll, wheel oder die Escape-Taste lösen keine Aktivierung aus.
  • Kompatibilität: navigator.userActivation ist erst seit Firefox 120 und Safari 16.4 verfügbar. In älteren Browsern ist der Wert undefined, deshalb mit optionaler Verkettung (?.) prüfen. Die Option includeUserActivation und MessageEvent.userActivation sind nicht standardisiert und gibt es nur in Chromium.
  • Die Aktivierung gilt für ein Fenster. Innerhalb eines Frame-Baums wird sie an übergeordnete Frames weitergegeben, bei gleichem Ursprung auch an untergeordnete Frames, aber nie an Frames desselben Ursprungs außerhalb der Kette.