探索如何使用拖放API为您的用户创建交互式体验
使用拖放API,您可以定义页面中的哪些元素是可拖动的,并在用户拖动元素时进行拦截。
在现代浏览器中,它得到了很好的支持:
在开始研究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
事件。
我们一进入放下目标:
- 这
dragenter
在放置目标上触发了事件 - 这
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!