核心知识
clientX / clientY:鼠标在视口中的位置
offsetLeft / offsetTop:元素相对于定位父级的位置
思路(偏移量法)
鼠标按下:
记录鼠标在元素内部的偏移量
offsetX = e.clientX - box.offsetLeft
offsetY = e.clientY - box.offsetTop
鼠标移动:
元素位置 = 当前鼠标位置 - 偏移量
left = e.clientX - offsetX
top = e.clientY - offsetY
鼠标松开:
结束拖拽
代码实现
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>拖拽示例</title>
<style>
#box {
width: 150px;
height: 150px;
background: #409eff;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
left: 100px;
top: 100px;
cursor: move;
user-select: none;
}
</style>
</head>
<body>
<div id="box">box</div>
<script>
const box = document.getElementById('box')
let isDragging = false // 是否正在拖拽
let offsetX = 0 // 鼠标在盒子中的位置
let offsetY = 0
// 鼠标按下时记录当前位置和偏移量
box.addEventListener('mousedown', (e) => {
console.log(box.offsetLeft, box.offsetTop)
isDragging = true
offsetX = e.clientX - box.offsetLeft
offsetY = e.clientY - box.offsetTop
})
document.addEventListener('mousemove', (e) => {
if (!isDragging) return
box.style.left = e.clientX - offsetX + 'px'
box.style.top = e.clientY - offsetY + 'px'
})
document.addEventListener('mouseup', (e) => {
isDragging = false
})
</script>
</body>
</html>