可以夸张点说,如果你不会拖拽,你不是一个合格的前端开发。

回想下,以前我们是怎么实现拖拽的,主要有以下几步:

1.目标元素绑定mousedown事件,记录下此时鼠标位置和拖拽元素的位置差,分别是 diffX ,diffY

2.在mousedown中绑定 document的mousemove 以及mouseup

3.在mousemove中计算拖拽元素的位置: x = event.clientX - diffX ,y = event.clientY - diffY

4.mouseup时中销毁绑定的 document mousemove 和mouseup事件,销毁拖拽元素

我们也知道,当一个元素拖拽的时候,鼠标顺序依次:mousedown,mousemove,mouseup,click , 如果一个元素既可以点击,又需要拖拽,悲剧就发生了。可能导致,我们拖着拖着发生了点击事件,页面跳转了。这时候,我们通常会采用延时操作,避免误操作。总之,处理起来是挺麻烦的。

现在好了,有了html5 drag,浏览器自动帮我们处理好了。

要让一个元素支持拖拽,首先我们需要在标签上标示出来:

<div draggable="true"></div>
对于Safari,还必须要在CSS中对能拖拽的元素如下设置:
*[draggable = true] {
-khtml-user-drag: element;}     

元素在拖放过程中触发的事件

先列下拖拽过程中可能触发的事件,如下:

  1. dragstart:事件主体是被拖放元素,在开始拖放被拖放元素时触发,。
  2. darg:事件主体是被拖放元素,在正在拖放被拖放元素时触发。
  3. dragenter:事件主体是目标元素,在被拖放元素进入某元素时触发。
  4. dragover:事件主体是目标元素,在被拖放在某元素内移动时触发。
  5. dragleave:事件主体是目标元素,在被拖放元素移出目标元素是触发。
  6. drop:事件主体是目标元素,在目标元素完全接受被拖放元素时触发。
  7. dragend:事件主体是被拖放元素,在整个拖放操作结束时触发。

其中事件主体是拖放元素的是,dragstart(开始拖动) 、darg(正在拖放) 、dragend(拖放结束),其他4个事件主体都是目标元素,进入、移动、离开、完全进入四个状态。

注意:为了减少事件,你可以在事件 ondragenter 的时候 绑定方法 ,而 ondragleave 的时候,删除 方法。最好不要绑定在 dragover 上,它就像 mouseover ,在拖动的过程中不断触发,对于浏览器的负担就很大了,浏览器还有可能崩溃。

$('.test').on('dragstart',function(e){
console.log('start');
}); $('.test').on('dragend',function(){
console.log('end');
})

如此,就可以让元素拖动了。需要注意的是,drag系列事件不能跟mousemove共存,只能取其一。

有了HTML5 drag API,判断拖拽元素跟其他dom元素相交变得容易起来了,只需要:

$('.drop-area').on('dragover',function(e){
console.log('dragover');
e.preventDefault();
});
$('.drop-area').on('drop',function(e){
console.log('drop');
});

需要注意的是,必须写上红色部分,如果不阻止默认事件,drop事件将不会触发。关于这点,可以去w3c查看。

dataTransfer对象

只有简单的拖放而没有数据变化是没有什么用的。为了在拖放操作时实现数据交换HTML5定义了dataTransfer对象来传递拖拽的数据。

因为它是事件对象的属性,所以只能在拖放事件的事件处理程序中访问dataTransfer对象。在事件处理程序中,可以使用这个对象的属性和方法来 完善拖放功能。

getData()和setData()

dataTransfer对象有 getData()和setData()两个主要方法,操作dataTransfer中携带的数据。不难想象,getData()可以取得由setData()保存的值。setData()方法的第一个参数,也是getDAta()方法唯一的一个参数,表示保存的数据类型。

IE只定义了“text”和“URL”两种有效的数据类型,而HTML5则对此加以扩展,允许指定各种MIME类型。考虑到向后兼容,HTML5也支持“text”和“URL”,但这两种类型会被映射为“text/plain”和“text/uri-list”。如下所示:

  1. text/html:文本文字格式
  2. text/plain:HTML代码格式
  3. text/xml:XML字符格式
  4. text/url-list:URL格式列表

实际上,dataTransfer对象可以为每种MIME类型都保存一个值。换句话说,同时在这个对象中保存了一段文本和一个URL不会有任何问题。不过,保存在dataTransfer对象中的数据只能在drop事件处理程序中读取。如果在ondrop处理程序中没有读到数据,那就是dataTransfer对象已经被销毁,数据也丢失了。

在拖动文本框中的文本时,浏览器会调用setData()方法,将拖动的文本以“text”格式保存在dataTransfer对象中。类似地,在拖放链接或图像时,会调用setData()方法并保存URL。然后,在这些元素被拖放到放置目标时,就可以通过getData()读到这些数据。当然,作为开发人员,你也可以在dragstart事件处理程序中调用setData(),手工保存自己要传输的数据,以便将来使用。

将数据保存为文本和保存为URL是有区别的。如果将数据保存为文本格式,那么数据不会得到任何特殊处理。而如果将数据保存为URL,浏览器会将其当成网页中的链接。换句话说,如果你把它放置到另一个浏览器窗口中,浏览器就会打开该URL。

Firefox在其第5个版本之前不能正确地将“URL”和“text”映射为“text/uri-list”和“text/plain”。但是却能把“Text”映射为“text/plain”。为了更好地在跨浏览器的情况下从dataTransfer对象取得数据,最好在取得URL数据时检测两个值,而在取得文本数据时使用“text”。

var dataTransfer =event.dataTransfer;//读取URLvar url = dataTransfer.getData("url")|| dataTransfer.getData("text/uri-list");//读取文本var text = dataTransfer.getData("Text");

注意:一定要把短数据类型放在前面,因为IE 10及之前的版本仍然不支持扩展的MIME类型名,而它们在遇到无法识别的数据类型时,会抛出错误。

使用 setDragImage 方法设置拖放图标

在HTML5中,一个元素在被拖放时,还可以自定义拖放元素的鼠标图标。调用格式如下:

setDragImage(Element img,long x,long y);

setDragImage调用格式

img表示拖放时的 <> 元素的图标,x 表示图标距离鼠标指针的x轴方向的偏移值,y表示图标距离鼠标指针y轴方向的偏移值。

使用 effectAllowed 和 dropEffect 属性设置拖放效果

dataTransfer对象的两个属性:dropEffect和effectAllowed,能通过它来确定被拖动的元素以及作为放置目标的元素能够接受什么操作。结合effectAllowed 和 dropEffect 这两个属性,可以自定义拖放过程中的效果。两个属性虽然都是为了实现同一功能,但绑定的元素不同:effectAllowed属性作用于被拖放元素;而 dropEffect 属性作用于目标元素,

其中,通过dropEffect属性可以知道被拖动的元素能够执行哪种放置行为。这个属性有下列4个可能的值。

  • none:不能把拖动的元素放在这里。这是除文本框之外所有元素的默认值。
  • move:应该把拖动的元素移动到放置目标
  • copy:应该把拖动的元素复制到放置目标
  • link:表示放置目标会打开拖动的元素(但拖动的元素必须是一个链接,有URL)。

在把元素拖动到放置目标上时,以上每一个值都会导致光标显示为不同的符号。然而,要怎样实现光标所指示的动作完全取决于你。换句话说,如果你不介入,没有什么会自动地移动、复制,也不会打开链接。总之,浏览器只能帮你改变光标的样式,而其它的都要靠你自己来实现。要使用dropEfect属性,必须在ondraggenter事件处理程序中针对放置目标来设置它。

dropEffect属性只有搭配effectAllowed属性才有用。effectAllowed属性表示允许拖放元素的哪种dropEffect,effectAllowed属性可能的值如下。

  1. uninitialized:没有该被拖动元素放置行为。
  2. none:被拖动的元素不能有任何行为。
  3. copy:只允许值为“copy”的dropEffect。
  4. link:只允许值为“link”的dropEffect。
  5. move:只允许值为“move”的dropEffect。
  6. copyLink:允许值为“copy”和“link”的dropEffect。
  7. copyMove:允许值为“copy”和”link”的dropEffect。
  8. linkMove:允许职位“link”和”move”的dropEffect。
  9. all:允许任意dropEffect。

必须在ondraggstart事件处理程序中设置effectAllowed属性。

假设你想允许用户把文本框中的文本拖放到一个<div>元素中。首先,必须将dropEffect和effectAllowed设置为”move”。但是,由于<div>元素的放置事件的默认行为是什么也不做,所以文本不可能自动移动。重写这个默认行为,就能从文本框中移走文本。然后你就可以自己编写代码将文本插入到<div>中,这样整个拖放操作就完成了。如果将dropEffect和effectAllowed的值设置为”copy”,那就不会自动移走文本框中的文本。

其它属性

  • addElement:事件主体是被拖放元素,为拖动操作添加一个元素。添加这个元素只影响数据(即增加作为拖动源而影响回调的对象),不会影响拖动操作时页面元素的外观。在写作文本时,只有Firefox 3.5+实现了这个方法。
  • clearData:事件主体是目标元素,清除以特定格式保存的数据。实现这个方法的浏览器有IE、Firefox 3.5、Chrome和Safari 4+。
  • types:当前保存的数据类型。这是一个类似数组的集合,以“text”这样的字符串形式保存着数据类型。实现这个属性的浏览器有IE10+、Firefox 3.5+和Chrome。

支持draggable属性的浏览器有IE10+、Firefox 4+、Safari 5+和Chrome。Opera 11.5以及之前的版本都不支持HTML5的拖放功能。另外,为了让Firefox 支持可拖动属性,还必须添加一个ondragstart事件处理程序,并在dataTransfer对象中保存了一些信息。

html5 drag api详解的更多相关文章

  1. 转: html5 history api详解~很好的文章

    从Ajax翻页的问题说起 请想象你正在看一个视频下面的评论,在翻到十几页的时候,你发现一个写得稍长,但非常有趣的评论.正当你想要停下滚轮细看的时候,手残按到了F5.然后,页面刷新了,评论又回到了第一页 ...

  2. Html5 Device API详解

    三.四月曾学习过html5相关知识,并就html5 device api做过一次讲解 课程时长一个小时,预期达到level 200目标,即知道html5 device api是什么,且知道怎么实现 面 ...

  3. 转:HTML5 History API 详解

    从Ajax翻页的问题说起 请想象你正在看一个视频下面的评论,在翻到十几页的时候,你发现一个写得稍长,但非常有趣的评论.正当你想要停下滚轮细看的时候,手残按到了F5.然后,页面刷新了,评论又回到了第一页 ...

  4. DOM API详解

    来源于:http://zxc0328.github.io/2016/01/23/learning-dom-part1/ https://zxc0328.github.io/2016/01/26/lea ...

  5. Swift_ScrollView _ API详解

    Swift_ScrollView _ API详解 GitHub class ViewController: UIViewController,UIScrollViewDelegate { var sc ...

  6. Java 8 Stream API详解--转

    原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java8引入了 ...

  7. jqGrid APi 详解

    jqGrid APi 详解 jqGrid皮肤 从3.5版本开始,jqGrid完全支持jquery UI的theme.我们可以从http://jqueryui.com/themeroller/下载我们所 ...

  8. hibernate学习(2)——api详解对象

    1   Configuration 配置对象 /详解Configuration对象 public class Configuration_test { @Test //Configuration 用户 ...

  9. 网络编程socket基本API详解(转)

    网络编程socket基本API详解   socket socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket ...

随机推荐

  1. 常见S1信令交互流程

    0. S1 Setup

  2. jLink V8调试exynos 4412 u-boot的几点补充

    /** ****************************************************************************** * @author    Maox ...

  3. POJ C++程序设计 编程题#3 编程作业—运算符重载

    编程题 #3 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 写一个二维数组 ...

  4. c#中操作word文档-一、模板方式写入

    转载自:http://blog.csdn.net/fujie724/article/details/5443322 适合模板写入 今天正好有人问我,怎么生成一个报表式的Word文档. 就是文字的样式和 ...

  5. 封装document.ready方法

    function $(fn){ if(document.addEventListener){ //W3C document.addEventListener('DOMContentLoaded',fu ...

  6. 主键、外键、超键、候选键的区别【Written By KillerLegend】

    先说一下属性的定义: 表的每一行对应一个元组,表的每一列对应一个域.由于域可以相同,为了加以区分,必须对每列起一个唯一的名字,称为属性(Attribute). 再来看看几个键的定义: 超键:在关系模式 ...

  7. 部署到iis后,发现无法加载运行CSS文件

    解决方法: 打开或关闭window功能中的Internet信息服务里的万维网服务=>常见HTTP功能=>静态内容

  8. 010-python基础-数据类型-字符串操作

    1.移除空白 username.strip() 2.分割 names = "alex,jack,rain" names_1 = names.split(",") ...

  9. linux 命令 more

    more命令: 从前往后读取文件,启动时加载整个文件,让整个文件的内容从上到下显示在屏幕上. 可以逐页读取,空格(space):下一页,b键(back):上一页,而且还有搜索字符串的功能. more ...

  10. oracle 分析函数(笔记)

    分析函数是oracle数据库在9i版本中引入并在以后版本中不断增强的新函数种类.分析函数提供好了跨行.多层次聚合引用值的能力.分析函数所展现的效果使用传统的SQL语句也能实现,但是实现方式比较复杂,效 ...