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 相关文章推荐
jQuery选择头像并实时显示的代码
Jun 27 Javascript
JS控制输入框内字符串长度
May 21 Javascript
Javascript中this关键字的一些小知识
Mar 15 Javascript
JavaScript控制网页层收起和展开效果的方法
Apr 15 Javascript
JS鼠标拖拽实例分析
Nov 23 Javascript
原生javascript实现自动更新的时间日期
Feb 12 Javascript
Angularjs中$http以post请求通过消息体传递参数的实现方法
Aug 05 Javascript
在js里怎么实现Xcode里的callFuncN方法(详解)
Nov 05 Javascript
bootstrap表单示例代码分享
May 18 Javascript
基于angular6.0实现的一个组件懒加载功能示例
Apr 12 Javascript
JavaScript计算出两个数的差值
Mar 19 Javascript
node.js 基于 STMP 协议和 EWS 协议发送邮件
Feb 14 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
php下使用SMTP发邮件的代码
2008/01/10 PHP
PHP SEO优化之URL优化方法
2011/04/21 PHP
windows下PHP_intl.dll正确配置方法(apache2.2+php5.3.5)
2014/01/14 PHP
Symfony2实现在controller中获取url的方法
2016/03/18 PHP
ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
2019/04/03 PHP
php如何实现数据库的备份和恢复
2020/11/30 PHP
Apache站点配置SSL强制跳转443
2021/03/09 Servers
深入理解javascript学习笔记(一) 编写高质量代码
2012/08/09 Javascript
parentElement,srcElement的使用小结
2014/01/13 Javascript
Javascript学习笔记之 函数篇(三) : 闭包和引用
2014/11/23 Javascript
使用jQuery处理AJAX请求的基础学习教程
2016/05/10 Javascript
深入理解JQuery中的事件与动画
2016/05/18 Javascript
js只执行1次的函数示例
2016/07/20 Javascript
js实现下拉框效果(select)
2017/03/28 Javascript
详解vue slot插槽的使用方法
2017/06/13 Javascript
浅谈JS对html标签的属性的干预以及对CSS样式表属性的干预
2017/06/25 Javascript
JavaScript原生实现观察者模式的示例
2017/12/15 Javascript
Vue 仿QQ左滑删除组件功能
2018/03/12 Javascript
Vue写一个简单的倒计时按钮功能
2018/04/20 Javascript
vue.js实现的全选与全不选功能示例【基于elementui】
2018/12/03 Javascript
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
2019/04/28 jQuery
Vue+Typescript中在Vue上挂载axios使用时报错问题
2019/08/07 Javascript
为Python程序添加图形化界面的教程
2015/04/29 Python
Python模块包中__init__.py文件功能分析
2016/06/14 Python
Python递归函数定义与用法示例
2017/06/02 Python
python3 发送任意文件邮件的实例
2018/01/23 Python
python编写简单端口扫描器
2019/09/04 Python
windows10在visual studio2019下配置使用openCV4.3.0
2020/07/14 Python
CSS3 新增选择器的实例
2019/11/13 HTML / CSS
图片上传插件ImgUploadJS:用HTML5 File API 实现截图粘贴上传、拖拽上传
2016/01/20 HTML / CSS
Canvas与图片压缩的示例代码
2017/11/28 HTML / CSS
Huda Beauty官方商店:化妆和美容产品
2020/09/05 全球购物
渡河少年教学反思
2014/02/12 职场文书
个人培训总结
2015/03/05 职场文书
Python 内置函数速查表一览
2021/06/02 Python
2021年最新用于图像处理的Python库总结
2021/06/15 Python