如何刷新页面不丢失新增待办列表项?现有代码问题求助
待办列表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"); }; }
错误分析
- 重复绑定生命周期事件:每次点击
Submit调用addItems时,都会重新绑定window.onbeforeunload和window.onload,覆盖之前的绑定。而且window.onload在页面加载完成后绑定,不会再触发,无法实现页面加载时恢复数据的功能。 - DOM操作与取值错误:
- 每次创建的li都使用相同的
id="listItem",DOM中id必须唯一,后续选择器只能选中第一个li,无法获取所有待办项。 $("#listItem").val()是获取输入框的value属性,但li元素没有value属性,无法正确获取待办内容。- 恢复数据时
$("#listItem").val("list")逻辑错误,这是给元素设置value,而不是创建li添加到列表中。
- 每次创建的li都使用相同的
- 存储逻辑不完整:只尝试存储单个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")); }); }
修复说明
- 分离生命周期事件:只在
window.onload绑定一次加载逻辑,避免重复绑定。 - 唯一标识与正确取值:不再给li设置重复id,通过
querySelectorAll获取所有li元素,收集其文本内容作为待办数据。 - 完整的存储逻辑:新增
saveTodos和loadTodos函数,分别负责将所有待办项序列化为JSON存储到localStorage,以及从localStorage读取并渲染所有待办项。 - 实时更新存储:在添加、删除待办项后立即调用
saveTodos,确保localStorage中的数据与页面同步,无需依赖onbeforeunload事件。
内容的提问来源于stack exchange,提问作者Fadi aljohari
相关产品推荐
相关产品推荐

