应监听input事件并加300ms防抖,统一委托到form容器,手动遍历提取字段值存localstorage,恢复时需比对时间戳、逐字段赋值并调用form.val()和form.render()。

layui 表单输入后怎么触发自动保存
不能依赖 blur 或点击事件——用户可能切后台、刷新、误关页,那时早没机会触发。必须监听 input 事件,并加防抖,300ms 内无新输入才写入草稿。否则每敲一个字都存一次,localStorage 写入频繁可能卡顿,还容易被浏览器限制(尤其 iOS 隐私模式)。
实操要点:
- 用
$('form').on('input', 'input, textarea, select')统一委托,避免给每个字段重复绑定 - 防抖用
setTimeout+clearTimeout管理,别用 lodash —— layui 项目通常不引入外部库 - 只保存有值的字段:空字符串、
null、undefined不进草稿对象,减少体积和恢复干扰 - 排除文件上传控件(
type="file"),它们的value是路径或空,且无法跨端恢复,本地只记状态标记
草稿数据怎么结构化存 localStorage
直接 JSON.stringify(form.serializeArray()) 不行:它把所有字段当字符串,checkbox 多选会丢值,select 未选中时返回空数组,而且没保留原始字段类型和关系。应该手动遍历表单元素,按需提取:
- 文本/数字/邮箱等
input:取elem.value,空则跳过 -
select:取elem.value,多选用[...elem.selectedOptions].map(o => o.value) -
checkbox和radio:用$('input[name="xxx"]:checked')拿值,未选中就不存 - 隐藏域(
type="hidden")也要纳入,有些业务状态靠它传递 - 存的时候加时间戳和表单唯一标识,例如 key 为
'draft-form-apply-20261002'
示例片段:
function getFormData() {
const data = {};
$('form input, form select, form textarea').each(function() {
const $this = $(this);
const name = $this.attr('name');
if (!name) return;
let val;
if (this.type === 'checkbox' || this.type === 'radio') {
val = $('input[name="' + name + '"]:checked').map((_, e) => e.value).get();
if (val.length === 0) return;
} else {
val = $this.val();
if (val === '') return;
}
data[name] = val;
});
return data;
}
刷新或返回页面后如何安全恢复草稿
恢复不是“有就填”,而是要有判断逻辑:草稿时间必须新于最后一次成功提交时间,否则会把旧数据覆盖新结果。常见错误是只检查 localStorage 是否存在,导致用户提交后又点返回,结果填回已过期的草稿。
- 提交成功后,立刻执行
localStorage.setItem('form-apply-submitted-at', Date.now().toString()) - 恢复前先读
submittedAt,再比对草稿的updatedAt(你存草稿时自己加的字段) - 恢复时逐字段回填:
$('input[name="xxx"]').val(val),但注意checkbox/radio要用.prop('checked', true),不能只设value - select 多选要先清空再设
selected属性,否则选项残留 - 恢复完调用
form.render(),否则 layui 的验证样式、下拉框渲染可能不生效
为什么草稿恢复后 checkbox 还是没打勾
因为 layui 的 form.render() 不会自动同步 DOM 的 checked 状态到 JS 数据模型,也不管你手动设了 prop('checked', true)。它只认初始化时的 checked 属性或后续通过 form.val() 设置的值。
- 不要用
$('input').prop('checked', true)后就结束,得补一句form.val('form-filter', { 'agree': true }) - 如果 checkbox 是数组型 name(如
name="hobby[]"),form.val()接收的是字符串数组,例如{ hobby: ['read', 'swim'] } - 恢复前先
form.val('form-filter', {})清空一遍,再批量赋值,避免旧值残留 - 特别注意:layui 2.8+ 的
form.val()在动态添加的 checkbox 上可能失效,此时必须确保 DOM 已挂载完成再调用
最易被忽略的一点:草稿恢复代码必须放在 layui.use(['form'], ...) 回调内部,且在 form.render() 之后执行;否则 form 模块还没加载完,form.val() 是 undefined。











