<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>
-Element in HTML 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 übergeordnete Element. Es ist eine deklarative Version der Methode
Element.attachShadow()
und akzeptiert dieselben 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. Ist das Attribut nicht gesetzt oder auf einen nicht erlaubten Wert gesetzt — oder wenn einShadowRoot
bereits deklarativ im selben Elternteil erstellt wurde — dann wird einHTMLTemplateElement
konstruiert. EinHTMLTemplateElement
kann nach dem Parsen nicht in einen Shadow-Root umgewandelt werden, zum Beispiel durch Setzen vonHTMLTemplateElement.shadowRootMode
.Hinweis: Sie können das nicht-standardmäßige
shadowroot
-Attribut in älteren Tutorials und Beispielen finden, die in Chrome 90-110 unterstützt wurden. Dieses Attribut wurde inzwischen entfernt und durch das Standard-Attributshadowrootmode
ersetzt. shadowrootclonable
-
Setzt den Wert der
clonable
-Eigenschaft einesShadowRoot
, das mit diesem Element erstellt wurde, auftrue
. Wenn gesetzt, wird bei einem Klon des Shadow-Hosts (dem übergeordneten Element dieses<template>
), das mitNode.cloneNode()
oderDocument.importNode()
erstellt wurde, ein Shadow-Root in die Kopie aufgenommen. shadowrootdelegatesfocus
-
Setzt den Wert der
delegatesFocus
-Eigenschaft einesShadowRoot
, das mit diesem Element erstellt wurde, auftrue
. Wenn dies gesetzt ist und ein nicht fokussierbares Element im Shadow-Baum ausgewählt wird, wird der Fokus an das erste fokussierbare Element im Baum delegiert. Der Wert ist standardmäßigfalse
. shadowrootserializable
Experimentell-
Setzt den Wert der
serializable
-Eigenschaft einesShadowRoot
, das mit diesem Element erstellt wurde, auftrue
. Wenn gesetzt, kann der Shadow-Root serialisiert werden, indem die MethodenElement.getHTML()
oderShadowRoot.getHTML()
mit dem Parameteroptions.serializableShadowRoots
auftrue
aufgerufen werden. Der Wert ist standardmäßigfalse
.
Verwendungshinweise
Es gibt zwei Hauptarten, das <template>
-Element zu verwenden.
Template-Dokumentfragment
Standardmäßig wird der Inhalt des Elements nicht gerendert.
Das entsprechende HTMLTemplateElement
-Interface umfasst eine standardmäßige content
-Eigenschaft (ohne ein entsprechendes Inhalts-/Markup-Attribut). Diese content
-Eigenschaft ist schreibgeschützt und enthält ein DocumentFragment
, das den vom Template repräsentierten DOM-Teilbaum enthält.
Dieses Fragment kann über die cloneNode
-Methode geklont und in den DOM eingefügt werden.
Seien Sie vorsichtig beim Verwenden der content
-Eigenschaft, da das zurückgegebene DocumentFragment
ein unerwartetes Verhalten zeigen kann.
Für weitere Details siehe den Abschnitt über das Vermeiden von DocumentFragment-Fallen unten.
Deklaratives Shadow-DOM
Wenn das <template>
-Element das Attribut shadowrootmode
mit einem Wert von entweder open
oder closed
enthält, erzeugt der HTML-Parser sofort einen Shadow-DOM. Das Element wird im DOM durch seinen Inhalt ersetzt, der in einem ShadowRoot
verpackt ist und an das übergeordnete Element angehängt wird.
Dies ist das deklarative Äquivalent dazu, Element.attachShadow()
aufzurufen, um einem Element einen Shadow-Root hinzuzufügen.
Wenn das Element einen anderen Wert für shadowrootmode
hat oder das shadowrootmode
-Attribut nicht vorhanden ist, generiert der Parser ein HTMLTemplateElement
.
Ähnlich gilt: Sind mehrere deklarative Shadow-Roots vorhanden, wird nur der erste ersetzt 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 Inhalte mittels JavaScript-Code einfügen werden. Dann folgt das Template, das die Struktur eines HTML-Fragments beschreibt, das eine einzelne Tabellenzeile darstellt.
Nun, da die Tabelle erstellt und das Template definiert ist, verwenden wir JavaScript, um Zeilen in die Tabelle einzufügen, wobei jede Zeile auf Basis 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, an die zwei neue Zeilen per JavaScript angehängt wurden:
Implementierung eines deklarativen Shadow-DOM
In diesem Beispiel werden zuerst eine versteckte Supportwarnung im Markup eingefügt. Diese Warnung wird später per JavaScript angezeigt, wenn der Browser das shadowrootmode
-Attribut nicht unterstützt. Danach gibt es zwei <article>
-Elemente, die 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 begrenzt, der anstelle des <template>
-Elements generiert wird, da das Attribut shadowrootmode
vorhanden ist.
<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 =
HTMLTemplateElement.prototype.hasOwnProperty("shadowRootMode");
document
.querySelector("p[hidden]")
.toggleAttribute("hidden", isShadowRootModeSupported);
Deklaratives Shadow-DOM mit delegiertem Fokus
Dieses Beispiel zeigt, wie shadowrootdelegatesfocus
auf einen Shadow-Root angewendet wird, der deklarativ erzeugt wird, und welcher Effekt dies auf den Fokus hat.
Der Code erklärt zuerst einen Shadow-Root innerhalb eines <div>
-Elements, mit Hilfe des <template>
-Elements mit dem Attribut shadowrootmode
.
Dies zeigt sowohl ein nicht fokussierbares <div>
mit Text als auch ein fokussierbares <input>
-Element.
Es verwendet auch CSS, um Elemente mit :focus
blau zu stylen, und um das normale Styling des Host-Elements zu setzten.
<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, 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 einen roten Rahmen auf das übergeordnete <div>
-Element anzuwenden, wenn es den Fokus hat.
div:focus {
border: 2px solid red;
}
Die Ergebnisse sind unten dargestellt.
Wenn das HTML zuerst gerendert wird, haben die Elemente kein Styling, wie im ersten Bild gezeigt.
Bei dem Shadow-Root, bei dem shadowrootdelegatesfocus
nicht gesetzt ist, können Sie überall klicken außer auf das <input>
, und der Fokus ändert sich nicht (wenn Sie das <input>
-Element auswählen, sieht es aus wie im zweiten Bild).
Beim Shadow-Root mit gesetztem shadowrootdelegatesfocus
wird durch Klicken auf den Text (das nicht fokussierbar ist) das <input>
-Element ausgewählt, da dies das erste fokussierbare Element im Baum ist.
Dies setzt auch den Fokus auf das übergeordnete Element, wie unten gezeigt.
Vermeidung von DocumentFragment-Fallen
Wenn ein DocumentFragment
-Wert übergeben wird, verschieben Node.appendChild
und ähnliche Methoden nur die Kind-Knoten dieses Werts in den Zielknoten. Daher ist es in der Regel vorzuziehen, Ereignishandler an die Kinder eines DocumentFragment
anzuschließen, anstatt 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 dem container
hinzugefügt; die Ereignishandler von firstClone
werden nicht kopiert. Im Gegensatz dazu wird, weil ein Ereignishandler dem ersten Kind-Knoten von secondClone
hinzugefügt wurde, der Ereignishandler beim Aufruf von appendChild
kopiert und durch Klicken darauf funktioniert er wie erwartet.
Technische Zusammenfassung
Inhaltskategorien | Metadateninhalt, Flussinhalt, Phraseninhalt, skriptunterstützendes Element |
---|---|
Erlaubter Inhalt | Keine Einschränkungen |
Tag-Auslassung | Keine, sowohl das Start- als auch das End-Tag sind obligatorisch. |
Erlaubte Eltern |
Jedes Element, das
Metadateninhalt,
Phraseninhalt oder
skriptunterstützende Elemente akzeptiert. Auch erlaubt als Kind eines <colgroup>
Elements, das nicht das
span -Attribut hat.
|
Implizite ARIA-Rolle | Keine entsprechende Rolle |
Erlaubte ARIA-Rollen | Keine role erlaubt |
DOM-Interface | [`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
Interface- Verwendung von Vorlagen und Slots
- CSS-Scoping Modul
- Deklarativer Shadow-DOM (mit HTML) in Verwendung von Shadow-DOM
- Deklarativer Shadow-DOM auf web.dev (2023)