Start · Sprachen · JavaScript · Referenz · Element: beforeinput

Element: beforeinput

Ereignis

Wird ausgelöst, kurz bevor der Inhalt eines <code>&lt;input&gt;</code>, <code>&lt;textarea&gt;</code> oder <code>contenteditable</code>-Elements geändert wird – und lässt sich meist abbrechen.

seit JavaScript Baseline: seit 2021 in allen modernen Browsern (Ch Kategorie: webapi

Signatur

element.addEventListener("beforeinput", handler)

Beschreibung

Das Ereignis beforeinput wird ausgelöst, bevor der Browser den Inhalt eines bearbeitbaren Elements verändert. Dazu gehören <input>, <textarea> und alle Elemente mit contenteditable. Der Handler bekommt ein InputEvent. Es sagt, was passieren soll (inputType, z. B. "insertText", "deleteContentBackward", "insertFromPaste") und welche Daten eingefügt werden (data bzw. dataTransfer).

Anders als das Ereignis input, das erst nach der Änderung kommt, lassen sich die meisten beforeinput-Ereignisse mit event.preventDefault() abbrechen. Damit kann man Eingaben filtern (z. B. nur Ziffern erlauben), Einfügen aus der Zwischenablage abfangen oder in Rich-Text-Editoren eigene Formatierungslogik umsetzen, ohne den DOM hinterher reparieren zu müssen.

Im Vergleich zu keydown ist beforeinput zuverlässiger: Es erfasst auch Eingaben über Einfügen, Ziehen und Ablegen, Autokorrektur, Spracheingabe und IME. Außerdem beschreibt es die beabsichtigte Bearbeitung, nicht die gedrückte Taste. Das Ereignis steigt im DOM auf (Bubbling), man kann es also per Ereignisdelegation an einem Elternelement abfangen. Mit event.getTargetRanges() erhält man in contenteditable-Elementen die betroffenen Bereiche als StaticRange-Objekte.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Name des Ereignisses: "beforeinput". Eine Property onbeforeinput gibt es in modernen Browsern ebenfalls, die Unterstützung ist aber uneinheitlicher als bei addEventListener.
$handler Pflicht (event: InputEvent) => void Callback-Funktion, die ein InputEvent erhält. Wichtige Eigenschaften: inputType, data, dataTransfer, isComposing, cancelable; Methode: getTargetRanges().
$options boolean | AddEventListenerOptions false Optionen wie capture, once, passive oder signal. Achtung: Mit passive: true hat preventDefault() keine Wirkung.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Den Standard kann der Handler über event.preventDefault() abbrechen, sofern event.cancelable den Wert true hat.

Beispiele

Nur Ziffern in ein Eingabefeld zulassen

const plz = document.querySelector('#plz');

plz.addEventListener('beforeinput', (event) => {
  // Löschen, Rückgängig usw. immer erlauben
  if (!event.inputType.startsWith('insert')) return;

  const text = event.data ?? event.dataTransfer?.getData('text/plain') ?? '';
  if (/\D/.test(text)) {
    event.preventDefault();
    console.log(`Abgelehnt: "${text}" (${event.inputType})`);
  }
});
Abgelehnt: "a" (insertText)

Eingabetyp protokollieren und Listener mit AbortController entfernen

const editor = document.querySelector('[contenteditable]');
const controller = new AbortController();

editor.addEventListener('beforeinput', (event) => {
  console.log(event.inputType, JSON.stringify(event.data));
}, { signal: controller.signal });

// Nach 10 Sekunden Protokollierung beenden
setTimeout(() => controller.abort(), 10_000);
insertText "H" deleteContentBackward null insertParagraph null

Fett-Formatierung in einem Rich-Text-Editor verhindern (on-Property)

const editor = document.querySelector('#editor');

editor.onbeforeinput = (event) => {
  if (event.inputType === 'formatBold' || event.inputType === 'formatItalic') {
    event.preventDefault();
    console.log('Formatierung ist hier nicht erlaubt.');
  }
};

// Handler wieder entfernen
// editor.onbeforeinput = null;
Formatierung ist hier nicht erlaubt.

Eingefügten Text vor dem Einfügen bereinigen

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

textarea.addEventListener('beforeinput', (event) => {
  if (event.inputType !== 'insertFromPaste') return;

  event.preventDefault();
  const raw = event.dataTransfer.getData('text/plain');
  const clean = raw.replace(/\s+/g, ' ').trim();
  // Bereinigten Text an der Cursorposition einfügen
  textarea.setRangeText(clean, textarea.selectionStart, textarea.selectionEnd, 'end');
  textarea.dispatchEvent(new Event('input', { bubbles: true }));
});

// Wichtig · Fallstricke

  • Nicht immer abbrechbar: Während einer IME-Komposition (event.isComposing === true, z. B. bei chinesischer oder japanischer Eingabe) sind Ereignisse wie insertCompositionText nicht abbrechbar. Vor preventDefault() daher event.cancelable prüfen.
  • Browser-Unterschiede: Firefox unterstützt beforeinput erst ab Version 87. Welche inputType-Werte vorkommen und ob getTargetRanges() bei <input>/<textarea> Werte liefert (dort meist ein leeres Array), unterscheidet sich je nach Engine. Die Werte historyUndo/historyRedo sind nicht überall abbrechbar.
  • Keine Auslösung durch Skripte: Setzt man element.value per JavaScript, wird weder beforeinput noch input ausgelöst.
  • Nicht bei jedem Eingabetyp: Bei <select>, Checkboxen oder Radiobuttons wird kein beforeinput ausgelöst.
  • data kann null sein: Beim Löschen, Einfügen aus der Zwischenablage oder Ziehen und Ablegen stehen die Daten stattdessen in dataTransfer.
  • Keine Sicherheitsprüfung: Ein Eingabefilter mit beforeinput dient nur der Bedienbarkeit. Eingaben müssen immer zusätzlich auf dem Server geprüft werden.
  • Wer nach einem abgebrochenen Ereignis den Inhalt selbst ändert, sollte bei Bedarf ein input-Ereignis manuell auslösen, damit Frameworks und Formularlogik davon erfahren.