HTML 拖放 API
HTML 拖放接口使应用程序能够在浏览器中使用拖放功能。
用户可以使用鼠标选择可拖动元素,将这些元素拖到可放置元素上,然后通过释放鼠标按钮将其放下。在拖动操作期间,可拖动元素的半透明表示形式跟随指针。
您可以自定义哪些元素可以变成可拖动的,可拖动元素产生的反馈类型以及可放置元素。
此 HTML 拖放概述包括接口的描述、向应用程序添加拖放支持的基本步骤以及接口的互操作性摘要。
概念和用法
拖动事件
HTML 拖放使用DOM 事件模型和从鼠标事件继承的拖动事件。典型的拖动操作始于用户选择可拖动元素,当用户将元素拖到可放置元素上时继续,然后在用户释放拖动的元素时结束。
在拖动操作期间,会触发几种事件类型,并且某些事件可能会触发多次,例如drag
和dragover
事件。
每个拖动事件类型都有一个关联的事件处理程序
事件 | 在...时触发 |
---|---|
drag |
...拖动项(元素或文本选择)被拖动。 |
dragend |
...拖动操作结束(例如释放鼠标按钮或按 Esc 键;请参阅完成拖动)。 |
dragenter |
...拖动项进入有效的放置目标。(请参阅指定放置目标)。 |
dragleave |
...拖动项离开有效的放置目标。 |
dragover |
...拖动项正在拖动到有效的放置目标上,每隔几百毫秒。 |
dragstart |
...用户开始拖动项目。(请参阅开始拖动操作)。 |
drop |
...项目被放置到有效的放置目标上。(请参阅执行放置)。 |
注意:从操作系统将文件拖动到浏览器中时,不会触发dragstart
或dragend
事件。
基础知识
本节总结了向应用程序添加拖放功能的基本步骤。
识别可拖动对象
要使元素可拖动,需要添加draggable
属性和dragstart
事件处理程序,如下面的代码示例所示
<script>
function dragstartHandler(ev) {
// Add the target element's id to the data transfer object
ev.dataTransfer.setData("text/plain", ev.target.id);
}
window.addEventListener("DOMContentLoaded", () => {
// Get the element by id
const element = document.getElementById("p1");
// Add the ondragstart event listener
element.addEventListener("dragstart", dragstartHandler);
});
</script>
<p id="p1" draggable="true">This element is draggable.</p>
有关更多信息,请参阅
定义拖动的的数据
应用程序可以自由地在拖动操作中包含任意数量的数据项。每个数据项都是特定type
的字符串——通常是 MIME 类型,例如text/html
。
每个DragEvent
都有一个dataTransfer
属性,该属性保存事件的数据。此属性(它是DataTransfer
对象)还具有管理拖动数据的方法。setData()
方法用于将项目添加到拖动数据中,如下例所示。
function dragstartHandler(ev) {
// Add different types of drag data
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,
);
}
定义拖动图像
默认情况下,浏览器会提供一个在拖动操作期间出现在指针旁边的图像。但是,应用程序可以使用setDragImage()
方法定义自定义图像,如下例所示。
// 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.
let img = new Image();
img.src = "example.gif";
function dragstartHandler(ev) {
ev.dataTransfer.setDragImage(img, 10, 10);
}
详细了解拖动反馈图像,请参阅
定义放置效果
dropEffect
属性用于控制用户在拖放操作期间获得的反馈。它通常会影响浏览器在拖动时显示的光标。例如,当用户将鼠标悬停在放置目标上时,浏览器的光标可能会指示将发生的操作类型。
可以定义三种效果
copy
表示将拖动的数据从其当前位置复制到放置位置。move
表示将拖动的数据从其当前位置移动到放置位置。link
表示将在源位置和放置位置之间创建某种形式的关系或连接。
在拖动操作期间,可以修改拖动效果以指示在某些位置允许某些效果。
以下示例显示了如何使用此属性。
function dragstartHandler(ev) {
ev.dataTransfer.dropEffect = "copy";
}
有关更多详细信息,请参阅
定义放置区域
默认情况下,浏览器会阻止将任何内容放置到大多数 HTML 元素上时发生任何事情。要更改此行为,使元素成为放置区域或可放置,该元素必须同时侦听dragover
和drop
事件。
以下示例显示了如何使用这些属性,并包含每个属性的基本事件处理程序。
<script>
function dragoverHandler(ev) {
ev.preventDefault();
ev.dataTransfer.dropEffect = "move";
}
function dropHandler(ev) {
ev.preventDefault();
// Get the id of the target and add the moved element to the target's DOM
const data = ev.dataTransfer.getData("text/plain");
ev.target.appendChild(document.getElementById(data));
}
</script>
<p id="target" ondrop="dropHandler(event)" ondragover="dragoverHandler(event)">
Drop Zone
</p>
请注意,每个处理程序都会调用preventDefault()
以防止对此事件进行其他事件处理(例如触摸事件或指针事件)。
有关更多信息,请参阅
处理放置效果
drop
事件的处理程序可以以应用程序特定的方式处理拖动数据。
通常,应用程序使用getData()
方法检索拖动项目,然后相应地处理它们。此外,应用程序语义可能因dropEffect
的值和/或修饰键的状态而异。
以下示例显示了一个放置处理程序从拖动数据中获取源元素的id
,然后使用id
将源元素移动到放置元素
<script>
function dragstartHandler(ev) {
// Add the target element's id to the data transfer object
ev.dataTransfer.setData("application/my-app", ev.target.id);
ev.dataTransfer.effectAllowed = "move";
}
function dragoverHandler(ev) {
ev.preventDefault();
ev.dataTransfer.dropEffect = "move";
}
function dropHandler(ev) {
ev.preventDefault();
// Get the id of the target and add the moved element to the target's DOM
const data = ev.dataTransfer.getData("application/my-app");
ev.target.appendChild(document.getElementById(data));
}
</script>
<p id="p1" draggable="true" ondragstart="dragstartHandler(event)">
This element is draggable.
</p>
<div
id="target"
ondrop="dropHandler(event)"
ondragover="dragoverHandler(event)">
Drop Zone
</div>
有关更多信息,请参阅
拖动结束
在拖动操作结束时,dragend
事件将在源元素(即拖动开始的目标元素)上触发。
无论拖动是否完成或被取消,此事件都会触发。dragend
事件处理程序可以检查dropEffect
属性的值以确定拖动操作是否成功。
有关处理拖动操作结束的更多信息,请参阅
接口
HTML 拖放接口是DragEvent
、DataTransfer
、DataTransferItem
和DataTransferItemList
。
DragEvent
接口有一个构造函数和一个dataTransfer
属性,该属性是DataTransfer
对象。
DataTransfer
对象包含拖动事件的状态,例如正在执行的拖动类型(如copy
或move
)、拖动的数据(一个或多个项目)以及每个拖动项目的 MIME 类型。DataTransfer
对象还具有将项目添加到或从拖动数据中删除的方法。
DragEvent
和DataTransfer
接口应该是向应用程序添加 HTML 拖放功能所需的唯一接口。
每个 DataTransfer
对象都包含一个 items
属性,该属性是一个 list
,其中包含 DataTransferItem
对象。一个 DataTransferItem
对象代表一个单独的拖动项,每个拖动项都有一个 kind
属性(string
或 file
)和一个 type
属性,用于表示数据项的 MIME 类型。 DataTransferItem
对象还提供方法来获取拖动项的数据。
DataTransferItemList
对象是一个 DataTransferItem
对象列表。列表对象提供方法用于将拖动项添加到列表中,从列表中删除拖动项,以及清除列表中的所有拖动项。
DataTransfer
和 DataTransferItem
接口之间的关键区别在于,前者使用同步的 getData()
方法来访问拖动项的数据,而后者则使用异步的 getAsString()
方法。
注意:DragEvent
和 DataTransfer
在桌面浏览器上得到广泛支持。但是,DataTransferItem
和 DataTransferItemList
接口的浏览器支持有限。有关拖放互操作性的更多信息,请参阅 互操作性。
示例
- 使用
DataTransfer
接口复制和移动元素 - 使用
DataTransferListItem
接口复制和移动元素 - 拖放文件(仅限 Firefox):https://jsfiddle.net/9C2EF/
- 拖放文件(所有浏览器):https://jsbin.com/hiqasek/
- 一个使用拖放 API 的停车项目:https://park.glitch.me/(您可以在 此处 编辑)
规范
规范 |
---|
HTML 标准 |