Layui如何实现表格行的拖拽换行排序(结合Sortable.js)

煙雲

煙雲

2026-05-09

997人浏览

原创

直接用 Sortable.js 拖拽 Layui 表格行会失效,因 Layui 启用虚拟滚动、DOM 动态复用,拖拽仅改 DOM 未同步 data 数组,导致排序错乱、索引丢失及报错。

为什么直接用 Sortable.js 拖拽 Layui 表格行会失效?

layui 的表格(layui.table)默认启用虚拟滚动、复用 dom 节点,且行元素(.layui-table-body tbody tr)不是原始渲染的静态节点,而是由 layui 动态管理的。直接对 tbody 初始化 sortable,拖拽时会触发 layui 内部的重绘逻辑,导致排序错乱、索引丢失、甚至报错 "cannot read property 'setattribute' of null"

根本原因在于:Layui 表格的 DOM 结构和数据模型是分离的,拖拽操作必须同步更新 data 数组,不能只改 DOM。

  • 不要对 .layui-table-body tbody 直接初始化 Sortable
  • 必须监听拖拽结束事件,在回调中手动更新表格数据源(table.config.data 或你维护的原始数组)
  • 拖拽目标容器需避开 Layui 自动管理区域,推荐用 .layui-table-main(即整个表格主体区)或自定义 tbody 容器(需禁用 Layui 虚拟滚动)

如何正确绑定 Sortable 到 Layui 表格并同步数据?

核心思路:绕过 Layui 的内部 tbody,用一个「纯净」的 tbody 容器承载行,并关闭 Layui 的 scrollbarheight(避免虚拟滚动)。然后用 Sortable 管理该容器,再在 onEnd 中重排你的数据源,并调用 table.reload()

实操步骤:

  • 初始化表格时设置 height: 'auto'limit: 1000(或足够大),禁用滚动条和分页,确保所有行真实渲染
  • 给表格容器加 ID,如 id="sortTable";在 done 回调里定位到 $('#sortTable .layui-table-body tbody')
  • Sortable.create(el, { ... }) 绑定,关键配置:handle: '.drag-handler'(推荐加拖拽手柄列,避免误触文本)、animation: 150ghostClass: 'sortable-ghost'
  • onEnd 回调中:获取当前 el.children 的顺序,映射回原始数据数组的索引,重新排列你的数据源(不是 DOM!)
  • 调用 table.reload('yourTableId', { data: newData }) 刷新表格

示例关键片段:

php版微信js-sdk支付接口类
php版微信js-sdk支付接口类

php版微信js-sdk支付接口类

下载
table.render({
  elem: '#sortTable',
  height: 'auto',
  limit: 9999,
  cols: [[
    { type: 'numbers', width: 50 },
    { field: 'title', title: '标题' },
    { title: '操作', width: 80, templet: '<div class="drag-handler">≡</div>' }
  ]],
  data: myDataList, // 你维护的可变数组
  done: function(res, curr, count){
    const tbody = document.querySelector('#sortTable .layui-table-body tbody');
    new Sortable(tbody, {
      handle: '.drag-handler',
      animation: 150,
      onEnd: function(evt) {
        const newIndex = evt.newIndex;
        const oldIndex = evt.oldIndex;
        // 在 myDataList 中执行数组移动(非 splice 移位,要用 splice + insert)
        const item = myDataList.splice(oldIndex, 1)[0];
        myDataList.splice(newIndex, 0, item);
        // 重载表格,不传 page / where,仅更新 data
        table.reload('sortTable', { data: myDataList });
      }
    });
  }
});

拖拽后序号列(type: 'numbers')不更新怎么办?

Layui 的 type: 'numbers' 是渲染时按当前页顺序生成的静态文本,table.reload() 不会自动重算它——因为它是“伪序号”,不绑定数据字段。如果你依赖序号反映真实排序位置,必须显式处理。

  • 方案一(推荐):去掉 type: 'numbers',改用真实字段,比如在数据中加 sortIndex 字段,表格列定义为 { field: 'sortIndex', title: '序号' },每次拖拽后遍历 myDataList 重赋值:myDataList.forEach((d, i) => d.sortIndex = i + 1)
  • 方案二:用 CSS 计数器模拟,但仅适用于展示,无法导出或参与搜索
  • 切勿尝试用 JS 遍历 DOM 修改 .layui-table-number 文本——Layui 下次 reload 会覆盖

移动端拖拽卡顿或失效的常见原因

移动端 touch 事件与 Sortable 默认配置存在兼容性问题,尤其在 iOS Safari 上容易触发页面滚动或点击穿透。

  • 必须添加 forceFallback: true,强制启用 fallback 模式(基于 mouse/touch 事件模拟)
  • 加上 fallbackTolerance: 3touchStartThreshold: 3,降低触发灵敏度,避免误判
  • 确保拖拽手柄(.drag-handler)有足够点击热区(最小 44×44px),并加 user-select: none
  • Layui 表格父容器不要设 overflow: hidden,否则移动端 touchmove 可能被截断

复杂点始终在数据同步而非 DOM 操作——只要没把 myDataListtable.reload 的 data 参数对齐,拖拽就只是视觉幻觉。别信 DOM 顺序,只信你手里那个数组。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

js layui

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1111

5

前端如何实现即时通讯
前端如何实现即时通讯

实现即时通讯的方法有WebSocket、Long Polling、Server-Sent Events、WebRTC等等。详细介绍:1、WebSocket,它可以在客户端和服务器之间建立持久连接,实现实时的双向通信,前端可以使用 WebSocket API来创建WebSocket连接,并通过发送和接收消息来实现即时通讯;2、Long Polling,是一种模拟实时通信的技术等等。

2023.10.09

2262

6

前端和后端的区别
前端和后端的区别

前端关注的是用户界面的设计和交互,而后端则注重数据处理和逻辑控制。想了解更多前端后端的相关内容,可以阅读本专题下面的文章。

2024.03.19

2130

13

php和前端的关联介绍
php和前端的关联介绍

php既可以作为前端语言,也可以作为后端语言。想了解更多php和前端的相关内容,可以阅读本专题下面的文章。

2024.03.22

2321

10

前端外包工作内容有哪些
前端外包工作内容有哪些

前端外包工作内容包括:1. 网站和应用程序开发;2. 用户界面和交互设计;3. 用户体验优化;4. 设计和视觉开发;5. 跨浏览器兼容性;6. 性能优化;7. 维护和更新;8. 项目管理和沟通。想了解更多前端的相关内容,可以阅读本专题下面的文章。

2024.05.22

336

5

ajax教程
ajax教程

php中文网为大家带来ajax教程合集,Ajax是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。php中文网还为大家带来ajax的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.14

1144

4

ajax中文乱码解决方法
ajax中文乱码解决方法

ajax中文乱码解决方法有设置请求头部的字符编码、在服务器端设置响应头部的字符编码和使用encodeURIComponent对中文进行编码。本专题为大家提供ajax中文乱码相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.31

319

5

ajax传递中文乱码怎么办
ajax传递中文乱码怎么办

ajax传递中文乱码的解决办法:1、设置统一的编码方式;2、服务器端编码;3、客户端解码;4、设置HTTP响应头;5、使用JSON格式。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.15

1019

5

ajax网站有哪些
ajax网站有哪些

使用ajax的网站有谷歌、维基百科、脸书、纽约时报、亚马逊、stackoverflow、twitter、hacker news、shopify和basecamp等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.09.24

918

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
ThinkPHP配置开发与CMS后台实战
ThinkPHP配置开发与CMS后台实战

共87课时 | 11.4万人学习

第二十三期_综合实战
第二十三期_综合实战

共89课时 | 9.7万人学习

Layui 快速入门精讲
Layui 快速入门精讲

共5课时 | 1.5万人学习