template标签是浏览器原生惰性DOM容器,内容存于只读content属性(DocumentFragment),须cloneNode(true)后插入并手动初始化状态、事件及ID。

template 标签不是黑科技,是浏览器原生支持的惰性 DOM 片段容器——它不渲染、不执行、不加载,但必须用 content.cloneNode(true) 才能真正“活过来”。直接塞进页面、读 innerHTML 或反复 appendChild(template.content) 都会静默失败。
为什么 template.innerHTML 总是空字符串
因为 template 的内容被浏览器解析后,全部存进只读的 content 属性(类型为 DocumentFragment),而非作为子节点挂在元素上。所以:
-
template.children返回空NodeList -
template.firstElementChild是null -
template.innerHTML永远返回""
正确路径只有一条:template.content → .cloneNode(true) → 插入目标容器。
克隆后必须手动初始化表单控件和事件
模板里的 <input value="a"> 克隆出来还是 value="a",但不会反映用户当前输入;onclick 属性无效,addEventListener 更不会自动绑定。
立即学习“前端免费学习笔记(深入)”;
- 克隆后需重置状态:
clone.querySelector('input').value = '' - 必须重新绑定事件:
clone.querySelector('button').addEventListener('click', handler) - ID 不能复用:克隆后要改掉
id,否则破坏唯一性,影响document.getElementById或 CSS 选择器 - 避免内联样式和
<style>:它们在template里不生效,且插入 light DOM 后可能全局污染
重复使用 template 必须每次都 cloneNode(true)
template.content 是一个 DocumentFragment,只能被插入一次。第二次 appendChild(template.content) 会静默失败——它已被移走,不是复制。
- 错:
container.appendChild(template.content)(仅第一次有效) - 对:
container.appendChild(template.content.cloneNode(true)) - 不加
true只克隆顶层 fragment,子节点全丢,基本不可用 - 批量插入时,建议先克隆多个到一个临时
DocumentFragment,再一次性append,减少重排
IE 不支持 template,别硬扛
IE 完全没实现 template,连 document.createElement('template').content 都是 undefined。强行 polyfill 补 content 和 cloneNode 行为,容易漏边角逻辑。
- 现代项目默认放弃 IE,这是合理取舍
- 真要兼容,不如构建时预编译成字符串模板(如用
<script type="text/template">),或直接用innerHTML+DOMParser - 注意:
<script type="text/template">是纯文本,无 HTML 解析校验,易 XSS,且编辑器无法提示嵌套错误
最常被忽略的一点:你写的不是“模板语法”,而是“待命的 DOM 结构”——它不解析变量、不响应数据变化、不自动更新。所有动态逻辑,都得靠 JS 一行行手动填、手动绑、手动清。



















