HTML5 – 拖放
拖放(DnD)是一种强大的用户界面概念,可以通过鼠标点击轻松复制、重新排序和删除项目。这允许用户点击并按住鼠标按钮在一个元素上,将其拖到另一个位置,然后释放鼠标按钮将元素放置在那里。
为了实现传统HTML4的拖放功能,开发人员要么必须使用复杂的JavaScript编程,要么使用其他JavaScript框架,如jQuery等。
现在HTML5推出了一个拖放(DnD)API,它将本地DnD支持带到浏览器,使编码变得更加容易。
HTML5 DnD由所有主流浏览器支持,如Chrome,Firefox 3.5和Safari 4等。
拖放事件
在拖放操作的各个阶段中会触发许多事件。以下是这些事件的列表 −
序号 | 事件及其描述 |
---|---|
1 | dragstart 当用户开始拖动对象时会触发此事件。 |
2 | dragenter 在进行拖动时,当鼠标首次移动到目标元素上方时触发此事件。此事件的侦听器应指示是否允许在此位置放置拖放。如果没有侦听器,或者侦听器执行的操作为零,则默认情况下不允许放置。 |
3 | dragover 此事件是在进行拖动时,鼠标移动到元素上方时触发的。大多数情况下,侦听器中发生的操作将与dragenter事件相同。 |
4 | dragleave 当鼠标在进行拖动时离开元素时,将触发此事件。侦听器应该删除用于下拉反馈的任何高亮显示或插入标记。 |
5 | drag 每次移动对象时拖动鼠标时都会触发此事件。 |
6 | drop 拖放操作结束时,在发生拖放的元素上触发drop事件。侦听器将负责检索正在拖动的数据并将其插入到拖放位置。 |
7 | dragend 当用户拖动对象并释放鼠标按钮时触发此事件。 |
注意 - 请注意,只有拖动事件会被触发;鼠标事件(如mousemove)在拖动操作期间不会被触发。
数据传输对象
所有拖放事件的事件侦听器方法都接受只读属性名称为dataTransfer的Event对象。
event.dataTransfer返回与事件相关的DataTransfer对象,如下所示 −
function EnterHandler(event) {
DataTransfer dt =event.dataTransfer;
.............
}
DataTransfer对象包含有关拖放操作的数据。可以通过与DataTransfer对象相关联的各种属性来检索和设置这些数据,如下所述 −
序号 | DataTransfer 属性及其描述 |
---|---|
1 | dataTransfer.dropEffect [ = value ] 返回当前选中的操作类型。 可设置此属性以更改选定操作。 可能的值为none、copy、link和move。 |
2 | dataTransfer.effectAllowed [ = value ] 返回允许执行的操作类型。 可设置此属性以更改允许的操作。 可能的值为 none、copy、copyLink、copyMove、link、linkMove、move、all 和 uninitialized 。 |
3 | dataTransfer.types 返回一个DOMStringList,列出了在dragstart事件中设置的格式。此外,如果正在拖动任何文件,则其中一个类型将是字符串“Files”。 |
4 | dataTransfer.clearData ( [ format ] ) 删除指定格式的数据。如果省略参数,则删除所有数据。 |
5 | dataTransfer.setData(format, data) 添加指定数据。 |
6 | data = dataTransfer.getData(format) 返回指定的数据。如果不存在此类数据,则返回空字符串。 |
7 | dataTransfer.files 返回正在拖动的文件的FileList(如果有)。 |
8 | dataTransfer.setDragImage(element, x, y) 使用指定的元素更新拖动反馈,替换任何先前指定的反馈。 |
9 | dataTransfer.addElement(element) 将给定的元素添加到用于呈现拖动反馈的元素列表中。 |
拖放流程
实现拖放操作需执行以下步骤 –
第1步 – 使物体可拖动
需要执行以下步骤 –
- 如果要拖动一个元素,则需要为该元素设置 draggable 属性为 true 。
-
为 dragstart 设置一个事件监听器,存储被拖动的数据。
-
事件监听器 dragstart 将设置允许的效果(复制、移动、链接或某些组合)。
这是使对象可拖动的示例:
<!DOCTYPE HTML>
<html>
<head>
<style type = "text/css">
#boxA, #boxB {
float:left;padding:10px;margin:10px;-moz-user-select:none;
}
#boxA { background-color:#6633FF; width:75px; height:75px; }
#boxB { background-color:#FF6699; width:150px; height:150px; }
</style>
<script type = "text/javascript">
function dragStart(ev) {
ev.dataTransfer.effectAllowed = 'move';
ev.dataTransfer.setData("Text", ev.target.getAttribute('id'));
ev.dataTransfer.setDragImage(ev.target,0,0);
return true;
}
</script>
</head>
<body>
<center>
<h2>拖拽HTML5演示</h2>
<div>尝试拖动紫色盒子。</div>
<div id = "boxA" draggable = "true" ondragstart = "return dragStart(ev)">
<p>拖动我</p>
</div>
<div id = "boxB">垃圾箱</div>
</center>
</body>
</html>
这将产生以下结果 −
第二步 – 放下对象
为了接受拖放,拖放目标必须监听至少三个事件。
- dragenter 事件,用于确定是否接受拖放。如果要接受,则必须取消此事件。
-
dragover 事件,用于确定向用户显示什么反馈。如果取消此事件,则更新反馈(通常是光标),基于
dropEffect
属性的值。 -
最后, drop 事件,允许执行实际的拖放。
以下是将对象拖放到另一个对象的示例 −
<html>
<head>
<style type="text/css">
#boxA, #boxB {
float:left;padding:10px;margin:10px;-moz-user-select:none;
}
#boxA { background-color: #6633FF; width:75px; height:75px; }
#boxB { background-color: #FF6699; width:150px; height:150px; }
</style>
<script type="text/javascript">
function dragStart(ev) {
ev.dataTransfer.effectAllowed='move';
ev.dataTransfer.setData("Text", ev.target.getAttribute('id'));
ev.dataTransfer.setDragImage(ev.target,0,0);
return true;
}
function dragEnter(ev) {
event.preventDefault();
return true;
}
function dragOver(ev) {
return false;
}
function dragDrop(ev) {
var src = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(src));
ev.stopPropagation();
return false;
}
</script>
</head>
<body>
<center>
<h2>拖拽HTML5演示</h2>
<div>尝试将紫色盒子移动到粉色盒子中。</div>
<div id="boxA" draggable="true" ondragstart="return dragStart(event)">
<p>拖动我</p>
</div>
<div id="boxB" ondragenter="return dragEnter(event)" ondrop="return dragDrop(event)" ondragover="return dragOver(event)">垃圾箱</div>
</center>
</body>
</html>
这将产生以下结果 −