<template>: Das Inhaltstemplate-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 zur Speicherung von HTML-Fragmenten, die entweder später über JavaScript verwendet oder sofort im Shadow DOM generiert werden können.
Attribute
Dieses Element enthält 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 das interne Shadow Root DOM für JavaScript zugänglich (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 zulässigen Wert gesetzt ist. Wenn das Attribut nicht gesetzt ist, nicht auf einen zulässigen Wert gesetzt ist — oder wenn bereits einShadowRoot
im selben Elternelement deklarativ erstellt wurde — wird einHTMLTemplateElement
konstruiert. EinHTMLTemplateElement
kann nach dem Parsen nicht mehr in ein Shadow Root umgewandelt werden, zum Beispiel durch Setzen vonHTMLTemplateElement.shadowRootMode
.Hinweis: Sie könnten auf das nicht standardmäßige Attribut
shadowroot
in älteren Tutorials und Beispielen stoßen, das in Chrome 90-110 unterstützt wurde. Dieses Attribut wurde inzwischen entfernt und durch das standardmäßige Attributshadowrootmode
ersetzt. shadowrootclonable
-
Setzt den Wert der
clonable
-Eigenschaft eines mit diesem Element erstelltenShadowRoot
auftrue
. Wenn gesetzt, enthält eine mitNode.cloneNode()
oderDocument.importNode()
erstellte Kopie des Shadow-Hosts (das Elternelement dieses<template>
) ein Shadow Root in der Kopie. shadowrootdelegatesfocus
-
Setzt den Wert der
delegatesFocus
-Eigenschaft eines mit diesem Element erstelltenShadowRoot
auftrue
. Wenn dies gesetzt ist und ein nicht fokussierbares Element im Shadow-Baum ausgewählt wird, wird der Fokus auf das erste fokussierbare Element im Baum delegiert. Der Standardwert istfalse
. shadowrootserializable
-
Setzt den Wert der
serializable
-Eigenschaft eines mit diesem Element erstelltenShadowRoot
auftrue
. Wenn gesetzt, kann das Shadow Root durch Aufrufen der MethodenElement.getHTML()
oderShadowRoot.getHTML()
mit dem Parameteroptions.serializableShadowRoots
auftrue
serialisiert werden. Der Standardwert istfalse
.
Anwendungshinweise
Dieses Element hat keinen erlaubten Inhalt, da alles, was im HTML-Quellcode 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 den verschachtelten Inhalt nur über die spezielle content
-Eigenschaft zugreifen. Wenn Sie jedoch Node.appendChild()
oder ähnliche Methoden für das <template>
-Element aufrufen, würden Sie Kinder in das <template>
-Element selbst einfügen, was gegen sein Inhaltsmodell verstößt und das von der content
-Eigenschaft zurückgegebene DocumentFragment
nicht tatsächlich aktualisiert.
Aufgrund der Art und Weise, wie das <template>
-Element analysiert wird, sind alle innerhalb des Templates enthaltenen offenen und schließenden <html>
, <head>
und <body>
-Tags Syntaxfehler und werden vom Parser ignoriert, sodass <template><head><title>Test</title></head></template>
dasselbe ist wie <template><title>Test</title></template>
.
Es gibt zwei Hauptmethoden, um das <template>
-Element zu verwenden.
Template-Dokumentenfragment
Standardmäßig wird der Inhalt des Elements nicht gerendert. Die entsprechende HTMLTemplateElement
-Schnittstelle umfasst eine Standard-content
-Eigenschaft (ohne ein entsprechendes Inhalts-/Markup-Attribut). Diese content
-Eigenschaft ist schreibgeschützt und hält ein DocumentFragment
, das den vom Template repräsentierten DOM-Teilbaum enthält. Dieses Fragment kann über die cloneNode
-Methode geklont und in das DOM eingefügt 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 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, wird sofort ein Shadow DOM vom HTML-Parser generiert. Das Element wird im DOM durch seinen Inhalt ersetzt, der in einem ShadowRoot
verpackt ist, das an das Elternelement angehängt ist. Dies ist das deklarative Äquivalent zum Aufrufen von Element.attachShadow()
, um ein Shadow Root an ein Element anzuhängen.
Wenn das Element einen anderen Wert für shadowrootmode
hat oder nicht das Attribut shadowrootmode
hat, erzeugt der Parser ein HTMLTemplateElement
. Ähnlich verhält es sich, wenn es mehrere deklarative Shadow Roots gibt: Nur das erste wird durch ein ShadowRoot
ersetzt — nachfolgende Instanzen werden als HTMLTemplateElement
-Objekte analysiert.
Beispiele
>Erzeugen von Tabelleneinträgen
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 auf Basis des Templates erstellt 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 hinzugefügten Zeilen, die über JavaScript angehängt wurden:
Implementieren eines deklarativen Shadow DOM
In diesem Beispiel ist zu Beginn des Markups eine versteckte Unterstützungsmeldung enthalten. Diese Warnung wird später über JavaScript angezeigt, wenn 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 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);
Deklaratives Shadow DOM mit delegiertem Fokus
Dieses Beispiel zeigt, wie shadowrootdelegatesfocus
auf ein Shadow Root angewendet wird, das deklarativ erstellt wird, und welche Auswirkungen dies auf den Fokus hat.
Der Code deklariert zunächst ein Shadow Root in einem <div>
-Element, indem das <template>
-Element mit dem Attribut shadowrootmode
verwendet wird. Dies zeigt sowohl ein nicht fokussierbares <div>
mit Text als auch ein fokussierbares <input>
-Element an. Es verwendet außerdem CSS, um Elemente mit :focus
blau zu färben und 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 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 dem übergeordneten <div>
-Element einen roten Rand zu verleihen, wenn es im Fokus ist.
div:focus {
border: 2px solid red;
}
Die Ergebnisse sind unten zu sehen. Wenn das HTML zuerst gerendert wird, haben die Elemente keine Stile, 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 das zweite Bild).
Für das Shadow Root mit gesetztem shadowrootdelegatesfocus
, führt das Klicken auf den Text (der nicht fokussierbar ist) zur Auswahl des <input>
-Elements, da dies das erste fokussierbare Element im Baum ist. Dies fokussiert auch das übergeordnete Element, wie unten gezeigt.
Vermeiden 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 in der Regel 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 = 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 Aufrufen 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 wurde, der Ereignishandler kopiert, wenn appendChild
aufgerufen wird, und das Klicken darauf funktioniert wie erwartet.
Technische Zusammenfassung
Inhaltskategorien | Metadaten-Inhalt, Flussinhalt, Phraseninhalt, Skripthilfe-Element |
---|---|
Erlaubter Inhalt | Nichts (siehe Anwendungshinweise) |
Tag-Auslassung | Keine, sowohl das Start- als auch das Endtag sind obligatorisch. |
Erlaubte Eltern |
Jedes Element, das
Metadaten-Inhalt,
Phraseninhalt oder
Skripthilfe-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
Loading…
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
- Deklaratives Shadow DOM (mit HTML) in Using Shadow DOM
- Deklaratives Shadow DOM auf web.dev (2023)