Signatur
Beschreibung
shadowRootDelegatesFocus spiegelt das boolesche HTML-Attribut shadowrootdelegatesfocus eines <template>-Elements wider. Das Attribut gehört zum deklarativen Shadow DOM: Hat ein <template> zusätzlich das Attribut shadowrootmode ("open" oder "closed"), erzeugt der HTML-Parser daraus direkt eine Shadow Root am Elternelement. Mit shadowrootdelegatesfocus wird diese Shadow Root so angelegt, als hätte man attachShadow({ mode, delegatesFocus: true }) aufgerufen.
Ist die Fokus-Delegation aktiv, gibt der Host den Fokus an das erste fokussierbare Element in seinem Shadow Tree weiter. Das passiert, wenn der Host angeklickt wird oder host.focus() aufgerufen wird. Außerdem trifft die CSS-Pseudoklasse :focus auf den Host zu, solange ein Element in seinem Shadow Tree den Fokus hat. Das ist praktisch für eigene Formular-Komponenten wie Eingabefelder oder Buttons, die sich wie native Steuerelemente verhalten sollen.
Mit der Eigenschaft liest oder setzt man nur das Attribut. Setzt man true, wird das Attribut (leer) gesetzt, bei false wird es entfernt. Eine Shadow Root entsteht dadurch nicht. Wirkung hat das Attribut nur, wenn das Markup über den HTML-Parser verarbeitet wird, also beim Laden der Seite, über Element.setHTMLUnsafe() oder Document.parseHTMLUnsafe().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value | boolean | false | Nur beim Setzen: true fügt das Attribut shadowrootdelegatesfocus hinzu, false entfernt es. |
Beispiele
Eigenschaft und Attribut synchron halten
const tpl = document.createElement('template');
console.log(tpl.shadowRootDelegatesFocus);
tpl.shadowRootDelegatesFocus = true;
console.log(tpl.hasAttribute('shadowrootdelegatesfocus'));
console.log(JSON.stringify(tpl.getAttribute('shadowrootdelegatesfocus')));
tpl.shadowRootDelegatesFocus = false;
console.log(tpl.hasAttribute('shadowrootdelegatesfocus'));
Deklarative Shadow Root mit Fokus-Delegation über setHTMLUnsafe()
const container = document.createElement('div');
document.body.append(container);
container.setHTMLUnsafe(`
<my-field>
<template shadowrootmode="open" shadowrootdelegatesfocus>
<label>Name <input id="name"></label>
</template>
</my-field>
`);
const host = container.querySelector('my-field');
console.log(host.shadowRoot.delegatesFocus);
// Der Fokus auf den Host landet im inneren <input>
host.focus();
console.log(host.shadowRoot.activeElement?.id);
Template programmatisch konfigurieren und als Markup einsetzen
const buildField = (label) => {
const tpl = document.createElement('template');
tpl.shadowRootMode = 'open';
tpl.shadowRootDelegatesFocus = true;
tpl.innerHTML = `<button>${label}</button>`;
return `<fancy-button>${tpl.outerHTML}</fancy-button>`;
};
const root = document.createElement('div');
root.setHTMLUnsafe(buildField('Speichern'));
document.body.append(root);
const host = root.querySelector('fancy-button');
console.log(host.shadowRoot.delegatesFocus);
// Wichtig · Fallstricke
- Nur der Parser wertet das Attribut aus: Setzt man die Eigenschaft an einem Template, das schon im DOM hängt, entsteht keine Shadow Root. Auch
innerHTMLverarbeitet deklaratives Shadow DOM nicht. Nutze stattdessensetHTMLUnsafe()oderDocument.parseHTMLUnsafe(). - Nach dem Parsen wird ein
<template shadowrootmode>entfernt und durch die Shadow Root ersetzt. Die Eigenschaft lässt sich danach nicht mehr am Template abfragen. Prüfe stattdessenhost.shadowRoot.delegatesFocus. - Ohne gültiges
shadowrootmodehatshadowrootdelegatesfocuskeine Wirkung. - Hat das Elternelement bereits eine Shadow Root, wird das deklarative Template ignoriert.
- Kompatibilität: Die Eigenschaft wird erst seit 2024 von allen großen Browsern unterstützt. Für ältere Browser sollte man eine Feature-Erkennung einbauen, z. B.
'shadowRootDelegatesFocus' in HTMLTemplateElement.prototype, und als AusweichlösungattachShadow({ mode: 'open', delegatesFocus: true })nutzen. - Sicherheit:
setHTMLUnsafe()bereinigt das Markup nicht. Nutzereingaben dürfen dort nicht unbereinigt eingefügt werden, sonst droht XSS.