最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何通过HTML模板实现列表项的动态生成
时间:2026-07-01 11:12:51 编辑:袖梨 来源:一聚教程网
应使用 createElement + textContent 防 XSS,模板字符串仅作结构骨架;优先用 template 标签配合 cloneNode(true) 渲染列表;高频渲染需通过 DocumentFragment 批量插入;响应式可用 renderList 封装全量重绘。
模板字符串里怎么插变量才不会被当成纯文本
直接用 innerHTML 拼接字符串时,如果变量含 HTML 字符(比如 <、"),会破坏结构甚至引发 XSS。必须先转义再插入,或改用更安全的方案。
推荐用 document.createElement + textContent 组合:对每个字段单独设 textContent,天然防注入;若真需渲染富文本,用 DOMPurify.sanitize() 处理后再塞进 innerHTML。
- 避免写
item.innerHTML = `<li>${name}</li>`——name是用户输入就危险 - 正确做法:
const li = document.createElement('li'); li.textContent = name; - 模板字符串只用于结构骨架,不掺变量:
const template = `<ul class="list"></ul>`
template 标签和 innerHTML 哪个更适合列表批量渲染
<template> 是浏览器原生支持的离线 DOM 容器,内容不渲染、不执行脚本、不加载资源,适合做可复用的列表项模板。比拼接字符串再 innerHTML 更可靠,尤其在需要绑定事件或保留子节点状态时。
但注意:<template> 内容必须用 content.cloneNode(true) 复制,直接 appendChild 会移动节点而非复制。
立即学习“前端免费学习笔记(深入)”;
- 定义模板:
<template id="item-template"><li class="item"><span class="title"></span></li></template> - 取模板:
const tmpl = document.getElementById('item-template').content; - 填充并追加:
const el = tmpl.cloneNode(true); el.querySelector('.title').textContent = item.title; list.appendChild(el); - 别漏掉
true参数,否则只克隆顶层<template>节点
循环渲染时如何避免重复创建 DOM 节点
每次新增一项都调用 createElement 或克隆 <template> 是安全的,但高频操作(如滚动加载上千条)会导致卡顿。关键不是“少创建”,而是“少触发重排重绘”。
把所有新节点先塞进 DocumentFragment,最后一次性 append 到目标容器,能显著减少 layout 回流次数。
- 错误示范:
items.forEach(item => list.appendChild(createItem(item)));—— 每次 append 都可能触发重排 - 正确做法:
const frag = document.createDocumentFragment(); items.forEach(item => frag.appendChild(createItem(item))); list.appendChild(frag); - 如果用
<template>,同样先往frag里 append 克隆节点,最后再挂载
Vue/React 风格的响应式列表在原生 JS 里怎么模拟
原生没有响应式数据绑定,但可以用 Proxy 监听数组变化,配合模板自动更新 DOM。不过要注意:数组方法如 push、splice 不会触发 set,得重写或用 Reflect.set + 手动通知。
更务实的做法是封装一个 renderList 函数,接收数据数组和渲染函数,每次数据变就全量重绘——只要列表不超过几百项,性能完全够用。
- 简单封装示例:
function renderList(container, data, renderItem) { container.innerHTML = ''; data.forEach(item => container.appendChild(renderItem(item))); } - 调用时传入已编译好的节点:
renderList(listEl, items, item => createItem(item)); - 不要试图监听
Array.prototype.push——改写原型易出兼容问题,且无法捕获字面量赋值
<template> 适合结构固定、字段不多的列表;一旦涉及条件分支(比如不同状态显示不同子组件)、嵌套列表或复杂交互,手写模板很快失控,这时候该上轻量框架或自定义 element 了。
相关文章
- 洛克王国世界画精灵怎么进化的 07-03
- 百战天虫测试资格预约入口 百战天虫公测时间及参与方式 07-03
- kimi网页版入口官网 07-03
- 《千年寻仙》元素师职业玩法介绍 07-03
- 夸克浏览器如何拦截弹窗 07-03
- 异环最新兑换码大全汇总 07-03