拖放(Drag 和 drop)是 HTML5 标准的组成部分,本文主要介绍与拖拽操作相关的对象及事件信息。
要接受元素的放下,目标元素必须监听至少3个事件:
首先是dragenter事件,用来决定是否接受“拖动的元素”被放下,如果接受放下,那么该事件就被取消,进入下一个事件
然后开始dragover事件,用来确定给用户什么样的反馈,即位于该元素之上时呈现什么样的效果,如果该事件被取消,反馈一般是一个鼠标指针, 也可以使用dropEffect属性定义,如果事件没有被取消,那么就是默认的行为,默认的行为一般就是什么也不做。
最后是drop事件,也就是实际将执行的放下动作,这个事件也需要被取消,这样dropEffect属性的设置就可以被使用。
一个简单的示例
在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的对象。
浏览器支持
Internet Explorer 9、Firefox、Opera 12、Chrome 以及 Safari 5 支持拖放。
注释:在 Safari 5.1.2 中不支持拖放。
相关的事件
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;
}
事件描述
事件名称 事件目标 可撤消? 存储模式 dropEffect值 默认操作 备注
dragstart 被拖拽元素 是 读、写 <q>none</q> 初始化操作 若调用preventDefault()函数取消此事件的默认行为,则拖拽功能将被取消。
drag 被拖拽元素 是 保护模式 <q>none</q> 在dragstart之后,释放鼠标之前,不管鼠标是否移动,此事件不停地被触发。
dragenter 目标元素 是 保护模式 effectAllowed限定的值。 更换目标元素。 进入目标元素时,触发一次。
dragleave 离开前的目标元素 否 保护模式 <q>none</q> 离开时触发一次。
dragover 目标元素 是 保护模式 effectAllowed限定的值 重置dropEffect为<q>none</q>,并中断后续事件执行。 在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限定的值时,整个事件链将被中止,