JS div拖拽

基本思路:在鼠标按下时,以选定象作为拖拽 对象,改变其宽,高,左边距,上边距,造成按下效果,同时插入一同宽同高的空div到原位置.保持大包容器的形状.鼠标移动过程中,利用循环遍历各子项及 包容器,读取各div的位置信息,不断判断当前鼠标位置在哪个div之中,而且当鼠标在该div的上半部时,将先前创建的空div移动插入到其前,下半部 时插入其后,撑出一个位置,鼠标松开时,就在空div撑出的位置之前插入被拖拽对象,并且删除空div,实现拖拽.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="dragDrop.aspx.cs" Inherits="_Default" %>

<!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 runat="server">
<style>
body {margin:0px;padding:0px;font-size:12px;text-align:center;}
body > div {text-align:center; margin-right:auto; margin-left:auto;}
.content{width:900px;}
.content .left{
float:left;
width:20%;
border:1px solid #FF0000;
margin:3px;
}
.content .center{float:left;border:1px solid #FF0000;margin:3px;width:57%}
.content .right{float:right;width:20%;border:1px solid #FF0000;margin:3px}
.mo{height:auto;border:1px solid #CCC;margin:3px;background:#FFF}
.mo h1{background:#ECF9FF;height:18px;padding:3px;cursor:move}
.mo .nr{height:80px;border:1px solid #F3F3F3;margin:2px}
h1{margin:0px;padding:0px;text-align:left;font-size:12px}
</style>
<script>
var dragobj={}
window.onerror=function(){return false}
function on_ini()//初始化
{
     String.prototype.inc=function(s){return this.indexOf(s)>-1?true:false}//prototype是系统内置,此处是自行扩展判断一字符串内是否包含另一字符串
     var agent=navigator.userAgent//获取从客户端向服务器发送的HTTP协议用户代理头的值。
     window.isOpr=agent.inc("Opera")//判断代理头值是否包含字符Opera
     window.isIE=agent.inc("IE")&&!isOpr//判断代理头值是否包含字符IE
     window.isMoz=agent.inc("Mozilla")&&!isOpr&&!isIE//判断代理头值是否包含字符Mozilla
     if(isMoz)//如果是Mozilla的FireFox浏览器
     {
          Event.prototype.__defineGetter__("x",function(){return this.clientX+2})//扩展event的属性:鼠标x坐标
          Event.prototype.__defineGetter__("y",function(){return this.clientY+2})//扩展event的属性:鼠标y坐标
     }
     basic_ini()
}

function basic_ini()//基本初始化
{
     window.$=function(obj){return typeof(obj)=="string"?document.getElementById(obj):obj}//为当前网页添加方法:根据对象ID获取对象
     window.oDel=function(obj){if($(obj)!=null){$(obj).parentNode.removeChild($(obj))}}//为当前网页添加方法:删除对象
}
window.onload=function()//页面加载时
{
     on_ini()//初始化
     var o=document.getElementsByTagName("h1")// 获取所有的Div标题元素
     for(var i=0;i<o.length;i++)
     {
          o[i].onmousedown=function(e)//鼠标按下时
          {
               if(dragobj.o!=null)//如果被拖拽对象不为空(即前一对拖拽对象未释放)
                return false
               e=e||event//在某些浏览器中为e?
               dragobj.o=this.parentNode//o为一个Div标题,所以取其父节点即是DIV为被拖拽对象
               dragobj.xy=getxy(dragobj.o)//获取选中DIV边框外界相对客户区左边的坐标:上,左,宽,高
               dragobj.xx=new Array((e.x-dragobj.xy[1]),(e.y-dragobj.xy[0]))//鼠标以Div边框外界左上角为原点的坐标.
               dragobj.o.style.width=dragobj.xy[2]+"px"//设置div的宽(含边框)
               dragobj.o.style.height=dragobj.xy[3]+"px"//设置div的高(含边框)
               dragobj.o.style.left=(e.x-dragobj.xx[0])+"px"//设置div的左边距(边框外界至客户区左边内部的距离)
               dragobj.o.style.top=(e.y-dragobj.xx[1])+"px"//设置div的上边距(边框外界至客户区左边内部的距离)  
               dragobj.o.style.position="absolute"//设置坐标为绝对位置
               var om=document.createElement("div")//创建一个DIV
               dragobj.otemp=om//创建一个临时对象,内部不包含任何东西
               om.style.width=dragobj.xy[2]+"px"//设置临时对象宽度跟被拖拽对象相同
               om.style.height=dragobj.xy[3]+"px"//设置临时对象高度跟被拖拽对象相同
               dragobj.o.parentNode.insertBefore(om,dragobj.o)//将临时对象插入到被拖拽对象之前.占据被拖拽对象 原位置,而在鼠标移动过程中根据鼠标位置,其将被移到相应位置,在相应位置撑出一个空位.
               return false
          }
     }
}
document.onselectstart=function(){return false}//禁用选择文本
window.onfocus=function(){document.onmouseup()}//页面获得焦点
window.onblur=function(){document.onmouseup()}//页面失去焦点
document.onmouseup=function()//鼠标松开时
{
     if(dragobj.o!=null)//如果被拖拽对象不为空
     {
          dragobj.o.style.width="auto"
          dragobj.o.style.height="auto"
          dragobj.otemp.parentNode.insertBefore(dragobj.o,dragobj.otemp)//移动dragobj.o在dragobj.otemp之前插入
         
          dragobj.o.style.position=""
          oDel(dragobj.otemp)//删除临时对象dragobj.otemp
          dragobj={}//清空拖拽对象
     }
}
document.onmousemove=function(e)//鼠标移动时
{
     e=e||event
     if(dragobj.o!=null)//如果被拖拽对象不为空
     {
          dragobj.o.style.left=(e.x-dragobj.xx[0])+"px"//设置被拖对象的左边距(鼠标距客户端距离-鼠标距Div边框外界的距离)跟随移动
          dragobj.o.style.top=(e.y-dragobj.xx[1])+"px"//设置被拖对象的上边距(鼠标距客户端距离-鼠标距Div边框外界的距离)跟随移动
          createtmpl(e)//移动过程中移到哪插到那
     }
}
function getxy(e)
{
     var a=new Array()
     var t=e.offsetTop;
     var l=e.offsetLeft;
     var w=e.offsetWidth;
     var h=e.offsetHeight;
     while(e=e.offsetParent)
     {
          t+=e.offsetTop;
          l+=e.offsetLeft;
     }
     a[0]=t;a[1]=l;a[2]=w;a[3]=h
     return a;
}
function inner(o,e)
{
     var a=getxy(o)
     if(e.x>a[1]&&e.x<(a[1]+a[2])&&e.y>a[0]&&e.y<(a[0]+a[3]))//如果e坐标在o的范围之内
     {
          if(e.y<(a[0]+a[3]/2))//如果e坐标在o的上半部
              return 1;
          else
              return 2;//如果e坐标在o的下半部
     }
     else
          return 0;//如果e坐标在o的范围之外
}
function createtmpl(e)//在鼠标移动过程中插入临时对象
{
     for(var i=0;i<12;i++)//遍历内部所有子DIV
     {
          if($("m"+i)==dragobj.o)
             continue
          var b=inner($("m"+i),e)//判断e相对$("m"+i)的位置:上半部,下半部,外面
          if(b==0)//在外面
             continue
          dragobj.otemp.style.width=$("m"+i).offsetWidth
          if(b==1)//上半部
          {
               $("m"+i).parentNode.insertBefore(dragobj.otemp,$("m"+i))//在$("m"+i)的前面插入dragobj.otemp
          }
          else
          {
               if($("m"+i).nextSibling==null)//如果是最后一项
               {
                    $("m"+i).parentNode.appendChild(dragobj.otemp)//追加到后面
               }
               else
               {
                    $("m"+i).parentNode.insertBefore(dragobj.otemp,$("m"+i).nextSibling)//如果在下半部,则在其后一项之前插入
               }
          }
          return
     }
     for(var j=0;j<3;j++)//遍历三大包容DIV,因为上面的循环是在子项上发生的,如果包容DIV内部没子项,而鼠标又移到了上面时,则需下面的代码
     {
          if($("dom"+j).innerHTML.inc("div")||$("dom"+j).innerHTML.inc("DIV"))//如果包容器内有Div
                continue
          var op=getxy($("dom"+j))
          if(e.x>(op[1]+10)&&e.x<(op[1]+op[2]-10))//如果鼠标在三大包容DIV的左边框+10像素,右边框-10像素范围内
          {
               $("dom"+j).appendChild(dragobj.otemp)//在包容DIV子项最后追加dragobj.otemp
               dragobj.otemp.style.width=(op[2]-10)+"px"//设置新加子项宽度.
          }
     }
}
</script></head>
<body>
<<div class=content>
<div class=left id=dom0>
<div class=mo id=m0>
   <h1>dom0</h1>
   <div class="nr"></div>
</div>
<div class=mo id=m1>
   <h1>dom1</h1><div class="nr"></div>
</div>
<div class=mo id=m2><h1>dom2</h1><div class="nr"></div></div>
<div class=mo id=m3><h1>dom3</h1><div class="nr"></div></div>
</div>
<div class=center id=dom1>
<div class=mo id=m4><h1>dom4</h1><div class="nr"></div></div>
<div class=mo id=m5><h1>dom5</h1><div class="nr"></div></div>
<div class=mo id=m6><h1>dom6</h1><div class="nr"></div></div>
<div class=mo id=m7><h1>dom7</h1><div class="nr"></div></div>
</div>
<div class=right id=dom2>
<div class=mo id=m8><h1>dom8</h1><div class="nr"></div></div>
<div class=mo id=m9><h1>dom9</h1><div class="nr"></div></div>
<div class=mo id=m10><h1>dom10</h1><div class="nr"></div></div>
<div class=mo id=m11><h1>dom11</h1><div class="nr"></div></div>
</div>
</div>
</body>
</html>

posted @ 2009-05-07 15:54  imba  阅读(1042)  评论(0编辑  收藏  举报