template标签不渲染dom,必须用clonenode(true)克隆content才能重复使用,否则content被移走后为空;直接appendchild(content)只生效一次,且ie完全不支持需polyfill。

template标签本身不渲染DOM,但必须手动克隆才能使用
<template></template> 标签的内容在解析时不会被添加到 DOM 中,也不会执行其中的脚本或加载图片等资源。它只是个“存储容器”,内容处于文档外(document.adoptNode 之前)且不可见。直接 querySelector 到 <template></template> 内部元素也拿不到实际节点——因为那些节点还没被插入、也没被克隆。
常见错误是这样写:
<template id="item"><div class="card"><span>{{name}}</span></div>
</template><script>
const tmpl = document.querySelector('#item');
// ❌ 错误:tmpl.content 是 DocumentFragment,但直接 append 它会移动节点(只生效一次)
document.body.appendChild(tmpl.content); // 第二次调用就空了
</script>
- 每次使用必须调用
tmpl.content.cloneNode(true),否则content被移走后就为空 -
cloneNode(true)是深克隆,保留所有子节点和事件绑定(但内联事件如onclick不会重绑定,需手动处理) - 不要试图对
<template></template>直接innerHTML赋值——它不支持写入,会静默失败
template + innerHTML 混用容易导致 XSS 和逻辑错乱
有人习惯把 <template></template> 当成字符串模板,先取 innerHTML,再 replace 占位符,最后 insertAdjacentHTML 插入。这绕过了 <template></template> 的安全优势,且破坏了 DOM 结构完整性。
正确做法是:先克隆 content,再操作节点本身:
const tmpl = document.querySelector('#item');
const instance = tmpl.content.cloneNode(true);
instance.querySelector('span').textContent = '张三'; // ✅ 安全、可预测
document.body.appendChild(instance);
- 避免用
innerHTML += ...或insertAdjacentHTML处理<template></template>内容,否则丢失原生 DOM 节点引用、事件监听器失效 - 若需动态生成结构,优先用
document.createElement+appendChild,而非拼接字符串——<template></template>的价值在于复用已有 DOM 片段,不是字符串占位器 - 注意
textContentvsinnerHTML:前者防 XSS,后者可能执行 script 或解析 HTML,除非你明确信任数据源
template 在 Shadow DOM 和 Web Components 中必须用 cloneNode
在自定义元素中,<template></template> 常作为 shadow root 的模板来源。如果直接 shadowRoot.appendChild(template.content),后续实例化时会报错或显示空白——因为 content 只能被移动一次。
- 每个组件实例都应调用
template.content.cloneNode(true),否则多个实例共享同一份节点引用,导致 DOM 错乱 - Chrome/Firefox 对重复使用
template.content有不同行为:Firefox 更严格,直接报错;Chrome 允许但内容为空,容易误判为逻辑问题 - Shadow DOM 中无法用
querySelector跨越影子边界访问<template></template>内部节点,必须在克隆后、附加前操作
IE 不支持 template 标签,需 fallback 或 polyfill
IE 所有版本完全忽略 <template></template> 标签,把它当成普通未知元素,其内容会意外渲染出来——这是最常被忽略的兼容性坑。
- 检测方式:用
document.createElement('template').content !== undefined判断是否支持 - 简单 fallback:把
<template></template>改成<script type="text/template"></script>,读取textContent后用DOMParser解析,但注意 XSS 风险 - 生产环境建议用
template-polyfill(轻量级),它会在不支持时自动将<template></template>内容设为display: none并提供兼容的content属性
真正麻烦的不是怎么写,而是忘记 cloneNode —— 它不像函数调用那样报错,而是在第二次使用时静默失效,调试起来非常隐蔽。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











