H5 拖拽基础 DataTransfer 和 drag/drop

6,006 阅读3分钟

WebAPI: DataTransfer

DataTransfer 构造器是对象用于保存拖动并放下(drag and drop)过程中的数据。例如使用 getData/setData 方法存取数据。

使用构造函数 DataTransfer以及 api

let d = new DataTransfer();
d.setData("a", 123);
d.getData("a"); // 123

从 dom 元素上获取

可拖动对象,darg event 对象的存在一个 dataTransfter 属性。

属性与方法

属性与方法说明
dropEffectnone, copy(拷贝到新位置), link(建立联系) 或 move(拖拽元素将被移动)。
effectAllowed提供所有可用的操作类型。必须是  nonecopycopyLinkcopyMovelinklinkMovemoveall or uninitialized  之一。
files包含数据传输中可用的所有本地文件的列表。如果拖动操作不涉及拖动文件,则此属性为空列表。
items提供一个包含所有拖动数据列表的 DataTransferItemList 对象。
types一个提供 dragstart 事件中设置的格式的 strings 数组。
clearData()移除数据,clearData 函数只能再 dragStart 函数,在 drop 函数里面调用。
getData()检索给定类型的数据,如果该类型的数据不存在或 data transfer 不包含数据,则返回空字符串。
setData()设置给定类型的数据。如果该类型的数据不存在,则将其添加到末尾,以便类型列表中的最后一项将是新的格式。如果该类型的数据已经存在,则在相同位置替换现有数据。
setDragImage()用于设置自定义的拖动图像。

H5 之前实现拖拽实现方法

PC 端

利用鼠标 mousedownmousemovemouseup 三个事件可以实现拖拽操作对象跟随鼠标任意移动的效果。

H5 端

使用 Touch 事件: touchstartontouchmovetouchend

拖拽实践类型+拖拽全局属性

事件On 型事件处理程序触发时刻
dragondrag当拖拽元素或选中的文本时触发。
dragendondragend )当拖拽操作结束时触发 (比如松开鼠标按键或敲“Esc”键)
dragenterondragenter当拖拽元素或选中的文本到一个可释放目标时触发
dragleaveondragleave当拖拽元素或选中的文本离开一个可释放目标时触发。
dragoverondragover)当元素或选中的文本被拖到一个可释放目标上时触发(每 100 毫秒触发一次)。
dragstartondragstart当用户开始拖拽一个元素或选中的文本时触发(见开始拖拽操作。
dropondrop当元素或选中的文本在可释放目标上被释放时触发。

drop 事件一般将拖动元素放置到目标元素上时触发。同时

注意: 当从操作系统向浏览器中拖拽文件时,不会触发 dragstartdragend 事件。

一个简单的拖拽示例

<!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>拖拽</title>
    <style>
      .container {
        width: 300px;
        height: 300px;
        border: 1px solid #000;
        background-color: #eee;
      }
      .pixi {
        width: 30px;
        height: 30px;
        border: 1px solid eee;
        background-color: red;
      }
      .bd {
        border: 3px dashed #fff;
      }
    </style>
    <script type="text/javascript">
      function drag(e) {
        console.log(e);
        e.dataTransfer.setData("Text", e.target.id);
        e.target.classList.add("bd");
      }
      function allowDrop(ev) {
        console.log(ev);
        ev.preventDefault();
      }

      function drop(ev) {
        ev.preventDefault();
        var data = ev.dataTransfer.getData("Text");
        let ch = document.getElementById(data);
        ev.target.appendChild(ch);
        ch.classList.remove("bd");
      }
    </script>
  </head>
  <body>
    <div
      id="ctn"
      class="container"
      ondrop="drop(event)"
      ondragover="allowDrop(event)"
    ></div>
    <div
      id="pixi"
      class="pixi"
      draggable="true"
      ondragstart="drag(event)"
    ></div>
  </body>
</html>

div#pixi 元素添加 draggable 属性。

React/Vue 组件

React 拖拽库

名字说明
react-beautiful-dnd使用 React 漂亮且易于拖放列表
react-dndDrag and Drop 为 react
react-draggableReact 拖拽组件
react-dropzone带有 React.js 的简单 HTML5 拖放区。

Vue 拖拽库

名字说明
Vue.Draggable基于 Sortable.js(一款轻量级拖拽排序 JS 插件) 开发的 Vue 拖拽组件。
vue-drag-resize支持拖拽和缩放两个大动作,轻量级,无依赖,功能扎实,适合需要缩放的应用场景。
vue-smooth-dnd是一款简单轻量的拖拽排序 Vue 组件,封装了 smooth-dnd 库。
v-drag简单好用的 Vue 拖拽组件,对触摸事件友好支持。
Vue-Easy-DnD就如他的名字一样简单快捷,没有任何啰嗦的功能,支持键盘事件,支持 SSR ,支持触摸事件。

小结

  • DataTransfer 是一个 WebAPI 保存拖动/放下数据的对象。getData/setData 两个方法更是常用。
  • 一个简单的拖拽实例,简单使用 DataTransfer 方法。接下来看 拖拽(drag/drop)API
  • drag/drop api 输出,以及简单的小栗子。

参考