<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.
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 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 die gleichen Aufzählungswerte.open
-
Ermöglicht den Zugang zum internen Shadow Root DOM für JavaScript (empfohlen für die meisten Anwendungsfälle).
closed
-
Verbirgt das interne 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, auf einen nicht erlaubten Wert gesetzt ist oder wenn bereits einShadowRoot
im selben übergeordneten Element deklarativ erstellt wurde, wird einHTMLTemplateElement
konstruiert. EinHTMLTemplateElement
kann nicht nachträglich in ein Shadow Root umgewandelt werden, z. B. durch Setzen vonHTMLTemplateElement.shadowRootMode
.Hinweis: Sie könnten das nicht standardisierte Attribut
shadowroot
in älteren Tutorials und Beispielen finden, die in Chrome 90-110 unterstützt wurden. Dieses Attribut wurde inzwischen entfernt und durch das standardisierte Attributshadowrootmode
ersetzt. shadowrootclonable
-
Setzt den Wert der
clonable
-Eigenschaft einesShadowRoot
, das mit diesem Element erstellt wurde, auftrue
. Wenn gesetzt, wird eine Kopie des Shadow Hosts (das übergeordnete Element dieses<template>
), die mitNode.cloneNode()
oderDocument.importNode()
erstellt wurde, ein Shadow Root in der Kopie enthalten. 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-Tree ausgewählt wird, wird der Fokus an das erste fokussierbare Element im Tree delegiert. Der Standardwert istfalse
. shadowrootserializable
Experimentell-
Setzt den Wert der
serializable
-Eigenschaft einesShadowRoot
, das mit diesem Element erstellt wurde, auftrue
. Wenn gesetzt, kann der Shadow Root durch Aufrufen der MethodenElement.getHTML()
oderShadowRoot.getHTML()
mit dem Parameteroptions.serializableShadowRoots
auftrue
serialisiert werden. Der Standardwert istfalse
.
Nutzungshinweise
Es gibt zwei Hauptmethoden, das <template>
-Element zu verwenden.
Template-Dokumentfragment
Standardmäßig wird der Inhalt des Elements nicht gerendert.
Das entsprechende HTMLTemplateElement
-Interface enthält eine Standard-content
-Eigenschaft (ohne ein entsprechendes Inhalts-/Markup-Attribut). Diese content
-Eigenschaft ist schreibgeschützt und hält ein DocumentFragment
, das den durch das Template dargestellten DOM-Teilbaum enthält.
Dieses Fragment kann über die Methode cloneNode
geklont und in das 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 lesen Sie den Abschnitt Vermeidung von DocumentFragment-Fallstricken 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 ein Shadow DOM. Das Element wird im DOM durch seinen Inhalt ersetzt, der in einem ShadowRoot
umwickelt ist, der an das übergeordnete Element angehängt wird.
Dies ist das deklarative Äquivalent, um Element.attachShadow()
aufzurufen und ein Shadow Root an ein Element anzuhängen.
Wenn das Element einen anderen Wert für shadowrootmode
hat oder das Attribut shadowrootmode
nicht hat, erstellt der Parser ein HTMLTemplateElement
.
Ebenso, wenn mehrere deklarative Shadow Roots vorhanden sind, wird nur das erste durch einen 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 mit 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 wurden, 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 originale HTML-Tabelle, mit zwei neuen Zeilen, die über JavaScript hinzugefügt wurden:
Implementieren eines deklarativen Shadow DOM
In diesem Beispiel wird eine versteckte Support-Warnung zu Beginn des Markups eingefügt. Diese Warnung wird später via JavaScript angezeigt, falls der Browser das Attribut shadowrootmode
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 das Shadow Root beschränkt, das an der Stelle des <template>
-Elements aufgrund 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 =
HTMLTemplateElement.prototype.hasOwnProperty("shadowRootMode");
document
.querySelector("p[hidden]")
.toggleAttribute("hidden", isShadowRootModeSupported);
Deklarativer Shadow DOM mit delegiertem Fokus
Dieses Beispiel zeigt, wie shadowrootdelegatesfocus
auf ein deklarativ erstelltes Shadow Root angewendet wird und welche Auswirkungen dies auf den Fokus hat.
Der Code deklariert zuerst einen Shadow Root innerhalb eines <div>
-Elements unter Verwendung des <template>
-Elements mit dem Attribut shadowrootmode
.
Dies zeigt sowohl ein nicht fokussierbares <div>
mit Text als auch ein fokussierbares <input>
-Element an.
Es verwendet auch CSS, um Elemente mit :focus
blau zu färben, und um das normale Styling des Host-Elements einzustellen.
<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, nur dass er das Attribut shadowrootdelegatesfocus
setzt, das den Fokus an das erste fokussierbare Element im Tree delegiert, wenn ein nicht fokussierbares Element im Tree 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 gelb-grünen Rand um das übergeordnete <div>
-Element zu legen, wenn es den Fokus hat.
div:focus {
border: 2px solid red;
}
Die Ergebnisse werden unten gezeigt.
Wenn das HTML zuerst gerendert wird, haben die Elemente kein Styling, wie im ersten Bild gezeigt.
Für das Shadow Root, das shadowrootdelegatesfocus
nicht gesetzt hat, 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 das Shadow Root mit gesetztem shadowrootdelegatesfocus
führt ein Klick auf den Text (der nicht fokussierbar ist) zur Auswahl des <input>
-Elements, da dies das erste fokussierbare Element im Tree ist.
Dies fokussiert auch das übergeordnete Element, wie unten gezeigt.
Vermeidung von DocumentFragment-Fallstricken
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
anzuhängen, 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);
Resultat
Da firstClone
ein DocumentFragment
ist, werden beim Aufruf von appendChild
nur seine Kinder zu container
hinzugefügt; die Ereignishandler von firstClone
werden nicht kopiert. Im Gegensatz dazu wird, da 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 | Metadata Content, Flow Content, Phrasing Content, script-supporting element |
---|---|
Erlaubte Inhalte | Keine Einschränkungen |
Tag-Auslassung | Keine, sowohl das Start- als auch das End-Tag sind obligatorisch. |
Erlaubte Eltern |
Jedes Element, das
Metadata Content,
Phrasing Content akzeptiert, oder
Script-supporting elements. Ebenfalls erlaubt als Kind eines <colgroup>
Elements, das keine
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 Standard # the-template-element |
Browser-Kompatibilität
BCD tables only load in the browser
Siehe auch
part
undexportparts
HTML Attribute<slot>
HTML Element:host
,:host()
, und:host-context()
CSS Pseudo-Klassen::part
und::slotted
CSS Pseudo-ElementeShadowRoot
Interface- Verwendung von Templates und Slots
- CSS Scoping Modul
- Deklarativer Shadow DOM (mit HTML) in Using Shadow DOM
- Deklarativer Shadow DOM auf web.dev (2023)