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

待办事项应用单任务删除逻辑实现问题求助及代码调试

问题分析与修复方案

原代码的核心问题

  • 数字增减逻辑反向:你需要将后续任务的键末尾数字减1,但代码里写的是parseInt(keyCount) + 1,反向操作会导致数字异常,甚至出现负数。
  • 键名截取逻辑错误:
    • key.substring(6 + title.length)依赖固定长度截取数字,一旦标题包含下划线或长度计算偏差,会截取到错误内容,导致parseInt返回NaN。
    • key.slice(0, -1)仅删除最后一个字符,若数字是两位数(如10),会错误截断为1,拼接后键名完全失效。
  • 循环依赖初始长度:localStorage的长度会随删除/添加操作动态变化,用初始的numItems循环会导致遍历不完整或重复处理。
  • keyFound触发时机错误:从后往前遍历的情况下,找到目标key后才处理后续任务,但后续任务的数字序号应大于目标key,反向遍历会导致重复修改。

修复后的代码

export function delTask(taskContainer) {
  const targetId = taskContainer.id.toString();
  const targetTitle = taskContainer.title;
  const targetPrefix = `task_${targetTitle}_`;

  // 先收集所有同标题的任务键,避免遍历过程中localStorage变化影响
  const taskKeys = [];
  for (let i = 0; i < localStorage.length; i++) {
    const key = localStorage.key(i);
    if (key.startsWith(targetPrefix)) {
      taskKeys.push(key);
    }
  }

  // 找到目标任务的数字序号
  let targetIndex = -1;
  taskKeys.forEach(key => {
    const parts = key.split('_');
    const index = parseInt(parts[parts.length - 1], 10);
    if (key === targetId) {
      targetIndex = index;
    }
  });

  if (targetIndex === -1) return;

  // 删除目标任务
  localStorage.removeItem(targetId);

  // 处理后续任务的键名更新
  taskKeys.forEach(key => {
    const parts = key.split('_');
    const index = parseInt(parts[parts.length - 1], 10);
    // 仅处理序号大于目标索引的任务
    if (index > targetIndex) {
      const newIndex = index - 1;
      const newKey = `${targetPrefix}${newIndex}`;
      const value = localStorage.getItem(key);
      localStorage.removeItem(key);
      localStorage.setItem(newKey, value);
    }
  });
}

更合理的实现思路

放弃单个任务对应单个localStorage键的方案,将同标题的任务存入数组,用单个键存储(如tasks_project 1),操作更简洁:

// 存储同标题任务数组
function saveTasks(title, tasks) {
  localStorage.setItem(`tasks_${title}`, JSON.stringify(tasks));
}

// 获取同标题任务数组
function getTasks(title) {
  const rawData = localStorage.getItem(`tasks_${title}`);
  return rawData ? JSON.parse(rawData) : [];
}

// 删除任务
export function delTask(taskContainer) {
  const title = taskContainer.title;
  const targetId = taskContainer.id;
  const tasks = getTasks(title);
  // 过滤掉目标任务后重新存储
  const updatedTasks = tasks.filter(task => task.id !== targetId);
  saveTasks(title, updatedTasks);
}

这种方式无需手动维护键名的数字序号,直接操作数组即可,彻底避免键名拼接的各类问题,更符合数据存储逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:27:38