Start · Sprachen · JavaScript · Referenz · Document.execCommand()

Document.execCommand()

Methode

Führt einen Bearbeitungsbefehl wie <code>bold</code>, <code>insertText</code> oder <code>copy</code> auf der aktuellen Auswahl in einem bearbeitbaren Bereich aus.

seit JavaScript Veraltet (deprecated) – in allen Browsern weiterhi deprecated seit ja Kategorie: webapi

Signatur

Document.prototype.execCommand(commandName, showDefaultUI, valueArgument)

Beschreibung

document.execCommand() führt einen benannten Bearbeitungsbefehl auf der aktuellen Auswahl oder an der Cursorposition aus. Das funktioniert nur, wenn das Dokument im Modus designMode = "on" ist oder der Fokus in einem Element mit contenteditable bzw. in einem <input>/<textarea> liegt. Zu den typischen Befehlen gehören bold, italic, underline, createLink, insertHTML, insertText, formatBlock, undo, redo, copy und cut.

Früher war die Methode die Grundlage für viele Rich-Text-Editoren (WYSIWYG) und für die Funktion „In die Zwischenablage kopieren“. Inzwischen gilt sie offiziell als veraltet: Es gibt keinen verbindlichen Standard, und die Browser erzeugen teilweise unterschiedliches HTML (zum Beispiel <b> statt <strong> oder <span style>).

Einen praktischen Vorteil hat sie trotzdem noch: Mit execCommand vorgenommene Änderungen landen im nativen Rückgängig-Stapel des Browsers, sodass Strg+Z sie zurücknehmen kann. Deshalb wird insertText heute noch gern verwendet, um Text in Eingabefelder einzufügen, ohne dass die Undo-Historie verloren geht. Für neuen Code solltest du die Clipboard API, die Selection/Range-APIs und das Ereignis beforeinput verwenden.

Parameter

Name Typ Default Beschreibung
$commandName Pflicht string Name des Befehls, z. B. "bold", "insertText", "createLink", "foreColor", "formatBlock", "copy", "undo".
$showDefaultUI boolean false Gibt an, ob eine Standard-Benutzeroberfläche angezeigt werden soll. Wird von modernen Browsern ignoriert, deshalb immer false übergeben.
$valueArgument string | null null Zusätzlicher Wert für Befehle, die einen brauchen, z. B. die URL bei createLink, die Farbe bei foreColor, den Text bei insertText oder "<h2>" bei formatBlock.

Rückgabewert

Typ
boolean
Beschreibung
true, wenn der Befehl unterstützt und ausgeführt wurde, sonst false (etwa bei unbekanntem Befehl, fehlendem bearbeitbarem Kontext oder bei copy/cut ohne Benutzeraktion).

Beispiele

Einfache Formatierungs-Toolbar für contenteditable

// HTML: <div id="editor" contenteditable="true">Text hier…</div>
//       <button data-cmd="bold">B</button> <button data-cmd="italic">I</button>
const editor = document.querySelector('#editor');

document.querySelectorAll('[data-cmd]').forEach((btn) => {
  // mousedown verhindern, damit die Auswahl im Editor erhalten bleibt
  btn.addEventListener('mousedown', (e) => e.preventDefault());
  btn.addEventListener('click', () => {
    const ok = document.execCommand(btn.dataset.cmd, false, null);
    console.log(`${btn.dataset.cmd}:`, ok);
    editor.focus();
  });
});
bold: true

Link und Überschrift einfügen

const addLink = () => {
  const url = prompt('URL eingeben:', 'https://');
  if (url && /^https?:\/\//.test(url)) {
    document.execCommand('createLink', false, url);
  }
};

const makeHeading = () => {
  // Den aktuellen Block in eine h2 umwandeln
  document.execCommand('formatBlock', false, '<h2>');
};

document.querySelector('#link-btn').addEventListener('click', addLink);
document.querySelector('#h2-btn').addEventListener('click', makeHeading);

Text einfügen, ohne die Undo-Historie zu verlieren

const textarea = document.querySelector('textarea');

const insertEmoji = (emoji) => {
  textarea.focus();
  // Mit insertText bleibt Strg+Z funktionsfähig – anders als bei textarea.value = …
  const ok = document.execCommand('insertText', false, emoji);
  if (!ok) {
    // Rückfall für Umgebungen ohne Unterstützung
    textarea.setRangeText(emoji, textarea.selectionStart, textarea.selectionEnd, 'end');
  }
};

document.querySelector('#emoji-btn').addEventListener('click', () => insertEmoji('🙂'));

Kopieren mit modernem Weg und Rückfall

const copyText = async (text) => {
  if (navigator.clipboard?.writeText) {
    await navigator.clipboard.writeText(text);
    return true;
  }
  // Alter Rückfall über ein temporäres Textfeld
  const ta = document.createElement('textarea');
  ta.value = text;
  ta.setAttribute('readonly', '');
  ta.style.position = 'fixed';
  ta.style.opacity = '0';
  document.body.append(ta);
  ta.select();
  const ok = document.execCommand('copy');
  ta.remove();
  return ok;
};

document.querySelector('#copy-btn').addEventListener('click', async () => {
  console.log('Kopiert:', await copyText('Hallo Zwischenablage'));
});
Kopiert: true

// Wichtig · Fallstricke

  • Veraltet: Die Methode ist nicht standardisiert (es gibt nur einen unvollständigen W3C-Entwurf). Sie funktioniert in allen aktuellen Browsern, kann sich aber je nach Browser unterschiedlich verhalten und soll in neuem Code nicht verwendet werden.
  • Uneinheitliches Markup: Chrome, Firefox und Safari erzeugen für denselben Befehl unterschiedliches HTML. Mit document.execCommand('styleWithCSS', false, true) lässt sich steuern, ob style-Attribute oder Tags wie <b> entstehen.
  • Sicherheit (XSS): insertHTML fügt das übergebene HTML ungefiltert ein. Benutzereingaben musst du vorher bereinigen (z. B. mit DOMPurify). Das gilt auch für den Inhalt eines contenteditable-Bereichs, bevor du ihn speicherst oder an anderer Stelle ausgibst. Bei createLink solltest du javascript:-URLs abweisen.
  • Benutzeraktion nötig: copy und cut funktionieren nur innerhalb eines durch den Nutzer ausgelösten Ereignisses (z. B. click). paste ist in Webseiten fast immer gesperrt und gibt false zurück.
  • Der Fokus bzw. die Auswahl muss beim Aufruf im bearbeitbaren Bereich liegen. Wenn du auf einen Button klickst, geht die Auswahl oft verloren. Abhilfe schafft preventDefault() im mousedown-Handler.
  • Mit document.queryCommandState(), queryCommandValue() und queryCommandSupported() lassen sich Zustand und Unterstützung abfragen. Diese Methoden sind ebenfalls veraltet.
  • Ersatz: navigator.clipboard für die Zwischenablage, Selection/Range für DOM-Manipulationen, beforeinput/InputEvent für eigene Editor-Logik, setRangeText() für Eingabefelder.