javascript拖拽浅析

为了提高用户体验,让操作更便捷化,拖拽操作会很常见,比如操作系统里面,你要删除一个文件,你可以直接把它拖入回收站,wordpress也有类型的功能,你想在侧边栏增加一个板块,可以直接拖一个小工具过去就行了,这的确方便了很多。如何在网页里面实现拖拽,本文做一个简单的解析。

首先说一下拖拽的原理:

鼠标在目标上按下(mousedown)——>摁住鼠标不放,然后移动鼠标(mousemove)——>获取鼠标的坐标位置,让目标跟随鼠标——>鼠标释放(mouseup),让目标停止跟随。

drag_and_drop

(示意图)

基本原理就是这样的,具体一些扩展应用,比如把一个对象拖放到另一个容器里,只需要做进一步的判断就可以了。

获取鼠标位置(坐标)

在拖拽开始之前,我们需要先知道怎么得到鼠标的位置,不然拖拽就无法进行下去。

主要代码:

function getMousePos(e){
    var e=window.event||e;
  if(e.pageX||e.pageY){
     return {x:e.pageX,y:e.pageY};
  }
  return{
    x:e.clientX + document.body.scrollLeft-document.body.clientLeft,
    y:e.clientY + document.body.scrollTop-document.body.clientTop
  };
}

查看演示示例

简单的鼠标跟随效果

已经得到了鼠标的位置,下面可以设置一个对象,让它跟随鼠标移动,模仿拖拽的效果:

主要代码:

//创建drag对象
var drag=function(){
    this.position=document.getElementById('position');
  this.star=document.getElementById('follow');
  this.pos=null;
  this.follow=false;
  this.a=document.getElementsByTagName('a');
}

//获取坐标
drag.prototype.getMousePos=function(e){
    var e=window.event||e;
  if(e.pageX||e.pageY){
     return {x:e.pageX,y:e.pageY};
  }
  return{
    x:e.clientX + document.body.scrollLeft-document.body.clientLeft,
    y:e.clientY + document.body.scrollTop-document.body.clientTop
  };
}

//显示鼠标坐标值
drag.prototype.show=function(e){
   this.pos=this.getMousePos(e);
   this.position.innerHTML='x='+this.pos.x+', y='+this.pos.y;
   if(this.follow){this.star.style.cssText='left:'+(this.pos.x+10)+'px;top:'+this.pos.y+'px';}
}

//初始化
drag.prototype.init=function(){
     var that=this;
     document.onmousemove=function(e){that.show(e);}
   this.a[0].onclick=function(){that.follow=!that.follow;if(that.follow){this.innerHTML='停止跟随';}else{this.innerHTML='开始跟随';}}
   this.a[0].onfocus=function(){this.blur();}
}

var drag_demo=new drag();
drag_demo.init();

HTML代码:

<a href="javascript:void(0)">开始跟随</a>
<div id="position"> </div>
<div id="follow">ⓐ✿</div>

查看演示效果:

简单拖拽的实现

有了上面的基础,我们就可以实现拖拽效果,其实就是给目标对象绑定onmousedown事件,然后让它跟随鼠标移动,当document的onmouseup发生的时候,停止跟随鼠标。为什么要用document的onmouseup,自己可以在实践中测试一下,鼠标可能会跑到目标对象的外面去,设定document的onmouseup能够避免这种现象造成的不良后果。

主要代码:

//创建drag对象
var drag=function(){
    this.position=document.getElementById('position');
  this.star=document.getElementById('follow');
  this.pos=null;
  this.follow=false;
}

//获取坐标
drag.prototype.getMousePos=function(e){
    var e=window.event||e;
  if(e.pageX||e.pageY){
     return {x:e.pageX,y:e.pageY};
  }
  return{
    x:e.clientX + document.body.scrollLeft-document.body.clientLeft,
    y:e.clientY + document.body.scrollTop-document.body.clientTop
  };
}

//显示鼠标坐标值
drag.prototype.show=function(e){
   this.pos=this.getMousePos(e);
   if(this.follow){this.star.style.cssText='left:'+(this.pos.x-30)+'px;top:'+(this.pos.y-30)+'px';}
}

//初始化
drag.prototype.init=function(){
     var that=this;
     document.onmousemove=function(e){that.show(e);}
   this.star.onmousedown=function(){that.follow=true;}
   document.onmouseup=function(){that.follow=false;}
}

var drag_demo=new drag();
drag_demo.init();

查看演示示例:

完善一点的案例

上面的拖拽似乎还很原始,需要进一步的改进,稍做改动,增加了一些拖动的限制,主要代码如下:

//创建drag对象
var drag=function(){
    this.position=document.getElementById('position');
  this.star=document.getElementById('follow');
  this.areaBox=document.getElementById('area');
  this.a=document.getElementsByTagName('a');
  this.pos=null;
  this.follow=false;
  this.diffX=0;
  this.diffY=0;
  this.stopX=false;
  this.stopY=false;
  this.styleTemp='';
  this.area={xstart:100,xend:300,ystart:100,yend:300};
  this.setArea=false;
}

//获取坐标
drag.prototype.getMousePos=function(e){
    var e=window.event||e;
  if(e.pageX||e.pageY){
     return {x:e.pageX,y:e.pageY};
  }
  return{
    x:e.clientX + document.body.scrollLeft-document.body.clientLeft,
    y:e.clientY + document.body.scrollTop-document.body.clientTop
  };
}

//显示鼠标坐标值
drag.prototype.show=function(e){
   this.pos=this.getMousePos(e);
   if(this.follow){
      if(this.setArea){
       if((this.pos.x-this.diffX)<this.area.xstart){this.diffX=this.pos.x-this.area.xstart;}
     if((this.pos.x-this.diffX)>this.area.xend){this.diffX=this.pos.x-this.area.xend;}
     if((this.pos.y-this.diffY)<this.area.ystart){this.diffY=this.pos.y-this.area.ystart;}
     if((this.pos.y-this.diffY)>this.area.yend){this.diffY=this.pos.y-this.area.yend;}
     if(this.pos.x<this.area.xstart||this.pos.x>(this.area.xend+this.star.offsetWidth)||this.pos.y<this.area.ystart||(this.area.yend+this.star.offsetHeight)<this.pos.y){this.follow=false;}
    }
      this.styleTemp='';
      if(!this.stopX){this.styleTemp+='left:'+(this.pos.x-this.diffX)+'px;';}else{this.styleTemp+='left:'+(this.star.offsetLeft)+'px;';}
    if(!this.stopY){this.styleTemp+='top:'+(this.pos.y-this.diffY)+'px;';}else{this.styleTemp+='top:'+(this.star.offsetTop)+'px;';}
    this.star.style.cssText=this.styleTemp;
   }
}

//初始化
drag.prototype.init=function(){
     var that=this;
     document.onmousemove=function(e){that.show(e);}
   this.star.onmousedown=function(e){
       that.follow=true;
     that.pos=that.getMousePos(e);
     that.diffX=that.pos.x-this.offsetLeft;
     that.diffY=that.pos.y-this.offsetTop;
   }
   document.onmouseup=function(){that.follow=false;}
   this.a[0].onclick=function(){that.stopX=!that.stopX;that.stopY=false;}
   this.a[1].onclick=function(){that.stopY=!that.stopY;that.stopX=false;}
   this.a[2].onclick=function(){
         that.setArea=!that.setArea;
       if(that.setArea){
          that.star.style.cssText='left:100px;top:100px;';
        that.areaBox.style.display='block';
       }else{
          that.areaBox.style.display='none';
       }
   }
   this.a[3].onclick=function(){that.stopX=false;that.stopY=false;that.setArea=false;that.areaBox.style.display='none';}
}

var drag_demo=new drag();
drag_demo.init();

查看示例效果

拖拽应用实例

利用拖拽调节图片透明度,查看示例

另外,如果有兴趣,你还可以参考这篇文章

回复 (6)

  1. 11:20 下午, 2010年12月11日design  / 回复


    博客之家:

    今天周末,有空就更新一下吧

    最近比较忙,再过一段时间吧,其实有东西可写了,只是没空闲时间-_-

  2. 10:50 上午, 2010年12月11日博客之家  / 回复

    今天周末,有空就更新一下吧

  3. 2:37 下午, 2010年12月3日ugg classic tall  / 回复

    不错,演示和讲解的很详细。

  4. 4:39 下午, 2010年11月29日博客之家  / 回复

    一直在学习,但是总是受阻于代码太复杂

  5. 1:42 下午, 2010年11月10日spray gun  / 回复

    哇不错,演示的和讲解的比较详细。

  6. 7:59 下午, 2010年09月28日web前端寒风  / 回复

    多谢博主分析,学习了

发表评论

允许使用的标签 - 您可以在评论中使用如下的 HTML 标签以及属性。

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">