js 左侧多个拖拽内容,拖拽其中一个dom到右侧,左侧dom不减少,右侧dom判断拖拽到dom内,未释放前可进行排序,右侧dom有多层结构,并且每层都可以拖拽排序,右侧dom可拖拽排序并添加移动动画,请用完整class 类代码实现,兼容谷歌低版本浏览器
时间: 2024-01-11 20:04:25 浏览: 108
好的,以下是一个可实现上述功能的 class 类代码:
```javascript
class DragAndDrop {
constructor(leftSelector, rightSelector) {
// 左侧可拖拽元素的选择器
this.leftSelector = leftSelector;
// 右侧可拖拽元素的选择器
this.rightSelector = rightSelector;
// 左侧可拖拽元素的集合
this.leftElems = document.querySelectorAll(leftSelector);
// 右侧可拖拽元素的集合
this.rightElems = document.querySelectorAll(rightSelector);
// 右侧当前拖拽的元素
this.draggedElem = null;
// 右侧当前拖拽元素的初始位置
this.draggedElemInitPos = null;
// 右侧当前拖拽元素的当前位置
this.draggedElemCurrentPos = null;
// 右侧当前拖拽元素的初始父元素
this.draggedElemInitParent = null;
// 右侧当前拖拽元素的当前父元素
this.draggedElemCurrentParent = null;
// 右侧当前拖拽元素的子元素集合
this.draggedElemChildren = null;
// 初始化拖拽事件
this.initDragEvents();
}
// 初始化拖拽事件
initDragEvents() {
// 给左侧可拖拽元素绑定拖拽事件
this.leftElems.forEach(elem => {
elem.addEventListener('dragstart', this.handleDragStart.bind(this));
});
// 给右侧可拖拽元素绑定拖拽事件
this.rightElems.forEach(elem => {
elem.addEventListener('dragstart', this.handleDragStart.bind(this));
elem.addEventListener('dragover', this.handleDragOver.bind(this));
elem.addEventListener('dragleave', this.handleDragLeave.bind(this));
elem.addEventListener('drop', this.handleDrop.bind(this));
});
}
// 处理拖拽开始事件
handleDragStart(e) {
// 设置右侧当前拖拽的元素
this.draggedElem = e.target;
// 设置右侧当前拖拽元素的初始位置
this.draggedElemInitPos = {
x: e.clientX,
y: e.clientY
};
// 设置右侧当前拖拽元素的当前位置
this.draggedElemCurrentPos = {
x: e.clientX,
y: e.clientY
};
// 设置右侧当前拖拽元素的初始父元素
this.draggedElemInitParent = this.draggedElem.parentElement;
// 设置右侧当前拖拽元素的当前父元素
this.draggedElemCurrentParent = this.draggedElem.parentElement;
// 设置右侧当前拖拽元素的子元素集合
this.draggedElemChildren = this.draggedElem.querySelectorAll(this.rightSelector);
// 设置拖拽图标
e.dataTransfer.setDragImage(this.draggedElem, 0, 0);
}
// 处理拖拽元素在目标元素上方悬停事件
handleDragOver(e) {
e.preventDefault();
// 判断目标元素是否是当前拖拽元素的子元素
if (this.draggedElem.contains(e.target)) {
return;
}
// 判断目标元素是否是当前拖拽元素的父元素
if (this.draggedElem.parentElement === e.target) {
return;
}
// 获取目标元素的位置信息
const targetElemPos = e.target.getBoundingClientRect();
// 判断当前拖拽元素是否被拖拽到目标元素的上半部分
if (e.clientY < targetElemPos.y + targetElemPos.height / 2) {
// 将当前拖拽元素插入到目标元素的前面
this.draggedElemCurrentParent.insertBefore(this.draggedElem, e.target);
} else {
// 将当前拖拽元素插入到目标元素的后面
this.draggedElemCurrentParent.insertBefore(this.draggedElem, e.target.nextElementSibling);
}
// 设置当前拖拽元素的当前位置和当前父元素
this.draggedElemCurrentPos = {
x: e.clientX,
y: e.clientY
};
this.draggedElemCurrentParent = this.draggedElem.parentElement;
}
// 处理拖拽元素离开目标元素事件
handleDragLeave(e) {
e.preventDefault();
}
// 处理拖拽元素放置到目标元素内部事件
handleDrop(e) {
e.preventDefault();
// 判断目标元素是否是当前拖拽元素的子元素
if (this.draggedElem.contains(e.target)) {
return;
}
// 判断目标元素是否是当前拖拽元素的父元素
if (this.draggedElem.parentElement === e.target) {
return;
}
// 将当前拖拽元素插入到目标元素的最后面
e.target.appendChild(this.draggedElem);
// 设置当前拖拽元素的当前位置和当前父元素
this.draggedElemCurrentPos = {
x: e.clientX,
y: e.clientY
};
this.draggedElemCurrentParent = this.draggedElem.parentElement;
}
}
```
使用方式:
```javascript
const dragAndDrop = new DragAndDrop('.left-elem', '.right-elem');
```
其中,`.left-elem` 和 `.right-elem` 分别为左侧和右侧可拖拽元素的选择器。在页面中,需要保证左侧和右侧元素的 HTML 结构已经存在,并且左侧和右侧元素的选择器必须能够正确地获取到左侧和右侧元素的集合。
阅读全文