HTML template element – szablony w standardzie

Szablony w aplikacjach webowych to dzisiaj nic nowego. Dla samego JavaScriptu mamy na rynku kilka dobrych rozwiązań wspomagających pracę z templateami jak choćby Handlebars, Mustache.js czy Underscorowy _.template(). To oczywiście tylko część tego co oferuje nam internet. A co z natywnym wsparciem dla szablonów?

Jak definiujemy szablony teraz?

Dotychczas, definiując szablon w dokumencie, mogliśmy skorzystać z dwóch rozwiązań. Pierwsze podejście to tworzenie takiego szablonu jako część DOM i ukrywanie go poprzez display:none lub nowy atrybut hidden:

<div id="myTemplate" hidden>
    <li class="todo-item"></li>
</div>

Drugie podejście wykorzystuje element script:

<script id="myTemplate" type="text/template">
    <li class="todo-item"></li>
</script>

Obydwa podejścia mają swoje wady i zalety, ale nie są to rozwiązania natywne. W3C postanowiło więc wprowadzić element <template>, który takie natywne wsparcie ma nam zapewnić

Element template

Element <template>, jak mówi specyfikacja, pozwala nam na zdefiniowanie fragmentu kodu HTML, który możemy wielokrotnie wykorzystywać w dalszej części naszej aplikacji. Zawartość tego elementu, czyli nasz szablon, nosi nazwę template content i znajduje się pod właściwością content. Poniżej przykładowy szablon.

<template id="myTemplate">
    <li class="todo-item"></li>
</template>

Element <template> ma kilka ciekawych właściwości o których warto pamiętać.

  1. Może zostać umieszczony w dowolnym miejscu na stronie, czyli i w <head> i w <body> ale także np. w <table>.
  2. Zawartość szablonu jest ignorowana przez przeglądarkę, co oznacza że HTML nie pojawi się na stronie.
  3. Wywołanie querySelector (lub jemu podobnych) na elemencie <template> nie zwróci nam żadnego wyniku. Jednak wywołanie tej funkcji na własności content już wynik zwróci:
    var t = document.querySelector('#myTemplate');
    t.content.querySelector('label');
  4. Znajdujące się wewnątrz skrypty nie zostaną wywołane.
  5. Przeglądarka nie pobierze również obrazków, video czy audio zdefiniowanych w szablonie.
  6. Zawartość content jest tylko do odczytu

Wykorzystanie szablonu

Najprostszym sposobem aby wykorzystać zdefiniowany szablon jest utworzenie głębokiej kopii zawartości content, używając do tego funkcji cloneNode(true).

var t = document.querySelector('#myTemplate'),
    todos = document.getElementById('todos');

todos.appendChild(t.content.cloneNode(true));

Warto tutaj zaznaczyć, że w momencie kopiowania zawartości, przeglądarka pobierze wszystkie zdefiniowane wewnątrz obrazki, video ipt. i/lub wywoła napotkane skrypty.

Link do demo (chrome 26+, lub firefox 22+)

Wsparcie przeglądarek

W chwili pisania tego postu jedynie chrome ( 26+) oraz firefox ( 22+) zapewniają wsparcie dla elementu <template>. Jak zawszę odsyłam jednak do caniuse.com aby być na bieżąco.

Aby wykryć wsparcie przeglądarki dla template wystarczy utworzyć ten element w JS i sprawdzić czy posiada on właściwość content.

function supports_template() {
  return 'content' in document.createElement('template');
}

Podsumowanie

To by było na tyle. Specyfikacja dalej się rozwija więc możemy się spodziewać kolejnych zmian, ale już teraz można powiedzieć, że dobrze że taki element się pojawił. Fajnie, że dostaniemy natywną możliwość definiowania szablonów, zamiast bawić się nie do końca semantycznymi rozwiązaniami. Wsparcie oczywiście nie jest jeszcze imponujące ale miejmy nadzieję, że to się szybko zmieni.

Źródła