<template>: Das Inhaltsvorlagenelement
Baseline Widely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since November 2015.
* Some parts of this feature may have varying levels of support.
Das <template>
HTML Element dient als Mechanismus zum Halten von HTML Fragmenten, die entweder später über JavaScript verwendet oder sofort in den Shadow-DOM generiert werden können.
Attribute
Dieses Element umfasst die globalen Attribute.
shadowrootmode
-
Erstellt einen Shadow-Root für das Elternelement. Es ist eine deklarative Version der Methode
Element.attachShadow()
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
-
Verbirgt 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 erlaubten Wert gesetzt ist. Wenn das Attribut nicht gesetzt ist, oder nicht auf einen erlaubten Wert gesetzt ist – oder wenn einShadowRoot
bereits deklarativ im selben Elternteil erstellt wurde –, dann wird einHTMLTemplateElement
konstruiert. EinHTMLTemplateElement
kann nach dem Parsen nicht in einen Shadow-Root geändert werden, zum Beispiel durch das Setzen vonHTMLTemplateElement.shadowRootMode
.Hinweis: Sie könnten das nicht-standardisierte Attribut
shadowroot
in älteren Tutorials und Beispielen finden, das in Chrome 90-110 unterstützt wurde. Dieses Attribut wurde inzwischen entfernt und durch das standardisierte Attributshadowrootmode
ersetzt. shadowrootclonable
-
Setzt den Wert der
clonable
Eigenschaft eines mittels dieses Elements erstelltenShadowRoot
auftrue
. Wenn gesetzt, wird ein Klon des Shadow-Hosts (des Elternelements dieses<template>
), das mitNode.cloneNode()
oderDocument.importNode()
erstellt wurde, einen Shadow-Root in der Kopie beinhalten. shadowrootdelegatesfocus
-
Setzt den Wert der
delegatesFocus
Eigenschaft eines mittels dieses Elements erstelltenShadowRoot
auftrue
. Wenn dies gesetzt ist und ein nicht-fokussierbares Element im Shadow-Baum ausgewählt wird, dann wird der Fokus an das erste fokussierbare Element im Baum delegiert. Der Wert ist standardmäßigfalse
. shadowrootserializable
Experimentell-
Setzt den Wert der
serializable
Eigenschaft eines mittels dieses Elements erstelltenShadowRoot
auftrue
. Wenn gesetzt, kann der Shadow-Root durch Aufrufen der MethodenElement.getHTML()
oderShadowRoot.getHTML()
mit dem Parameteroptions.serializableShadowRoots
, dertrue
gesetzt ist, serialisiert werden. Der Wert ist standardmäßigfalse
.
Nutzungshinweise
Es gibt zwei Hauptwege, das <template>
Element zu nutzen.
Dokumentfragment der Vorlage
Standardmäßig wird der Inhalt des Elements nicht gerendert.
Die entsprechende HTMLTemplateElement
-Schnittstelle umfasst eine Standard content
Eigenschaft (ohne gleichwertiges Content/Markup-Attribut). Diese content
-Eigenschaft ist schreibgeschützt und hält ein DocumentFragment
, das den vom Template dargestellten DOM-Teilbaum enthält.
Dieses Fragment kann über die Methode cloneNode
geklont und in den DOM eingefügt werden.
Seien Sie vorsichtig bei der Nutzung der content
-Eigenschaft, da das zurückgegebene DocumentFragment
unerwartetes Verhalten zeigen kann.
Für weitere Details siehe den Abschnitt Vermeidung von DocumentFragment-Fallen unten.
Deklarativer Shadow DOM
Wenn das <template>
Element das Attribut shadowrootmode
mit einem Wert von entweder open
oder closed
enthält, generiert der HTML Parser sofort einen Shadow DOM. Das Element wird im DOM durch seinen Inhalt ersetzt, der in einem ShadowRoot
gewickelt ist, welcher an das Elternelement angefügt wird.
Dies ist das deklarative Äquivalent zum Aufrufen von Element.attachShadow()
, um einen Shadow-Root an ein Element anzufügen.
Wenn das Element einen anderen Wert für shadowrootmode
hat oder das Attribut shadowrootmode
nicht vorhanden ist, erzeugt der Parser ein HTMLTemplateElement
.
Ebenso, wenn es mehrere deklarative Shadow-Roots gibt, wird nur der erste durch ein ShadowRoot
ersetzt — nachfolgende Instanzen werden als HTMLTemplateElement
-Objekte geparst.
Beispiele
Generieren von Tabellenzeilen
Zuerst beginnen 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 Inhalte durch JavaScript-Code einfügen werden. Dann folgt das Template, das die Struktur eines HTML-Fragments beschreibt, das eine einzelne Tabellenzeile darstellt.
Nachdem die Tabelle erstellt und das Template definiert ist, nutzen 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 = template.content.cloneNode(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 = template.content.cloneNode(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 eine versteckte Unterstützung-Warnung am Anfang des Markups enthalten. Diese Warnung wird später über JavaScript angezeigt, wenn der Browser das Attribut shadowrootmode
nicht unterstützt. Anschließend gibt es zwei <article>
-Elemente, die jeweils verschachtelte <style>
-Elemente mit unterschiedlichen Verhaltensweisen enthalten. Das erste <style>
-Element gilt global für das gesamte Dokument. Das zweite ist auf den Shadow-Root beschränkt, der anstelle des <template>
-Elements aufgrund des Vorhandenseins des Attributs shadowrootmode
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);
Deklarativer Shadow DOM mit delegiertem Fokus
Dieses Beispiel zeigt, wie shadowrootdelegatesfocus
auf einen deklarativ erstellten Shadow-Root angewendet wird und welche Auswirkungen dies auf den Fokus hat.
Der Code deklariert zuerst einen Shadow-Root innerhalb eines <div>
-Elements, indem das <template>
-Element mit dem shadowrootmode
-Attribut verwendet wird.
Dies zeigt sowohl ein nicht-fokussierbares <div>
, das Text enthält, als auch ein fokussierbares <input>
-Element an.
Es verwendet auch CSS, um Elemente mit :focus
blau zu stylen und das normale Styling des Host-Elements zu setzen.
<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 er das shadowrootdelegatesfocus
-Attribut setzt, welches den Fokus auf das erste fokussierbare Element im Baum delegiert, falls 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 ein rotes Border auf das Eltern-<div>
-Element anzuwenden, wenn es den Fokus hat.
div:focus {
border: 2px solid red;
}
Die Ergebnisse sind unten zu sehen.
Wenn das HTML zunächst gerendert wird, haben die Elemente kein Styling, wie im ersten Bild gezeigt.
Für den Shadow-Root, der nicht shadowrootdelegatesfocus
gesetzt hat, können Sie überall außer auf das <input>
klicken und der Fokus ändert sich nicht (wenn Sie das <input>
-Element auswählen, sieht es aus wie das zweite Bild).
Für den Shadow-Root mit gesetztem shadowrootdelegatesfocus
wählt ein Klick auf den Text (der nicht-fokussierbar ist) das <input>
-Element, da dies das erste fokussierbare Element im Baum ist.
Dies fokussiert auch das Elternelement, wie unten gezeigt.
Vermeidung von DocumentFragment-Fallen
Wenn ein DocumentFragment
-Wert übergeben wird, bewegen Node.appendChild
und ähnliche Methoden nur die Kindknoten dieses Werts in den Zielknoten. Daher ist es meist vorzuziehen, Ereignishandler an die Kinder eines DocumentFragment
anzuhängen, statt an das 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 = template.content.cloneNode(true);
firstClone.addEventListener("click", clickHandler);
container.appendChild(firstClone);
const secondClone = template.content.cloneNode(true);
secondClone.children[0].addEventListener("click", clickHandler);
container.appendChild(secondClone);
Ergebnis
Da firstClone
ein DocumentFragment
ist, werden beim Aufruf von appendChild
nur dessen Kinder zu container
hinzugefügt; die Ereignishandler von firstClone
werden nicht kopiert. Im Gegensatz dazu wird, weil ein Ereignishandler zum ersten Kindknoten von secondClone
hinzugefügt wird, der Ereignishandler beim Aufruf von appendChild
kopiert und ein Klick darauf funktioniert wie erwartet.
Technische Zusammenfassung
Inhaltskategorien | Metadaten-Inhalt, Flussinhalt, Phraseninhalt, skriptunterstützendes Element |
---|---|
Erlaubter Inhalt | Keine Einschränkungen |
Weglassen des Tags | Keine, sowohl das Start- als auch das End-Tag sind erforderlich. |
Erlaubte Eltern |
Jedes Element, das
Metadaten-Inhalt,
Phraseninhalt, oder
skriptunterstützende Elemente akzeptiert. Auch erlaubt als Kind eines <colgroup>
Elements, das kein span-Attribut hat.
|
Implizite ARIA-Rolle | Keine entsprechende Rolle |
Erlaubte ARIA-Rollen | Keine role erlaubt |
DOM-Schnittstelle | [`HTMLTemplateElement`](/de/docs/Web/API/HTMLTemplateElement) |
Spezifikationen
Specification |
---|
HTML # the-template-element |
Browser-Kompatibilität
Siehe auch
part
undexportparts
HTML-Attribute<slot>
HTML-Element:has-slotted
,:host
,:host()
, und:host-context()
CSS-Pseudoklassen::part
und::slotted
CSS-PseudoelementeShadowRoot
Schnittstelle- Verwendung von Templates und Slots
- CSS-Scoping Modul
- Deklarativer Shadow DOM (mit HTML) in Using Shadow DOM
- Deklarativer Shadow DOM auf web.dev (2023)