被拖动的源对象可以触发的事件:
(1)ondragstart:源对象开始被拖动
(2)ondrag:源对象被拖动过程中(鼠标可能在移动也可能未移动)
(3)ondragend:源对象被拖动结束
拖动源对象可以进入到上方的目标对象可以触发的事件:
(1)ondragenter:目标对象被源对象拖动着进入
(2)ondragover:目标对象被源对象拖动着悬停在上方
(3)ondragleave:源对象拖动着离开了目标对象
(4)ondrop:源对象拖动着在目标对象上方释放/松手
拖拽API总共就是7个函数!!
五、如何在拖动的源对象事件和目标对象事件间传递数据
HTML5为所有的拖动相关事件提供了一个新的属性:
e.dataTransfer { } //数据传递对象
功能:用于在源对象和目标对象的事件间传递数据
源对象上的事件处理中保存数据:
e.dataTransfer.setData( k, v ); //k-v必须都是string类型
目标对象上的事件处理中读取数据:
var v = e.dataTransfer.getData( k );
示例一:实现一个可以随着鼠标拖动而移动的小飞机
提示:飞机需要绝对定位!ondrag事件中获取鼠标的坐标值!!!
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
body{
margin:0;
position: relative;
}
img{
position:absolute;
}
</style>
</head>
<body>
<h3>随着鼠标拖动而移动的小飞机</h3>
<img id="p3" src="img/p3.png" alt=""/>
<script>
p3.ondragstart=function(e){
console.log('事件源p3开始拖动');
//记录刚一拖动时,鼠标在飞机上的偏移量
offsetX= e.offsetX;
offsetY= e.offsetY;
}
p3.ondrag=function(e){
console.log('事件源p3拖动中');
var x= e.pageX;
var y= e.pageY;
console.log(x+'-'+y);
//drag事件最后一刻,无法读取鼠标的坐标,pageX和pageY都变为0
if(x==0 && y==0){
return; //不处理拖动最后一刻X和Y都为0的情形
}
x-=offsetX;
y-=offsetY;
p3.style.left=x+'px';
p3.style.top=y+'px';
}
p3.ondragend=function(){
console.log('源对象p3拖动结束');
}
</script>
</body>
</html>
效果如下:
示例二:
模拟电脑中 ”垃圾桶“的效果, 总共显示三个小飞机,拖动着某个小飞机到垃圾桶上方后,小飞机从DOM树上删除
提示:删除需要从DOM子节点中删除元素,需要阻止ondragover的默认行为!!利用源对象和目标对象的数据传递记录小飞机的ID值!!!
重要信息:
ondragover有一个默认行为!!!那就是当ondragover触发时,ondrop会失效!!!!这个可能是浏览器的版本问题,需要以后浏览器不断更新可能才会解决!!
如何阻止?
ondragover= function(e){ //源对象在悬停在目标对象上时 e.preventDefault(); //阻止默认行为,使得drop可以触发 .....
}ondrop= function(e){ //源对象松手释放在了目标对象中
.....
}
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
body {
text-align: center;
}
#trash {
opacity: .2;
margin: 15px;
}
</style>
</head>
<body>
<h3>拖动飞机到垃圾桶后从DOM树中删除子元素</h3>
<img id="trash" src="img/trash_full.png">
<hr/>
<img id="p3" src="img/p3.png">
<img id="p4" src="img/p4.png">
<img id="p5" src="img/p5.png">
<script>
//为源对象添加事件监听 —— 记录拖动了哪一个源对象
var srcList = document.querySelectorAll('.src');//找到全部img元素
for(var i=0; i<srcList.length; i++){ //遍历img元素
var p = srcList[i];
p.ondragstart = function(e){ //开始拖动源对象
e.dataTransfer.setData('PlaneID',this.id);//保存数据--该img元素的id
}
p.ondrag = function(){}
p.ondragend = function(){}
}
//为目标对象添加事件监听 —— 删除拖动的源对象
trash.ondragenter = function(){ //源对象进入目标对象
console.log('drag enter');
trash.style.opacity = "1"; //将透明度变成1
}
trash.ondragleave= function(){ //源对象离开目标对象后
console.log('drag leave');
trash.style.opacity = ".2"; //将透明度变为0.2
}
trash.ondragover= function(e){ //源对象在悬停在目标对象上时
e.preventDefault(); //阻止默认行为,使得drop可以触发
}
trash.ondrop= function(e){ //源对象松手释放在了目标对象中
console.log('drop');
trash.style.opacity = ".2"; //将透明度变为0.2
//删除被拖动的源对象
var id = e.dataTransfer.getData('PlaneID');//得到数据--id值
var p = document.getElementById(id); //根据id值找到相关的元素
p.parentNode.removeChild(p); //从父元素中删除子节点
}
</script>
</body>
</html>
效果如下:
拖拽小飞机到垃圾桶删除后:
如图,原本三架小飞机,现在变成了两架!!!
六、拖拽API的补充知识点!!(重要,面试中也许会问到噢!!)
面试题:
如何在网页中显示客户端(电脑)的一张图片?
如何拖动客户端的网页显示在服务器端下载的页面中?
这两个问题是什么意思呢?
我们平时在电脑中拖拽一张图片到浏览器中实现的下载操作!!!按照H5之前的标准,要实现直接拖拽一张图片到浏览器中显示是无法完成!!但是自从H5新特性出来之后增加了拖拽API的特性,完美的实现了这一功能!!!
应用场合:
在某网站上,上传图片当做是头像
上传相片...
HTML5新增的文件操作对象:
File: 代表一个文件对象
FileList: 代表一个文件列表对象,类数组
FileReader:用于从文件中读取数据
FileWriter:用于向文件中写出数据
相关函数:
div.ondrop = function(e){
var f = e.dataTransfer.files[0]; //找到拖放的文件
var fr = new FileReader(); //创建文件读取器
fr.readAsURLData(f); //读取文件内容
fr.onload = function(){ //读取完成
img.src = fr.result; //使用读取到的数据
}
}