localStorage数据正常但添加元素时DOM容器出现重复渲染问题
问题根因
页面出现重复元素、localStorage数据正常的核心原因是createElement()渲染逻辑存在缺陷:每次调用该函数时,没有清空容器内已存在的旧DOM节点,只是在现有内容的末尾持续追加新创建的元素。
- 页面首次加载时调用
createElement(),容器为空,渲染结果和localStorage存储数据一致 - 点击添加按钮后,新数据被push进数组,此时调用
createElement()会遍历全量数组数据重新生成所有DOM节点追加到容器中,之前已经渲染过的旧节点不会被删除,因此页面上会出现重复元素 - 后续每次点击添加,都会重复执行「全量遍历生成节点+末尾追加」的逻辑,重复元素会越来越多
- 刷新页面时
createElement()仅在初始化阶段执行1次,没有重复追加的操作,因此只会渲染和数组长度匹配的正确内容,重复元素消失。
另外代码里还存在一个逻辑bug:判断是否允许提交的条件if (title || id)中,id是Date.now()生成的时间戳,永远为真值,即使用户没有输入任何内容,也会往数组中插入空title的无效数据。
修复方案
方案1(改动最小):每次渲染前清空容器
修改createElement函数,在遍历生成新节点前先清除容器内所有旧内容:
function createElement() { // 清空容器已有内容 container.innerHTML = ''; array.forEach((arr, id) => { let div = document.createElement("div"); div.classList.add("div"); div.id = id; div.innerHTML = arr.title; container.appendChild(div); }); }
同时修复空值判断逻辑,把点击事件里的判断条件改成:
// 仅当输入内容非空时才允许提交 if (title) { // 原有业务逻辑 }
方案2(性能更优):仅追加新增元素
不需要每次点击都重绘整个列表,点击添加时只生成新条目对应的DOM节点插入容器即可,避免全量重绘的开销:
button.addEventListener("click", (e) => { e.preventDefault(); let title = input.value.trim(); // 空输入直接拦截 if (!title) return; let id = Date.now(); let arrayInfo = { title, id }; if (!isUpdate) { array.push(arrayInfo); // 仅创建新添加条目的DOM let div = document.createElement("div"); div.classList.add("div"); div.id = array.length - 1; div.innerHTML = title; container.appendChild(div); // 提交后清空输入框 input.value = ''; } else { isUpdate = false; } localStorage.setItem("array", JSON.stringify(array)); });
内容的提问来源于stack exchange,提问作者beginner
相关产品推荐
相关产品推荐

