html5 拖放 - html5 详细教程
html5 拖放
版本:HTML5
在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放。
HTML 拖放(Drag and Drop)接口使应用程序能够在Firefox和其他浏览器中使用拖放功能。例如,通过这些功能,用户可以使用鼠标选择可拖动元素,将元素拖动到可放置元素,并通过释放鼠标按钮来放置这些元素。可拖动元素的一个半透明表示在拖动操作期间跟随鼠标指针。
对于网站、扩展以及 XUL 应用程序来说,你可以自定义能够成为可拖拽的元素类型、可拖拽元素产生的反馈类型,以及可放置的元素。
此文档为 HTML 拖放的概述,包含了相关接口的说明、在应用程序中加入拖放支持的基本步骤,以及相关接口的使用简介。
拖拽事件
HTML 的 drag & drop 使用了 DOM event model 以及从mouse events 继承而来的 drag events 。一个典型的drag操作是这样开始的:用户用鼠标选中一个可拖动的(draggable)元素,移动鼠标到一个可放置的(droppable)元素,然后释放鼠标。 在操作期间,会触发一些事件类型,有一些事件类型可能会被多次触发(比如drag 和 dragover 事件类型)。
在拖拽行为中,一些事件类型会被触发,并且一些事件可能触发很多次,比如drag和dragover事件。
所有的 drag event types 有一个对应的 global event handler。每个拖动事件类型和拖动全局属性都有对应的描述文档。下面的表格提供了一个简短的事件类型描述,以及一个相关文档的链接。
拖放是一种常见的特性,即抓取对象以后拖到另一个位置。在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放。拖放的过程分为源对象和目标对象。源对象是指你即将拖动元素,而目标对象则是指拖动之后要放置的目标位置。
拖放的源对象(可能发生移动的)可以触发的事件——3个:
- dragstart:拖动开始
- drag:拖动中
- dragend:拖动结束
整个拖动过程的组成: dragstart*1 + drag*n + dragend*1
拖放的目标对象(不会发生移动)可以触发的事件——4个:
- dragenter:拖动着进入
- dragover:拖动着悬停
- dragleave:拖动着离开
- drop:释放
整个拖动过程的组成1: dragenter*1 + dragover*n + dragleave*1
整个拖动过程的组成2: dragenter*1 + dragover*n + drop*1
dataTransfer:用于数据传递的“拖拉机”对象;
- 在拖动源对象事件中使用e.dataTransfer属性保存数据:e.dataTransfer.setData( k, v )
- 在拖动目标对象事件中使用e.dataTransfer属性读取数据:var value = e.dataTransfer.getData( k )
Event | On Event Handler | Fires when… |
---|---|---|
drag | ondrag | 当拖动元素或选中的文本时触发。 |
dragend | ondragend | 当拖拽操作结束时触发 (比如松开鼠标按键或敲“Esc”键). (见结束拖拽) |
dragenter | ondragenter | 当拖动元素或选中的文本到一个可释放目标时触发(见 指定释放目标)。 |
dragexit | ondragexit | 当元素变得不再是拖动操作的选中目标时触发。 |
dragleave | ondragleave | 当拖动元素或选中的文本离开一个可释放目标时触发。 |
dragover | ondragover | 当元素或选中的文本被拖到一个可释放目标上时触发(每100毫秒触发一次)。 |
dragstart | ondragstart | 当用户开始拖动一个元素或选中的文本时触发(见开始拖动操作)。 |
drop | ondrop | 当元素或选中的文本在可释放目标上被释放时触发(见执行释放)。 |
dragstart
和dragend
事件。 实例
拖动IE图标图片到矩形框中:
#div1 {width:200px;height:150px;padding:10px;border:1px solid #aaaaaa;}#div1 {width:200px;height:150px;padding:10px;border:1px solid #aaaaaa;}拖动IE图标图片到矩形框中:
function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { ev.dataTransfer.setData("Text",ev.target.id); } function drop(ev) { ev.preventDefault(); var data=ev.dataTransfer.getData("Text"); ev.target.appendChild(document.getElementById(data)); }
拖动IE图标图片到矩形框中
function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { ev.dataTransfer.setData("Text",ev.target.id); } function drop(ev) { ev.preventDefault(); var data=ev.dataTransfer.getData("Text"); ev.target.appendChild(document.getElementById(data)); }浏览器兼容性
Internet Explorer 9、Firefox、Opera、Chrome 和 Safari 支持 标签的属性及方法。 | ||||
注意:Internet Explorer 8 及更早的IE版本不支持 元素。 |
接口
HTML 的拖拽接口有DragEvent
,DataTransfer
,DataTransferItem
和DataTransferItemList
。
DragEvent
接口有一个构造函数和一个 dataTransfer 属性,dataTransfer 属性是一个 DataTransfer 对象。DataTransfer
对象包含了拖拽事件的状态,例如拖动事件的类型(如拷贝copy
或者移动move
),拖动的数据(一个或者多个项)和每个拖动项的类型(MIME类型)。DataTransfer
对象也有一些方法,可以向拖动数据中添加项或者删除项。DragEvent
和DataTransfer
接口应该仅有的接口来给应用程序添加 html 拖放功能。
但是,注意 Firefox 给DataTransfer
添加了可能用到的一些扩展的功能,尽管这些扩展只在 Firefox 上才可用。每个DataTransfer
包含一个 items 属性,这个属性是一个DataTransferItem
对象的列表。
一个web应用需要添加拖拽功能时,应当仅仅使用DragEvent
和DataTransfer
接口即可。 然而,Firefox支持一些DataTransfer
对象上的Gecko-specific extensions,注意这些拓展仅仅适用于Firefox。
每一个DataTransfer
对象代表一个单独的拖动项,每一项有一个 kind 属性,代表数据的 kind(string
或file
),还有一个 type 属性,代表数据项的type(例如MIME类型),另外,DataTransferItem
对象也包含了得到拖拽项的数据的方法。
DataTransferItemList
对象是DataTransferItem
对象的列表。这个列表对象包含以下方法:向列表中添加拖动项,从列表中移除拖动项和清空列表中所有的拖拽项。
DataTransfer
和DataTransferItem
接口的一个主要的不同在于,前者使用同步的getData()
方法去得到一个拖拽项的数据,然后后者使用异步的getAsString()
方法得到一个拖拽项的数据。
DragEvent
和DataTransfer
接口是所有桌面浏览器都支持的。但是,DataTransferItem
和DataTransferItemList
接口并不被所有浏览器支持。
Gecko 专用接口
Mozilla 和 Firefox 支持一些不在标准拖放模型中的特性。 它们是一些帮助实现拖动多个项目和拖动非文本内容(如文件)的便捷函数。想要了解更多信息,请参见拖放多个项目。另外,请查看DataTransfer
参考页以获取所有 Gecko 专有属性 和 Gecko 专有方法。
dataTransfer对象
在拖曳操作的过程中,我们可以用过dataTransfer对象来传输数据,以便在拖曳操作结束的时候对数据进行其他的操作。
对象属性:
- dropEffect:设置或返回拖放目标上允许发生的拖放行为。如果此处设置的拖放行为不再effectAllowed属性设置的多种拖放行为之内,拖放操作将会失败。该属性值只允许为“null”、“copy”、“link”和“move”四值之一。
- effectAllowed:设置或返回被拖动元素允许发生的拖动行为。该属性值可设为“none”、“copy”、“copyLink”、“copyMove”、“link”、“linkMove”、“move”、“all”和“uninitialized”。
- items:该属性返回DataTransferItems对象,该对象代表了拖动数据。
- types:该属性返回一个DOMStringList对象,该对象包括了存入dataTransfer中数据的所有类型。
对象方法:
- setData(format,data):将指定格式的数据赋值给dataTransfer对象,参数format定义数据的格式也就是数据的类型,data为待赋值的数据
- getData(format):从dataTransfer对象中获取指定格式的数据,format代表数据格式,data为数据。
- clearData([format]):从dataTransfer对象中删除指定格式的数据,参数可选,若不给出,则为删除对象中所有的数据。
- addElement(element):添加自定义图标
- setDragImage(element,x,y):设置拖放操作的自定义图标。其中element设置自定义图标,x设置图标与鼠标在水平方向上的距离,y设置图标与鼠标在垂直方向上的距离。
基础
这一部分提供了将拖放功能添加到应用程序的基本步骤的摘要。每节内容包含描述、简短的代码案例,以及额外的知识的链接。
确定什么是可拖动的
让一个元素被拖动需要添加draggable
属性,再加上全局事件处理函数ondragstart
,如下面的示例代码所示:
function dragstart_handler(ev) { // Add the target element's id to the data transfer object ev.dataTransfer.setData("text/plain", ev.target.innerText); }This element is draggable.
定义拖动数据
应用程序可以在拖动操作中包含任意数量的数据项。每个数据项都是一个string
类型,典型的 MIME 类型,如:text/html
。
每个drag event
都有一个dataTransfer
属性保保存事件的数据。这个属性(DataTransfer
对象)也有管理拖动数据的方法。setData()
方法添加一个项目的拖拽数据,如下面的示例代码所示:
function dragstart_handler(ev) { // 添加拖拽数据 ev.dataTransfer.setData("text/plain", ev.target.innerText); ev.dataTransfer.setData("text/html", ev.target.outerHTML); ev.dataTransfer.setData("text/uri-list", ev.target.ownerDocument.location.href); }
查看推荐拖动类型了解可拖拽的通用数据类型(如文本、HTML、链接和文件),移步拖动数据获取更多有关拖动数据的信息
定义拖动图像
拖动过程中,浏览器会在鼠标旁显示一张默认图片。当然,应用程序也可以通过setDragImage()
方法自定义一张图片,如下面的例子所示。
function dragstart_handler(ev) { // Create an image and then use it for the drag image. // NOTE: change "example.gif" to a real image URL or the image // will not be created and the default drag image will be used. var img = new Image(); img.src = 'example.gif'; ev.dataTransfer.setDragImage(img, 10, 10); }
定义拖动效果
dropEffect
属性用来控制拖放操作中用户给予的反馈。它会影响到拖动过程中浏览器显示的鼠标样式。比如,当用户悬停在目标元素上的时候,浏览器鼠标也许要反映拖放操作的类型。
有 3 个效果可以定义:
copy
表明被拖动的数据将从它原本的位置拷贝到目标的位置。move
表明被拖动的数据将被移动。link
表明在拖动源位置和目标位置之间将会创建一些关系表格或是连接。
在拖动过程中,拖动效果也许会被修改以用于表明在具体位置上具体效果是否被允许,如果允许,在该位置则被允许放置。
以下例子表明如何使用该属性。
function dragstart_handler(ev) { ev.dataTransfer.dropEffect = "copy"; }
定义一个放置区
当拖动一个项目到 HTML 元素中时,浏览器默认不会有任何响应。想要让一个元素变成可释放区域,该元素必须设置ondragover
和ondrop
事件处理程序属性,下面的例子通过简单的事件处理展示了如何使用这些属性,
function dragover_handler(ev) { ev.preventDefault(); ev.dataTransfer.dropEffect = "move"; } function drop_handler(ev) { ev.preventDefault(); // Get the id of the target and add the moved element to the target's DOM var data = ev.dataTransfer.getData("text/plain"); ev.target.appendChild(document.getElementById(data)); }Drop Zone
注意每个处理程序调用preventDefault()
来阻止对这个事件的其它处理过程(如触点事件或指针事件)。
处理放置效果
drop
事件的处理程序是以程序指定的方法处理拖动数据。一般,程序调用getData()
方法取出拖动项目并按一定方式处理。程序意义根据dropEffect
的值与/或可变更关键字的状态而不同
下面的例子展示了一个处理程序,从拖动数据中获取事件源元素的id然后根据id移动源元素到目标元素
function dragstart_handler(ev) { // Add the target element's id to the data transfer object ev.dataTransfer.setData("application/my-app", ev.target.id); ev.dataTransfer.dropEffect = "move"; } function dragover_handler(ev) { ev.preventDefault(); ev.dataTransfer.dropEffect = "move" } function drop_handler(ev) { ev.preventDefault(); // Get the id of the target and add the moved element to the target's DOM var data = ev.dataTransfer.getData("application/my-app"); ev.target.appendChild(document.getElementById(data)); }This element is draggable.
Drop Zone
拖动结束
拖动操作结束时,在源元素(开始拖动时的目标元素)上触发dragend
事件。不管拖动是完成还是被取消这个事件都会被触发。dragend
事件处理程序可以检查dropEffect
属性的值来确认拖动成功与否。
互操作性
在数据交换对象接口的浏览器兼容性表中可以看到拖放在桌面浏览器中相对支持得比较完整(除了DataTransferItem
和DataTransferItemList
接口支持得较少)。这个数据也显示出拖放操作在移动浏览器中支持得非常弱。
鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com
图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!