原生JS实现可限制范围的拖拽组件详解

作者:小括号

时间:2026-10-26

浏览:136

本文介绍了一个基于原生JavaScript编写的轻量级拖拽组件。通过监听mousedown、mousemove和mouseup事件实现元素拖动,并支持设置最大移动范围(maxLeft/maxTop)。代码包含调用者修复逻辑、坐标计算及边界限制算法,适用于需要自定义拖拽行为的Web开发场景。

文章目录

原生JS拖拽组件实现与使用

相关实现代码如下:

 
/* 
使用步骤如下:
实例化拖拽对象,指定容器ID及最大移动边界,例如:var d = new Drag({id:'dragPannel',maxLeft:500,maxTop:200});
调用初始化方法激活拖拽功能:d.ready();
开发时需注意以下关键点:
被拖动元素的left和top定位样式必须直接定义在style属性中,否则无法正确获取初始位置。
* 
*/ 
用于修正函数调用上下文的辅助函数,确保内部方法中的this指向正确的实例对象。
function repairCaller(newObj, fn){
return function(){
return fn.apply(newObj, arguments);
} 
} 
function Drag( config ){
this.moveTarget = T.dom.get( config.id );
this.startLeft = parseInt(this.moveTarget.style.left); //记录拖动开始前元素的left值
this.startTop = parseInt(this.moveTarget.style.top); //记录拖动开始前元素的top值
this.startClientX = this.startLeft; //保存拖动起始时的clientX坐标
this.startClientY = this.startTop; //保存拖动起始时的clientY坐标
this.MAX_LEFT = config.maxLeft||document.documentElement.clientWidth - this.moveTarget.offsetWidth; //计算允许的最大横向移动范围
this.MAX_TOP = config.maxTop||document.documentElement.clientHeight - this.moveTarget.offsetHeight; //计算允许的最大纵向移动范围
this.lock = true;
} 
Drag.prototype.ready = function(){
//绑定相关鼠标事件
T.bind(document, "mousedown", repairCaller(this,this.down));
T.bind(document, "mousemove", repairCaller(this,this.move));
T.bind(document, "mouseup", repairCaller(this,this.stop));
} 
Drag.prototype.down = function(){
//获取当前事件对象
var event = T.event.getEvent(arguments[0]),
target = T.event.getTarget(event);
if (target == this.moveTarget){
this.lock = false;
//在拖动开始时记录关键坐标数据
this.startLeft = parseInt(this.moveTarget.style.left);
this.startTop = parseInt(this.moveTarget.style.top);
this.startClientX = event.clientX;
this.startClientY = event.clientY;
} 
}; 
Drag.prototype.move = function(){
if(!this.lock ){
//获取当前事件对象
var event = T.event.getEvent(arguments[0]),
target = T.event.getTarget(event);
if(target == this.moveTarget){
//清除可能存在的文本选中状态
//window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
//计算当前拖动位置是否超出预设的最大限制
var realLeft = this.startLeft + event.clientX - this.startClientX, //计算实际横向偏移量
realTop = this.startTop + event.clientY - this.startClientY, //计算实际纵向偏移量
rightLeft , rightTop; //用于存储最终合法的left和top值
rightLeft = realLeft > this.MAX_LEFT ? this.MAX_LEFT : ( realLeft > 0 ? realLeft : 0 );
rightTop = realTop > this.MAX_TOP ? this.MAX_TOP : ( realTop > 0 ? realTop : 0 );
this.moveTarget.style.left = rightLeft + "px";
this.moveTarget.style.top = rightTop + "px";
} 
else{
this.lock = true;
} 
} 
}; 
Drag.prototype.stop = function(){
this.lock = true
}; 

开发注意事项与边界处理

开发总结:


在实现过程中需特别注意以下细节:


1、被拖动层的position定位、left和top属性必须显式写在style属性中。


2、在移动过程中动态设置left和top时,必须附带单位(如px),否则样式不生效。


3、若存在多级div嵌套结构,需为父级div添加overflow:hidden样式以防止溢出显示异常。


功能实现完毕!

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章