SortableJS保存和重置列表排序:完整指南
2025-03-23 02:10:22
SortableJS:保存和重置列表排序
使用 SortableJS 实现拖拽列表时,我们常需要保存当前排序,并在需要时重置回初始状态。这篇文章会讲清楚如何搞定这个事。
遇到的问题
当前代码尝试使用 alert($('#simpleList').toArray())
获取排序后的列表项,但只会得到 [object HTMLUListElement]
。重置功能也没实现。
问题原因
$('#simpleList')
返回的是一个 jQuery 对象,而不是 SortableJS 实例。toArray()
是 SortableJS 实例的方法, 不是Jquery方法。- 没有保存初始顺序。
解决方案
我们一步步解决。
1. 获取 SortableJS 实例
首先,需要正确获取 SortableJS 实例。 应该将 Sortable.create()
的返回值存储到一个变量里:
// 初始化可排序列表
var sortable = Sortable.create(simpleList, {
animation: 150
});
2. 获取当前排序
有了实例,就能用 toArray()
方法获得排序后的 data-id
值数组:
function getCurrentOrder() {
var order = sortable.toArray();
alert("当前排序:" + order.join(', '));
}
在HTML里,修改一下"Current order!"按钮的 onclick
事件:
<button type="button" onclick="getCurrentOrder()">Current order!</button>
3. 保存初始排序
为了实现重置, 我们需要在初始化之后、任何拖拽操作之前保存列表的初始状态。 在Sortable.create
后立刻获取一下就好。
var sortable = Sortable.create(simpleList, {
animation: 150
});
var initialOrder = sortable.toArray();
4. 重置排序
重置的原理就是将当前的列表项顺序调整回初始顺序。利用 sort()
方法,配合之前保存的 initialOrder
,实现起来很简单:
function resetOrder() {
sortable.sort(initialOrder);
}
给"Reset!"按钮加上对应的 onclick
事件:
<button type="button" onclick="resetOrder()">Reset!</button>
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<script src="https://raw.githack.com/SortableJS/Sortable/master/Sortable.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<!-- Simple List -->
<ul id="simpleList" class="list-group">
<li data-id="i1" class="col-1">#1</li>
<li data-id="i2" class="col-2">#2</li>
<li data-id="i3" class="col-3">#3</li>
<li data-id="i4" class="col-4">#4</li>
</ul>
<button type="button" onclick="getCurrentOrder()">Current order!</button>
<button type="button" onclick="resetOrder()">Reset!</button>
<script>
//Initiate sortable list
var sortable = Sortable.create(simpleList, {
animation: 150
});
// Save initial order.
var initialOrder = sortable.toArray();
function getCurrentOrder() {
var order = sortable.toArray();
alert("当前顺序是: " + order.join(', '));
}
function resetOrder() {
sortable.sort(initialOrder);
}
</script>
</html>
进阶用法:持久化存储排序
上面代码只是在当前页面会话有效,刷新就没了.如果想长期保存排序结果,可以用浏览器本地存储(localStorage 或 sessionStorage)或服务器端数据库。
使用 localStorage
localStorage
能把数据长期保存在浏览器里,除非用户手动清除。
- 保存排序: 在拖拽结束后,获取当前顺序,并将其存储到
localStorage
:
var sortable = Sortable.create(simpleList, {
animation: 150,
onEnd: function (/**Event*/evt) {
var currentOrder = sortable.toArray();
localStorage.setItem('mySortableListOrder', JSON.stringify(currentOrder));
},
});
onEnd
事件在拖拽完成后触发。
- 加载排序: 在页面加载时,从
localStorage
读取排序,并应用到列表:
//Check stored data:
var savedOrder = localStorage.getItem('mySortableListOrder');
if (savedOrder) {
try
{
var orderArray = JSON.parse(savedOrder);
sortable.sort(orderArray);
}
catch(e){ //Deal with parse errors.
localStorage.removeItem('mySortableListOrder');
}
}
- 注意需要处理可能出现的解析错误, 出现问题的时候,可以直接清除localstorage.
使用服务器端存储
更可靠的方法是将排序数据保存到服务器数据库。大致流程:
- 拖拽结束时发送请求: 使用 AJAX(如
fetch
或 jQuery 的$.ajax
)将当前排序发送到服务器。 - 服务器端处理: 服务器端接收数据,更新数据库中对应用户的排序记录。
- 页面加载时获取排序: 页面加载时,向服务器发送请求,获取该用户的排序数据。
- 应用排序: 服务器返回排序数据后,使用
sortable.sort()
方法应用排序。
这种方法比本地存储好,即使用户换了浏览器或设备也能用.
使用cookie
和Local Storage很像,但有一些不同:
- 存储容量限制,远小于Local Storage.
- 可以设定过期时间.
存入:
function setSortableCookie(name,value,days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
读取
function getSortableCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
删除
function eraseSortableCookie(name) {
document.cookie = name+'=; Max-Age=-99999999;';
}
使用和Local Storage相似,把localstorage的调用,换成cookie处理就好, cookie比较麻烦的一点在于,cookie会发到服务器,对于性能稍有影响,不过对当前问题影响不大.
同样需要注意错误处理.
总结
要点:
- 正确获取 SortableJS 实例。
- 使用
toArray()
获取当前排序的数组。 - 在初始化后保存一份, 方便后面还原
- 使用
sort()
方法, 配合存储下来的数据,来重置排序。 - 根据自己需求决定是不是要把数据存在本地或服务器.