You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DOM节点克隆与值填充问题:动态列表仅显示第二个数据项

问题描述

尝试通过克隆<li>元素动态创建列表并填充对应数据,但列表仅显示对象里的第二个数据项,检查代码未找到问题。

原始代码
<ul>
    <li>{name},{price}</li>
</ul>
    
<script>
function loop(node) {

  value = [{
      name: 'Bananas',
      price: '4'
    },
    {
      name: 'Candy',
      price: '2'
    },
    {
      name: 'Oranges',
      price: '2'
    },
    {
      name: 'Vegetables',
      price: '5'
    }
  ]

  let obj = Object.entries(value);
  let len = Object.entries(value).length;

  for (let k = 0; k < value.length; k++) {

    let object = Object.entries(obj[k][1]);

    for (const property in object) {

      let search = `${object[property]}`;
      let values = Object.entries(search.split(','));


      let textName = values[0][1];
      console.log(textName + ':' + values[1][1]);

      let regex = new RegExp("{\s*" + textName + "[0-9]*\s*}", "i");

      if (node.childNodes[k].innerHTML) {
        node.appendChild(node.childNodes[k].cloneNode(true));
        node.childNodes[k].innerHTML = node.childNodes[k].innerHTML.replace(regex, values[1][1]);
      }
    }
  }
}

function nodeParentList() {
  let parentList = [];
  var docElements = document.getElementsByTagName("*")
  for (var i = 0; i < docElements.length; i++) {
    parentList.push(docElements[i]);
  }
  return parentList;
}


var docElements = nodeParentList();
for (var i = 0; i < docElements.length; i++) {
  loop(docElements[i]);
}

</script>
预期效果

最终列表应显示:

  • Bananas,4
  • Candy,2
  • Oranges,2
  • Vegetables,5
问题分析与修正

原始代码核心问题

  1. 全局遍历调用冗余:nodeParentList获取页面所有元素并逐个执行loop,导致<ul>被重复处理,逻辑混乱。
  2. 循环嵌套逻辑错误:内层循环遍历对象的name和price属性,每次循环都克隆<li>,造成重复创建元素,且替换操作互相覆盖。
  3. 子节点索引混乱:每次appendChild后,<ul>的子节点数量动态变化,node.childNodes[k]无法正确定位目标元素。

修正后的代码

<ul>
    <li class="list-template">{name},{price}</li>
</ul>
    
<script>
// 获取目标列表和模板元素
const list = document.querySelector('ul');
const template = document.querySelector('.list-template');

// 数据数组
const items = [
    { name: 'Bananas', price: '4' },
    { name: 'Candy', price: '2' },
    { name: 'Oranges', price: '2' },
    { name: 'Vegetables', price: '5' }
];

// 遍历数据创建列表项
items.forEach(item => {
    // 克隆模板
    const listItem = template.cloneNode(true);
    // 移除模板标识类
    listItem.classList.remove('list-template');
    // 替换占位符
    let html = listItem.innerHTML;
    html = html.replace(/\{name\}/i, item.name);
    html = html.replace(/\{price\}/i, item.price);
    listItem.innerHTML = html;
    // 添加到列表
    list.appendChild(listItem);
});

// 移除原始模板元素
template.remove();
</script>

修正说明

  1. 精准定位元素:直接通过querySelector获取目标<ul>和模板<li>,避免无意义的全局遍历。
  2. 单循环处理数据:遍历数据数组,每个数据项对应生成一个<li>,逻辑清晰直观。
  3. 模板复用与清理:克隆模板后替换占位符,最后移除原始模板,确保页面只保留动态生成的列表项。

内容的提问来源于stack exchange,提问作者MArt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 20:00:13