<template>: элемент шаблона контента
====================================

HTML-элемент шаблона контента **`<template>`** — это механизм для отложенного создания клиентского контента, который не отображается во время загрузки страницы, но может быть инициализирован при помощи JavaScript.

Шаблон можно представить себе как фрагмент контента страницы, сохранённый для последующего использования в документе. Хотя парсер и обрабатывает содержимое элемента **`<template>`** во время загрузки страницы, он делает это, только чтобы убедиться в валидности содержимого, само содержимое при этом не отображается.

| Категории контента | Метаданные, основной поток, фразовый контент, элементы поддержки скриптов |
| --- | --- |
| Допустимый контент | Нет ограничений |
| Пропуск тегов | Нет, открывающий и закрывающий теги обязательны. |
| Допустимые родители | Любые элементы, которые могут содержать метаданные, фразовый контент или элементы поддержки скриптов. Допускается вкладывать элемент в `<colgroup>` (en-US), у которого *отсутствует* атрибут `span` (en-US). |
| Неявные ARIA-роли | Нет соответствующей роли |
| Допустимые ARIA-роли | Нет |
| DOM-интерфейс | `HTMLTemplateElement` (en-US) |

Атрибуты
--------

Элемент может иметь общие атрибуты.

Однако у ``HTMLTemplateElement` (en-US)` есть свойство ``content` (en-US)`, которое возвращает доступный только для чтения ``DocumentFragment``, содержащий DOM-поддерево шаблона. Обратите внимание, что прямое использование значения ``content` (en-US)` может привести к непредсказуемому поведению, см. раздел ловушка `DocumentFragment` ниже.

Примеры
-------

Начнём с HTML.


```html
<table id="producttable">
  <thead>
    <tr>
      <td>UPC_Code</td>
      <td>Product_Name</td>
    </tr>
  </thead>
  <tbody>
    <!-- данные будут вставлены сюда -->
  </tbody>
</table>

<template id="productrow">
  <tr>
    <td class="record"></td>
    <td></td>
  </tr>
</template>
```


Для начала у нас есть таблица, в которую мы собираемся вставить контент с помощью Javascript. За таблицей следует шаблон, который описывает структуру HTML-фрагмента — строку таблицы.

Теперь, когда таблица была создана, а шаблон определён, используем JavaScript, чтобы вставить строки в таблицу. Каждая строка будет строиться по шаблону.


```js
// Убеждаемся, что браузер поддерживает тег <template>,
// проверив наличие атрибута content у элемента template.
if ("content" in document.createElement("template")) {
  // Находим элемент tbody таблицы
  // и шаблон строки
  var tbody = document.querySelector("tbody");
  var template = document.querySelector("#productrow");

  // Клонируем новую строку и вставляем её в таблицу
  var clone = template.content.cloneNode(true);
  var td = clone.querySelectorAll("td");
  td[0].textContent = "1235646565";
  td[1].textContent = "Stuff";

  tbody.appendChild(clone);

  // Клонируем новую строку ещё раз и вставляем её в таблицу
  var clone2 = template.content.cloneNode(true);
  td = clone2.querySelectorAll("td");
  td[0].textContent = "0384928528";
  td[1].textContent = "Acme Kidney Beans 2";

  tbody.appendChild(clone2);
} else {
  // Иной способ заполнить таблицу, потому что
  // HTML-элемент template не поддерживается.
}
```


Как результат имеем HTML-таблицу с двумя новыми строками, добавленными с помощью JavaScript:
```

table {
  background: #000;
}
table td {
  background: #fff;
}
```

Ловушка `DocumentFragment`
--------------------------

`DocumentFragment` не подходит в качестве целевого объекта для многих событий, поэтому предпочтительнее клонировать или ссылаться на элементы внутри него.

Рассмотрим следующие HTML-разметку и JavaScript-код:

### HTML


```html
<div id="container"></div>

<template id="template">
  <div>Click me</div>
</template>
```

### JavaScript


```js
const container = document.getElementById("container");
const template = document.getElementById("template");

function clickHandler(event) {
  event.target.append(" — Clicked this div");
}

const firstClone = template.content.cloneNode(true);
firstClone.addEventListener("click", clickHandler);
container.appendChild(firstClone);

const secondClone = template.content.firstElementChild.cloneNode(true);
secondClone.addEventListener("click", clickHandler);
container.appendChild(secondClone);
```

### Результат

В переменной `firstClone` у нас экземпляр (клон) `DocumentFragment`, и хотя у нас получилось отрисовать его внутри контейнера, клик по нему не срабатывает. В переменной `secondClone` у нас экземпляр (клон) ``HTMLDivElement``, клик по которому работает как ожидается.

Спецификации
------------

| Specification |
| --- |
| HTML Standard # the-template-element |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* Веб-компоненты: `<slot>` (и устаревший: `<shadow>`)
* Использование шаблонов и слотов (en-US)