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

页面刷新后LocalStorage存储的Todo列表消失,新增项后恢复的问题

问题排查与解决

问题根源

  1. 页面初始化未渲染本地存储数据:读取LocalStorage后,没有调用addToDOM()将数据渲染到页面,导致刷新后DOM为空,但todoList实际已加载了本地数据,新增项时调用addToDOM()才会把所有数据渲染出来。
  2. LocalStorage无数据时的空值处理缺失:当LocalStorage中不存在todo键时,JSON.parse()会返回null,此时todoList被赋值为null,后续调用数组方法(如includes、push)会报错。
  3. DOM渲染未清空旧元素:addToDOM()每次调用都直接在容器末尾追加元素,未先清空原有内容,导致重复渲染(比如删除后调用addToDOM()会重复添加剩余项)。
  4. 删除逻辑存在缺陷:使用待办项的值进行过滤删除,若存在重复内容的待办项,会误删所有相同值的项,而非仅删除目标项。

修复方案

针对上述问题,逐一修改代码:

  1. 初始化时处理空值并调用渲染函数
    将todoList的初始化改为:

    let todoList = JSON.parse(window.localStorage.getItem("todo")) || [];
    

    并在定义addToDOM后立即调用:

    addToDOM();
    
  2. 修改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);
      }
    };
    
  3. 修复删除逻辑,按索引过滤
    将删除时的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:55:18