template - garevna/js-course GitHub Wiki
Элемент <template> предназначен для хранения шаблона разметки
Он не отображается на странице
Он парсится браузером, поэтому должен содержать только валидный код разметки
это фрагмент документа, у которого нет родителя в дереве DOM
DocumentFragment содержит DOM-элементы ( nodes ), как и объект document
Но поскольку фрагмент документа не является частью структуры DOM, он не отображается на странице
Это шаблон разметки, который при необходимости может быть вставлен в нужное время в нужном месте
Откроем вкладку Elements инструментов разработчика и вставим в элемент body следующий код разметки:
<body>
<template id="sample">
<h3>Template header</h3>
<p>Template text</p>
</template>
</body>При этом на странице ничего не появится, а вот во вкладке Elements мы увидим следующую картинку
▼ <template id="sample">
▼ #document-fragment
<h3>Template header</h3>
<p>Template text</p>
</template>Свойство content элемента template содержит код разметки, находящийся в контейнере <template>...</template>
<template id="svg">
<svg width="400" height="400">
<circle cx="200" cy="200"
r="100"
fill="transparent"
stroke="red"
style="stroke-width:5">
</circle>
</svg>
</template>Выведем в консоль свойство content
const circle = document.querySelector ( "#svg" )
console.dir ( circle.content )▼ #document-fragment
baseURI: "about:blank"
childElementCount: 2
► childNodes: NodeList(5) [text, h3, text, p, text]
► children: HTMLCollection(2) [h3, p]
► firstChild: text
► firstElementChild: h3
isConnected: false
► lastChild: text
► lastElementChild: p
nextSibling: null
nodeName: "#document-fragment"
nodeType: 11
nodeValue: null
► ownerDocument: document
parentElement: null
parentNode: null
previousSibling: null
textContent: "↵ Template header↵ Template text↵ "
► __proto__: DocumentFragmentЕсли выполнить код:
document.body.appendChild ( circle.content )то после вставки в DOM содержимого шаблона контейнер <template id="svg"></template> будет пустым
Можно проверить это:
console.dir ( circle.content )Свойство childNodes будет NodeList [ ] ( пустая коллекция узлов )
Свойство children будет HTMLCollection [ ] ( пустая коллекция элементов )
document.body.appendChild ( circle.content.cloneNode ( true ) )<template id="sample">
<style>
svg { border: dotted 1px; }
circle { stroke-width:5; }
</style>
<svg width="400" height="400" id="svg">
<circle cx="200" cy="200" r="100"
id="circle"
fill="transparent"
stroke="red">
</circle>
</svg>
</template>class CanvasElement extends HTMLElement {
constructor () {
super()
var shadow = this.attachShadow ( { mode: 'open' } )
var sample = document.querySelector ( "#sample" )
shadow.appendChild ( sample.content )
}
}
customElements.define ( 'canvas-element', CanvasElement )<canvas-element></canvas-element>Теперь давайте все сделаем на чистом JS:
const template = document.body.appendChild (
document.createElement ( "template" )
)
template.innerHTML = `
<style>
.red { color: red; }
.div { width: 100px; height: 50px; border: solid 1px green; }
</style>
<div class="div"></div>
<p class="red">Hello!</p>
`
customElements.define( 'sample-element',
class extends HTMLElement {
constructor() {
super()
const shadowRoot = this.attachShadow({ mode: 'open' })
.appendChild( template.content.cloneNode(true) )
}
})Теперь вы можете сколько угодно раз вставить на страницу:
document.body.appendChild (
document.createElement ( "sample-element" )
)Жутко удобно, правда ? 
<template>
1