Signatur
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:targetverliert den Fokus,relatedTargetist das Element, das ihn bekommt.focus/focusin:targetbekommt den Fokus,relatedTargetist 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
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);
}
});
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)}`);
};
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);
// Wichtig · Fallstricke
- Immer mit
nullrechnen: Der Wert istnull, wenn der Fokus zu einem anderen Fenster oder Tab, in die Browser-Oberfläche oder auf ein nicht fokussierbares Element geht.menu.contains(null)gibtfalsezurück, der Zugriff aufnull.tagNamedagegen löst einen Fehler aus. - Safari/macOS: Ein Klick fokussiert
<button>-Elemente und Links dort standardmäßig nicht, deshalb istrelatedTargetbei einemblurdurch Klick oftnull. Abhilfe: Solche Elemente mittabindex="-1"odertabindex="0"fokussierbar machen. - Bubbling:
focusundblursteigen nicht im DOM auf. Für die Delegation an einen Container nimmt manfocusinbzw.focusout. - Shadow DOM und iframes: Liegt das Element in einem Shadow DOM, wird
relatedTargetwietargetauf den Shadow-Host umgesetzt (Retargeting). Das eigentliche Element findet man bei offenem Shadow DOM überevent.composedPath(). Über Dokumentgrenzen hinweg (iframes) wird das fremde Element aus Sicherheitsgründen nicht offengelegt. - Reihenfolge: Wenn
blur/focusoutausgelöst wird, istdocument.activeElementmeist noch nicht das neue Element, oft ist es in diesem Momentbody.relatedTargetist deshalb die zuverlässigere Quelle. - Bei Maus-Ereignissen gibt es eine gleichnamige Eigenschaft
MouseEvent.relatedTarget(fürmouseover/mouseout) mit eigener Bedeutung.