前言:很多時(shí)候我們都有這樣的一種需求:在一個(gè)數(shù)據(jù)列表中叹括,對(duì)數(shù)據(jù)進(jìn)行排序瀑晒,然后這個(gè)排序又希望用戶體驗(yàn)好一點(diǎn)绍坝,頁(yè)面不刷新,也不需要彈出修改數(shù)據(jù)的彈出層苔悦,直接在列表中拖拽數(shù)據(jù)實(shí)現(xiàn)排序轩褐。那么這樣的需求可以如何實(shí)現(xiàn)呢?這就需要用到前端的拖拽插件了玖详,前端拖拽插件有很多把介,這里選擇的是Sortable插件。
下載插件
Sortable是可以實(shí)現(xiàn)DOM元素拖拽效果的前端插件蟋座,它的包很小拗踢,簡(jiǎn)單易用,功能齊全蜈七,效果很好秒拔,它不依賴(lài)jQuery庫(kù),是使用原生JavaScript開(kāi)發(fā)的飒硅。最重要的是它可以讓我們完成列表數(shù)據(jù)拖拽排序的需求砂缩。
下載地址:https://github.com/RubaXa/Sortable
官方DEMO:http://rubaxa.github.io/Sortable/
開(kāi)始使用
在頁(yè)面初始化成功后,創(chuàng)建出Sortable對(duì)象三娩,然后傳入需要拖拽的DOM元素庵芭,該DOM元素應(yīng)該是一個(gè)列表,這樣雀监,該列表下的數(shù)據(jù)就能拖拽了:
$(function () {
//給需要做拖拽排序的dom對(duì)象實(shí)例化出拖拽排序的對(duì)象
var el = $("#items")[0];
Sortable sortable = new Sortable(el);
})
完成拖拽排序
然后結(jié)合Sortable的其他屬性和方法双吆,調(diào)用后臺(tái)程序就能完成拖拽排序的需求。在初始化Sortable代碼的基礎(chǔ)上進(jìn)行改造会前,加上拖拽數(shù)據(jù)事件好乐,觸發(fā)了該事件就把拖拽后的數(shù)據(jù)傳到后臺(tái),然后由后臺(tái)程序完成數(shù)據(jù)重新排序:
//Sortable對(duì)象提取出來(lái)
var sortable;
$(function () {
//給需要做拖拽排序的dom對(duì)象實(shí)例化出拖拽排序的對(duì)象,并添加數(shù)據(jù)拖拽事件
var el = $("#items")[0];
sortable = new Sortable(el,{
onUpdate:updateSort
});
})
//更新數(shù)據(jù)排序方法
function updateSort() {
//調(diào)用Sortable對(duì)象的toArray方法瓦宜,該方法的作用看下面屬性和方法的詳細(xì)介紹
var ids = sortable.toArray();
$.ajax({
url:"xxx",
type:"POST",
data:JSON.stringify(ids),
contentType:"application/json",
dataType:"json"
})
}
其他屬性和方法
屬性:
group:string or array
sort:boolean 定義是否列表單元是否可以在列表容器內(nèi)進(jìn)行拖拽排序蔚万;
delay:number 定義鼠標(biāo)選中列表單元可以開(kāi)始拖動(dòng)的延遲時(shí)間;
disabled:boolean 定義是否此sortable對(duì)象是否可用临庇,為true時(shí)sortable對(duì)象不能拖放排序等功能反璃,為false時(shí)為可以進(jìn)行排序,相當(dāng)于一個(gè)開(kāi)關(guān)假夺;
animation:number 單位:ms淮蜈,定義排序動(dòng)畫(huà)的時(shí)間;
handle:selector 格式為簡(jiǎn)單css選擇器的字符串已卷,使列表單元中符合選擇器的元素成為拖動(dòng)的手柄梧田,只有按住拖動(dòng)手柄才能使列表單元進(jìn)行拖動(dòng);
filter:selector 格式為簡(jiǎn)單css選擇器的字符串,定義哪些列表單元不能進(jìn)行拖放柿扣,可設(shè)置為多個(gè)選擇器肖方,中間用“,”分隔未状;
draggable:selector 格式為簡(jiǎn)單css選擇器的字符串俯画,定義哪些列表單元可以進(jìn)行拖放
ghostClass:selector 格式為簡(jiǎn)單css選擇器的字符串,當(dāng)拖動(dòng)列表單元時(shí)會(huì)生成一個(gè)副本作為影子單元來(lái)模擬被拖動(dòng)單元排序的情況司草,此配置項(xiàng)就是來(lái)給這個(gè)影子單元添加一個(gè)class艰垂,我們可以通過(guò)這種方式來(lái)給影子元素進(jìn)行編輯樣式;
chosenClass:selector 格式為簡(jiǎn)單css選擇器的字符串埋虹,當(dāng)選中列表單元時(shí)會(huì)給該單元增加一個(gè)class猜憎;
forceFallback:boolean 如果設(shè)置為true時(shí),將不使用原生的html5的拖放搔课,可以修改一些拖放中元素的樣式等胰柑;
fallbackClass:string 當(dāng)forceFallback設(shè)置為true時(shí),拖放過(guò)程中鼠標(biāo)附著單元的樣式爬泥;
scroll:boolean 默認(rèn)為true柬讨,當(dāng)排序的容器是個(gè)可滾動(dòng)的區(qū)域,拖放可以引起區(qū)域滾動(dòng)
事件:
onChoose:function 列表單元被選中的回調(diào)函數(shù)
onStart:function 列表單元拖動(dòng)開(kāi)始的回調(diào)函數(shù)
onEnd:function 列表單元拖放結(jié)束后的回調(diào)函數(shù)
onAdd:function 列表單元添加到本列表容器的回調(diào)函數(shù)
onUpdate:function 列表單元在列表容器中的排序發(fā)生變化后的回調(diào)函數(shù)
onRemove:function 列表元素移到另一個(gè)列表容器的回調(diào)函數(shù)
onFilter:function 試圖選中一個(gè)被filter過(guò)濾的列表單元的回調(diào)函數(shù)
onMove:function 當(dāng)移動(dòng)列表單元在一個(gè)列表容器中或者多個(gè)列表容器中的回調(diào)函數(shù)
onClone:function 當(dāng)創(chuàng)建一個(gè)列表單元副本的時(shí)候的回調(diào)函數(shù)
事件對(duì)象:
事件對(duì)象在各個(gè)函數(shù)中略有不同袍啡,可通過(guò)輸出對(duì)象查看對(duì)象的屬性踩官,下面簡(jiǎn)單列舉幾個(gè):
to:HTMLElement--移動(dòng)到列表容器
from:HTMLElement--來(lái)源的列表容器
item:HTMLElement--被移動(dòng)的列表單元
clone:HTMLElement--副本的列表單元
oldIndex:number/undefined--在列表容器中的原序號(hào)
newIndex:number/undefined--在列表容器中的新序號(hào)
方法
option(name[,value])
獲得或者設(shè)置項(xiàng)參數(shù),使用方法類(lèi)似于jQuery用法境输,沒(méi)有第二個(gè)參數(shù)為獲得option中第一個(gè)參數(shù)所對(duì)應(yīng)的值蔗牡,有第二個(gè)參數(shù)時(shí),將重新賦給第一個(gè)參數(shù)所對(duì)應(yīng)的值嗅剖;
toArray()
序列化可排序的列表單元的data-id(可通過(guò)配置項(xiàng)中dataIdAttr修改)放入一個(gè)數(shù)組辩越,并返回這個(gè)數(shù)組中
sort()
通過(guò)自定義列表單元的data-id的數(shù)組對(duì)列表單元進(jìn)行排序
save()
destroy()