原生js拖拽
思路:
1.鼠标按下的时候,记录鼠标在inner的相对的位置offsetX,offsetY,并给document绑定mousemove和mouseup事件
2.在mousemove事件中,实时计算:e.clientX - wrapRect.left - offsetX和e.clientY - wrapRect.top - offsetY
3.在mouseup事件中,解除document的mousemove和mouseup事件
4.添加isDrag变量,控制mousemove事件的执行
<!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>.wrap {width: 500px;height: 500px;border: 1px solid #ccc;position: relative;}.inner {width: 100px;height: 100px;border: 1px solid red;position: absolute;left: 0;top: 0;background: #ddd;}</style>
</head><body><!-- 写一个在div里面的小的div可以自由的去移动的功能 --><div class="wrap" id="wrap"><div class="inner" id="inner"></div></div><script>const wrap = document.getElementById('wrap');const inner = document.getElementById('inner');//第一步,鼠标在inner上按下的时候,记下此时的鼠标的位置let offsetX = 0;let offsetY = 0;const wrapRect = wrap.getBoundingClientRect();const maxLeft = wrapRect.width - inner.offsetWidth;const maxTop = wrapRect.height - inner.offsetHeight;let isDrag = falseconst onMouseMove = (e) => {if (!isDrag) return//鼠标在移动的时候,计算鼠标所移动的距离 wrapRect是不会动的,所以可放在外面let left = e.clientX - wrapRect.left - offsetX;let top = e.clientY - wrapRect.top - offsetY;//边界的判断inner.style.left = Math.min(Math.max(left, 0), maxLeft) + 'px';inner.style.top = Math.min(Math.max(top, 0), maxTop) + 'px';}const onMouseUp = () => {isDrag = false;document.removeEventListener('mousemove', onMouseMove);document.removeEventListener('mouseup', onMouseUp);}inner.addEventListener('mousedown', (e) => {isDrag = true//获取鼠标在inner里面的相对的位置 getBoundingClientRect.left是相对于视口的位置,需要获取到inner的实时的位置,所以这里的inner.getBoundingClientRect需要实时获取offsetX = e.clientX - inner.getBoundingClientRect().left;offsetY = e.clientY - inner.getBoundingClientRect().top;//给document绑定事件. 如果只给inner绑定事件,当鼠标移动太快移出去了,那么会卡document.addEventListener('mousemove', onMouseMove);document.addEventListener('mouseup', onMouseUp);})</script>
</body></html>