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怎么把&amp;字符换成&quot;&amp;amp:&quot;
Oct 19 Javascript
才发现的超链接js导致网页中GIF动画停止的解决方法
Nov 02 Javascript
JavaScript 捕获窗口关闭事件
Jul 26 Javascript
js定义对象或数组直接量时各浏览器对多余逗号的处理(json)
Mar 05 Javascript
js原生appendChild的bug解决心得分享
Jul 01 Javascript
浅谈使用MVC模式进行JavaScript程序开发
Nov 10 Javascript
angularjs封装bootstrap时间插件datetimepicker
Jun 20 Javascript
jQuery ready()和onload的加载耗时分析
Sep 08 Javascript
分享一个精简的vue.js 图片lazyload插件实例
Mar 13 Javascript
微信小程序自定义带价格显示日历效果
Dec 29 Javascript
angular组件间通讯的实现方法示例
May 07 Javascript
Vue获取微博授权URL代码实例
Nov 04 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
《五等分的花嫁》漫画完结!2020年10月第2期TV动画制作组换血!
2020/03/06 日漫
8个出色的WordPress SEO插件收集
2011/02/26 PHP
php中计算中文字符串长度、截取中文字符串的函数代码
2011/08/09 PHP
php使用smtp发送支持附件的邮件示例
2014/04/13 PHP
PHP开发框架kohana中处理ajax请求的例子
2014/07/14 PHP
javascript开发中因空格引发的错误
2010/11/08 Javascript
获取表单控件原始(初始)值的方法
2013/08/21 Javascript
整理AngularJS中的一些常用指令
2015/06/16 Javascript
使用requestAnimationFrame实现js动画性能好
2015/08/06 Javascript
jQuery实现验证年龄简单思路
2016/02/24 Javascript
举例讲解如何判断JavaScript中对象的类型
2016/04/22 Javascript
JS设置手机验证码60s等待实现代码
2017/06/14 Javascript
react-router4 嵌套路由的使用方法
2017/07/24 Javascript
JS实现的A*寻路算法详解
2018/12/14 Javascript
Vue3.0结合bootstrap创建多页面应用
2019/05/28 Javascript
微信小程序表单验证插件WxValidate的二次封装功能(终极版)
2019/09/03 Javascript
实例解析Python的Twisted框架中Deferred对象的用法
2016/05/25 Python
matplotlib调整子图间距,调整整体空白的方法
2018/08/03 Python
Python pip替换为阿里源的方法步骤
2019/07/02 Python
python在新的图片窗口显示图片(图像)的方法
2019/07/11 Python
Python+AutoIt实现界面工具开发过程详解
2019/08/07 Python
Python 写了个新型冠状病毒疫情传播模拟程序
2020/02/14 Python
python 负数取模运算实例
2020/06/03 Python
英国马莎百货官网:Marks & Spencer
2016/07/29 全球购物
万宝龙英国官网:Montblanc手表、书写工具、皮革和珠宝
2018/10/16 全球购物
乐高西班牙官方商店:LEGO Shop ES
2019/12/01 全球购物
SQL Server提供的3种恢复模型都是什么? 有什么区别?
2012/05/13 面试题
PyQt QMainWindow的使用示例
2021/03/24 Python
数控技术专科生自我评价
2014/01/08 职场文书
大学生的自我鉴定范文
2014/01/21 职场文书
银行简历自我评价
2014/02/11 职场文书
2014年个人债务授权委托书范本
2014/09/22 职场文书
入党积极分子个人总结
2015/03/02 职场文书
2016拓展训练心得体会范文
2016/01/12 职场文书
英语版自我评价,35句话轻松搞定
2019/10/08 职场文书
Java并发编程之Executor接口的使用
2021/06/21 Java/Android