JavaScript中的拖拽(以及Html5中的拖放)

JavaScript中的拖拽(以及Html5中的拖放)

原理:

html:

 <div id="div1"></div>

css:

  #div1{
      height:120px;
      width:120px;
      background:green;  
      position:absolute;
  }

javascript:

window.onload=function (){
    var obj=document.getElementById("div1");
    obj.onmousedown=function (ev){
        //获取鼠标相对 div的距离
         var e= ev || event;
         var relativeX=e.clientX-obj.offsetLeft;
         var relativeY=e.clientY-obj.offsetTop;
         //相对距离;
         //div太小,将事件加载document上;
    document.onmousemove=function (ev){
         //重新计算div的位置滴呀
         var e=ev || event;
         //这里我们还要限制物体运动的边界;
         var l=e.clientX-relativeX; //物体的位置,是以鼠标的位置来计算出来的
         var t=e.clientY-relativeY;
         l<0?l=0:null; //左边界
         l>document.documentElement.clientWidth-obj.offsetWidth?l=document.documentElement.clientWidth-obj.offsetWidth:null; //右边界
         t>document.documentElement.clientHeight-obj.offsetHeight?t=document.documentElement.clientHeight-obj.offsetHeight:null;//下边界
         t<0?t=0:null; //上边界
         
         obj.style.left=l+'px';
         obj.style.top=t+'px';
     }
     //当鼠标松开时候,清空
      document.onmouseup=function (){
        document.onmousemove=null;
        document.onmouseup=null; 
     }
     return false; //解决火狐中bug
    }
}

上面的代码是在可视的区域中运动的滴呀;

如果body的高度和宽度超出我们浏览大小,显出出了滚动条;

那么就要改进坐标的获取方式了;

如下:

 //得到鼠标的坐标滴哎呀
   function getPosition(e){
       var clientx=e.clientX;
       var clienty=e.clientY;
       var scrollLeft=document.body.scrollLeft || document.documentElement.scrollLeft;
       var scrollTop=document.body.scrollTop || document.documentElement.scrollTop;
       var x=clientx+scrollLeft;
       var y=clienty+scrollTop;
       return {x:x,y:y};
   }

接下来,我们再来总结:

无法拖出可视区(上面的就是)

无法拖出整个页面(上面的就是)

无法拖出某个父级元素

原理:

html:

  <div id="parent">
     <div id="son">
     </div>
  </div>

css:

 #parent{
     height:400px;
     width:400px;
     background:green;
     position:relative; 
     opacity:0.5;
     filter:alpha(opacity:50);
     margin:0 auto;
 }
 #son{
     height:80px;
     width:80px;
     background:red;
     opacity:0.5;
     filter:alpha(opacity:50);
     position:absolute;
      
 }

javascript:

 //然后son在parent中移动,但不能超出边框;
   window.onload=function (){
       var son=document.getElementById("son");
       var parent=document.getElementById("parent");
       son.onmousedown=function (ev){
           var e=ev || event;
            //鼠标坐标,是相对整个页面的滴啊
            //这里的offsetLeft 和 offsetTop 相对于parent的值滴呀
           var relativeX=e.clientX-son.offsetLeft;
           var relativeY=e.clientY-son.offsetTop;
            //将事件绑定在我们的document上
       document.onmousemove=function (ev){
           var e=ev || event;
           
           //物体在浏览其中移动不用管,关键是限制他的边界;
           var x=e.clientX-relativeX;
           var y=e.clientY-relativeY;
           if(x<0){
             x=0;   
           }else if(x>(parent.offsetWidth-son.offsetWidth)){ //offsetWidth是他的盒子模型宽度
               x=parent.offsetWidth-son.offsetWidth;
           }
           if(y<0){
              y=0;   
           }else if(y>(parent.offsetHeight-son.offsetHeight)){
              y=parent.offsetHeight-son.offsetHeight;
           }
           son.style.left=x+'px';
           son.style.top=y+'px';
       }
       document.onmouseup=function(){
        document.onmousemove=null;
        document.onmouseup=null;   
       }
       
     }
   }

还有一个磁性吸附;

其实,所谓的磁性吸附,就就是当div快要到达边界的时候,马上让它到达边界,如;

if(x<10){

   x=0;

}//就是这种效果滴呀

上面的代码就能达到所谓的“磁性吸附的效果滴呀”。

 

上面的拖拽都是托的空的div,那么如果,div中有文字,或者div周围有文字呢?

 就会出现文本被选中的情况!

解决方法:在son.onmousedown=function (){

return false; //最后一步阻止默认的行为;

//能够解决chrom ff 中的bug;

//但是,没法解决ie9一下版本的兼容性问题

}

 但是ie有个独特的事件捕获的概念;

我们就可以利用者一点来解决这个bug

 document.onmouseup=function(){
       document.onmousemove=null;
       document.onmouseup=null;   
         if(son.setCapture!=undefined){
           son.releaseCaputre();
          }
       }
        if(son.setCapture!=undefined){
          son.setCaputre();
         }
       return false;
     }
   }

 终结版:带框的拖拽

好吧,最后带来我们的额终结版的拖拽!(完整代码如下)

<!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>无标题文档</title>
<style type="text/css">
 #parent{
     height:400px;
     width:400px;
     background:green;
     position:relative; 
     opacity:0.5;
     filter:alpha(opacity:50);
     margin:0 auto;
 }
 #son{
     height:80px;
     width:80px;
     background:red;
     opacity:0.5;
     filter:alpha(opacity:50);
     position:absolute;
      
 }
 .box{
     position:absolute;
     border:1px dashed black; 
 }
</style>
</head>

<body>
  <div id="parent">
     <div id="son">
       测试       测试       测试       测试       测试
     </div>
  </div>
</body>
<script type="text/javascript">
   //然后son在parent中移动,但不能超出边框;
   window.onload=function (){
       var son=document.getElementById("son");
       var parent=document.getElementById("parent");
       son.onmousedown=function (ev){
           var e=ev || event;
            //鼠标坐标,是相对整个页面的滴啊
            //这里的offsetLeft 和 offsetTop 相对于parent的值滴呀
           var relativeX=e.clientX-son.offsetLeft; 
           var relativeY=e.clientY-son.offsetTop;
            //将事件绑定在我们的document上
            //这里我们再创建一个div
            var ele_div=document.createElement('div');
            ele_div.className='box';//初始样式
            //初始高度宽度  --还要减去我们border
            ele_div.style.height=son.offsetHeight-2+'px';
            ele_div.style.width=son.offsetWidth-2+'px';
            //初始位置;
            ele_div.style.top=son.style.top;
            ele_div.style.left=son.style.left;
            
            //document.body.appendChild(ele_div);
            parent.appendChild(ele_div);
            document.onmousemove=function (ev){
           var e=ev || event;
           
           //物体在浏览其中移动不用管,关键是限制他的边界;
           var x=e.clientX-relativeX;
           var y=e.clientY-relativeY;
           if(x<10){
             x=0;   
           }else if(x>(parent.offsetWidth-son.offsetWidth)){ //offsetWidth是他的盒子模型宽度
               x=parent.offsetWidth-son.offsetWidth;
           }
           if(y<10){
              y=0;   
           }else if(y>(parent.offsetHeight-son.offsetHeight)){
              y=parent.offsetHeight-son.offsetHeight;
           }
           //移动的仅仅是我们的虚框;
           ele_div.style.left=x+'px';
           ele_div.style.top=y+'px';
       }
       document.onmouseup=function(){
         son.style.left=ele_div.style.left;
         son.style.top=ele_div.style.top;
         //并且移除该该元素
       //document.body.removeChild(ele_div);
        parent.removeChild(ele_div);
       document.onmousemove=null;
       document.onmouseup=null;   
         if(son.setCapture!=undefined){
           son.releaseCaputre();
          }
       }
        if(son.setCapture!=undefined){
          son.setCaputre();//这样就算是解决了这个bug滴呀
         }
       return false;
     }
   }
</script>
</html>

 效果:

接下来是HTML5中的拖放到指定的位置滴呀;区分拖放的拖拽滴呀;

 

posted @ 2016-02-16 16:47  咕-咚  阅读(676)  评论(0编辑  收藏  举报