js 左侧多个拖拽内容,拖拽其中一个dom到右侧,右侧dom判断拖拽到dom内,未释放前可进行排序,右侧dom可拖拽排序并添加移动动画,请用完整class 类代码实现
时间: 2024-01-10 14:02:49 浏览: 149
下面是一个完整的 JavaScript 类代码,实现了左侧多个拖拽内容,拖拽其中一个 DOM 到右侧,右侧 DOM 判断拖拽到 DOM 内,未释放前可进行排序,右侧 DOM 可拖拽排序并添加移动动画的功能。
```html
<!-- 左侧拖拽内容 -->
<div class="left">
<div class="box" draggable="true">Box 1</div>
<div class="box" draggable="true">Box 2</div>
<div class="box" draggable="true">Box 3</div>
</div>
<!-- 右侧拖拽容器 -->
<div class="right">
<div class="dropzone">Drop Here</div>
<div class="box-container"></div>
</div>
```
```css
.left {
display: flex;
flex-wrap: wrap;
}
.left .box {
width: 100px;
height: 100px;
background-color: #f0f0f0;
border: 1px solid #ccc;
margin: 10px;
}
.right {
display: flex;
align-items: center;
justify-content: center;
height: 300px;
background-color: #f5f5f5;
}
.right .dropzone {
width: 200px;
height: 50px;
background-color: #ccc;
text-align: center;
line-height: 50px;
margin-right: 10px;
}
.right .box-container {
display: flex;
flex-wrap: wrap;
}
```
```javascript
class DragAndDrop {
constructor() {
// 左侧拖拽内容
this.left = document.querySelector('.left');
// 右侧拖拽容器
this.right = document.querySelector('.right');
this.dropzone = this.right.querySelector('.dropzone');
this.boxContainer = this.right.querySelector('.box-container');
// 绑定左侧拖拽事件
this.bindDragEvent(this.left);
// 绑定右侧拖拽事件
this.bindDragEvent(this.right);
// 绑定右侧排序事件
this.bindSortEvent();
}
// 绑定拖拽事件
bindDragEvent(element) {
// 记录拖拽开始的元素
let draggableElement = null;
// 监听 dragstart 事件,开始拖拽
element.addEventListener('dragstart', (event) => {
draggableElement = event.target;
event.dataTransfer.setData('text/plain', '');
event.dataTransfer.setDragImage(draggableElement, 0, 0);
});
// 监听 dragover 事件,拖拽到目标元素上
element.addEventListener('dragover', (event) => {
event.preventDefault();
// 如果是右侧容器,判断拖拽到目标元素上
if (element === this.right) {
const box = this.getBoxFromPoint(event.clientX, event.clientY);
if (box) {
box.classList.add('over');
}
}
});
// 监听 dragleave 事件,拖拽离开目标元素
element.addEventListener('dragleave', (event) => {
// 如果是右侧容器,移除目标元素上的样式
if (element === this.right) {
const box = this.getBoxFromPoint(event.clientX, event.clientY);
if (box) {
box.classList.remove('over');
}
}
});
// 监听 drop 事件,完成拖拽
element.addEventListener('drop', (event) => {
event.preventDefault();
// 如果是右侧容器,将拖拽元素添加到目标元素中
if (element === this.right) {
const box = this.getBoxFromPoint(event.clientX, event.clientY);
if (box) {
box.classList.remove('over');
this.boxContainer.insertBefore(draggableElement, box.nextSibling);
} else {
this.boxContainer.appendChild(draggableElement);
}
}
});
}
// 获取鼠标位置下的 DOM 元素
getBoxFromPoint(x, y) {
const element = document.elementFromPoint(x, y);
if (element && element.classList.contains('box')) {
return element;
}
return null;
}
// 绑定排序事件
bindSortEvent() {
let draggingElement = null;
// 监听 dragstart 事件,开始拖拽
this.boxContainer.addEventListener('dragstart', (event) => {
draggingElement = event.target;
event.dataTransfer.setData('text/plain', '');
event.dataTransfer.setDragImage(draggingElement, 0, 0);
});
// 监听 dragover 事件,拖拽到目标元素上
this.boxContainer.addEventListener('dragover', (event) => {
event.preventDefault();
// 获取当前拖拽元素和目标元素
const droppedElement = event.target;
if (draggingElement !== droppedElement && droppedElement.classList.contains('box')) {
// 根据鼠标位置判断拖拽方向
const rect = droppedElement.getBoundingClientRect();
const isBefore = event.clientY < rect.top + rect.height / 2;
// 在目标元素前或后插入拖拽元素
if (isBefore) {
this.boxContainer.insertBefore(draggingElement, droppedElement);
} else {
this.boxContainer.insertBefore(draggingElement, droppedElement.nextSibling);
}
}
});
// 监听 dragend 事件,拖拽结束
this.boxContainer.addEventListener('dragend', (event) => {
// 为拖拽元素添加动画类名
draggingElement.classList.add('animate');
// 等待过渡效果完成后,移除动画类名
setTimeout(() => {
draggingElement.classList.remove('animate');
}, 500);
});
}
}
// 初始化 DragAndDrop 实例
new DragAndDrop();
```
在上面的代码中,我们首先定义了左侧拖拽内容和右侧拖拽容器。然后通过绑定拖拽事件,实现了将左侧拖拽内容拖拽到右侧拖拽容器中,并支持在容器内进行排序操作。在排序操作中,我们使用了 dragover 事件和 elementFromPoint 方法来判断拖拽方向和目标元素位置,使用 insertBefore 方法在目标元素前或后插入拖拽元素。最后,我们为拖拽元素添加了移动动画,让用户更加直观地感受到拖拽效果。
阅读全文