页面刷新后LocalStorage存储的Todo列表消失,新增项后恢复的问题
问题排查与解决
问题根源
- 页面初始化未渲染本地存储数据:读取LocalStorage后,没有调用
addToDOM()将数据渲染到页面,导致刷新后DOM为空,但todoList实际已加载了本地数据,新增项时调用addToDOM()才会把所有数据渲染出来。 - LocalStorage无数据时的空值处理缺失:当LocalStorage中不存在
todo键时,JSON.parse()会返回null,此时todoList被赋值为null,后续调用数组方法(如includes、push)会报错。 - DOM渲染未清空旧元素:
addToDOM()每次调用都直接在容器末尾追加元素,未先清空原有内容,导致重复渲染(比如删除后调用addToDOM()会重复添加剩余项)。 - 删除逻辑存在缺陷:使用待办项的值进行过滤删除,若存在重复内容的待办项,会误删所有相同值的项,而非仅删除目标项。
修复方案
针对上述问题,逐一修改代码:
初始化时处理空值并调用渲染函数
将todoList的初始化改为:let todoList = JSON.parse(window.localStorage.getItem("todo")) || [];并在定义
addToDOM后立即调用:addToDOM();修改
addToDOM函数,先清空容器
在循环渲染前添加todos.innerHTML = "",避免重复渲染:const addToDOM = () => { todos.innerHTML = ""; // 清空旧内容 for (let i = 0; i < todoList.length; i++) { const html = ` <div class="todo" id=${i}> <p class="todo-text" >${todoList[i]}</p> <i class="fa-solid fa-check" ></i> <i class="fa-solid fa-trash"></i> </div> `; todos.insertAdjacentHTML("beforeend", html); } };修复删除逻辑,按索引过滤
将删除时的filter改为按索引判断,确保只删除目标项:todoList = todoList.filter((_, index) => index !== elementID);
完整修复后的代码
const input = document.querySelector("input"); const button = document.querySelector("button"); const todos = document.querySelector(".todos"); const alertRed = document.querySelector(".alert-red"); // 初始化todoList,处理LocalStorage为空的情况 let todoList = JSON.parse(window.localStorage.getItem("todo")) || []; const saveToLocal = (array) => { window.localStorage.setItem("todo", JSON.stringify(array)); }; const addToDOM = () => { todos.innerHTML = ""; // 清空旧内容,避免重复渲染 for (let i = 0; i < todoList.length; i++) { const html = ` <div class="todo" id=${i}> <p class="todo-text" >${todoList[i]}</p> <i class="fa-solid fa-check" ></i> <i class="fa-solid fa-trash"></i> </div> `; todos.insertAdjacentHTML("beforeend", html); } }; // 页面初始化时渲染本地存储的待办项 addToDOM(); // Add items to list button.onclick = (e) => { e.preventDefault(); if (!todoList.includes(input.value) && input.value !== "") { todoList.push(input.value); saveToLocal(todoList); } addToDOM(); input.value = ""; }; // Handle Enter Press document.onkeypress = (e) => { if (e.key === "Enter") { button.click(); } }; todos.onclick = (e) => { e.preventDefault(); const isCheck = e.target.classList.contains("fa-check"); const isTrash = e.target.classList.contains("fa-trash"); if (isCheck) e.target.previousElementSibling.classList.toggle("checked"); if (isTrash) { const element = e.target.parentElement; const elementID = parseInt(element.id); element.classList.add("removed"); // 按索引过滤,仅删除目标项 todoList = todoList.filter((_, index) => index !== elementID); saveToLocal(todoList); setTimeout(() => { addToDOM(); }, 300); } };
内容的提问来源于stack exchange,提问作者Arash Kazerooni
相关产品推荐
相关产品推荐

