Signatur
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
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'}`);
});
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');
}
});
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
// Wichtig · Fallstricke
- Bubbling:
focusoutsteigt auf,blurnicht. Für Delegation alsofocusoutverwenden oderblurin der Capture-Phase abfangen. - Reihenfolge: In modernen Browsern gilt:
blur→focusout→focus→focusin. Ältere Browser (alte Edge- und IE-Versionen) wichen davon teils ab. relatedTargetist oftnull, 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, ruftfocus()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)
focusoutaus, andere nicht. Verlasse dich nicht darauf. onfocusoutals Eigenschaft bzw. HTML-Attribut fehlte in Firefox lange.addEventListenerist die sichere Wahl.- Im Shadow DOM wird
targetauf den Host umgeleitet (retargeting). Das eigentliche Element liefertevent.composedPath()[0].