HTML<template>元素允许我们在普通的HTML流程中删除可重复使用的代码模板,这些模板不会立即呈现,但可以在以后使用。
<template id="book-template">
<li><span class="title"></span> — <span class="author"></span></li>
</template>
<ul id="books"></ul>
上面的示例在脚本使用模板之前不会呈现任何内容。
const fragment = document.getElementById('book-template');
const books = [
{ title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
{ title: 'A Farewell to Arms', author: 'Ernest Hemingway' },
{ title: 'Catch 22', author: 'Joseph Heller' }
];
books.forEach(book => {
// Create an instance of the template content
const instance = document.importNode(fragment.content, true);
// Add relevant content to the template
instance.querySelector('.title').innerHTML = book.title;
instance.querySelector('.author').innerHTML = book.author;
// Append the instance ot the DOM
document.getElementById('books').appendChild(instance);
});
真正的魔法发生在document.importNode方法中。此函数将创建模板的副本,content并准备将其插入到另一个文档(或文档片段)中。函数的第一个参数抓取模板的内容,第二个参数告诉浏览器对元素的DOM子树(即其所有子节点)进行深层复制。
我们可以template.content直接使用它,但是这样做我们将从元素中删除内容并稍后附加到文档的主体。任何DOM节点只能在一个位置连接,因此后续使用模板的内容将导致空文档片段(基本上为空值),因为之前已移动了内容。使用document.importNode允许我们在多个位置重用相同模板内容的实例。
然后将该节点附加到document.body用户并为其呈现。这最终使我们能够做有趣的事情,比如为我们的用户提供用于创建内容的模板。
关于模板的一个有趣的事情是它们可以包含任何 HTML。这包括脚本和样式元素。一个非常简单的示例是一个模板,它附加一个按钮,在单击它时会提醒我们。
<template id="template">
<script>
const button = document.getElementById('click-me');
button.addEventListener('click', event => alert(event));
</script>
<style>
#click-me {
all: unset;
background: tomato;
border: 0;
border-radius: 4px;
color: white;
font-family: Helvetica;
font-size: 1.5rem;
padding: .5rem 1rem;
}
</style>
<button id="click-me">Log click event</button>
</template>