网页开发者版 — 最后更新于 2024年9月12日
所有当前引擎都支持。
本节定义了一种基于事件的拖放机制。
本规范没有定义拖放操作究竟是什么。
在具有指向设备的可视媒体上,拖动操作可能是mousedown
事件的默认操作,后面跟着一系列mousemove
事件,释放鼠标可以触发放下操作。
当使用除指向设备以外的输入模式时,用户可能需要明确指示其执行拖放操作的意图,分别说明他们希望拖动什么以及希望将其放在哪里。
要使元素可拖动,请为元素提供一个draggable
属性,并为dragstart
设置一个事件监听器,以存储正在拖动的的数据。
事件处理程序通常需要检查它是否不是正在拖动的文本选择,然后需要将数据存储到DataTransfer
对象中并设置允许的效果(复制、移动、链接或某些组合)。
例如
< p > What fruits do you like?</ p >
< ol ondragstart = "dragStartHandler(event)" >
< li draggable = "true" data-value = "fruit-apple" > Apples</ li >
< li draggable = "true" data-value = "fruit-orange" > Oranges</ li >
< li draggable = "true" data-value = "fruit-pear" > Pears</ li >
</ ol >
< script >
var internalDNDType = 'text/x-example' ; // set this to something specific to your site
function dragStartHandler( event) {
if ( event. target instanceof HTMLLIElement) {
// use the element's data-value="" attribute as the value to be moving:
event. dataTransfer. setData( internalDNDType, event. target. dataset. value);
event. dataTransfer. effectAllowed = 'move' ; // only allow moves
} else {
event. preventDefault(); // don't allow selection to be dragged
}
}
</ script >
要接受放下操作,放下目标必须监听以下事件
dragenter
事件处理程序通过取消事件来报告放下目标是否可能愿意接受放下操作。dragover
事件处理程序通过设置与事件关联的DataTransfer
的dropEffect
属性来指定将向用户显示什么反馈。此事件也需要被取消。drop
事件处理程序最后有机会接受或拒绝放下操作。如果接受放下操作,则事件处理程序必须在目标上执行放下操作。此事件需要被取消,以便dropEffect
属性的值可以被源使用。否则,放下操作将被拒绝。例如
< p > Drop your favorite fruits below:</ p >
< ol ondragenter = "dragEnterHandler(event)" ondragover = "dragOverHandler(event)"
ondrop = "dropHandler(event)" >
</ ol >
< script >
var internalDNDType = 'text/x-example' ; // set this to something specific to your site
function dragEnterHandler( event) {
var items = event. dataTransfer. items;
for ( var i = 0 ; i < items. length; ++ i) {
var item = items[ i];
if ( item. kind == 'string' && item. type == internalDNDType) {
event. preventDefault();
return ;
}
}
}
function dragOverHandler( event) {
event. dataTransfer. dropEffect = 'move' ;
event. preventDefault();
}
function dropHandler( event) {
var li = document. createElement( 'li' );
var data = event. dataTransfer. getData( internalDNDType);
if ( data == 'fruit-apple' ) {
li. textContent = 'Apples' ;
} else if ( data == 'fruit-orange' ) {
li. textContent = 'Oranges' ;
} else if ( data == 'fruit-pear' ) {
li. textContent = 'Pears' ;
} else {
li. textContent = 'Unknown Fruit' ;
}
event. target. appendChild( li);
}
</ script >
要从显示中删除原始元素(即被拖动的元素),可以使用dragend
事件。
对于我们这里的示例,这意味着更新原始标记以处理该事件
< p > What fruits do you like?</ p >
< ol ondragstart = "dragStartHandler(event)" ondragend = "dragEndHandler(event)" >
...as before...
</ ol >
< script >
function dragStartHandler( event) {
// ...as before...
}
function dragEndHandler( event) {
if ( event. dataTransfer. dropEffect == 'move' ) {
// remove the dragged element
event. target. parentNode. removeChild( event. target);
}
}
</ script >
构成拖放操作基础的数据,称为拖放数据存储,包含以下信息
一个拖放数据存储项列表,它是一个表示拖动数据的项列表,每个项包含以下信息
数据的类型
文本。
带有文件名的二进制数据。
一个 Unicode 字符串,给出数据的类型或格式,通常由MIME 类型给出。出于遗留原因,某些不是MIME 类型的值是特殊处理的。API 不强制使用MIME 类型;也可以使用其他值。但是,在所有情况下,API 都会将这些值转换为 ASCII 小写。
每个项类型字符串最多只能有一个文本项。
一个 Unicode 或二进制字符串,在某些情况下带有文件名(本身是一个 Unicode 字符串),根据拖放数据项类型。
拖放数据存储项列表按照项添加到列表中的顺序排序;最近添加的项位于最后。
以下信息用于在拖动过程中生成 UI 反馈
一个拖放数据存储模式,它可以是以下之一
一个拖放数据存储允许效果状态,它是一个字符串。
当拖放数据存储创建时,必须对其进行初始化,使其拖放数据存储项列表为空,没有拖放数据存储默认反馈,没有拖放数据存储位图和拖放数据存储热点坐标,其拖放数据存储模式为保护模式,其拖放数据存储允许效果状态为字符串“uninitialized
”。
DataTransfer
接口所有当前引擎都支持。
DataTransfer
对象用于公开构成拖放操作基础的拖放数据存储。
dataTransfer = new DataTransfer()
创建一个新的DataTransfer
对象,并带有一个空的拖放数据存储。
dataTransfer.dropEffect [ = value ]
返回当前选定的操作类型。如果操作类型不是effectAllowed
属性允许的操作类型之一,则操作将失败。
可以设置,以更改选定的操作。
可能的值为“none
”、“copy
”、“link
”和“move
”。
dataTransfer.effectAllowed [ = value ]
返回要允许的操作类型。
可以设置(在dragstart
事件期间),以更改允许的操作。
可能的值为“none
”、“copy
”、“copyLink
”、“copyMove
”、“link
”、“linkMove
”、“move
”、“all
”和“uninitialized
”,
dataTransfer.items
返回一个DataTransferItemList
对象,其中包含拖放数据。
dataTransfer.setDragImage(element, x, y)
使用给定的元素更新拖动反馈,替换任何先前指定的反馈。
dataTransfer.types
返回一个冻结数组,其中列出了在dragstart
事件中设置的格式。此外,如果正在拖动任何文件,则其中一个类型将是字符串“Files
”。
data = dataTransfer.getData(format)
返回指定的数据。如果没有此类数据,则返回空字符串。
dataTransfer.setData(format, data)
添加指定的数据。
dataTransfer.clearData([ format ])
删除指定格式的数据。如果省略参数,则删除所有数据。
dataTransfer.files
返回一个FileList
,其中包含正在拖动的文件(如果有)。
作为拖放事件的一部分创建的DataTransfer
对象仅在触发这些事件时有效。
DataTransferItemList
接口所有当前引擎都支持。
每个 DataTransfer
对象都关联着一个 DataTransferItemList
对象。
items.length
返回拖放数据存储区中的项目数量。
items[index]
返回表示拖放数据存储区中第 index 个条目的 DataTransferItem
对象。
items.remove(index)
移除拖放数据存储区中的第 index 个条目。
items.clear()
移除拖放数据存储区中的所有条目。
items.add(data)
items.add(data, type)
为给定的数据添加一个新条目到拖放数据存储区。如果数据是纯文本,则还需要提供一个 type 字符串。
DataTransferItem
接口所有当前引擎都支持。
每个 DataTransferItem
对象都关联着一个 DataTransfer
对象。
item.kind
返回拖放数据项类型,其中之一:“string”,“file”。
item.type
返回拖放数据项类型字符串。
item.getAsString(callback)
如果拖放数据项类型为“text”,则使用字符串数据作为参数调用回调函数。
file = item.getAsFile()
返回一个 File
对象,如果拖放数据项类型为“File”。
DragEvent
接口所有当前引擎都支持。
所有当前引擎都支持。
拖放处理模型涉及多个事件。它们都使用 DragEvent
接口。
event.dataTransfer
返回事件的 DataTransfer
对象。
尽管为了与其他事件接口保持一致,DragEvent
接口有一个构造函数,但它并不是特别有用。特别是,无法从脚本创建有用的 DataTransfer
对象,因为 DataTransfer
对象具有由浏览器在拖放过程中协调的处理和安全模型。
以下事件参与拖放模型。
事件名称 | 目标 | 可取消? | 拖放数据存储模式 | dropEffect | 默认操作 |
---|---|---|---|---|---|
dragstart 所有当前引擎都支持。 Firefox9+Safari3.1+Chrome1+ Opera12+Edge79+ Edge (遗留)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ | 源节点 | ✓ 可取消 | 读写模式 | "none " | 启动拖放操作 |
drag 所有当前引擎都支持。 Firefox9+Safari3.1+Chrome1+ Opera12+Edge79+ Edge (遗留)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ | 源节点 | ✓ 可取消 | 保护模式 | "none " | 继续拖放操作 |
dragenter 所有当前引擎都支持。 Firefox9+Safari3.1+Chrome1+ Opera12+Edge79+ Edge (遗留)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ | 用户立即选择 或 body 元素 | ✓ 可取消 | 保护模式 | 基于 effectAllowed 值 | 拒绝 用户立即选择 作为潜在的 目标元素 |
dragleave 所有当前引擎都支持。 Firefox9+Safari3.1+Chrome1+ Opera12+Edge79+ Edge (遗留)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ | 上一个目标元素 | — | 保护模式 | "none " | 无 |
dragover 所有当前引擎都支持。 Firefox9+Safari3.1+Chrome1+ Opera12+Edge79+ Edge (遗留)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ | 当前目标元素 | ✓ 可取消 | 保护模式 | 基于 effectAllowed 值 | 将 当前拖放操作 重置为“none” |
drop 所有当前引擎都支持。 Firefox9+Safari3.1+Chrome1+ Opera12+Edge79+ Edge (遗留)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ | 当前目标元素 | ✓ 可取消 | 只读模式 | 当前拖放操作 | 变化 |
dragend 所有当前引擎都支持。 Firefox9+Safari3.1+Chrome1+ Opera12+Edge79+ Edge (遗留)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ | 源节点 | — | 保护模式 | 当前拖放操作 | 变化 |
所有这些事件都会冒泡,并且是组合的,并且 effectAllowed
属性始终具有在 dragstart
事件之后具有的值,在 dragstart
事件中默认为“uninitialized
”。
draggable
属性所有当前引擎都支持。
所有 HTML 元素 都可以设置 draggable
内容属性。 draggable
属性是一个 枚举属性,具有以下关键字和状态
关键字 | 状态 | 简要描述 |
---|---|---|
true
| true | 元素可拖动。 |
false
| false | 元素不可拖动。 |
属性的 缺失值默认值 和 无效值默认值 均为 auto 状态。auto 状态使用用户代理的默认行为。
具有 draggable
属性的元素也应该具有一个 title
属性,该属性以非视觉交互的目的命名元素。
element.draggable [ = value ]
如果元素可拖动,则返回 true;否则,返回 false。
可以设置,以覆盖默认值并设置 draggable
内容属性。