浏览器无原生草稿箱API,需用JavaScript监听input事件、防抖存localStorage,带timestamp校验过期,白名单过滤敏感字段,恢复时异步setSelectionRange还原光标。

浏览器原生不提供 HTML 草稿箱功能,所有“草稿箱”效果都得靠 JavaScript 主动捕获、序列化、持久化用户输入,并手动管理列表结构——没有现成的 drafts API,也别指望 contenteditable 自带草稿能力。
监听输入并自动保存草稿到 localStorage
核心是监听表单控件(、)的 input 事件,每次变化就存一次。注意不是用 change(只在失焦时触发),否则用户切走就丢内容。
实操建议:
- 给每个可编辑区域加唯一
id或data-draft-key,用于生成 localStorage key,例如localStorage.setItem('draft-contact-form', JSON.stringify({ content: value, timestamp: Date.now() })) - 加防抖(500ms),避免高频输入狂刷存储;但别用节流,否则可能漏存最后几字
- 检查
localStorage是否可用(部分 iOS 隐私模式会直接抛QuotaExceededError),需 try/catch 包裹写入逻辑 - 敏感字段(如密码、token)绝不能进草稿,建议白名单控制可存字段名,而非全量
form.elements
渲染草稿列表时如何避免重复或过期数据
草稿列表本质是读取多个 localStorage key 后组装的数组,但用户可能删掉对应表单页、改了字段结构,或草稿超过 7 天没用——这些都得清理,否则列表越攒越多、点开却报错。
实操建议:
- 每次读取草稿前,先遍历所有已知 key(比如用
Object.keys(localStorage)过滤出draft-*前缀),再逐个JSON.parse;解析失败就removeItem掉这个 key - 草稿对象里必须带
timestamp字段,渲染列表时过滤掉Date.now() - timestamp > 7 * 24 * 60 * 60 * 1000的条目 - 列表项点击加载草稿时,要校验当前 DOM 是否还存在对应
id的编辑器,不存在就提示“原始表单已不可用”,并自动清除该草稿 - 不要用
innerHTML += ...拼接列表,用document.createElement+appendChild或template元素,避免 XSS(草稿内容可能含未转义 HTML)
恢复草稿时怎么精准还原光标位置和选区
单纯 element.value = draft.content 会丢失光标位置,用户还得手动拖到修改处。真要体验好,得存光标偏移量。
实操建议:
- 监听
focus和blur时用element.selectionStart/selectionEnd记录位置,连同内容一起存进草稿对象 - 恢复时先赋值,再用
setTimeout(() => { element.focus(); element.setSelectionRange(start, end); }, 0)—— 必须异步,否则 DOM 还没重绘,setSelectionRange无效 - 仅对
和做光标恢复;contenteditable元素要用getSelection()+rangeAPI,复杂度高,多数场景建议回避 - 移动端 Safari 对
setSelectionRange支持不稳定,可加 fallback:恢复后自动滚动到容器底部(element.scrollTop = element.scrollHeight)
草稿箱最麻烦的从来不是存和取,而是“什么时候该删”。用户关掉页面、切换账号、清缓存、甚至只是换了个浏览器,草稿就变成孤儿数据。真正健壮的实现,得把清理逻辑分散到加载、渲染、恢复、提交多个环节里,而不是指望一次定时任务扫干净。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











