介绍
拖放是一种常见的用户交互,您可以在许多图形用户界面中找到它。
已有 JavaScript 库可用于向您的应用程序添加拖放功能。但是,可能存在库不可用或引入项目不需要的开销或依赖项的情况。在这些情况下,了解现代 Web 浏览器中可用的 API 可以提供替代解决方案。
该HTML拖放API依赖于DOM的事件模型我们就可以得到被拖动或下降,以更新拖动或丢弃元素信息。使用 JavaScript 事件处理程序,您可以将任何元素变成可拖动的项目或可以放入的项目。
在本教程中,我们将使用 HTML Drag and Drop API 和 vanilla JavaScript 构建一个拖放示例,以使用事件处理程序。
先决条件
要完成本教程,您需要:
- 支持拖放 API(Chrome 4+、Firefox 3.5+、Safari 3.1+、Edge 18+)的现代 Web 浏览器。
步骤 1 — 创建项目和初始标记
我们的项目将包含一个容器,其中包含两种类型的子元素:
- 可以拖动的子元素
- 可以将元素放入其中的子元素
首先,打开终端窗口并创建一个新的项目目录:
- mkdir drag-and-drop-example
接下来,导航到该目录:
- cd drag-and-drop-example
然后,index.html
在该目录中创建一个文件:
- nano index.html
接下来,为 HTML 网页添加样板代码:
<!DOCTYPE html>
<html>
<head>
<title>My Drag-and-Drop Example</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
</body>
</html>
在<body>
标签之间添加您的draggable
项目和您的dropzone
(放置目标):
<div class="example-parent">
<div class="example-origin">
<div
id="draggable-1"
class="example-draggable"
>
draggable
</div>
</div>
<div
class="example-dropzone"
>
dropzone
</div>
</div>
保存并关闭文件。然后,创建一个style.css
文件:
- nano style.css
接下来,为我们index.html
文件中的元素添加样式:
.example-parent {
border: 2px solid #DFA612;
color: black;
display: flex;
font-family: sans-serif;
font-weight: bold;
}
.example-origin {
flex-basis: 100%;
flex-grow: 1;
padding: 10px;
}
.example-draggable {
background-color: #4AAE9B;
font-weight: normal;
margin-bottom: 10px;
margin-top: 10px;
padding: 10px;
}
.example-dropzone {
background-color: #6DB65B;
flex-basis: 100%;
flex-grow: 1;
padding: 10px;
}
这将为应用程序添加一些格式。现在您可以index.html
在浏览器中查看并观察这会产生 adraggable
<div>
和 a dropzone
<div>
。
接下来,我们将<div>
通过添加draggable
属性明确地使第一个可拖动:
<div class="example-parent">
<div class="example-origin">
<div
id="draggable-1"
class="example-draggable"
draggable="true"
>
draggable
</div>
</div>
<div
class="example-dropzone"
>
dropzone
</div>
</div>
保存并关闭文件。
最后,index.html
再次在浏览器中查看。如果我们点击draggable
<div>
并在屏幕上拖动它,应该有它移动的视觉指示。
该draggable
属性的默认值为auto
。这意味着元素是否可拖动将由浏览器的默认行为决定。通常,这意味着文本选择、图像和链接无需指定即可拖动draggable="true"
。
您现在有一个带有可拖动元素的 HTML 文件。我们将继续添加onevent
处理程序。
第 2 步 – 使用 JavaScript 处理拖放事件
目前,如果我们在拖动可拖动元素时释放鼠标,则不会发生任何事情。要在 DOM 元素上触发拖放操作,我们需要使用拖放 API:
ondragstart
:此事件处理程序将附加到我们的draggable
元素并在dragstart
事件发生时触发。ondragover
:此事件处理程序将附加到我们的dropzone
元素并在dragover
事件发生时触发。ondrop
:此事件处理程序也将附加到我们的dropzone
元素并在drop
事件发生时触发。
注:共有八个事件处理程序总数:ondrag
,ondragend
,ondragenter
,ondragexit
,ondragleave
,ondragover
,ondragstart
,和ondrop
。对于我们的示例,我们不会要求所有这些。
首先,让script.js
我们在我们的 中引用一个新文件index.html
:
<body>
...
<script src="script.js"></script>
</body>
接下来,创建一个新script.js
文件:
- nano script.js
该DataTransfer
对象将跟踪与当前发生的拖动相关的信息。要在拖放时更新我们的元素,我们需要直接访问该DataTransfer
对象。为此,我们可以dataTransfer
从 DOM 元素的DragEvent
.
注意:该DataTransfer
对象在技术上可以跟踪同时拖动的多个元素的信息。对于我们的示例,我们将专注于拖动一个元素。
该dataTransfer
对象的setData
方法可用于设置当前拖动元素的拖动状态信息。它需要两个参数:
- 声明第二个参数格式的字符串
- 正在传输的实际数据
我们的目标是将我们的draggable
元素移动到一个新的父元素。我们需要能够选择draggable
具有唯一性的元素id
。我们可以使用 方法设置id
拖动元素的 ,setData
以便稍后使用。
让我们重新访问我们的script.js
文件并创建一个新函数来使用setData
:
function onDragStart(event) {
event
.dataTransfer
.setData('text/plain', event.target.id);
}
注意:据报道,Internet Explorer 9 到 11 在使用'text/plain'
. 该'text'
浏览器需要该格式。
要更新拖动项的 CSS 样式,我们可以再次使用 DOM 事件访问其样式,并为currentTarget
.
让我们添加到我们的函数并将其更改backgroundColor
为yellow
:
function onDragStart(event) {
event
.dataTransfer
.setData('text/plain', event.target.id);
event
.currentTarget
.style
.backgroundColor = 'yellow';
}
注意:如果您想要仅拖动样式,您更改的任何样式都需要在放置时再次手动更新。如果您在开始拖动时更改任何内容,则被拖动的元素将保持新样式,除非您将其更改回来。
现在,我们有了用于拖动开始时的 JavaScript 函数。
我们可以添加ondragstart
到draggable
元素中index.html
:
<div class="example-parent">
<div class="example-origin">
<div
id="draggable-1"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
draggable
</div>
</div>
<div class="example-dropzone">
dropzone
</div>
</div>
index.html
在浏览器中查看。如果您现在尝试拖动您的项目,将应用我们函数中声明的样式:
但是,当您释放您的点击时,什么也不会发生。
按此顺序触发的下一个事件处理程序是ondragover
。
<div>
浏览器中某些 DOM 元素(如s)的默认放置行为通常不接受放置。此行为将拦截我们试图实现的行为。为确保我们获得所需的丢弃行为,我们将应用preventDefault
.
让我们重新访问该script.js
文件并创建一个新函数以使用preventDefault
. 将此代码添加到文件末尾:
function onDragOver(event) {
event.preventDefault();
}
现在,我们可以添加ondragover
到我们的dropzone
元素中index.html
:
<div class="example-parent">
<div class="example-origin">
<div
id="draggable-1"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
draggable
</div>
</div>
<div
class="example-dropzone"
ondragover="onDragOver(event);"
>
dropzone
</div>
</div>
在这一点上,我们还没有写出处理实际掉落的代码。在此序列中触发的最终事件处理程序是ondrop
。
让我们重新访问我们的script.js
文件并创建一个新函数。
我们可以使用dataTransfer
object 的setData
方法引用我们之前保存的数据。我们将使用dataTransfer
对象的getData
方法。我们设置的数据是id
,所以这就是返回给我们的:
function onDrop(event) {
const id = event
.dataTransfer
.getData('text');
}
选择我们检索到的draggable
元素id
:
function onDrop(event) {
// ...
const draggableElement = document.getElementById(id);
}
选择我们的dropzone
元素:
function onDrop(event) {
// ...
const dropzone = event.target;
}
将我们的draggable
元素附加到dropzone
:
function onDrop(event) {
// ...
dropzone.appendChild(draggableElement);
}
重置我们的dataTransfer
对象:
function onDrop(event) {
// ...
event
.dataTransfer
.clearData();
}
现在,我们可以添加ondrop
到我们的dropzone
元素中index.html
:
<div class="example-parent">
<div class="example-origin">
<div
id="draggable-1"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
draggable
</div>
</div>
<div
class="example-dropzone"
ondragover="onDragOver(event);"
ondrop="onDrop(event);"
>
dropzone
</div>
</div>
一旦完成,我们就有了一个完整的拖放功能。index.html
在浏览器中查看并将draggable
元素拖动到dropzone
.
我们的示例处理单个可拖动项目和单个放置目标的场景。您可以拥有多个可拖动项目、多个放置目标,并使用所有其他拖放 API 事件处理程序对其进行自定义。
第 3 步 – 使用多个可拖动项目构建高级示例
下面是如何使用此 API 的另一个示例:带有可拖动任务的待办事项列表,您可以将其从一"To-do"
列移动到另一"Done"
列。
要创建您自己的待办事项列表,请添加更多具有唯一id
s 的可拖动元素到index.html
:
<div class="example-parent">
<h1>To-do list</h1>
<div class="example-origin">
To-do
<div
id="draggable-1"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
thing 1
</div>
<div
id="draggable-2"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
thing 2
</div>
<div
id="draggable-3"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
thing 3
</div>
<div
id="draggable-4"
class="example-draggable"
draggable="true"
ondragstart="onDragStart(event);"
>
thing 4
</div>
</div>
<div
class="example-dropzone"
ondragover="onDragOver(event);"
ondrop="onDrop(event);"
>
Done
</div>
</div>
index.html
在浏览器中查看并将待办事项列中的项目拖到完成列。您已经创建了一个待办事项应用程序并测试了该功能。
结论
在本文中,您创建了一个待办事项应用程序来探索适用于现代 Web 浏览器的拖放功能。
拖放 API 提供了多种选项,用于自定义除拖放之外的操作。例如,您可以更新拖动项目的 CSS 样式。此外,您可以选择复制可拖动项目,以便在放置时复制它,而不是移动项目。
请记住,虽然许多 Web 浏览器支持此技术,但如果您的受众包含不支持此功能的设备,您可能无法依赖它。
要了解有关使用拖放 API 可以放置的所有内容的更多信息,请查看MDN 的相关文档。