转自:http://www.cnblogs.com/fsjohnhuang/p/3961066.html

一、前言                                   

在HTML4的时代,各前端工程师为了实现拖拽功能可说是煞费苦心,初听HTML5的DnD API觉得那些痛苦的日子将一去不复返,但事实又是怎样的呢?下面我们一起来看看DnD API的真面目吧!

二、由于篇幅较长,特设目录一陀                      

三、HTML4下实现简单拖拽

四、HTML5下实现简单拖拽

五、如何启用DnD效果

六、draggable属性详解

七、DnD的生命周期

八、DnD中最重要的数据传递对象──DataTransfer对象

九、[object DataTransferItemList]类型

十、[object DataTransferItem]类型

十一、浏览器支持

十二、特征检测是否支持HTML5的DnD API

十三、总结

十四、参考

十五、勘误

十六、书评

三、HTML4下实现简单拖拽                          

功能:实现在div#title上按下鼠标左键并移动鼠标时,拖拽整个div#dialog,但释放鼠标时停止拖拽。

html代码片断

<div id="dialog"> <div id="title">Hi there!</div><div id="content">Welcome here every one. We would learn the HTML5 feature DnD API now!<div>
</div>

js代码片断

DnD && DnD(document.getElementById('title'), document.getElementById('dialog'));

DnD.js工具库

 View Code

contains.js工具库

 View Code

具体代码地址:https://github.com/fsjohnhuang/DnD-polyfill/blob/master/sample/sample3/

四、HTML5实现简单拖拽                          

功能:实现在div#title上按下鼠标左键并移动鼠标时,拖拽整个div#dialog,但释放鼠标时停止拖拽。下面的例子仅能在FF下运行

html代码片段

<div id="dialog"> <div id="title" draggable="true">Hi there!</div><div id="content">Welcome here every one. We would learn the HTML5 feature DnD API now!<div>
</div>

js代码片段

DnD && DnD(document.getElementById('title'), document.getElementById('dialog'));

DnD.js工具库

 View Code

contains.js工具库与上一节的相同

具体代码地址:https://github.com/fsjohnhuang/DnD-polyfill/blob/master/sample/sample4/

五、如何启用DnD效果                            

html片段

<div id="drag" draggable="true" style="width:100px;height:50px;">
test
</div>

js片段

var drag = document.getElementById('drag');
drag.onselectstart = function(){return false;};
// FF下拖拽时,默认不会生成一个被拖拽元素的阴影并跟随鼠标移动
// 需通过e.dataTransfer.setData来启动该效果
drag.ondragstart = function(e){e.dataTransfer.setData('text', e.target.innerHTML);
};

关键点:

1. 为触发拖拽的元素添加 draggable="true" 特性,用于启动HTML5的DnD功能(即元素的 dragstart 事件可被触发);

2. 在FF下即使添加 draggable="true" 特性,但仅仅会触发 dragstart 事件,但DnD功能并没有被完全打开(拖拽元素时没有任何视觉效果),需要调用 event.dataTransfer.setData('Text','') 彻底开启DnD功能。

3. 在Safari4下则需要借助CSS规则来启动DnD功能, [draggable=true]{ -webkit-user-drag: element; }

六、draggable属性详解                              

作用:用于指定标签是否可被拖拽

属性值范围如下:

1.  true ,表示可被拖拽

2.  false ,表示不可被拖拽

3.  auto ,默认值,img和带href属性的a标签则表示可拖拽,其他标签表示不可被拖拽

4. 其他值,表示不可被拖拽

七、DnD生命周期                                  

1. 被拖拽元素的生命周期

dragstart :当被拖拽元素开始被拖拽时触发

 注意:

[a]. event.dataTransfer的大部分设置均在这里配置

[b]. 若调用event.preventDefault()则会阻止拖拽行为,导致后续的拖拽事件不被触发

[c]. 触发dragstart事件后,其他元素的mousemove,mouseover,mouseenter,mouseleave,mouseout事件均不会被触发了

 drag :当被拖拽元素被拖拽时触发

 dragend :当拖拽行为结束后触发

2. 目标元素的生命周期

dragenter :当被拖拽元素进入目标元素时触发

dragover :当被拖拽元素在目标元素上移动时触发

    注意:

[a]. 可以在这里设置dropEffect的值,事件的默认行为是将dropEffect设置为none

[b]. 该事件是被拖拽元素在目标元素上移动一段时间后才触发

[c]. 事件的默认行为是不允许被拖拽元素在其他元素上释放或放置(即无法触发 drop 事件),需要通过 event.preventDefault() 来阻止默认行为才能触发后续的 drop 事件。

drop :当被拖拽元素在目标元素上,而且释放鼠标左键时触发

 注意:

[a]. 对于外来的被拖拽元素(超链接、文件、图片源), drop 事件的默认行为是浏览器将当前页面重定向到被拖拽元素所指向的资源上

[b]. 对文档内部的被拖拽元素,IE10+和Chrome下的默认行为是不作为,而FF得默认行为是新打开一个文档用于访问被拖拽元素所指向的资源

dragleave :当被拖拽元素离开目标元素时触发。

示例代码:

<div id="drag" style="width:50px;height:50px;">Test</div>
<div id="drop" style="width:100px;height:100px;border:solid 1px red;"></div>
<script type="text/javascript">var drag = document.getElementById('drag'), drop = document.getElementById('drop');drag.ondragstart = function(evt){evt.dataTransfer.setData('Text', 'www.baidu.com');};drop.ondragover = function(evt){evt.preventDefault(); // 这样才能触发drop的drop事件};
</script>

3. 整体生命周期

dragstart -> drag -> dragenter -> dragover ->  dragleave  -> drop -> dragend

八、DnD中最重要的数据传递对象──DataTransfer对象          

DataTransfer对象用于在配置拖拽行为效果,并且在拖拽过程的各事件间传递数据信息。它存储在事件对象当中,下面我们逐步了解它吧。

1. [object DragEvent]对象

继承自 [object MouseEvent] 对象,其实就多了个 {DataTransfer} dataTransfer 属性

2. [object DataTransfer]对象详解

上文说到DataTransfer对象可用于传递数据信息,而数据信息的数据类型被限定为字符串文件类型

  2.1.  effectAllowed 和 dropEffect 属性

这个两个属性对于初次接触DnD的朋友来说,可谓最令人摸不着头脑的,网上和各书籍上对这两个属性的解释均不全面,下面我试图尽量把它们讲明白。

effectAllowed 和 dropEffect 最主要的作用是,用于配置拖拽操作过程中鼠标指针的类型以便提示用户后续可执行怎样的操作;其次的作用是,控制 drop 事件的触发与否。

     [a] effectAllowed 

作用:用于设置被拖拽元素可执行的操作。

取值范围:

   copy ,限定dropEffect的属性值为copy,否则会鼠标指针为禁止样式

       link ,限定dropEffect的属性值为link,否则会鼠标指针为禁止样式

move ,限定dropEffect的属性值为move,否则会鼠标指针为禁止样式

copyLink ,限定dropEffect的属性值为copy和link,否则会鼠标指针为禁止样式

copyMove ,限定dropEffect的属性值为copy和move,否则会鼠标指针为禁止样式

linkMove ,限定dropEffect的属性值为link和move,否则会鼠标指针为禁止样式

       all ,允许dropEffect的属性值为任意值

none ,鼠标指针一直为禁止样式,不管dropEffect的属性值是什么

uninitialized ,没有限定dropEffect属性的值,效果和 all 一样。

注意:仅能在 dragstart 事件中设置该属性,其他事件中设置均无效。

 [b].  dropEffect 

     作用:用于设置目标元素将执行的操作,若属性值属于 effectAllowed 范围内,则鼠标指针将显示对应的指针样式,否则则显示禁止的指针样式。

   取值范围:

copy :被拖拽元素将被复制到目标元素内,若属于 effectAllowed 范围内时,则鼠标指针显示复制的样式,否则则显示禁止的指针样式。

    link :被拖拽元素将以超链接的形式打开资源(具体是否打开资源请参考七、2),若属于 effectAllowed  范围内时,则鼠标指针显示超链接的样式,否则则显示禁止的指针样式。

move :被拖拽元素将被移动到目标元素内,若属于 effectAllowed   范围内时,则鼠标指针显示移动的样式,否则则显示禁止的指针样式。

none :被拖拽元素不能在目标元素上作任何操作,一直显示禁止的指针样式。除了文本框外其他元素的默认值均为none

 注意:   

  1. 仅能在 dragover 事件中设置该属性值,其他事件中设置均无效

  2. 当显示禁止的指针样式时,将无法触发目标元素的 drop 事件。

[c]. 在真实浏览器中的测试结果

浏览器 effectAllowed默认值 effectAllowed值

dropEffect默认值

默认使用鼠标指针的效果

IE10+ uninitialized uninitialized copy copy
copyLink none link
copyMove none copy
linkMove none link
all copy link
none    
move move move
link link link
copy copy copy
备注:

1. 无法通过 shift键 切换copyLink,copyMove和linkMove的样式;

2. 若effectAllowed设置为copyLink、copyMove或linkMove,且dropEffect与之对应,则鼠标样式将为dropEffect所设置的样式

Chrome37 all copyLink none copy
copyMove none move
linkMove none move
move move move
link link link
copy copy copy
all copy move
备注:

1. 无法通过 shift键 切换copyLink,copyMove和linkMove的样式;

2. 若effectAllowed设置为copyLink、copyMove或linkMove,且dropEffect与之对应,则鼠标样式将为dropEffect所设置的样式

FF31 for Windows uninitialized copyLink copy copy
copyMove move move
linkMove move move
move move move
link link link
copy copy copy
uninitialized move move
备注:

1. 可通过 shift键 切换copyLink,copyMove和linkMove的样式;

2. 若effectAllowed设置为copyLink、copyMove或linkMove,且dropEffect与之对应,则鼠标样式将为dropEffect所设置的样式

FF33 for Linux 仅能触发dragstart事件,其他事件一律无效,因此不用理会

  2.2. 其他属性

   items :数据类型为DataTransferItemList,存储DataTransfer对象中所有的数据项

 注意:1. FF33 for Linux下没有该属性

2. IE10+没有该属性

   files :数据类型为FileList(IE5~9没有该属性)

types :数据类型为DOMStringList,存储DataTransfer对象中所有数据项的数据类型

  注意:1. IE5~9下没有该属性

       2. 仅能在dragenter,dragover和drop中获取该属性

 2.3. 方法

void addElement({HTMLElement} element) :添加一起跟随鼠标移动的元素。仅在 dragstart 事件中调用,Chrome37和IE10+不支持该方法;

void setDragImage({Element} image, {long} x, {long} y) :设置拖动时跟随鼠标移动的图片,用来替代默认的元素,若image不是图片元素则会元素临时转换为图片;x用于设置图标与鼠标在水平方向上的距离,y设置图标与鼠标在垂直方向上的距离。仅在 dragstart 事件中调用。IE10+不支持该方法;

  注意:

   1. {Element} image必须在DOM树中,而且在渲染树中(即display不为none)为有效元素,否则会导致没有元素跟随鼠标移动;

   2. Chrome37下,若{Element} image为无效元素时,将不会触发dragstart事件后的其他事件。

boolean setData({DOMString} format, {DOMString} data) :将指定格式的数据赋值给dataTransfer或clipboardData,format值范围为URL、Text(或text)和各种MIME类型,其实Text会被自动映射为text/plain,URL会被自动映射为text/uri-list类型。仅在 dragstart 事件中调用。

注意:

   1. FF5-是不会将text映射为text/plain,而仅仅支持Text映射为text/plain,因此使用Text或直接使用text/plain

   2. IE10+仅支持Text和URL两种类型,不支持text/plain、text/uri-list等类型

   3.  text/plain类型则不会对数据进行额外处理,而text/uri-list类型则会将数据视为url来使用(体现在当将元素拖拽到OS桌面释放时)

   4.  Chrome和FF支持任意的非空字符串作为format

   5. 当没有填写第二个入参时,则会根据format来删除相应的数据项

   6. 当设置text/uri-list类型的数据时,数据必须带协议名,如http://fsjohnhuang.cnblogs.com;若仅写为fsjohnhuang.cnblogs.com,那么dataTransfer将自动弃除,在`dragstart`事件还能获取到,但在drop事件中将无法获

DOMString getData({DOMString} format) :从DataTransfer对象或ClipboardData对象中获取指定格式的数据

void clearData([{DOMString} format]) :从DataTransfer对象或ClipboardData对象中删除指定格式或全部kind值为string的数据。仅在 dragstart 事件中调用,在其他事件中调用会抛InvalidStateError。

 2.4. 数据存储模式

  Read/Write mode:在 dragstart 事件为该模式,可读写数据

  Read-only mode:在 drop 事件为该模式,仅能读取数据

  Protected mode:在其他事件为该模式,仅能枚举数据

九、[object DataTransferItemList]类型                  

readonly unsigined long length

getter DataTransferItem(unsigned long index) ,使用方式:items[1]

deleter void(unsigned long index) ,使用方式:delete items[1],在非Read/Write mode下会报InvalidStateError,而添加数据则不会有问题

void clear()

DataTransferItem add(DOMString data, DOMString type)

DataTransferItem add(File data)

十、[object DataTransferItem]类型                    

readonly attribute DOMString kind ,表示数据的大类型,值范围string和file

readonly attribute DOMString type ,表示数据的小类型,一般使用mimetype表示,但在Chrome和FF下可以是任意非空字符串

void getAsString(FunctionStringCallback cb) ,当kind为string时,则只能在Read-only mode和Read/Write mode下才可用。其中cb仅有一个类型为{DOMString}的入参

File getAsFile() ,当kind为file时,则只能在Read-only mode和Read/Write mode下才可用,没有数据时返回null

十一、浏览器支持                               

IE5~9部分标签支持;

IE10+、FF、Chrome支持。

也许大家会好惊讶IE5已经开始支持DnD API啦??其实DnD API的最初是由IE提出来的,只是后来被HTML5纳入草案而已。大家也许会问在IE5~9上运行上文的代码没有效果,是不是我写错了,下一篇《JS魔法堂:IE5~9的Drag & Drop API(http://www.cnblogs.com/fsjohnhuang/p/3980563.html)》我们将一起探讨IE5~9的DnD API。

十二、特征检测是否支持HTML5的DnD API                  

由于IE5~9的DnD API与HTML5标准的有差异,因此特征检测变得尤为必要了。下面的代码参考了Modernizr.draganddrop的实现(地址:https://github.com/Modernizr/Modernizr/blob/master/feature-detects/draganddrop.js)

var supportDnD = function(){var div = document.createElement('div');return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div);};

十三、总结                                  

回到文章最开头的两个示例,会发现使用HTML5 DnD API实现拖拽效果的代码量并不比HTML4中的少,效果也并不理想(个人水平有限优化也没做好),最让人心酸的是各浏览器在细节上还是有差异的(兼容性是前端工程师一直的痛啊)。也许大家会说那么DnD API是不是就仅仅好看而不实用呢?其实不然,只是示例把这个特性用到不适合的地方而已。

HTML5 DnD API最常见的用法就是文件拖拽上传,或把文档内某元素拖到其他元素内或OS桌面上等。这些都是HTML4时代的js很难处理,或者无法处理的。

尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/3961066.html  ^_^肥仔John

十四、参考                                  

http://www.w3school.com.cn/html5/html_5_draganddrop.asp
http://www.cnblogs.com/wpfpizicai/archive/2012/04/07/2436454.html
http://www.kankanews.com/ICkengine/archives/82862.shtml
http://jingyan.baidu.com/article/6dad5075cf6e62a123e36e11.html
http://www.zhangxinxu.com/wordpress/2011/02/html5-drag-drop-%E6%8B%96%E6%8B%BD%E4%B8%8E%E6%8B%96%E6%94%BE%E7%AE%80%E4%BB%8B/
http://my.oschina.net/caixw/blog/102845
http://www.cnblogs.com/birdshome/archive/2006/07/22/Drag_Drop.html
《HTML5实战》第11章、HTML5中元素的拖放
《HTML5用户指南》第8章、拖放
http://msdn.microsoft.com/en-us/library/ff974353(v=vs.85).aspx
《HTML5与CSS3权威指南》4.5.拖放
《论道HTML5》3.3.Drag & Drop API

十五、勘误                                  

《HTML5实战》P292 setData的format参数格式包含text/url-list,应更正为text/uri-list

十六、书评                                  

《HTML5实战》第11章、HTML5中元素的拖放,这一章感觉就一笔带过,纯属印象派。
《HTML5用户指南》第8章、拖放,除了简单介绍HTML5 DnD API外,还介绍起源和IE上DnD的特点和作者对DnD API不完美的抱怨,比《HTML5实战》更值得拜读。
《HTML5与CSS3权威指南》4.5.拖放,内容,深度与《HTML5实战》相似
《论道HTML5》3.3.Drag & Drop API,对比上述三本书,它提及到使用Modernizr作DnD特征检测,其他基本相似

转载于:https://www.cnblogs.com/mauricechans/p/5855953.html

HTML5 Drop API相关推荐

  1. 开大你的音响,感受HTML5 Audio API带来的视听盛宴

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 话说HTML5的炫酷真的是让我爱不释手,即使在这个提到IE就伤心不完的年代.但话又说回来,追求卓越W ...

  2. HTML5 新增 API

    HTML5 新增 API 1. 选择器 API 2. 历史对象 API 3. 新增 Web 存储 API 3.1 Web 存储 API 类型 3.2 本地存储 localStorage 3.2.1 l ...

  3. HTML5拖放API,回收站效果

    目录 最终展示结果: API概念: 源码: html及js部分 css部分: image资源 最终展示结果: API概念: ----来自百度百科 API之主要目的是提供应用程序与开发人员以访问一组例程 ...

  4. 基于HTML5拖放API:目前市面上的一些修图工具软件带有自动为图片添加不同款式相框的功能,用户可以选择本地图片文件然后为其添加相框效果

    这是一份很简单的作业,由于百度当时没找到,就自己写了一下,命名不是很机智只是为了写的快且好懂,使用只需要将桌面的图片拖拉进里面就直接生成一个新的带相框的图片,代码很短好理解.. <!DOCTYP ...

  5. 基于html5 File API文件操作

    文章来源:小青年原创  发布时间:2016-08-16  关键词:blob,File,FileReader,DataURI,URL  转载需标注本文原始地址: http://zhaomenghuan. ...

  6. html拖放api之图片相框,html5拖放API简介及应用

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 通常我们在上传文件时,需要使用 这样的上传文件标签.而在html5中,它提供了拖放的接口,以下的内容就是对html5拖放 ...

  7. HTML5 Audio API

    话说HTML5的炫酷真的是让我爱不释手,即使在这个提到IE就伤心不完的年代.但话又说回来,追求卓越Web创造更美世界这样高的追求什么时候又与IE沾过边儿呢?所以当你在看本文并且我们开始讨论HTML5等 ...

  8. 感受HTML5 Audio API带来的视听盛宴

    开大你的音响,感受HTML5 Audio API带来的视听盛宴 话说HTML5的炫酷真的是让我爱不释手,即使在这个提到IE就伤心不完的年代.但话又说回来,追求卓越Web创造更美世界这样高的追求什么时候 ...

  9. html5在线api,HTML5 历史记录API

    HTML5 历史记录API HTML5历史记录API的使用方法,在线实例演示HTML5历史记录API如何使用.浏览器的兼容性.语法定义及它的属性值详细资料等. HTML5历史记录API使您可以通过Ja ...

最新文章

  1. 前端性能毫秒必争方案(一)HTTP请求
  2. java算法面试题_【干货】经典算法面试题代码实现-Java版
  3. mysql新增字段位置_图解MySQL | [原理解析] MySQL 为表添加列 是怎么quot;立刻quot;完成的...
  4. java获取当前执行文件的路径
  5. 精确搜索linux日志,Linux 日志查询 - 精确详细
  6. PG数据库插件扩展搭建(一)
  7. 备考分享!第十一届CDA考试Level Ⅱ 优秀考生采访
  8. 复杂网络作业四:第三题——随机图、小世界网络和真实网络的度分布
  9. FPGA数字鉴相鉴频器的开发记录
  10. Android实现头像上传至数据库与保存 简易新闻(十七 上)
  11. WebSpider和一些杂七杂八
  12. 懂的android基础如何面试月薪过万
  13. 鸿蒙开发者招募!给后辈的一点建议,终局之战
  14. TPLINK免驱版网卡插上后无法识别到CD驱动器怎么办?
  15. 2 画图软件 界面设计
  16. Vue + nightwatch + Chrome76进行e2e测试的正确配置(二)
  17. 2015百度竞价之如何增加有效点击率?
  18. Nifi实时同步mysql_nifi实现数据库到数据库之间数据同步
  19. 串口服务器直连路由器如何配置,塔石物联网:串口服务器如何实现跨网段传输!...
  20. LONGSYS 64G M6固态硬盘SM2244G主控开卡

热门文章

  1. java多线程之线程的同步与锁定(转)
  2. C# 获取Excel版本
  3. SQL2000中因为选定的用户拥有对象,所以无法除去该用户.
  4. 什么是技术,技术是什么
  5. S5P4418 OV5640摄像头 花屏的解决方法
  6. k8s存储卷(empyDir;hostPath;nfs)
  7. css里calculate,calc() ---一个会计算的css属性
  8. Linux 中内核级加强型火墙的管理
  9. tortoise清理本地分支_TortoiseGit操作本地仓库的详细使用方法
  10. 2020年7月编程语言排行榜来喽,R编程语言创历史最高纪录