因为layui表格是异步渲染,table.render()执行完毕时tbody仍为空,只有done回调能确保dom完全就绪,此时绑定事件委托才有效。
必须在 done 回调里绑定事件委托,用 table.checkrow 或 table.togglecheckrow 更新状态,不能直接操作 dom 的 checked 属性。
为什么 click 事件必须写在 done 回调里
Layui 表格是异步渲染的,table.render() 执行完时 .layui-table-body 内还是空的。此时查 tbody tr 肯定找不到节点,绑定事件自然无效。
-
done: function(res, curr, count) { }是唯一能确保表格 DOM 完全就绪的钩子 - 推荐委托到
.layui-table-body .layui-table,监听tr的click,避免翻页后失效 - 别对每行单独绑定——既低效,又会在分页、重载后重复绑定导致多次触发
如何正确触发选中逻辑,而不是硬设 checked
直接改 $('input[type="checkbox"]').prop('checked', true) 看似快,但会破坏 layui 内部状态与 UI 的同步:样式不更新、form.render() 不响应、table.checkStatus() 返回空或错乱。
- 必须调用
table.checkRow(tableId, data)(Layui 2.8+)或table.toggleCheckRow(tableId, data) -
data必须是该行原始数据对象,比如res.data[index],不是 DOM 元素 - 获取索引推荐用
$(tr).data('index'),再从res.data中取;若用了id字段,更稳妥的是$(tr).data('id')+ 遍历table.cache[tableId]
点击区域要过滤哪些元素
用户点表头、操作列按钮、复选框本身时,不该再触发行选中,否则会和原生行为冲突(比如点一次 checkbox 反而取消)。
- 开头加判断:
if (e.target.tagName === 'TH' || $(e.target).closest('.layui-table-col-special').length) return - 重点过滤复选框相关区域:
if ($(e.target).is('input[type="checkbox"], .layui-form-checkbox, .layui-form-checkbox *')) return - 如果用了固定列(left/right),注意
tr[data-index]在主表体和固定列里都存在,委托目标要统一指向.layui-table-body .layui-table,避免重复触发
全选/单选切换和跨页选中怎么稳住
table.checkStatus(tableId) 默认只返回当前页数据,且内部 checkCtrl 状态容易被手动操作污染。依赖它做“已选中”判断,十次有八次不准。
- 每次手动选中/取消后,都应调一次
table.checkStatus(tableId)校验,别缓存结果 - 启用分页时,必须自己维护一个
Set记录所有已选id,翻页时靠table.cache[tableId]和这个集合比对,重置每行的checked状态 - 如果只是单选需求,优先考虑
{type: 'radio'}列 +on('radio')监听,比 checkbox + 手动清空其他行更轻量可靠
最易被忽略的是:DOM 就绪时机、状态更新入口、以及跨页时 cache 和 UI 的不同步——这三处出问题,表现都是“点了没反应”或“选了又丢”,但原因完全不同。











