HTML 模板
在 Web 组件之前,一直缺少基于 HTML 解析构建 DOM 子树,然后在需要时再把这个子树渲染出 来的机制。
一种间接方案是使用 innerHTML 把标记字符串转换为 DOM 元素,但这种方式存在严重的 安全隐患。
另一种间接方案是使用 document.createElement()构建每个元素,然后逐个把它们添加 到孤儿根节点(不是添加到 DOM),但这样做特别麻烦,完全与标记无关。
更好的方式是提前在页面中写出特殊标记,让浏览器自动将其解析为 DOM 子树,但跳过渲
视频讲解
染。这正是 HTML 模板的核心思想,而标签正是为这个目的而生的。
在浏览器中渲染时,上面例子中的文本不会被渲染到页面上。 因为的内容不属于活动
文档,所以 document.querySelector()等 DOM 查询方法不会发现其中的 标签。 获取这个标签,这个标签不在DOM里面 我们想以最快的方式给某
个 HTML 元素添加多个子元素。如果连续调用 document.appendChild(),则不仅费事,还会导致多
次布局重排。 而使用 DocumentFragment 可以一次性添加所有子节点,最多只会有一次布局重排 还可以添加并执行<template id="foo">
<p>I'm inside a template!</p>
</template>
使用 DocumentFragment
const fragment = document.querySelector('#foo').content;
console.log(document.querySelector('p')); // null
console.log(fragment.querySelector('p')); // <p>...<p>
快速添加大量子元素
const fragment = new DocumentFragment();
const foo = document.querySelector('#foo');
// 为 DocumentFragment 添加子元素不会导致布局重排
fragment.appendChild(document.createElement('p'));
fragment.appendChild(document.createElement('p'));
fragment.appendChild(document.createElement('p'));
console.log(fragment.children.length); // 3
// 1、转移
foo.appendChild(fragment);
// 转移后就空了
console.log(fragment.children.length); // 0
// 2、拷贝
foo.appendChild(document.importNode(fragment, true));
console.log(fragment.children.length); // 3