JavaScript 实现元素拖拽:基于闭包的封装与实现

作者:异步漫步

时间:2026-10-27

浏览:360

本文详细介绍如何使用 JavaScript 闭包封装一个通用的拖拽管理器。通过维护内部状态变量,封装鼠标按下、移动和抬起事件,实现元素的自由拖拽。重点解决了鼠标移动过快导致脱离元素的问题,通过注册 document 级别的鼠标抬起事件确保交互同步,并提供了完整的代码示例与注意事项。

文章目录
JavaScript 实现拖拽功能,详细解析闭包机制

JavaScript 拖拽功能实现:闭包封装与事件处理

本方案采用简洁的闭包模式进行实现。


代码示例

具体代码实现如下:

 
/** 
* 使用 JetBrains WebStorm 创建。
* 用户:lsj
* 日期:12-11-24
* 时间:下午 12:59
* 修改此模板请使用 文件 | 设置 | 文件模板。
*/ 
var dragmanager=(function(){
{ 
// 标识移动元素的 z 轴坐标层级
var index_z=1;
// 当前正在被拖拽的元素引用
var drganow;
// 拖拽动作开始标识
var dragbegin=false;
// 鼠标点击时,鼠标位置相对于 div 左侧的距离
var relativex=0;
// 鼠标点击时,鼠标位置相对于 div 顶部的距离
var relativey=0;
// 标识鼠标是否已移出目标元素区域
var isout=false;
return {
/** 
/* 为 document 绑定鼠标松开事件,主要防止鼠标移动过快跳出目标元素区域
*/ 
bingDocOnMouseUp:function(){
{ 
// 注册全局的 onmouseup 事件,主要防止鼠标移动过快导致鼠标与元素不同步
document.onmouseup=function(e){
{ 
var ev = window.event || e;
if(isout && dragbegin){
{ 
// 更新 div 的相对位置
drganow.style.left= (ev.clientX-relativex)+'px';
drganow.style.top=(ev.clientY-relativey)+'px';
drganow.style.cursor='normal';
dragbegin=false;
isout=false;
} 
} 
}, 
/** 
/* 将注入的元素绑定相应事件
* @param el 目标元素
*/ 
registerElementEv:function(element){
{ 
element.onmousedown=function(e){
{ 
var ev = window.event || e;
var clientx=ev.clientX;
var clienty= ev.clientY;
var left= parseInt(this.style.left.substring(0, this.style.left.indexOf("p")));
var top= parseInt(this.style.top.substring(0, this.style.top.indexOf("p")));
relativex=clientx-left;
relativey=clienty-top;
index_z++;
this.style.zIndex=index_z;
drganow=this;
dragbegin=true;
} 
element.onmousemove=function(e){
{ 
var ev = window.event || e;
// 开始执行拖拽逻辑
if(dragbegin){
{ 
// 更新 div 的相对位置
this.style.left= (ev.clientX-relativex)+'px';
this.style.top=(ev.clientY-relativey)+'px';
this.style.cursor='move';
} 
} 
element.onmouseout=function(e){
{ 
isout=true;
} 
element.onmouseup=function(e){
{ 
var ev = window.event || e;
if(dragbegin){
{ 
// 更新 div 的相对位置
drganow.style.left= (ev.clientX-relativex)+'px';
drganow.style.top=(ev.clientY-relativey)+'px';
drganow.style.cursor='normal';
dragbegin=false;
} 
} 
} 
} 
})(); 

1. 采用闭包形式实现,便于后期维护,将移动过程所需的变量全部封装在 dragmanager 内部。


2. 在拖拽过程中,若鼠标移动过快导致移动元素跟不上鼠标的移动轨迹,因此需要注册 document.onmouseup 事件。该事件的触发开关由移动元素的 onmouseout 事件控制。


3. 在拖拽过程中可能会触发浏览器自身的 onmousemove 选中事件,在 IE 浏览器下可通过 onmousemove="document.selection.empty()" 进行屏蔽。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章