localstorage 是唯一合理选择,需用 json.stringify() 存储并用 json.parse() 读取,且先判断 getitem() 是否为 null;checkbox 应监听 change 而非 click;渲染用 innerhtml 一次性赋值并重绑事件;日期显示用 tolocaledatestring() 适配本地化。

用 localStorage 保存清单数据,别用 sessionStorage
页面刷新就清空清单?那是用了 sessionStorage。日常清单必须跨会话持久化,localStorage 才是唯一合理选择。
常见错误是把 JSON.stringify() 后直接存字符串,但忘了读取时要 JSON.parse();更隐蔽的坑是没处理 localStorage.getItem() 返回 null 的情况,导致 JSON.parse(null) 报错 Unexpected token 'n'。
- 初始化时先检查
localStorage.getItem('todoList')是否为null,是则设为空数组 - 每次增删改后,都用
localStorage.setItem('todoList', JSON.stringify(list))全量写入 - 不要尝试只存变更字段——HTML 页面没后端,全量同步最稳妥
input[type="checkbox"] 绑定事件别用 click,用 change
移动端点 checkbox 容易触发两次 click,且 Safari 对 label + checkbox 的 click 冒泡处理不一致;change 是语义正确、兼容性稳定的监听方式。
典型场景:勾选后自动更新 DOM 样式(如加删除线)并同步到 localStorage。若用 click,可能在 iOS 上出现状态滞后或重复执行。
- 监听
change事件,而非click或input - 在事件回调里通过
e.target.checked获取最新状态,别依赖e.target.parentNode.querySelector('input').checked - 避免在
change回调里直接操作localStorage—— 先更新内存数组,再统一saveToStorage()
渲染列表用 innerHTML = '' 而不是 removeChild 循环
逐个删 DOM 节点比一次性清空再重建慢得多,尤其当清单项超 20 条时,性能差异明显。现代浏览器对 innerHTML 批量渲染优化充分,只要不拼接不受信内容,就是安全且高效的选择。
容易被忽略的是:清空后必须重新绑定事件。如果用事件委托(比如监听 ul 上的 change),可跳过这步;否则每次重绘后都要重新 addEventListener 到每个新 checkbox。
- 生成完整 HTML 字符串后,一次性赋给
listElement.innerHTML - 若不用事件委托,确保在渲染后遍历新节点、为每个
input[type="checkbox"]补上change监听器 - 别在循环里反复读写
innerHTML——拼好整个字符串再赋值
用 date.toLocaleDateString() 显示日期,别硬写 new Date().getFullYear()
用户可能切换系统语言或时区,硬编码年月日格式(如 yyyy-mm-dd)会导致中文用户看到英文缩写,或夏令时偏差。浏览器原生方法能自动适配。
真实踩坑案例:某清单页在 macOS 中文系统下显示 “Jun 5, 2024”,而用户期望“2024年6月5日”。这不是 bug,是没用对 API。
- 用
new Date().toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' }) - 如果只需年月,去掉
day选项即可,不必自己截字符串 - 避免用
Date.now()或new Date().getTime()做显示——它们返回时间戳,不是人眼可读格式
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











