template标签是不渲染的占位容器,用于javaScript动态克隆纯净html片段;其content属性返回DocumentFragment,须用clonenode(true)复用,innerHTML为空字符串。

template 标签本质是“不渲染的占位容器”
它不是为了直接展示,而是为后续 javascript 动态克隆提供干净、无副作用的 HTML 片段。浏览器解析时会跳过 内部内容,既不执行脚本、不加载图片,也不触发布局或样式计算——这点和 或隐藏的
有根本
区别。
必须用 content 属性 + cloneNode 才能真正复用
直接取 template 元素的 innerHTML 会得到空字符串;正确路径是访问其 content 属性(一个 DocumentFragment),再用 cloneNode(true) 复制:
const tmpl = document.querySelector('#item-tmpl'); const instance = tmpl.content.cloneNode(true); document.body.appendChild(instance);
-
tmpl.content 是只读的,不能直接 appendChild 到页面,必须 clone
-
cloneNode(true) 深拷贝所有子节点,包括事件监听器(如果有的话)不会被复制,需手动绑定
- 若模板含
,仅在作为自定义元素模板时生效,独立使用时 会被忽略
常见误用:当成普通 dom 容器直接 innerHTML 插入
以下写法无效且易引发困惑:
const tmpl = document.querySelector('#item-tmpl'); document.body.innerHTML += tmpl.innerHTML; // ❌ tmpl.innerHTML 是空字符串
错误现象:页面什么也没出现,控制台无报错,但逻辑卡死在“以为拿到了 HTML 字符串”。
立即学习“前端免费学习笔记(深入)”;
- 原因:
的内容不在主文档树中,innerHTML 不反序列化 content
- 替代方案:真要字符串操作,应提前用
template.outerHTML 提取原始 HTML,再用 DOMParser 解析,但失去 content 的纯净性优势
- 性能提示:频繁 cloneNode 比 innerHTML + createElement 组合稍重,但胜在结构安全、无 xss 风险
与现代框架模板机制的本质区别
是原生、静态、无响应式的——它不编译表达式,不追踪数据变化,也不自动更新 DOM。它只解决“一次生成、多次实例化”的基础需求。
- vue 的
是编译时指令占位符,最终不产出真实 DOM 节点
- react 的 jsX 本质是 JS 函数调用,与 HTML
无任何实现关联
- 若需响应式,必须配合手动监听 + 替换子节点,例如用
textContent 更新文本,或用 dataset 绑定状态
真正容易被忽略的是: 内的
和 标签虽不执行,但依然会被解析并计入文档资源计数——上线前记得清理无用样式或脚本引用。