视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
JS拖拽排序插件Sortable.js用法实例分析
2020-11-27 22:00:41 责编:小采
文档


本文实例讲述了JS拖拽排序插件Sortable.js用法。分享给大家供大家参考,具体如下:

最近由于项目功能设计的原因,需要对table中的行实现拖拽排序功能,找来找去发现Sortable.js能很好的满足这个需求,而且它还是开源的,于是乎就开始学习使用Sortable.js,再然后就有了这篇文章。

特点:

  • 轻量级但功能强大
  • 移动列表项时有动画
  • 支持触屏设备和大多数浏览器(IE9及以下除外)
  • 支持单个列表容器内部拖拽排序,也支持两个列表容器互相拖拽排序
  • 支持拖放操作和可选择的文本
  • 非常友善的滚动效果
  • 基于原生HTML5中的拖放API
  • 支持多种框架(Angular、Vue、React等)
  • 支持所有的CSS框架,如:Bootstrap
  • 简单的API,方便调用
  • CDN
  • 不依赖于jQuery
  • 下载地址:https://github.com/RubaXa/Sortable
    或者点击此处本站下载

    运行效果如下图所示:

    单个列表容器内部拖拽排序

    <head>
     <script src="~/Scripts/jquery-3.3.1.min.js"></script>
     <script src="~/Scripts/Sortable-master/Sortable.min.js"></script>
     <script type="text/javascript">
     $(document).ready(function () {
     var ul = document.getElementById("infos");
     var sortable = new Sortable(ul, {
     handle: "input,li",//设置li、input支持拖拽
     animation: 150,//设置动画时长
     // Element dragging started
     onStart: function (/**Event*/evt) {
     evt.oldIndex; // element index within parent,此处指的是li的索引值
     },
     // Element dragging ended
     onEnd: function (/**Event*/evt) {
     var lis = $("#infos li");
     //拖拽完毕后重新设置序号,使其连续
     for (var i = 0; i < lis.length; i++) {
     var no = $(lis[i]).find("input:eq(0)");
     no.val(i + 1);
     }
     }
     });
     });
     </script>
     <style>
     li{
     cursor:pointer;
     padding-bottom:5px;
     list-style:none;
     }
     </style>
    </head>
    <body>
     <ul id="infos">
     <li>
     <input type="text" value="1" />
     <input type="text" value="hierarchy" />
     <select>
     <option value="">--请选择--</option>
     <option value="1">objective</option>
     <option value="2">proposition</option>
     </select>
     </li>
     <li>
     <input type="text" value="2" />
     <input type="text" value="hierarchy" />
     <select>
     <option value="">--请选择--</option>
     <option value="1">eliminate</option>
     <option value="2">alige</option>
     </select>
     </li>
     <li>
     <input type="text" value="3" />
     <input type="text" value="hierarchy" />
     <select>
     <option value="">--请选择--</option>
     <option value="1">optimize</option>
     <option value="2">deploy</option>
     </select>
     </li>
     </ul>
    </body>
    
    

    两个列表容器相互拖拽排序

    <head>
     <script src="~/Scripts/jquery-3.3.1.min.js"></script>
     <script src="~/Scripts/Sortable-master/Sortable.min.js"></script>
     <script type="text/javascript">
     $(document).ready(function () {
     var infosOne = document.getElementById("infosOne");
     var sortableOne = new Sortable(infosOne, {
     group: "guo",//若需要在两个列表容器间拖拽排序,那group的值必须相同
     handle: "input,li",//设置li、input支持拖拽
     animation: 150,//设置动画时长
     // Element dragging started
     onStart: function (/**Event*/evt) {
     evt.oldIndex; // element index within parent,此处指的是li的索引值
     },
     // Element dragging ended
     onEnd: function (/**Event*/evt) {
     var lis = $("#infosOne li");
     for (var i = 0; i < lis.length; i++) {
     var no = $(lis[i]).find("input:eq(0)");
     no.val(i + 1);
     }
     lis = $("#infosTwo li");
     for (var i = 0; i < lis.length; i++) {
     var no = $(lis[i]).find("input:eq(0)");
     no.val(i + 1);
     }
     }
     });
     var infosTwo = document.getElementById("infosTwo");
     var sortableTwo = new Sortable(infosTwo, {
     group:"guo",//若需要在两个列表容器间拖拽排序,那group的值必须相同
     handle: "input,li",//设置li、input支持拖拽
     animation: 150,//设置动画时长
     // Element dragging started
     onStart: function (/**Event*/evt) {
     evt.oldIndex; // element index within parent,此处指的是li的索引值
     },
     // Element dragging ended
     onEnd: function (/**Event*/evt) {
     var lis = $("#infosOne li");
     for (var i = 0; i < lis.length; i++) {
     var no = $(lis[i]).find("input:eq(0)");
     no.val(i + 1);
     }
     lis = $("#infosTwo li");
     for (var i = 0; i < lis.length; i++) {
     var no = $(lis[i]).find("input:eq(0)");
     no.val(i + 1);
     }
     }
     });
     });
     </script>
    </head>
    <body>
     <ul id="infosOne">
     <li>
     <input type="text" value="1" />
     <input type="text" value="hierarchy" />
     <select>
     <option value="">--请选择--</option>
     <option value="1">objective</option>
     <option value="2">proposition</option>
     </select>
     </li>
     <li>
     <input type="text" value="2" />
     <input type="text" value="hierarchy" />
     <select>
     <option value="">--请选择--</option>
     <option value="1">eliminate</option>
     <option value="2">alige</option>
     </select>
     </li>
     <li>
     <input type="text" value="3" />
     <input type="text" value="hierarchy" />
     <select>
     <option value="">--请选择--</option>
     <option value="1">optimize</option>
     <option value="2">deploy</option>
     </select>
     </li>
     </ul>
     <hr />
     <ul id="infosTwo">
     <li>
     <input type="text" value="1" />
     <input type="text" value="hierarchy" />
     <select>
     <option value="">--请选择--</option>
     <option value="1">目标任务</option>
     <option value="2">论题议题</option>
     </select>
     </li>
     <li>
     <input type="text" value="2" />
     <input type="text" value="hierarchy" />
     <select>
     <option value="">--请选择--</option>
     <option value="1">消除排除</option>
     <option value="2">机敏的敏捷的</option>
     </select>
     </li>
     <li>
     <input type="text" value="3" />
     <input type="text" value="hierarchy" />
     <select>
     <option value="">--请选择--</option>
     <option value="1">优化使最优化</option>
     <option value="2">发布部署</option>
     </select>
     </li>
     </ul>
    </body>
    
    

    常见配置项及事件

    var sortable = new Sortable(el, {
     group: "name", // or { name: "...", pull: [true, false, clone], put: [true, false, array] }
     sort: true, // sorting inside list
     delay: 0, // time in milliseconds to define when the sorting should start
     touchStartThreshold: 0, // px, how many pixels the point should move before cancelling a delayed drag event
     disabled: false, // Disables the sortable if set to true.
     store: null, // @see Store
     animation: 150, // ms, animation speed moving items when sorting, `0` — without animation
     handle: ".my-handle", // Drag handle selector within list items
     filter: ".ignore-elements", // Selectors that do not lead to dragging (String or Function)
     preventOnFilter: true, // Call `event.preventDefault()` when triggered `filter`
     draggable: ".item", // Specifies which items inside the element should be draggable
     ghostClass: "sortable-ghost", // Class name for the drop placeholder
     chosenClass: "sortable-chosen", // Class name for the chosen item
     dragClass: "sortable-drag", // Class name for the dragging item
     dataIdAttr: 'data-id',
     forceFallback: false, // ignore the HTML5 DnD behaviour and force the fallback to kick in
     fallbackClass: "sortable-fallback", // Class name for the cloned DOM Element when using forceFallback
     fallbackOnBody: false, // Appends the cloned DOM Element into the Document's 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
     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 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
     },
     // 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) {
     // Example: http://jsbin.com/tuyafe/1/edit?js,output
     evt.dragged; // dragged HTMLElement
     evt.draggedRect; // TextRectangle {left, top, right и bottom}
     evt.related; // HTMLElement on which have guided
     evt.relatedRect; // TextRectangle
     originalEvent.clientY; // mouse position
     // return false; — for cancel
     },
     // Called when creating a clone of element
     onClone: function (/**Event*/evt) {
     var origEl = evt.item;
     var cloneEl = evt.clone;
     }
    });
    
    

    属性

    group:string or array
    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 当创建一个列表单元副本的时候的回调函数

    事件对象:

    事件对象在各个函数中略有不同,可通过输出对象查看对象的属性,下面简单列举几个:

    to:HTMLElement--移动到列表容器
    from:HTMLElement--来源的列表容器
    item:HTMLElement--被移动的列表单元
    clone:HTMLElement--副本的列表单元
    oldIndex:number/undefined--在列表容器中的原序号
    newIndex:number/undefined--在列表容器中的新序号

    方法

    option(name[,value])
    获得或者设置项参数,使用方法类似于jQuery用法,没有第二个参数为获得option中第一个参数所对应的值,有第二个参数时,将重新赋给第一个参数所对应的值;

    closest
    返回满足selector条件的元素集合中的第一个项

    toArray()
    序列化可排序的列表单元的data-id(可通过配置项中dataIdAttr修改)放入一个数组,并返回这个数组中

    sort()
    通过自定义列表单元的data-id的数组对列表单元进行排序

    save()

    destroy()

    PS:这里再为大家推荐一款关于排序的演示工具供大家参考:

    在线动画演示插入/选择/冒泡/归并/希尔/快速排序算法过程工具:
    http://tools.jb51.net/aideddesign/paixu_ys

    更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript表格(table)操作技巧大全》、《JavaScript操作DOM技巧总结》、《JavaScript遍历算法与技巧总结》、《JavaScript数算用法总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript查找算法技巧总结》及《JavaScript错误与调试技巧总结》

    希望本文所述对大家JavaScript程序设计有所帮助。

    下载本文
    显示全文
    专题