Spec-Zone.ru › HTML

<template>: Элемент шаблона содержимого

Базовая линия Широко доступная

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна во всех браузерах с ноября 2015 года.

  • Подробнее
  • Полная совместимость
  • Отправить отзыв

Элемент <template> HTML служит механизмом для хранения фрагментов HTML, которые можно использовать позже с помощью JavaScript или сразу сгенерировать в домен тени.

Атрибуты

Этот элемент включает глобальные атрибуты.

shadowrootmode

Создаёт домен тени для родительского элемента. Это декларативный аналог метода Element.attachShadow() и принимает те же перечисляемые значения.

open

Выводит внутренний домен тени для JavaScript (рекомендуется для большинства случаев использования).

closed

Скрывает внутренний домен тени от JavaScript.

Примечание: Парсер HTML создаёт объект ShadowRoot в DOM для первого <template> в узле с этим атрибутом, установленным на допустимое значение. Если атрибут не установлен или не установлен на допустимое значение — или если HTMLTemplateElement уже был декларативно создан в том же родителе — то будет создан HTMLTemplateElement. HTMLTemplateElement не может быть изменён на домен тени после парсинга, например, путём установки HTMLTemplateElement.shadowRootMode.

Примечание: Вы можете встретить нестандартный shadowroot атрибут в старых учебниках и примерах, которые поддерживались в Chrome 90-110. Этот атрибут с тех пор был удалён и заменён стандартным атрибутом shadowrootmode.

shadowrootclonable

Устанавливает значение свойства clonable ShadowRoot, созданного с помощью этого элемента, на true. Если он установлен, копия тени (родительский элемент этого <template>) при создании с помощью Node.cloneNode() или Document.importNode() будет включать домен тени в копию.

shadowrootdelegatesfocus

Устанавливает значение свойства delegatesFocus ShadowRoot, созданного с помощью этого элемента, на true. Если он установлен и выбран нефокусируемый элемент в дереве тени, фокус перенаправляется на первый фокусируемый элемент в дереве. Значение по умолчанию равно false.

shadowrootserializable Экспериментальное

Устанавливает значение свойства serializable ShadowRoot, созданного с помощью этого элемента, на true. Если он установлен, домен тени может быть сериализован путём вызова методов Element.getHTML() или ShadowRoot.getHTML() с параметром options.serializableShadowRoots установлен на true. Значение по умолчанию false.

Примечания по использованию

Существует два основных способа использования элемента <template>.

Фрагмент документа шаблона

По умолчанию содержимое элемента не отображается. Соответствующий интерфейс HTMLTemplateElement включает стандартное свойство content (без эквивалентного атрибута содержимого/разметки). Это content свойство является только для чтения и содержит DocumentFragment, который содержит поддерево DOM, представленное шаблоном. Этот фрагмент можно клонировать с помощью метода cloneNode и вставить в DOM.

Будьте осторожны при использовании свойства content, так как возвращаемый DocumentFragment может вести себя неожиданно. Более подробную информацию см. в разделе «Избегайте проблем с DocumentFragment» ниже.

Декларативный домен тени

Если элемент <template> содержит атрибут shadowrootmode со значением open или closed, парсер HTML сразу же сгенерирует домен тени. Элемент в DOM заменяется своим содержимым, заключённым в ShadowRoot, который прикреплён к родительскому элементу. Это декларативный эквивалент вызова Element.attachShadow() для прикрепления домена тени к элементу.

Если у элемента другое значение для shadowrootmode, или атрибут shadowrootmode отсутствует, парсер генерирует HTMLTemplateElement. Аналогично, если есть несколько декларативных доменов тени, только первый из них заменяется ShadowRoot — последующие экземпляры парсятся как объекты HTMLTemplateElement.

Примеры

Генерация строк таблицы

Сначала мы начнём с HTML-части примера.

html
<table id="producttable">
  <thead>
    <tr>
      <td>UPC_Code</td>
      <td>Product_Name</td>
    </tr>
  </thead>
  <tbody>
    <!-- existing data could optionally be included here -->
  </tbody>
</table>

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

Сначала у нас есть таблица, в которую мы позже вставим содержимое с помощью JavaScript. Затем следует шаблон, описывающий структуру фрагмента HTML, представляющего одну строку таблицы.

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

js
// Test to see if the browser supports the HTML template element by checking
// for the presence of the template element's content attribute.
if ("content" in document.createElement("template")) {
  // Instantiate the table with the existing HTML tbody
  // and the row with the template
  const tbody = document.querySelector("tbody");
  const template = document.querySelector("#productrow");

  // Clone the new row and insert it into the table
  const clone = template.content.cloneNode(true);
  let td = clone.querySelectorAll("td");
  td[0].textContent = "1235646565";
  td[1].textContent = "Stuff";

  tbody.appendChild(clone);

  // Clone the new row and insert it into the table
  const clone2 = template.content.cloneNode(true);
  td = clone2.querySelectorAll("td");
  td[0].textContent = "0384928528";
  td[1].textContent = "Acme Kidney Beans 2";

  tbody.appendChild(clone2);
} else {
  // Find another way to add the rows to the table because
  // the HTML template element is not supported.
}

Результатом является исходная HTML-таблица с двумя добавленными в неё строками через JavaScript:

Реализация декларативного домена тени

В этом примере в начале разметки включено скрытое предупреждение о поддержке. Это предупреждение впоследствии будет отображаться с помощью JavaScript, если браузер не поддерживает атрибут shadowrootmode. Далее следуют два элемента <article>, каждый из которых содержит вложенные элементы <style> с разным поведением. Первый элемент <style> является глобальным для всего документа. Второй ограничен доменом тени, сгенерированным вместо элемента <template> из-за присутствия атрибута shadowrootmode.

html
<p hidden>
  ⛔ Your browser doesn't support <code>shadowrootmode</code> attribute yet.
</p>
<article>
  <style>
    p {
      padding: 8px;
      background-color: wheat;
    }
  </style>
  <p>I'm in the DOM.</p>
</article>
<article>
  <template shadowrootmode="open">
    <style>
      p {
        padding: 8px;
        background-color: plum;
      }
    </style>
    <p>I'm in the shadow DOM.</p>
  </template>
</article>
js
const isShadowRootModeSupported =
  HTMLTemplateElement.prototype.hasOwnProperty("shadowRootMode");

document
  .querySelector("p[hidden]")
  .toggleAttribute("hidden", isShadowRootModeSupported);

Декларативный домен тени с делегированным фокусом

Этот пример демонстрирует, как shadowrootdelegatesfocus применяется к корню тени, созданному декларативно, и какое влияние это оказывает на фокус.

Код сначала объявляет корень тени внутри элемента <div>, используя элемент <template> с атрибутом shadowrootmode. Это отображает как нефокусируемый <div> с текстом, так и фокусируемый элемент <input>. Также используется CSS для стилизации элементов с :focus в синий цвет и для установки обычного стилирования элемента-хоста.

html
<div>
  <template shadowrootmode="open">
    <style>
      :host {
        display: block;
        border: 1px dotted black;
        padding: 10px;
        margin: 10px;
      }
      :focus {
        outline: 2px solid blue;
      }
    </style>
    <div>Clickable Shadow DOM text</div>
    <input type="text" placeholder="Input inside Shadow DOM" />
  </template>
</div>

Второй блок кода идентичен, за исключением того, что он устанавливает атрибут shadowrootdelegatesfocus, который делегирует фокус первому фокусируемому элементу в дереве, если выбран нефокусируемый элемент в дереве.

html
<div>
  <template shadowrootmode="open" shadowrootdelegatesfocus>
    <style>
      :host {
        display: block;
        border: 1px dotted black;
        padding: 10px;
        margin: 10px;
      }
      :focus {
        outline: 2px solid blue;
      }
    </style>
    <div>Clickable Shadow DOM text</div>
    <input type="text" placeholder="Input inside Shadow DOM" />
  </template>
</div>

Наконец, мы используем следующий CSS для применения зелёно-жёлтой границы к родительскому элементу <div> при фокусировке на нём.

css
div:focus {
  border: 2px solid red;
}

Результаты показаны ниже. При первом отображении HTML элементы не имеют стилей, как показано на первом изображении. Для корня тени, у которого не установлен shadowrootdelegatesfocus атрибут, вы можете кликнуть в любом месте, кроме <input>, и фокус не изменится (если вы выберете элемент <input>, то это будет выглядеть как на втором изображении).

Screenshot of code with no focus set

Для корня тени, у которого установлен shadowrootdelegatesfocus атрибут, нажатие на текст (который не фокусируется) выбирает элемент <input>, так как это первый фокусируемый элемент в дереве. Это также фокусирует родительский элемент, как показано ниже.

Screenshot of the code where the element has focus

Избегание проблем с DocumentFragment

Когда передаётся значение DocumentFragment, методы Node.appendChild и аналогичные перемещают только дочерние узлы этого значения в целевой узел. Поэтому обычно предпочтительнее прикреплять обработчики событий к дочерним элементам 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.cloneNode(true);
secondClone.children[0].addEventListener("click", clickHandler);
container.appendChild(secondClone);

Результат

Так как firstClone является DocumentFragment, только его дочерние элементы добавляются к container при вызове appendChild; обработчики событий firstClone не копируются. В отличие от этого, так как обработчик событий добавлен к первому дочернему узлу secondClone, обработчик событий копируется при вызове appendChild, и нажатие на него работает так, как ожидается.

Технический обзор

Категории контента Метаданные, потоковый контент, фразный контент, элементы поддержки скриптов
Разрешенный контент Без ограничений
Пропуск тега Нет, как начальный, так и конечный тег обязательны.
Разрешенные родительские элементы Любой элемент, который принимает метаданные, фразы или элементы поддержки скриптов. Также разрешается как дочерний элемент элемента <colgroup>, у которого нет атрибута span.
Неявная роль ARIA Нет соответствующей роли
Разрешенные роли ARIA Нет role разрешенных ролей
Интерфейс DOM HTMLTemplateElement

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

Спецификация
Стандарт HTML
# the-template-element

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

Рабочие столы Мобильные устройства
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari на iOS Samsung Internet WebView Android
template 26 13 22 15 8 26 22 14 8 1.5 4.4
shadowrootclonable 124 124 125 110 Нет 124 125 82 Нет Нет 124
shadowrootdelegatesfocus 123 123 123 109 Нет 123 123 82 Нет Нет 123
shadowrootmode 11190–111 11190–111 123 9776–97 16.4 11190–111 123 7564–75 16.4 22.015.0–22.0 11190–111
shadowrootserializable 125 125 Нет 111 Нет 125 Нет 83 Нет Нет 125

См. также

  • part и exportparts атрибуты HTML
  • <slot> элемент HTML
  • :host, :host() и :host-context() псевдоклассы CSS
  • ::part и ::slotted псевдоэлементы CSS
  • ShadowRoot интерфейс
  • Использование шаблонов и слотов
  • Модуль CSS scoping
  • Декларативный Shadow DOM (с html) в разделе Использование Shadow DOM
  • Декларативный Shadow DOM на web.dev (2023)

© 2005–2023 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API