HTML无法自动保存,需JavaScript结合localStorage与事件监听实现;推荐防抖+beforeunload组合,避免setInterval导致的数据丢失、I/O浪费及主线程阻塞等问题。
HTML 本身做不到自动保存,必须靠 JavaScript 驱动 localStorage + 合理事件监听才能落地。定时轮询(setInterval)是下策,防抖+beforeunload 才是真实用、少丢数据的组合。
为什么不能直接用 setInterval 每30秒存一次
setInterval 看似简单,但实际会带来三类问题:一是用户刚敲完字就关页,最后一次输入没来得及存;二是内容没变也硬写,浪费 I/O 还可能触发 QuotaExceededError;三是移动端键盘收起、页面切后台时,定时器可能被系统暂停或降频,导致漏存。
更关键的是:
是同步操作,但频繁调用仍会阻塞主线程——尤其在低配 Android 设备上,连续 10 次写入就能感知卡顿。
别写
这种逻辑
真要用定时器,至少加“值比对”:只在
和上次缓存不同时才写
注意 Safari 无痕模式下
直接静默失败,
里捕获不到异常,得先做可用性探测
input 事件 + 防抖才是主流做法
监听
事件能捕获每次按键、粘贴、中文输入法上屏,比
或
更及时。但原生触发太密,必须加防抖。
立即学习
“
前端免费学习笔记(深入)
”;
实操要点:
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
用
+
手写防抖,延迟设为
(太短易漏,太长易丢)
只对非空字段存:比如
,避免覆盖 placeholder 或初始值
键名带上下文:如
,防止多表单冲突
存前用
,取回必须
,否则
返回
会导致
beforeunload 必须配合“脏标记”使用
是唯一能拦截关闭/刷新的时机,但它只允许同步执行,且窗口极短(约 50ms)。很多人在这里写
,结果什么都没存成。
正确姿势是:
定义一个全局布尔变量
每次防抖存完后设为
;每次 input 触发时设为
回调里只做一件事:
(现代浏览器只显示统一提示)
真正的存储动作,必须在防抖函数里完成,不能拖到
里
恢复草稿时容易忽略的细节
页面加载后恢复不是简单遍历赋值。几个硬坑:
用
即可,但
元素得用
,别用
(XSS 风险)
checkbox/radio 要单独处理:
,不能直接赋
恢复后手动触发
,否则 Vue/React 不响应
时间戳校验别漏:存的时候写
,恢复前判断是否超 24 小时,过期就丢弃
最麻烦的其实是动态字段和富文本编辑器——它们不走原生
流,得各自绑定对应事件(如 Quill 的
),而且 DOM 插入后必须立刻监听,否则新增行的输入就进不了草稿。
localStorage.setItem()setInterval(() => { saveDraft() }, 30000)JSON.stringify(formData)localStoragetry/catchinputchangeblursetTimeoutclearTimeout400–600msif (el.value.trim()) { ... }draft-${location.pathname}-${el.name}JSON.stringify()JSON.parse()getItem()nullSyntaxError: Unexpected token ubeforeunloadawait saveDraft()hasUnsavedChanges = falsefalsetruebeforeunloadif (hasUnsavedChanges) return ''beforeunloadtextarea.value = textcontenteditable.innerText = text.innerHTMLel.checked = storedValue === 'true'valuedispatchEvent(new Event('input', { bubbles: true }))savedAt: Date.now()inputtext-change