拖放是一种常见的特性,即抓取对象以后拖到另一个位置。在H5中,任何元素都支持拖放,但是需要注意的是,有些元素存有默认行为(如a元素),应当取消该元素的默认行为。
使用 preventDefault() 取消事件的默认动作
拖动元素-事件:
事件 | 描述 |
---|---|
ondragstart | 当元素开始被拖动时触发——开始拖动 |
ondrag | 拖动源触发——正在拖动 |
ondragend | 拖动源在拖动操作结束将得到dragend对象(不管成功与否)——拖动结束 |
注意:ondrag事件在拖动元素时一直触发,在后面的例子你会看到。
放置元素-事件:
事件 | 描述 |
---|---|
ondragenter | 当拖动中鼠标第一次进入一个元素时触发 |
ondragover | 当拖动中的鼠标移动经过一个元素时触发 |
ondragleave | 当拖动中的鼠标离开元素时触发 |
ondrop | 当拖动操作结束并释放于释放元素上触发 |
注意:只有在拖拽时触发相关事件,鼠标事件是不会触发的。
属性/方法 | 描述 |
---|---|
files | 其属性返回和放置相关的所有文件 |
types | 属性使用数组的形式返回当前注册的格式 |
effectAllowed | 此属性通知浏览器当前可被用户选用的操作 |
dropEffect | 拖放的操作类型,决定了浏览器如何显示鼠标形状 |
items | 属性返回所有项与相关格式的所有文件 |
setData(format,data) | 在dragstart事件调用此函数在dataTransfer对象中存储数据 |
getData(format) | 从dataTransfer对象取出数据 |
setDragImage(element,x,y) | 使用存在的图像元素作为拖动图像 |
addElement(element) | 提供一个页面元素作为参考,同时使用此参数作为拖放反馈图像 |
clearData() | 表示清空所有已注册数据,带参数则清除指定的注册数据(此方法不需要传参99) |
具体API请参照:https://developer.mozilla.org/zh-CN/docs/Web/API/DataTransfer |
需要注意的是,想要让元素可拖动,必须把该元素的 draggable 属性设为 “true” 才允许拖动。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>拖放API</title>
<style>
section{
background:red;
border-radius:50%;
width:100px;
height:100px
}
</style>
</head>
<body>
<section draggable="true" id="demo"></section>
<script>
// 获取元素DOM
var demo = document.querySelector('#demo')
// 开始拖动
demo.ondragstart = function (){
console.log('开始拖动')
}
// 正在拖动
demo.ondrag = function (){
console.log('正在拖动(此事件一直触发,除非结束)')
}
// 结束拖动
demo.ondragend = function (){
console.log('结束拖动')
}
</script>
</body>
</html>
开始拖动——正在拖动——放下
此时,控制台打印结果如下:
在进行拖放操作的时候,dataTransfer对象可以用来保存被拖动的数据。它可以保存一项或多项数据、一种或多数数据类型。通俗一点讲,就是可以通过它来传输被拖动的数据,以便在拖拽结束的时候,对数据进行其他的操作。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>拖放API</title>
<style>
.element{
width:50px;
height:50px;
background:red;
border-radius:50%;
}
section{
width:150px;
height:150px;
background:black;
}
</style>
</head>
<body>
<p>请把小球元素拖到这里:</p>
<section id="container"></section>
<hr>
<div id="e1" class="element" draggable="true">1号</div>
<div id="e2" class="element" draggable="true">2号</div>
<div id="e3" class="element" draggable="true">3号</div>
<script>
// 获取所有 .element DOM节点
var elements = document.querySelectorAll('.element')
// 获取 #container DOM节点
var container = document.getElementById('container')
// 遍历(拖动动作)
for(var i = 0, len = elements.length; i < len; i++){
elements[i].ondragstart = function (e){
// dataTransfer对象中存储数据
e.dataTransfer.setData('id',this.id)
}
}
// 取消默认事件(否则无法放置)
// 其他方法:container.ondragover = function (even){
// even.preventDefault()
// }
container.ondragover = () => {return false}
// 放置 .element DOM节点(放下)
container.ondrop = function (e){
// 获取 dataTransfer对象数据
var id = e.dataTransfer.getData('id')
// 根据 id 添加到容器
let Flag = document.getElementById(id)
this.appendChild(Flag)
// 控制台查看小球id
console.log(`您当前放置的小球是:【${id}】`)
}
</script>
</body>
</html>
未拖入:
已拖入:
注意:在其它的事件(如ondragover、ondragleave等),是无法获取dataTransfer里面的值了。这是由于W3C要求对dataTransfer里的值进行保护。因此,如果需要在这些事件里获取数据,只能通过一个全局变量等其它方式来实现了。