localStorage 完全够用且免部署,需 JSON 序列化、提示数据仅本地保存;用 input[type="date"] 获取日期并校验;打卡去重用 Set 并按 Date 排序;点击后立即更新 DOM 和 localStorage,注意容量限制。

用 localStorage 存打卡日期,别碰后端或数据库
日常打卡不需要服务器——99% 的场景下,localStorage 完全够用,且免部署、免登录、双击打开就能写。它按域名隔离,同一页面反复刷新不会丢数据;但注意:localStorage 只存字符串,得自己 JSON.stringify() 和 JSON.parse();另外,如果用户清缓存或用无痕模式,数据就没了,这点得在界面上轻量提示(比如加个 「数据仅保存在本浏览器」)。
用 input[type="date"] 获取日期,别手输或写日历组件
原生 input[type="date"] 在 Chrome/Firefox/Safari(桌面+iOS)都支持良好,能唤起系统级日期选择器,避免格式错(如 2024-02-30)、时区混乱或兼容性补丁。关键点:
- 设
value为new Date().toISOString().split('T')[0],自动填入今天 - 加
min属性限制可选范围(例如min="2024-01-01"),防止倒填 - 提交前校验:若
input.value为空,说明用户没点选(尤其 Safari 移动端偶尔不触发 change),得拦截并提示
渲染打卡列表时,用 Array.from(new Set()) 去重,别靠后端 dedup
用户可能一天点多次“打卡”,前端要确保同一天只记一次。常见错误是每次点击都 push 进数组再渲染,结果列表重复。正确做法是把已存日期转成 Set 去重,再转回数组排序:
const dates = JSON.parse(localStorage.getItem('checkins') || '[]');
const uniqueDates = Array.from(new Set(dates)).sort((a, b) => new Date(b) - new Date(a));注意:Set 对字符串去重安全,但别对对象用;排序用 new Date() 比字符串比较更稳(避免 "2024-1-1" 和 "2024-01-01" 排序错乱)。
立即学习“前端免费学习笔记(深入)”;
点击打卡按钮后,立刻更新 DOM 并同步 localStorage,别等异步回调
没有网络请求,就不存在 loading 或失败重试逻辑。用户点一下,应该:
- 立即将该日期加入数组(去重后)
- 立刻重绘列表(哪怕只用
innerHTML粗暴替换) - 立刻执行
localStorage.setItem('checkins', JSON.stringify(newArray))
漏掉最后一步是高频翻车点——看着界面更新了,关掉浏览器再开,发现没保存。另外,别在 setItem 后加 console.log 就以为写成功了:它同步执行,但若超出 5MB 限额会静默失败,建议加个简单 try/catch 提示容量告警。



















