# @bpmn-io/draggle 中文文档

规范地址：https://npmcn.com/package/%40bpmn-io/draggle/

版本：4\.1\.2
npm 元数据更新时间：2026-07-08T15:54:02.560Z
中文译文更新时间：2026-11-08T13:08:16.269Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40bpmn-io/draggle
原文对照：https://npmcn.com/package/%40bpmn-io/draggle/?lang=original
项目主页：https://github.com/bpmn-io/draggle
源码仓库：https://github.com/bpmn-io/draggle

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：35 kB，6 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：未声明
- 运行依赖：1 个
- 首次发布：2023-08-01T11:20:14.345Z
- 最新版本发布：2025-07-18T14:36:15.564Z
- 近 30 天下载量：58144（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：5（近 12 个月 0 个）

## 中文简介

拖倒那么简单,很痛

## 安装

```sh
npm install @bpmn-io/draggle
```

也可以使用：`pnpm add @bpmn-io/draggle`、`yarn add @bpmn-io/draggle`、`bun add @bpmn-io/draggle`

## README

# @bpmn-io/ draggle (英语)

> 拖倒那么简单,很痛

> 这个项目是从 [https://github.com/bevacqua/dragula 页面存档备份,存于互联网档案馆](https://github.com/bevacqua/dragula)

[![CI](https://github.com/bpmn-io/draggle/workflows/CI/badge.svg)](https://github.com/bpmn-io/draggle/actions?query=workflow%3ACI)

## 安装

你可以在npm得到它.

```shell
npm install @bpmn-io/draggle --save
```

或者一个CDN.

```shell
<script src='https://unpkg.com/@bpmn-io/draggle@4.0.0/dist/draggle.js'></script>
```

如果您没有使用任何软件包管理器, 您可以使用 `@bpmn-io/draggle` 下载 `dist` 文件夹。 我们 **强烈建议** 使用 `npm`虽然.

### 包括 Java 脚本

有个警告 `draggle`你不应该把它包括在 `<head>` 网络应用程序。 把脚本放进 `<head>`,因此 `draggle` 不遗余力地支持这一使用案例.

地点 `draggle` 输入 `<body>`,转而.

### 包括CSS队!

有一些CSS的风格 你需要纳入,以便 `draggle` 将按预期工作.

你可以加入它们 `dist/draggle.css` 在文档中.

## 发展

启动一个开发服务器 .

```shell
npm start
```

执行测试.

```shell
npm run all
```

## 使用量

Draggle 提供了最简单的 API 在您的应用程序中拖放微风 .

### `draggle(containers?, options?)`

默认, `draggle` 将允许用户在其中任意 `containers` 放在清单上的任何其他容器中 如果元素被扔到任何地方,那不是其中之一 `containers`,根据 `revertOnSpill` 财务报告和审定财务报表 `removeOnSpill` 选项.

注意拖曳只在左键上被触发,并且只有在没有按下元键时才会被触发.

下面的例子允许用户从 `left` 输入 `right`,从 `right` 输入 `left`。 。 。 .

```js
draggle([document.querySelector('#left'), document.querySelector('#right')]);
```

您也可提供 `options` 对象。 这个 **默认值概览**。 。 。 .

```js
draggle(containers, {
  isContainer: function (el) {
    return false; // only elements in drake.containers will be taken into account
  },
  moves: function (el, source, handle, sibling) {
    return true; // elements are always draggable by default
  },
  accepts: function (el, target, source, sibling) {
    return true; // elements can be dropped in any of the `containers` by default
  },
  invalid: function (el, handle) {
    return false; // don't prevent any drags from initiating by default
  },
  direction: 'vertical',             // Y axis is considered when determining where an element would be dropped
  copy: false,                       // elements are moved by default, not copied
  copySortSource: false,             // elements in copy-source containers can be reordered
  revertOnSpill: false,              // spilling will put the element back where it was dragged from, if this is true
  removeOnSpill: false,              // spilling will `.remove` the element, if this is true
  mirrorContainer: document.body,    // set the element that gets mirror elements appended
  ignoreInputTextSelection: true,     // allows users to select input text, see details below
  slideFactorX: 0,               // allows users to select the amount of movement on the X axis before it is considered a drag instead of a click
  slideFactorY: 0,               // allows users to select the amount of movement on the Y axis before it is considered a drag instead of a click
});
```

你可以省略这个 `containers` 参数,并在稍后动态地添加容器.

```js
var drake = draggle({
  copy: true
});
drake.containers.push(container);
```

您也可以设置 `containers` 从 `options` 对象.

```js
var drake = draggle({ containers: containers });
```

您也无法设置任何参数, 它默认为没有容器和默认选项的拖拉机.

```js
var drake = draggle();
```

以下详细介绍这些备选方案.

#### `options.containers`

设置此选项与将第一个参数中的容器传递到 `draggle(containers, options)`。 。 。 .

#### `options.isContainer`

除了你传递到的容器 `draggle`,或者您动态的容器 `push` 或者说 `unshift` 从 [drake.集装箱](https://npmcn.com/package/%40bpmn-io/draggle/#readme-drakecontainers),也可以使用这种方法来指定定义该特定容器的任意类型的逻辑 `drake` 举个例子.

以下示例以 CSS 类动态处理所有 DOM 元素: `draggle-container` 作为此的拖放容器 `drake`。 。 。 .

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

#### `options.moves`

您可以定义一个 `moves` 将使用 `(el, source, handle, sibling)` 当单击元素时。 如果此方法返回 `false`拖曳活动不会开始 也不会被阻止 这个 `handle` 元素将是原始的点击目标, 如果该元素是预期的, 它将有利于测试 _"破手柄" "drag hands"_。 。 。 .

#### `options.accepts`

你可以设置 `accepts` 改为具有下列签名的方法: `(el, target, source, sibling)`。它将被调用以确保元素 `el`,来自容器 `source`,可以投放到容器上 `target` 之前为 `sibling` 键。 这个 `sibling` 可能会是 `null`,这意味着该元素将作为最后的元素放入容器。 注意,如果 `options.copy` 设置为 `true`, (中文(简体) ), `el` 将设定为副本,而不是原拖放的元素.

还注意到 **拖曳开始的位置将永远成为将元素丢出的有效位置**,即使 `accepts` 已返回 `false` 所有情况.

#### `options.copy`

若为 `copy` 设置为 `true` _(或一种返回的方法) `true`(中文(简体) )_,项目将被复制而不是移动。 这意味着以下差异:

| 活动 | 移动 | 复制 |
| --- | --- | --- |
| `drag` | 元素将被隐藏 `source` | 什么都没有发生 |
| `drop` | 元素将移入 `target` | 元素将被克隆为 `target` |
| `remove` | DOM 将删除元素 | 什么都没有发生 |
| `cancel` | 元素会留在里面 `source` | 什么都没有发生 |

如果一个方法被通过,当一个元素开始被拖动时,它就会被调用,以便决定它是否应该遵循 `copy` 行为或不行为。 考虑以下例子.

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

#### `options.copySortSource`

若为 `copy` 设置为 `true` _(或一种返回的方法) `true`(中文(简体) )_ 财务报告和审定财务报表 `copySortSource` 实值 `true` 用户还可以在 `copy`\- 来源容器.

```js
copy: true,
copySortSource: true
```

#### `options.revertOnSpill`

默认情况下,在任何容器外溢出一个元素会将元素移回 _由反馈阴影预览的位置_设置 `revertOnSpill` 改为 `true` 确保将任何经批准的容器外投放的部件运回开始拖放活动的源部件,而不是停留在 _由反馈阴影预览的位置_。 。 。 .

#### `options.removeOnSpill`

默认情况下,在任何容器外溢出一个元素会将元素移回 _由反馈阴影预览的位置_设置 `removeOnSpill` 改为 `true` 将确保从DOM中取出任何经批准的集装箱以外的部件。 请注意: `remove` 如果 `copy` 设置为 `true`。 。 。 .

#### `options.direction`

当一个元素被扔入容器时,它会被放置在鼠标被放出的地方附近. 如果 `direction` 实值 `'vertical'`,默认值,将考虑Y轴。 否则,如果 `direction` 实值 `'horizontal'`,将考虑X轴.

#### `options.invalid`

你可以提供 `invalid` 使用一个方法 `(el, handle)` 签名。 这种方法应返回 `true` 对于不应被拖动的元素。 这个 `handle` 参数是单击的元素,而 `el` 是将被拖动的项目。 以下是默认执行,无法防止任何拖曳.

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

请注意: `invalid` 将引用于点击的 DOM 元素和每个家长直至直系子女 `drake` 集装箱.

例如,你可以设定 `invalid` 返回 `false` 当单击元素时 _(或其任何父母)_ 是一个锚标记.

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

#### `options.mirrorContainer`

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

#### `options.ignoreInputTextSelection`

当启用此选项时, 如果用户点击输入元素, 拖曳将不会开始, 直到鼠标指针退出输入 。 这将转换为用户能够选择包含在可拖动元素内部的输入中的文本,并且仍然通过将其鼠标移出输入之外来拖动元素——所以你可以得到两个世界中最好的.

此选项默认启用 。 通过设定关闭它 `false`。如果其已禁用,您的用户将无法在输入中选择文本 `draggle` 装有老鼠的容器.

### API 密码

这个 `draggle` 方法返回一个带有简洁 API 的小对象。 我们会提到API返回 `draggle` 作为 `drake`。 。 。 .

#### `drake.containers`

该财产中收存的集装箱已转交给 `draggle` 创建时 `drake` 举个例子 你们可以 `push` 更多的集装箱和 `splice` 随意装入旧容器.

#### `drake.dragging`

这个地产是 `true` 当一个元素被拖动时.

#### `drake.start(item)`

输入拖动模式 **没有阴影**。这种方法在为现有的拖放解决方案提供辅助键盘快捷键时最为有用。 虽然一开始不会创造出阴影,但用户点击后会立即得到一个 `item` 并开始拖来拖去。 注意,如果他们点击和拖动别的东西, `.end` 将在接起新项目之前拨打.

#### `drake.end()`

顺利结束拖曳事件, 如使用 **以预览阴影标记的最后位置** 作为下降目标。 适当的 `cancel` 或者说 `drop` 事件将会被发射,这取决于该物品是否在原卸出之处被放回原地 _(本质上是无操作,被当做是) `cancel` 活动)_。 。 。 .

#### `drake.cancel(revert)`

如果一个元素由 `drake` 正在拖动中,此方法将优雅地取消拖动动作 。 也可以通过 `revert` 在方法引用层面,有效产生与 `revertOnSpill` 曾经 `true`。 。 。 .

请注意: **(单位:千美元) _"取消资格"_ 将产生 `cancel` 事件** 仅在以下情况下.

-   `revertOnSpill` 实值 `true`
-   投弃目标 _(由反馈阴影预览)_ 是源容器 **财务报告和审定财务报表** 物品被丢入原来拖出的位置

#### `drake.remove()`

如果一个元素由 `drake` 目前正在拖取中,这种方法将优雅地从DOM中删除.

#### `drake.on` _(活动)_

这个 `drake` 是一个事件发送器。 以下事件可使用 `drake.on(type, listener)`数字 :

| 事件名称 | 听者参数 | 事件描述 |
| --- | --- | --- |
| `drag` | `el, source` | `el` 已经取消 `source` |
| `dragend` | `el` | 拖动事件 `el` 结束于 `cancel`, (中文(简体) ), `remove`,或 `drop` |
| `drop` | `el, target, source, sibling` | `el` 被丢入 `target` 之前为 `sibling` 元素,最初来自 `source` |
| `cancel` | `el, container, source` | `el` 被拖走却无所事事 回到了 `container`其最后稳定的父母; `el` 最初来自 `source` |
| `remove` | `el, container, source` | `el` 被拖走却无所事事 从DOM中取出 最后一位稳定的父母 `container`,最初来自 `source` |
| `shadow` | `el, container, source` | `el`, (中文(简体) ), _视觉辅助阴影_,被移动到 `container`。可能多次触发作为 `el` 变化,即使在同一范围内 `container`· ; `el` 最初来自 `source` |
| `over` | `el, container, source` | `el` 结束了 `container`,最初来自 `source` |
| `out` | `el, container, source` | `el` 被拖出来 `container` 或下降,最初来自 `source` |
| `cloned` | `clone, original, type` | DOM 元素 `original` 被复制为 `clone`,则 `type` _(单位:千美元)`'mirror'` 或者说 `'copy'`(中文(简体) )_。为镜像图像和何时发射 `copy: true` |

#### `drake.canMove(item)`

返回是否为 `drake` 实例可以接受 DOM 元素的拖曳 `item`。此方法返回 `true` 符合下列所有条件时 `false` 否则.

-   `item` 属于指定容器之一的儿童,用于: `drake`
-   `item` 通过相关的 [`invalid`](https://npmcn.com/package/%40bpmn-io/draggle/#readme-optionsinvalid) 检查
-   `item` 通过 a `moves` 检查

#### `drake.destroy()`

删除所有拖放事件 `draggle` 来管理拖放 `containers`如果 `.destroy` 当一个元素被拖动时,该拖动将被有效取消.

### 支助科

Draggle只使用四个CSS类. 目的在下文迅速解释,但你可以检查 `dist/draggle.css` 以查看相应的 CSS 规则.

-   `gu-unselectable` 添加到 `mirrorContainer` 元素在拖动时。 你可以用它来塑造 `mirrorContainer` 一边拖着东西.
-   `gu-transit` 当其镜像被拖动时,将添加到源元素中。 只会增加不透明度.
-   `gu-mirror` 添加到镜像中。 它处理固定定位和 `z-index` _(并去除元素上任何先前的边距)_。请注意,镜像附在 `mirrorContainer`,而不是其初始容器。 记住,当你的元素 与巢规则,像 `.list .item { padding: 10px; }`。 。 。 .
-   `gu-hide` 是应用的助手类 `display: none` 到一个元素.

## 许可证

麻省理工学院

## 常见问题

### @bpmn-io/draggle 是什么？

拖倒那么简单,很痛

### 如何安装 @bpmn-io/draggle？

在项目目录运行 npm install @bpmn-io/draggle，或使用 pnpm add / yarn add / bun add。

### @bpmn-io/draggle 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/bpmn-io\_\_draggle 是否存在。

### @bpmn-io/draggle 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @bpmn-io/draggle 可以商用吗？

@bpmn-io/draggle 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @bpmn-io/draggle 的下载量有多少？

根据 npm 官方下载统计，@bpmn-io/draggle 在 2026/10/09 – 2026/11/07 这 30 天内被下载 58,144 次，日均约 1,938 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @bpmn-io/draggle 还在维护吗？

最新版本 4\.1\.2 发布于 2025/07/18（1\.3 年前）；至今共发布 5 个版本，其中过去 12 个月发布了 0 个；首次发布于 2023/08/01。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

