Overview
1. 所拖动的项或区域被称为拖动源(drag source),最终到达的项或目标区域称为放置目标(drop target)。
2. 数据传输(data transfer)是拖放的中央控制部分。数据传输机制的工作原理类似于网络协议谈判,协商需要通过MIME(Multipurpose Internet Mail Exchange,多功能因特网邮件扩展服务,用来给未知内容分类的标准化文本字符串,如:“text/plain”,代表普通文本)来执行。
3. 拖放事件流
- dragstart,用户按下鼠标并移动鼠标时,此事件被初始化。它是唯一一个支持dataTransfer通过setData调用来设置数据的事件。这是因为出于安全考虑,拖动开始后,任何数据替换行为都要被禁止。
- drag,用户在页面中移动鼠标时,会反复对拖动源调用drag事件。拖动反馈的视觉效果可以在drag事件中被修改。
- dragenter,拖动跨入页面中的新元素时,会触发该元素的dragenter事件,此事件适于设置元素的放置反馈。
- dragleave,用户鼠标移出之前调用dragenter事件的元素时,触发dragleave事件。
- dragover,移动到某元素上时,会频繁调用dragover事件,该事件在当前鼠标停留的目标上调用。
- drop,该事件中应该包含处理放置动作的代码。
- dragend,在拖动源上触发,适于清空拖动过程中的状态。
4. 在放置操作中用来更改拖放反馈的函数。通常,浏览器为拖动操作定义默认的视觉指针指示符。图像或者链接会跟随鼠标光标一起移动,或者在拖动位置上显示被拖动元素的低解析度图像。任何元素都可以被设置为拖动图像,对于非图像的情况,浏览器会创建其截图来供鼠标指针显示。
- setDragImage(element, x, y),浏览器使用已存在到图像元素作为拖动图像,该图像会出现在鼠标指针旁边,以提示用户拖动操作的效果。如果提供了x和y值,x表示鼠标指针相对于反馈图像左边的水平位置,y值表示鼠标指针相对于反馈图像定边的垂直位置
- addElement(element),将参数作为拖动反馈图像来绘制。
5. 当从父元素拖动到它所包含的某个字元素上时,拖动就移出来父元素而进入了子元素。
6. 从元素A向元素B拖动的过程中,首先触发元素B的dragenter事件,然后再触发元素A的dragleave事件。
7. 不论放置动作是否发生,即用户取消了拖动,抑或完成了拖动,dragend事件处理器仍会被调用。
8. HTML5拖放设计是对桌面拖放功能的再现。实际的放置功能能够跨窗口工作,如果不同的浏览器支持拖放API,放置功能甚至还能跨浏览器工作。
9. 出于安全考虑,在拖动事件中,浏览器允许访问文件列表(我们可以用了显示文件数量,event.dataTransfer.files.length),但是不允许访问文件数据。
10. 在拖放源上触发的dragstart、drag、dragend事件在文件拖放过程中不会被触发。因为此时的拖放源时文件系统本身。
11. 文件放置的dragover事件中,也需要调用preventDefault(),因为浏览器默认动作是直接打开文件。
12. 设置和查询可用的拖放操作类型:
- effectAllowed:此属性可设置为none、copy、copyLink、copyMove、link、linkMove、move或all之中的任意一个
- dropEffect:确定当前正在执行的操作时何种类型,或设置强制执行某种操作类型。包括copy、link、move。或设为none,及时阻止所有放置动作的发生。
Example
简单的HTML5拖拽和放置应用有以下四个步骤。
1. make an Element Draggable
首先把希望拖动的元素的 draggable 性质设为 true。除了文本控件之类的少数元素,页面中的其他元素默认不可拖动。
<img draggable="true">
2. specify what should happen when the element is dragged
然后指定当这个元素被拖拽时应该发生的行为。把这个处理函数绑定到 ondragstart 性质里
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
函数 dataTransfer.setData(format,data) 指定要被拖拽的数据类型和它的取值。
3. specify where the dragged data can be dropped
默认情况下,系统假定所有目标都不是有效的放置位置。为了在有效的放置目标上触发,我们必须阻止默认的处理方式。在 ondragover 性质下绑定阻止默认处理函数。在dragenter事件中也要做相同处理。
<div id="div1" οndrοp="drop(event)" οndragοver="allowDrop(event)"></div>
function allowDrop(ev) {
ev.preventDefault();
}
4. handle drop event
当拖拽的数据被放置好以后, drop 事件触发。
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
- Call preventDefault() to prevent the browser default handling of the data (default is open as link on drop)
- Get the dragged data with the dataTransfer.getData(format) method. This method will return any data that was set to the same type in the setData() method
- The dragged data is the id of the dragged element ("drag1")
- Append the dragged element into the drop element