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

点击删除图标时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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:10:30