前言

SortableJS 是一个功能强大的 JavaScript 拖拽库。可用于列表拖拽排序、以及低代码拖拽配置等场景。
下面我们根据几个 Demo 来熟悉 SortableJS 的应用场景。

Sortable.js 中文网:www.sortablejs.com
Sortable.js 使用文档:https://github.com/SortableJS/Sortable

示例

1、引入 SortableJS

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
</head>
<body>
  
</body>
</html>

2、示例一:列表拖拽排序

<div id="example1" class="list-group">
    <div class="list-group-item">Item 1</div>
    <div class="list-group-item">Item 2</div>
    <div class="list-group-item">Item 3</div>
    <div class="list-group-item">Item 4</div>
    <div class="list-group-item">Item 5</div>
    <div class="list-group-item">Item 6</div>
</div>

new Sortable(example1, {
  animation: 150,
  // 拖拽时预览图样式
  ghostClass: 'blue-background-class'
});

.blue-background-class {
    background-color: #C8EBFB!important;
}

3、示例二:多组列表相互拖拽

<div class="row">
    <div id="example2Left" class="list-group col-6">
      <div class="list-group-item">Item 1</div>
      <div class="list-group-item">Item 2</div>
      <div class="list-group-item">Item 3</div>
      <div class="list-group-item">Item 4</div>
      <div class="list-group-item">Item 5</div>
      <div class="list-group-item">Item 6</div>
    </div>
  
    <div id="example2Right" class="list-group col-6">
      <div class="list-group-item tinted">Item 1</div>
      <div class="list-group-item tinted">Item 2</div>
      <div class="list-group-item tinted">Item 3</div>
      <div class="list-group-item tinted">Item 4</div>
      <div class="list-group-item tinted">Item 5</div>
      <div class="list-group-item tinted">Item 6</div>
    </div>
</div>

new Sortable(example2Left, {
  group: 'shared', // set both lists to same group
  animation: 150
});

new Sortable(example2Right, {
  group: 'shared',
  animation: 150
});

.tinted {
    background-color: #fff6b2!important;
}

4、示例三:多组列表拖拽克隆

通过拖拽复制节点。

<div class="row">
    <div id="example3Left" class="list-group col-6">
      <div class="list-group-item">Item 1</div>
      <div class="list-group-item">Item 2</div>
      <div class="list-group-item">Item 3</div>
      <div class="list-group-item">Item 4</div>
      <div class="list-group-item">Item 5</div>
      <div class="list-group-item">Item 6</div>
    </div>
  
    <div id="example3Right" class="list-group col-6">
      <div class="list-group-item tinted">Item 1</div>
      <div class="list-group-item tinted">Item 2</div>
      <div class="list-group-item tinted">Item 3</div>
      <div class="list-group-item tinted">Item 4</div>
      <div class="list-group-item tinted">Item 5</div>
      <div class="list-group-item tinted">Item 6</div>
    </div>
</div>

new Sortable(example3Left, {
    group: {
    name: 'shared',
    pull: 'clone' // To clone: set pull to 'clone'
    },
    animation: 150
});

new Sortable(example3Right, {
    group: {
    name: 'shared',
    pull: 'clone'
    },
    animation: 150
});

5、示例四:禁止 Sorting

设置列表禁止排序、禁止将其他列表内容拖放至本列表中。

<div class="row">
    <div id="example4Left" class="list-group col-6">
      <div class="list-group-item">Item 1</div>
      <div class="list-group-item">Item 2</div>
      <div class="list-group-item">Item 3</div>
      <div class="list-group-item">Item 4</div>
      <div class="list-group-item">Item 5</div>
      <div class="list-group-item">Item 6</div>
    </div>
  
    <div id="example4Right" class="list-group col-6">
      <div class="list-group-item tinted">Item 1</div>
      <div class="list-group-item tinted">Item 2</div>
      <div class="list-group-item tinted">Item 3</div>
      <div class="list-group-item tinted">Item 4</div>
      <div class="list-group-item tinted">Item 5</div>
      <div class="list-group-item tinted">Item 6</div>
    </div>
</div>

new Sortable(example4Left, {
    group: {
    name: 'shared',
    pull: 'clone',
    put: false // Do not allow items to be put into this list
    },
    animation: 150,
    sort: false // To disable sorting: set sort to false
});

new Sortable(example4Right, {
    group: 'shared',
    animation: 150
});

6、示例五:只对指定的 class 子元素上作用拖拽

比如指定当鼠标移动上 i 标签 元素时进行拖拽。

<div id="example5" class="list-group col">
    <div class="list-group-item"><i class="handle"></i>&nbsp;&nbsp;Item 1</div>
    <div class="list-group-item"><i class="handle"></i>&nbsp;&nbsp;Item 2</div>
    <div class="list-group-item"><i class="handle"></i>&nbsp;&nbsp;Item 3</div>
    <div class="list-group-item"><i class="handle"></i>&nbsp;&nbsp;Item 4</div>
    <div class="list-group-item"><i class="handle"></i>&nbsp;&nbsp;Item 5</div>
    <div class="list-group-item"><i class="handle"></i>&nbsp;&nbsp;Item 6</div>
</div>

new Sortable(example5, {
  handle: '.handle', // handle class
  animation: 150
});

.handle {
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 2px solid gray;
  cursor: grab;
}

7、示例六:过滤 Filter

过滤不需要使用拖拽的列表单元。

<div id="example6" class="list-group">
    <div class="list-group-item">Item 1</div>
    <div class="list-group-item">Item 2</div>
    <div class="list-group-item">Item 3</div>
    <div class="list-group-item filtered">Filtered</div>
    <div class="list-group-item">Item 4</div>
    <div class="list-group-item">Item 5</div>
</div>

new Sortable(example6, {
  filter: '.filtered',
  animation: 150
});

.filtered{
  background-color: red!important;
}

常用配置

1、属性

  • group
string: 用于定义多组列表进行交互时进行关联的名称;
// or
object:{ name, pull, put }
    name:同上面 string;
    // 定义从容器列表移除的设置,可选值为:true/false/'clone'/function
    // 如果为 false,不能拖动容器子项添加到其他容器内,但可以在本容器内进行拖拽排序
    pull: true,
    // 定义向容器列表放置列表单元的的设置,可选值为true/false/['foo','bar']/function
    // 其中 ['foo','bar']:这个可以是一个字符串或者是字符串的数组,代表的是group配置项里定义的name值
    // 如果为 false,不允许其他容器的子项拖拽至当前容器内,但可以在本容器内进行拖拽排序
    put: true,
  • sort:boolean 定义列表单元是否可以在列表容器内进行拖拽排序。
  • disabled:boolean 定义当前容器单元 sortable 对象是否可用。
  • animation:number 单位:ms,定义排序过程中动画的时间。
  • handle:selector 格式:简单的选择器字符串,比如 class;使得在容器内,任意层级的子元素,只有存在指定的 class 的元素上,才能够拖动。
  • filter:selector 格式:简单的选择器字符串,比如 class;定义哪些列表单元不能进行拖放,可设置为多个选择器,中间用“,”分隔。
  • draggable:selector 格式:简单的选择器字符串,比如 class;定义哪些列表单元可以进行拖拽。
  • dragClass:selector 格式 class 选择器,定义拖拽时,跟随鼠标移动的预览元素样式。
  • ghostClass:selector 格式 class 选择器,在拖动元素时,放置位置的影子设置样式。
  • chosenClass:selector 格式 class 选择器,当选中列表单元时会给该单元增加一个 class。
  • scroll:boolean 默认为true,当排序的容器是个可滚动的区域,拖放可以引起区域滚动。

2、事件

// 列表单元被选中的回调函数
  onChoose(evt) {
    console.log('onChoose: 列表单元被选中!');
  },
  
  // 列表单元拖动开始的回调函数
  onStart(evt) {
    console.log('onStart: 列表单元拖动开始的回调函数!');
  },
  
  // 容器列表单元,在拖放结束后的回调函数
  onEnd(evt) {
    console.log('onEnd: 列表单元拖放结束后的回调函数!');
  },
  
  // 其他列表单元添加到本列表容器的回调函数
  onAdd(evt) {
    console.log('onAdd: 其他列表单元添加到本列表容器的回调函数');
  },
  
  // 列表单元在列表容器中的排序发生变化后的回调函数
  onUpdate(evt) {
    console.log('onUpdate: 列表单元在列表容器中的排序发生变化后的回调函数');
  },
  
  // 列表元素移到另一个列表容器成功后的回调函数
  onRemove(evt) {
    console.log('onRemove: 列表元素移到另一个列表容器的回调函数');
  },
  
  // 试图选中一个被 filter 过滤的列表单元的回调函数
  onFilter(evt) {
    console.log('onFilter: 试图选中一个被filter过滤的列表单元的回调函数');
  },
  
  // 当移动列表单元在一个列表容器中或者多个列表容器中的回调函数
  onMove(evt, originalEvt) {
    console.log('onMove: 当移动列表单元在一个列表容器中或者多个列表容器中的回调函数');
  },
  
  // 当创建一个列表单元副本的时候的回调函数
  onClone(evt) {
    console.log('onClone: 当创建一个列表单元副本的时候的回调函数');
  },
  
  // 用于传递数据,在容器单元按住拖动时触发
  setData: function (/** DataTransfer */dataTransfer, /** HTMLElement*/dragEl) {
    dataTransfer.setData('Text', dragEl.textContent); // `dataTransfer` object of HTML5 DragEvent
  },

3、事件对象

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

to:HTMLElement--移动到的列表容器
from:HTMLElement--来源的列表容器
target:HTMLElement--来源的列表容器
item:HTMLElement--被移动的列表单元
clone:HTMLElement--副本的列表单元
oldIndex:number/undefined--在列表容器中的原序号
newIndex:number/undefined--在列表容器中的新序号
pullMode:默认是 undefined,当项目位于另一个可排序列表中时,如果操作克隆,值为 clone,如果是移动,只为 true

4、方法

  • option:设置/获取配置信息
sortable.option('sort', false); // 设置
sortable.option('sort'); // 获取
  • toArray:获取 序列化可排序的列表单元的 data-id
var order = sortable.toArray(); // ['36h', '36i', '36j', '36k', '36l', '36m']
  • sort:根据列表单元的 data-id 进行排序
sortable.sort(order.reverse()); // 重新排序
  • destory:销毁容器排序:
sortable.destroy(); // 销毁容器排序
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐