我的任务是创建拖放界面,用户在其中拖动一个元素,该元素会在很短的时间内改变其外观 - 直到它被放到目的地。
我想使用原生 Web API 来实现。我在MDN文档中找到了名为“dragstart”的事件。并准备了这个fiddle来演示该行为。
const source = document.getElementById("draggable");
source.addEventListener("dragstart", (event) => {
event.target.classList.add("dragging");
});
source.addEventListener("dragend", (event) => {
event.target.classList.remove("dragging");
});
body {
/* Prevent the user from selecting text in the example */
user-select: none;
}
#container {
width: 400px;
height: 20px;
background: blueviolet;
padding: 10px;
}
#draggable {
text-align: center;
background: white;
}
.dragging {
width: 422px;
color: red;
font-weight: 700;
}
<div id="container">
<div id="draggable" draggable="true">Drag me</div>
</div>
<div class="dropzone"></div>
但是结果还不够。在我的任务中,我需要默认元素来保留其外观并仅更改其拖动的最小化版本 - 理想情况下它应该更窄并显示与默认元素略有不同的内容。
如果您知道任何来源,该任务是在哪里解决的(无论如何),我很高兴收到您的回复。
您可以通过克隆可拖动元素来创建自己的幽灵元素,在其上应用自定义样式,将其附加到文档中,但将其移到屏幕之外以免看到重复的元素,使用setDragImage,最后从其中删除幽灵元素文件。
要显示图像以使指针位于其中心,请使用图像宽度和高度一半的值。
这样你就可以使用
event.dataTransfer.setDragImage(ghostEl, ghostEl.offsetWidth / 2, ghostEl.offsetHeight / 2);
为了将幽灵元素移动到屏幕之外,您可以使用绝对位置或变换属性:
transform: translateX(-100%);
最终代码:
const source = document.getElementById("draggable");
let ghostEl;
source.addEventListener("dragstart", (event) => {
ghostEl = event.target.cloneNode(true);
ghostEl.classList.add("ghost");
document.body.appendChild(ghostEl);
event.dataTransfer.setDragImage(ghostEl, ghostEl.offsetWidth / 2, ghostEl.offsetHeight / 2);
});
source.addEventListener("dragend", (event) => {
// reset the transparency
ghostEl.classList.remove("ghost");
document.body.removeChild(ghostEl);
});
body {
/* Prevent the user from selecting text in the example */
user-select: none;
}
#container {
width: 400px;
height: 20px;
background: blueviolet;
padding: 10px;
}
#draggable {
text-align: center;
background: white;
}
.ghost {
width: 422px;
color: red;
font-weight: 700;
transform: translateX(-100%);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>App</title>
</head>
<body>
<div id="container">
<div id="draggable" draggable="true">Drag me</div>
</div>
<div class="dropzone"></div>
</body>
</html>