用到的三个鼠标事件:
onmousedown: 当鼠标按下
onmousemove:当鼠标移动
onmouseup:当鼠标松开
思路:动态监听鼠标位置,给div设置绝对定位(display: absolute),在 onmousemove 事件中动态改变 div 的 left 和 top 的值。
e.clientX
e.clientY
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.test {
width: 50px;
height: 50px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<div class="test"></div>
<script>
const div = document.querySelector('.test');
let isMouseDown = false; // 监听器,监听是否点击该 div 元素
div.onmousedown = (e) => {
isMouseDown = true; // 点击该 div 元素则设置监听器为 true
}
window.onmousemove = (e) => {
if(!isMouseDown) {
return;
}
div.style.left = e.clientX + 'px'; //动态获取并改变 left 的值
div.style.top = e.clientY + 'px';
}
div.onmouseup = () => {
isMouseDown = false;
}
</script>
</body>
</html>
上面这种实现方式可以基本实现 div 跟随鼠标移动,但是有一点小缺陷,鼠标总会处于 div 的左上方而不是最初点击的位置。
如果鼠标最开始点击的是 div 的中心,或者是右下方某个位置,我们也想要在拖动的过程中鼠标一直处于最开始点击的位置,优化如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.test {
width: 50px;
height: 50px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<div class="test" id='test'></div>
<script>
const div = document.querySelector('.test');
let x = 0;
let y = 0;
let offsetTop = 0;
let offsetLeft = 0;
let isMouseDown = false;
div.onmousedown = (e) => {
x = e.clientX; //记录鼠标最开始点击的位置
y = e.clientY;
offsetLeft = div.offsetLeft; //记录 div 元素最开始距离左边的距离
offsetTop = div.offsetTop; //记录 div 元素最开始距离顶部的距离
isMouseDown = true;
}
window.onmousemove = (e) => {
if(!isMouseDown) {
return;
}
let nx = e.clientX;
let ny = e.clientY;
let nLeft = nx - (x - offsetLeft); //获得 div 元素真实位置信息
let nTop = ny - (y - offsetTop);
div.style.left = nLeft + 'px';
div.style.top = nTop + 'px';
}
div.onmouseup = () => {
isMouseDown = false;
}
</script>
</body>
</html>
以上代码思路要复杂一点,这里简单再说一下(关键是要理清 clientX,clientY 和 offsetTop,offsetLeft的关系):
正方形中黑点是鼠标指针,要想保存鼠标最开始相对于 div 的位置,必须用鼠标此时的位置 减去 最开始 鼠标按下时候的 (clientY - offsetTop 和 clientX -offsetLeft) 的值
网友评论