### [HTML template 元素:批量渲染列表的正确做法](https://www.huociguo.com/article/1495)
**Published:** 2026-09-30T04:33:18
**Author:** 米了
**Excerpt:** 重复结构是 template 加 cloneNode,不用字符串拼接 innerHTML。含两段写法对照、四条…
列表、表格这类重复结构,渲染方式决定后续能不能改。字符串拼接 HTML 的写法短期省事,代价集中在三处:插入带尖括号的文本会破坏结构、类名调整要在 JS 里重写整段标签、同一份结构无法在多处复用。`` 元素把这三处问题一并解决。

## 问题写法
```js
list.innerHTML += `${item.name}`;
```
item.name 携带标签字符时会被当成 HTML 解析。每次赋值都要重新解析整段字符串,此前持有的节点引用同时失效。
## 改进写法
```html
```
```js
const tpl = document.getElementById('rowTpl');
const list = document.getElementById('list');
items.forEach((item) => {
const node = tpl.content.cloneNode(true);
node.querySelector('.name').textContent = item.name;
node.querySelector('button').dataset.id = item.id;
list.appendChild(node);
});
```
## 为什么这样改更稳
1. 结构与数据分离。模板留在 HTML 里,类名或层级调整不必改动 JS。
2. 文本走 textContent。标签字符被转义,不产生注入点。
3. 一次解析多次复制。浏览器只在解析源码时处理一遍模板内容,之后均为 cloneNode。
4. 复制结果是真实节点。事件绑定、dataset、自定义属性都能直接使用。
## 注意事项
- template 内的元素不参与渲染,也不出现在 document.querySelector 的结果里,取节点要先读 template.content;
- template 内的 img 不发起请求,适合当作延迟图片的占位;
- tr、td 只有在 table 上下文中才按预期解析,行模板建议整体放入 table 或另行补一层结构;
- cloneNode(true) 的 true 不能省略,省略后只复制顶层节点;
- 复制结果必须 append 到文档,改动才生效;
- 不支持 template 的旧浏览器,降级为 script type=”text/template” 再读取 innerHTML。
## 什么时候不必用
只插入一次的静态片段,用 innerHTML 没有明显损失;结构由后端模板引擎直接输出时,也不需要额外包一层 template。重复渲染、数据来源不可信、DOM 结构需要长期维护这三种场景,才适合换用 template 加 cloneNode。
**Tags:** cloneNode, DOM操作, template元素, 列表渲染, 前端安全
**Categories:** HTML5
---