HTML5 Drag&Drop

225 阅读3分钟

HTML中的拖放功能

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情

HTML 拖放功能使得用户能够在浏览器中使用拖放功能。例如,用户可使用鼠标选择可拖拽(draggable)元素,将元素拖拽到可放置(droppable)元素,并释放鼠标按钮以放置这些元素。拖拽操作期间,会有一个可拖拽元素的半透明快照跟随着鼠标指针。

一个典型的拖拽操作是这样的:用户选中一个可拖拽的(draggable) 元素,并将其拖拽(鼠标不放开)到一个可放置的(droppable) 元素,然后释放鼠标。

Drag Events 拖拽事件

拖拽事件Drag Events继承了 mouse events

拖拽事件类型共计7种,可以按照如下类别划分:

  • 可拖拽元素

    • 事件事件处理触发时机
      dragstartondragstart可拖拽元素被拖拽起来的一瞬
      dragondrag可拖拽元素一直被拖拽时,每隔100ms触发一次
      dragendondragend可拖拽元素被释放的一瞬
  • 可释放元素

    • 事件事件处理触发时机
      dragenterondragenter可拖拽元素被拽入可释放元素时
      dragoverondragover可拖拽元素一直在可释放元素上时,不松开鼠标释放元素
      dragleaveondragleave可拖拽元素被拽离可释放元素时
      dropondrop松开鼠标释放,释放可拖拽元素,将其放入可释放元素中

接口对象

HTML拖拽事件用到了以下对象: DragEvent, DataTransfer, DataTransferItemDataTransferItemList。它们四个的关系如下:

DragEvent

DragEvent接口是一个表示拖放交互的DOM事件。用户通过将指针设备(如鼠标)放置在触摸表面上开始拖动,然后将指针拖动到新的位置(如另一个DOM元素)。

这个接口继承了MouseEventEvent的属性。其自身的属性 dragEvent.dataTransfer对应的是一个DataTransfer对象。

DataTransfer

用于保存拖拽操作时的数据,可以有多个数据项和对应的数据类型。

标准属性如下:

  • dataTransfer.dropEffect:拖拽效果,可选值——copymovelinknone

  • dataTransfer.effectAllowed:可选的效果

  • dataTransfer.files: 拖拽的文件

  • dataTransfer.items:只读,DataTransferItemList对象,其中每个元素是DataTransferItem对象,具有 kindtype属性,描述所拖拽的元素。

    DataTransferItem {kind: "string", type: "text/plain"}
    
  • dataTransfer.types:只读,拖拽对象的MIME类型。

如何使用拖拽功能

1. 设置元素可拖拽

web页面中,文本、图像和链接是默认可拖拽的,而其它HTML元素默认是不可拖拽的。

要想将HTML元素设置成可拖拽的,需要以下三步:

  1. 元素的draggable属性设置为truedraggable="``true"
  2. 在元素上监听dragstart事件;
  3. dragstart事件监听器中设置被拖拽的数据。ev.dataTransfer.setData("text/plain", ev.target.id);

此外,还可以设置拖拽背景图片和拖拽效果,这俩不是必须的。

3. 确定可释放元素

如果想要在某个元素中可以释放被拖拽对象,那么需要在该元素上绑定dragover事件并阻止默认事件操作。

<div ondragover="event.preventDefault()">

4. 处理释放效果

在可释放元素上监听drop事件,通过event.dataTransfer.getData()方法取出被拖拽的数据,并对其作出相应操作。

5. 拖拽结束

无论是否拖拽成功,都会触发被拖拽元素上的dragend事件。可能需要根据DataTransfer.dropEffect来处理释放时应该发生的操作,如果是move操作的话,需要将被拖拽对象从原位置移除。

6. 如何取消释放操作

方法1:

dragover事件监听时,根据条件判断是否阻止默认操作,调用了preventDefault()方法,表示可以在这里释放。

if (true){
    ev.preventDefault();
} 

方法2:

dropdropend事件里不做任何操作,同样可以设置条件判断。

参考文档

developer.mozilla.org/zh-CN/docs/…