SortableJS是功能強大的JavaScript 拖拽庫
其特點爲:
- 兼容性好-支持觸屏設備和大部分瀏覽器
- 簡單-簡單的API,方便使用
- 原生-基於原生HTML5中的拖放API
- CSS框架兼容性-支持所有的css框架,像Bootstrap
- 零依賴-不依賴Jquery等其他框架
- SPA支持良好-支持多種框架(angular、vue、react等)
安裝
npm install sortablejs --save
配置函數
setSort() {
const el = document.querySelectorAll(
'.el-table__body-wrapper > table > tbody'
)[0];
Sortable.create(el, {
disabled: !this.enableDrag,
ghostClass: 'sortable-ghost',
setData: function(dataTransfer) {
dataTransfer.setData('Text', '');
},
onEnd: (evt) => {
}
});
},
我們在數據加載完成之後,就調用setSort() 方法來開啓拖拽排序功能。
有關配置的細節:
var sortable = new Sortable(el, {
group: "name", // or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] }
sort: true, // boolean 定義是否列表單元是否可以在列表容器內進行拖拽排序
delay: 0, // number 定義鼠標選中列表單元可以開始拖動的延遲時間;
touchStartThreshold: 0, // px, how many pixels the point should move before cancelling a delayed drag event
disabled: false, // boolean 定義是否此sortable對象是否可用,爲true時sortable對象不能拖放排序等功能,爲false時爲可以進行排序,相當於一個開關;
store: null, // @see Store
animation: 150, // ms, number 單位:ms,定義排序動畫的時間
easing: "cubic-bezier(1, 0, 0, 1)", // Easing for animation. Defaults to null. See https://easings.net/ for examples.
handle: ".my-handle", // 格式爲簡單css選擇器的字符串,使列表單元中符合選擇器的元素成爲拖動的手柄,只有按住拖動手柄才能使列表單元進行拖動
filter: ".ignore-elements", // 過濾器,不需要進行拖動的元素
preventOnFilter: true, // 在觸發過濾器`filter`的時候調用`event.preventDefault()`
draggable: ".item", // 允許拖拽的項目類名
ghostClass: "sortable-ghost", // drop placeholder的css類名
chosenClass: "sortable-chosen", // 被選中項的css 類名
dragClass: "sortable-drag", // 正在被拖拽中的css類名
dataIdAttr: 'data-id',
swapThreshold: 1, // Threshold of the swap zone
invertSwap: false, // Will always use inverted swap zone if set to true
invertedSwapThreshold: 1, // Threshold of the inverted swap zone (will be set to swapThreshold value by default)
direction: 'horizontal', // 拖拽方向 (默認情況下會自動判斷方向)
forceFallback: false, // 忽略 HTML5拖拽行爲,強制回調進行
fallbackClass: "sortable-fallback", // 當使用forceFallback的時候,被複制的dom的css類名
fallbackOnBody: false, // 將cloned DOM 元素掛到body元素上。
fallbackTolerance: 0, // Specify in pixels how far the mouse should move before it's considered as a drag.
scroll: true, // or HTMLElement
scrollFn: function(offsetX, offsetY, originalEvent, touchEvt, hoverTargetEl) { ...
}, // if you have custom scrollbar scrollFn may be used for autoscrolling
scrollSensitivity: 30, // px, how near the mouse must be to an edge to start scrolling.
scrollSpeed: 10, // px
bubbleScroll: true, // apply autoscroll to all parent elements, allowing for easier movement
dragoverBubble: false,
removeCloneOnHide: true, // Remove the clone element when it is not showing, rather than just hiding it
emptyInsertThreshold: 5, // px, distance mouse must be from empty sortable to insert drag element into it
setData: function( /** DataTransfer */ dataTransfer, /** HTMLElement*/ dragEl) {
dataTransfer.setData('Text', dragEl.textContent); // `dataTransfer` object of HTML5 DragEvent
},
// 元素被選中
onChoose: function( /**Event*/ evt) {
evt.oldIndex; // element index within parent
},
// 元素未被選中的時候(從選中到未選中)
onUnchoose: function( /**Event*/ evt) {
// same properties as onEnd
},
// 開始拖拽的時候
onStart: function( /**Event*/ evt) {
evt.oldIndex; // element index within parent
},
// 結束拖拽
onEnd: function( /**Event*/ evt) {
var itemEl = evt.item; // dragged HTMLElement
evt.to; // target list
evt.from; // previous list
evt.oldIndex; // element's old index within old parent
evt.newIndex; // element's new index within new parent
evt.clone // the clone element
evt.pullMode; // when item is in another sortable: `"clone"` if cloning, `true` if moving
},
// 元素從一個列表拖拽到另一個列表
onAdd: function( /**Event*/ evt) {
// same properties as onEnd
},
// 列表內元素順序更新的時候觸發
onUpdate: function( /**Event*/ evt) {
// same properties as onEnd
},
// 列表的任何更改都會觸發
onSort: function( /**Event*/ evt) {
// same properties as onEnd
},
// 元素從列表中移除進入另一個列表
onRemove: function( /**Event*/ evt) {
// same properties as onEnd
},
// 試圖拖拽一個filtered的元素
onFilter: function( /**Event*/ evt) {
var itemEl = evt.item; // HTMLElement receiving the `mousedown|tapstart` event.
},
// 拖拽移動的時候
onMove: function( /**Event*/ evt, /**Event*/ originalEvent) {
// Example: https://jsbin.com/nawahef/edit?js,output
evt.dragged; // dragged HTMLElement
evt.draggedRect; // DOMRect {left, top, right, bottom}
evt.related; // HTMLElement on which have guided
evt.relatedRect; // DOMRect
evt.willInsertAfter; // Boolean that is true if Sortable will insert drag element after target by default
originalEvent.clientY; // mouse position
// return false; ? for cancel
// return -1; ? insert before target
// return 1; ? insert after target
},
// clone一個元素的時候觸發
onClone: function( /**Event*/ evt) {
var origEl = evt.item;
var cloneEl = evt.clone;
},
// 拖拽元素改變位置的時候
onChange: function( /**Event*/ evt) {
evt.newIndex // most likely why this event is used is to get the dragging element's current index
// same properties as onEnd
}
});
group:string or object
string: 命名, 個人建議用元素id就行, 用處是爲了設置可以拖放容器時使用, 在array中的put的設置中再做介紹;
object: {
name,
pull,
put
}
name: 同string的方法,
pull: pull用來定義從這個列表容器移動出去的設置, true / false / 'clone' / function
true: 列表容器內的列表單元可以被移出;
false: 列表容器內的列表單元不可以被移出;
'clone':
列表單元移出, 移動的爲該元素的副本;
function: 用來進行pull的函數判斷, 可以進行復雜邏輯, 在函數中return false / true來判斷是否移出;
put: put用來定義往這個列表容器放置列表單元的的設置, true / false / ['foo', 'bar'] / function
true: 列表容器可以從其他列表容器內放入列表單元;
false: 與true相反;
['foo', 'bar']: 這個可以是一個字符串或者是字符串的數組, 代表的是group配置項裏定義的name值;
function: 用來進行put的函數判斷, 可以進行復雜邏輯, 在函數中return false / true來判斷是否放入;
sort:boolean 定義是否列表單元是否可以在列表容器內進行拖拽排序;
delay:number 定義鼠標選中列表單元可以開始拖動的延遲時間;
disabled:boolean 定義是否此sortable對象是否可用,爲true時sortable對象不能拖放排序等功能,爲false時爲可以進行排序,相當於一個開關;
animation:number 單位:ms,定義排序動畫的時間;
handle:selector 格式爲簡單css選擇器的字符串,使列表單元中符合選擇器的元素成爲拖動的手柄,只有按住拖動手柄才能使列表單元進行拖動;
filter:selector 格式爲簡單css選擇器的字符串,定義哪些列表單元不能進行拖放,可設置爲多個選擇器,中間用“,”分隔;
draggable:selector 格式爲簡單css選擇器的字符串,定義哪些列表單元可以進行拖放
ghostClass:selector 格式爲簡單css選擇器的字符串,當拖動列表單元時會生成一個副本作爲影子單元來模擬被拖動單元排序的情況,此配置項就是來給這個影子單元添加一個class,我們可以通過這種方式來給影子元素進行編輯樣式;
chosenClass:selector 格式爲簡單css選擇器的字符串,當選中列表單元時會給該單元增加一個class;
forceFallback:boolean 如果設置爲true時,將不使用原生的html5的拖放,可以修改一些拖放中元素的樣式等;
fallbackClass:string 當forceFallback設置爲true時,拖放過程中鼠標附着單元的樣式;
scroll:boolean 默認爲true,當排序的容器是個可滾動的區域,拖放可以引起區域滾動
事件
onChoose:function 列表單元被選中的回調函數
onStart:function 列表單元拖動開始的回調函數
onEnd:function 列表單元拖放結束後的回調函數
onAdd:function 列表單元添加到本列表容器的回調函數
onUpdate:function 列表單元在列表容器中的排序發生變化後的回調函數
onRemove:function 列表元素移到另一個列表容器的回調函數
onFilter:function 試圖選中一個被filter過濾的列表單元的回調函數
onMove:function 當移動列表單元在一個列表容器中或者多個列表容器中的回調函數
onClone:function 當創建一個列表單元副本的時候的回調函數