Start · Sprachen · JavaScript · Referenz · HTMLElement: command

HTMLElement: command

Ereignis

Wird auf dem Zielelement ausgelöst, wenn ein <code>&lt;button&gt;</code> mit gültigen <code>commandfor</code>- und <code>command</code>-Werten aktiviert wird.

seit JavaScript Chrome/Edge 135+, Firefox 144+, Safari 26.2+ (Invo Kategorie: webapi

Signatur

element.addEventListener("command", (event: CommandEvent) =&gt; {})

Beschreibung

Das command-Ereignis gehört zur Invoker Commands API. Ein <button> kann über das HTML-Attribut commandfor (bzw. die Eigenschaft commandForElement) ein anderes Element steuern und mit command (bzw. der Eigenschaft command) festlegen, welche Aktion ausgeführt wird. Wird der Button angeklickt oder per Tastatur aktiviert, feuert der Browser auf dem gesteuerten Element ein command-Ereignis vom Typ CommandEvent.

Eingebaute Befehle arbeiten ganz ohne JavaScript: show-modal, close und request-close für <dialog> sowie show-popover, hide-popover und toggle-popover für Popover-Elemente. Eigene Befehle müssen mit zwei Bindestrichen beginnen (z. B. --rotate). Sie haben kein Standardverhalten und werden ausschließlich über einen Listener für dieses Ereignis umgesetzt.

Das Ereignisobjekt hat zwei zusätzliche Eigenschaften: event.command (der Befehlsname als String) und event.source (der auslösende Button). Das Ereignis lässt sich abbrechen: Mit event.preventDefault() unterbinden Sie die eingebaute Aktion, etwa das Schließen eines Dialogs.

Sie registrieren den Listener entweder mit addEventListener("command", …) oder über die Eigenschaft oncommand. Typische Anwendungen sind deklarative Bedienelemente wie Menüs, Dialoge und Werkzeugleisten, die ohne eigene click-Listener auf jedem einzelnen Button auskommen.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname, immer "command".
$listener Pflicht (event: CommandEvent) => void Callback-Funktion. Sie erhält ein CommandEvent mit den Eigenschaften command (string) und source (HTMLButtonElement).
$options boolean | AddEventListenerOptions false Übliche Listener-Optionen wie once, capture oder signal.

Rückgabewert

Typ
void
Beschreibung
addEventListener hat keinen Rückgabewert. Im Handler bestimmt event.preventDefault(), ob die eingebaute Aktion ausgeführt wird.

Beispiele

Eigenen Befehl mit addEventListener umsetzen

// HTML-Struktur per JS erzeugen: Button steuert ein Bild
const img = document.createElement('img');
img.id = 'foto';
img.alt = 'Beispielbild';
const btn = document.createElement('button');
btn.type = 'button';
btn.textContent = 'Drehen';
btn.commandForElement = img; // entspricht commandfor="foto"
btn.command = '--rotate';     // eigene Befehle beginnen mit --
document.body.append(btn, img);

let winkel = 0;
img.addEventListener('command', (event) => {
  if (event.command === '--rotate') {
    winkel = (winkel + 90) % 360;
    img.style.rotate = `${winkel}deg`;
    console.log(`Gedreht auf ${winkel}° durch`, event.source.textContent);
  }
});

btn.click(); // löst das command-Ereignis auf dem Bild aus
Gedreht auf 90° durch Drehen

oncommand-Eigenschaft und removeEventListener

const panel = document.createElement('div');
const btn = document.createElement('button');
btn.type = 'button';
btn.textContent = 'Markieren';
btn.commandForElement = panel;
btn.command = '--highlight';
document.body.append(btn, panel);

// Variante 1: on-Property (ersetzt einen früher gesetzten Handler)
panel.oncommand = (event) => console.log('oncommand:', event.command);

// Variante 2: Listener, der sich später wieder entfernen lässt
const handler = (event) => {
  panel.classList.toggle('aktiv');
  console.log('Listener:', panel.classList.contains('aktiv'));
};
panel.addEventListener('command', handler);

btn.click();
panel.removeEventListener('command', handler);
panel.oncommand = null;
btn.click(); // keine Ausgabe mehr
oncommand: --highlight Listener: true

Schließen eines Dialogs mit preventDefault verhindern

const dialog = document.createElement('dialog');
dialog.innerHTML = '<textarea></textarea>';
const closeBtn = document.createElement('button');
closeBtn.type = 'button';
closeBtn.textContent = 'Schließen';
closeBtn.commandForElement = dialog;
closeBtn.command = 'close'; // eingebauter Befehl
dialog.append(closeBtn);
document.body.append(dialog);
dialog.showModal();

dialog.addEventListener('command', (event) => {
  const text = dialog.querySelector('textarea').value;
  if (event.command === 'close' && text.trim() !== '') {
    if (!confirm('Ungespeicherte Eingaben verwerfen?')) {
      event.preventDefault(); // Dialog bleibt offen
    }
  }
});

Feature-Erkennung mit Fallback

const unterstuetzt = 'command' in HTMLButtonElement.prototype &&
  'commandForElement' in HTMLButtonElement.prototype;

if (!unterstuetzt) {
  // Fallback: click-Listener auf alle Buttons mit commandfor
  document.querySelectorAll('button[commandfor]').forEach((btn) => {
    btn.addEventListener('click', () => {
      const ziel = document.getElementById(btn.getAttribute('commandfor'));
      const cmd = btn.getAttribute('command');
      if (cmd === 'show-modal') ziel?.showModal();
      if (cmd === 'close') ziel?.close();
    });
  });
}
console.log('Invoker Commands nativ:', unterstuetzt);
Invoker Commands nativ: true

// Wichtig · Fallstricke

  • Keine Event-Delegation per Bubbling: Das Ereignis blubbert nicht auf. Ein Listener auf document greift deshalb nur in der Capture-Phase: document.addEventListener("command", fn, { capture: true }).
  • Das Ziel ist das gesteuerte Element, nicht der Button. Den auslösenden Button liefert event.source.
  • Eigene Befehle brauchen das Präfix --. Unbekannte Werte ohne dieses Präfix sind ungültig. Für sie wird kein Ereignis ausgelöst.
  • commandfor verweist per ID nur auf Elemente im selben Baum (Dokument bzw. Shadow Root). Über Shadow-DOM-Grenzen hinweg setzen Sie die Eigenschaft commandForElement direkt.
  • Setzen Sie innerhalb von Formularen ausdrücklich type="button", damit der Button das Formular nicht absendet.
  • Die Aktivierung funktioniert nur mit <button>-Elementen. Ein <div> mit command-Attribut löst nichts aus.
  • Browser-Kompatibilität: Die API ist relativ neu (Chromium 135+, Firefox 144+, Safari 26.2+). Für ältere Browser brauchen Sie eine Feature-Erkennung und einen Fallback über click oder ein Polyfill.