HTML тег <template>
Тег <template> хранит фрагменты кода, которые можно клонировать и многократно использовать в HTML-документе. Смотрите примеры.
Тег <template> содержит HTML-разметку, которую вы хотите повторно использовать, но не отображать при загрузке страницы. Браузер разбирает разметку, чтобы убедиться в её корректности, а затем сохраняет её как инертный шаблон. Вы клонируете этот шаблон с помощью JavaScript всякий раз, когда нужна копия на живой странице — распространённый паттерн для создания повторяющихся элементов списка, строк таблицы или карточек.
На этой странице рассматривается, почему содержимое template является инертным, как активировать его с помощью JavaScript (content, cloneNode, appendChild), а также практический цикл для создания множества элементов из одного шаблона.
Тег <template> — это новый элемент в HTML5. Он может быть размещён в любом месте внутри <head> или <body> и может содержать любое содержимое, допустимое для этих элементов.
Почему содержимое template является инертным
Всё внутри <template> разбирается как обычный HTML, но браузер считает его инертным до момента активации. Это означает:
- Оно не отображается — ничто внутри шаблона не появляется на странице.
- Теги
<script>внутри него не выполняются. - Теги
<style>внутри него не применяются. - Внешние ресурсы не загружаются — источники
<img>,<video>и<audio>не запрашиваются, поэтому шаблон со 100 изображениями не генерирует сетевых запросов до его использования. - Его узлы не являются частью основного дерева документа. Вызов
document.getElementById()илиquerySelector()на странице не найдёт элементы, расположенные внутри шаблона.
Эта инертность и есть суть подхода: вы можете отправить фрагмент разметки вместе со страницей, который остаётся дешёвым и не имеющим побочных эффектов до того момента, когда он действительно понадобится.
Синтаксис
Тег <template> используется парно. Содержимое записывается между открывающим (<template>) и закрывающим (</template>) тегами.
Пример HTML-тега <template>:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<h1>This is a heading.</h1>
<p>
<q>If you tell the truth, you don't have to remember anything.</q>
― Mark Twain
</p>
<template>
<h2>This is a second heading.</h2>
<p>
“I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best.”
― Marilyn Monroe
</p>
</template>
</body>
</html>Если вы откроете приведённый выше пример, второй заголовок и цитата Мэрилин Монро нигде не будут отображаться на странице — они находятся внутри <template>, который невидим и инертен во время загрузки. Ничто не отображается, пока JavaScript не клонирует содержимое в живой документ.
Активация шаблона с помощью JavaScript
Чтобы использовать содержимое шаблона, вы читаете его через свойство content элемента, клонируете его и вставляете клон на страницу. Вот канонический паттерн с пояснениями:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<template id="myTemplate">
<p>Template content</p>
</template>
<div id="normalContent">
<p>First paragraph</p>
</div>
<!-- JavaScript function clones the template and adds it to the document. -->
<button onclick="useTemplate();">Show content</button>
<script>
function useTemplate() {
const myTemplate = document.getElementById('myTemplate');
const normalContent = document.getElementById('normalContent');
const clonedTemplate = myTemplate.content.cloneNode(true);
normalContent.appendChild(clonedTemplate);
}
</script>
</body>
</html>При нажатии кнопки выполняется функция useTemplate(). Вот что делает каждая строка:
myTemplate.contentвозвращаетDocumentFragmentшаблона — лёгкий контейнер вне документа, содержащий дочерние узлы шаблона. Вы никогда не вставляете этот фрагмент напрямую, так как это опустошит исходный шаблон; вместо этого вы его клонируете..cloneNode(true)создаёт глубокий клон фрагмента. Аргументtrueозначает «клонировать этот узел и всех его потомков». Приfalseвы скопируете только пустой фрагмент и потеряете<p>внутри него, поэтому для шаблонов почти всегда передаютtrue.normalContent.appendChild(clonedTemplate)вставляет клонированные узлы в живой DOM после существующего первого абзаца. Поскольку это копия, шаблон остаётся нетронутым и может быть использован столько раз, сколько нужно.
Подробнее об этих методах см. в разделе JavaScript HTML DOM.
Сценарий использования: создание повторяющегося содержимого в цикле
Настоящая сила <template> проявляется, когда нужно создать множество похожих элементов. Вместо того чтобы писать каждую строку вручную или формировать разметку конкатенацией строк, вы храните один шаблон и клонируете его для каждой единицы данных:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<ul id="fruitList"></ul>
<template id="itemTemplate">
<li class="fruit"></li>
</template>
<script>
const fruits = ['Apple', 'Banana', 'Cherry'];
const list = document.getElementById('fruitList');
const template = document.getElementById('itemTemplate');
fruits.forEach(function (fruit) {
// Clone the template for each fruit.
const clone = template.content.cloneNode(true);
// Fill in the clone before inserting it.
clone.querySelector('.fruit').textContent = fruit;
list.appendChild(clone);
});
</script>
</body>
</html>В результате создаётся три элемента <li>, по одному для каждого фрукта. Тот же подход масштабируется на строки таблиц, карточки товаров или любые списки, управляемые данными — определите разметку один раз, клонируйте её в цикле и заполните динамические части перед добавлением.
Тег <template> поддерживает Глобальные атрибуты.