Start · Sprachen · JavaScript · Referenz · FocusEvent

FocusEvent

Schnittstelle

Stellt Fokus-Ereignisse wie <code>focus</code>, <code>blur</code>, <code>focusin</code> und <code>focusout</code> dar und gibt über <code>relatedTarget</code> das jeweils andere beteiligte Element an.

seit JavaScript Baseline: alle Browser (DOM Level 3 Events / UI Ev Kategorie: webapi

Signatur

interface FocusEvent extends UIEvent

Beschreibung

FocusEvent ist die Ereignis-Schnittstelle für alle Fokuswechsel im DOM. Wenn ein Element den Tastatur-Fokus erhält oder verliert, erzeugt der Browser Ereignisse dieses Typs: focus und focusin beim Erhalten, blur und focusout beim Verlieren des Fokus. Die Schnittstelle erbt von UIEvent und damit von Event.

Der wichtigste Unterschied zwischen den Ereignispaaren: focus und blur steigen nicht auf (bubbling), focusin und focusout dagegen schon. Wer Fokuswechsel zentral an einem Container überwachen möchte (Ereignis-Delegation, z. B. für ein ganzes Formular), sollte daher focusin/focusout verwenden oder bei focus/blur die Capture-Phase nutzen.

Die einzige eigene Eigenschaft ist relatedTarget: Bei blur/focusout ist es das Element, das den Fokus erhält, bei focus/focusin das Element, das den Fokus verliert. Damit lässt sich z. B. prüfen, ob der Fokus einen Komponentenbereich (Dropdown, Dialog, Menü) wirklich verlässt oder nur innerhalb davon wandert.

Mit dem Konstruktor new FocusEvent(type, options) lassen sich synthetische Fokus-Ereignisse erzeugen, etwa für Tests. Solche Ereignisse verschieben den tatsächlichen Fokus aber nicht – dafür ist HTMLElement.prototype.focus() zuständig.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Name des Ereignisses, typischerweise "focus", "blur", "focusin" oder "focusout" (Konstruktor).
$options FocusEventInit {} Optionales Objekt mit den Feldern aus UIEventInit (bubbles, cancelable, composed, view, detail) sowie relatedTarget (EventTarget | null, Standard null).
$relatedTarget EventTarget | null null Instanz-Eigenschaft (schreibgeschützt): das sekundäre Ziel des Fokuswechsels. null, wenn kein solches Element existiert (z. B. Fokus wechselt in ein anderes Fenster) oder aus Sicherheitsgründen verborgen wird.

Rückgabewert

Typ
FocusEvent
Beschreibung
Der Konstruktor liefert eine neue FocusEvent-Instanz; in Event-Handlern wird sie als Ereignisobjekt übergeben.

Beispiele

Fokus und Verlassen eines Eingabefelds behandeln

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

const onFocus = (event) => {
  event.target.classList.add('aktiv');
  console.log('Fokus erhalten, vorher:', event.relatedTarget?.id ?? 'nichts');
};

const onBlur = (event) => {
  event.target.classList.remove('aktiv');
  if (!event.target.value.includes('@')) {
    console.log('Bitte gültige E-Mail eingeben');
  }
};

input.addEventListener('focus', onFocus);
input.addEventListener('blur', onBlur);

// Alternativ über die on-Property:
// input.onfocus = onFocus;

// Später wieder entfernen:
// input.removeEventListener('focus', onFocus);
Fokus erhalten, vorher: name Bitte gültige E-Mail eingeben

Ereignis-Delegation mit focusin/focusout am Formular

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

// focusin/focusout steigen auf – ein Listener genügt für alle Felder
form.addEventListener('focusin', (event) => {
  event.target.closest('.feld')?.classList.add('hervorgehoben');
});

form.addEventListener('focusout', (event) => {
  event.target.closest('.feld')?.classList.remove('hervorgehoben');
});

Dropdown schließen, wenn der Fokus die Komponente verlässt

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

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

Synthetisches FocusEvent erzeugen (z. B. im Test)

const field = document.createElement('input');
document.body.append(field);

field.addEventListener('focusin', (e) => {
  console.log(e instanceof FocusEvent, e.type, e.bubbles, e.relatedTarget);
});

const evt = new FocusEvent('focusin', { bubbles: true, relatedTarget: null });
field.dispatchEvent(evt);
console.log(document.activeElement === field);
true "focusin" true null false

// Wichtig · Fallstricke

  • Bubbling: focus und blur steigen nicht auf. Für Delegation focusin/focusout nutzen oder addEventListener('focus', fn, true) (Capture).
  • Reihenfolge (laut Spezifikation und in aktuellen Browsern): blur → focusout → focus → focusin. Ältere Browser wichen teilweise ab – nicht auf eine exakte Reihenfolge zwischen verschiedenen Elementen verlassen.
  • relatedTarget ist oft null: wenn der Fokus das Dokument/Fenster verlässt, auf ein nicht fokussierbares Element geklickt wird oder das Ziel in einem anderen Ursprung (iframe) liegt. Safari auf macOS fokussiert Buttons beim Klick standardmäßig nicht, daher ist relatedTarget dort bei Klicks auf <button> häufig null.
  • Während blur/focusout zeigt document.activeElement meist schon auf body, noch nicht auf das neue Element. Wer das neue Element braucht, nutzt relatedTarget oder wartet per requestAnimationFrame/setTimeout.
  • Fokus-Ereignisse sind nicht abbrechbar; preventDefault() verhindert den Fokuswechsel nicht. Um Fokus beim Klicken zu verhindern, mousedown/pointerdown abbrechen.
  • Mit dispatchEvent() ausgelöste Ereignisse haben isTrusted === false und ändern den echten Fokus nicht.
  • Barrierefreiheit: Fokus nicht in blur-Handlern „zurückzwingen“ (Fokusfalle), außer in modalen Dialogen mit klarer Schließmöglichkeit.