功能描述

点击已有元素,复制其本身,然后将其拖拽到画布上

功能拆解

  • 鼠标点击后克隆点击的元素,生成拖拽元素(dragEl
  • dragEl添加当前页面中,并定位到鼠标位置
  • 监听鼠标点击后的移动,通过修改dragEl的top与left值实现dragEl的随鼠标移动效果
  • 监听鼠标的移动范围,如果超出画布区域松开鼠标,则将dragEl移除
  • dragEl添加mousedownmouseup事件,实现点击画布上元素后,元素跟随鼠标移动

代码实现

1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class DragItem {
parentEl = null;
dragEl = null;
active = false;
_style = {
left: 0,
top: 0,
width: 0,
height: 0,
};
constructor(e, parentEl) {
this.parentEl = parentEl;
this.init(e);
}
init(e) {
// ...
}

setStyle(obj) {
Object.keys(obj).forEach((k) => {
if (this._style[k] != undefined || this._style[k] != null) {
this._style[k] = obj[k];
}
});
Object.keys(this._style).forEach((k) => {
this.dragEl.style[k] = this._style[k] + "px";
});
}

getDragEl() {
return this.dragEl;
}
}

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
class DragItem {
parentEl = null;
dragEl = null;
active = false;
_style = {
left: 0,
top: 0,
width: 0,
height: 0,
};
constructor(e, parentEl) {
console.log(e, parentEl)
this.parentEl = parentEl;
this.init(e);
}
init(e) {
this._createDragItem(e);
const _this = this;
document.addEventListener("mousemove", function (e) {
if (_this.active)return;
const { width, height } = _this.dragEl.getBoundingClientRect();
const { clientX, clientY } = e;
_this.setStyle({
left: clientX - width / 2,
top: clientY - height / 2,
})
});
document.addEventListener("mouseup", function (e) {
if(_this.active)return;
if (!isInView(e.clientX, e.clientY)) _this.dragEl.remove();
_this.active = true;
});
}

_createDragItem (e) {
const { clientX, clientY } = e;
// 创建一个DIV元素
const dragItem = e.target.cloneNode(false);
const computedStyle = window.getComputedStyle(e.target);
dragItem.style.position = 'absolute';
dragItem.style.zIndex = 999;
this.dragEl = dragItem;
this.active = false;
const { width, height } = e.target.getBoundingClientRect();
this.setStyle({
left: clientX - width / 2,
top: clientY - height / 2,
width,
height
});
// 将元素添加到文档中
this.parentEl.appendChild(dragItem);

// 拖拽逻辑
this._setDragEvent();
}

_setDragEvent() {
const _this = this;
this.dragEl.addEventListener('mousedown', function(e) {
dragControll.hide();
const { clientX, clientY } = e;
const { left, top } = e.target.getBoundingClientRect();
const offsetX = clientX - left;
const offsetY = clientY - top;

function drag(e) {
_this.setStyle({
left: e.clientX - offsetX,
top: e.clientY - offsetY,
})
}

function stopDrag() {
document.removeEventListener('mousemove', drag);
document.removeEventListener('mouseup', stopDrag);
}

document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', stopDrag);
});
}

setStyle(obj) {
Object.keys(obj).forEach((k) => {
if (this._style[k] != undefined || this._style[k] != null) {
this._style[k] = obj[k];
}
});
Object.keys(this._style).forEach((k) => {
this.dragEl.style[k] = this._style[k] + "px";
});
}

getDragEl() {
return this.dragEl;
}
}

最后更新: 2024年04月15日 00:12