<template> HTML-Inhalt-Template-Element
Baseline
Weitgehend verfügbar
*
Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit November 2015 browserübergreifend verfügbar.
* Einige Teile dieser Funktion werden möglicherweise unterschiedlich gut unterstützt.
Das <template>-HTML-Element dient als Mechanismus zum Halten von HTML-Fragmenten, die entweder später über JavaScript verwendet oder sofort in Shadow DOM generiert werden können.
Attribute
Dieses Element enthält die globalen Attribute.
shadowrootmode-
Erstellt einen Shadow Root für das übergeordnete Element. Es ist eine deklarative Version der
Element.attachShadow()-Methode und akzeptiert die gleichen aufgezählten Werte.open-
Macht den internen Shadow Root DOM für JavaScript zugänglich (empfohlen für die meisten Anwendungsfälle).
closed-
Versteckt den internen Shadow Root DOM vor JavaScript.
Hinweis: Der HTML-Parser erstellt ein
ShadowRoot-Objekt im DOM für das erste<template>in einem Knoten mit diesem Attribut, das auf einen zulässigen Wert gesetzt ist. Wenn das Attribut nicht gesetzt oder nicht auf einen zulässigen Wert gesetzt ist — oder wenn einShadowRootbereits deklarativ im selben Elternteil erstellt wurde — dann wird einHTMLTemplateElementkonstruiert. EinHTMLTemplateElementkann nach dem Parsen nicht nachträglich in einen Shadow Root umgewandelt werden, zum Beispiel durch Setzen vonHTMLTemplateElement.shadowRootMode.Hinweis: Sie finden möglicherweise das nicht standardisierte Attribut
shadowrootin älteren Tutorials und Beispielen, die in Chrome 90-110 unterstützt wurden. Dieses Attribut wurde inzwischen entfernt und durch das standardisierte Attributshadowrootmodeersetzt. shadowrootclonable-
Setzt den Wert der
clonable-Eigenschaft eines mit diesem Element erstelltenShadowRootauftrue. Wenn gesetzt, enthält ein mitNode.cloneNode()oderDocument.importNode()erstellter Klon des Shadow Hosts (des übergeordneten Elements dieses<template>) einen Shadow Root in der Kopie. shadowrootcustomelementregistry-
Setzt die
customElementRegistry-Eigenschaft eines mit diesem Element erstelltenShadowRootaufnull, anstatt auf das Custom Element Registry des Dokuments. Dies ermöglicht es, später ein begrenztesCustomElementRegistryanzuhängen, indemCustomElementRegistry.initialize()aufgerufen wird. shadowrootdelegatesfocus-
Setzt den Wert der
delegatesFocus-Eigenschaft eines mittels dieses Elements erstelltenShadowRootauftrue. Ist dies gesetzt und ein nicht-fokussierbares Element im Shadow-Baum wird ausgewählt, wird der Fokus an das erste fokussierbare Element im Baum delegiert. Der Standardwert istfalse. shadowrootreferencetarget-
Setzt den Wert der
referenceTarget-Eigenschaft eines mittels dieses Elements erstelltenShadowRoot. Der Wert sollte die ID eines Elements innerhalb des Shadow DOM sein. Wenn gesetzt, führt eine Zielreferenz zum Hostelement von außerhalb des Shadow DOM dazu, dass das referenzierte Zielobjekt das tatsächliche Ziel der Referenz zum Hostelement wird. shadowrootserializable-
Setzt den Wert der
serializable-Eigenschaft eines mittels dieses Elements erstelltenShadowRootauftrue. Wenn gesetzt, kann der Shadow Root durch Aufrufen der MethodenElement.getHTML()oderShadowRoot.getHTML()mit dem Parameteroptions.serializableShadowRootsauftrueserialisiert werden. Der Standardwert istfalse.
Hinweise zur Verwendung
Dieses Element hat keinen zulässigen Inhalt, da alles, was im HTML-Quelltext darin verschachtelt ist, nicht tatsächlich zu den Kindern des <template>-Elements wird. Die Node.childNodes-Eigenschaft des <template>-Elements ist immer leer, und Sie können auf den verschachtelten Inhalt nur über die spezielle content-Eigenschaft zugreifen. Wenn Sie jedoch Node.appendChild() oder ähnliche Methoden auf das <template>-Element anwenden, fügen Sie Kinder in das <template>-Element selbst ein, was gegen sein Inhaltsmodell verstößt und das durch die content-Eigenschaft zurückgegebene DocumentFragment nicht tatsächlich aktualisiert.
Aufgrund der Art und Weise, wie das <template>-Element geparst wird, sind alle <html>, <head> und <body> Öffnungs- und Schließtags im Template Syntaxfehler und werden vom Parser ignoriert. So ist <template><head><title>Test</title></head></template> dasselbe wie <template><title>Test</title></template>.
Es gibt zwei Hauptmethoden, um das <template>-Element zu verwenden.
Template-Dokumentfragment
Standardmäßig wird der Inhalt des Elements nicht gerendert. Die entsprechende HTMLTemplateElement-Schnittstelle enthält eine Standard-[content](/de/docs/Web/API/HTMLTemplateElement/content)-Eigenschaft (ohne ein gleichwertiges Inhalts-/Markup-Attribut). Diese content-Eigenschaft ist schreibgeschützt und enthält ein DocumentFragment, das den vom Template dargestellten DOM-Unterbaum enthält.
Die Methoden Node.cloneNode() und Document.importNode() erstellen beide eine Kopie eines Knotens. Der Unterschied besteht darin, dass importNode() den Knoten im Kontext des aufrufenden Dokuments klont, während cloneNode() das Dokument des geklonten Knotens verwendet. Der Dokumentkontext bestimmt das CustomElementRegistry für die Konstruktion von benutzerdefinierten Elementen. Aus diesem Grund sollten Sie document.importNode() verwenden, um das content-Fragment zu klonen, damit benutzerdefinierte Elementnachkommen mit den Definitionen im aktuellen Dokument und nicht im separaten Dokument, das den Template-Inhalt besitzt, konstruiert werden. Weitere Details finden Sie auf der Seite Node.cloneNode().
Beachten Sie, dass dem DocumentFragment-Container selbst keine Daten angehängt werden sollten. Siehe das Beispiel Daten auf dem DocumentFragment werden nicht geklont für weitere Details.
Deklaratives Shadow DOM
Wenn das <template>-Element das shadowrootmode-Attribut mit einem Wert von entweder open oder closed enthält, wird durch den HTML-Parser sofort ein Shadow DOM generiert. Das Element wird im DOM durch seinen Inhalt ersetzt, der in einem ShadowRoot umschlossen ist, der an das übergeordnete Element angehängt wird. Dies ist das deklarative Äquivalent zum Aufruf von Element.attachShadow(), um einen Shadow Root an ein Element anzuhängen.
Wenn das Element einen anderen Wert für shadowrootmode hat oder nicht über das shadowrootmode-Attribut verfügt, generiert der Parser ein HTMLTemplateElement. In ähnlicher Weise ersetzt nur der erste eine deklarative Shadow Roots durch einen ShadowRoot — nachfolgende Instanzen werden als HTMLTemplateElement-Objekte geparst.
Beispiele
>Erzeugen von Tabellenzeilen
Zuerst starten wir mit dem HTML-Teil des Beispiels.
<table id="producttable">
<thead>
<tr>
<td>UPC_Code</td>
<td>Product_Name</td>
</tr>
</thead>
<tbody>
<!-- existing data could optionally be included here -->
</tbody>
</table>
<template id="productrow">
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
Zuerst haben wir eine Tabelle, in die wir später mithilfe von JavaScript-Inhalt einfügen werden. Dann kommt das Template, das die Struktur eines HTML-Fragments beschreibt, das eine einzelne Tabellenzeile darstellt.
Nun, da die Tabelle erstellt und das Template definiert wurde, verwenden wir JavaScript, um Zeilen in die Tabelle einzufügen, wobei jede Zeile mit dem Template als Basis konstruiert wird.
// Test to see if the browser supports the HTML template element by checking
// for the presence of the template element's content attribute.
if ("content" in document.createElement("template")) {
// Instantiate the table with the existing HTML tbody
// and the row with the template
const tbody = document.querySelector("tbody");
const template = document.querySelector("#productrow");
// Clone the new row and insert it into the table
const clone = document.importNode(template.content, true);
let td = clone.querySelectorAll("td");
td[0].textContent = "1235646565";
td[1].textContent = "Stuff";
tbody.appendChild(clone);
// Clone the new row and insert it into the table
const clone2 = document.importNode(template.content, true);
td = clone2.querySelectorAll("td");
td[0].textContent = "0384928528";
td[1].textContent = "Acme Kidney Beans 2";
tbody.appendChild(clone2);
} else {
// Find another way to add the rows to the table because
// the HTML template element is not supported.
}
Das Ergebnis ist die ursprüngliche HTML-Tabelle, der zwei neue Zeilen über JavaScript hinzugefügt wurden:
Implementierung eines deklarativen Shadow DOM
In diesem Beispiel ist zu Beginn des Markups eine versteckte Warnung enthalten. Diese Warnung wird später per JavaScript angezeigt, wenn der Browser das shadowrootmode-Attribut nicht unterstützt. Als nächstes gibt es zwei <article>-Elemente, die jeweils verschachtelte <style>-Elemente mit unterschiedlichen Verhaltensweisen enthalten. Das erste <style>-Element ist global für das gesamte Dokument. Das zweite ist auf den Shadow Root beschränkt, der anstelle des <template>-Elements aufgrund des Vorhandenseins des shadowrootmode-Attributs generiert wird.
<p hidden>
⛔ Your browser doesn't support <code>shadowrootmode</code> attribute yet.
</p>
<article>
<style>
p {
padding: 8px;
background-color: wheat;
}
</style>
<p>I'm in the DOM.</p>
</article>
<article>
<template shadowrootmode="open">
<style>
p {
padding: 8px;
background-color: plum;
}
</style>
<p>I'm in the shadow DOM.</p>
</template>
</article>
const isShadowRootModeSupported = Object.hasOwn(
HTMLTemplateElement.prototype,
"shadowRootMode",
);
document
.querySelector("p[hidden]")
.toggleAttribute("hidden", isShadowRootModeSupported);
Deklaratives Shadow DOM mit delegiertem Fokus
Dieses Beispiel demonstriert, wie shadowrootdelegatesfocus auf einen deklarativ erstellten Shadow Root angewendet wird und welche Auswirkung dies auf den Fokus hat.
Der Code deklariert zuerst einen Shadow Root innerhalb eines <div>-Elements unter Verwendung des <template>-Elements mit dem shadowrootmode-Attribut. Dies zeigt sowohl ein nicht-fokussierbares <div> mit Text als auch ein fokussierbares <input>-Element an. Es verwendet auch CSS, um Elemente mit :focus auf blau zu stylen und um das normale Styling des Hostelements festzulegen.
<div>
<template shadowrootmode="open">
<style>
:host {
display: block;
border: 1px dotted black;
padding: 10px;
margin: 10px;
}
:focus {
outline: 2px solid blue;
}
</style>
<div>Clickable Shadow DOM text</div>
<input type="text" placeholder="Input inside Shadow DOM" />
</template>
</div>
Der zweite Codeblock ist identisch, außer dass das Attribut shadowrootdelegatesfocus gesetzt ist, welches den Fokus auf das erste fokussierbare Element im Baum delegiert, wenn ein nicht-fokussierbares Element im Baum ausgewählt wird.
<div>
<template shadowrootmode="open" shadowrootdelegatesfocus>
<style>
:host {
display: block;
border: 1px dotted black;
padding: 10px;
margin: 10px;
}
:focus {
outline: 2px solid blue;
}
</style>
<div>Clickable Shadow DOM text</div>
<input type="text" placeholder="Input inside Shadow DOM" />
</template>
</div>
Zuletzt verwenden wir das folgende CSS, um einem fokussierten <div>-Elternelement einen roten Rahmen zu verleihen.
div:focus {
border: 2px solid red;
}
Die Ergebnisse sind unten zu sehen. Wenn das HTML zuerst gerendert wird, haben die Elemente keine Formatierung, wie im ersten Bild gezeigt. Für den Shadow Root ohne shadowrootdelegatesfocus können Sie überall außer dem <input> klicken und der Fokus ändert sich nicht (wenn Sie das <input>-Element auswählen, sieht es aus wie im zweiten Bild).

Für den Shadow Root mit shadowrootdelegatesfocus wird durch Klicken auf den Text (der nicht fokussierbar ist) das <input>-Element ausgewählt, da dies das erste fokussierbare Element im Baum ist. Dies fokussiert auch das Elternelement, wie unten gezeigt.

Daten auf dem DocumentFragment werden nicht geklont
Wenn ein DocumentFragment-Wert übergeben wird, verschieben Node.appendChild und ähnliche Methoden nur die Kindknoten dieses Wertes in den Zielknoten. Daher ist es normalerweise vorzuziehen, Ereignishandler an den Kindern eines DocumentFragment anzubringen, anstatt am DocumentFragment selbst.
Betrachten Sie das folgende HTML und JavaScript:
HTML
<div id="container"></div>
<template id="template">
<div>Click me</div>
</template>
JavaScript
const container = document.getElementById("container");
const template = document.getElementById("template");
function clickHandler(event) {
event.target.append(" — Clicked this div");
}
const firstClone = document.importNode(template.content, true);
firstClone.addEventListener("click", clickHandler);
container.appendChild(firstClone);
const secondClone = document.importNode(template.content, true);
secondClone.children[0].addEventListener("click", clickHandler);
container.appendChild(secondClone);
Ergebnis
Da firstClone ein DocumentFragment ist, werden bei appendChild nur die Kinder zu container hinzugefügt; die Ereignishandler von firstClone werden nicht kopiert. Im Gegensatz dazu wird, weil einem ersten Kindknoten von secondClone ein Ereignishandler hinzugefügt wird, der Ereignishandler bei appendChild kopiert und das Klicken darauf funktioniert, wie man erwarten würde.
Technische Zusammenfassung
| Inhaltskategorien | Metadaten-Inhalt, Flussinhalt, Phraseninhalt, script-supportendes Element |
|---|---|
| Zulässiger Inhalt | Keine (siehe Hinweise zur Verwendung) |
| Tag-Auslassung | Keine, sowohl der Start- als auch der End-Tag sind obligatorisch. |
| Erlaubte Eltern |
Jedes Element, das
Metadaten-Inhalt,
Phraseninhalt, oder
script-supportende Elemente akzeptiert. Auch als Kind eines <colgroup>
Elements erlaubt, das kein
span Attribut hat.
|
| Implizite ARIA-Rolle | Keine entsprechende Rolle |
| Zulässige ARIA-Rollen | Keine role erlaubt |
| DOM-Schnittstelle | [`HTMLTemplateElement`](/de/docs/Web/API/HTMLTemplateElement) |
Spezifikationen
| Spezifikation |
|---|
| HTML> # the-template-element> |
Browser-Kompatibilität
Siehe auch
partundexportpartsHTML-Attribute<slot>HTML-Element:has-slotted,:host,:host(), und:host-context()CSS-Pseudoklassen::partund::slottedCSS-PseudoelementeShadowRootSchnittstelle- Verwendung von Templates und Slots
- CSS Scoping-Modul
- Deklaratives Shadow DOM (mit html) in Verwendung von Shadow DOM
- Deklaratives Shadow DOM auf web.dev (2023)