拖拽行时的虚线插入线需用sortable.js在onmove事件中动态插入带边框的空tr,必须在table.render()的done回调里初始化,设置colspan和pointer-events:none,并返回true允许落点。
拖拽行时出现虚线边框(即“插入指示线”),本质是监听 sortable 的 onmove 或 ondragover 类事件,动态在目标位置前后插入一个带 border-top: 1px dashed #999 的空 <tr> 或伪元素。<a style="color:#f60; text-decoration:underline;" title="layui" href="https://m.php.cn/zt/18036.html" target="_blank">layui</a> 原生 table 不提供该能力,必须依赖第三方库或手动实现。
<h3>用 Sortable.js 实现虚线插入线(推荐)</h3>
<p>Sortable 是最成熟、兼容性最好的方案,它原生支持 <code>ghostClass 和 chosenClass,但插入线需靠 onMove + DOM 操作实现:
- 必须在
table.render()的done回调里初始化 Sortable,否则tbody可能未就绪 - 不要直接操作
table.cache数组来模拟插入线,那只是数据层面;虚线是视觉层,得改 DOM - 插入线应为一个独立
<tr class="layui-table-insert-line"><td colspan="N"></td></tr>,并设置pointer-events: none避免干扰拖拽 -
onMove函数返回false会阻止插入,所以务必返回true允许落点,再手动渲染虚线
示例关键片段:
Sortable.create(tbody, {
animation: 150,
ghostClass: 'sortable-ghost',
onMove: function (evt) {
const targetRow = evt.related;
const insertBefore = evt.dropTarget;
// 清除旧插入线
$('.layui-table-insert-line').remove();
// 插入新虚线:在 insertBefore 上方
if (insertBefore) {
$(insertBefore).before(
'<tr class="layui-table-insert-line"><td colspan="' + cols[0].length + '" style="border-top:1px dashed #999; height:2px; padding:0;"></td></tr>'
);
}
return true;
}
});
不用第三方库,纯 mouse 事件模拟插入线(慎用)
若因项目限制不能引入 Sortable,可监听 mousedown → mousemove → mouseup 手动追踪拖拽位置,但极易出错:
- 必须自己维护“被拖行”的克隆节点,并设置
position: absolute+z-index,否则会被表格 overflow 裁剪 - 插入线位置计算依赖
getBoundingClientRect(),但 Layui 表格有固定表头、滚动条等干扰,top值容易偏移 - 移动端完全不可用,因为没
mousemove,且 touch 事件坐标处理更复杂 - 每次
mousemove都要反复查询所有tr的位置并比对,性能差,卡顿明显
常见错误:虚线一闪而过或位置不准
这是最常遇到的问题,根源几乎都出在时机和定位上:
- 在
table.render()外初始化拖拽逻辑 →tbody还没生成,querySelector('tbody')返回null - 插入线
<tr> 没加 <code>colspan,导致只在第一列显示虚线,其他列空白 - 没重置
table.css('border-collapse', 'separate'),虚线被合并边框吃掉 - 使用了
fixed: true的列 → 固定列和普通列的tr不在同一 DOM 树层级,插入线无法跨区域生效
虚线本身不难画,难的是让它始终贴着目标行边缘、不抖动、不遮挡内容、且在各种缩放/滚动/固定列场景下都稳定——这要求你必须把插入线的生命周期和 Sortable 的状态机深度绑定,而不是当成一个独立的 CSS 效果去“加上去”。











