Start · Sprachen · JavaScript · Referenz · FocusEvent.relatedTarget

FocusEvent.relatedTarget

Eigenschaft

Schreibgeschützt: das zweite beteiligte Element bei einem Fokuswechsel, also das Element, das den Fokus abgibt oder bekommt. Ist kein solches Element beteiligt, ist der Wert <code>null</code>.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

FocusEvent.relatedTarget

Beschreibung

Bei einem Fokuswechsel sind meist zwei Elemente beteiligt: eines verliert den Fokus, ein anderes bekommt ihn. event.target ist das Element, an dem das Ereignis ausgelöst wird. relatedTarget ist das jeweils andere Element. Welches das ist, hängt von der Art des Ereignisses ab:

  • blur / focusout: target verliert den Fokus, relatedTarget ist das Element, das ihn bekommt.
  • focus / focusin: target bekommt den Fokus, relatedTarget ist das Element, das ihn verliert.

Die Eigenschaft wird vor allem für Komponenten gebraucht, die wissen müssen, wohin der Fokus wandert. Typische Beispiele sind Dropdown-Menüs, Kombinationsfelder, Popover oder Dialoge. Sie sollen sich nur schließen, wenn der Fokus die Komponente wirklich verlässt, nicht aber, wenn er innerhalb der Komponente zu einem anderen Kind-Element springt. Das lässt sich mit container.contains(event.relatedTarget) sauber prüfen.

Oft ist der Wert null. Das passiert, wenn der Fokus aus dem Dokument hinausgeht (etwa in einen anderen Tab, ein anderes Fenster oder die Adressleiste), wenn er von außen hereinkommt oder wenn auf ein Element geklickt wird, das keinen Fokus annehmen kann. Robuster Code muss diesen Fall immer berücksichtigen.

Rückgabewert

Typ
EventTarget | null
Beschreibung
Das zweite am Fokuswechsel beteiligte Element (meist ein Element) oder null, wenn kein solches Element existiert oder es nicht offengelegt werden darf.

Beispiele

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

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

// focusout steigt im DOM auf (bubbling) – ein Listener am Container reicht
menu.addEventListener('focusout', (event) => {
  const next = event.relatedTarget;
  // null = Fokus geht ganz aus dem Dokument oder auf ein nicht fokussierbares Element
  if (next === null || !menu.contains(next)) {
    menu.classList.remove('open');
    console.log('Menü geschlossen');
  } else {
    console.log('Fokus bleibt im Menü:', next.textContent);
  }
});
Fokus bleibt im Menü: Einstellungen Menü geschlossen

Fokuswechsel protokollieren (focus und blur)

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

const describe = (el) => (el ? `<${el.tagName.toLowerCase()} id="${el.id}">` : 'null');

input.addEventListener('focus', (e) => {
  console.log(`focus: kam von ${describe(e.relatedTarget)}`);
});

input.onblur = (e) => {
  console.log(`blur: geht zu ${describe(e.relatedTarget)}`);
};
focus: kam von <input id="name"> blur: geht zu <button id="submit">

Synthetisches FocusEvent mit relatedTarget erzeugen (z. B. in Tests)

const from = document.createElement('input');
const to = document.createElement('button');
document.body.append(from, to);

from.addEventListener('focusout', (e) => {
  console.log('Ziel des Wechsels:', e.relatedTarget === to);
});

const evt = new FocusEvent('focusout', {
  bubbles: true,
  relatedTarget: to
});
from.dispatchEvent(evt);

// Nachträglich zuweisen hat keine Wirkung – die Eigenschaft ist schreibgeschützt
evt.relatedTarget = null;
console.log(evt.relatedTarget === to);
Ziel des Wechsels: true true

// Wichtig · Fallstricke

  • Immer mit null rechnen: Der Wert ist null, wenn der Fokus zu einem anderen Fenster oder Tab, in die Browser-Oberfläche oder auf ein nicht fokussierbares Element geht. menu.contains(null) gibt false zurück, der Zugriff auf null.tagName dagegen löst einen Fehler aus.
  • Safari/macOS: Ein Klick fokussiert <button>-Elemente und Links dort standardmäßig nicht, deshalb ist relatedTarget bei einem blur durch Klick oft null. Abhilfe: Solche Elemente mit tabindex="-1" oder tabindex="0" fokussierbar machen.
  • Bubbling: focus und blur steigen nicht im DOM auf. Für die Delegation an einen Container nimmt man focusin bzw. focusout.
  • Shadow DOM und iframes: Liegt das Element in einem Shadow DOM, wird relatedTarget wie target auf den Shadow-Host umgesetzt (Retargeting). Das eigentliche Element findet man bei offenem Shadow DOM über event.composedPath(). Über Dokumentgrenzen hinweg (iframes) wird das fremde Element aus Sicherheitsgründen nicht offengelegt.
  • Reihenfolge: Wenn blur/focusout ausgelöst wird, ist document.activeElement meist noch nicht das neue Element, oft ist es in diesem Moment body. relatedTarget ist deshalb die zuverlässigere Quelle.
  • Bei Maus-Ereignissen gibt es eine gleichnamige Eigenschaft MouseEvent.relatedTarget (für mouseover/mouseout) mit eigener Bedeutung.