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 相关文章推荐
juqery 学习之三 选择器 子元素与表单
Nov 25 Javascript
纯JS实现五子棋游戏兼容各浏览器(附源码)
Apr 24 Javascript
使用js如何实现全选与全不选
Dec 30 Javascript
jquery.validate使用时遇到的问题
May 25 Javascript
浅析JavaScript中的变量复制、参数传递和作用域链
Jan 13 Javascript
Node.js实现连接mysql数据库功能示例
Sep 15 Javascript
JavaScript编程设计模式之构造器模式实例分析
Oct 25 Javascript
详解webpack + react + react-router 如何实现懒加载
Nov 20 Javascript
仿京东快报向上滚动的实例
Dec 13 Javascript
深入了解JavaScript代码覆盖
Jun 13 Javascript
webpack打包html里面img后src为“[object Module]”问题
Dec 22 Javascript
JavaScript常用8种数组去重代码实例
Sep 09 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树的代码,可以嵌套任意层
2006/10/09 PHP
新版PHP极大的增强功能和性能
2006/10/09 PHP
坏狼php学习 计数器实例代码
2008/06/15 PHP
浅谈thinkphp的实例化模型
2015/01/04 PHP
PHP+MySQL删除操作实例
2015/01/21 PHP
PHP中static关键字以及与self关键字的区别
2015/07/01 PHP
thinkphp查询,3.X 5.0方法(亲试可行)
2017/06/17 PHP
php反射学习之依赖注入示例
2019/06/14 PHP
Aster vs Newbee BO5 第三场2.19
2021/03/10 DOTA
jquery的ajax从纯真网(cz88.net)获取IP地址对应地区名
2009/12/02 Javascript
Javascript解决常见浏览器兼容问题的12种方法
2010/01/04 Javascript
jQuery1.4.2与老版本json格式兼容的解决方法
2011/02/12 Javascript
弹出最简单的模式化遮罩层的js代码
2013/12/04 Javascript
谈谈JavaScript自定义回调函数
2015/10/18 Javascript
jQuery封装placeholder效果实现方法,让低版本浏览器支持该效果
2017/07/08 jQuery
ES6解构赋值实例详解
2017/10/31 Javascript
浅析前端路由简介以及vue-router实现原理
2018/06/01 Javascript
Vue父子传递实例讲解
2020/02/14 Javascript
vue+ESLint 配置保存 自动格式化代码
2020/03/17 Javascript
nuxt 页面路由配置,主页轮播组件开发操作
2020/11/05 Javascript
python正则表达式match和search用法实例
2015/03/26 Python
Python中用memcached来减少数据库查询次数的教程
2015/04/07 Python
谈谈Python进行验证码识别的一些想法
2016/01/25 Python
浅谈Python数据类型之间的转换
2016/06/08 Python
python3+selenium自动化测试框架详解
2019/03/17 Python
Python定时任务APScheduler的实例实例详解
2019/07/22 Python
Python多线程threading join和守护线程setDeamon原理详解
2020/03/18 Python
前端实现弹幕效果的方法总结(包含css3和canvas的实现方式)
2018/07/12 HTML / CSS
Alba Moda德国网上商店:意大利时尚女装销售
2016/11/14 全球购物
七年级音乐教学反思
2014/01/26 职场文书
拓展训练激励口号
2014/06/17 职场文书
房产销售独家委托书范本
2014/10/01 职场文书
2014年采购部工作总结
2014/11/20 职场文书
我是特种兵观后感
2015/06/11 职场文书
浅谈mysql增加索引不生效的几种情况
2021/06/23 MySQL
Python爬取奶茶店数据分析哪家最好喝以及性价比
2022/09/23 Python