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