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

相关文档推荐:
官方文档 https://github.com/SortableJS/Sortable
中文文档 https://www.itxst.com/sortablejs
演示 http://sortablejs.github.io/Sortable/

开始

npm方式安装

$ npm install sortablejs --save

Bower方式安装

$ bower install --save sortablejs

引入项目方式

// 默认
import Sortable from 'sortablejs';// 没有默认插件
import Sortable from 'sortablejs/modular/sortable.core.esm.js';// 包含所有插件
import Sortable from 'sortablejs/modular/sortable.complete.esm.js';

Cherrypick plugins

// Cherrypick extra plugins
import Sortable, { MultiDrag, Swap } from 'sortablejs';Sortable.mount(new MultiDrag(), new Swap());// Cherrypick default plugins
import Sortable, { AutoScroll } from 'sortablejs/modular/sortable.core.esm.js';Sortable.mount(new AutoScroll());

示例

<ul id="items"><li>item 1</li><li>item 2</li><li>item 3</li>
</ul>
var el = document.getElementById('items');
var sortable = Sortable.create(el);

完整配置项

var sortable = new Sortable(el, {group: "name",  // or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] }sort: true,  // sorting inside listdelay: 0, // time in milliseconds to define when the sorting should startdelayOnTouchOnly: false, // only delay if user is using touchtouchStartThreshold: 0, // px, how many pixels the point should move before cancelling a delayed drag eventdisabled: false, // Disables the sortable if set to true.store: null,  // @see Storeanimation: 150,  // ms, animation speed moving items when sorting, `0` — without animationeasing: "cubic-bezier(1, 0, 0, 1)", // Easing for animation. Defaults to null. See https://easings.net/ for examples.handle: ".my-handle",  // Drag handle selector within list itemsfilter: ".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 draggabledataIdAttr: 'data-id', // HTML attribute that is used by the `toArray()` methodghostClass: "sortable-ghost",  // Class name for the drop placeholderchosenClass: "sortable-chosen",  // Class name for the chosen itemdragClass: "sortable-drag",  // Class name for the dragging itemswapThreshold: 1, // Threshold of the swap zoneinvertSwap: false, // Will always use inverted swap zone if set to trueinvertedSwapThreshold: 1, // Threshold of the inverted swap zone (will be set to swapThreshold value by default)direction: 'horizontal', // Direction of Sortable (will be detected automatically if not given)forceFallback: false,  // ignore the HTML5 DnD behaviour and force the fallback to kick infallbackClass: "sortable-fallback",  // Class name for the cloned DOM Element when using forceFallbackfallbackOnBody: false,  // Appends the cloned DOM Element into the Document's BodyfallbackTolerance: 0, // Specify in pixels how far the mouse should move before it's considered as a drag.dragoverBubble: false,removeCloneOnHide: true, // Remove the clone element when it is not showing, rather than just hiding itemptyInsertThreshold: 5, // px, distance mouse must be from empty sortable to insert drag element into itsetData: function (/** DataTransfer */dataTransfer, /** HTMLElement*/dragEl) {dataTransfer.setData('Text', dragEl.textContent); // `dataTransfer` object of HTML5 DragEvent},// Element is chosenonChoose: function (/**Event*/evt) {evt.oldIndex;  // element index within parent},// Element is unchosenonUnchoose: function(/**Event*/evt) {// same properties as onEnd},// Element dragging startedonStart: function (/**Event*/evt) {evt.oldIndex;  // element index within parent},// Element dragging endedonEnd: function (/**Event*/evt) {var itemEl = evt.item;  // dragged HTMLElementevt.to;    // target listevt.from;  // previous listevt.oldIndex;  // element's old index within old parentevt.newIndex;  // element's new index within new parentevt.oldDraggableIndex; // element's old index within old parent, only counting draggable elementsevt.newDraggableIndex; // element's new index within new parent, only counting draggable elementsevt.clone // the clone elementevt.pullMode;  // when item is in another sortable: `"clone"` if cloning, `true` if moving},// Element is dropped into the list from another listonAdd: function (/**Event*/evt) {// same properties as onEnd},// Changed sorting within listonUpdate: 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 listonRemove: function (/**Event*/evt) {// same properties as onEnd},// Attempt to drag a filtered elementonFilter: function (/**Event*/evt) {var itemEl = evt.item;  // HTMLElement receiving the `mousedown|tapstart` event.},// Event when you move an item in the list or between listsonMove: function (/**Event*/evt, /**Event*/originalEvent) {// Example: https://jsbin.com/nawahef/edit?js,outputevt.dragged; // dragged HTMLElementevt.draggedRect; // DOMRect {left, top, right, bottom}evt.related; // HTMLElement on which have guidedevt.relatedRect; // DOMRectevt.willInsertAfter; // Boolean that is true if Sortable will insert drag element after target by defaultoriginalEvent.clientY; // mouse position// return false; — for cancel// return -1; — insert before target// return 1; — insert after target// return true; — keep default insertion point based on the direction// return void; — keep default insertion point based on the direction},// Called when creating a clone of elementonClone: function (/**Event*/evt) {var origEl = evt.item;var cloneEl = evt.clone;},// Called when dragging element changes positiononChange: 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来判断是否放入;

演示:
https://jsbin.com/hijetos/edit?js,output
https://jsbin.com/nacoyah/edit?js,output
https://jsbin.com/bifuyab/edit?js,output

sort:boolean 定义是否列表单元是否可以在列表容器内进行拖拽排序;
演示:
https://jsbin.com/jayedig/edit?js,output

delay:number 定义鼠标选中列表单元可以开始拖动的延迟时间;
演示:
https://jsbin.com/zosiwah/edit?js,output

disabled:boolean 定义是否此sortable对象是否可用,为true时sortable对象不能拖放排序等功能,为false时为可以进行排序,相当于一个开关;
演示:
https://jsbin.com/sewokud/edit?js,output

animation:number 单位:ms,定义排序动画的时间;

handle:selector 格式为简单css选择器的字符串,使列表单元中符合选择器的元素成为拖动的手柄,只有按住拖动手柄才能使列表单元进行拖动;
演示:
https://jsbin.com/numakuh/edit?html,js,output

filter:selector 格式为简单css选择器的字符串,定义哪些列表单元不能进行拖放,可设置为多个选择器,中间用“,”分隔;

draggable:selector 格式为简单css选择器的字符串,定义哪些列表单元可以进行拖放

ghostClass:selector 格式为简单css选择器的字符串,当拖动列表单元时会生成一个副本作为影子单元来模拟被拖动单元排序的情况,此配置项就是来给这个影子单元添加一个class,我们可以通过这种方式来给影子元素进行编辑样式;
演示:
https://jsbin.com/henuyiw/edit?css,js,output

chosenClass:selector 格式为简单css选择器的字符串,当选中列表单元时会给该单元增加一个class;
演示:
https://jsbin.com/hoqufox/edit?css,js,output

forceFallback:boolean 如果设置为true时,将不使用原生的html5的拖放,可以修改一些拖放中元素的样式等;
演示:
https://jsbin.com/sibiput/edit?html,css,js,output

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
没理解
toArray()
序列化可排序的列表单元的data-id(可通过配置项中dataIdAttr修改)放入一个数组,并返回这个数组中
sort()
通过自定义列表单元的data-id的数组对列表单元进行排序
save()
destroy()

Store

保存和恢复排序。

<ul><li data-id="1">order</li><li data-id="2">save</li><li data-id="3">restore</li>
</ul>
Sortable.create(el, {group: "localStorage-example",store: {/*** Get the order of elements. Called once during initialization.* @param   {Sortable}  sortable* @returns {Array}*/get: function (sortable) {var order = localStorage.getItem(sortable.options.group.name);return order ? order.split('|') : [];},/*** Save the order of elements. Called onEnd (when the item is dropped).* @param {Sortable}  sortable*/set: function (sortable) {var order = sortable.toArray();localStorage.setItem(sortable.options.group.name, order.join('|'));}}
})

js拖拽库——Sortable.js相关推荐

  1. js 拖拽生成html,js拖拽插件 js 拖拽控件生成自定义表单 怎么实现

    想请教一个js的问题,拖拽控件 js 拖拽控件生成自定义表单 怎么实现 说说步骤吧 监听mousedown事件 - 获取鼠标点击元素,判断是否可拖拽 - 设置flag做标记 - 建一个tempDOM, ...

  2. vue.js 拖拽排序_快速轻巧的Vue.js拖放可排序库

    vue.js 拖拽排序 vue-smooth-dnd (vue-smooth-dnd) A fast and lightweight drag&drop, sortable library f ...

  3. html列表拖拽排序插件,js拖拽排序插件Sortable

    插件描述:功能强大的Javript拖拽排序库Sortable,拖拽兼容性好,零依赖 更新时间:2020-05-15 18:19:16 SortableJS 功能强大的JavaScript 拖拽库 特性 ...

  4. html列表拖拽排序插件,JS拖拽排序插件Sortable.js用法实例分析

    本文实例讲述了JS拖拽排序插件Sortable.js用法.分享给大家供大家参考,具体如下: 最近由于项目功能设计的原因,需要对table中的行实现拖拽排序功能,找来找去发现Sortable.js能很好 ...

  5. sortable 拖拽时互换目标的位置_双端通用型JS拖拽插件的封装与应用

    最近工作中遇到一个需求,需要将一个元素从某位置拖动到另一固定位置后执行某一交互行为,具体效果如下: 这个看似简单的需求,然而实现起来却并不那么顺利.我首先想到的是如何通过哪个现有的插件来快速解决这个问 ...

  6. 【组件】前端js拖拽插件 VUE

    [组件]前端js拖拽插件 VUE Vue Draggable - Vue 拖拽组件王者 Vue drag resize - 轻量级,无依赖,可缩放 Vue smooth dnd - 简单动效,上下拖拽 ...

  7. php拖拽原理,JS拖拽效果及原理解析

    这篇文章主要介绍了如何实现js拖拽效果及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 元素拖拽分成3个步骤:按下鼠标,移动鼠标,松开鼠标. ...

  8. 解决JS拖拽出现的问题

    解决JS拖拽出现的问题 参考文章: (1)解决JS拖拽出现的问题 (2)https://www.cnblogs.com/yuanjingjing/p/10154198.html 备忘一下.

  9. js拖拽图片到浏览器上传

    拖拽的事件有很多,这个懂的都懂不懂的就- <!doctype html> <html> <head> <meta charset="utf-8&qu ...

最新文章

  1. airflow sql_alchemy_conn mysql_airflow的安装和使用 - 完全版
  2. python爬百度翻译-python爬虫实现百度翻译
  3. 【问题】定时任务整理笔记附问题求大佬解答!!!!
  4. invalidate () 方法
  5. 《Android开发艺术探索》自定义View中关于“HorizontalScrollViewEx”的改进
  6. localhost访问IIS资源突然不好使了
  7. 利用Siri API开发的语音输入法Air Dictate出现
  8. 自定义水晶报表的显示
  9. 利用维纳滤波编码实现给定的运动模糊图像恢复
  10. Mac下安装Flink的local模式(flink-1.0.2)
  11. BST:Transformer在推荐领域的应用
  12. JasperReport生成PDF中文不显示处理
  13. oracle解压后不能运行,求救:oracle10安装后net Manager等工具无法启动
  14. Fiddler 4监听手机数据
  15. Android图书馆选座系统课程设计
  16. 最全最简单的dubbo教程-开篇《一》
  17. 使用Visio画各种可视化的流程图之用例图和类图
  18. 二行代码解决全部网页木马
  19. PMP证书现在还值得考吗?
  20. 【项目管理】如何成为合格的项目负责人

热门文章

  1. 神经网络模型量化方法简介
  2. Android 进阶——调试调优利器 ADB常用指令大全
  3. 中国CAE行业现状及发展前景分析
  4. Greenplum的工作负载及资源管理
  5. RDD断点回归案例怎么分析?
  6. 基础排序算法及其优化(Java)
  7. 格签名重要论文简介1-GPV08
  8. mac计划启动事件-alarm.user-visible-Weekly Usage Report
  9. dell venue 7 linux,64位处理器 戴尔全新Venue 7平板评测
  10. Unity 客户端简单框架(手游)