需在双击编辑前用dataset存oldVal,edit事件中读取dataset.oldValue和obj.value对比;监听表格容器dblclick并用e.target.closest('td[lay-edit]')定位单元格,存innerText.trim()至dataset,edit时直接取用,避免闭包或全局Map。
layui table 编辑后怎么监听失焦并拿到 oldVal 和 newVal
layui 的 table 表格本身不提供「编辑前后值对比」的原生钩子,edit 事件只在单元格内容变更后触发,且不携带旧值。必须自己存旧值、再比对。
核心思路:在单元格进入编辑状态(双击或回车)时,用 td 的 dataset 或临时对象缓存原始文本;失焦时读取当前输入框值,再比对。
- 监听
table.on('edit')只能拿到新值和行数据,拿不到旧值 —— 这是最大误区 - 必须配合
table.render()的done回调或cell事件,提前给可编辑单元格打标记 - 推荐用
td元素的dataset.oldValue存旧值,避免污染全局变量
怎么在双击编辑前就存下 oldVal
不能等 edit 事件,得在用户真正开始编辑前拦截。Layui 没有「编辑开始」事件,但可以监听表格容器上的 dblclick,并判断是否点中了带 lay-edit 属性的 td。
- 给表格容器加
id="testTable",然后绑定原生dblclick事件 - 用
e.target.closest('td[lay-edit]')定位到被双击的单元格 - 立刻读取该
td的innerText(注意去除空格和换行),存入td.dataset.oldValue - 别用
textContent,它可能包含隐藏的或换行符,导致比对误判
document.getElementById('testTable').addEventListener('dblclick', function(e) {
const td = e.target.closest('td[lay-edit]');
if (td) {
td.dataset.oldValue = td.innerText.trim();
}
});
edit 事件里怎么安全取到 oldVal 和 newVal
table.on('edit') 触发时,td 已更新,但 dataset.oldValue 还在。只要前面存得对,这里就能比。
-
obj.value是新值(已 trim 过) -
obj.cell是当前td元素,可读dataset.oldValue - 注意:如果用户没改内容直接失焦,
obj.value === obj.cell.dataset.oldValue成立,应跳过后续逻辑 - 别用
obj.oldValue—— Layui 根本没这个字段,是常见想当然错误
table.on('edit(test)', function(obj){
const oldValue = obj.cell.dataset.oldValue || '';
const newValue = obj.value;
if (oldValue === newValue) return; // 未改动,不处理
console.log('从', oldValue, '改成了', newValue);
});
为什么用 dataset 而不是闭包或全局 map 存 oldVal
用 dataset 是最轻量、最可靠的方式。闭包容易因重绘/重载丢失上下文;全局 Map 需手动维护生命周期,表格刷新后 key 对不上就漏值。
-
td元素销毁时,dataset自动释放,无内存泄漏风险 - 支持分页、重载、动态列 —— 只要
td还在,oldValue就在 - 兼容性没问题:
dataset在 IE11+ 和所有现代浏览器都可用 - 别把旧值存在
input上 —— Layui 编辑框是动态创建又销毁的,不可靠
真正容易被忽略的是:表格初始化后第一次双击前,有些 td 可能还没渲染完成,dataset.oldValue 读出来是 undefined。务必在 dblclick 里做空值 fallback,比如用 obj.cell.innerText.trim() 备用兜底。










