<template>: Das Inhaltsvorlage-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 den 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 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, bei dem dieses Attribut auf einen erlaubten Wert gesetzt ist. Wenn das Attribut nicht gesetzt oder nicht auf einen erlaubten Wert gesetzt ist - oder wenn ein ShadowRoot bereits deklarativ im selben Elternelement erstellt wurde - wird ein HTMLTemplateElement konstruiert. Ein HTMLTemplateElement kann anschließend nicht in einen Shadow Root umgewandelt werden, zum Beispiel durch das Setzen von HTMLTemplateElement.shadowRootMode.

Hinweis: Sie können das nicht standardisierte shadowroot Attribut in älteren Tutorials und Beispielen finden, das in Chrome 90-110 unterstützt wurde. Dieses Attribut wurde seitdem entfernt und durch das standardisierte shadowrootmode Attribut ersetzt.

shadowrootclonable

Setzt den Wert der clonable Eigenschaft eines ShadowRoot, das mit diesem Element erstellt wurde, auf true. Wenn gesetzt, enthält ein Klon des Shadow Hosts (das Elternelement dieses <template>), erstellt mit Node.cloneNode() oder Document.importNode(), einen Shadow Root in der Kopie.

shadowrootdelegatesfocus

Setzt den Wert der delegatesFocus Eigenschaft eines ShadowRoot, das mit diesem Element erstellt wurde, auf true. Wenn dies gesetzt ist und ein nicht-fokussierbares Element im Shadow Tree ausgewählt wird, wird der Fokus an das erste fokussierbare Element im Baum delegiert. Der Wert ist standardmäßig false.

shadowrootserializable Experimentell

Setzt den Wert der serializable Eigenschaft eines ShadowRoot, das mit diesem Element erstellt wurde, auf true. Wenn gesetzt, kann der Shadow Root serialisiert werden, indem die Methoden Element.getHTML() oder ShadowRoot.getHTML() mit dem Parameter options.serializableShadowRoots auf true aufgerufen werden. Der Wert ist standardmäßig false.

Nutzungshinweise

Es gibt zwei Hauptwege, das <template> Element zu verwenden.

Dokumentfragment-Vorlage

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 dargestellten DOM-Teilbaum enthält. Dieses Fragment kann mittels der cloneNode Methode geklont und in den DOM eingefügt werden.

Seien Sie vorsichtig bei der Verwendung der content Eigenschaft, da das zurückgegebene DocumentFragment unerwartetes Verhalten zeigen kann. Für weitere Details sehen Sie sich den Abschnitt Vermeidung von DocumentFragment-Fallstricken unten an.

Deklarativer Shadow DOM

Wenn das <template> Element das shadowrootmode Attribut 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 eingeschlossen ist, der an das Elternelement angehängt wird. Dies ist das deklarative Äquivalent dazu, Element.attachShadow() aufzurufen, um einen Shadow Root an ein Element anzuhängen.

Wenn das Element einen anderen Wert für shadowrootmode hat oder das shadowrootmode Attribut fehlt, generiert der Parser ein HTMLTemplateElement. Ähnlich, wenn es mehrere deklarative Shadow Roots gibt, wird nur der erste durch einen ShadowRoot ersetzt - nachfolgende Instanzen werden als HTMLTemplateElement Objekte geparst.

Beispiele

Generierung von Tabellenzeilen

Zuerst beginnen wir mit dem HTML-Teil des Beispiels.

html
<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 mithilfe von JavaScript-Code einfügen werden. Danach kommt das Template, das die Struktur eines HTML-Fragments beschreibt, das eine einzelne Tabellenreihe repräsentiert.

Nun, da die Tabelle erstellt und das Template definiert wurde, verwenden wir JavaScript, um Zeilen in die Tabelle einzufügen, wobei jede Zeile mit dem Template als Grundlage konstruiert wird.

js
// 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ützungswarnung am Anfang des Markups enthalten. Diese Warnung wird später über JavaScript angezeigt, wenn der Browser das shadowrootmode Attribut nicht unterstützt. Als nächstes folgen 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 dem Shadow Root zugeordnet, der anstelle des <template> Elements generiert ist, da das Attribut shadowrootmode vorhanden ist.

html
<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>
js
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 einen deklarativ erstellten Shadow Root angewendet wird und welchen Effekt dies auf den Fokus hat.

Der Code erklärt zunächst einen Shadow Root innerhalb eines <div> Elements, wobei das <template> Element mit dem shadowrootmode Attribut verwendet wird. Dies zeigt sowohl ein nicht-fokussierbares <div> mit Text als auch ein fokussierbares <input> Element. Es verwendet auch CSS, um Elemente mit :focus in Blau zu stylen und das normale Styling des Host-Elements zu setzen.

html
<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, wenn ein nicht-fokussierbares Element im Baum ausgewählt wird.

html
<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 folgendes CSS, um einem übergeordneten <div> Element einen gelb-grünen Rand zu geben, wenn es den Fokus hat.

css
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. Für den Shadow Root, der 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 wie im zweiten Bild aus).

Screenshot vom Code ohne eingestellten Fokus

Für den Shadow Root mit gesetztem shadowrootdelegatesfocus führt ein Klick auf den Text (der nicht-fokussierbar ist) dazu, dass das <input> Element ausgewählt wird, da dies das erste fokussierbare Element im Baum ist. Dies fokussiert auch das übergeordnete Element, wie unten gezeigt.

Screenshot des Codes, bei dem das Element den Fokus hat

Vermeidung von DocumentFragment-Fallstricken

Wenn ein DocumentFragment Wert übergeben wird, verschieben Node.appendChild und ähnliche Methoden nur die Kindknoten dieses Werts in den Zielknoten. Daher ist es üblicherweise vorzuziehen, Ereignis-Handler an die Kinder eines DocumentFragment anzuhängen, anstatt an das DocumentFragment selbst.

Betrachten Sie das folgende HTML und JavaScript:

HTML

html
<div id="container"></div>

<template id="template">
  <div>Click me</div>
</template>

JavaScript

js
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 die Kinder zu container hinzugefügt; die Ereignis-Handler von firstClone werden nicht kopiert. Im Gegensatz dazu wird ein Ereignis-Handler, der zum ersten Kindknoten von secondClone hinzugefügt wird, kopiert, wenn appendChild aufgerufen wird, und das Klicken darauf funktioniert wie erwartet.

Technische Zusammenfassung

Inhaltskategorien Metadateninhalt, Flussinhalt, Phraseninhalt, script-unterstützende Elemente
Erlaubter Inhalt Keine Einschränkungen
Tag-Auslassung Keine, sowohl das Start- als auch das End-Tag sind erforderlich.
Erlaubte Eltern Jedes Element, das Metadateninhalt, Phraseninhalt, oder script-unterstützende Elemente akzeptiert. Auch als Kind eines <colgroup> Elements erlaubt, das kein span Attribut hat.
Implizite ARIA-Rolle Keine entsprechende Rolle
Erlaubte ARIA-Rollen Kein role erlaubt
DOM-Schnittstelle [`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