Start · Sprachen · JavaScript · Referenz · Element: focusin

Element: focusin

Ereignis

Wird ausgelöst, wenn ein Element den Fokus erhalten hat – direkt nach <code>focus</code>, aber im Gegensatz dazu mit Bubbling.

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

Signatur

element.addEventListener("focusin", handler)

Beschreibung

Das Ereignis focusin wird ausgelöst, sobald ein Element den Fokus erhalten hat. Es folgt unmittelbar auf das Ereignis focus. Der entscheidende Unterschied: focusin steigt im DOM auf (Bubbling), focus dagegen nicht. Das Ereignis ist ein FocusEvent und lässt sich nicht abbrechen.

Deshalb eignet sich focusin besonders gut für Event-Delegation: Ein einziger Listener auf einem Formular, einer Toolbar oder einem Dialog erfährt, welches Kindelement gerade den Fokus bekommen hat. Typische Anwendungen sind das Hervorheben aktiver Formulargruppen, Fokus-Tracking für die Barrierefreiheit, Roving-Tabindex-Muster oder das Anzeigen kontextbezogener Hilfetexte.

Über event.target erhält man das Element, das den Fokus bekommen hat, und über event.relatedTarget das Element, das ihn verloren hat (oder null). Das Gegenstück ist focusout. Anders als bei focus gibt es für focusin keine onfocusin-Eigenschaft in den Browsern; man registriert den Handler daher mit addEventListener.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "focusin".
$handler Pflicht (event: FocusEvent) => void Callback, das ein FocusEvent erhält. Wichtige Eigenschaften: target (bekommt den Fokus), relatedTarget (verliert den Fokus bzw. null).
$options boolean | AddEventListenerOptions false Optionen wie capture, once, passive oder signal (zum Entfernen per AbortController).

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein FocusEvent mit bubbles: true und cancelable: false.

Beispiele

Aktives Formularfeld per Delegation hervorheben

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

// Ein Listener für alle Felder – funktioniert dank Bubbling
form.addEventListener('focusin', (event) => {
  const gruppe = event.target.closest('.feldgruppe');
  gruppe?.classList.add('aktiv');
  console.log(`Fokus auf: ${event.target.name}`);
});

form.addEventListener('focusout', (event) => {
  event.target.closest('.feldgruppe')?.classList.remove('aktiv');
});
Fokus auf: email

Fokuswechsel mit relatedTarget protokollieren

document.addEventListener('focusin', (event) => {
  const von = event.relatedTarget?.id || '(nichts)';
  const nach = event.target.id || event.target.tagName;
  console.log(`Fokus: ${von} → ${nach}`);
});
Fokus: vorname → nachname

Listener wieder entfernen (removeEventListener und AbortController)

const toolbar = document.querySelector('[role="toolbar"]');

const onFocusIn = (event) => {
  // Roving Tabindex: nur das fokussierte Element ist per Tab erreichbar
  toolbar.querySelectorAll('button').forEach((btn) => {
    btn.tabIndex = btn === event.target ? 0 : -1;
  });
};

toolbar.addEventListener('focusin', onFocusIn);
// Später wieder entfernen:
toolbar.removeEventListener('focusin', onFocusIn);

// Alternative mit AbortController
const controller = new AbortController();
toolbar.addEventListener('focusin', onFocusIn, { signal: controller.signal });
controller.abort(); // entfernt den Listener

// Wichtig · Fallstricke

  • Keine onfocusin-Eigenschaft: element.onfocusin = … funktioniert in den Browsern nicht zuverlässig. Verwende addEventListener.
  • Reihenfolge beim Fokuswechsel von A nach B: blur (A) → focusout (A) → focus (B) → focusin (B). Ältere Spezifikationen und manche alten Browser verwendeten eine andere Reihenfolge; verlasse dich nicht zu stark darauf.
  • Alternative ohne focusin: focus mit { capture: true } erreicht ebenfalls den Elternknoten, allerdings in der Capture-Phase.
  • relatedTarget ist null, wenn der Fokus von außerhalb des Dokuments kommt (z. B. aus einem anderen Fenster) oder wenn das vorherige Element nicht fokussierbar war.
  • Ein programmatischer Aufruf von element.focus() löst focusin ebenfalls aus. Wer darin erneut den Fokus verschiebt, riskiert Endlosschleifen.
  • Bei Shadow DOM wird event.target auf den Host umgeleitet (Retargeting). Das tatsächlich fokussierte Element findest du über event.composedPath()[0].
  • Kompatibilität: wird von allen modernen Browsern unterstützt. Firefox kennt das Ereignis erst ab Version 52.