
本文讲解如何使用 javascript 将 json 数组中的每一项,按索引顺序精准注入到页面中具有相同 class(如 `.fun`)的多个 div 中,并动态设置 `data-id` 属性与插入结构化内容。
在实际开发中,我们常需将结构化数据(如电影列表)批量渲染到一组语义相同但需独立标识的 DOM 容器中。此时若错误地嵌套循环(如对每个数据项遍历全部 DOM 节点),极易导致状态覆盖、逻辑错位或性能浪费——正如原问题中 dataset.id 被反复赋值最终仅保留最后一个值的问题。
推荐方案:基于索引的单层映射
核心思路是:确保 data 数组与目标 DOM 元素集合(通过 document.querySelectorAll('.fun') 获取)长度一致且顺序一一对应,直接用 for 循环按索引同步写入,避免冗余判断和闭包陷阱。
✅ 正确实现如下:
const data = [
{
"id": 1,
"movie_name": "last holiday",
"date": "2023-10-29",
"length": ["1 hour 30"]
},
{
"id": 2,
"movie_name": "pitch perfect",
"date": "2023-04-24",
"length": ["2 hours"]
}
];
const funElements = document.querySelectorAll('.fun');
// 确保数据数量 ≤ DOM 元素数量,防止越界
for (let i = 0; i < data.length && i < funElements.length; i++) {
const item = data[i];
const el = funElements[i];
// 设置 data-id 属性
el.dataset.id = item.id;
// 插入结构化内容(注意:原需求中输出为 /,此处按示例保持语义一致性)
el.insertAdjacentHTML('beforeend', `
${item.movie_name}
${item.date}
`);
}
? 关键注意事项:
- ✅ 不要用 forEach + for 嵌套遍历:这会导致每个 data 项都尝试匹配所有 .fun 元素,引发重复写入与 dataset.id 覆盖;
- ✅ 优先使用 for (let i = 0; ...) 而非 for...in:for...in 遍历对象属性(含原型链),不适用于数组索引;for...of 或传统 for 更安全;
- ✅ 增加边界校验:i
- ✅ insertAdjacentHTML 是安全高效的插入方式:它不会重绘整个元素,且天然支持 HTML 字符串模板;
- ⚠️ ID 属性唯一性原则:虽然本例使用 data-id(合法自定义属性),但切勿将 id="1" 直接设为元素 ID —— ID 必须全局唯一且不能纯数字。
? 进阶建议:
若数据与 DOM 数量不一致(如后端返回 5 条,但页面只预留 3 个 .fun),可配合 Array.from(funElements).slice(0, data.length) 或动态创建缺失容器;若需双向绑定或响应式更新,建议迁移到轻量框架(如 Alpine.js)或使用 MutationObserver 监听变化。
此方法简洁、高效、可预测,是处理“同构容器 + 序列化数据”场景的最佳实践。










