<template>: Das Content Template-Element
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 Speichern 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 enumerierten 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, wenn dieses Attribut auf einen erlaubten Wert gesetzt ist. Wenn das Attribut nicht gesetzt oder nicht auf einen erlaubten Wert gesetzt ist — oder wenn bereits einShadowRoot
deklarativ im selben Elternteil erstellt wurde — dann wird einHTMLTemplateElement
konstruiert. EinHTMLTemplateElement
kann nach dem Parsen nicht nachträglich in einen Shadow-Root umgewandelt werden, z.B. durch Setzen vonHTMLTemplateElement.shadowRootMode
.Hinweis: In älteren Tutorials und Beispielen, die einst in Chrome 90-110 unterstützt wurden, finden Sie möglicherweise das nicht-standardisierte
shadowroot
-Attribut. Dieses Attribut wurde entfernt und durch das standardmäßigeshadowrootmode
-Attribut ersetzt. shadowrootclonable
-
Setzt den Wert der
clonable
-Eigenschaft eines mit diesem Element erstelltenShadowRoot
auftrue
. Wenn gesetzt, wird ein Klon des Shadow-Hosts (dem Elternelement dieses<template>
), erstellt mitNode.cloneNode()
oderDocument.importNode()
, ein Shadow-Root in die Kopie einfügen. shadowrootdelegatesfocus
-
Setzt den Wert der
delegatesFocus
-Eigenschaft eines mit diesem Element erstelltenShadowRoot
auftrue
. Falls gesetzt und ein nicht-fokussierbares Element im Shadow-Tree ausgewählt ist, 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 mit diesem Element erstelltenShadowRoot
auftrue
. Wenn gesetzt, kann der Shadow-Root durch Aufruf der MethodenElement.getHTML()
oderShadowRoot.getHTML()
mit dem Parameteroptions.serializableShadowRoots
auftrue
serialisiert werden. Der Wert ist standardmäßigfalse
.
Hinweise zur Nutzung
Es gibt zwei Hauptwege, das <template>
-Element zu verwenden.
Template-Dokumentfragment
Standardmäßig wird der Inhalt des Elements nicht gerendert.
Das entsprechende HTMLTemplateElement
-Interface enthält eine standardmäßige content
-Eigenschaft (ohne ein entsprechendes Inhalts-/Markup-Attribut). Diese content
-Eigenschaft ist schreibgeschützt und hält ein DocumentFragment
, das den DOM-Teilbaum enthält, der durch das Template dargestellt wird.
Dieses Fragment kann über die Methode cloneNode
geklont und in den DOM eingesetzt werden.
Seien Sie vorsichtig bei der Verwendung der content
-Eigenschaft, da das zurückgegebene DocumentFragment
unerwartetes Verhalten zeigen kann.
Weitere Details finden Sie im 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, wird der Shadow-DOM sofort durch den HTML-Parser generiert. Das Element wird im DOM durch seinen Inhalt ersetzt, der in einen ShadowRoot
gewickelt ist und an das Elternelement angehängt wird.
Dies ist das deklarative Äquivalent zum Aufruf von Element.attachShadow()
, um ein Shadow-Root an ein Element anzuhängen.
Wenn das Element einen anderen Wert für shadowrootmode
hat oder das Attribut shadowrootmode
nicht hat, generiert der Parser ein HTMLTemplateElement
.
Ebenso gilt, wenn mehrere deklarative Shadow-Roots vorhanden sind, wird nur der erste durch ein ShadowRoot
ersetzt — nachfolgende Instanzen werden als HTMLTemplateElement
-Objekte geparst.
Beispiele
Generierung 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 mit JavaScript-Code einfügen. Dann kommt das Template, das die Struktur eines HTML-Fragments beschreibt, das eine einzelne Tabellenzeile darstellt.
Nachdem die Tabelle erstellt und das Template definiert wurde, verwenden wir JavaScript, um Zeilen in die Tabelle einzufügen, wobei jede Zeile anhand des Templates 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, mit zwei neuen Zeilen, die über JavaScript hinzugefügt wurden:
Implementierung eines deklarativen Shadow DOM
In diesem Beispiel ist eine versteckte Support-Warnung zu Beginn des Markups enthalten. Diese Warnung wird später über JavaScript angezeigt, wenn der Browser das shadowrootmode
-Attribut nicht unterstützt. Danach 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 welchen Einfluss dies auf den Fokus hat.
Der Code erklärt zuerst einen Shadow-Root innerhalb eines <div>
-Elements, indem das <template>
-Element mit dem Attribut shadowrootmode
verwendet wird.
Dies zeigt sowohl ein nicht-fokussierbares <div>
-Element, das Text enthält, als auch ein fokussierbares <input>
-Element.
Es wird auch CSS verwendet, um Elemente mit :focus
blau zu gestalten und die normale Gestaltung des Host-Elements 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 er das Attribut shadowrootdelegatesfocus
setzt, das den Fokus an 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 dem Elternelement <div>
einen roten Rahmen zu geben, wenn es im Fokus ist.
div:focus {
border: 2px solid red;
}
Die Ergebnisse sind unten gezeigt.
Wenn das HTML zuerst gerendert wird, haben die Elemente keine Stilierung, wie im ersten Bild gezeigt.
Für den Shadow-Root, der nicht shadowrootdelegatesfocus
gesetzt hat, können Sie überall außer auf das <input>
-Element klicken und der Fokus ändert sich nicht (wenn Sie das <input>
-Element auswählen, sieht es wie im zweiten Bild aus).
Für den Shadow-Root mit gesetztem 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.
Vermeidung von DocumentFragment-Fallen
Wenn ein DocumentFragment
-Wert übergeben wird, verschieben Node.appendChild
und ähnliche Methoden nur die Kindknoten dieses Wertes in den Zielknoten. Daher ist es üblicher vorzuziehen, Ereignishandler an die Kinder von einem 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 nur dessen Kinder zu container
hinzugefügt, wenn appendChild
aufgerufen wird; die Ereignishandler von firstClone
werden nicht kopiert. Im Gegensatz dazu wird, weil ein Ereignishandler zu dem ersten Kindknoten von secondClone
hinzugefügt wird, der Ereignishandler kopiert, wenn appendChild
aufgerufen wird, und das Klicken darauf funktioniert wie erwartet.
Technische Zusammenfassung
Inhaltskategorien | Metadaten-Inhalt, Fluss-Inhalt, Phrasen-Inhalt, skriptunterstützendes Element |
---|---|
Erlaubter Inhalt | Keine Einschränkungen |
Tag-Ommission | Keine, sowohl der Start- als auch der End-Tag sind obligatorisch. |
Erlaubte Eltern |
Jedes Element, das
Metadaten-Inhalt,
Phrasen-Inhalt, oder
skriptunterstützende Elemente akzeptiert. Auch als Kind eines <colgroup> -Elements erlaubt, 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()
, and: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)