原文链接
魔改了下大佬的代码。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>拖动</title>
<style>
h2 {
font-size: 20px;
color: #0d88c1;
}
div#left,
div#right {
width: 120px;
float: left;
margin: 10px 100px 10px 0px;
height: 240px;
background-color: #dddddd;
overflow-y: auto;
}
div label {
font-size: 22px;
font-weight: bold;
width: 100%;
display: inline-block;
padding: 4px 0;
text-align: center;
margin: 0px 0 2px 0;
color: #fff;
background-color: #0d88c1;
}
.over {
border: 1px dashed red;
box-sizing: border-box;
}
</style>
</head>
<body>
<h2>拖放(Drag 和 drop)</h2>
<!-- 左边元素框 -->
<div id="left" class="drag-container1">
<label draggable="true" class>index1</label>
<label draggable="true" class>index2</label>
<label draggable="true" class>index3</label>
<label draggable="true" class>index4</label>
<label draggable="true" class>index5</label>
<label draggable="true" class>index6</label>
<label draggable="true" class>index7</label>
</div>
<!-- 右边元素框 -->
<div id="right" class="drag-container1"></div>
<script>
(async () => {
let container1DragElement = null;
const containerName = "drag-container1";
// 获取元素 selector
function getSelector(el) {
var tag, index = 1, stack = [];
for (; el.parentNode; el = el.parentNode) {
tag = el.tagName;
if (tag != "HTML") {
for (child of el.parentNode.children) {
if (child == el) {
break;
} else {
index++;
}
}
if (tag == "BODY") {
stack.unshift(tag);
} else {
stack.unshift(tag + ':nth-child(' + index + ')');
}
}
}
return stack.join(' > ');
}
/**
* 判断是否是容器
*/
function isContainer(ele) {
return ele && ele.classList.contains(containerName);
}
function findContainer(ele) {
var container = ele;
while (true) {
if (container.tagName == "HTML") {
return isContainer(container);
}
if (container.classList.contains(containerName)) {
return container;
}
container = container.parentNode;
}
return container;
}
var moveItem = document.getElementsByTagName('label');
for (let i = 0; i < moveItem.length; i++) {
//动态设置label元素id
moveItem[i].setAttribute('id', 'label' + i);
moveItem[i].ondragstart = function (ev) {
//dataTransfer.setData() 方法设置被拖数据的数据类型和值
container1DragElement = this;
{ {/* ev.dataTransfer.setData("dragElementSelector", getSelector(this)); */ } }
ev.dataTransfer.setData("offsetX", getSelector(ev.offsetX));
ev.dataTransfer.setData("offsetY", getSelector(ev.offsetY));
};
}
const containers = document.querySelectorAll(".drag-container1");
containers.forEach(container => {
// 阻止向上冒泡
container.ondragover = ev => ev.preventDefault();
container.ondragenter = ev => ev.target.classList.add('over');
container.ondragleave = ev => ev.target.classList.remove('over');
container.ondrop = function (ev) {
ev.preventDefault();
ev.target.classList.remove('over');
let container = null;
if (isContainer(ev.toElement)) {
//如果为container,元素放置在末尾
container = ev.toElement;
container.appendChild(container1DragElement);
} else {
container = findContainer(ev.toElement);
if (!container) {
console.warn("没有找到目标容器,无法执行拖拽操作");
return;
}
if (ev.toElement.nextElementSibling) {
console.log("ev.toElement.nextElementSibling", ev.toElement.nextElementSibling);
console.log("container1DragElement", container1DragElement);
if (ev.toElement.nextElementSibling == container1DragElement) {
// 如果是两个相邻的标签,则交换这两个标签
container.insertBefore(ev.toElement.nextElementSibling, ev.toElement);
} else {
container.insertBefore(container1DragElement, ev.toElement.nextElementSibling);
}
} else {
container.appendChild(container1DragElement);
}
}
}
});
})();
</script>
</body>
</html>
···
### 参考资料
[JavaScript进阶之实现拖拽(上)](https://juejin.cn/post/6844904158273765384)
[https://www.nhooo.com/note/qadmbg.html](https://www.nhooo.com/note/qadmbg.html)