Signatur
Beschreibung
Die schreibgeschützte Eigenschaft document.activeElement gibt das Element zurück, das im Dokument gerade fokussiert ist, also Tastatureingaben erhält. Meist ist das ein Formularfeld wie <input>, <textarea> oder <select>, ein Link, ein Button oder ein Element mit tabindex bzw. contenteditable.
Ist kein Element fokussiert, liefert die Eigenschaft in der Regel document.body und in seltenen Fällen null, etwa wenn es kein <body> gibt. Steckt der Fokus in einem <iframe>, erhältst du das <iframe>-Element selbst. Das fokussierte Element darin findest du über iframe.contentDocument.activeElement, sofern die Same-Origin-Policy den Zugriff erlaubt.
Typische Einsatzfälle sind Barrierefreiheit und Fokusverwaltung: Vor dem Öffnen eines modalen Dialogs merkst du dir das aktive Element und setzt den Fokus nach dem Schließen wieder dorthin. Außerdem kannst du Tastenkürzel abschalten, solange der Nutzer in ein Textfeld tippt, oder einen Fokus-Zyklus („Focus Trap“) bauen.
Bei Web Components mit Shadow DOM zeigt document.activeElement nur auf das Host-Element. Das tatsächlich fokussierte Element im Schattenbaum liefert shadowRoot.activeElement.
Rückgabewert
document.body, in Ausnahmefällen null. Liegt der Fokus in einem Iframe oder einem Shadow Root, bekommst du das jeweilige <iframe>- bzw. Host-Element.Beispiele
Aktuell fokussiertes Element ausgeben
const input = document.createElement('input');
input.id = 'suche';
document.body.append(input);
input.focus();
console.log(document.activeElement === input); // true
console.log(document.activeElement.id);
input.blur();
console.log(document.activeElement === document.body);
Tastenkürzel nicht auslösen, während in ein Textfeld getippt wird
const istEingabefeld = (el) =>
el instanceof HTMLInputElement ||
el instanceof HTMLTextAreaElement ||
el instanceof HTMLSelectElement ||
el?.isContentEditable === true;
document.addEventListener('keydown', (event) => {
if (istEingabefeld(document.activeElement)) return;
if (event.key === '/') {
event.preventDefault();
document.querySelector('#suche')?.focus();
}
});
Fokus nach dem Schließen eines Dialogs wiederherstellen
let vorherFokussiert = null;
const dialog = document.querySelector('dialog');
const oeffneDialog = () => {
vorherFokussiert = document.activeElement;
dialog.showModal();
};
dialog.addEventListener('close', () => {
// Zurück zum auslösenden Element, falls es noch im DOM ist
if (vorherFokussiert instanceof HTMLElement && vorherFokussiert.isConnected) {
vorherFokussiert.focus();
}
});
document.querySelector('#oeffnen')?.addEventListener('click', oeffneDialog);
Fokussiertes Element im Shadow DOM ermitteln
const tiefstesAktivesElement = (root = document) => {
let el = root.activeElement;
while (el?.shadowRoot?.activeElement) {
el = el.shadowRoot.activeElement;
}
return el;
};
console.log(tiefstesAktivesElement());
// Wichtig · Fallstricke
- Schreibgeschützt: Eine Zuweisung an
document.activeElementbleibt wirkungslos. Den Fokus setzt du mitelement.focus()und entfernst ihn mitelement.blur(). - Nicht auf
nullverlassen: Ohne Fokus kommt meistdocument.bodyzurück, nichtnull. Prüfe beide Fälle. - Zeitpunkt bei Fokus-Events: Während
bluroderfocusoutläuft, zeigtactiveElementoft schon aufdocument.body. Das neue Ziel findest du inevent.relatedTarget. - Klicks auf Buttons: In Safari (macOS) bekommen Buttons und Links beim Mausklick standardmäßig keinen Fokus.
activeElementkann dann vom Erwarteten abweichen. - Iframes und Shadow DOM: Du erhältst nur das äußere
<iframe>- bzw. Host-Element. Bei Iframes von fremden Origins kommst du wegen der Same-Origin-Policy nicht an das innere Element. - Fenster ohne Fokus:
activeElementbehält seinen Wert, auch wenn das Browserfenster selbst nicht fokussiert ist. Ob das Dokument wirklich fokussiert ist, zeigtdocument.hasFocus(). - Die Eigenschaft wird von allen modernen Browsern unterstützt.
ShadowRoot.activeElementgibt es in allen aktuellen Browsern.