HTML/Web Components/template

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
Web Components Logo

Das template-Element ermöglicht es, Template-Vorlagen als Inhaltsfragmente im HTML-Dokument anzugeben, die zwar auf ihre Richtigkeit geparst, aber nicht gerendert werden. Erst wenn sie benötigt werden, können sie mit appendChild() in den Elementenbaum eingehängt werden. [1] [2]

Sie sind eine gute Alternative zum zeitaufwendigen Nachladen von Inhalten mit AjaX oder dem dynamischen Erzeugen mit createElement, das bei komplexeren HTML-Strukturen schnell unbequem und unübersichtlich wird. Eric Bidelman stellt in diesem Artikel die Vorgängervorgehensweisen „Offscreen DOM“ und „Overloading Script“ und ihre Nachteile vor.

Template als Vorlage
<template id="zusatz">
  <h1>Überschrift</h1>
  <p>Textabsatz</p>
</template>

Templates und ihr Inhalt …

  • sind inaktiv, bis sie aufgerufen werden. Das Markup ist nicht sichtbar und wird nicht gerendert. Auch mit document.getElementById() oder querySelector() kann nicht auf Elemente des Templates zugegriffen werden.
    • Sie können aber mit console.dir(document.getElement….content.childNodes) indirekt über die content-Eigenschaft und childNodes auf den Inhalt zugreifen.
  • beinträchtigen die Seitenladezeit nicht, da Scripte, Bilder und andere Mediendateien nicht geladen oder abgespielt werden, bis das Template verwendet wird.
  • können überall im head, body oder frameset notiert werden und können beliebigen Inhalt (z. B. auch das style-Element) haben. template kann auch Nachfahrenelement von table oder select sein, die sonst nur festgelegte Kindelemete haben.

Feature-Erkennung

Um zu erkennen, ob der Browser das template-Element unterstützt, können Sie die Existenz der content-Eigenschaft überprüfen. Falls es nicht unterstützt wird, müssen Sie die Inhalte von Ihrem Server nachladen oder einen Polyfill verwenden.

Feature-Erkennung
function supportsTemplate() {
  return 'content' in document.createElement('template');
}

if (supportsTemplate()) {
  // Perfekt!
} else {
  // Nachladen von Seiteninhalten mit Ajax
}

Anwendungsbeispiel

In einer Webseite sollen alle angebotenen Waren in einer Tabelle aufgelistet werden. Dabei soll für jeden Posten eine neue Tabellenzeile eingefügt werden.

Template anlegen

Unsere Seite besteht aus einer (noch) leeren Tabelle und dem Template.

Einbinden des Templates ansehen …
    <table id="angebotsliste">
      <thead>
        <tr>
          <th>Produkt</th>
          <th>Anzahl</th>
          <th>Preis</td>
        </tr>
      </thead>
      <tbody>
        <!-- Platz zum Einfügen der Tabellenzeilen -->
      </tbody>
    </table>

    <template id="neueReihe">
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
    </template>

Im Markup wird eine Tabelle mit Kopf, aber ohne weitere Inhaltselemente im body notiert.
Darunter befindet sich das inaktive template mit der id neueReihe. Es besteht aus einer tr mit mehreren Tabellenzellen (td).

Template einbinden

Das inaktive Template kann mit appendChild in den Elementenbaum eingebunden werden und wird dann gerendert.

Einbinden des Templates
var vorlage = document.getElementById('irgendeine-id');
document.body.appendChild(vorlage.content.cloneNode(true));

In unserem Beispiel soll die Liste auf Knopfdruck angezeigt werden:

Einbinden des Templates ansehen …
function listeAusgeben() {
  var tbody = document.querySelector("#stocklist tbody"),
      temp = document.querySelector("#neueReihe");

  if (
    // Feature-detection: Prüfen, ob template unterstützt wird
    'content' in document.createElement('template')
    && tbody // Tabelle #stocklist und darin <tbody> gefunden?
    && temp // template gefunden?
  ) {

    // Tabelle leeren
    tbody.innerHTML = "";

    // stocklist durchgehen und alle Artikel in Tabelle auflisten
    cart.forEach(function (article) {
      var tr, cells;

      // template für einen Artikel "laden" (lies: klonen)
      tr = document.importNode(temp.content, true);

      // Zellen befüllen
      cells = tr.querySelectorAll("td");
      cells[0].textContent = article.title;
      cells[1].textContent = article.amount;
      cells[2].textContent = article.price.toFixed(2);		

      // template einpassen
      tbody.appendChild(tr);
    });

  } else {
    // Nachladen von Seiteninhalten mit Ajax
  }
}

Mit einem Click auf den Button wird die Funktion listeAusgeben() aufgerufen.
In einer Feature-Detektion wird zuerst geprüft, ob die content-Eigenschaft des template-Elements unterstützt wird und ob die aufnehmende Tabelle und das einzufügende Template vorhanden sind.
Anschließend werden eventuell vorhandene Inhalte in <tbody> geleert.
Mit forEach wird für jeden vorhandenen Artikel ein template geklont und mit textContent befüllt.

verschachtelte Templates

Es ist möglich, Templates beliebig ineinander zu verschachteln.

verschachtelte Template
<template id="zusatz">
  <h1>Überschrift</h1>
  <p>Textabsatz</p>
  <template id="nochwas">
    <h1>Ergänzung</h1>
    <p>Textabsatz</p>
  </template>
</template>
Beachten Sie, dass das Aktivieren eines Templates eventuell darin befindliche Templates unberührt lässt. Diese müssen ebenfalls aktiviert werden.

Fazit

Mit dem template-Element können Sie noch nicht benötigte Teile der Seite bereits beim ersten Übertragen mitsenden und später aktivieren.

Dies können Meldefenster, Login-Formulare, Einstellungen-Dialoge etc. sein, die bei Bedarf aus dem template-Markup erstellt werden, um den Dialog nicht erst direkt vom Server laden zu müssen, also HTTP-Requests einzusparen, und letztlich schneller verfügbar zu sein.

Auch beim Lazy-Loading (engl. etwa „faules ..“ oder „müßiges Laden“), einem Entwurfsmuster, bei dem Datenobjekte grundsätzlich Werte oder andere, abhängige Objekte bereitstellen, diese aber erst bei einer konkreten Anfrage aus der Datenquelle holen, ist das Verwenden von template sinnvoll.[3]

Siehe auch

Weblinks

  1. W3C: The template element
  2. MDN: template
  3. Wikipedia: Lazy Loading