要实现一个点击元素,拖动元素到页面上你想要在的地方。如何实现这个功能呢?我想到了两种实现方法:第一种就是最近学习的html5的drag和drop功能;第二种是绑定鼠标的onmousedown,onmousemove事件。然后这两种实现方式又有什么区别呢?

普通鼠标事件

我们把body中的div元素设定为我们要移动的元素,移动的位置整个页面。这种鼠标事件的响应周期是350毫秒。具体实现如下:

  • 鼠标点击下时,计算鼠标点击的位置距离DIV左边和上边的距离
  • 鼠标移动时,计算处DIV元素左上角是否在页面可以移动的区域内
  • 合理设置DIV的top和left值,实现元素跟随鼠标移动的功能。
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>实现鼠标拖放</title>
<style type="text/css">
div{
position: absolute;
width: 200px;
height: 200px;
background: #369
}
</style>
</head>
<body>
<div></div>
</body>

<script type="text/javascript">

window.onload = function(){
var oDiv = document.getElementsByTagName("div")[0];

// 鼠标点击的位置距离DIV左边的距离
var disX = 0;
// 鼠标点击的位置距离DIV顶部的距离
var disY = 0;
oDiv.onmousedown = function(){

var e = e || window.event;
console.log(e);
disX = e.clientX - oDiv.offsetLeft;
disY = e.clientY- oDiv.offsetTop;

document.onmousemove = function(e){
var e = e || window.event;
// 横轴坐标
var leftX = e.clientX - disX;
// 纵轴坐标
var topY =e.clientY - disY;

if( leftX < 0 ){
leftX = 0;
}
// 获取浏览器视口大小 document.document.documentElement.clientWidth
else if( leftX > document.documentElement.clientWidth - oDiv.offsetWidth ){
leftX = document.documentElement.clientWidth - oDiv.offsetWidth;
}

if( topY < 0 ){
topY = 0;
}
else if( topY > document.documentElement.clientHeight -oDiv.offsetHeight ){
topY = document.documentElement.clientHeight - oDiv.offsetHeight;
}
oDiv.style.left = leftX + "px";
oDiv.style.top = topY+"px";
}
document.onmouseup = function(){
document.onmousemove = null;
document.onmouseup = null;
}
}
}
</script>
</html>

利用html5的drag和drop功能

重点是:

  • 要移动元素的draggable属性必须为true
  • dragover默认浏览器效果是drop失效,所以必须阻止默认事件。
  • dragover事件必须用addEventListener绑定,否则不生效。
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSONP实现跨域2</title>
<style type="text/css">
div{
position: absolute;
width: 200px;
height: 200px;
background: #369
}
</style>
</head>
<body>
<div draggable='true'></div>
</body>

<script type="text/javascript">

//第一种方法
window.onload = function() {
//获取被拖拽元素
const item = document.getElementsByTagName('div')[0];
//鼠标点击的位置离div左边和上边的距离,现在设置为0
let disX = 0, disY = 0;
//div在页面上的位置。
let leftX = 0, topY = 0;
item.ondragstart = function(event) {
let e = event || window.event;
//记录鼠标点击位置和div的距离,鼠标当前位置剪去div离body的位置
disX = e.clientX - item.offsetLeft;
disY = e.clientY - item.offsetTop;
event.dataTransfer.effectAllowed = 'all';
}
item.ondragend = function(event) {
let e = event || window.event;
leftX = e.clientX - disX;
topY = e.clientY - disY;

if(leftX < 0) {
leftX = 0;
} else if (leftX > document.documentElement.clientWidth - item.offsetWidth) {
leftX = document.documentElement.clientWidth - item.offsetWidth;
}

if (topY < 0) {
topY = 0;
} else if (topY > document.documentElement.clientHeight - item.offsetHeight) {
topY = document.documentElement.clientHeight - item.offsetHeight;
}

item.style.left = leftX + "px";
item.style.top = topY + "px";
}
document.addEventListener("dragover", function(event) {
event.preventDefault();
// event.dataTransfer.dropEffect = 'link';
});
}

</script>
</html>

区别

这两种实现方式究竟有什么区别?当然让你自己去尝试一下啦。
总之,第一种实现的效果元素跟随,第二种被拖动元素在没有放下前一直在原位置有占位,同时跟随鼠标的效果是半透明的。