在html5中新增了两个与表单元素相关的api-文件api和拖放api。拖放api可以实现一些有趣的功能,允许我们拖动选项并将其放置到浏览器中的任何地方。这很好地体现了html5作为web应用程序规范的思路,使得开发者可以从桌面计算中借用更多的功能。
接上节

四、拖放API

在HTML5中,提供了直接支持拖放操作的API。虽然
HTML5之前已经可以使用​​​mousedown​​​,​​mousemove​​​,
​​​mouseup​​​来实现拖放操作,但是只支持在浏览器内部的拖
放,而在HTML5中,已经支持在浏览器与其他应用程序之
间的数据的互相拖动,同时也大大简化了有关于拖放方面
的代码.

拖放的步骤

在HTML5中要想实现拖放操作,至少要经过如下两个步骤:
1.将想要拖放的对象元素的draggable属性设为true (draggable=“true”)。这样才能将该元素进行拖放。另外,img元素与a元素(必须指定href),默认允许拖放。
2.编写与拖放有关的事件处理代码。关于拖放存在如下表所示的几个事件:
​​​dragstart​​​ 被拖动的元素或文本 This event is fired when the user starts dragging an element or text selection。当开始拖动选择的元素或文本的时候出发
​​​drag​​​ 被拖动的元素或文本 This event is fired when an element or text selection is being dragged。在元素在拖动的过程中触发。(会重复触发)
​​​dragenter​​​ 拖放的目标元素 This event is fired when a dragged element or text selection enters a valid drop target。元素进入目标元素区域的时候触发。
​​​dragover​​​ 拖放的目标元素 This event is fired when an element or text selection is being dragged over a valid drop target (every few hundred milliseconds).在目标元素领域经过的时候触发
​​​dragleave​​​ 拖放的目标元素 This event is fired when a dragged element or text selection leaves a valid drop target.当离开目标元素的时候触发。
​​​dragend​​​ 拖放的目标元素 This event is fired when a drag operation is being ended (by releasing a mouse button or hitting the escape key).当拖放操作完成后触发(松开了鼠标键或者按下了esc键)
​​​dragexit​​​ 被拖动的元素 This event is fired when an element is no longer the drag operation’s immediate selection target.当元素不再是拖动操作的直接目标时触发
​​​drop​​​ 被拖动的元素 This event is fired when an element or text selection is dropped on a valid drop ​​target​​。当在有效的目标上放下拖动的元素后触发

dataTransfer对象

在所有的拖放事件中都提供了一个数据传输对象dataTransfer,主要是用于在源对象和目标对象之间传递数据。

DataTransfer对象的属性:

​dropEffect​​​属性:返回已选择的拖放效果,如果该操作效果与起初设置的effectAllowed效果不符,则拖拽操作失败。可以设置修改,包含这几个值:“none”,“copy”,“link” 和 “move”。
​​​effectAllowed​​​ 属性:返回允许执行的拖拽操作效果,可以设置修改,包含这些值:“none”,“copy”,“copyLink”,“copyMove”,“link”,“linkMove”,“move”,“all”和 “uninitialized”。
​​​types​​属性:返回在dragstart事件出发时为元素存储数据的格式,如果是外部文件的拖拽,则返回“files” 。

DataTransfer对象的方法:

​void clearData(DOMString format)​​​方法:删除指定格式的数据,如果未指定格式,则删除当前元素的所有携带数据。
注:clearData方法可以用来清除DataTransfer对象内数据
​​​void setData(DOMString format, DOMString data)​​​方法:为元素添加指定数据 。
注:setData方法在拖放开始时向dataTransfer对象中存入数据,
用types属性来指定数据的MIME类型。
​​​DOMString getData(DOMString format)​​​方法:返回指定数据,如果数据不存在,则返回空字符串 。
注:getData方法在拖动结束时读取dataTransfer对象中的数据
​​​void setDragImage(Element image, long x, long y)​​:制定拖拽元素时跟随鼠标移动的图片,x、y分别是相对于鼠标的坐标(部分浏览器中可以用canvas等其他元素来设置) 。

使用​​effectAllowed​​​和​​dropEffect​​属性设置拖放效果

dropEffect属性与effectAllowed属性结合起来可以设定拖放时的视觉效
果。
effectAllowed属性表示当一个元素被拖动时所允许的视觉效果,一般在
​​​ondragstart​​​事件中设定,允许设定的值为none、copy、 copyLink、
copyMove、link、linkMove、move,all,unintialize。
dropEffect属性表示实际拖放时的视觉效果,一般在ondragover事件中
指定,允许设定的值为none,copy,link,move。
​​​dropEffect​​​属性所表示的实际视觉效果必须在effectAllowed属性所表示
的允许的视觉效果范围内。规则如下所示:
如果effectAllowed属性设定为none,则不允许拖放要拖放的元素。
如果dropEffect属性设定为none,则不允许被拖放到目标元素中。
如果effectAllowed属性设定为all或不设定,则dropEffect属性允
许被设定为任何值,并且按指定的视觉效果进行显示。
如果effectAllowed属性设定为具体效果(不为none,all),
dropEffect属性也设定了具体视觉效果,则两个具体效果值必须完全相等,
否则不允许将被拖放元素拖放到目标元素中。

<html>
<head>
<meta charset="utf-8" />
<title>使用拖放API将商品拖入购物车</title>
<link href="Css/css1.css" rel="stylesheet" type="text/css">
<script language=javascript>
// JavaScript Document
function $$(id) {
return document.getElementById(id);
}
//自定义页面加载时调用的函数
function pageload() {
//获取全部的图书商品
var Drag = document.getElementsByTagName("img");
//遍历每一个图书商品
for (var intI = 0; intI < Drag.length; intI++) {
//为每一个商品添加被拖放元素的dragstart事件
Drag[intI].addEventListener("dragstart",
function(e) {
var objDtf = e.dataTransfer;
objDtf.setData("text/html", addCart(this.title, this.alt, 1));
},
false);
}
var Cart = $$("ulCart");
//添加目标元素的drop事件
Cart.addEventListener("drop",
function(e) {
var objDtf = e.dataTransfer;
var strHTML = objDtf.getData("text/html");
Cart.innerHTML += strHTML;
e.preventDefault();
e.stopPropagation();
},
false);
}
//添加页面的dragover事件
document.ondragover = function(e) {
//阻止默认方法,取消拒绝被拖放
e.preventDefault();
}
//添加页面drop事件
document.ondrop = function(e) {
//阻止默认方法,取消拒绝被拖放
e.preventDefault();
}
//自定义向购物车中添加记录的函数
function addCart(a, b, c) {
var strHTML = "<li class='liC'>";
strHTML += "<span>" + a + "</span>";
strHTML += "<span>" + b + "</span>";
strHTML += "<span>" + c + "</span>";
strHTML += "<span>" + b * c + "</span>";
strHTML += "</li>";
return strHTML;
}
</script>
</head>
<body onLoad="pageload();">
<ul>
<li class="liF">
<img src="images/img02.jpg" id="img02"
alt="42" title="2006作品" draggable="true">
</li>
<li class="liF">
<img src="images/img03.jpg" id="img03"
alt="56" title="2008作品" draggable="true">
</li>
<li class="liF">
<img src="images/2.jpg" id="img04"
alt="52" title="2010作品" draggable="true">
</li>
<li class="liF">
<img src="images/1.jpg" id="img05"
alt="59" title="2011作品" draggable="true">
</li>
</ul>
<ul id="ulCart">
<li class="liT">
<span>书名</span>
<span>定价</span>
<span>数量</span>
<span>总价</span>
</li>
</ul>
</body>
</html>

使用​​setDragImage​​方法设置拖放图标

在拖动一个元素时,可以添加自己定制的拖动图标。
实现的方法:
在dragstart事件上,可以使用setDragImage方
法,该方法有三个参数。
第一个参数image为设定为拖放图标的图标元素;
第二个参数x为拖放图标离鼠标指针的x轴方向的位移量;
第三个参数y为拖放图标离鼠标指针的y轴方向的位移量。

<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>拖放示例</title>
<script type="text/javascript">
function init()
{
var source = document.getElementById("dragme");
var dest = document.getElementById("text");
//创建图标元素
var dragIcon = document.createElement('img');
//设定图标来源
dragIcon.src='images/2.png';
// 开始拖放
source.addEventListener("dragstart", function(ev)
{
// 向dataTransfer对象追加数据
var dt = ev.dataTransfer;
dt.setDragImage(dragIcon, -10, -10);
dt.effectAllowed = 'all';
//拖动元素为dt.setData("text/plain", this.id);
dt.setData("text/plain", "珊瑚贝欢迎你");
}, false);
// dragend:拖放结束
dest.addEventListener("dragend", function(ev)
{
//不执行默认处理(拒绝被拖放)
ev.preventDefault();
}, false);
// drop:被拖放
dest.addEventListener("drop", function(ev)
{
// 从DataTransfer对象那里取得数据
var dt = ev.dataTransfer;
var text = dt.getData("text/plain");
dest.textContent += text;
//不执行默认处理(拒绝被拖放)
ev.preventDefault();
//停止事件传播
ev.stopPropagation();
}, false);
}
//设置页面属性,不执行默认处理(拒绝被拖放)
document.ondragover = function(e){e.preventDefault();};
document.ondrop = function(e){e.preventDefault();};
</script>
</head>
<body οnlοad="init()">
<h1>拖放欢迎语</h1>
<!-- (7) 把draggable属性设为true -->
<div id="dragme" draggable="true" style="width: 200px; border: 1px solid gray;">
拖放
</div>
<div id="text" style="width: 200px; height: 200px; border: 1px solid gray;"></div>
</body>