Sortable.js是一款优秀的js拖拽库,支持ie9及以上版本ie浏览器和现代浏览器,也可以运行在移动触摸设备中。不依赖jQuery。支持 Meteor、AngularJS、React、Vue、Knockout框架和任何CSS库,如Bootstrap、Element UI。你可以用来拖拽div、table等元素。
https://github.com/SortableJS/Sortable
fix:可拖动到末尾元素
fix:从克隆元素中删除 ID
fix:MultiDrag 添加avoidImplicitDeselect选项
vue2版中文文档请访问: vue.draggable
vue3版中文文档请访问: vue.draggable.next
$ npm install sortablejs --save
$ bower install --save sortablejs
// Default SortableJS
import Sortable from 'sortablejs';
// Core SortableJS (without default plugins)
import Sortable from 'sortablejs/modular/sortable.core.esm.js';
// Complete SortableJS (with all plugins)
import Sortable from 'sortablejs/modular/sortable.complete.esm.js';
<script src="https://www.itxst.com/package/sortable/sortable.min.js"></script>
<div id="itxst">
<div data-id="1">item 1</div>
<div data-id="2">item 2</div>
<div data-id="3">item 3</div>
</div>
<script>
//获取对象
var el = document.getElementById('itxst');
//设置配置
var ops = {
animation: 1000,
//拖动结束
onEnd: function (evt) {
console.log(evt);
//获取拖动后的排序
var arr = sortable.toArray();
alert(JSON.stringify(arr));
},};
//初始化
var sortable = Sortable.create(el, ops);
</script>
var sortable = new Sortable(el, {
//一个网页存在多个分组时设置
//or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] }
group: "name",
//是否允许列内部排序,如果为false当有多个排序组时,多个组之间可以拖拽,本身不能拖拽
sort: true,
// 按下鼠标后多久可以拖拽 1000表示1秒
delay: 0,
//如果为false按下鼠标不动才计算延时,移动则无效
delayOnTouchOnly: false,
//当按下鼠标移动了n个像素时会取消延迟delay事件,即可超过了这个范围无法拖动元素了
//px, how many pixels the point should move before cancelling a delayed drag event
touchStartThreshold: 0,
//启用禁用拖拽
disabled: false,
//Store
store: null,
//动画效果
animation: 150,
// Easing 动画 默认null. See https://easings.net/ for examples.
easing: "cubic-bezier(1, 0, 0, 1)",
//句柄,点击指定class样式的对象才能拖拽元素
handle: ".my-handle",
//忽略class为ignore-elements的元素不能拖动,或者通过函数来实现过滤不允许拖动的对象
// Selectors that do not lead to dragging (String or Function)
filter: ".ignore-elements",
//触发filter时调用`event.preventDefault()`
// Call `event.preventDefault()` when triggered `filter`
preventOnFilter: true,
//指定那些元素可以被拖拽
// Specifies which items inside the element should be draggable
draggable: ".item",
//指定获取拖动后排序的data属性
dataIdAttr: 'data-id',
//停靠位置的自定义样式
// Class name for the drop placeholder
ghostClass: "sortable-ghost",
//选中元素的自定义样式
// Class name for the chosen item
chosenClass: "sortable-chosen",
//拖拽时的自定义样式
// Class name for the dragging item
dragClass: "sortable-drag",
//交互区大小,A元素到B元素内多深的距离触发替换位置
//Threshold of the swap zone
swapThreshold: 1,
// Will always use inverted swap zone if set to true
invertSwap: false,
// Threshold of the inverted swap zone (will be set to swapThreshold value by default)
invertedSwapThreshold: 1,
//拖拽方向(默认会自动判断方向)
direction: 'horizontal',
//忽略HTML5原生拖拽行为
forceFallback: false,
//拖拽时被克隆元素的样式名称
// Class name for the cloned DOM Element when using forceFallback
fallbackClass: "sortable-fallback",
// Appends the cloned DOM Element into the Document's Body
fallbackOnBody: false,
// Specify in pixels how far the mouse should move before it's considered as a drag.
fallbackTolerance: 0,
dragoverBubble: false,
// Remove the clone element when it is not showing, rather than just hiding it
removeCloneOnHide: true,
// px, distance mouse must be from empty sortable to insert drag element into it
emptyInsertThreshold: 5,
setData: function (/** DataTransfer */dataTransfer, /** HTMLElement*/dragEl) {
dataTransfer.setData('Text', dragEl.textContent); // `dataTransfer` object of HTML5 DragEvent
},
//点击选中元素事件
// Element is chosen
onChoose: function (/**Event*/evt) {
evt.oldIndex; // element index within parent
},
//取消选中事件
// Element is unchosen
onUnchoose: function (/**Event*/evt) {
// same properties as onEnd
},
//开始拖拽事件
// Element dragging started
onStart: function (/**Event*/evt) {
evt.oldIndex; // element index within parent
},
//结束拖拽事件
// Element dragging ended
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.oldDraggableIndex; // element's old index within old parent, only counting draggable elements
evt.newDraggableIndex; // element's new index within new parent, only counting draggable elements
evt.clone // the clone element
evt.pullMode; // when item is in another sortable: `"clone"` if cloning, `true` if moving
},
// 被拖拽的元素加入到其他列表时的事件
// Element is dropped into the list from another list
onAdd: function (/**Event*/evt) {
// same properties as onEnd
},
//排序发生改变时的事件
// Changed sorting within list
onUpdate: function (/**Event*/evt) {
// same properties as onEnd
},
// Called by any change to the list (add / update / remove)
onSort: function (/**Event*/evt) {
// same properties as onEnd
},
// Element is removed from the list into another list
onRemove: function (/**Event*/evt) {
// same properties as onEnd
},
// Attempt to drag a filtered element
onFilter: function (/**Event*/evt) {
var itemEl = evt.item; // HTMLElement receiving the `mousedown|tapstart` event.
},
// Event when you move an item in the list or between lists
onMove: function (/**Event*/evt, /**Event*/originalEvent) {
/*
evt.dragged; // 被拖拽的对象
evt.draggedRect; // 被拖拽的对象所在区域 {left, top, right, bottom}
evt.related; // 被替换的对象
evt.relatedRect; // DOMRect
evt.willInsertAfter; // 是在被替换对象的前面还是后面
originalEvent.clientY; // 鼠标的位置
*/
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
},
// Called when creating a clone of element
onClone: function (/**Event*/evt) {
var origEl = evt.item;
var cloneEl = evt.clone;
},
// Called when dragging element changes position
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
}
});
table表格要实现拖拽行,需要在每行加上tbody比较特殊
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>sortable.js table表格拖拽例子</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
<script src="https://www.itxst.com/package/sortable/sortable.min.js"></script>
</head>
<body>
<table id="itxst">
<tbody>
<tr>
<td>1</td>
<td>www.baidu.com</td>
</tr>
</tbody>
<tbody>
<tr>
<td>2</td>
<td>www.itxst.com</td>
</tr>
</tbody>
</table>
<script>
//获取对象
var el = document.getElementById('itxst');
//设置配置
var ops = { animation: 1000 };
//初始化
var sortable = Sortable.create(el, ops);
</script>
</body>
</html>