html5 template标签循环渲染需手动克隆填充,非响应式;须用content.clonenode(true)获取文档片段,queryselector填值,documentfragment批量插入防重排。

HTML5模板中用template标签做循环渲染,本质是手动克隆+填充,不是Vue那种响应式
浏览器原生template不支持数据绑定或自动循环,它只是个“离线容器”,得靠JS手动取内容、clone、填值、插入。很多人误以为写个template加for就能像框架一样跑起来,结果发现DOM没更新、变量没替换、甚至content为空——那是因为template.content默认不可见,且不自动解析占位符。
常见错误现象:document.querySelector('template').innerHTML返回空字符串;用innerHTML直接拼接字符串进template后,再cloneNode(true)却没生效;循环里反复appendChild但只显示最后一个项。
- 必须用
template.content访问其文档片段,不能用innerHTML或textContent - 每次循环都要调用
content.cloneNode(true),否则所有项会共用同一份节点引用 - 填值推荐用
querySelector找目标元素再改textContent/value,别用innerHTML拼接(XSS风险+破坏事件监听器) - 若模板含
<script></script>或<style></style>,cloneNode(true)不会执行脚本,也不会重复加载样式
用DocumentFragment批量插入,避免频繁重排重绘
直接在循环里对父容器反复appendChild,每轮都触发一次DOM重排,列表一过百条性能就明显卡顿。正确做法是先创建DocumentFragment,把所有克隆好的节点先塞进去,最后一次性append到真实DOM。
使用场景:渲染商品列表、评论流、配置项表格等中等规模静态数据(template不解决无限滚动问题。
立即学习“前端免费学习笔记(深入)”;
-
const frag = document.createDocumentFragment()创建轻量中间容器 - 循环体内:克隆节点 → 填充数据 →
frag.appendChild(cloned) - 循环结束后:
container.appendChild(frag),仅一次真实DOM操作 - 注意:
frag不能被querySelector查到,它不在主DOM树中
template里的data-属性和slot不适用于纯JS循环渲染
想用data-id存原始数据ID,或用slot做内容分发?小心掉坑。原生template在克隆后,data-属性能保留,但不会自动映射成JS对象;而slot机制依赖Shadow DOM,普通template不激活slot插槽逻辑——它只是静态HTML结构。
错误示范:<template><li><slot name="title"></slot></li></template> + cloned.querySelector('[slot="title"]').textContent = 'xxx',实际无效,因为没定义shadowRoot,slot根本没激活。
- 存ID/索引等元信息,用
dataset配合setAttribute更可靠:cloned.querySelector('li').dataset.id = item.id - 需要条件渲染(比如状态不同显示不同图标),在克隆后用
if分支控制classList.toggle或style.display - 别指望
template自带作用域或上下文,所有逻辑都在JS层,模板只是HTML模具
兼容性没问题,但IE11及以下完全不支持template
Chrome 26+、Firefox 22+、Safari 6.1+、Edge 13+ 都支持,但IE全系不识别template标签,document.querySelector('template')返回null,content属性报错。如果项目还要兼容IE,要么降级用script type="text/template"模拟,要么直接放弃template改用字符串模板(如innerHTML += `<li>${item.name}</li>`)。
性能影响:现代浏览器中template比字符串拼接略慢一点(多一次DOM解析),但可读性和安全性高得多;IE方案里字符串拼接要格外防XSS,必须对item.name做textContent式转义(不能只靠replace(/, ')。
- 检测支持:
typeof HTMLTemplateElement !== 'undefined' - IE fallback常用写法:
const tmpl = document.getElementById('list-tmpl') || document.querySelector('script[type="text/template"]') - 用
DOMParser解析字符串模板也能绕过IE限制,但增加复杂度,小项目不如直接字符串拼接+严格转义
template本身能解决的。











