HTML5拖放drag及⽂件拖拽上传
HTML5中提供了拖放的api,只需要监听拖放事件,就可以完成相应的功能。
1、可拖放元素
默认情况下,img 元素和 a 元素,以及⽂本都是可拖动的,⽽其他元素是不能。想要拖放某个元素,必须设置该元素的 draggable 属性为 true,当该属性为 false 时,将不允许拖放。
<img src="img/img1.png" alt="" draggable="false">
2、拖放事件
拖放事件是发⽣在两个地⽅的:⼀个是被拖放的元素上,另⼀个是拖放⽬标元素上的。
dragstart:被拖放元素上发⽣,按下⿏标键并开始移动是触发,此时光标变成”不能放”符号(圆环中有⼀条反斜线)
drag:被拖放元素上发⽣,⿏标拖动期间持续触发(类似mousemove)
dragend:被拖放元素上发⽣,拖动停⽌时触发
dragenter:拖放⽬标元素上发⽣,元素被拖到该⽬标上触发(类似mouseover)
dragover:拖放⽬标元素上发⽣,被拖放元素在放置⽬标范围内移动时持续触发
dragleave:拖放⽬标元素上发⽣,被拖放元素拖出了放置⽬标范围时触发
drop:拖放⽬标元素上发⽣,被拖放元素放置到了⽬标元素中时触发(在⽬标元素范围内释放⿏标键)
所有的元素都⽀持放置⽬标事件(dragenter,dragover,dragleave,drop),但只有⼀些元素默认允许放置,如input,⼤多数元素是不允许放置的,即不是有效的放置⽬标,不会发⽣drop事件。
为了让元素变成可放置,可以重写 dragenter 和 dragover 事件的默认⾏为,只要阻⽌他的默认⾏为就可以了。
在Firefox中,drop事件的默认⾏为是打开被放到⽬标元素上的URL。即把图⽚或链接拖放到⽬标上,页⾯会转向该图⽚或者该链接页⾯;⽽拖放⽂本到⽬标上,则导致url错误。
为了改变这个情况,可以在 drop 事件的处理程序中阻⽌其默认⾏为
在Firefox中,拖放⽂本会跳到⽤搜索引擎去搜索拖放的⽂本,阻⽌该⾏为,可以在 document.body 上添加⼀个 drop 事件处理程序,并在其中阻⽌事件传播。
3、dataTransfer 对象
dataTransfer对象是拖放事件event中的⼀个属性,⽤于从被拖动元素项放置⽬标传递字符串格式的数据。
dataTransfer的属性和⽅法:
setData(format, data):设置拖拽事件中传递的数据,format 参数为数据类型。format,有多种,在HTML5中允许各种mime类型,但也兼容“text”和“url”,这两种会被映射成”text/plain“ 和 "text/uri-list"
在拖动⽂本框⽂本时,浏览器会⾃动调⽤ setData()⽅法,并以 "text"⽅式保存;拖放链接和图像时,会以"url" ⽅式保存。
可以⼿动地在 dragstart 事件处理程序中调⽤ setData() 保存⾃定义的传输数据
getData(format):获取数据,只能drop 事件中获取数据。
addElement(element):为拖动操作添加⼀个元素作为源元素,这个元素只影响数据。⾮标准⽅法Firefox⽀持,Chrome不⽀持
clearData(format):清除以特定格式保存的数据,若没有给定格式则清除所有数据,但除了⽂件files外,⽂件使⽤该⽅法清除;
setDragImage(element,x,y):为拖动操作指定⼀个图标,element 可以是任何⼀种图像元素,可以是 <img>、 <canvas>等。x,y 是图标在光标下的坐标
files:返回被拖拽的 FileList(⽂件列表),相当于它是⽤户拖拽进浏览器的⽂件列表,是个 FileList 对象,有 length 属性,可以通过下标访问。
types:当前保存数据的类型,是⼀个字符串数组的集合,如果有⽂件则有⼀个是files,只读。
dropEffect:获取或设置被拖动的元素在放置⽬标上能够执⾏那些放置⾏为。每个只是改变拖动元素到放置⽬标上的光标类型,但具体数据如何操作可有⽤户⾃定义。在 dragenter 事件处理程序中设置
"none":不能把元素放在这⾥,默认值(⽂本框除外)
"move":被拖拽元素将被移动到⽬标元素内
"link":被拖拽元素将以超链接的形式打开资源
"copy":被拖拽元素将被复制到⽬标元素内
effectAllowed:获取或设置允许拖动元素进⾏哪⼀种 dropEffect ⾏为。在dragstart 事件处理程序中设置。
"uninitialized":没有设置⾏为,相当于所有
"none":被拖动的元素不能有任何⾏为
"copy":只允许 copy 的dropEffect
"link":只允许link 的dropEffect
"move":只允许 move 的dropEffect
"copyLink":允许 copy 和 link 的dropEffect
"copyMove":允许 copy 和 move 的dropEffect
"linkMove":允许 link 和 move 的dropEffect
"all":允许所有的dropEffect
4、⽰例
<div id="div1">hello drag</div>
<div id="div2">
<input type="text" id="input1">
<input type="text" id="input2">
<img  id="img1" src="img/date.png" alt="" draggable="false">
<a href="www.baidu">baidu</a>
<input type="file"  id="files">
</div>
<div id="div3" ></div>
<div id="div4" draggable="true">可拖动</div>
<div id="div5" draggable="false">不可拖动</div>
let div1 = document.querySelector("#div1");
let div3 = document.querySelector("#div3");
let div4 = document.querySelector("#div4");
let div5 = document.querySelector("#div5");
let input1 = document.querySelector("#input1");
let input2 = document.querySelector("#input2");
let img1 = document.querySelector("#img1");
//拖拽div1中的⽂本
div1.addEventListener("dragstart",function(e){
//  console.log("dragstart");
console.pe);
e.dataTransfer.setData("text","hello set data");
e.dataTransfer.setData("url","www.baidu");
// e.dataTransfer.dropEffect = "move";
},false);
div1.addEventListener("drag",function(e){
//  console.log("drag");
console.pe);
},false);
div1.addEventListener("dragend",function(e){
/
/  console.log("dragend");
console.pe);
},false);
input2.addEventListener("dragstart",function(e){
//  console.log("dragstart");
console.pe);
},false);
// 将⽂本拖放到 input 框中
input1.addEventListener("dragenter",(e)=>{
//  console.log("dragenter");
console.pe);
},false);
input1.addEventListener("dragover",(e)=>{
//  console.log("dragover");
console.pe);
},false);
input1.addEventListener("dragleave",(e)=>{
//  console.log("dragleave");
console.pe);
},false);
input1.addEventListener("drop",(e)=>{
//  console.log("drop");
console.pe);
console.log(Data("text"));
console.log(pes);
//  e.preventDefault();
},false);
//将div 设置为允许放置drop
div3.addEventListener("dragover",(e)=>{
e.preventDefault();
console.log("dragOver: dropEffect = " + e.dataTransfer.dropEffect + " ; effectAllowed = " + e.dataTransfer.effectAllowed) //e.dataTransfer.dropEffect = "move"
},false);
div3.addEventListener("dragenter",e=>{
e.preventDefault();
e.dataTransfer.dropEffect = "copy";
},false);
div3.addEventListener("drop",e=>{
console.log(e);
console.log(Data("url"));
console.log(Data("text"));
console.log(pes);
e.preventDefault(); //兼容firefox,阻⽌Firefox打开url
if(Data("text")){
e.target.ElementById(Data("text")));
}
},false);
div4.addEventListener("dragstart",e=>{
e.dataTransfer.setData("text",e.target.id);
e.dataTransfer.setDragImage(img1,10,10); // 设置拖动背景图标
console.log("dragOver: dropEffect = " + e.dataTransfer.dropEffect + " ; effectAllowed = " + e.dataTransfer.effectAllowed);
e.dataTransfer.effectAllowed = "copy";  // 在 dragstart 事件中,设置dataTransfer.effectAllowed
},false);
//阻⽌ firefox搜索拖放的⽂本
drop = function (event) {
// event.preventDefault();
event.stopPropagation();
html5开发示例};
}
⽂件拖拽上传
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style media="screen">
* {margin:0; padding:0; list-style: none}
.
box {width:400px; height:200px; background:#CCC; border:1px solid black; line-height:200px; position:absolute; left:50%; top:50%; margin-left:-200px; margin-top:-100px; text-align:center; display:none;}        .img_list {overflow:hidden;}
.img_list li {float:left; width:200px; height:200px; border:3px solid #666; margin:10px; position:relative;}
.img_list li img {width:100%; height:100%;}
.img_list li .del_btn {position:absolute; right:0; top:0;}
</style>
<script>
let oUl=document.querySelector('.img_list');
let oBox=document.querySelector('.box');
let timer;
document.addEventListener('dragover', (ev)=>{
clearTimeout(timer);
oBox.style.display='block';
timer=setTimeout(function (){
oBox.style.display='none';
}, 300);
ev.preventDefault();
}, false);
oBox.addEventListener('dragenter', ()=>{
oBox.innerHTML='请松⼿';
}, false);
oBox.addEventListener('dragleave', ()=>{
oBox.innerHTML='请把⽂件拖到这⼉';
}, false);
oBox.addEventListener('drop', (ev)=>{
Array.from(ev.dataTransfer.files).forEach(file=>{
if(!pe.startsWith('image/')){
return;
}
let reader=new FileReader();
let ateElement('li');
oLi.file=file;
oLi.innerHTML='<img src="a.png" alt=""><a href="javascript:;" class="del_btn">删除</a>';
let oImg=oLi.children[0];
oImg.sult;
let oBtnDel=oLi.children[1];
};
oUl.appendChild(oLi);
};
});
ev.preventDefault();
}, false);
//真的上传
let oBtnUpload=document.querySelector('#btn_upload');
let data=new FormData();
Array.from(oUl.children).forEach(li=>{
data.append('f1', li.file);
});
//
let oAjax=new XMLHttpRequest();
//POST
oAjax.open('POST', `localhost:8080/api`, true);
oAjax.send(data);
adyState==4){
if(oAjax.status>=200 && oAjax.status<300 || oAjax.status==304){                            alert('成功');
}else{
alert('失败');
}
}
};
};
};
</script>
</head>
<body>
<ul class="img_list">
<!--<li>
<img src="a.png" alt="">
<a href="javascript:;" class="del_btn">删除</a>
</li>
<li>
<img src="b.png" alt="">
<a href="javascript:;" class="del_btn">删除</a>
</li>-->
</ul>
<input type="button" name="" value="上传" id="btn_upload">
<div class="box">
请把⽂件拖到这⼉
</div>
</body>
</html>