必须在done回调中手动操作DOM实现行合并:遍历tbody tr,逐列比对textContent.trim(),独立维护各列currentVal/startRow/rowspan,清除旧属性后再设rowspan并隐藏重复td,禁用height避免虚拟滚动错位。
必须在 done 回调里手动操作 DOM
layui 表格不支持配置项或 render 函数直接生成 rowspan,所有「自动合并」尝试都会在分页、排序、重载后失效。唯一稳定路径是:等表格真实 dom 渲染完成,在 done 回调中遍历 tbody tr,逐列比对 textcontent.trim(),手动设 rowspan 并隐藏重复 td。
-
done是唯一安全时机——此时res.data已就位,且真实tr元素已挂载到.layui-table-body tbody - 不能用
$("#demo")查找数据表,Layui 把它塞进了#demo + .layui-table-box .layui-table-body table里 - 每次执行前必须清除旧的
rowspan和display: none,否则翻页后状态叠加导致错位
目标列索引 ≠ cols 数组下标
你配置的 {field: 'deptName'} 在 DOM 中可能不是第 0 列——前面若有复选框、序号、固定列,实际 td 位置就会偏移。硬写 colIndex = 0 必然出错。
- 用浏览器 inspect 看目标
td是tr的第几个子节点(从 0 开始) - 或用
$('th[data-field="deptName"]').index()反查表头列序,通常与数据行一致 - 如果该列设置了
fixed: 'left',它会单独渲染在另一个table中,不能和主表混算索引
多列合并必须独立计算 rowspan
按 deptName 合并 3 行、category 合并 2 行,不能共用一个 mark 变量。强行耦合会导致某列跨行错位,甚至 DOM 异常。
- 每列需维护各自的
currentVal、startRow、rowspan - 遍历一次
tr,内部为每列分别判断:当前值是否等于上一行对应列的值 - 不要写成
if (data[i].deptName === data[i-1].deptName && data[i].category === data[i-1].category)——这是「同时相同」,不是「各自相同」 - 遇到
null或undefined要显式判断:!val && !prevVal才算相等,否则null === undefined为 true,但语义错误
IE11 下 rowspan 渲染异常怎么处理
IE11 对动态设置 rowspan 支持极差:若后续对应行缺失或被其他 td 占位,就会空白或错行。这不是 JS 逻辑问题,而是渲染引擎限制。
- 必须正向遍历:从第 0 行开始,算出跨度后,用
$('<td rowspan="N">xxx</td>')替换首行对应td,再把后续N-1行该列td.remove() - 确保表格 CSS 含
table-layout: fixed,否则 IE 下宽度错乱 - 避免将操作列(如开关、按钮)纳入合并范围——它们的 DOM 结构不稳定,容易触发渲染异常


















