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

如何在localStorage中保存To Do任务?代码实现问题求助

解决ToDo列表保存到localStorage的问题

原代码的核心问题

  1. 保存逻辑错误:原代码里每次点击保存按钮才声明空数组,且push方法返回的是数组新长度,导致你存到localStorage的是数字而非数组内容。
  2. 未加载已有数据:页面刷新后,没有从localStorage读取之前保存的待办项,数据直接丢失。
  3. 删除不同步:仅清空DOM元素,没有同步更新localStorage里的数据源。
  4. 缺少结构化存储:直接存文本不利于后续增删管理,用带唯一标识的对象存储更合理。

修正后的完整代码

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" />
  <meta name="description" content="This web app provides you with accessibility of todo list" />
  <title>Simple To-Do-List</title>
  <link rel="stylesheet" href="style.css" />
</head>

<body>
  <div class="container">
    <h2>A Reliable To-Do-App</h2>

    <div class="text-input center">
      <input type="text" id="todo-input" placeholder="Write you task here.." />
      <button type="button" id="addBtn">Add</button>
    </div>
    <div class="display"></div>
  </div>
  <script src="app.js"></script>
</body>

</html>

JavaScript(实现完整持久化功能)

// 初始化待办列表:从localStorage读取,无数据则设为空数组
let todosList = JSON.parse(localStorage.getItem('todos')) || [];

// 获取DOM元素
const toDoInput = document.getElementById("todo-input");
const addBtn = document.getElementById("addBtn");
const display = document.querySelector(".display");

// 页面加载时渲染已保存的待办项
renderTodos();

// 添加待办项事件
addBtn.addEventListener("click", () => {
  const todoText = toDoInput.value.trim();
  if (!todoText) return; // 空内容不添加

  // 创建带唯一ID的待办对象
  const newTodo = {
    id: Date.now(), // 用时间戳做临时唯一标识
    text: todoText
  };

  // 更新数组并同步到localStorage
  todosList.push(newTodo);
  saveToLocalStorage();

  // 渲染新增的待办项
  renderTodoItem(newTodo);

  // 清空输入框
  toDoInput.value = "";
});

// 渲染单个待办项到DOM
function renderTodoItem(todo) {
  const list = document.createElement("ul");
  const todoLi = document.createElement("li");
  const deleteBtn = document.createElement("button");

  todoLi.textContent = todo.text; // 用textContent更安全,避免XSS风险
  deleteBtn.textContent = "Delete";

  // 添加类名
  list.classList.add("list");
  todoLi.classList.add("todos");
  deleteBtn.classList.add("deleteBtn");

  // 组装DOM结构
  list.appendChild(todoLi);
  list.appendChild(deleteBtn);
  display.appendChild(list);

  // 删除按钮事件
  deleteBtn.addEventListener("click", () => {
    // 从数组中移除对应待办项
    todosList = todosList.filter(item => item.id !== todo.id);
    // 更新localStorage
    saveToLocalStorage();
    // 删除DOM元素
    list.remove();
  });
}

// 渲染所有待办项
function renderTodos() {
  display.innerHTML = ""; // 清空现有内容
  todosList.forEach(todo => {
    renderTodoItem(todo);
  });
}

// 保存到localStorage的工具函数
function saveToLocalStorage() {
  localStorage.setItem('todos', JSON.stringify(todosList));
}

关键改进说明

  • 结构化存储:用{id, text}对象存储每个待办项,通过ID实现精准删除。
  • 持久化数组:全局维护待办数组,页面加载时读取localStorage,每次增删后同步更新存储。
  • 正确使用数组方法:先将待办项推入数组,再把整个数组转JSON存入localStorage,避免存储push返回的长度值。
  • 数据同步:删除DOM元素时,同时从数组和localStorage移除对应数据,保证数据一致性。
  • 安全赋值:用textContent替代innerHTML,避免用户输入HTML内容引发的安全问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:55:26