<ul class="droplist" id="droplist">
<li class="dragitem" draggable="true">item01</li>
<li class="dragitem" draggable="true">item02</li>
<li class="dragitem" draggable="true">item03</li>
<li class="dragitem" draggable="true">item04</li>
</ul>
.droplist {
max-width: 500px;
border: 10px solid #f1f1f1;
padding: 10px;
}
.dragitem {
display: flex;
align-items: center;
list-style: none;
padding: 10px;
height: 40px;
color: #fff;
background: slateblue;
}
.dragitem:not(:first-child) {
margin-top: 10px;
}
var currentDragItem = null;
var offsetY = 0;
document.querySelectorAll("#droplist>.dragitem").forEach(function (el) {
el.addEventListener(
"dragstart",
function (ev) {
offsetY = ev.offsetY;
currentDragItem = this;
},
true
);
el.addEventListener("dragend", function (ev) {
currentDragItem = null;
});
});
droplist.ondragover = function (ev) {
ev.preventDefault();
if (!currentDragItem) return;
var dragitem = ev.target.closest(".dragitem");
dragitem &&
dragitem[ev.offsetY > offsetY ? "after" : "before"](currentDragItem);
};
// 下面代码是用来美化拖拽效果
if ("setDragImage" in window.DataTransfer.prototype && document.body.animate) {
var cloneObj = null;
var offsetX = 0;
var offsetY = 0;
var startX = 0;
var startY = 0;
var dragbox = null;
var lastDrop = null;
var axis, _axis;
var previewImage = new Image();
previewImage.src =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAQSURBVHgBAQUA+v8AAAAAAAAFAAFkeJU4AAAAAElFTkSuQmCC";
var styles = document.createElement("style");
styles.textContent =
"[dragging]{position:static!important;box-sizing:border-box!important;margin:0!important;}\
.drag-obj{position:fixed;left:0;top:0;z-index:999;pointer-events:none;}";
document.querySelector("head").appendChild(styles);
document.addEventListener("dragstart", function (ev) {
if (ev.target.nodeType === Node.ELEMENT_NODE) {
dragbox = ev.target;
dragbox.dragData = {};
axis = dragbox.getAttribute("axis");
_axis = axis;
ev.dataTransfer.setData("text", "");
ev.dataTransfer.setDragImage(previewImage, 0, 0);
var rect = dragbox.getBoundingClientRect();
var left = rect.left;
var top = rect.top;
startX = ev.clientX;
startY = ev.clientY;
offsetX = startX - left;
offsetY = startY - top;
dragbox.style.transition = "none";
cloneObj = document.createElement("DIV");
var fakeObj = dragbox.cloneNode(true);
fakeObj.style.width = dragbox.offsetWidth + "px";
fakeObj.style.height = dragbox.offsetHeight + "px";
fakeObj.style.transform = "translate3d(0,0,0)";
fakeObj.setAttribute("dragging", "");
cloneObj.appendChild(fakeObj);
cloneObj.className = "drag-obj";
cloneObj.style = "transform:translate3d( " + left + "px ," + top + "px,0);";
// console.log(cloneObj)
document.body.appendChild(cloneObj);
}
});
document.addEventListener("dragend", function (ev) {
if (cloneObj) {
var rect = ev.target.getBoundingClientRect();
var left = rect.left;
var top = rect.top;
var reset = cloneObj.animate(
[
{
transform: cloneObj.style.transform
},
{
transform: "translate3d(" + left + "px," + top + "px,0)"
}
],
{
duration: 150,
easing: "ease-in-out"
}
);
reset.onfinish = function () {
document.body.removeChild(cloneObj);
cloneObj = null;
dragbox.dragData = null;
dragbox.style.visibility = "visible";
};
}
});
document.addEventListener("drop", function (ev) {
const dropbox = ev.target.closest("[allowdrop]");
ev.preventDefault();
if (dropbox) {
ev.stopPropagation();
dropbox.removeAttribute("over");
}
});
document.addEventListener("dragenter", function (ev) {
if (lastDrop) {
lastDrop.toggleAttribute("over", false);
}
const dropbox = ev.target.closest("[allowdrop]"); // 获取最近的放置目标
if (dropbox) {
dropbox.toggleAttribute("over", true);
lastDrop = dropbox;
}
});
document.addEventListener("dragover", function (ev) {
ev.preventDefault();
const dropbox = ev.target.closest("[allowdrop]");
if (dropbox) {
ev.dataTransfer.dropEffect = "copy";
} else {
ev.dataTransfer.dropEffect = "move";
}
if (cloneObj) {
dragbox.style.visibility = "hidden";
var left = ~~(ev.clientX - offsetX);
var top = ~~(ev.clientY - offsetY);
if (ev.shiftKey || axis) {
if (_axis === "X") {
top = ~~(startY - offsetY);
} else if (_axis === "Y") {
left = ~~(startX - offsetX);
} else {
_axis =
(~~Math.abs(ev.clientX - startX) > ~~Math.abs(ev.clientY - startY) &&
"X") ||
(~~Math.abs(ev.clientX - startX) < ~~Math.abs(ev.clientY - startY) &&
"Y") ||
"";
}
} else {
_axis = "";
}
startX = left + offsetX;
startY = top + offsetY;
cloneObj.style.transform = "translate3d( " + left + "px ," + top + "px,0)";
dragbox.dragData.left = left;
dragbox.dragData.top = top;
}
});
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.