在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是一个枚举属性,用于指定一个标签是否可以被拖拽。有以下四种取值:
true:表示此元素可拖拽。false:表示此元素不可拖拽。auto:除img和带href的标签a标签表示可拖拽外,其它标签均表示不可拖拽。这个属性用于接受拖拽元素的目标元素上,表示能接受的数据类型及操作方式。多个值用空格分开,不区分大小写。其值有以下类型组成:
string:开头的字符串,长度不能小于8个字符:表示能接受
DataTransferItem.kind值为string的
data对象。file:开头的字符串,长度不能小于6个字符:表示能接受
DataTransferItem.kind值为file且
DataTransferItem.type的值匹配file:之后的字符的
DataTransferItem的对象。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元素本身就是第一个目标元素。
在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表示此次拖拽允许显示的鼠标样式,可以是以下值:none
、copy
、copyLink
、copyMove
、link
、linkMove
、move
、all
和uninitialized
。只能在dragstart事件中更改此值。
dropEffect表示此次拖拽过程中显示的样式,可以是以下几个值:copy
、move
、link
和none
。在具体的拖拽过程中,还受effectAllowed值限定,具体限定内容见下表,当dropEffect的值被设置为一个不属于effectAllowed限定的值时,整个事件链将被中止,即后续事件都将不会被触发,但不会发生任何错误提示。
| 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 |
这个函数用于设置鼠标移动过程中随鼠标一起移动的效果图,而不是鼠标指针的显示效果。x、y参数用于指定图像相对于鼠标指针的位置;image参数用于指定图像元素,若是一个img元素,则显示图像元素,否则将给定的元素转换成一张图像并显示。
该函数只能在读写模式(也就是dragstart事件)下有用,在其它事件中调用无效。若不调用此函数,则在拖拽时,被拖拽元素被转换成一个图处并当作一个效果图显示。
对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类的定义:
string或File。单从字面就很好理解这两个值代表的是什么意思。kind属性为string时,在只读或是读写模式下,可以通过回调函数处理此对象关联的实际数据。kind为file是,通过此函数能获取真实的数据,否则返回null,只在只读或是读写模式下有效。在非读写模式下删除DataTransferItemList中的数据,会返回InvalidStateError错误。若是在非读写模式下添加数据,则不执行任何操作。DataTransfer.setData则是对这两个函数的封装(根据第二个参数决定是删除还是添加)。
返回根据下列步骤产生的字符串集合(DOMStringList):
DOMStringList对象L。DataTransfer.items对象。DataTransfer.items的子项的kind的值为string,则将该项的
type值添加到L对象中。DataTransfer.items的子项的kind的值为file,则向L对象添加"Files"字符串。
getData是从DataTransfer.items中查找数据。返回符合以下条件的数据:
DataTransferItem.kind为string
DataTransferItem.type的值等于format参数如果没有找到匹配的或是处于保护模式下,则返回一个空字符串。
参数format在传递到函数内部之前,都会被转换成小写字符,且如果参数值为text
或是url
,则会被转换成text/plain
和text/uri-list
。
setData用于向DataTransfer.items中添加或删除一条数据:
当没有指定第二个参数data时,则是从DataTransfer.items中删除符合以下条件的数据:
kind等于string
type等于参数format当指定第二个参数data时,则是向DataTransfer.items中添加数据,新添加的数据格式如下:
kind的值为string
type的值为formatdata参数作为DataTransferItem的实际值。参数format在传递到函数内部之前,都会被转换成小写字符,且如果参数值为text
或是url
,则会被转换成text/plain
和text/uri-list
。
如果不处于读写模式下,则不做任何操作。
清除所有kind值为string
的项。只在读写模式下起作用。
存储模式决定了DataTransfer各项内容是否可用。下表列出相关的信息,其中Y
表示可用,N
表示不可用。
| 读写 | 只读 | 保护 | |
|---|---|---|---|
| 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://www.cnblogs.com/muyan927/p/5677641.html