Start · Sprachen · JavaScript · Referenz · Element: focusout

Element: focusout

Ereignis

Wird ausgelöst, wenn ein Element den Fokus verliert, direkt nach <code>blur</code>. Anders als <code>blur</code> steigt das Ereignis im DOM auf (Bubbling).

seit JavaScript Baseline: alle Browser (Firefox ab Version 52) Kategorie: webapi

Signatur

element.addEventListener("focusout", handler)

Beschreibung

Das Ereignis focusout wird an einem Element ausgelöst, sobald es den Fokus verliert, etwa durch Tab-Taste, Mausklick auf ein anderes Element oder programmatisch per element.blur(). Es ist ein FocusEvent und wird direkt nach dem Ereignis blur ausgelöst.

Der wichtigste Unterschied zu blur: focusout steigt auf (bubbles). Deshalb eignet es sich gut für Ereignis-Delegation. Ein einziger Listener am <form> oder an einem Container reicht, um das Verlassen aller Eingabefelder zu überwachen, etwa für eine Validierung beim Verlassen eines Feldes oder zum automatischen Speichern.

Über die Eigenschaft relatedTarget erfährst du, welches Element den Fokus als Nächstes bekommt. Wechselt der Fokus aus dem Fenster heraus oder auf ein Element, das keinen Fokus annehmen kann, ist der Wert null. Damit lässt sich zuverlässig prüfen, ob der Fokus einen ganzen Bereich verlassen hat, zum Beispiel um ein Dropdown oder Menü zu schließen.

Registriert wird das Ereignis mit addEventListener("focusout", …). Eine eigene Eigenschaft onfocusout ist nicht in allen Browsern zuverlässig vorhanden (in Firefox fehlt sie lange). Nutze daher bevorzugt addEventListener.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "focusout".
$handler Pflicht (event: FocusEvent) => void Callback, der ein FocusEvent erhält. Wichtige Eigenschaften: target (Element, das den Fokus verliert) und relatedTarget (Element, das den Fokus bekommt, oder null).
$options boolean | { capture?: boolean, once?: boolean, passive?: boolean, signal?: AbortSignal } false Optionale Listener-Optionen, z. B. once oder signal zum späteren Entfernen über einen AbortController.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Das Ereignis selbst ist nicht abbrechbar: preventDefault() verhindert den Fokusverlust nicht.

Beispiele

Formularvalidierung per Ereignis-Delegation

const form = document.querySelector('#signup');

// Ein Listener für alle Felder, möglich, weil focusout aufsteigt
form.addEventListener('focusout', (event) => {
  const field = event.target;
  if (!(field instanceof HTMLInputElement)) return;

  const valid = field.checkValidity();
  field.classList.toggle('is-invalid', !valid);
  console.log(`${field.name}: ${valid ? 'gültig' : 'ungültig'}`);
});
email: ungültig

Dropdown schließen, wenn der Fokus den Bereich verlässt

const menu = document.querySelector('.dropdown');

menu.addEventListener('focusout', (event) => {
  // relatedTarget = Element, das den Fokus als Nächstes bekommt
  const next = event.relatedTarget;
  if (!next || !menu.contains(next)) {
    menu.classList.remove('open');
    console.log('Menü geschlossen');
  }
});
Menü geschlossen

Listener entfernen: removeEventListener und AbortController

const input = document.querySelector('#title');

const autosave = (event) => {
  localStorage.setItem('draft-title', event.target.value);
  console.log('Entwurf gespeichert');
};

input.addEventListener('focusout', autosave);
// Später wieder abmelden
input.removeEventListener('focusout', autosave);

// Alternative mit AbortController
const controller = new AbortController();
input.addEventListener('focusout', autosave, { signal: controller.signal });
controller.abort(); // entfernt den Listener

Reihenfolge der Fokus-Ereignisse beobachten

const a = document.querySelector('#a');
const b = document.querySelector('#b');

for (const type of ['blur', 'focusout', 'focus', 'focusin']) {
  document.addEventListener(type, (e) => console.log(type, e.target.id), true);
}

a.focus();
b.focus(); // Fokuswechsel von #a nach #b
focus a focusin a blur a focusout a focus b focusin b

// Wichtig · Fallstricke

  • Bubbling: focusout steigt auf, blur nicht. Für Delegation also focusout verwenden oder blur in der Capture-Phase abfangen.
  • Reihenfolge: In modernen Browsern gilt: blur → focusout → focus → focusin. Ältere Browser (alte Edge- und IE-Versionen) wichen davon teils ab.
  • relatedTarget ist oft null, etwa bei einem Klick auf nicht fokussierbare Elemente, beim Wechsel in ein anderes Fenster oder einen anderen Tab, in manchen Browsern auch bei Buttons (Safari auf macOS fokussiert Buttons per Klick nicht). Prüfe darauf, bevor du Menüs schließt.
  • Nicht abbrechbar: preventDefault() verhindert den Fokusverlust nicht. Wer Fokus erzwingen will, ruft focus() erneut auf. Vorsicht: Das kann Endlosschleifen erzeugen und die Barrierefreiheit verschlechtern.
  • Beim Entfernen des fokussierten Elements aus dem DOM lösen manche Browser (z. B. Chrome) focusout aus, andere nicht. Verlasse dich nicht darauf.
  • onfocusout als Eigenschaft bzw. HTML-Attribut fehlte in Firefox lange. addEventListener ist die sichere Wahl.
  • Im Shadow DOM wird target auf den Host umgeleitet (retargeting). Das eigentliche Element liefert event.composedPath()[0].