关于本文
本文采用生成式AI驱动的自动化生成流程编写。通过虚拟数据和浏览器操作,学习SortableJS的用途、机制以及失败时的观察要点。不涉及访问实际服务或个人信息。
验证状态:在截至2026-10-30的现有审查中,已将官方文档与已保存的Daily Code固定源码进行核对,并记录了Node.js语法检查的结果。浏览器的实际操作、渲染以及CDN响应尚未验证。屏幕说明为代码层面的预期值,与实际测量有所区别。
| 项目 | 内容 |
|---|---|
| 目标对象 | Chrome/Edge/Firefox等现代浏览器(实际设备兼容性未确认) |
| 使用的库 | SortableJS(教程内版本:1.15.6) |
| 费用 | 演示源码本身无需付费API。通信费用和使用条件取决于环境 |
| 数据 | 页面内的虚拟数据。无需凭证、位置信息或企业数据 |
| 学习操作 | 通过拖拽或按钮将任务卡片移动至已完成 |
为什么要尝试这项技术
任务列表虽然也可以用Excel表格制作,但如果想要直观地移动下一步要做的任务,卡片式的界面就会非常有用。SortableJS是一个能够轻松为元素添加拖拽排序操作的库。不过,卡片被移动了并不等于工作状态已经保存到服务器上。这次我们来制作一个只操作页面DOM的小型看板,有意识地区分“外观状态”和“数据持久化”。
在制作动态示例时,不能仅停留在“界面动了”这一表面结果上,还需要区分“哪个输入改变了哪个变量、哪段处理更新了绘制”。在本节教程中,我们会将这种变化在屏幕上明确显示出来。在实际应用到产品中时,请另外设计认证和保存等处理逻辑。
首先尝试:在线演示与预期结果
初始显示时,“未开始”栏有“🔍 调查”、“🧪 尝试”2 项,“已完成”栏有“✅ 计划”1 项。如果正常初始化,状态栏应显示为SUCCESS: 未着手 2 / 完了 1。点击一次“将首项移至已完成”,“🔍 调查”会移动,显示为SUCCESS: 未着手 1 / 完了 2,点击第二次时“🧪 尝试”会移动,显示为SUCCESS: 未着手 0 / 完了 3。第三次时没有可移动的对象,数量保持不变。通过拖拽卡片在列之间移动时,数量也会更新。仅在同一列内上下调整顺序时,数量不会改变。重新加载页面后预计会恢复到初始状态,因为并未实现 localStorage 和后端。
操作前需确认的事项
确认你的电脑能够运行 JavaScript。不需要管理员权限。
打开浏览器的开发者工具,准备在 Console 中查看是否有错误,在 Network 中查看是否有 CDN 获取失败的情况。
如果演示尚未发布,请将上述
docs/demos/sortablejs-kanban/内的index.html和app.js保存到同一个文件夹中。包含 README 的web/sortablejs-kanban/里没有用于运行的这两个文件。在终端中进入该保存文件夹,如果在 Windows 下执行py -3 -m http.server 8000 --bind 127.0.0.1,如果在 Linux/macOS 下执行python3 -m http.server 8000 --bind 127.0.0.1。在浏览器中http://127.0.0.1:8000/,结束时在终端中按 Ctrl+C。在无法使用 Python 的环境中,需要使用其他的本地 HTTP 服务器。初始的
SUCCESS并确认数量为 2 件/1 件后,点击按钮一次、再点击一次以记录数量。SUCCESS仅表示到达了初始化处理阶段,并不保证在真实设备上拖拽或 CDN 分发的成功。请在浏览器中另行确认卡片是否能够实际移动。
机制全貌
flowchart LR
A["入力やクリック"] --> B["イベントを受ける"]
B --> C["SortableJS のAPI"]
C --> D["状態と描画を更新"]
D --> E["見た目と文字で確認"]
该图是用于学习的概念图,并未表示浏览器内部实现或网络通信的细节。不过,追踪库是如何将“操作送达哪个变量”这一点是相通的。
它是如何运作的:解读 API
将 Sortable.create 应用于列元素后,便可以通过拖拽对列内的卡片进行重新排序。如果是通过 group 指定了公共分组的两个列,则允许跨列移动。移动后的 onEnd 会重新计算各列的子元素数量,并反映到屏幕上的数量中。在此,即使首张卡片移动,也不会擅自改写原有卡片的文本或标识符。在有多张卡片的状态下仅靠外观进行计数作为学习用途已足够,但在实际业务中,需要在卡片中保存不变的 task ID。
最小代码的阅读方法
for (const el of [todo, done]) {
Sortable.create(el, { group: 'tasks', animation: 160, onEnd: update });
}
上述内容是从实际的app.js中提取并保持结构以便于阅读的摘录。todo和done是前阶段通过document.querySelector获取的元素,update是重新显示数量的函数。它不是可以独立运行的完整文件。HTML 与实现合集位于 Daily Code 的docs/demos/sortablejs-kanban/内中。onEnd在拖拽完成时调用update。另一方面,按钮操作是done.append(todo.firstElementChild)之后update()直接调用。
仅修改一个条件进行比较
在实际业务中使用时,可以设计一种方案:从 onEnd 事件中读取“卡片 ID”、“移动目标列”以及“顺序”,并保存至 API。不过,绝对不能在事件触发后立即显示成功。如果服务器拒绝保存,则必须将其恢复到原位,或者明确指出未保存。作为需求,还需决定是允许在网络断开时移动,还是必须处于联网状态。
首先app.js的animation:160把animation:0改为仅一处进行修改,然后重新加载页面并比较拖拽移动动画。双方的条目数预计都从 2/1 开始,如果在列之间移动卡片,则会变为 1/2。animation是毫秒单位的动画设置,而不是用于更改卡片保存目标或条目数的设置。比较完成后,请将其改回 160。目前尚未实际测量其在浏览器中的运行结果。
操作失败时应检查哪里
仅靠拖拽操作,键盘用户将无法移动任务。在示例中,我们仅准备了一个将未开始的顶部1条任务发送至已完成的按钮并通过role="status"通知进展条目数。任意卡片的选中、从已完成移回未开始、使用键盘进行重新排序以及撤销操作均未实现,因此不能称之为完全的无障碍支持。在实际服务中,请包括焦点管理在内进行单独的实现与测试。此外,直接将 DOM 文本作为任务 ID 的设计会在出现同名任务的瞬间产生歧义,因此请避免使用。
| 观察到的状态 | 排查点 | 应对示例 |
|---|---|---|
| 屏幕与初始状态保持一致 | 获取脚本、初始化与事件注册 | 检查 控制台 / 网络 / script 标签 |
| 显示变化但含义不对 | 输入值、数组、单位、更新目标 | 固定值并逐个条件进行检查 |
| 按钮无法点击 | 选择器与 DOM 生成顺序 | 检查 HTML 确认 ID 是否一致 |
| 仅在部分设备上无法运行 | 浏览器功能、权限、CDN、性能 | 记录设备、版本以及复现操作 |
浏览器内的错误与公开 Web 服务器的故障是不同的。前者通过开发者工具中的错误内容来调查,后者通过 HTTP 响应或资产分发条件来调查。不要将未知的失败表述为成功,这能提升技术备忘录的可靠性。
在业务与学习中的应用
它可应用于故障处理进度管理、文稿编辑阶段、样本审查等待以及轻量级团队协作等。在需要审计跟踪的业务中,不仅需要浏览器 DOM,还需要在服务器上记录更新人员、更新时间和修改前后的内容。意识到外观与业务需求的边界,是这个小型演示在实务中带来的收获。
在引入前需要决定的事项
向读者公开时,需要确定显示的数据来自哪里、谁可以修改、留在屏幕上的信息种类,以及更新库时的确认事项。本次演示中既没有登录功能,也没有服务器保存功能。因此,在添加运营功能之前,建议首先区分“按预期显示的最小部分”以及“需要实务可靠性、权限和备份的部分”。由于第三方 CDN 涉及外部通信,因此必须提前确认企业网络是否允许。
与其他方式进行比较
| 方式 | 适用场景 | 注意事项 |
|---|---|---|
| SortableJS | 通过拖拽或按钮将任务卡片移动到已完成等符合目的的场景 | 需要更新依赖库并管理使用条件 |
| 浏览器标准 API | 自己编写小型功能 | 自行确认规范与兼容性 |
| 静态图片与表格 | 不需要操作的说明 | 无法当场体验状态的变化 |
库是按需选择的工具。请综合考量你想达成的目标与学习成本。在小型页面中,不把“引入库”作为目的会更容易进行维护。
GitHub 示例
博客正文负责讲解背景与思路,Daily Code 负责提供用于运行与修改的代码,两者职责分明。不包含用于向外部服务发送或保存数据的 API。
官方信息与一手资料
资料查阅范围:重新确认了 2026-10-30 SortableJS 官方 README 中的group/onEnd以及 MDN 关于拖拽操作和键盘替代方案的说明。尚未对 CDN 资产的实际加载和浏览器操作进行验证。
验证范围的补充
可以参考 Daily Code 的固定提交以及现有的 Node.js 语法检查结果。但尚未验证实际浏览器的屏幕显示、库 CDN 的响应以及在所有设备上的运行情况。请读者在自己的环境中利用控制台(Console)和网络(Network)实际确认运行情况。
