sortable.js中文文档

Sortable.js是一款优秀的js拖拽库,支持ie9及以上版本ie浏览器和现代浏览器,也可以运行在移动触摸设备中。不依赖jQuery。支持 Meteor、AngularJS、React、Vue、Knockout框架和任何CSS库,如Bootstrap、Element UI。你可以用来拖拽div、table等元素。

官方网站

https://github.com/SortableJS/Sortable

Sortable.js下载

下载文件

版本更新

v1.15.0 2022 年 3 月 21 日

fix:可拖动到末尾元素
fix:从克隆元素中删除 ID
fix:MultiDrag 添加avoidImplicitDeselect选项

其他版本文档

vue2版中文文档请访问:  vue.draggable  
vue3版中文文档请访问:  vue.draggable.next

npm安装方式

$ npm install sortablejs --save

Bower安装方式

$ bower install --save sortablejs

es导入方式

// 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';

umd方式

<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>

在线试一试