sortable2
v1.1.0
Published
JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices. No jQuery required. Supports Meteor, AngularJS, React, Polymer, Vue, Knockout and any CSS library, e.g. Bootstrap.
Downloads
44
Maintainers
Readme
Sortable改良版
Sortable是一个用于可重新排序的拖放列表的JavaScript库.
演示: http://sortablejs.github.io/Sortable/
特征
- 支持触摸设备和 现代 浏览器(包括IE9)
- 可以从一个列表拖动到另一个列表或在同一列表中
- 移动项目时的CSS动画
- 支持拖动手柄和可选文本
- 智能自动滚动
- 高级交换检测
- 使用原生HTML5拖放API构建
- 支持任何CSS库,例如Bootstrap
- 简单的API
- 不需要jQuery
安装
通过 npm
$ npm install sortable2 --save
通过 bower:
$ bower install --save sortable2
用法
<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);
您可以使用列表及其元素的任何元素,而不仅仅是 ul
/li
.
选项
var sortable = new Sortable(el, {
// 或{name:“...”,pull:[true,false,'clone',array],put:[true,false,array]}
group: "name",
// 在列表内排序
sort: true,
// 以毫秒为单位定义何时开始排序
delay: 0,
// 仅在用户使用触摸时才会延迟
delayOnTouchOnly: false,
// px,在取消延迟拖动事件之前该点应移动多少像素
touchStartThreshold: 0,
// 如果设置为true ,则禁用sortable.
disabled: false,
// @see 存储
store: null,
// ms,排序时动画速度移动项目,“0” - 没有动画
animation: 150,
// 缓动动画。默认为null。有关 示例,请参阅 https://easings.net/。
easing: "cubic-bezier(1, 0, 0, 1)",
// 在列表项中拖动句柄选择器
handle: ".my-handle",
// 不会导致拖动的选择器(String或Function)
filter: ".ignore-elements",
// 触发`filter`时调用`event.preventDefault()
preventOnFilter: true,
// 指定元素内的哪些项应该是可拖动的
draggable: ".item",
// drop placeholder的类名
ghostClass: "sortable-ghost",
// 所选项目的类名称
chosenClass: "sortable-chosen",
// 拖动项的类名
dragClass: "sortable-drag",
dataIdAttr: 'data-id',
// 交换区域的阈值
swapThreshold: 1,
// 如果设置为true ,将始终使用反向交换区域
invertSwap: false,
// 反向交换区域的阈值(默认设置为swapThreshold值)
invertedSwapThreshold: 1,
// 锁定拖拉方向
direction: 'xy',
// 忽略HTML5 拖拉行为并强制回退
forceFallback: false,
// 使用forceFallback时克隆的DOM元素的类名
fallbackClass: "sortable-fallback",
// 将克隆的DOM元素追加到Document的Body中
fallbackOnBody: false,
// 像素为单位指定鼠标在被视为拖动之前应移动多远。
fallbackTolerance: 0,
// or HTMLElement
scroll: true,
// 如果你有自定义滚动条scrollFn可用于自动滚动
scrollFn: function(offsetX, offsetY, originalEvent, touchEvt, hoverTargetEl) { ... },
// px, 鼠标必须靠近边缘才能开始滚动。
scrollSensitivity: 30,
// px
scrollSpeed: 10,
// 将 autoscroll 应用于所有父元素,以便更轻松地移动
bubbleScroll: true,
dragoverBubble: false,
// 删除未显示的克隆元素,而不是仅隐藏它
removeCloneOnHide: true,
// px,distance mouse必须是空的sortable才能将drag元素插入其中
emptyInsertThreshold: 5,
setData: function (/** DataTransfer */dataTransfer, /** HTMLElement*/dragEl) {
dataTransfer.setData('Text', dragEl.textContent); // HTML5 DragEvent的`dataTransfer`对象
},
// 元素被选中
onChoose: function (/**Event*/evt) {
evt.oldIndex; // 父元素索引
},
// 元素是非选择的
onUnchoose: function(/**Event*/evt) {
// 与onEnd相同的属性
},
// 元素拖动已开始
onStart: function (/**Event*/evt) {
evt.oldIndex; // 父元素索引
},
// 元素拖动结束
onEnd: function (/**Event*/evt) {
var itemEl = evt.item; // 拖动HTMLElement
evt.to; // 目标列表
evt.from; // 上一个清单
evt.oldIndex; // 元素在旧父级中的旧索引
evt.newIndex; // 元素在新父级中的新索引
evt.oldDraggableIndex; // 元素在旧父元素中的旧索引,仅计算可拖动元素
evt.newDraggableIndex; // 元素在新父元素中的新索引,仅计算可拖动元素
evt.clone // 克隆元素
evt.pullMode; // 当item在另一个sortable中时:`clone`如果克隆,`true`如果移动
},
// 元素从另一个列表中放入列表中
onAdd: function (/**Event*/evt) {
// 与onEnd相同的属性
},
// 更改了列表中的排序
onUpdate: function (/**Event*/evt) {
// 与onEnd相同的属性
},
// 通过列表的任何更改调用(添加/更新/删除)
onSort: function (/**Event*/evt) {
// 与onEnd相同的属性
},
// 元素从列表中删除到另一个列表中
onRemove: function (/**Event*/evt) {
// 与onEnd相同的属性
},
// 尝试拖动已过滤的元素
onFilter: function (/**Event*/evt) {
var itemEl = evt.item; // HTMLElement接收 `mousedown|tapstart` 事件.
},
// 在列表中或列表之间移动项目时的事件
onMove: function (/**Event*/evt, /**Event*/originalEvent) {
evt.dragged; // 拖动HTMLElement
evt.draggedRect; // DOMRect {left, top, right, bottom}
evt.related; // 引导的HTMLElement
evt.relatedRect; // DOMRect
evt.willInsertAfter; // 如果Sortable默认情况下会在目标之后插入drag元素,则为true
originalEvent.clientY; // 鼠标位置
// 返回false; - 取消
// 返回-1; - 在目标之前插入
// 返回1; - 插入目标后
},
// 在创建元素克隆时调用
onClone: function (/**Event*/evt) {
var origEl = evt.item;
var cloneEl = evt.clone;
},
// 拖动元素更改位置时调用
onChange: function(/**Event*/evt) {
evt.newIndex // 最有可能使用此事件的原因是获取拖动元素的当前索引
// 与onEnd相同的属性
}
});
group
选项
要将元素从一个列表拖动到另一个列表,两个列表必须具有相同的group
值。您还可以定义列表是否可以放弃,提供和保留副本(clone
)以及接收元素。
- name:
String
— 组名 - pull:
true|false|["foo", "bar"]|'clone'|function
— 从列表中移动的能力.clone
— 复制项目,而不是移动。或者可以放入元素的组名称数组。默认为true
. - put:
true|false|["baz", "qux"]|function
— 是否可以从其他列表添加元素,或者是否可以添加元素的组名称数组. - revertClone:
boolean
— 移动到另一个列表后,将克隆元素恢复到初始位置
演示:
- https://jsbin.com/hijetos/edit?js,output
- https://jsbin.com/nacoyah/edit?js,output — 在
pull
和中使用复杂逻辑put
- https://jsbin.com/bifuyab/edit?js,output — 使用
revertClone: true
sort
选项
在列表内排序。
演示: https://jsbin.com/jayedig/edit?js,output
delay
选项
定义何时开始排序的时间(以毫秒为单位)。不幸的是,由于浏览器的限制,在本机拖放的IE或Edge上无法延迟。
演示: https://jsbin.com/zosiwah/edit?js,output
delayOnTouchOnly
选项
是否应仅在用户使用触摸时(例如,在移动设备上)应用延迟。在任何其他情况下都不会延迟。默认为 false
.
swapThreshold
选项
交换区域将占用的目标的百分比,作为0和之间的浮点数1
阅读更多: https://github.com/SortableJS/Sortable/wiki/Swap-Thresholds-and-Direction#swap-threshold
演示: http://sortablejs.github.io/Sortable#thresholds
invertSwap
选项
设置为true
将交换区域设置为目标的两侧,以便对“介于”项目之间进行排序
演示: http://sortablejs.github.io/Sortable#thresholds
invertedSwapThreshold
选项
反转交换区域将占用的目标百分比,作为0
和之间的浮点数1
。如果没有给出,将默认为 swapThreshold
.
Read more: https://github.com/SortableJS/Sortable/wiki/Swap-Thresholds-and-Direction#dealing-with-swap-glitching
direction
选项
拖拉方向排序
touchStartThreshold
选项
此选项与fallbackTolerance
选项类似。
delay
设置此选项后,即使您的手指没有移动,
某些具有非常敏感触摸显示屏的手机(如Samsung Galaxy S8)也会触发不需要的触摸移动事件,从而导致排序无法触发。
此选项设置在取消延迟排序之前必须发生的最小指针移动
3 到 5 是最佳值.
disabled
选项
如果设置为,则禁用sortable true
.
演示: https://jsbin.com/sewokud/edit?js,output
var sortable = Sortable.create(list);
document.getElementById("switcher").onclick = function () {
var state = sortable.option("disabled"); // get
sortable.option("disabled", !state); // set
};
handle
选项
要使列表项可拖动,Sortable将禁用用户的文本选择。 这并不总是令人满意的。要允许文本选择,请定义一个拖动处理程序,它是每个列表元素的一个区域,允许它被拖动
演示: https://jsbin.com/numakuh/edit?html,js,output
Sortable.create(el, {
handle: ".my-handle"
});
<ul>
<li><span class="my-handle">::</span> list item text one
<li><span class="my-handle">::</span> list item text two
</ul>
.my-handle {
cursor: move;
cursor: -webkit-grabbing;
}
filter
选项
Sortable.create(list, {
filter: ".js-remove, .js-edit",
onFilter: function (evt) {
var item = evt.item,
ctrl = evt.target;
if (Sortable.utils.is(ctrl, ".js-remove")) { // Click on remove button
item.parentNode.removeChild(item); // remove sortable item
}
else if (Sortable.utils.is(ctrl, ".js-edit")) { // Click on edit link
// ...
}
}
})
ghostClass
选项
放置占位符的类名(默认 sortable-ghost
).
演示: https://jsbin.com/henuyiw/edit?css,js,output
.ghost {
opacity: 0.4;
}
Sortable.create(list, {
ghostClass: "ghost"
});
chosenClass
选项
所选项目的类名称(默认sortable-chosen
).
演示: https://jsbin.com/hoqufox/edit?css,js,output
.chosen {
color: #fff;
background-color: #c00;
}
Sortable.create(list, {
delay: 500,
chosenClass: "chosen"
});
forceFallback
选项
如果设置为true
,即使我们使用HTML5浏览器,也将使用非HTML5浏览器的后备。
这使我们有可能测试旧浏览器的行为,即使在较新的浏览器中,也可以使Drag'n Drop在桌面,移动和旧浏览器之间更加一致。
最重要的是,Fallback总是生成该DOM元素的副本,并附加fallbackClass
选项中定义的类。此行为控制此“拖动”元素的外观.
演示: https://jsbin.com/sibiput/edit?html,css,js,output
fallbackTolerance
选项
模拟本机阻力阈值。 以像素为单位指定鼠标在被视为拖动之前应移动多远。如果项目也可以在链接列表中单击,则非常有用。 当用户在可排序元素中单击时,在您按下的时间和释放时间之间,您的手移动一点并不罕见。 仅当您将指针移动超过某个公差时才会开始拖动,这样您每次单击时都不会意外地开始拖动.
3 到 5 是最佳值.
scroll
选项
如果设置为true,则页面(或可排序区域)在到达边缘时滚动.
演示:
window
: https://jsbin.com/dosilir/edit?js,outputoverflow: hidden
: https://jsbin.com/xecihez/edit?html,js,output
scrollFn
选项
定义将用于自动滚动的功能。默认情况下使用el.scrollTop / el.scrollLeft。有自定义滚动条和专用滚动功能时很有用
scrollSensitivity
选项
定义鼠标必须靠近边缘以开始滚动的方式.
scrollSpeed
选项
鼠标指针进入scrollSensitivity
距离后窗口应滚动的速度
bubbleScroll
选项
如果设置为true
,则普通autoscroll
函数也将应用于用户拖动的元素的所有父元素.
演示: https://jsbin.com/kesewor/edit?html,js,output
dragoverBubble
选项
如果设置为true
,则dragover事件将冒泡到父排序。
适用于后备和本地dragover事件。默认情况下,
它是false
,但Sortable只会在元素插入父Sortable后停止冒泡,或者可以插入父Sortable,但不是在特定时间(由于动画等)
removeCloneOnHide
选项
如果设置为false
,则通过将其CSS display
属性设置为隐藏克隆 none
。默认情况下,此选项是true
,意味着Sortable将在DOM被隐藏时从DOM中删除克隆元素。
emptyInsertThreshold
选项
鼠标必须是空的可排序的距离(以像素为单位),同时拖动要插入到可排序的拖动元素。默认为5
。设置为0
禁用此功能.
Demo: https://jsbin.com/becavoj/edit?js,output
事件对象 (演示)
- to:
HTMLElement
— 目标元素 - from:
HTMLElement
— 拖动元素 - item:
HTMLElement
— 拖动dom - clone:
HTMLElement
- oldIndex:
Number|undefined
— 父级中的旧索引 - newIndex:
Number|undefined
— 父级内的新索引 - oldDraggableIndex:
Number|undefined
— 父级中的旧索引,仅计算可拖动元素 - newDraggableIndex:
Number|undefined
— 父级内的新索引,仅计算可拖动元素 - pullMode:
String|Boolean|undefined
— 拖拉模式,拖动到另一个可排序("clone"
,true
, orfalse
),否则未定义
move
事件对象
- to:
HTMLElement
- from:
HTMLElement
- dragged:
HTMLElement
- draggedRect:
DOMRect
- related:
HTMLElement
— 引导的元素 - relatedRect:
DOMRect
- willInsertAfter:
Boolean
—true
如果将元素插入目标之后(或false
之前
方法
option(name:String
[, value:*
]):*
获取或设置选项.
closest(el:String
[, selector:HTMLElement
]):HTMLElement|null
对于集合中的每个元素,通过测试元素本身并遍历DOM树中的祖先来获取与选择器匹配的第一个元素.
toArray():String[]
将可排序项 data-id
'的 (dataIdAttr
选项) 序列化为字符串数组.
sort(order:String[]
)
根据数组对元素进行排序.
var order = sortable.toArray();
sortable.sort(order.reverse()); // apply
save()
保存当前排序 (see store)
destroy()
完全删除可排序功能.
存储
保存和恢复排序.
<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('|'));
}
}
})
静态方法和属性
Sortable.create(el:HTMLElement
[, options:Object
]):Sortable
创建新实例.
Sortable.active:Sortable
链接到活动实例.
Sortable.utils
- on(el
:HTMLElement
, event:String
, fn:Function
) — 附加事件处理函数 - off(el
:HTMLElement
, event:String
, fn:Function
) — 删除事件处理程序 - css(el
:HTMLElement
):Object
— 获取所有CSS属性的值 - css(el
:HTMLElement
, prop:String
):Mixed
— 获取样式属性的值 - css(el
:HTMLElement
, prop:String
, value:String
) — 设置一个CSS属性 - css(el
:HTMLElement
, props:Object
) — 设置更多CSS属性 - find(ctx
:HTMLElement
, tagName:String
[, iterator:Function
]):Array
— 按标签名称获取元素 - bind(ctx
:Mixed
, fn:Function
):Function
— 获取一个函数并返回一个始终具有特定上下文的新函数 - is(el
:HTMLElement
, selector:String
):Boolean
— 检查选择器当前匹配的元素集 - closest(el
:HTMLElement
, selector:String
[, ctx:HTMLElement
]):HTMLElement|Null
— 对于集合中的每个元素,通过测试元素本身并遍历DOM树中的祖先来获取与选择器匹配的第一个元素 - clone(el
:HTMLElement
):HTMLElement
— 创建匹配元素集的深层副本 - toggleClass(el
:HTMLElement
, name:String
, state:Boolean
) — 在每个元素中添加或删除一个类 - detectDirection(el
:HTMLElement
):String
— 拖动方向:x
或y
获取xy