HTML5元素拖拽drag与拖放drop

<h4>一、什么是拖拽和释放?</h4>
拖拽:Drag
释放:Drop
拖拽指的是鼠标点击源对象后一直移动对象不松手,一但松手即释放了
<h4>二、什么是源对象和目标对象?</h4>

drag&drop.png

源对象:SourceObject,被拖动的对象,可以是一张图片,一个DIV, 一段文本
目标对象:TargetObject,被拖动的对象可以移动到目标对象上方,实施移出/释放操作(可以在这个区域上方悬停(未松手),可以释松手释放将源对象放置此处(已松手),也可以悬停后离开该区域)
<h5>HTML5为拖放对象添加了7个新的事件:</h5>
<h6>源对象可以触发的事件:</h6>
<pre>(1)ondragstart:源对象开始被拖动
(2)ondrag:源对象被拖动过程中(鼠标可能在移动也可能未移动)
(3)ondragend:源对象被拖动结束
</pre>
<h6>目标对象可以触发的事件:</h6><pre>
(1)ondragenter:源对象被拖动着进入目标对象上方
(2)ondragover:源对象被拖动着处于目标对象上方(悬停静止/移动)
(3)ondrop:源对象被拖动着在目标对象上方松开鼠标
(4)ondragleave:源对象被拖动着离开目标对象上方</pre>
注意:ondragover事件结束后的默认行为就是要触发ondragleave,即默认情况下,ondrop永远无法触发。可能需要阻止ondragover事件的默认行为:event.preventDefault();
如何阻止?<pre>ondragover= function(e){ //源对象在悬停在目标对象上时
e.preventDefault(); //阻止默认行为,使得drop可以触发
.....

}
ondrop= function(e){ //源对象松手释放在了目标对象中

.....

}</pre>
示例一:实现一个可以随着鼠标拖动而移动的图片
提示:图片需要绝对定位!ondrag事件中获取鼠标的坐标值!!!
<pre><!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>随着鼠标拖动而移动的小飞机</title>
<style>
body{
margin:0;
position: relative;
}
img{
position:absolute;
}
</style>
</head>
<body>

QQ截图20170328143504.png

<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>
</pre>
<h6>如何在拖动的源对象事件和目标对象事件间传递数据 </h6>
HTML5中所有拖放相关的事件对象都有一个属性:dataTransfer

(1)源对象上触发的事件对象与目标对象上触发的事件对象是不同的对象!
(2)源对象拖放事件的dataTransfer对于与目标上是不同的对象!
(3)每个dataTransfer对象都有setData()、getData()、clearData()等方法,用于在源对象和目标对象间传递数据
源对象上:保存数据——数据装上拖拉机
event.dataTransfer.setData('text/html', '数据');
目标对象上:读取数据——从拖拉机上取出数据
var data = event.dataTransfer.getData('text/html');

示例二:
模拟电脑中 ”垃圾桶“的效果, 总共显示三个小飞机,拖动着某个小飞机到垃圾桶上方后,小飞机从DOM树上删除
提示:删除需要从DOM子节点中删除元素,需要阻止ondragover的默认行为!!利用源对象和目标对象的数据传递记录小飞机的ID值!!!
<pre>
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>拖动飞机到垃圾桶后从DOM树中删除子元素</title>
<style>
body {
text-align: center;
}
#trash {
opacity: .2;
margin: 15px;
}
</style>
</head>
<body>

QQ截图20170328143030.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>  

</pre>

QQ截图20170328140517.png

实例三:
<pre>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>拖动图片进入DIV</title>
<style>

targetObj {

border: 4px solid #eee;
width: 400px;
height: 300px;
margin: 0 auto;
padding: 10px;

}
</style>
</head>
<body>

<div id="targetObj"></div>

QQ截图20170328143231.png

<script>
//拖动进入DIV,边框变深;离开则变浅
targetObj.ondragenter = function(){
this.style.borderColor = '#999';
}
targetObj.ondragover = function(event){
event.preventDefault(); //只有阻止dragover的默认行为才能触发ondrop
}
targetObj.ondrop = function(){ //鼠标松开
console.log('drop');
this.style.borderColor = '#eee';
this.appendChild(srcObj); //DIV把IMG追加为自己的孩子
/var copy = srcObj.cloneNode(); //克隆节点-核心DOM方法
copy.removeAttribute('id');
this.appendChild(copy);
/
}
targetObj.ondragleave = function(){
this.style.borderColor = '#eee';
}
</script>
</body>
</html></pre>
效果图:

QQ截图20170328141646.png

实例四:
<pre>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>

targetObj {

border: 4px solid #eee;
width: 400px;
height: 300px;
margin: 0 auto;
padding: 10px;

}
</style>
</head>
<body>

<div id="targetObj"></div>

QQ截图20170328143334.png

<script>
var imgList = document.querySelectorAll('img');
for(var i=0; i<imgList.length; i++){
//为每个图片(源对象)绑定事件监听
var img = imgList[i];
img.ondragstart = function(event){ //开始拖动
console.log('src: drag start');
console.log(event.dataTransfer);
event.dataTransfer.setData('text/html', this.getAttribute('src')); //保存数据-海南装拖拉机
}
img.ondrag = function(){ //拖动中
}
img.ondragend = function(){ //拖动结束
}
}
//目标对象可以触发的拖放事件
targetObj.ondragenter = function(){ //拖动进入
}
targetObj.ondragover = function(event){ //悬停
event.preventDefault();
}
targetObj.ondrop = function(event){ //拖动释放
console.log('target: drop');
console.log(event.dataTransfer);
var d = event.dataTransfer.getData('text/html');
console.log('东北接收到了海南的数据:'+d);
//根据属性选择器查找元素
var img = document.querySelector('[src="'+d+'"]');
this.appendChild(img);
}
targetObj.ondragleave = function(){ //拖动离开
}
</script>
</body>
</html>
</pre>
效果图:

4.png

<h6>Html5新增的文件操作对象--补充</h6>HTML5 File API : http://www.cnblogs.com/zichi/p/html5-file-api.html
File: 代表一个文件对象
FileList: 代表一个文件列表对象,类数组
FileReader:用于从文件中读取数据
FileWriter:用于向文件中写出数据
相关函数:
<pre>
div.ondrop = function(e){

var f = e.dataTransfer.files[0]; //找到拖放的文件

var fr = new FileReader(); //创建文件读取器

fr.readAsURLData(f); //读取文件内容

fr.onload = function(){ //读取完成

img.src = fr.result; //使用读取到的数据

}
}</pre>
实例:
<pre>
<span style="font-size:18px;"><!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>拖放API的扩展知识-请拖动您的照片到下方方框区域</title>
<style>
#container {
border: 1px solid #aaa;
border-radius: 3px;
padding: 10px;
margin: 10px;
min-height: 400px;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
//监听document的drop事件——取消其默认行为:在新窗口中打开图片
document.ondragover = function(e){
e.preventDefault(); //使得drop事件可以触发
}
document.ondrop = function(e){
e.preventDefault(); //阻止在新窗口中打开图片,否则仍然会执行下载操作!!!
}

//监听div#container的drop事件,设法读取到释放的图片数据,显示出来  
container.ondragover = function(e){  
  e.preventDefault();  
}  
container.ondrop = function(e){  
  console.log('客户端拖动着一张图片释放了...')  
  //当前的目标对象读取拖放源对象存储的数据  
  //console.log(e.dataTransfer); //显示有问题  
  //console.log(e.dataTransfer.files.length); //拖进来的图片的数量  
  var f0 = e.dataTransfer.files[0];  
  //console.log(f0); //文件对象 File  

  //从文件对象中读取数据  
  var fr = new FileReader();  
  //fr.readAsText(f0); //从文件中读取文本字符串  
  fr.readAsDataURL(f0); //从文件中读取URL数据  
  fr.onload = function(){  
    console.log('读取文件完成')  
    console.log(fr.result);  
    var img = new Image();  
    img.src = fr.result; //URL数据  
    container.appendChild(img);  
  }  
}  

</script>
</body>
</html></span></pre>

QQ截图20170328142717.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容

  • html5出现了很多比较好的应用,今天我们来讲讲关于元素拖动的。 前言 关于拖动,我们应该理解什么是拖动源和放置目...
    侬姝沁儿阅读 1,245评论 0 5
  • (续jQuery基础(1)) 第5章 DOM节点的复制与替换 (1)DOM拷贝clone() 克隆节点是DOM的常...
    凛0_0阅读 1,329评论 0 8
  • 拖放是一种常见的特性,即抓取对象以后拖到另一个位置 首先需要了解几个知识点 在拖动目标上触发事件(源元素): on...
    暴烈的海胆阅读 648评论 0 0
  • 转载请声明 原文链接 关注公众号获取更多资讯 这篇文章主要总结H5的一些新增的功能以及一些基础归纳,这里只是一个提...
    程序员poetry阅读 9,069评论 22 225
  • 分布式集群的架构的架构师,也有着较高的要求,而互联网上受人敬仰的架构师大多属于这类。你也可以认为这才是真正的架构师...
    NHXuan阅读 397评论 0 0