layui弹窗需在end回调中同步保存表单至localstorage实现草稿续填,key格式为“draft-业务前缀-字段名”,恢复时在success回调中读取并填充,提交成功后批量清除对应草稿。

在Layui弹窗中,用户填写表单后意外关闭弹层(如点遮罩、按ESC、关掉标签页),会导致输入内容全部丢失;必须在真正卸载前把值存进localStorage,才能实现草稿续填。
监听layer关闭前的最后时机
使用layer.open的end回调——这是唯一确保DOM已完全移除、JS上下文尚未销毁的钩子,比cancel、yes、close等都更可靠。
在open配置中直接写入end函数:【end必须是同步执行的函数,不能是异步await或setTimeout包裹】
end回调里可安全访问弹窗内DOM,也能调用localStorage.setItem(),不会因弹窗消失而中断写入。
获取并保存表单字段值
方法一:按name属性逐个取值(适合字段少、结构固定)
在end函数中,先用document.getElementById或layui.$获取弹窗容器,再遍历所有input、textarea元素,读取name和value:
const formEl = document.querySelector('.layui-layer-content form'); if (formEl) { Array.from(formEl.elements).forEach(el => { if (el.name && el.value.trim()) { localStorage.setItem(`draft-${layer.index}-${el.name}`, el.value); } }); }
注意:不要用layer.getChildFrame()去取iframe内容——如果弹窗是type:2且跨域,该方法返回null,后续操作会报错。
构造带命名空间的key避免冲突
第一步:用layer.index作为本次弹窗唯一标识,防止同一页面多次打开同类型弹窗时数据覆盖
第二步:拼接业务前缀,例如用户编辑弹窗统一用'draft-user-edit-'开头
第三步:字段名后不加额外后缀,保持与后端API字段一致,比如name、phone、remark
最终key形如:【draft-user-edit-phone】,这样恢复时能直接映射到对应input的name属性
自动填充上次暂存的草稿
在layer.open前,先检查localStorage中是否存在对应前缀的键:
const draftKeys = Object.keys(localStorage).filter(k => k.startsWith('draft-user-edit-'));
如果有匹配项,说明用户曾打开过该弹窗但未提交,此时在content或success回调中遍历这些key,用正则提取字段名,再赋值给对应表单控件:
draftKeys.forEach(key => { const field = key.replace('draft-user-edit-', ''); const val = localStorage.getItem(key); const input = formEl?.elements[field]; if (input && val !== undefined) input.value = val; });
这一步必须在表单DOM渲染完成后再执行,否则elements集合为空——推荐放在layer.open的success回调里做,不要放在content字符串里硬塞。
提交成功后立即清理草稿
1. 在表单submit监听函数中,确认接口返回成功响应后,执行:
localStorage.removeItem('draft-user-edit-name'); localStorage.removeItem('draft-user-edit-phone'); ……
2. 或更稳妥地批量清除:
Object.keys(localStorage).forEach(key => { if (key.startsWith('draft-user-edit-')) localStorage.removeItem(key); });
3. 【切勿在end回调里无条件清空所有draft-*,否则用户只是想取消、还没提交,草稿就永远丢了】











