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

如何刷新页面不丢失新增待办列表项?现有代码问题求助

待办列表localStorage失效问题排查与修复

问题描述

开发待办列表项目时,每次刷新页面都会丢失所有新增列表项,尝试使用localStorage相关代码但无效,附上完整代码请求排查:

原测试用localStorage代码:

window.onbeforeunload = function () {
    localStorage.setItem("list", $("#listItem").val());
};

window.onload = function () {
    var name = localStorage.getItem("list");
    if (name !== null) $("#listItem").val("list");
};

HTML代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <title>To Do List</title>
  </head>
  <body>
    <section class="section-center">
      <form class="todolist-form">
        <h3>To Do List!</h3>
        <div class="input-button">
          <input type="text" id="items-input" placeholder="e.g. eggs" />
          <input type="button" class="submit-btn" onclick="addItems()" value="Submit" />
        </div>
        <div class="added-items">
          <ul id="faves"></ul>
        </div>
      </form>
    </section>
    <script src="main.js"></script>
  </body>
</html>

原JavaScript代码:

function addItems() {
  var li = document.createElement("LI");
  li.setAttribute("id", "listItem");
  var input = document.getElementById("items-input");
  li.innerHTML = input.value;
  input.value = "";
  document.getElementById("faves").appendChild(li);
  var deleteBtn = document.createElement("button");
  deleteBtn.classList.add("delete-btn");
  deleteBtn.innerHTML = "Delete";
  deleteBtn.type = "button";
  document.getElementById("faves").appendChild(deleteBtn);
  var hrzBreak = document.createElement("br");
  document.getElementById("faves").appendChild(hrzBreak);
  window.onbeforeunload = function () {
    localStorage.setItem("list", $("#listItem").val());
  };
  window.onload = function () {
    var name = localStorage.getItem("list");
    if (name !== null) $("#listItem").val("list");
  };
}

错误分析

  1. 重复绑定生命周期事件:每次点击Submit调用addItems时,都会重新绑定window.onbeforeunload和window.onload,覆盖之前的绑定。而且window.onload在页面加载完成后绑定,不会再触发,无法实现页面加载时恢复数据的功能。
  2. DOM操作与取值错误:
    • 每次创建的li都使用相同的id="listItem",DOM中id必须唯一,后续选择器只能选中第一个li,无法获取所有待办项。
    • $("#listItem").val()是获取输入框的value属性,但li元素没有value属性,无法正确获取待办内容。
    • 恢复数据时$("#listItem").val("list")逻辑错误,这是给元素设置value,而不是创建li添加到列表中。
  3. 存储逻辑不完整:只尝试存储单个li的内容,没有收集所有待办项进行存储,导致刷新后只能恢复一项甚至恢复失败。

修复后的完整代码

HTML(无需修改,保持原结构)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <title>To Do List</title>
  </head>
  <body>
    <section class="section-center">
      <form class="todolist-form">
        <h3>To Do List!</h3>
        <div class="input-button">
          <input type="text" id="items-input" placeholder="e.g. eggs" />
          <input type="button" class="submit-btn" onclick="addItems()" value="Submit" />
        </div>
        <div class="added-items">
          <ul id="faves"></ul>
        </div>
      </form>
    </section>
    <script src="main.js"></script>
  </body>
</html>

JavaScript(main.js)

// 页面加载时恢复待办列表
window.onload = function() {
  loadTodos();
};

// 添加待办项
function addItems() {
  const input = document.getElementById("items-input");
  const todoText = input.value.trim();
  if (!todoText) return; // 空内容不添加

  const li = document.createElement("li");
  li.textContent = todoText;

  const deleteBtn = document.createElement("button");
  deleteBtn.classList.add("delete-btn");
  deleteBtn.textContent = "Delete";
  deleteBtn.type = "button";
  deleteBtn.onclick = function() {
    li.remove();
    deleteBtn.remove();
    saveTodos(); // 删除后更新存储
  };

  const favesList = document.getElementById("faves");
  favesList.appendChild(li);
  favesList.appendChild(deleteBtn);
  favesList.appendChild(document.createElement("br"));

  input.value = "";
  saveTodos(); // 添加后更新存储
}

// 保存所有待办到localStorage
function saveTodos() {
  const todos = [];
  // 获取所有li元素的文本内容
  document.querySelectorAll("#faves li").forEach(li => {
    todos.push(li.textContent);
  });
  localStorage.setItem("todos", JSON.stringify(todos));
}

// 从localStorage加载待办列表
function loadTodos() {
  const savedTodos = localStorage.getItem("todos");
  if (!savedTodos) return;

  const todos = JSON.parse(savedTodos);
  const favesList = document.getElementById("faves");
  todos.forEach(todoText => {
    const li = document.createElement("li");
    li.textContent = todoText;

    const deleteBtn = document.createElement("button");
    deleteBtn.classList.add("delete-btn");
    deleteBtn.textContent = "Delete";
    deleteBtn.type = "button";
    deleteBtn.onclick = function() {
      li.remove();
      deleteBtn.remove();
      saveTodos();
    };

    favesList.appendChild(li);
    favesList.appendChild(deleteBtn);
    favesList.appendChild(document.createElement("br"));
  });
}

修复说明

  1. 分离生命周期事件:只在window.onload绑定一次加载逻辑,避免重复绑定。
  2. 唯一标识与正确取值:不再给li设置重复id,通过querySelectorAll获取所有li元素,收集其文本内容作为待办数据。
  3. 完整的存储逻辑:新增saveTodos和loadTodos函数,分别负责将所有待办项序列化为JSON存储到localStorage,以及从localStorage读取并渲染所有待办项。
  4. 实时更新存储:在添加、删除待办项后立即调用saveTodos,确保localStorage中的数据与页面同步,无需依赖onbeforeunload事件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 04:25:21