/ Drag-Drop

HTML5 拖放

早在 IE4,微软就引进了 JavasScript 拖放。当时只有图像和文本两种对象可以拖放,唯一有效的放置目标是文本框。到了 IE5,拖放功能得到扩展,添加了新事件,几乎网页中的任何元素都可以作为放置目标。IE5.5 则让网页中的任何元素都可以拖放。HTML5 以 IE 的实例为基础制定了拖放规范。Firefox 3.5+、Safari 3+、Chrome 也根据标准实现了原生拖放功能。

可拖动属性

默认情况下,图像、链接、文本(被选中部分)是可拖动的。HTML5 为所有 HTML 元素规定了一个 draggabble 属性,控制元素是否可以拖动。图像、链接的 draggable 属性默认为 true,其他元素默认为 false
关键字 描述
true 内容可被拖动。
false 内容不可被拖动。
auto 内容执行默认的浏览器行为(文本、链接和图像可被拖动;其他元素不可以)。
支持 draggable 属性的浏览器有: IE10+、FF4+、Safari 5+、Chrome、Opera 12+。Opera 11.5- 不支持拖放功能。

拖放事件

被拖动元素事件

拖动某元素时,将依次触发以下事件:
  1. dragstart - 按下鼠鼠标键并开始移动时,被拖动元素上触发 dragstart 事件;
  2. drag - 触发 dragstart 事件后,随即触发 drag 事件,而且元素拖动期间会持续触发该事件;
  3. dragend - 拖动停止时(释放鼠标、无论放置目标是否有效)触发 dragend 事件。

放置目标元素事件

当某个元素被拖动到一个有效的放置目标时,依次触发下列事件:
  1. dragenter - 元素进入到目标元素上时触发事件;
  2. dragover - 紧随 dragover 事件,被拖动元素在目标元素范围内移动时会持续触发该事件;
  3. dragleavedrop - 元素拖出了放置目标,则 dragover 事件不再发生,触发 dragleave 事件;如果元素放到了目标上,则触发 drop 事件。

自定义放置目标

所有元素都支持放置目标事件,但多数元素默认是不允许放置的。重写 dragenter 和 dragover 事件的默认行为,可以把任何元素变成有效的放置目标
dropArea.addEventListener("dragenter", doNothing(event), false);
dropArea.addEventListener("dragover", doNothing(event), false);

// 阻止 Firefox 打开 URL
dropArea.addEventListener("drop", doNothing(event), false);

function doNothing(event) {
event.stopPropagation();
event.preventDefault();
}


Firefox 3.5+ 中,放置事件的默认行为是打开放到目标上的 URL。如果是图像则打开图像,如果是文本则会导致无效 URL 错误(不安装拖拽插件的情况下)。所以还要取消 Firefox 中 drop 事件的默认行为,阻止它打开 URL

dataTransfer 对象

IE5 引入了 dataTransfer 对象,它是拖放事件对象的一个属性,用于从被拖动元素向放置目标传递字符串格式的数据。在事件处理程序中,可以用这个对象的属性和方法来完善拖放功能。 HTML5 规范草案也收入了 dataTransfer 对象。

dataTransfer 对象的方法

Method Description
clearData 清除以特定格式保存的数据 object.clearData(format) - IE、FF3.5+、Chrome、Safari4+ 支持
getData dataTransfer 对象中读取指定类型的值,object.getData(format),参数是 MIME 类型
setData  为 dataTransfer 对象指定特定格式的数据,object.setData(format, data)。IE 只定义了 TextURL 两种数据格式。HTML5 允许指定各种 MIME 类型。HTML5 也兼容 Text 和 URL,会被映射到 text/plaintext/uri-listdataTransfer 对象可以为每种 MIME 类型都保存一个值,这些数据只能在 ondrop 处理程序中读取。

dataTransfer 对象的属性

Property Description
dropEffect 获取或设置被拖动元素能够执行哪中放置行为,不同的行为显示相应的光标: none - 不能放置拖动元素(除文本框以外所有元素的默认值); move - 应该把元素移动到放置目标; copy - 应该把拖动元素复制到放置目标; link - 应该在放置目标上打开拖动元素(拖动元素必须是有 URL 的链接)使用 dropEffect 属性时必须在 ondragenter 中针对放置目标设置
effectAllowed dropEffect 属性只有搭配 effectAllowed 属性时才有用。 effectAllowed 属性表示允许拖动元素的哪种 dropEffect。可能的值如下: uninitialized - 被拖动元素没有设置放置行为; none - 被拖动元素不允许有任何行为; copy - 只允许 copy 值的 dropEffect; move - 只允许 move 值的 dropEffect; copeLink - copy 和 link 值的 dropEffect; copeMove - copy 和 move 值的 dropEffect; linkMove - link 和 move 值的 dropEffect; all - 允许任意 dropEffect。必须在 ondragstart 中设置 effectAllowed。(Firefox 5- 设置了 effectAllowed 值的话,则不一定会触发 drop 事件。)
files 返回被拖放文件的 FileList 对象,比如拖放文件上传时可以对这个对象做进一步处理
types 返回  ondragstart 事件中传递的数据类型的类似数组的集合,IE10+、FF3.5+、Chrome 支持

其他新增方法和属性

HTML5 规范中 dataTransfer 对象还包含下列属性和方法:
  • addElement(element) - 为拖动操作添加一个元素(即增加作为拖动源而响应的回调对象),只有 Firefox 3.5+ 实现了。
  • setDragImage(element, x, y) - 指定一个元素拖动发生时显示在光标下方,三个参数分别是要显示的 HTML 元素 和 光标在显示元素中的 x、y 坐标。 HTML 元素如果是图像则显示图像,如果是其他元素则显示渲染后的元素。

参考及演示