js 左侧多个拖拽内容,拖拽其中一个dom到右侧,左侧dom不减少,右侧dom判断拖拽到dom内,未释放前可进行排序,右侧dom有多层结构,并且每层有个可以拖拽的按钮,鼠标移动上去即可拖拽排序并添加移动动画,请用完整class 类代码完整实现,不使用第三方插件
时间: 2024-01-12 11:03:24 浏览: 15
好的,以下是完整的 class 类代码实现:
```javascript
class DragAndDrop {
constructor(leftContainer, rightContainer) {
this.leftContainer = leftContainer;
this.rightContainer = rightContainer;
this.draggedItem = null;
this.draggedOverItem = null;
this.draggedOverContainer = null;
// 绑定拖拽事件
this.bindDragEvents();
}
bindDragEvents() {
// 绑定左侧容器的拖拽事件
this.leftContainer.addEventListener('dragstart', (event) => {
this.draggedItem = event.target;
event.dataTransfer.setData('text/plain', ''); // 设置数据类型
});
// 绑定右侧容器的拖拽事件
this.rightContainer.addEventListener('dragstart', (event) => {
this.draggedItem = event.target;
event.dataTransfer.setData('text/plain', ''); // 设置数据类型
});
// 绑定右侧容器的拖拽进入事件
this.rightContainer.addEventListener('dragenter', (event) => {
event.preventDefault();
this.draggedOverContainer = event.target;
this.draggedOverItem = this.getDraggedOverItem(event.clientY);
// 添加移动动画
this.draggedOverItem.classList.add('dragged-over');
});
// 绑定右侧容器的拖拽移动事件
this.rightContainer.addEventListener('dragover', (event) => {
event.preventDefault();
this.draggedOverItem = this.getDraggedOverItem(event.clientY);
});
// 绑定右侧容器的拖拽离开事件
this.rightContainer.addEventListener('dragleave', () => {
this.draggedOverItem.classList.remove('dragged-over');
});
// 绑定右侧容器的拖拽放置事件
this.rightContainer.addEventListener('drop', (event) => {
event.preventDefault();
// 判断是否是拖拽的按钮
if (this.draggedItem.classList.contains('drag-handle')) {
this.moveItem();
} else {
this.copyItem();
}
});
// 绑定右侧容器内的按钮的拖拽事件
this.rightContainer.querySelectorAll('.drag-handle').forEach((item) => {
item.addEventListener('dragstart', (event) => {
this.draggedItem = event.target.parentNode;
event.dataTransfer.setData('text/plain', ''); // 设置数据类型
});
});
}
getDraggedOverItem(y) {
// 获取容器内最近的一个元素
const items = [...this.draggedOverContainer.querySelectorAll('.item:not(.dragged-item)')];
return items.reduce((closest, child) => {
const box = child.getBoundingClientRect();
const offset = y - box.top - box.height / 2;
if (offset < 0 && offset > closest.offset) {
return { offset, element: child };
} else {
return closest;
}
}, { offset: Number.NEGATIVE_INFINITY }).element;
}
moveItem() {
// 移动拖拽的元素到目标元素前面
this.draggedOverContainer.insertBefore(this.draggedItem, this.draggedOverItem);
this.draggedOverItem.classList.remove('dragged-over');
}
copyItem() {
// 复制拖拽的元素到目标元素前面
const newItem = this.draggedItem.cloneNode(true);
this.draggedOverContainer.insertBefore(newItem, this.draggedOverItem);
this.draggedOverItem.classList.remove('dragged-over');
}
}
```
在此基础上,还需要在 HTML 中添加相应的元素和一些 CSS 样式,以实现完整的拖拽排序功能。