HTML-Template-Element und cloneNode

Das HTML-template-Element enthält ein HTML-Fragment – z.B. Zeilen einer Tabelle, figure-Tags mit figcaption und img. Der Inhalt des template-Elements wird auf der Seite erst angezeigt, wenn Javascript das Fragment klont und ins DOM einfügt.

Javascript clone from template tag

Javascript Template-Engines

Wer PHP programmiert, kennt Template-Systeme wie Smarty oder Twigg: Templates sind Vorlagen aus HTML für den wiederholten Einsatz. Mehr oder minder alle Programmiersprachen arbeiten mit Template-Systemen.

Diese Templates sind immer dann effizient, wenn HTML-Elemente auf eine Anforderung hin mehrfach eingefügt werden sollen. Javascript hat von Haus aus kein Template-System im Angebot. HTML-Elemente werden aufwändig mit createElement erzeugt und zu einem Fragment zusammengesetzt. Die Alternative sind Javascript Template Engines wie

Ähnlich wie in PHP nutzen Javascript Template Engines besondere Zeichenkombinationen oder Direktiven:

EJS      <%    %>
Mustache {{    }}

Javascript Template-Systeme werden z.B. in NodeJS eingesetzt, aber sie können auch ohne Node ausgeführt werden.

HTML-Templates für Javascript

HTML bietet ein spezielles Template-Tag für Javascript, das mit Javascript cloneNode in »echte« HTML-Fragmente umgewandelt und eingebunden wird.

Vorher ist das Markup innerhalt des Template-Elements kein Teil des DOMs und kann auch nicht mit Methoden wie document.getElementById angesprochen werden. Inhalte eines Template-Tags werden erst heruntergeladen, wenn der Template-Code offiziell geklont und eingebunden ist: Bilder in einem Template-Tag werden nicht geladen.

<div id="book-list">
<!-- Platzhalter werden per JS ersetzt -->
</div>
<template id="book-template">
	<div class="book-card">
		<img src="" alt="" loading="lazy" width="" height="">
		<hgroup></hgroup>
		<div class="cards-category"></div>
	</div>
</template>
const container = document.getElementById("book-list");
const template = document.getElementById("book-template");

// Erst Observer definieren!
const observer = new IntersectionObserver(entries => {
	entries.forEach(entry => {
		if (entry.isIntersecting) {
			const placeholder = entry.target;
			const book = JSON.parse(placeholder.dataset.book);
			const clone = template.content.cloneNode(true);
			const card = clone.querySelector(".book-card");

			const img = card.querySelector("img");
			const hgroup = card.querySelector("hgroup");
			const p = card.querySelector("p");
			const cat = card.querySelector(".cards-category");
	  
			img.src = book.img;
			img.alt = book.titel;
			img.width = book.width;
			img.height = book.height;
			hgroup.textContent = book.titel;
			p.textContent = book.autor;
			cat.textContent = book.type;

			// Klasse für Transition nach dem nächsten Frame
			requestAnimationFrame(() => {
				card.classList.add("visible");
			});

			placeholder.replaceWith(clone);
			observer.unobserve(placeholder);
		}
	});
}, {
	rootMargin: "200px",
	threshold: 0.01
});

// Buchdaten laden und Platzhalter erzeugen
fetch('books.json')
	.then(res => res.json())
	.then(books => {
		books.slice(0,8).forEach(book => {
			const div = document.createElement("div");
			div.dataset.book = JSON.stringify(book);
			div.style.minHeight = "200px";
			container.appendChild(div);
			observer.observe(div);
	});
});
Kopieren

Das Template-Beispiel für die kleine Liste von Buch-Cards ist schlicht und kann im head- oder an belieber Stelle im body-Element stehen.

Das Schöne an den schlichten Template-Elementen aus purem HTML: Für Wiederholungen der Elemente und für Abfragen werden keine speziellen Direktiven gebraucht, sondern einfach nur Javascript in Reinform.

Loop in Handlebars

{{#each array}} {{@index}}: {{this}} {{/each}}

Loop Javascript

for (const elem of slides) { … }

Template Literals – native Javascript Template Engine

Template Literal ist mit ES6 auf den Plan getreten und ersetzt das Katzenhaarknäuel von verschachtelten einfachen und doppelten Hochkommas, +- und \-Zeichen der Mischung aus Strings und Variablen.

Eine typische Anwendung für Javascript Templates ist das dynamische Erstellen von Listeneinträgen und Tabellenzeilen in Anwendungen, wenn z.B. Elemente in einem JSON-Array geliefert und als Tabelle oder Liste dargestellt werden sollen.

const lager = [
	{"frucht":"🌽", "ger":139, "austria":20, "switzerland":11 },
	{"frucht":"🍆", "ger":170, "austria":29, "switzerland":9 },
	{"frucht":"🍅", "ger":163, "austria":21, "switzerland":12 },
	{"frucht":"🍇", "ger":109, "austria":13, "switzerland":4 },
	{"frucht":"🍎", "ger":115, "austria":17, "switzerland":8 }
];

let template = lager.map(item => {
	return `
		<div class="entry">
			<span class="frucht">${item.frucht}</span>
			<span class="num ger">${item.ger}</span> 
			<span class="num austria">${item.austria}</span> 
			<span class="num switzerland">${item.switzerland}</span> 
		</div>
	`;
}).join("");

document.querySelector("fruit-shop").innerHTML = template;

Eleganter als HTML-Templates für Javascript allemal, und eine native Javascript-Template-Engine anstelle der wechselnden Template Engines von Handlebar bis Moustach.

Suchen auf mediaevent.de