拖放:Drag & Drop,D&D,最早来自于桌面操作系统的效果,可以拖动着某文件图标,在另一个地方释放
H5提供了对D&D的支持 —— 七个事件句柄:
拖动的源对象(被拖动的对象)可以触发的事件:
dragstart:拖动开始事件
drag:拖动中
dragend:拖动结束事件
整个拖动过程的组成: dragstart * 1 + drag * n + dragend*1
拖放的目标对象(固定不动的对象)可以触发的事件:
dragenter:拖动着源对象进入(主要看光标位置)
dragover:拖动着源对象在目标对象上方悬停
dragleave:拖动着离开
drop:源对象在目标对象上方被释放
提示:dropover事件的默认行为是“必须触发dragleave”;只有阻止了此默认行为drop才可能触发
如何在拖动的源对象和目标对象间传递数据?
方法1:使用全局变量
优缺点:简单,但会污染全局对象
方法2:使用H5拖放API的数据运输对象——dataTransfer
H5的拖放API为每个拖放事件都提供了一个e.dataTranfer(拖拉机)属性,专用于在一次拖放过程中的7个事件间传递数据
源对象的事件——保存数据
e.dataTransfer.setData( key, value );
目标对象的事件——获取数据
var value = e.dataTransfer.getData( key );
如何拖动客户端的一张图片显示在服务器端下载的网页中?
H5中指定的用于文件IO的新对象:
File:表示一个文件/目录对象
FileList:类数组对象
FileReader:文件读取器,用于读取文件内容
FileWriter:文件写出器,用于向文件中写出内容
div.ondrop = function(e){
var f0 = e.dataTransfer.files[0]; //获取被拖动的文件
var fr = new FileReader(); //创建文件读取器
fr.readAsDataURL(f0); //从文件中读取内容
fr.onload = function(){ //文件内容读取完成
fr.result; //读取到的文件数据
}
}
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>拖放</title>
<style>
body{position: relative;margin:0;}
body:before{content:"";display: table;}
#drop{height:100px;width:200px;border:2px solid red;margin:0 auto 100px;}
#drop>img{position: relative;z-index: -1;}
#img{height:100px;width:620px;border:2px solid red;margin:0 auto;}
#img>img{position: relative;}
#aa{
position: relative;
border: 1px solid blue;
width: 800px;
height: 100px;
margin-left:50px;
}
#a1{position: absolute;left:0;}
#box{width:800px;height: 600px;border: 1px solid #000;overflow:auto;}
</style>
</head>
<body>
<h2>拖拽移动目标</h2>
<div id="aa"><img src="img/p3.png" id="a1"/></div>
<script>
a1.ondragstart=function(e){
a1.offsetX= e.offsetX;
}
a1.ondrag=function(e){
var left=e.pageX-a1.offsetX-parseInt(aa.offsetLeft);
console.log(left);
if(left<0)return;
a1.style.left=left+"px";
}
a1.ondragend=function(){
alert(a1.style.left);
}
</script>
<h2>拖拽释放到源目标</h2>
<div id="drop"><img src="img/p0.png"/></div>
<div id="img">
<img src="img/p3.png" id="p3"/>
<img src="img/p4.png" id="p4"/>
<img src="img/p5.png" id="p5"/>
</div>
<script>
var imgs=document.querySelectorAll("#img>img");
for(var i=0;i<imgs.length;i++){
imgs[i].ondragstart=function(e){
e.dataTransfer.setData("Id",this.id);
}
}
drop.ondragenter=function(){//鼠标第一次进入目标元素 触发
drop.style.borderColor="blue";
//console.log("ondragenter");
}
drop.ondragover=function(e){//源目标拖动到目标元素 触发
e.preventDefault();
//console.log("ondragover");
}
drop.ondragleave=function(){//源目标离开目标元素 触发
//console.log("ondragleave");
drop.style.borderColor="red";
}
drop.ondrop=function(e){//源目标投放 触发
//console.log("ondrop");
drop.style.borderColor="red";
var id= e.dataTransfer.getData("Id");
var obj=document.getElementById(id);
//console.log(obj);
//选择英雄
drop.innerHTML="";
//appendChild属于剪切复制,不能直接添加,要线复制节点
drop.appendChild(obj.cloneNode(true));
/*//拖拽删除
obj.remove();
*/
}
</script>
<h2>外界图片拖拽</h2>
<div id="box"></div>
<script>
//防止浏览器直接打开客户端图片
//本质:是拖动客户端的图片,在document对象上释放
document.ondragover=function(e){e.preventDefault();}
document.ondrop=function(e){e.preventDefault();}
//当拖拽客户端的图片在div上方时,把该图片放入div中
box.ondragover=function(e){e.preventDefault();}
box.ondrop=function(e){
//浏览器会把拖动的图片的内容放到e.dataTransfer中
//目标对象可以从拖拉机(e.dataTransfer)中读取这些数据
var f0= e.dataTransfer.files[0];//被拖动的第一张图片
var fr=new FileReader();//文件读取器
fr.readAsDataURL(f0);//读取文件的内容,组成一种data路径
fr.onload=function(){
var img=new Image;
img.src=fr.result;//result:读取的结果(data路径)
box.appendChild(img);
}
}
</script>
</body>
</html>