如何使用拖放API

探索如何使用拖放API为您的用户创建交互式体验

使用拖放API,您可以定义页面中的哪些元素是可拖动的,并在用户拖动元素时进行拦截。

在现代浏览器中,它得到了很好的支持:

Browser support

在开始研究API之前,我们必须知道如何定义页面中的哪些元素可拖动的。我们可以通过添加draggable页面HTML中的属性,其值为true

<div draggable="true">
  ...
</div>

这足以使该元素可拖动。

提示:除非您进行设置,否则默认情况下图像,文本选择和链接是可拖动的draggable对他们虚假

我们还可以从浏览器内部的用户计算机中拖动文件。在这种情况下,我们正在转移档案

我们需要澄清的另一点是我们可以将元素拖到哪里。我们不仅可以拖动任何元素,也不能仅拖放到任何元素中。元素必须有效放下目标

要使一个元素成为放置目标,您需要监听它dragover事件,您要么从中返回false,要么调用preventDefault()关于通过的事件:

const element = document.querySelector('#my-drop-target)
element.addEventListener('dragover', event => {
  event.preventDefault()
})

一旦这样做,便有了一个可拖动元素和一个放置目标,就可以开始了。我们可以在draggable元素上进行交互的事件是:

  • dragstart
  • drag
  • dragend

在放置目标上:

  • dragenter
  • dragover
  • dragleave
  • drop

拖放操作和触发事件概述

当用户开始拖动可拖动元素,用鼠标单击并移动鼠标,或者点按并按住水龙头,然后移动选区,dragstart事件被触发:

element.addEventListener('dragstart', event => {
  //...
})

event作为参数传递给事件处理函数的对象是DragEvent目的。

它从更一般的角度延伸事件对象,与其他所有事件共享:鼠标,键盘,滚动等。

此时,该元素正在被拖动,并且drag事件被触发。多次拖动该项目,因此我们必须像scroll或者mouseover事件。

我们一进入放下目标

  1. dragenter在放置目标上触发了事件
  2. dragover在放置目标上触发了事件

如果被拖动的元素首先进入放置目标,然后从该目标移开,则dragleave事件在放置目标上触发。

如果用户释放鼠标,dragend在要拖动的元素上触发事件,并且drop事件在放置目标上触发。

拖动数据:DataTransfer

与拖放相关的每个事件都是DragEvent就像我提到的那样,它带有一个名为dataTransfer其中包含要拖动的数据,并提供5个属性:

  • dropEffect
  • effectAllowed
  • files
  • items(只读)
  • types(只读)

当拖动事件开始时,您可以执行一些操作。

设置/获得效果

您可以通过设置effectAllowed物业dragstart事件。您有一些选项可以设置放置目标应如何处理放置的元素:

  • none它不应该被丢弃
  • move它可以移动
  • copy可以复制
  • link可以链接
  • copyMove可以复制或移动
  • copyLink可以复制或链接
  • linkMove可以移动或链接
  • all可以复制,移动或链接

(都是字符串)。

默认是all

dropEffect属性用于获取拖放操作的类型,这是用户这次通过使用修饰键设置的类型。例如,在Mac上,按Alt键将放置目标设置为复制项目而不是移动项目。

此属性不是只读的。我们可以在dragenter或者dragover事件,这些字符串值之一:

  • none它不应该被丢弃
  • move它可以移动
  • copy可以复制
  • link可以链接

例子:

element.addEventListener('dragenter', event => {
  event.dataTrasfer.dropEffect = 'move'
})

正在传输的数据

您可以访问从dataTransfer.items属性,它是一个类似于数组的对象,您可以使用循环对其进行迭代并访问每个对象DataTransferItem目的。

DataTransferItem具有2个只读属性:

  • kind:要拖动的项目的类型。返回包含以下内容的字符串file或者string
  • type项目的MIME类型

它有2种方法:

  • getAsFile()返回一个File表示要拖动的数据的对象
  • getAsString()执行回调函数,粘贴一个字符串对象,该对象表示要拖动的数据

它们的名称相似,但工作方式却大不相同。第一个返回File目的:

element.addEventListener('dragenter', event => {
  for (item of event.dataTrasfer.items) {
    const theFile = item.getAsFile()
  }
})

了解有关文件对象的更多信息,请访问https://flaviocopes.com/file/

第二个将项目作为字符串传递给回调函数:

element.addEventListener('dragenter', event => {
  for (item of event.dataTrasfer.items) {
    item.getAsString(theString => {
      console.log(theString)
    })
  }
})

被拖动的项目文件的类型存储在types的属性dataTransfer目的。它是一个包含字符串的数组string默认情况下。如果我们要拖动文件,则对应的类型是一串值Files

如果有文件正在传输,除了列出dataTransfer.items,它们存储在files的财产dataTransfer

该属性指向FileList列出要拖动的文件的对象。

在Codepen上查看此演示:

看笔拖放!由Flavio Copes(@flaviocopes) 在密码笔

Tech Wiki Online!