Signatur
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
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
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
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);
// Wichtig · Fallstricke
- Keine Event-Delegation per Bubbling: Das Ereignis blubbert nicht auf. Ein Listener auf
documentgreift 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. commandforverweist per ID nur auf Elemente im selben Baum (Dokument bzw. Shadow Root). Über Shadow-DOM-Grenzen hinweg setzen Sie die EigenschaftcommandForElementdirekt.- 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>mitcommand-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
clickoder ein Polyfill.