在JavaScript中实现拖拽功能,核心是通过监听鼠标的相关事件,动态计算元素的位置并更新样式,整个过程不需要依赖任何第三方库,原生API就能完成。

拖拽功能的实现原理
拖拽功能主要分为三个阶段:按下鼠标准备拖拽、移动鼠标执行拖拽、松开鼠标结束拖拽,对应需要监听三个鼠标事件:mousedown、mousemove、mouseup。实现时需要先记录鼠标按下时的初始位置和元素的初始位置,移动时计算鼠标移动的距离,再将这个距离同步到元素的位置上,松开鼠标时移除移动和松开的事件监听即可。
核心事件与逻辑说明
1. mousedown事件
当鼠标按下被拖拽元素时触发,此时需要记录两个关键信息:鼠标按下时的页面坐标,以及被拖拽元素当前的偏移位置。同时给document绑定mousemove和mouseup事件,避免鼠标移动过快脱离元素导致拖拽失效。
2. mousemove事件
鼠标移动时触发,计算当前鼠标坐标和初始鼠标坐标的差值,这个差值就是元素需要移动的距离,将差值加上元素的初始位置,就是元素新的位置,更新元素的left和top样式即可。
3. mouseup事件
鼠标松开时触发,此时需要移除document上绑定的mousemove和mouseup事件,结束拖拽过程。
完整代码示例
以下是一个可拖拽div的完整实现代码,元素可以在页面内自由拖拽:
// 获取被拖拽的元素
const dragBox = document.getElementById('dragBox');
// 记录初始状态的变量
let startX = 0;
let startY = 0;
let originLeft = 0;
let originTop = 0;
let isDragging = false;
// 监听鼠标按下事件
dragBox.addEventListener('mousedown', function(e) {
isDragging = true;
// 记录鼠标按下的坐标
startX = e.pageX;
startY = e.pageY;
// 记录元素当前的偏移位置,getComputedStyle获取的是字符串,需要转成数字
originLeft = parseInt(getComputedStyle(dragBox).left) || 0;
originTop = parseInt(getComputedStyle(dragBox).top) || 0;
// 给document绑定鼠标移动事件,避免鼠标脱离元素
document.addEventListener('mousemove', handleMouseMove);
// 给document绑定鼠标松开事件
document.addEventListener('mouseup', handleMouseUp);
// 阻止默认行为,避免选中文本影响拖拽
e.preventDefault();
});
// 鼠标移动处理函数
function handleMouseMove(e) {
if (!isDragging) return;
// 计算鼠标移动的距离
const moveX = e.pageX - startX;
const moveY = e.pageY - startY;
// 计算元素新的位置
const newLeft = originLeft + moveX;
const newTop = originTop + moveY;
// 更新元素位置
dragBox.style.left = newLeft + 'px';
dragBox.style.top = newTop + 'px';
}
// 鼠标松开处理函数
function handleMouseUp() {
isDragging = false;
// 移除事件监听
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
}对应的HTML结构只需要一个可定位的元素即可:
<div id="dragBox" style="width: 100px; height: 100px; background: #409eff; color: #fff; text-align: center; line-height: 100px; position: absolute; left: 0; top: 0; cursor: move;">可拖拽</div>
注意事项与优化
- 给被拖拽元素设置
position: absolute或position: fixed,否则修改left和top样式不会生效。 - 事件绑定在document上而不是被拖拽元素上,避免鼠标移动速度过快脱离元素导致拖拽中断。
- 可以在计算新位置时增加边界判断,避免元素被拖拽到可视区域外,比如判断
newLeft不能小于0,不能大于窗口宽度减去元素宽度。 - 如果需要支持移动端,还需要额外监听
touchstart、touchmove、touchend事件,逻辑和鼠标事件类似,只是坐标需要从touch对象中获取。
JavaScript拖拽功能DOM事件mousedownmousemove修改时间:2026-06-05 02:07:45