前言
最近在实现用js来实现拖拽效果,在实现的过程中,参照了一些文章,大多都是用的mousedown、mousemove和mouseup这三个事件来实现的,用这3个事件来实现拖拽效果,很容易就造成鼠标移速过快导致节点跟不上,容易造成视觉上的卡顿效果
也有一些提到了h5的draggable,但也只是提及了它的概念
为了能流畅的使用元素拖拽效果,就只能通过draggable去实现,所以就有了这篇文章
如果这篇文章能够帮到你的话,emmm也不求个点赞啥的,主要是为了防止自己以后忘了怎么用,有个参考
emmm…由于这里只是简单的应用,所以这里只是会用到一部分Api,如果想要了解更多,可以去菜鸟教程或者是浏览其他大佬的文章!
首先,要想要一个节点能够进行拖拽,首先就要给这个节点设置draggable
<div draggable="true" class="box"></div>
样式
body,
html {
margin: 0;
padding: 0;
}
.box {
width: 200px;
height: 200px;
background-color: skyblue;
position: absolute;
}
设置之后,这个div就可以进行设置拖动了
这里主要涉及到3个事件:dragstart(开始拖动)、drag(拖动中)和dragend(拖动结束)
其中dragstart和dragend只会在开始和结束 触发(即触发一次),而drag会在拖拽的过程中一直触发,直到拖拽结束
示例:通过js获取节点并添加事件
let box = document.querySelector('.box');
box.addEventListener('dragstart', (e) => {
console.log('拖动开始');
})
box.addEventListener('drag', (e) => {
console.log('拖动中');
})
box.addEventListener('dragend', (e) => {
console.log('拖动结束');
})
完整的实现代码如下:
<!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>Document</title>
</head>
<style>
body,
html {
margin: 0;
padding: 0;
}
.box {
width: 200px;
height: 200px;
background-color: skyblue;
position: absolute;
top: 0;
left: 0;
}
</style>
<body>
<div draggable="true" class="box"></div>
<script>
let box = document.querySelector('.box');
// 用于保存鼠标在节点中的位置
let initX = null,
initY = null;
box.addEventListener('dragstart', (e) => {
// 在开始拖拽,保存鼠标在节点中的位置
initX = e.offsetX;
initY = e.offsetY;
})
box.addEventListener('drag', (e) => {
// 拖拽过程中,如果不减去鼠标在节点中的位置,会出现 div 的左上角与 鼠标位置重合
// 中间会有 "闪现" 的效果
let _left = e.clientX - initX
let _top = e.clientY - initY
box.style.left = _left + 'px';
box.style.top = _top + 'px';
// 这个过程结束后,e.clientX和e.clientY都会变成0
// 就会导致 left 和 top 的值变为负值
})
box.addEventListener('dragend', (e) => {
// 所以结束的时候也要设置位置,
// 不然盒子会闪现到左上角
let _left = e.clientX - initX
let _top = e.clientY - initY
box.style.left = _left + 'px';
box.style.top = _top + 'px';
})
</script>
</body>
</html>
这里只是简单的实现了节点的拖拽效果,可能你的需求不仅仅只是实现拖拽,还要保证这个盒子不能拖出边界啥的,以后如果有时间的话我会这部分代码也给写出来