早在 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- 不支持拖放功能。
为了让 Firefox 支持可拖动属性,还必须添加一个 ondragstart 事件处理程序,并在 dataTransfer 中保存一些信息。 IE9- 通过 mousedown 事件调用 dragDrop() 能够让任何元素可拖动。Safari 4- 必须给相应元素设置 CSS 样式 -khtml-user-drag:element 。
拖放事件
被拖动元素事件
拖动某元素时,将依次触发以下事件:
dragstart - 按下鼠鼠标键并开始移动时,被拖动元素上触发 dragstart 事件;
drag - 触发 dragstart 事件后,随即触发 drag 事件,而且元素拖动期间会持续触发该事件;
dragend - 拖动停止时(释放鼠标、无论放置目标是否有效)触发 dragend 事件。
放置目标元素事件
当某个元素被拖动到一个有效的放置目标时,依次触发下列事件:
dragenter - 元素进入到目标元素上时触发事件;
dragover - 紧随 dragover 事件,被拖动元素在目标元素范围内移动时会持续触发该事件;
dragleave 或 drop - 元素拖出了放置目标,则 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
清除以特定格式保存的数据 object.clearData(format) - IE、FF3.5+、Chrome、Safari4+ 支持
从 dataTransfer 对象中读取指定类型的值,object.getData(format),参数是 MIME 类型
为 dataTransfer 对象指定特定格式的数据,object.setData(format, data)。IE 只定义了 Text 和 URL 两种数据格式。HTML5 允许指定各种 MIME 类型。HTML5 也兼容 Text 和 URL,会被映射到 text/plain 和 text/uri-list。dataTransfer 对象可以为每种 MIME 类型都保存一个值,这些数据只能在 ondrop 处理程序中读取。
dataTransfer 对象的属性
Property
Description
获取或设置被拖动元素能够执行哪中放置行为,不同的行为显示相应的光标:
none - 不能放置拖动元素(除文本框以外所有元素的默认值);
move - 应该把元素移动到放置目标;
copy - 应该把拖动元素复制到放置目标;
link - 应该在放置目标上打开拖动元素(拖动元素必须是有 URL 的链接)使用 dropEffect 属性时必须在 ondragenter 中针对放置目标设置。
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 事件。)
返回被拖放文件的 FileList 对象,比如拖放文件上传时可以对这个对象做进一步处理
返回 ondragstart 事件中传递的数据类型的类似数组的集合,IE10+、FF3.5+、Chrome 支持
其他新增方法和属性
HTML5 规范中 dataTransfer 对象还包含下列属性和方法:
addElement(element) - 为拖动操作添加一个元素(即增加作为拖动源而响应的回调对象),只有 Firefox 3.5+ 实现了。
setDragImage(element, x, y) - 指定一个元素拖动发生时显示在光标下方,三个参数分别是要显示的 HTML 元素 和 光标在显示元素中的 x、y 坐标。 HTML 元素如果是图像则显示图像,如果是其他元素则显示渲染后的元素。
参考及演示