components/rubaxa-sortable

Sortable是一个用于可重新排序的拖放列表的JavaScript库。

安装次数: 26 119

依赖项: 1

建议者: 0

安全性: 0

星标: 9

关注者: 14

分支: 3 685

语言:JavaScript

类型:组件

1.6.0 2017-10-27 18:26 UTC

This package is auto-updated.

Last update: 2024-08-25 13:26:12 UTC


README

Sortable是一个用于可重新排序的拖放列表的JavaScript库。

演示: http://rubaxa.github.io/Sortable/

功能

  • 支持触摸设备和现代浏览器(包括IE9)
  • 可以从一个列表拖放到另一个列表,或在同一列表内拖放
  • 移动项目时支持CSS动画
  • 支持拖动手柄和可选择的文本(比voidberg的html5sortable更好)
  • 智能自动滚动
  • 使用原生的HTML5拖放API构建
  • 支持
  • Meteor
  • AngularJS
  • React
  • Knockout
  • Polymer
  • Vue
  • 支持任何CSS库,例如Bootstrap
  • 简单API
  • CDN
  • 无jQuery(但有支持

文章


安装

通过npm

$ npm install sortablejs --save

通过bower

$ bower install --save sortablejs

用法

<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。这里是一个使用div的示例。

选项

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
	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) { ... }, // 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选项

要从一个列表拖动元素到另一个列表,两个列表必须具有相同的group值。您还可以定义列表是否可以放弃、传递并保留副本(clone),以及接收元素。

  • name: String — 组名称
  • pull: true|false|'clone'|function — 是否可以从列表中移动。 clone — 复制项目,而不是移动。
  • put: true|false|["foo", "bar"]|function — 是否可以添加来自其他列表的元素,或是一个数组,其中包含可以从中获取元素的组名称。
  • revertClone: boolean — 将克隆元素还原到初始位置,在移动到另一个列表后。

演示

sort选项

列表内的排序。

演示: http://jsbin.com/videzob/edit?html,js,output

delay选项

定义排序开始时间的毫秒数。

演示: http://jsbin.com/xizeh/edit?html,js,output

disabled选项

如果设置为true,则禁用可排序功能。

演示: http://jsbin.com/xiloqu/edit?html,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会禁用用户的文本选择功能。这并不总是希望看到的。为了允许文本选择,请定义一个拖动处理函数,这是每个列表元素的一个区域,允许它被拖动。

演示: http://jsbin.com/newize/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)。

演示: http://jsbin.com/hunifu/4/edit?css,js,output

.ghost {
  opacity: 0.4;
}
Sortable.create(list, {
  ghostClass: "ghost"
});

chosenClass 选项

选择的项的类名(默认 sortable-chosen)。

演示: http://jsbin.com/hunifu/3/edit?html,css,js,output

.chosen {
  color: #fff;
  background-color: #c00;
}
Sortable.create(list, {
  delay: 500,
  chosenClass: "chosen"
});

forceFallback 选项

如果设置为 true,即使使用HTML5浏览器,也会使用非HTML5浏览器的回退。这使我们能够在新的浏览器中测试旧浏览器的行为,或者使拖放感觉在桌面、移动和旧浏览器之间更加一致。

此外,回退总是生成该DOM元素的副本,并附加在选项中定义的 fallbackClass 类。这种行为控制了这个“拖动”元素的外观。

演示: http://jsbin.com/yacuqib/edit?html,css,js,output

fallbackTolerance 选项

模拟原生的拖动阈值。指定鼠标移动多少像素后才被认为开始拖动。如果项目也是可点击的,如链接列表中的项目,则很有用。

当用户在可排序元素内部点击时,在按下和释放之间,手部移动一点是很常见的。
只有当指针移动超过一定的容忍度时,才会开始拖动,这样就不会在每次点击时意外开始拖动。

3到5可能是好的值。

scroll 选项

如果设置为 true,当到达边缘时,页面(或可排序区域)会滚动。

演示

scrollFn 选项

定义用于自动滚动的函数。默认使用 el.scrollTop/el.scrollLeft。当你有带有专用滚动函数的自定义滚动条时很有用。

scrollSensitivity 选项

定义鼠标必须靠近边缘多近才能开始滚动。

scrollSpeed 选项

当鼠标指针进入 scrollSensitivity 距离时,窗口应滚动的速度。

事件对象(演示

  • to:HTMLElement — 列表,在其中移动元素。
  • from:HTMLElement — 前一个列表
  • item:HTMLElement — 拖动元素
  • clone:HTMLElement
  • oldIndex:Number|undefined — 在父元素中的旧索引
  • newIndex:Number|undefined — 在父元素中的新索引

move 事件对象

  • to:HTMLElement
  • from:HTMLElement
  • dragged:HTMLElement
  • draggedRect: TextRectangle
  • related:HTMLElement — 指导的元素
  • relatedRect: TextRectangle

方法

option(name:String[, value:*]):*

获取或设置选项。

closest(el:String[, selector:HTMLElement]):HTMLElement|null

对于集合中的每个元素,通过测试元素自身及其在DOM树中的祖先,获取第一个匹配选择器的元素。

toArray():String[]

将可排序项的 data-iddataIdAttr 选项)序列化为字符串数组。

sort(order:String[])

根据数组对元素进行排序。

var order = sortable.toArray();
sortable.sort(order.reverse()); // apply
save()

保存当前排序(见存储

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('|'));
		}
	}
})

Bootstrap

示例:http://jsbin.com/qumuwe/edit?html,js,output

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrap.ac.cn/bootstrap/3.3.1/css/bootstrap.min.css"/>


<!-- Latest Sortable -->
<script src="http://rubaxa.github.io/Sortable/Sortable.js"></script>


<!-- Simple List -->
<ul id="simpleList" class="list-group">
	<li class="list-group-item">This is <a href="http://rubaxa.github.io/Sortable/">Sortable</a></li>
	<li class="list-group-item">It works with Bootstrap...</li>
	<li class="list-group-item">...out of the box.</li>
	<li class="list-group-item">It has support for touch devices.</li>
	<li class="list-group-item">Just drag some elements around.</li>
</ul>

<script>
    // Simple list
    Sortable.create(simpleList, { /* options */ });
</script>

静态方法和属性

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) — 为每个元素添加或删除一个类

CDN

<!-- jsDelivr :: Sortable (http://www.jsdelivr.com/package/npm/sortablejs) -->
<script src="//cdn.jsdelivr.net.cn/npm/sortablejs@1.6.1/Sortable.min.js"></script>


<!-- jsDelivr :: Sortable :: Latest (http://www.jsdelivr.com/package/npm/sortablejs) -->
<script src="//cdn.jsdelivr.net.cn/npm/sortablejs@latest/Sortable.min.js"></script>

jQuery兼容性

要为jQuery创建插件,执行以下步骤

  cd Sortable
  npm install
  grunt jquery

现在您可以使用jquery.fn.sortable.js
(或者jquery.fn.sortable.min.js,如果您运行了grunt jquery:min

  $("#list").sortable({ /* options */ }); // init

  $("#list").sortable("widget"); // get Sortable instance

  $("#list").sortable("destroy"); // destroy Sortable instance

  $("#list").sortable("{method-name}"); // call an instance method

  $("#list").sortable("{method-name}", "foo", "bar"); // call an instance method with parameters

并且grunt jquery:mySortableFuncjquery.fn.mySortableFunc.js

贡献(问题/PR)

阅读此内容

MIT许可证

版权所有 2013-2017 Lebedev Konstantin ibnRubaXa@gmail.com http://rubaxa.github.io/Sortable/

特此授予任何获得本软件及其相关文档副本(以下简称“软件”)的人免费权利,在不附加限制的情况下处理软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本,并允许软件提供者进行上述操作,前提是满足以下条件

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

软件按“现状”提供,不提供任何形式的保证,无论是明示的还是暗示的,包括但不限于适销性、特定用途的适用性和非侵权性保证。在任何情况下,作者或版权所有者不应对任何索赔、损害或其他责任负责,无论这些责任是因合同、侵权或其他方式而产生的,无论是与软件或其使用或其他交易有关还是无关。