必须用 template.content.clonenode(true) 克隆模板,因 template.content 是唯一可操作的只读 documentfragment 入口;填值用 textcontent/value 而非 innerhtml 防 xss;批量插入需经 documentfragment 中转以避免重排重绘。

直接用 template.content.cloneNode(true) 是唯一稳定、可复用的路径,其他方式在渲染第二条数据时大概率静默失败。
必须从 template.content 克隆,不能碰 innerHTML
template 的内容被封装在只读的 DocumentFragment 中:
• template.innerHTML 永远返回空字符串
• template.children 是空 NodeList
• template.textContent 只返回带缩进的纯文本,无法操作结构
所有操作必须通过 template.content 进入,这是唯一合法入口。
克隆必须用 cloneNode(true),浅克隆或不克隆都出问题
常见错误现象包括:第二次渲染空白、所有项显示相同数据、输入框光标丢失、表单值没更新但 DOM 看起来“填进去了”——根本原因如下:
- 直接
appendChild(template.content)是移动语义:第一次调用后,template.content就为空了 -
cloneNode(false)只克隆顶层元素,子节点、事件监听器、表单当前值(如 input 光标位置、select 选中项)全部丢失 - 只有
cloneNode(true)才能深克隆全部子节点、属性、文本和实时表单状态
填值优先用 textContent 和 value,别碰 innerHTML
用 innerHTML 填用户数据等于主动引入 XSS 风险,还会清空已绑定的事件监听器(比如模板里写好的 onclick 或手动加的 addEventListener):
- 纯文本内容 →
cloned.querySelector('.title').textContent = data.title - 表单控件 →
cloned.querySelector('input').value = data.inputValue(不是 textContent) - 需渲染富文本?先对输入做 HTML 转义(如
text.replace(/&/g, '&')),再塞进innerHTML - 模板含
<script></script>或<style></style>?克隆后它们依然不执行、不生效——别指望“活”过来
批量插入必须走 DocumentFragment 中转
循环中每轮都 container.appendChild(cloned),浏览器就得反复重排重绘,性能会快速恶化:
- 100 条数据就可能明显卡顿
- 500 条基本卡死
- 正确做法:创建
const frag = document.createDocumentFragment() - 循环体内:克隆 → 填值 →
frag.appendChild(cloned) - 循环结束后,只调一次
container.appendChild(frag)
frag 是轻量中间容器,不在主 DOM 树中,不能被 querySelector 查到,放心使用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











