一、拖放事件
1、概念
在 HTML5 中增加了多个针对元素拖放的事件,使实现元素拖放变得更简单。拖放事件仅仅能实现拖放的动作,要想真正实现拖放后进行数据交互,还需要结合 dataTransfer 对象,才能真正实现拖放效果。
注意:要实现元素拖放,首先要在目标元素上 设置 draggable = “true” ,否则无法实现拖放。
2、事件
① dragStart:在元素拖动开始时触发,事件对象是被拖动元素。
② drag:在元素拖动过程中触发,事件对象是被拖动元素。
③ dragEnter:当被拖动元素进入目标元素时触发,事件对象是目标元素。
④ dragOver:当被拖动元素在目标元素内移动时触发,事件对象是目标元素。
⑤ dragLeave:当被拖动元素离开目标元素时触发,事件对象目标元素。
⑥ drop:当被拖动元素放置在目标元素上是触发,事件对象是目标元素。
⑦ dragEnd:当拖放事件完成后,即 drop 事件之后触发,事件对象是被拖动元素。
3、事件执行顺序
正常情况下,在页面中执行一次拖放操作,一般会按顺序执行以下五个事件:dragStart、dragEnter、dragOver、drop、dragEnd 。如果反复拖动元素离开和进入目标元素,则 dragEnter 和 dragLeave 事件会被执行多次。
二、dataTransfer 对象
1、概念
dataTransfer 对象是事件对象的一个属性,用来暂时存放被拖放的数据,只能在拖放事件的处理程序中访问该对象。不过目前不同的浏览器对该对象的支持情况不同,所以下面以谷歌浏览器为标准说明。
2、属性
① dropEffect
该属性用来设置拖放操作的实际行为,应该在 dragEnter 和 dragOver 事件中设置,允许设置的值有:
copy:将被拖动对象拷贝到目标元素中
move:将被拖动对象移动到目标元素中
link:在目标元素中建立一个被拖动对象的链接
none:不允许放到目标元素中
function dragEnter(event) {
event.dataTransfer.dropEffect = 'move';
}
② effectAllowed
该属性用来设置允许发生的拖动行为,应该在 dragStart 事件中设置,允许设置的值有:
copy:将被拖动对象拷贝到目标元素,此时 dropEffect 应设置为 “copy”
move:将被拖动对象移动到目标元素中,此时 dropEffect 应设置为 “move”
link:在目标元素中建立一个被拖动对象的链接,此时 dropEffect 应设置为 “link”
copyLink:拷贝对象或建立对象链接,此时 dropEffect 应设置为 “copy” 或 “link”
copyMove:拷贝或移动对象,此时 dropEffect 应设置为 “copy” 或 “move”
linkMove:建立对象链接或移动对象,此时 dropEffect 应设置为 “link” 或 “move”
all:允许所有拖放行为。
none:不允许任何拖放行为
uninitialized:默认值,效果相当于 all
function dragStart(event) {
event.dataTransfer.effectAllowed = 'copyLink';
}
③ types
该属性返回一个 List 对象,里面包含所有存储到 dataTransfer 的数据类型。
④ files
该属性返回一个 List 对象,当从本地拖拽文件带浏览器中时,可以通过该属性获取文件列表。
3、方法
① setData(format,data)
该方法用来将指定格式的数据存储在 dataTransfer 对象中,参数 format 定义数据类型,data 定义要存储的数据。
// 将被拖动对象的id属性 以 text 类型存储到 dataTransfer 对象中
event.dataTransfer.setData("text",event.target.id);
② getData(format)
该方法用来从 dataTransfer 对象中获取指定格式的数据。参数 format 定义要读取数据的类型,如果指定的数据类型不存在,则返回空字符串或报错。
// 从 dataTransfer 对象中读取出 text 类型的数据,赋值给变量
var data = event.dataTransfer.getData("text");
③ clearData([format])
该方法用来从 dataTransfer 对象中删除指定格式的数据,参数 format 可选,如果不写参数,则删除 dataTransfer 对象中的所有数据。
// 删除 dataTransfer 对象中 所有 text 类型的数据。
event.dataTransfer.clearData("text");
④ setDragImage(element,x,y)
该方法用来设置进行拖放操作时鼠标指针跟随显示的图片,参数 element 定义图片、x 定义图片与鼠标指针在水平方向上的距离、y 定义图片与鼠标指针在垂直方向上的距离。默认情况下,是将拖动对象转换成透明图片来跟随鼠标指针移动。
// 将一张图片设置到跟随指针移动
var img = new Image();
img.src = "../logo.png";
event.dataTransfer.setDragImage(img,0,0);
三、拖动案例
案例展示:
初始状态:
拖放中:
拖放结束:
案例代码:
<head>
<style>
body {
text-align: center;
}
.box {
margin-left: 800px;
}
#sourceObject,#aimObject {
float: left;
padding: 10px;
margin: 15px;
}
#sourceObject {
background-color: #DFD7D7;
width: 75px;
height: 70px;
}
#aimObject {
background-color: #A347FF;
width: 150px;
height: 150px;
}
</style>
<script>
// 开始拖放
function dragStart(event) {
// 设置允许发生的拖放行为
event.dataTransfer.effectAllowed = 'copy';
// 利用 dataTransfer 存储 拖放对象的 id
event.dataTransfer.setData("Text",event.target.id);
document.querySelector("#status").innerHTML = "开始拖动"
}
// 拖放中
function drag(event) {
document.querySelector("#status").innerHTML = "拖动中..."
}
// 拖放结束
function dragEnd(event) {
document.querySelector("#status").innerHTML = "拖动结束"
}
// 拖放进入目标元素
function dragEnter(event) {
// 屏蔽元素的默认行为 否则 drop 事件可能不会被触发
event.preventDefault();
document.querySelector("#status").innerHTML = "进入目标区域"
}
// 拖放在目标元素内移动
function dragOver(event) {
// 屏蔽元素的默认行为 否则 drop 事件可能不会被触发
event.preventDefault();
// 设置拖放操作的实际行为
event.dataTransfer.dropEffect = "copy";
document.querySelector("#status").innerHTML = "在目标区域移动"
}
// 拖放离开目标元素
function dragLeave(event) {
document.querySelector("#status").innerHTML = "离开目标区域"
}
// 将拖放元素放置到目标元素中
function drop(event) {
// 屏蔽元素的默认行为 否则 drop 事件可能不会被触发
event.preventDefault();
// 读取 dataTransfer 对象中的数据
var data = event.dataTransfer.getData("Text");
// 将 拖放对象 加入到 目标元素中
event.target.appendChild(document.getElementById(data))
document.getElementById(data).innerHTML = "废弃文件"
document.querySelector("#status").innerHTML = "在目标区域放下拖动对象"
}
</script>
</head>
<body>
<h2>HTML5拖放</h2>
<div id="status">状态监控中</div>
<div class="box">
<div id="aimObject" ondragover="dragOver(event)" ondrop="drop(event)" ondragleave="dragLeave(event)" ondragenter="dragEnter(event)">
<p>回收站</p>
</div>
<div id="sourceObject" draggable="true" ondrag="drag(event)" ondragstart="dragStart(event)" ondragend="dragEnd(event)">
<p>待删除文件</p>
</div>
</div>
</body>