元素内容需克隆后使用,直接操作会清空源;必须用content.cloneNode(true)深克隆,再修改textContent或dataset;注意判空、防XSS,跨文档才需importNode。
浏览器遇到 时会解析其内容但不将其加入

document.querySelector('template').content 只能得到一个 DocumentFragment,它不能被重复插入——每次插入后自动清空。所以「克隆」不是可选项,而是必须步骤。
content.cloneNode(true) 才能安全复用直接操作 template.content 会导致后续调用失败,因为它的节点只属于一次插入。正确做法是每次使用前都调用 cloneNode(true) 深拷贝整个 fragment。
true 表示深克隆(含所有子节点),false 只克隆 fragment 自身,无实际意义textContent 或设置 dataset
content 做任何 appendChild 或 innerHTML 修改,那会污染模板源const tmpl = document.querySelector('#item-tmpl');
const instance = tmpl.content.cloneNode(true);
instance.querySelector('.title').textContent = '新标题';
instance.querySelector('.id').dataset.id = '123';
document.body.appendChild(instance);
content 是否为空如果 内容为空、或被 JS 清空过,content 下可能没有子节点,querySelector 会返回 null,导致脚本报错。
instance.children.length > 0
instance.querySelector('.title')?.textContent = '...'
template 当普通标签处理,导致内容被提前展开——此时 content 为空,需在客户端重新校验dataset 和文本节点,避免 innerHTML用 innerHTML 插入用户数据有 XSS 风险,且破坏 template 的语义隔离。应把结构固定在模板里,只替换纯文本或自定义属性。
el.textContent = data.desc 或 el.dataset.value = data.id
DOMPurify.sanitize() 处理后再设 innerHTML
document.importNode ——这在跨文档场景(如 iframe、Shadow DOM)才需要;绝大多数页面内使用,cloneNode(true) 已足够。但一旦涉及 Web Component 的 attachShadow,就得留意 fragment 所属文档是否匹配。