HTML5 的拖拽介绍
            
                    
 本文主要介绍与拖拽操作相关的对象及事件信息,但并不涉及太多的源码演示。
   一个简单的示例
  在html5中要实现拖放操作,相对于以前通过鼠标操作实现,要简单得多,数据安全性也更有保障。只需要以下几步即可。
    - 给被拖拽元素添加draggable属性,如果是文件拖放。
- 为目标元素添加一个dropzone属性,这一步也不是必须的,可以省略。
- 在拖拽元素的dragstart中初始化相关的数据信息,主要是DataTransfer对象。
- 在目标元素的dragover事件中,取消其默认操作。
- 在目标元素的drop事件中,处理接受到的数据。
- 在被拖拽元素的dragend事件中,做善后工作。若没有则可以省略。
大致代码如下:
      <div id="source" draggable="draggable">source</div>      <div id="target">target</div>      <script type="text/javascript">      var target = document.getElementById('target');      var source = document.getElementById('source');      source.ondragstart = function(e){        e.dataTransfer.effectAllowed = 'copyMove';        e.dataTransfer.setData('test', 'testData');      };      target.ondragover = function(e){        e.dataTransfer.dropEffect = 'move';        e.preventDefault(); // 不能少      };      target.ondrop = function(e){        var elem = document.createElement('a');        elem.innerHTML = e.dataTransfer.getData('test');        e.target.appendChild(elem);      };      </script> draggable属性
  draggable是一个枚举属性,用于指定一个标签是否可以被拖拽。有以下四种取值:
    - true:表示此元素可拖拽。
- false:表示此元素不可拖拽。
- auto:除- img和带- href的标签- a标签表示可拖拽外,其它标签均表示不可拖拽。
- 其它任何值:表示不可拖拽。
dropzone属性
  这个属性用于接受拖拽元素的目标元素上,表示能接受的数据类型及操作方式。多个值用空格分开,不区分大小写。其值有以下类型组成:
    - copy:表示将允许的元素放到该元素上时,会将拖拽数据复制到目标元素上。
- link:表示将允许的元素放到该元素上时,将链接数据到目标元素上。
- move:表示将允许的元素放到该元素上时,会将数据移动到目标元素上。
- 以string: 开头的字符串,长度不能小于8个字符:表示能接受DataTransferItem.kind值为string 的data对象。
- 以file: 开头的字符串,长度不能小于6个字符:表示能接受DataTransferItem.kind值为file 且DataTransferItem.type的值匹配file: 之后的字符的DataTransferItem的对象。
相关的事件
  DragEvent接口定义
  DragEvent从MouseEvent接口继承,其定义如下,与MouseEvent相比,只是多了个DataTransfer对象。所有针对拖拽的操作也是通过控制此对象来完成的。
      [Construct(DOMString type, optional DragEventInit eventInitDict)]      interface DragEvent : MouseEvent      {        readonly attribute DataTransfer? dataTransfer;      };      /* 这是用于初始事件的参数定义 */      dictionary DragEventInit : EventInit      {        // 从UIEvent继承的属性:        Window? view = null;        long detail = 0;        // 从MouseEvent继承的属性:        long screenX = 0;        long screenY = 0;        long clientX = 0;        long clientY = 0;        boolean ctrlKey = false;        boolean shiftKey = false;        boolean altKey = false;        boolean metaKey = false;        unsigned short button = 0;        unsigned short buttons = 0;        EventTarget? relatedTarget = null;        // DragEvent添加的新属性:        DataTransfer? dataTransfer;      } 事件描述
    拖拽相关事件    | 事件名称 | 事件目标 | 可撤消? | 存储模式1 | dropEffect值 | 默认操作 | 备注 | 
      | 1.存储模式是针对于 DataTransfer对象的操作,具体数据见后表。
 | 
       | dragstart | 被拖拽元素 | 是 | 读、写 | none | 初始化操作 | 若调用preventDefault()函数取消此事件的默认行为,则拖拽功能将被取消。 | 
    | drag | 被拖拽元素 | 是 | 保护模式 | none | 
 | 在dragstart之后,释放鼠标之前,不管鼠标是否移动,此事件不停地被触发。 | 
    | dragenter | 目标元素 | 是 | 保护模式 | effectAllowed限定的值。 | 更换目标元素。 | 进入目标元素时,触发一次。 | 
    | dragleave | 离开前的目标元素 | 否 | 保护模式 | none | 
 | 离开时触发一次。 | 
    | dragover | 目标元素 | 是 | 保护模式 | effectAllowed限定的值 | 重置dropEffect为 none,并中断后续事件执行。 | 在dragenter之后,dragleave之前,不管是否移动,此事件都将不停地触发。 | 
    | drop | 目标元素 | 是 | 只读模式 | 当前设定的值 | 
 | 释放鼠后,由目标元素触发。 | 
    | dragend | 被拖拽元素 | 否 | 保护模式 | 当前设定的值 | 
 | 释放鼠标后,由被拖拽元素触发,顺序在drop之后。 | 
    
  目标元素是指当前鼠停留的元素,如要将A元素拖放到F元素上,中间经过的所有元素,在鼠标经过期间都是一个目标素,相应的事件都会被触发,A元素本身就是第一个目标元素。
   DataTransfer接口
  在HTML5中,为了实现在拖放过程中的数据交换,给所有的拖拽事件提供了一个DataTransfer属性。通过此对象的方法和属性来完善拖放功能。
      interface DataTransfer      {        attribute DOMString dropEffect;        attribute DOMString effectAllowed;        void setDragImage(Element image, long x, long y);        readonly attribute DOMString[] types;        DOMString getData(DOMString format);        void setData(DOMString format, DOMString data);        void clearData(optional DOMString format);        readonly attribute DataTransferItemList items;        readonly attribute FileList files;      } effectAllowed和dropEffect
  这两个属性用于描述在拖拽过程中,鼠标显示的样式,受浏览器和操作系统的影响,鼠标显示的图标并不一致。
  effectAllowed表示此次拖拽允许显示的鼠标样式,可以是以下值:none
、copy
、copyLink
、copyMove
、link
、linkMove
、move
、all
和uninitialized
。只能在dragstart事件中更改此值。 
  dropEffect表示此次拖拽过程中显示的样式,可以是以下几个值:copy
、move
、link
和none
。在具体的拖拽过程中,还受effectAllowed值限定,具体限定内容见下表,当dropEffect的值被设置为一个不属于effectAllowed限定的值时,整个事件链将被中止,即后续事件都将不会被触发,但不会发生任何错误提示。
    effectAllowed与dropEffect对照表    | effectAllowed | dropEffect | 
      | 1:根据用户所使用的平台不同,可能会出现的值,如在windows下,copyMove的effectAllowed值,默认为copy操作,在按shift键时,则会变成move操作。 | 
       | none | none | 
    | copy | copy | 
    | copyLink | copy或是link1 | 
    | copyMove | copy或是move1 | 
    | all | copy、link1或是move1 | 
    | link | link | 
    | linkMove | link或是move1 | 
    | move | move | 
    | uninitialized,被拖拽为一个文本框中选中的内容? | move或是copy1,link1 | 
    | uninitialized,被拖拽对象为一个普通选中项? | copy或是link1,move1 | 
    | uninitialized,被拖拽对象为一个带链接的a元素 | link或是copy1,move1 | 
    | 其它情况 | copy或是link1,move1 | 
    
   setDragImage(image, x, y)
  这个函数用于设置鼠标移动过程中随鼠标一起移动的效果图,而不是鼠标指针的显示效果。x、y参数用于指定图像相对于鼠标指针的位置;image参数用于指定图像元素,若是一个img元素,则显示图像元素,否则将给定的元素转换成一张图像并显示。
  该函数只能在读写模式(也就是dragstart事件)下有用,在其它事件中调用无效。若不调用此函数,则在拖拽时,被拖拽元素被转换成一个图处并当作一个效果图显示。 
   items属性
  对items的接口定义如下:
      interface DataTransferItemList      {        readonly attribute unsigned long length;        getter DataTransferItem(unsigned long index); // items[index]        deleter void(unsigned long index); // delete items[index]        void clear();        DataTransferItem? add(DOMString data, DOMString type);        DataTransferItem? add(File data);      }      interface DataTransferItem      {        readonly attribute DOMString kind;        readonly attribute DOMString type;        void getAsString(FunctionStringCallback? _callback);        File? getAsFile();      }      [Callback, NoInterfaceObject]      interface FunctionStringCallback      {        void handleEvent(DOMString data);      } 从上面的定义不难看出:DataTransfer.items就是DataTransferItem的一个数组。DataTransferItemList仅仅是定义一套以数组形式存取DataTransferItem对象的接口。我们主要看一下DataTransferItem类的定义:
    - kind:表示数据的类型,只能是string或File。单从字面就很好理解这两个值代表的是什么意思。
- type:实际数据的类型或是格式,一般用mimetype表示,但并不是强制mimetype格式。
- getAsString(callback):当kind属性为string时,在只读或是读写模式下,可以通过回调函数处理此对象关联的实际数据。
- getAsFile():当kind为file是,通过此函数能获取真实的数据,否则返回null,只在只读或是读写模式下有效。
在非读写模式下删除DataTransferItemList中的数据,会返回InvalidStateError错误。若是在非读写模式下添加数据,则不执行任何操作。DataTransfer.setData则是对这两个函数的封装(根据第二个参数决定是删除还是添加)。
   types属性
  返回根据下列步骤产生的字符串集合(DOMStringList):
    - 产生一个空的DOMStringList对象L。
- 遍历DataTransfer.items对象。
- 若DataTransfer.items的子项的kind的值为string ,则将该项的type值添加到L对象中。
- 若DataTransfer.items的子项的kind的值为file ,则向L对象添加"Files"字符串。
- 返回L对象
getData(format)
  getData是从DataTransfer.items中查找数据。返回符合以下条件的数据:
    - DataTransferItem.kind为- string 
- DataTransferItem.type的值等于- format参数
如果没有找到匹配的或是处于保护模式下,则返回一个空字符串。
  参数format在传递到函数内部之前,都会被转换成小写字符,且如果参数值为text
或是url
,则会被转换成text/plain
和text/uri-list
。 
   setData(format, data)
  setData用于向DataTransfer.items中添加或删除一条数据:
  当没有指定第二个参数data时,则是从DataTransfer.items中删除符合以下条件的数据:
    - kind等于- string 
- type等于参数- format
当指定第二个参数data时,则是向DataTransfer.items中添加数据,新添加的数据格式如下:
    - kind的值为- string 
- type的值为- format
- data参数作为- DataTransferItem的实际值。
参数format在传递到函数内部之前,都会被转换成小写字符,且如果参数值为text
或是url
,则会被转换成text/plain
和text/uri-list
。 
  如果不处于读写模式下,则不做任何操作。
   clearData()
  清除所有kind值为string
的项。只在读写模式下起作用。
  </section> 存储模式
  存储模式决定了DataTransfer各项内容是否可用。下表列出相关的信息,其中Y
表示可用,N
表示不可用。
    存储模式与DataTransfer各项的关系    | 
 | 读写 | 只读 | 保护 | 
       | dropEffect | 只在 dragenter与dragover事件中可更改,其它事件中只可读取。 | 
    | effectAllowed | 只在 dragstart事件中起作用 | 
    | items | 对items的操作详细情况参考后面的 setData函数 | 
    | types | 仅在 dragenter、dragover与drop三个事件中可获取此值 | 
    | setData | Y | N | N | 
    | getData | Y | Y | N | 
    | clearData | Y | N | N | 
    | DataTransferItem.getAsString | Y | Y | N | 
    | DataTransferItem.getAsFile | Y | Y | N | 
    
  来自:http://blog.830725.com/post/html5-drag-and-drop-intro.html