场景
很多场景都需要拖曳盒子,如:
- 一个弹窗,需要可以拖动。
- 登录验证,滑动验证。
原理
思路:思路来源_1
思路来源_2
给需要滑动的盒子绑定鼠标按下事件
绑定鼠标弹起事件
,盒子得脱离文档流,给定位absolute等
,需要获取鼠标的初始位置
,在鼠标按下事件内定义外层包裹盒子的鼠标移动事件
,根据鼠标位置计算出盒子的坐标(left, top)
,动态赋值盒子坐标,在鼠标弹起事件内取消鼠标移动事件
本案例还应该-wrap.offsetLeft
和-wrap.offsetTop
的,mouse_in_box_x,mouse_in_box_y
里减了,那boxX,boxY
也要减,因为wrap.offset
是固定的,所以是可以消掉的,对结果没影响。
源码
<!DOCTYPE html>
<html lang="zh-CN">
<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>
.wrap {
width: 200px;
height: 200px;
margin: 50px auto;
border: 1px solid black;
position: relative;
}
.wrap .box {
position: absolute;
height: 50px;
width: 50px;
background: #1d84f6;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div class="wrap">
<div class="box">
</div>
</div>
<script>
// 拖拽三步走
const wrap = document.querySelector('.wrap')
const box = document.querySelector('.box')
// 1. 鼠标按下: 记录鼠标初始位置
box.onmousedown = function (e) {
//当鼠标按下的时候,获得鼠标在盒子中的位置
//鼠标在盒子中的位置=鼠标在页面中的位置-盒子在页面的位置
//鼠标在页面中的位置
var x = e.pageX
var y = e.pageY
//盒子在页面中的位置
var box_x = box.offsetLeft;
var box_y = box.offsetTop;
//鼠标在盒子中的位置
var mouse_in_box_x = x - box_x; // var mouse_in_box_x = x - box_x - wrap.offsetLeft;
var mouse_in_box_y = y - box_y; // var mouse_in_box_y = y - box_y - wrap.offsetTop;
//2. 在鼠标按下事件内定义鼠标移动事件
wrap.onmousemove = function (e) {
//鼠标在页面中移动时,求盒子的坐标
//鼠标移动时盒子移动位置=鼠标在当前页面位置-鼠标在盒子中的距离
x = e.pageX
y = e.pageY
//盒子的坐标
var boxX = x - mouse_in_box_x; // var boxX = x - mouse_in_box_x - wrap.offsetLeft;
var boxY = y - mouse_in_box_y; // var boxY = y - mouse_in_box_y - wrap.offsetTop;
// 安全
if (boxX < 0) boxX = 0
if (boxY < 0) boxY = 0
if (boxX > 150) boxX = 150
if (boxY > 150) boxY = 150
//px一定不能忘
box.style.left = boxX + 'px';
box.style.top = boxY + 'px';
}
// 3. 鼠标松开: 去除移动事件
box.onmouseup = function () {
wrap.onmousemove = null
// 可以在这里判定拖动的距离是否满足验证条件
}
}
</script>
</body>
</html>