Dragula 让拖放操作变简单的 JS 库 - 文章教程

Dragula 让拖放操作变简单的 JS 库

发布于 2020-07-02 字数 10443 浏览 2603 评论 0

Dragula 是一个 JavaScript 库,实现了网页上的拖放功能。提供 JavaScript、AngularJS 和 React 版本。

Dragula 让拖放操作变简单的 JS 库

特征

  • 超级容易设置
  • 没有臃肿的依赖
  • 自己计算排序顺序
  • 物品将被丢弃的阴影提供视觉反馈
  • 触摸事件!
  • 无需任何配置即可无缝处理点击

安装

1、npm安装

   npm install dragula --save

2、bower安装

   bower install dragula --save

3、CDN

<script src='https://cdnjs.cloudflare.com/ajax/libs/dragula/$VERSION/dragula.min.js'></script>

注:最好放在<body>中引用,不要放在<head>中。

css

需要引入一些css样式,在页面中引入 dist/dragula.cssdist/dragula.min.css,如果你使用的是Stylus,你可以这样引入

@import 'node_modules/dragula/dragula'

方法

dragula(containers?, options?)

dragula 允许在 containers 中间互相拖动,如果拖动到containers之外的元素时,会根据 revertOnSpill 和removeOnSpill 的配置终止操作。
请注意,拖动仅在左键单击时触发

下面的示例允许用户将元素从中left拖入right和从中right拖入left

dragula([document.querySelector('#left'), document.querySelector('#right')]);

您还可以提供一个options对象。以下是默认值的介绍

dragula(containers, {
  isContainer: function (el) {
    return false; // 点击和拖动都会触发,drake.containers元素将被考虑
  },
  moves: function (el, source, handle, sibling) {
    return true; // 一直能拖动,拖动时触发
  },
  accepts: function (el, target, source, sibling) {
    return true; // 元素可以放在任何`container`中
  },
  invalid: function (el, handle) {
    return false; // 默认情况下不会阻止任何拖动
  },
  direction: 'vertical',             //元素的排放方向
  copy: false,                       // 拖动的元素是否为副本
  copySortSource: false,             // 复制的源容器重新排序
  revertOnSpill: false,              // 是否将拖到容器外的元素放回原处
  removeOnSpill: false,              // 是否将拖到容器外的元素删除
  mirrorContainer: document.body,    // 设置获取附加镜像元素的元素
  ignoreInputTextSelection: true     //允许用户选择输入文本
});

您可以省略container参数,稍后动态添加容器。

var drake = dragula({
  copy: true
});
drake.containers.push(container);

还可以从options对象设置容器

var drake = dragula({ containers: containers });

你还可以设置一个没有container和options的draglua

var drake = dragula();

options 对象详解

containers

和 dragula(containers?, options?) 的第一个参数效果是一样的。

isContainer

containers,您还可以使用此方法指定任何类型的逻辑,这些逻辑定义了这个特定drake实例的containers
下面的示例使用一个CSS类dragula-container动态地处理所有DOM元素,将它们作为这个drake的dragula容器。

var drake = dragula({
isContainer: function (el) {
   return el.classList.contains('dragula-container');
 }
});

moves

您可以定义一个moves方法,当单击一个元素时,它将被调用(el、source、handle、sibling)。如果此方法返回false,则不会开始拖动事件,也不会阻止该事件。handle元素将是原始的单击目标,这便于测试该元素是否是预期的“drag handle”。

accepts

您可以将accept设置为具有以下签名的方法:(el、target、source、sibling)。它将被调用,以确保来自source的元素el可以在sibling元素之前被拖放到容器target上。sibling元素可以为null,这意味着元素将作为容器中的最后一个元素放置。注意如果options .copy被设置为true, el将被设置为copy,而不是原来拖动的元素。

还要注意,拖动开始的位置始终是放置元素的有效位置,即使在所有元素accepts都返回false。

copy

如果copy被设置为true(或返回true的方法),那么项目将被复制,而不是移动。这意味着下列差别:
drag —- move: 元素将从源中隐藏 / copy: 什么都不会发生
drop —- move:元素将被移动到目标中 / copy: 元素将克隆到目标
remove—-move:元素将从DOM中删除 / copy: 什么都不会发生
cancel—-move:元素将保留在源代码中/ copy: 什么都不会发生

如果传递了一个方法,则无论何时开始拖拽一个元素,都会调用该方法,以决定它是否应该遵循复制行为。考虑下面的例子。

copy: function (el, source) {
 return el.className === 'you-may-copy-us';
}

copySortSource

如果copy被设置为true(或返回true的方法),copySortSource也为true,那么用户将能够对复制源容器中的元素进行排序。

revertOnSpill

默认情况下,将元素溢出到任何容器外将会将元素移回反馈阴影预览的放置位置。将revertOnSpill设置为true将确保将任何经过批准的容器外的元素移回拖放事件开始的源元素,而不是停留在反馈阴影预览的拖放位置。

removeOnSpill

默认情况下,将元素溢出到任何容器外将会将元素移回反馈阴影预览的放置位置。将removeOnSpill设置为true将确保从DOM中删除任何经过批准的容器之外的元素。注意,如果copy被设置为true,那么remove事件不会触发。

direction

当一个元素被放到容器中时,它将被放置在鼠标被释放的位置附近。如果方向为“vertical”(默认值),则将考虑Y轴。否则,如果方向为“horizontal”,则考虑X轴。

invalid

您可以提供一个带有(el, handle)签名的无效方法。对于不应该触发拖动的元素,此方法应该返回true。handle参数是被单击的元素,而el是要拖动的项。这是默认实现,它不阻止任何拖动。

function invalidTarget (el, handle) {
 return false;
}

请注意,invalid将在被单击的DOM元素和drake容器的每个父元素及其直接子元素上调用。

例如,当单击的元素(或其任何父元素)是锚标记时,可以将invalid设置为return false。

invalid: function (el, handle) {
 return el.tagName === 'A';
}

mirrorContainer

拖动时显示镜像元素的 DOM 元素将被附加到其中。默认为document.body

ignoreInputTextSelection

当启用此选项时,如果用户单击输入元素,则在鼠标指针退出输入之前不会开始拖动。这意味着用户可以在包含在draggable元素中的输入中选择文本,并且仍然可以通过将鼠标移到输入之外来拖动该元素——这样您就可以同时使用这两种方法。

默认情况下启用此选项。通过设置为false来关闭它。如果禁用了它,用户将无法用鼠标在dragula容器的输入中选择文本。

API

dragula方法返回一个带有简洁API的小对象。我们将把dragula返回的API称为drake。

drake.containers

此属性包含构建此drake实例时传递给dragula的容器集合。您可以随意push更多的容器和拼接旧容器。

drake.dragging

每当拖动元素时,此属性将为true。

drake.start(item)

进入没有阴影的拖动模式。当为现有的拖放解决方案提供互补的键盘快捷方式时,此方法非常有用。虽然一开始不会创建阴影,但是用户只要单击项目并开始拖动它,就会得到阴影。注意,如果他们单击并拖动其他内容,.end将在获取新项目之前被调用。

drake.end()

优雅地结束拖放事件,就像使用预览阴影标记的最后一个位置作为拖放目标一样。cancel或drop事件将被触发,这取决于该项目是否被拖回到最初被提取的地方(本质上是一个被视为cancel事件的no-op)。

drake.cancel(revert)

如果当前正在拖拽drake管理的元素,此方法将优雅地取消拖拽操作。您还可以在方法调用时传递revert,有效地生成与revertOnSpill为true时相同的结果。

注意,“取消”只会在以下场景中导致取消事件。

  1. revertOnSpill 为 true
  2. Drop target(如反馈阴影预览的那样)是源容器,项目将被放置在最初拖动它的位置

drake.remove()

如果当前正在拖拽 drake 管理的元素,此方法将优雅地将其从 DOM 中删除。

drake.on (Events)

drake是一个事件发射器。drake.on(type, listener)可以使用drake跟踪以下事件。

Events

  • drag,(el, source) —— el被从source 移除
  • dragend,(el) —— el的拖动事件以cancel、remove或drop结束
  • drop,(el, target, source, sibling) ——el在sibling元素之前被放入target 中,最初来自 source
  • cancel,(el, container, source) —— el被拖着走,但它什么也没得到,又回到了它最后一个稳定的container里;el最初来源于source
  • remove,(el, container, source) —— el被拖着走了,被从DOM中移除。它最后一个稳定的父类是container,最初来自source
  • shadow,(el, container, source) —— el,视觉辅助阴影,被移动到container中。当el位置发生变化时,即使在同一容器内,也可能多次触发;el最初来源于source
  • over,(el, container, source) —— el是over container,最初来自source
  • out,(el, container, source) —— el被拖出容器或被丢弃,最初来自source
  • cloned,(clone, original, type) —— DOM元素original被克隆为clone,类型为(‘mirror’或’copy’)。为镜像和复制时触发:true

drake.canMove(item)

返回drake实例是否可以接受DOM元素项的拖动。当满足下面列出的所有条件时,此方法返回true,否则返回false。

  • item是drake指定容器之一的子容器
  • item通过相关的无效检查
  • item通过移动检查

drake.destroy()

删除dragula用于管理容器之间拖放的所有拖放事件。如果在拖动元素时调用.destroy,则该拖动将被有效地取消。

css

Dragula只使用四个CSS类。下面将快速解释它们的用途

  • gu-unselectable —– 在拖动时添加到mirrorContainer元素。您可以在拖动对象时使用它来设置mirrorContainer的样式。
  • gu-transit —– 在拖动源元素的镜像时将其添加到源元素。它只是增加了不透明度。
  • gu-mirror —– 被添加到镜像中。它处理fixed 定位和z-index(并删除元素上的任何先前的边距)。注意,镜像被附加到mirrorContainer,而不是它的初始容器。当使用嵌套规则对元素进行样式化时,请记住这一点,比如.list .item {padding: 10px;}
  • gu-hide —– 是一个帮助类,用于对元素应用display: none。

默认:

.gu-mirror {
  position: fixed !important;
  margin: 0 !important;
  z-index: 9999 !important;
  opacity: 0.8;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
  filter: alpha(opacity=80);
}
.gu-hide {
  display: none !important;
}
.gu-unselectable {
  -webkit-user-select: none !important;
  -moz-user-select: none !important;
  -ms-user-select: none !important;
  user-select: none !important;
}
.gu-transit {
  opacity: 0.2;
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
  filter: alpha(opacity=20);
}

参考

Github/dragula:https://github.com/bevacqua/dragula

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

目前还没有任何评论,快来抢沙发吧!

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

2583 文章
29 评论
84935 人气
更多

推荐作者

Jay

文章 0 评论 0

guowei007

文章 0 评论 0

2668157715

文章 0 评论 0

HY阳

文章 0 评论 0

想挽留

文章 30 评论 3