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
问题分析与修正
原始代码核心问题
- 全局遍历调用冗余:
nodeParentList获取页面所有元素并逐个执行loop,导致<ul>被重复处理,逻辑混乱。 - 循环嵌套逻辑错误:内层循环遍历对象的
name和price属性,每次循环都克隆<li>,造成重复创建元素,且替换操作互相覆盖。 - 子节点索引混乱:每次
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>
修正说明
- 精准定位元素:直接通过
querySelector获取目标<ul>和模板<li>,避免无意义的全局遍历。 - 单循环处理数据:遍历数据数组,每个数据项对应生成一个
<li>,逻辑清晰直观。 - 模板复用与清理:克隆模板后替换占位符,最后移除原始模板,确保页面只保留动态生成的列表项。
内容的提问来源于stack exchange,提问作者MArt
相关产品推荐
相关产品推荐

