JQuery之拖拽插件实现代码

  而很多页面效果都要用到这些位置。不得已,得练练,得记记。

  下面就来说说这个基于 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>