标签完全游离于标准渲染流水线之外,不参与 dom 构建、不触发样式计算、不进入渲染树;其内容仅为静态 documentfragment,须通过 clonenode(true) 或 importnode() 显式克隆后才激活并进入后续流程。

HTML <template></template> 标签在渲染流水线中处于什么位置
<template></template> 不参与 DOM 构建、不触发样式计算、不进入渲染树,它被浏览器解析器直接跳过——既不生成节点,也不执行内联脚本或加载图片。它的内容只在 JS 显式调用 document.importNode() 或 cloneNode(true) 时才“激活”并进入后续流程。这意味着:它完全游离于标准渲染流水线(DOM → CSSOM → Render Tree → Layout → Paint)之外,是纯静态的 DOM 片段容器。
为什么直接 innerHTML = template.innerHTML 会破坏表单状态
因为 template.innerHTML 返回的是字符串,赋值给其他元素的 innerHTML 会触发全新 HTML 解析,所有 <input checked>、<select></select> 选中项、<textarea></textarea> 光标位置等运行时状态全部丢失。正确做法是:
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
- 用
document.importNode(tmpl.content, true)克隆文档片段(保留表单控件状态、selected属性、value值) - 避免在模板里写
<script></script>——克隆后不会自动执行,需手动eval()或appendChild()脚本节点 - 若模板含
<style></style>,插入后不会自动生效,得靠 JS 注入或提前挂载到
<template></template> 填充数据时常见的 XSS 风险点
手动填充时,容易把用户输入直接塞进 innerHTML,比如 node.innerHTML = data.content。这会执行任意 HTML/JS,哪怕模板本身是静态的。安全做法是:
- 对纯文本内容一律用
textContent(如el.textContent = data.title) - 若必须支持富文本,先用 DOMPurify 等库清洗,再设
innerHTML - 禁止模板内使用
{{ }}或v-bind:这类框架语法——原生 HTML 不识别,也不会报错,只会原样显示 - 不要在
data-bind值里拼接 JS 表达式,比如data-bind="onclick:doSomething()",这无法自动绑定
多次复用同一个 <template></template> 时最容易忽略的 ID 冲突
模板里写 <div id="card-1">,克隆三次就会产生三个相同 ID 的元素。后果包括:<code>document.getElementById() 只返回第一个、CSS 选择器 #card-1 生效不可控、aria-labelledby 等可访问性属性失效。解决方式很简单:
- 模板中禁用
id,改用data-id或data-bind - 克隆后由 JS 动态生成唯一 ID 并设到对应节点上(如
fragment.querySelector('[data-bind="root"]').id = 'card-' + Date.now()) - 若用作 Web Component 模板,优先走 Shadow DOM,天然隔离 ID 作用域
真正难处理的不是怎么克隆,而是克隆之后要不要缓存节点、何时更新、是否要监听数据变化——这些都得自己写,<template></template> 本身不提供任何响应式能力。










