JQuery之拖拽插件实现代码


Posted in Javascript onApril 14, 2011

而很多页面效果都要用到这些位置。不得已,得练练,得记记。
下面就来说说这个基于 JQuery的简易拖拽插件吧。
按惯例,先说说拖拽的原理,以及搞这么一个东东的步骤:
那什么是拖拽呢? 看名字就知道了:就是把一个东东拖来拽去的。 放到我们的DOM上,就是改变它的位置。
它只有两个难点:1、如何知道是在拖? 2、如何知道从哪拖,拖到哪?
其实,这也算不上难点,毕竟两者都是基础的东西,关键在于熟练。
换到js 中,我们搞一个拖拽效果,大致有如下步骤:
1、让元素捕获事件(一般情况下,无非就是mousedown、mousemove、mouseup)
2、在mousedown时,标记开始拖拽,并获取元素及鼠标的位置。
3、在mousemove时,不断的获取鼠标的新位置,并通过相应的位置算法,来重新定位元素位置。
4、在mouseup时,结束拖拽。。。然后周而复始。
这中间,个需要注意的地方:被拖拽的元素,至少需要相对或绝对定位,否则拖拽不会有效果。
OK,不多说,无代码,无真相。相应的解释都在其中了:
下载:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 
<title>Jeremy - DragDrop Test !</title> 
<meta name="keywords" content="Javascript自由拖拽类" /> 
<script type="text/javascript" src="jquery-1.4.2.min.js"></script> 
<script type="text/javascript"> 
(function($) 
{ 
$.extend({ 
//获取鼠标当前坐标 
mouseCoords:function(ev){ 
if(ev.pageX || ev.pageY){ 
return {x:ev.pageX, y:ev.pageY}; 
} 
return { 
x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, 
y:ev.clientY + document.body.scrollTop - document.body.clientTop 
}; 
}, 
//获取样式值 
getStyle:function(obj,styleName) 
{ 
return obj.currentStyle ? obj.currentStyle[styleName] : document.defaultView.getComputedStyle(obj,null)[styleName]; 
// return obj.currentStyle ? obj.currentStyle[styleName] : document.defaultView.getComputedStyle(obj,null).getPropertyValue(styleName); 
} 
}); 
// 元素拖拽插件 
$.fn.dragDrop = function(options) 
{ 
var opts = $.extend({},$.fn.dragDrop.defaults,options); 
return this.each(function(){ 
//是否正在拖动 
var bDraging = false; 
//移动的元素 
var moveEle = $(this); 
//点击哪个元素,以触发移动。 
//该元素需要是被移动元素的子元素(比如标题等) 
var focuEle = opts.focuEle ? $(opts.focuEle,moveEle) : moveEle ; 
if(!focuEle || focuEle.length<=0) 
{ 
alert('focuEle is not found! the element must be a child of '+this.id); 
return false; 
} 
// initDiffX|Y : 初始时,鼠标与被移动元素原点的距离 
// moveX|Y : 移动时,被移动元素定位位置 (新鼠标位置与initDiffX|Y的差值) 
// 如果定义了移动中的回调函数,该对象将以参数传入回调函数。 
var dragParams = {initDiffX:'',initDiffY:'',moveX:'',moveY:''}; 
//被移动元素,需要设置定位样式,否则拖拽效果将无效。 
moveEle.css({'position':'absolute','left':'0','top':'0'}); 
//点击时,记录鼠标位置 
//DOM写法: getElementById('***').onmousedown= function(event); 
focuEle.bind('mousedown',function(e){ 
//标记开始移动 
bDraging = true; 
//改变鼠标形状 
moveEle.css({'cursor':'move'}); 
//捕获事件。(该用法,还有个好处,就是防止移动太快导致鼠标跑出被移动元素之外) 
if(moveEle.get(0).setCapture) 
{ 
moveEle.get(0).setCapture(); 
} 
//(实际上是鼠标当前位置相对于被移动元素原点的距离) 
// DOM写法:(ev.clientX + document.body.scrollLeft - document.body.clientLeft) - document.getElementById('***').style.left; 
dragParams.initDiffX = $.mouseCoords(e).x - moveEle.position().left; 
dragParams.initDiffY = $.mouseCoords(e).y - moveEle.position().top; 
}); 
//移动过程 
focuEle.bind('mousemove',function(e){ 
if(bDraging) 
{ 
//被移动元素的新位置,实际上鼠标当前位置与原位置之差 
//实际上,被移动元素的新位置,也可以直接是鼠标位置,这也能体现拖拽,但是元素的位置就不会精确。 
dragParams.moveX = $.mouseCoords(e).x - dragParams.initDiffX; 
dragParams.moveY = $.mouseCoords(e).y - dragParams.initDiffY; 
//是否限定在某个区域中移动. 
//fixarea格式: [x轴最小值,x轴最大值,y轴最小值,y轴最大值] 
if(opts.fixarea) 
{ 
if(dragParams.moveX<opts.fixarea[0]) 
{ 
dragParams.moveX=opts.fixarea[0] 
} 
if(dragParams.moveX>opts.fixarea[1]) 
{ 
dragParams.moveX=opts.fixarea[1] 
} 
if(dragParams.moveY<opts.fixarea[2]) 
{ 
dragParams.moveY=opts.fixarea[2] 
} 
if(dragParams.moveY>opts.fixarea[3]) 
{ 
dragParams.moveY=opts.fixarea[3] 
} 
} 
//移动方向:可以是不限定、垂直、水平。 
if(opts.dragDirection=='all') 
{ 
//DOM写法: document.getElementById('***').style.left = '***px'; 
moveEle.css({'left':dragParams.moveX,'top':dragParams.moveY}); 
} 
else if (opts.dragDirection=='vertical') 
{ 
moveEle.css({'top':dragParams.moveY}); 
} 
else if(opts.dragDirection=='horizontal') 
{ 
moveEle.css({'left':dragParams.moveX}); 
} 
//如果有回调 
if(opts.callback) 
{ 
//将dragParams作为参数传递 
opts.callback.call(opts.callback,dragParams); 
} 
} 
}); 
//鼠标弹起时,标记为取消移动 
focuEle.bind('mouseup',function(e){ 
bDraging=false; 
moveEle.css({'cursor':'default'}); 
if(moveEle.get(0).releaseCapture) 
{ 
moveEle.get(0).releaseCapture(); 
} 
}); 
}); 
}; 
//默认配置 
$.fn.dragDrop.defaults = 
{ 
focuEle:null, //点击哪个元素开始拖动,可为空。不为空时,需要为被拖动元素的子元素。 
callback:null, //拖动时触发的回调。 
dragDirection:'all', //拖动方向:['all','vertical','horizontal'] 
fixarea:null //限制在哪个区域拖动,以数组形式提供[minX,maxX,minY,maxY] 
}; 
})(jQuery); 
// test 
$(function(){ 
//限定区域,有回调函数。 
$('#dragDiv').dragDrop({fixarea:[0,$('#dragContainer').width()-50,0,$('#dragContainer').height()-50],callback:function(params){ 
$('#span1').text('X:'+params.moveX+' Y:'+params.moveY); 
}}); 
//默认设置 
$('#dragDiv1').dragDrop(); 
}); 
</script> 
</head> 
<body> 
<div id="dragContainer" style="position:relative;left:10px;top:10px;border:1px dashed blue;width:500px;height:500px;"> 
<div id="dragDiv" style="background-color:blue;height:50px;width:50px;"> 
</div> 
<div id="dragDiv1" style="border:1px solid red;height:50px;width:50px;"> 
</div> 
</div> 
<span id="span1"></span> 
</body> 
</html>
Javascript 相关文章推荐
js下获取div中的数据的原理分析
Apr 07 Javascript
详解JavaScript中getFullYear()方法的使用
Jun 10 Javascript
JavaScript中的this,call,apply使用及区别详解
Jan 29 Javascript
Bootstrap实现带动画过渡的弹出框
Aug 09 Javascript
jquery实现全选、全不选以及单选功能
Mar 23 jQuery
关于jQuery.ajax()的jsonp碰上post详解
Jul 02 jQuery
canvas轨迹回放功能实现
Dec 20 Javascript
详解vue-meta如何让你更优雅的管理头部标签
Jan 18 Javascript
详解实现一个通用的“划词高亮”在线笔记功能
Apr 23 Javascript
JavaScript Tab菜单实现过程解析
May 13 Javascript
vue实现多个echarts根据屏幕大小变化而变化实例
Jul 19 Javascript
javascript之Object.assign()的痛点分析
Mar 03 Javascript
jQuery创建插件的代码分析
Apr 14 #Javascript
Jquery公告滚动+AJAX后台得到数据
Apr 14 #Javascript
jquery中eq和get的区别与使用方法
Apr 14 #Javascript
基于jquery的blockui插件显示弹出层
Apr 14 #Javascript
强大的jquery插件jqeuryUI做网页对话框效果!简单
Apr 14 #Javascript
让textarea自动调整大小的js代码
Apr 12 #Javascript
javascript算法学习(直接插入排序)
Apr 12 #Javascript
You might like
Mysql的常用命令
2006/10/09 PHP
PHP中in_array函数使用的问题与解决办法
2016/09/11 PHP
php使用scandir()函数扫描指定目录下所有文件示例
2019/06/08 PHP
php接口隔离原则实例分析
2019/11/11 PHP
javascript 用记忆函数快速计算递归函数
2010/03/15 Javascript
javascript表格隔行变色加鼠标移入移出及点击效果的方法
2015/04/10 Javascript
jquery实现动态改变div宽度和高度
2015/05/08 Javascript
使用Chart.js图表库制作漂亮的响应式表单
2015/10/28 Javascript
jQuery表单验证插件解析(推荐)
2016/07/21 Javascript
JavaScript随机打乱数组顺序之随机洗牌算法
2016/08/02 Javascript
详解Vue 普通对象数据更新与 file 对象数据更新
2017/04/26 Javascript
JS运动特效之同时运动实现方法分析
2018/01/24 Javascript
详解超简单的react服务器渲染(ssr)入坑指南
2019/02/28 Javascript
JS利用prototype给类添加方法操作详解
2019/06/21 Javascript
最全vue的vue-amap使用高德地图插件画多边形范围的示例代码
2020/07/17 Javascript
[01:48]2018DOTA2亚洲邀请赛主赛事第二日五佳镜头 VG完美团战逆转TNC
2018/04/05 DOTA
Python 文件读写操作实例详解
2014/03/12 Python
Python读写Redis数据库操作示例
2014/03/18 Python
基于Python实现文件大小输出
2016/01/11 Python
Phantomjs抓取渲染JS后的网页(Python代码)
2016/05/13 Python
Python爬虫包 BeautifulSoup  递归抓取实例详解
2017/01/28 Python
python实现简易版计算器
2020/06/22 Python
浅谈django2.0 ForeignKey参数的变化
2019/08/06 Python
Python实现遗传算法(二进制编码)求函数最优值方式
2020/02/11 Python
python实现坦克大战
2020/04/24 Python
解决python的空格和tab混淆而报错的问题
2021/02/26 Python
诺心蛋糕官网:LE CAKE
2018/08/25 全球购物
HomeAway澳大利亚:预订你的度假屋,公寓、度假村、别墅等
2019/02/20 全球购物
中国专业的音频分享平台:喜马拉雅
2019/05/24 全球购物
Java中会存在内存泄漏吗,请简单描述
2016/12/22 面试题
高级Java程序员面试要点
2013/08/02 面试题
贷款担保书范文
2014/05/13 职场文书
预备党员党支部意见
2015/06/02 职场文书
单位工资证明范本
2015/06/12 职场文书
《扇形统计图》教学反思
2016/02/17 职场文书
面试分析分布式架构Redis热点key大Value解决方案
2022/03/13 Redis