突袭HTML5之Javascript API扩展4—拖拽(Drag/Drop)概述


Posted in HTML / CSS onJanuary 31, 2013

拖拽(Drag/Drop)是个非常普遍的功能。你可以抓住一个对象,并且拖动到你想放置的区域。很多javascript都类似实现了相关的功能,例如,jQueryUI的draganddrop组件。在HTML5中,拖拽(draganddrop)成为了标准操作,任何元素都支持。正因为这个功能太普遍了,所有的主流浏览器都支持这个操作。
启用拖拽-draggable属性
非常简单,只需要将一个元素的拖动属性修改为draggable,这个元素就支持拖动了,如下所示:

复制代码
代码如下:

<imgdraggable="true"/>

拖动中数据的传递
拖动的过程中,我们往往需要传递相应的逻辑数据来完成转换的过程,这里主要是使用dataTransfer对象进行数据传递,下面先看看它的成员:
方法成员:
复制代码
代码如下:

setData(format,data):把被拖动的数据赋值给dataTransfer对象。

format:一个String型参数,指定被拖动数据的类型。该参数取值可以是“Text”(文本类型)和“URL”(URL类型)。该参数是大小写无关的,所以传入"text"与"Text"是一样的。
data:一个变体类型参数,指定被拖动的数据。该数据可以是文本,图片路径,URL等等。
该函数有Boolean类型的返回值,true表示数据成功加到dataTransfer中,false代表不成功。如果需要,可以通过这个参数来决定是否应该继续执行某些逻辑。
复制代码
代码如下:

getData(format):获取dataTransfer中存放的拖动数据。

format意义与setData中的一样,取值可以是"Text"(文本类型)和"URL"(URL类型)。
复制代码
代码如下:

clearData(format):移除指定类型的数据。

这里的format除了上面可以指定的"Text"(文本类型)和"URL"(URL类型)外,还可以取下列值:file-文件,html-html元素,image-图片。
这个方法可以用于去选择性的处理拖动的数据类型。
属性成员
复制代码
代码如下:

effectAllowed:设置或获取数据源元素中的数据可以执行的操作。

属性类型为字符串,取值范围如下:
"copy"-复制数据.
"link"-链接数据.
"move"-移动数据
"copyLink"-复制或链接数据,由目标对象来确定。
"copyMove"-复制或移动数据,由目标对象来确定。
"linkMove"-链接或移动数据,由目标对象来确定。
"all"-所有的操作都是支持的。
"none"-禁止拖动。
"uninitialized"-默认值,采用默认的行为。
注意设置effectAllowed为none以后,拖动是禁止的,但是鼠标形状还是显示没有可拖动的对象的形状,如果想不显示这个鼠标形状,则需要将window的event事件的属性returnValue设置为false。
复制代码
代码如下:

dropEffect:设置或获取拖动的目标上允许的操作以及相关的鼠标形状。

属性类型为字符串,取值范围如下
"copy"-鼠标显示为复制时的形状;
"link"-鼠标显示为连接的形状;
"move"-鼠标显示为移动的形状。
"none"(默认值)-鼠标显示为没有拖动的形状。
effectAllowed指定了数据源支持的操作,所以通常在ondragstart事件中指定。dropEffect指定了拖动放置的目标支持的操作,所以与effectAllowed配合,通常在拖动的目标上的ondragenter,ondragover和ondrop等事件中使用。
复制代码
代码如下:

files:返回拖动的文件的列表FileList。
types:ondragstart中发送的数据(被拖动的数据)类型的列表。

dataTransfer对象的存在,使得在拖动的数据源和目标元素之间传递逻辑数据变成了可能。通常我们使用setData方法在数据源元素的ondragstart事件中提供数据,然后再目标元素中,使用getData方法获取数据。
拖动中触发的事件
下面是一次拖拽会发生的事件,基本上事件的触发顺序也就是下面的顺序:
复制代码
代码如下:

dragstart:要被拖拽的元素开始拖拽时触发,这个事件对象是被拖拽元素。
drag:拖拽元素时触发,这个事件对象是被拖拽元素。
dragenter:拖拽元素进入目标元素时触发,这个事件对象是目标元素。
dragover:拖拽某元素在目标元素上移动时触发,这个事件对象是目标元素。
dragleave:拖拽某元素离开目标元素时触发,这个事件对象是目标元素。
drop:将被拖拽元素放在目标元素内时触发,这个事件对象是目标元素。
dragend:在drop之后触发,就是拖拽完毕时触发,这个事件对象是被拖拽元素。

基本上事件的参数event都会传入相关的元素,可以很方便的进行一些修改。这里,我们并不需要处理每个事件,通常只需要挂接主要的几个事件即可。
拖动开始-ondragstart事件
从这个事件传入的参数含有的信息非常丰富,从中可以很方便的获取到被拖动的元素(event.Target);从中可以设置被拖动数据(event.dataTransfer.setData);所以你可以很方便实现拖动的背后逻辑(当然你绑定的时候也可以传递其他的参数)。
拖动过程中-ondrag,ondragover,ondragenter和ondragleave事件
ondrag事件的对象是被拖拽元素,通常这个事件处理的比较少。ondragenter事件是当拖动进入当前元素时发生,ondragleave事件是在当拖动离开当前元素时发生,ondragover事件是在拖动在当前元素中移动时发生。
这里只需要注意一点,因为默认情况下,浏览器是禁止元素drop的,所以为了让元素可以drop,需要在这个函数中返回false或者调用event.preventDefault()方法。如下面的例子所示。
拖动结束-ondrop,ondragend事件
当可拖动的数据被drop的时候,drop事件触发。drop结束后,dragend事件被触发,这个事件使用的也相对少一点。
看一个简单的例子:
复制代码
代码如下:

<!DOCTYPEHTML>
<html>
<head>
<scripttype="text/javascript">
functionallowDrop(ev){
ev.preventDefault();
}
functiondrag(ev){
ev.dataTransfer.setData("Text",ev.target.id);
}
functiondrop(ev){
vardata=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
ev.preventDefault();
}
</script>
</head>
<body>
<divid="div1"ondrop="drop(event)"ondragover="allowDrop(event)"></div>
<imgid="drag1"src="img_logo.gif"draggable="true"ondragstart="drag(event)"width="336"height="69"/>
</body>
</html>

文件拖拽
上面的例子已经使用了dataTransfer的各种方法和属性,下面再看网上的另外一个有趣的应用:拖拽一个图片到网页上,然后在网页上显示。这个应用用到了dataTransfer的files属性。
复制代码
代码如下:

<!DOCTYPEHTML>
<html>
<head>
<metacharset="utf-8">
<title>HTML5拖放文件</title>
<style>
#section{font-family:"Georgia","微软雅黑","华文中宋";}
.container{display:inline-block;min-height:200px;min-width:360px;color:#f30;padding:30px;border:3pxsolid#ddd;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;}
.preview{max-width:360px;}
#files-list{position:absolute;top:0;left:500px;}
#list{width:460px;}
#list.preview{max-width:250px;}
#listp{color:#888;font-size:12px;}
#list.green{color:#09c;}
</style>
</head>
<body>
<divid="section">
<p>把你的图片拖到下面的容器内:</p>
<divid="container"class="container">
</div>
<divid="files-list">
<p>已经拖进过来的文件:</p>
<ulid="list"></ul>
</div>
</div>
<script>
if(window.FileReader){
varlist=document.getElementById('list'),
cnt=document.getElementById('container');
//判断是否图片
functionisImage(type){
switch(type){
case'image/jpeg':
case'image/png':
case'image/gif':
case'image/bmp':
case'image/jpg':
returntrue;
default:
returnfalse;
}
}
//处理拖放文件列表
functionhandleFileSelect(evt){
evt.stopPropagation();
evt.preventDefault();
varfiles=evt.dataTransfer.files;
for(vari=0,f;f=files[i];i++){
vart=f.type?f.type:'n/a',
reader=newFileReader(),
looks=function(f,img){
list.innerHTML+='<li><strong>'+f.name+'</strong>('+t+
')-'+f.size+'bytes<p>'+img+'</p></li>';
cnt.innerHTML=img;
},
isImg=isImage(t),
img;
//处理得到的图片
if(isImg){
reader.onload=(function(theFile){
returnfunction(e){
img='<imgclass="preview"src="'+e.target.result+'"title="'+theFile.name+'"/>';
looks(theFile,img);
};
})(f)
reader.readAsDataURL(f);
}else{
img='"o((>ω<))o",你传进来的不是图片!!';
looks(f,img);
}
}
}
//处理插入拖出效果
functionhandleDragEnter(evt){this.setAttribute('style','border-style:dashed;');}
functionhandleDragLeave(evt){this.setAttribute('style','');}
//处理文件拖入事件,防止浏览器默认事件带来的重定向
functionhandleDragOver(evt){
evt.stopPropagation();
evt.preventDefault();
}
cnt.addEventListener('dragenter',handleDragEnter,false);
cnt.addEventListener('dragover',handleDragOver,false);
cnt.addEventListener('drop',handleFileSelect,false);
cnt.addEventListener('dragleave',handleDragLeave,false);
}else{
document.getElementById('section').innerHTML='你的浏览器不支持啊,同学';
}
</script>
</body>
</html>

这个例子中使用了html5中的文件读取API:FileReader对象;该对象提供了下列异步方法用于读取文件:
1.FileReader.readAsBinaryString(fileBlob)
以二进制的方式读取文件,result属性会包含一个文件的二进制的格式
2.FileReader.readAsText(fileBlob,opt_encoding)
以文本的方式读取文件,result属性将会包含一个文件的文本格式,默认解码参数是“utf-8”。
3.FileReader.readAsDataURL(file)
以URL形式读取文件result将会包含一个文件的DataURL格式(图片通常用这种方式)。
当使用上面的方法读取文件后,会触发下列事件:
复制代码
代码如下:

onloadstart,onprogress,onabort,onerror,onload,onloadend

这些事件都很简单,需要的时候挂接就可以了。看下面的代码示例:
复制代码
代码如下:

functionstartRead(){
//obtaininputelementthroughDOM
varfile=document.getElementById('file').files[0];
if(file){
getAsText(file);
}
}
functiongetAsText(readFile){
varreader=newFileReader();
//ReadfileintomemoryasUTF-16
reader.readAsText(readFile,"UTF-16");
//Handleprogress,success,anderrors
reader.onprogress=updateProgress;
reader.onload=loaded;
reader.onerror=errorHandler;
}
functionupdateProgress(evt){
if(evt.lengthComputable){
//evt.loadedandevt.totalareProgressEventproperties
varloaded=(evt.loaded/evt.total);
if(loaded<1){
//Increasetheprogbarlength
//style.width=(loaded*200)+"px";
}
}
}
functionloaded(evt){
//Obtainthereadfiledata
varfileString=evt.target.result;
//HandleUTF-16filedump
if(utils.regexp.isChinese(fileString)){
//ChineseCharacters+Namevalidation
}
else{
//runothercharsettest
}
//xhr.send(fileString)
}
functionerrorHandler(evt){
if(evt.target.error.name=="NotReadableErr"){
//Thefilecouldnotberead
}
}

这里也简单说一下:普通的文件下载使用的就是window.open方法,例如:
复制代码
代码如下:

window.open('http://aaa.bbbb.com/ccc.rar','_blank')

实用参考:
官方文档:http://www.w3schools.com/html5/
一个不错的教程网站:http://html5.phphubei.com/html5/features/DrapAndDrop/
MSDN帮助:http://msdn.microsoft.com/en-us/library/ms535861(v=vs.85).aspx
文件拖拽详述:http://www.html5rocks.com/zh/tutorials/file/dndfiles/
文件拖拽并上传:http://www.chinaz.com/design/2010/0909/131984.shtml
文件拖拽上传完整例子:http://www.cnblogs.com/liaofeng/archive/2011/05/18/2049928.html
文件下载的例子:http://hi.baidu.com/guo_biru/item/2d7201c012b6debd0c0a7b05
window.open攻略:http://www.cnblogs.com/liulf/archive/2010/03/01/1675511.html
window.open参数:http://www.koyoz.com/blog/?action=show&id=176 
HTML / CSS 相关文章推荐
CSS3 选择器 基本选择器介绍
Jan 21 HTML / CSS
一款超酷的js+css3实现的3D标签云特效兼容ie7/8/9
Nov 18 HTML / CSS
css3实现可滑动跳转的分页插件示例
May 08 HTML / CSS
使用Html5、CSS实现文字阴影效果
Jan 17 HTML / CSS
基于HTML5超酷摄像头(HTML5 webcam)拍照功能实现代码
Dec 13 HTML / CSS
突袭HTML5之Javascript API扩展2—地理信息服务及地理位置API学习
Jan 31 HTML / CSS
让ie浏览器成为支持html5的浏览器的解决方法(使用html5shiv)
Apr 08 HTML / CSS
深入解析HTML5使用SVG图像时的viewBox属性用法
Sep 02 HTML / CSS
HTML5学习心得总结(推荐)
Jul 08 HTML / CSS
HTML5添加禁止缩放功能
Nov 03 HTML / CSS
详解html2canvas截图不能截取圆角图片的解决方案
Jan 30 HTML / CSS
html5中嵌入视频自动播放的问题解决
May 25 HTML / CSS
突袭HTML5之Javascript API扩展3—本地存储全新体验
Jan 31 #HTML / CSS
突袭HTML5之Javascript API扩展2—地理信息服务及地理位置API学习
Jan 31 #HTML / CSS
突袭HTML5之Javascript API扩展1—Web Worker异步执行及相关概述
Jan 31 #HTML / CSS
HTML5之SVG 2D入门13—svg对决canvas及长处和适用场景分析
Jan 30 #HTML / CSS
HTML5之SVG 2D入门12—SVG DOM及DOM操作介绍
Jan 30 #HTML / CSS
HTML5之SVG 2D入门11—用户交互性(动画)介绍及应用
Jan 30 #HTML / CSS
HTML5之SVG 2D入门10—滤镜的定义及使用
Jan 30 #HTML / CSS
You might like
PHP转换文件夹下所有文件编码的实现代码
2013/06/06 PHP
PHP四种基本排序算法示例
2015/04/09 PHP
ASP.NET jQuery 实例16 通过控件CustomValidator验证RadioButtonList
2012/02/03 Javascript
非常好用的JsonToString 方法 简单实例
2013/07/18 Javascript
Jquery遍历checkbox获取选中项value值的方法
2014/02/13 Javascript
jquery下div 的resize事件示例代码
2014/03/09 Javascript
js 获取元素下面所有li的两种方法
2014/04/14 Javascript
JavaScript限定图片显示大小的方法
2015/03/11 Javascript
基于Node.js的强大爬虫 能直接发布抓取的文章哦
2016/01/10 Javascript
javascript基础知识讲解
2017/01/11 Javascript
微信小程序顶部可滚动导航效果
2017/10/31 Javascript
Vue.JS实现垂直方向展开、收缩不定高度模块的JS组件
2018/06/19 Javascript
Angular7创建项目、组件、服务以及服务的使用
2019/02/19 Javascript
vue自定义键盘信息、监听数据变化的方法示例【基于vm.$watch】
2019/03/16 Javascript
解决vue-cli@3.xx安装不成功的问题及搭建ts-vue项目
2020/02/09 Javascript
小程序跳转H5页面的方法步骤
2020/03/06 Javascript
javascript事件循环event loop的简单模型解释与应用分析
2020/03/14 Javascript
JavaScript实现放大镜效果代码示例
2020/04/29 Javascript
Centos5.x下升级python到python2.7版本教程
2015/02/14 Python
Python正则表达式教程之二:捕获篇
2017/03/02 Python
Python使用pip安装报错:is not a supported wheel on this platform的解决方法
2018/01/23 Python
Python实现将多个空格换为一个空格.md的方法
2018/12/20 Python
Python中一般处理中文的几种方法
2019/03/06 Python
Python dict和defaultdict使用实例解析
2020/03/12 Python
浅谈在JupyterNotebook下导入自己的模块的问题
2020/04/16 Python
python如何编写win程序
2020/06/08 Python
Python select及selectors模块概念用法详解
2020/06/22 Python
通过css3动画和opacity透明度实现呼吸灯效果
2019/08/09 HTML / CSS
美国网上眼镜供应商:LEOTONY(眼镜、RX太阳镜和太阳镜)
2017/10/31 全球购物
外语系毕业生自荐信范文
2013/12/16 职场文书
服装厂厂长岗位职责
2013/12/27 职场文书
民主评议党员自我评价材料
2014/09/18 职场文书
狮子林导游词
2015/02/03 职场文书
建议书格式
2015/02/04 职场文书
女方家长婚礼致辞
2015/07/27 职场文书
敬业奉献模范事迹材料(2016精选版)
2016/02/26 职场文书