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 相关文章推荐
测试JavaScript字符串处理性能的代码
Dec 07 Javascript
Javascript实现滑块滑动改变值的实现代码
Apr 12 Javascript
JavaScript 性能优化小结
Oct 12 Javascript
基于jquery实现鼠标滚轮驱动的图片切换效果
Oct 26 Javascript
JS实现的表格操作类详解(添加,删除,排序,上移,下移)
Dec 22 Javascript
js canvas实现擦除动画
Jul 16 Javascript
简单几步实现返回顶部效果
Dec 05 Javascript
jQuery实现弹窗下底部页面禁止滑动效果
Dec 19 jQuery
JS匿名函数和匿名自执行函数概念与用法分析
Mar 16 Javascript
Vue $emit $refs子父组件间方法的调用实例
Sep 12 Javascript
JSON.stringify()方法讲解
Jan 31 Javascript
微信小程序iBeacon测距及稳定程序的实现解析
Jul 31 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中获取关键词及所属来源搜索引擎名称的代码
2011/02/15 PHP
PHP针对常规模板引擎中与CSS/JSON冲突的解决方法
2014/08/19 PHP
destoon首页调用求购供应信息的地区名称的方法
2014/08/21 PHP
跟我学Laravel之路由
2014/10/15 PHP
PHP中的命名空间相关概念浅析
2015/01/22 PHP
PHP程序中使用adodb连接不同数据库的代码实例
2015/12/19 PHP
利用PHP实现一个简单的用户登记表示例
2017/04/25 PHP
Laravel 6.2 中添加了可调用容器对象的方法
2019/10/22 PHP
php + ajax 实现的写入数据库操作简单示例
2020/05/16 PHP
c#和Javascript操作同一json对象的实现代码
2012/01/17 Javascript
jquery实现弹出div,始终显示在屏幕正中间的简单实例
2014/03/08 Javascript
基于JavaScript获取鼠标位置的各种方法
2015/12/16 Javascript
AngularJS基础 ng-class-odd 指令示例
2016/08/01 Javascript
AngularJS基础 ng-keypress 指令简单示例
2016/08/02 Javascript
Angularjs中controller的三种写法分享
2016/09/21 Javascript
纯JS代码实现隔行变色鼠标移入高亮
2016/11/23 Javascript
electron demo项目npm install安装失败的解决方法
2018/02/06 Javascript
vue数据传递--我有特殊的实现技巧
2018/03/20 Javascript
再谈Angular4 脏值检测(性能优化)
2018/04/23 Javascript
使用bootstrap实现下拉框搜索功能的实例讲解
2018/08/10 Javascript
详解JS实现系统登录页的登录和验证
2019/04/29 Javascript
利用Python的Django框架中的ORM建立查询API
2015/04/20 Python
在CentOS上配置Nginx+Gunicorn+Python+Flask环境的教程
2016/06/07 Python
通过Python爬虫代理IP快速增加博客阅读量
2016/12/14 Python
python 动态加载的实现方法
2017/12/22 Python
django mysql数据库及图片上传接口详解
2019/07/18 Python
python3 图片 4通道转成3通道 1通道转成3通道 图片压缩实例
2019/12/03 Python
python 实现的IP 存活扫描脚本
2020/12/10 Python
3D动画《斗罗大陆》上线当日播放过亿
2021/03/16 国漫
微软新西兰官方网站:Microsoft New Zealand
2018/08/17 全球购物
大学生活学习的自我评价
2013/12/03 职场文书
技能比武方案
2014/05/21 职场文书
服装设计师求职信
2014/06/04 职场文书
篮球比赛口号
2014/06/10 职场文书
村主任“四风”问题个人对照检查材料思想汇报
2014/10/02 职场文书
求职简历自我评价范文
2015/03/10 职场文书