<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-
Устанавливает значение свойства
clonableShadowRoot, созданного с помощью этого элемента, наtrue. Если он установлен, копия тени (родительский элемент этого<template>) при создании с помощьюNode.cloneNode()илиDocument.importNode()будет включать домен тени в копию. shadowrootdelegatesfocus-
Устанавливает значение свойства
delegatesFocusShadowRoot, созданного с помощью этого элемента, наtrue. Если он установлен и выбран нефокусируемый элемент в дереве тени, фокус перенаправляется на первый фокусируемый элемент в дереве. Значение по умолчанию равноfalse. -
shadowrootserializableЭкспериментальное -
Устанавливает значение свойства
serializableShadowRoot, созданного с помощью этого элемента, на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-части примера.
<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 для вставки строк в таблицу, где каждая строка строится на основе шаблона.
// 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.
<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>
const isShadowRootModeSupported = HTMLTemplateElement.prototype.hasOwnProperty("shadowRootMode"); document .querySelector("p[hidden]") .toggleAttribute("hidden", isShadowRootModeSupported);
Декларативный домен тени с делегированным фокусом
Этот пример демонстрирует, как shadowrootdelegatesfocus применяется к корню тени, созданному декларативно, и какое влияние это оказывает на фокус.
Код сначала объявляет корень тени внутри элемента <div>, используя элемент <template> с атрибутом shadowrootmode. Это отображает как нефокусируемый <div> с текстом, так и фокусируемый элемент <input>. Также используется CSS для стилизации элементов с :focus в синий цвет и для установки обычного стилирования элемента-хоста.
<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, который делегирует фокус первому фокусируемому элементу в дереве, если выбран нефокусируемый элемент в дереве.
<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> при фокусировке на нём.
div:focus { border: 2px solid red; }
Результаты показаны ниже. При первом отображении HTML элементы не имеют стилей, как показано на первом изображении. Для корня тени, у которого не установлен shadowrootdelegatesfocus атрибут, вы можете кликнуть в любом месте, кроме <input>, и фокус не изменится (если вы выберете элемент <input>, то это будет выглядеть как на втором изображении).
Для корня тени, у которого установлен shadowrootdelegatesfocus атрибут, нажатие на текст (который не фокусируется) выбирает элемент <input>, так как это первый фокусируемый элемент в дереве. Это также фокусирует родительский элемент, как показано ниже.
Избегание проблем с DocumentFragment
Когда передаётся значение DocumentFragment, методы Node.appendChild и аналогичные перемещают только дочерние узлы этого значения в целевой узел. Поэтому обычно предпочтительнее прикреплять обработчики событий к дочерним элементам DocumentFragment, а не к самому DocumentFragment.
Рассмотрим следующий HTML и JavaScript:
HTML
<div id="container"></div> <template id="template"> <div>Click me</div> </template>
JavaScript
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