仿物品栏拖放效果--jquery插件

来蓝色很久了,很少发过帖子,以后要像大家多学习发帖.
最近应项目需求,写了一个小小的jquery 拖放的插件,相对于jquery UI组件里面的draggable droppable效率更高,更轻便,也容易使用.
DEMO: http://cloverdesign.googlecode.com/svn/trunk/utils/drag.html

接受4个参数
              limit : window,//是否限制拖放范围, 默认限制当前窗口内
              drop:false,//是否drop
              handle:false,//拖动手柄(点哪里可以拖)
              finish:function () {}//回调函数

使用方法:
$('#xx').Drag({drop:'#yy',finish:change});
#xx是指可拖拽的DOM元素. #yy指 被拖拽的DOM元素可以放到哪个DOM元素里,finish是拖拽完成后的回调函数;

[html]<!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=gb2312" />
<title>物品栏拖拽--Drag and Drop</title>
<meta name="description" content="物品栏拖拽,拖放" />
<meta name="keywords" content="物品栏拖拽,拖放" />
<style type="text/css">
body{font:12px Verdana, Arial, "宋体", sans-serif;}
h1{font-size: 18px;font-family: 微软雅黑;font-weight:normal;}
h2{clear:both;font-size: 16px;margin: 0;padding: 5px;border-bottom: 1px solid #69c;color: #1a1;font-family: 微软雅黑;font-weight:normal;}
h3{margin: 0;font-size: 14px;font-family: 微软雅黑;font-weight:normal;}
p{clear:both;}
.author{position:fixed;_position: absolute;right:20px;top:20px;}
ul{clear:both;float: left;}
/*格子拖放*/
.grid li{float: left;list-style: none;width: 32px;height: 32px;border: 1px solid #ccc;background: #eee;margin: 5px;padding: 1px;-moz-user-select:none;}
.grid img{width:32px;height: 32px;}
.grid div{position: relative;}
.grid span{position: absolute;right:1px;top:1px;color: #fff;}
/*交换数据用的DIV*/
#tempBox{position: absolute;z-index:9999;}
/*单个拖放demo*/
#test{clear:both;width: 500px;margin: 30px;padding: 10px;line-height: 24px;background: #ccc;}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
</head>
<body>
<h1>拖放,拖拽,仿物品栏拖拽.</h1>
<h2>Drop Container</h2>
<ul class="drop grid">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<h2>Drags</h2>
<ul class="drag grid">
<li id="l1"><div><img src="http://cloverdesign.googlecode.com/svn/trunk/utils/icon/img-1198795645853.jpg" alt="" title="" /><span>2</span></div></li>
<li id="l2"><div><img src="http://cloverdesign.googlecode.com/svn/trunk/utils/icon/img-1198795645855.jpg" alt="" title="" /><span>23</span></div></li>
<li id="l3"><div><img src="http://cloverdesign.googlecode.com/svn/trunk/utils/icon/img-1198795645857.jpg" alt="" title="" /><span>1</span></div></li>
<li id="l4"><div><img src="http://cloverdesign.googlecode.com/svn/trunk/utils/icon/img-1198795645861.jpg" alt="" title="" /><span>13</span></div></li>
<li id="l5"><div><img src="http://cloverdesign.googlecode.com/svn/trunk/utils/icon/img-1198795645862.jpg" alt="" title="" /><span>13</span></div></li>
<li id="l1"><div><img src="http://cloverdesign.googlecode.com/svn/trunk/utils/icon/img-1198795645864.jpg" alt="" title="" /><span>2</span></div></li>
<li id="l2"><div><img src="http://cloverdesign.googlecode.com/svn/trunk/utils/icon/img-1198795645866.jpg" alt="" title="" /><span>23</span></div></li>
<li id="l3"><div><img src="http://cloverdesign.googlecode.com/svn/trunk/utils/icon/img-1198795645868.jpg" alt="" title="" /><span>1</span></div></li>
<li id="l4"><div><img src="http://cloverdesign.googlecode.com/svn/trunk/utils/icon/img-1198795645869.jpg" alt="" title="" /><span>13</span></div></li>
</ul>
<div id="test">
<h2>标题拖动</h2>
<p>这是一个JQ拖放插件.</p>
<h3>功能:</h3>
<ol>
<li>限制拖动范围</li>
<li>可设置是否可放置(drop) 及可放置(drop)位置</li>
<li>设置拖动手柄</li>
<li>拖动完成后回调函数</li>
</ol>
<p>类似物品栏里的物品可相互拖拽,而且可以有限制拖放.如:下面格子里的东西可以拖到上面 但是不能拖到下面的其他格子里; 上面格子里的东西可以在上下格子里任意拖放</p>
</div>
<p>类似物品栏里的物品可相互拖拽,而且可以有限制拖放.如:下面格子里的东西可以拖到上面 但是不能拖到下面的其他格子里; 上面格子里的东西可以在上下格子里任意拖放</p>
<a href="http://cloverdesign.googlecode.com/svn/trunk/utils/dragdrop.rar" title="">代码下载</a>
<a href="http://blog.idealoft.net/" class="author" title="三叶草的博客" target="_blank">Clover's blog</a>
<script type="text/javascript">
<!--
//拖放插件DragDrop
$.fn.Drag=function (options) {
var defaults={
limit : window,//是否限制拖放范围,默认限制当前窗口内
drop:false,//是否drop
handle:false,//拖动手柄
finish:function () {}//回调函数
};
var options=$.extend(defaults,options);
this.X=0;//初始位置
this.Y=0;
this.dx=0;//位置差值
this.dy=0;
var This=this;
var ThisO=$(this);//被拖目标
var thatO;
if (options.drop) {
var ThatO=$(options.drop);//可放下位置
ThisO.find('div').css({cursor:'move'});
var tempBox=$('<div id="tempBox" class="grid"></div>');
}else {
options.handle ? ThisO.find(options.handle).css({cursor:'move','-moz-user-select':'none'}) : ThisO.css({cursor:'move','-moz-user-select':'none'});
}
//拖动开始
this.dragStart=function (e) {
var cX=e.pageX;
var cY=e.pageY;
if (options.drop) {
ThisO=$(this);
if (ThisO.find('div').length!=1) {return}//如果没有拖动对象就返回
This.X=ThisO.find('div').offset().left;
This.Y=ThisO.find('div').offset().top;
tempBox.html(ThisO.html());
ThisO.html('');
$('body').append(tempBox);
tempBox.css({left:This.X,top:This.Y});
}else {
This.X=ThisO.offset().left;
This.Y=ThisO.offset().top;
ThisO.css({margin:0})
}
This.dx=cX-This.X;
This.dy=cY-This.Y;
if (!options.drop) {ThisO.css({position:'absolute',left:This.X,top:This.Y})}
$(document).mousemove(This.dragMove);
$(document).mouseup(This.dragStop);
if ($.browser.msie) {ThisO[0].setCapture();}//IE,鼠标移到窗口外面也能释放
}
//拖动中
this.dragMove=function (e) {
var cX=e.pageX;
var cY=e.pageY;

if (options.limit) {//限制拖动范围
//容器的尺寸
var L=$(options.limit)[0].offsetLeft ? $(options.limit).offset().left : 0;
var T=$(options.limit)[0].offsetTop ? $(options.limit).offset().top : 0;
var R=L $(options.limit).width();
var B=T $(options.limit).height();
//获取拖动范围
var iLeft=cX-This.dx, iTop=cY-This.dy;
//获取超出长度
var iRight=iLeft parseInt(ThisO.innerWidth())-R, iBottom=iTop parseInt(ThisO.innerHeight())-B;
//alert($(window).height())
//先设置右下, 再设置左上
if(iRight > 0) iLeft -= iRight;

if(iBottom > 0) iTop -= iBottom;
if(L > iLeft) iLeft = L;
if(T > iTop) iTop = T;
if (options.drop) {
tempBox.css({left:iLeft,top:iTop})
}else {
ThisO.css({left : iLeft,top : iTop})
}
}else {
//不限制范围
if (options.drop) {
tempBox.css({left:cX-This.dx,top:cY-This.dy})
}else {
ThisO.css({left:cX-This.dx,top:cY-This.dy});
}
}

}
//拖动结束
this.dragStop=function (e) {
if (options.drop) {
var flag=false;
var cX=e.pageX;
var cY=e.pageY;
var oLf=ThisO.offset().left;
var oRt=oLf ThisO.width();
var oTp=ThisO.offset().top;
var oBt=oTp ThisO.height();
if (!(cX>oLf && cX<oRt && cY>oTp && cY<oBt)) {//如果不是在原位
for (var i=0; i<ThatO.length; i ) {
var XL=$(ThatO[i]).offset().left;
var XR=XL $(ThatO[i]).width();
var YL=$(ThatO[i]).offset().top;
var YR=YL $(ThatO[i]).height();
if (XL<cX && cX<XR && YL<cY && cY<YR) {//找到拖放目标 交换位置
var newElm=$(ThatO[i]).html();
$(ThatO[i]).html(tempBox.html());
ThisO.html(newElm);
thatO=$(ThatO[i]);
tempBox.remove();
flag=true;
break;//一旦找到 就终止循环
}
}
}
if (!flag) {//如果找不到拖放位置,归回原位
tempBox.css({left:This.X,top:This.Y});
ThisO.html(tempBox.html());
tempBox.remove();
}
}
$(document).unbind('mousemove');
$(document).unbind('mouseup');
options.finish(e,ThisO,thatO);
if ($.browser.msie) {ThisO[0].releaseCapture();}
}
//绑定拖动
options.handle ? ThisO.find(options.handle).mousedown(This.dragStart) : ThisO.mousedown(This.dragStart);

//IE禁止选中文本
//document.body.onselectstart=function(){return false;}
}
//下面是例子
//.drag li 里面的元素对应的放置位置是 .drop li, 完成后回调change函数,默认限制拖动范围是窗口内部
$('.drag li').Drag({drop:'.drop li',finish:change});
//.drag li 里面的元素对应的放置位置是 .drop li和.drag li(自身), 完成后回调change函数,默认限制拖动范围是窗口内部
$('.drop li').Drag({drop:'.drop li, .drag li',finish:change});
$('#test').Drag({handle:'h2',finish:change});//不限制拖动范围 可设置limit:false
var change=function (e,oldElm,newElm) {
//alert('拖动完成')
}
//-->
</script>
</body>
</html>[/html]

有话要说