W3docs

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> поддерживает Глобальные атрибуты.

Практика

Практика
Что делает HTML-тег '<template>'?
Что делает HTML-тег '<template>'?
Was this page helpful?