点击删除图标时localStorage被全部清空,求排查解决建议
点击删除图标后localStorage被清空的问题分析与解决
问题根源
- 全局
todos数组未同步本地存储数据:你通过savedTodos读取了localStorage里的待办项,但没有把这些数据同步到全局的todos数组中。这导致todos始终是空数组,每次执行删除操作时,都会把空数组存回localStorage,直接清空了所有数据。 - 删除时传入的文本包含多余字符:你给LI元素添加了Font Awesome的删除图标,
e.target.parentElement.innerText会把图标对应的特殊字符也包含进去,而todos里存储的是纯待办文本,两者不匹配,导致splice找不到要删除的项,最后还是把空数组存回了localStorage。
修复方案
1. 同步本地存储数据到todos数组
把全局todos数组直接用localStorage的数据初始化,或者将savedTodos的内容同步进去:
// 方案一:直接用本地存储数据初始化todos const todos = JSON.parse(localStorage.getItem('todos')) || [] // 删掉原来的const savedTodos = ...,后续遍历直接使用todos // 方案二:保留savedTodos,同步数据到todos const todos = [] const savedTodos = JSON.parse(localStorage.getItem('todos')) || [] todos.push(...savedTodos) // 批量将本地存储的待办项加入todos
2. 避免图标干扰,存储/读取纯待办文本
- 提交新待办时,直接存储输入框的纯文本,不要使用
newTodo.innerText(该内容已包含图标字符):
// 替换原来的todos.push(newTodo.innerText) todos.push(todoInput.value)
- 创建LI元素时,用自定义属性存储纯文本,删除时读取该属性:
// 遍历本地存储数据创建LI时 for (let i = 0; i < todos.length; i++) { let newTodo = document.createElement('LI') const todoText = todos[i] newTodo.innerText = todoText newTodo.dataset.todo = todoText // 用data-todo属性存储纯文本 const deleteBtn = document.createElement('I') deleteBtn.classList.add('fa-sharp', 'fa-solid', 'fa-square-xmark') newTodo.append(deleteBtn) todoList.appendChild(newTodo) } // 提交表单创建LI时 form.addEventListener('submit', function (e) { e.preventDefault() // 必须添加,防止页面刷新丢失数据 const todoText = todoInput.value.trim() if (!todoText) return // 空内容不提交 const newTodo = document.createElement('li') newTodo.innerText = todoText newTodo.dataset.todo = todoText newTodo.classList.add('todo-item') const deleteBtn = document.createElement('i') deleteBtn.classList.add('fa-sharp', 'fa-solid', 'fa-square-xmark') newTodo.append(deleteBtn) todoList.appendChild(newTodo) todoInput.value = '' todos.push(todoText) localStorage.setItem('todos', JSON.stringify(todos)) })
- 删除时读取
data-todo属性获取纯文本:
todoList.addEventListener('click', function (e) { if (e.target.tagName === 'I') { const todoItem = e.target.parentElement todoItem.remove() removeFromStorage(todoItem.dataset.todo) } else if (e.target.tagName === 'LI') { e.target.classList.toggle('todo-complete') } })
3. 优化删除函数的循环逻辑
原正序循环在执行splice后会导致索引错位,改成倒序循环或找到目标项后直接跳出:
function removeFromStorage(itemToRemove) { // 倒序遍历,避免splice操作后索引混乱 for (let i = todos.length - 1; i >= 0; i--) { if (todos[i] === itemToRemove) { todos.splice(i, 1) break // 找到唯一目标项后直接退出循环 } } localStorage.setItem('todos', JSON.stringify(todos)) }
完整修复后代码
const todoInput = document.querySelector('#todo-item') const todoList = document.querySelector('.todo-list') const form = document.querySelector('form') // 直接用本地存储数据初始化todos数组 const todos = JSON.parse(localStorage.getItem('todos')) || [] for (let i = 0; i < todos.length; i++) { let newTodo = document.createElement('LI') const todoText = todos[i] newTodo.innerText = todoText newTodo.dataset.todo = todoText newTodo.classList.add('todo-item') const deleteBtn = document.createElement('I') deleteBtn.classList.add('fa-sharp', 'fa-solid', 'fa-square-xmark') newTodo.append(deleteBtn) todoList.appendChild(newTodo) } form.addEventListener('submit', function (e) { e.preventDefault() const todoText = todoInput.value.trim() if (!todoText) return const newTodo = document.createElement('li') newTodo.innerText = todoText newTodo.dataset.todo = todoText newTodo.classList.add('todo-item') const deleteBtn = document.createElement('i') deleteBtn.classList.add('fa-sharp', 'fa-solid', 'fa-square-xmark') newTodo.append(deleteBtn) todoList.appendChild(newTodo) todoInput.value = '' todos.push(todoText) localStorage.setItem('todos', JSON.stringify(todos)) }) function removeFromStorage(itemToRemove) { for (let i = todos.length - 1; i >= 0; i--) { if (todos[i] === itemToRemove) { todos.splice(i, 1) break } } localStorage.setItem('todos', JSON.stringify(todos)) } todoList.addEventListener('click', function (e) { if (e.target.tagName === 'I') { const todoItem = e.target.parentElement todoItem.remove() removeFromStorage(todoItem.dataset.todo) } else if (e.target.tagName === 'LI') { e.target.classList.toggle('todo-complete') } })
内容的提问来源于stack exchange,提问作者Frank Pitkat
相关产品推荐
相关产品推荐

