必须在done回调中绑定事件委托并调用table.checkrow或table.togglecheckrow,不可直接操作input[type="checkbox"]的checked属性,因为layui复选框是模拟渲染的,直接修改dom不会同步样式、form.render()和内部状态,导致checkstatus返回错误。
必须在 done 回调里绑定事件委托,调用 table.checkrow 或 table.togglecheckrow,不能直接操作 input[type="checkbox"] 的 checked 属性——否则 ui 样式、form.render()、table.checkstatus() 全部失效。
为什么不能直接改 DOM 的 checked?
layui 的复选框是用 .layui-form-checkbox 模拟的,真实 input 被隐藏。直接设 prop('checked', true) 只改了原生状态,但没触发 layui 的样式更新(比如没加 layui-form-checked 类),也没同步到内部缓存,导致 table.checkStatus('yourTableId') 返回空或错乱。
常见错误现象:
-
table.checkStatus('test')始终返回{data: [], count: 0} - 点击行后复选框图标没变化,但控制台查 DOM 显示
checked="true" - 翻页后之前选中的行丢失,因为内部状态根本没记录
正确做法:在 done 里委托 + 调用 checkRow
done 是表格 DOM 渲染完成后的唯一可靠时机。此时 tbody 已就位,且 res.data 可用。推荐用事件委托,避免翻页后失效或重复绑定。
实操要点:
- 委托目标写成
'.layui-table-body .layui-table',不是tbody tr—— 固定列(.layui-table-fixed-l/r)里的tr也得响应,而它们不在主tbody里 - 获取行数据必须用
$(tr).data('index')拿索引,再从res.data[index]取原始对象;若用了id字段,更稳妥的是$(tr).data('id')+ 遍历table.cache[tableId] - 调用
table.checkRow('test', rowData)(单选)或table.toggleCheckRow('test', rowData)(多选),rowData必须是原始数据对象,不是 jQuery 对象或 DOM 元素
示例片段:
table.render({
elem: '#test',
id: 'test',
url: '/api/list',
cols: [[{type: 'checkbox'}, {field: 'name', title: '姓名'}]],
done: function(res, curr, count) {
$('.layui-table-body .layui-table').on('click', 'tbody tr', function(e) {
if (e.target.tagName === 'TH' ||
$(e.target).closest('.layui-table-col-special').length ||
$(e.target).is('input[type="checkbox"], .layui-form-checkbox, .layui-form-checkbox *')) {
return;
}
var index = $(this).data('index');
var rowData = res.data[index];
table.toggleCheckRow('test', rowData); // 多选
// table.checkRow('test', rowData); // 单选(会自动取消其他行)
});
}
});
容易踩的坑:过滤不全 & 固定列干扰
用户点表头、点“操作”按钮、甚至点复选框内部的 <i></i> 图标时,如果没过滤,就会触发两次 toggle:一次是原生 checkbox 的 click,一次是 JS 的 toggleCheckRow,结果状态翻转错乱。
关键过滤条件必须包含:
-
e.target.tagName === 'TH':排除表头点击 -
$(e.target).closest('.layui-table-col-special').length:排除操作列(编辑/删除按钮所在列) -
$(e.target).is('input[type="checkbox"], .layui-form-checkbox, .layui-form-checkbox *'):排除复选框自身及所有子元素(含模拟勾选的<i></i>)
固定列问题:主表体和左右固定列里都有相同 data-index 的 tr,如果委托目标写成 document 或 body,同一点击可能触发多次。统一委托到 '.layui-table-body .layui-table' 可规避。
最易被忽略的一点:如果你开了分页,table.checkStatus() 默认只返回当前页选中项。跨页记忆需要自己维护 selectedIds = new Set(),并在 toggleCheckRow 后手动增删 —— layui 不管这个。











