元素拖拽实现
# 元素拖拽实现
# 思路
1.拿到鼠标点击元素时,元素一开始的位置
2.拿到鼠标移动的距离
拿到鼠标点击的位置,拿到鼠标移动时实时的位置,
鼠标移动的实时位置 = 鼠标移动时实时的位置 - 鼠标点击的位置
3.确定鼠标移动后元素的位置(元素一开始的位置+鼠标移动的距离)
1
2
3
4
5
6
7
2
3
4
5
6
7
# 代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>前端小记-拖拽</title>
<style>
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
overflow: hidden;
}
.wrap {
position: relative;
height: 100%;
background: #bfa;
}
.wrap > .test {
position: absolute;
left: 100px;
top: 100px;
background: pink;
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<div class="wrap">
<div class="test"></div>
</div>
</body>
<script>
/*拖拽的思路:
1.拿到鼠标点击元素时,元素一开始的位置
2.拿到鼠标移动的距离
拿到鼠标点击的位置,拿到鼠标移动时实时的位置,
鼠标移动的实时位置 = 鼠标移动时实时的位置 - 鼠标点击的位置
3.确定鼠标移动后元素的位置(元素一开始的位置+鼠标移动的距离)
*/
window.onload = function () {
// 获取元素
let testNode = document.querySelector(".wrap > .test");
// 获取元素的起始位置
let startPoint = { x: 0, y: 0 };
// 鼠标按下时的位置
let mouseDownPoint = { x: 0, y: 0 };
// 鼠标移动时的位置
let mouseMovePoint = { x: 0, y: 0 };
// 鼠标移动的距离
let dis = { x: 0, y: 0 };
// 为了在下面可以更方便的清除鼠标移动事件和鼠标抬起事件,此时选择使用dom0事件
testNode.onmousedown = function (ev) {
//1.拿到鼠标点击元素时,元素一开始的位置
// 此时的offsetLeft是相对于整个视口的,因为此时的包含块就是初始包含块就是视口
startPoint.x = this.offsetLeft;
startPoint.y = this.offsetTop;
// 2.拿到鼠标点击元素时,鼠标一开始的位置
// 此时的ev.clientX也是参照于视口的
mouseDownPoint.x = ev.clientX;
mouseDownPoint.y = ev.clientY;
// 鼠标移动事件必须在鼠标按下事件之后才能触发,所以将mousemove事件放到mousedown事件的内部
document.onmousemove = function (ev) {
mouseMovePoint.x = ev.clientX;
mouseMovePoint.y = ev.clientY;
dis.x = mouseMovePoint.x - mouseDownPoint.x;
dis.y = mouseMovePoint.y - mouseDownPoint.y;
testNode.style.left = startPoint.x + dis.x + "px";
testNode.style.top = startPoint.y + dis.y + "px";
};
// 当鼠标抬起的时候将鼠标移动事件和鼠标抬起事件清除,防止鼠标抬起之后再移动鼠标导致元素跟着移动
document.onmouseup = function () {
document.onmousemove = document.onmouseup = null;
};
// 禁止浏览器的默认行为
return false;
};
};
</script>
</html>
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
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
# 限制范围
在鼠标移动事件中添加移动范围的代码,新的鼠标移动事件的代码如下:
// 鼠标移动事件必须在鼠标按下事件之后才能触发,所以将mousemove事件放到mousedown事件的内部
document.onmousemove = function (ev) {
mouseMovePoint.x = ev.clientX;
mouseMovePoint.y = ev.clientY;
dis.x = mouseMovePoint.x - mouseDownPoint.x;
dis.y = mouseMovePoint.y - mouseDownPoint.y;
let L = startPoint.x + dis.x;
let T = startPoint.y + dis.y;
if (L < 0) {
L = 0;
}
if (T < 0) {
T = 0;
}
if (
T >
document.documentElement.clientHeight - testNode.offsetHeight
) {
T = document.documentElement.clientHeight - testNode.offsetHeight;
}
if (L > document.documentElement.clientWidth - testNode.offsetWidth) {
L = document.documentElement.clientWidth - testNode.offsetWidth;
}
testNode.style.left = L + "px";
testNode.style.top = T + "px";
};
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
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
# 磁性吸附
在元素移动到具体边框较小的距离时将元素直接吸附到边框上,修改后的鼠标移动事件具体代码如下:
// 鼠标移动事件必须在鼠标按下事件之后才能触发,所以将mousemove事件放到mousedown事件的内部
document.onmousemove = function (ev) {
mouseMovePoint.x = ev.clientX;
mouseMovePoint.y = ev.clientY;
dis.x = mouseMovePoint.x - mouseDownPoint.x;
dis.y = mouseMovePoint.y - mouseDownPoint.y;
let L = startPoint.x + dis.x;
let T = startPoint.y + dis.y;
if (L < 30) {
L = 0;
} else if (
L >
document.documentElement.clientWidth - testNode.offsetWidth - 30
) {
L = document.documentElement.clientWidth - testNode.offsetWidth;
}
if (T < 30) {
T = 0;
} else if (
T >
document.documentElement.clientHeight - testNode.offsetHeight - 30
) {
T = document.documentElement.clientHeight - testNode.offsetHeight;
}
testNode.style.left = L + "px";
testNode.style.top = T + "px";
};
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
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
完善页面 (opens new window)
上次更新: 2023-12-26 18:29:08