JavaScript 简单拖放效果

本文详细介绍了使用JavaScript实现拖拽效果的基本原理与步骤。通过分析JesktopDrag类的构造及事件处理过程,如mousedown、mousemove和mouseup,展示了如何使元素在网页上拖动并限制其移动范围。

在拖拽的过程中,这些文字不会被选中.

Drag Me!!
拖放状态: 拖放未开始.

程序说明:

    拖放效果,也叫拖拽、拖动,学名Drag-and-drop ,是最常见的js特效之一。在多处地方能见,例如QQ空间摆设时~
这是一个最简单的拖拽,不带Handle,只给于拖拽和限定范围。所以原理很简单,但是重要在细节方面。而往往细节确是最容易忽略的,尤其是在Javascript里,需要对多种浏览器进行测试,这是很多语言都不需要的。

程序原理:

    这里以JesktopDrag为例,来介绍拖拽的原理。
    这里利用了对象字面量来完成了整个类,类中的init为主要处理方法。
    拖拽的整个事件分析为  onmousedown -> onmousemove
                                        -> onmouseup 
    现在逐步分析:
    1. init:function(o,minX,maxX,minY,maxY){}  这个为运行的方法,其中对象o为obj既你需要的拖放的对象,而剩下的按顺序分别为X坐标最小值和最大值,Y坐标的最小值和最大值。然后从拖放的行为进行分析,拖放首先要点击鼠标,所以向对象o绑定事件,然后连接start方法:o.onmousedown = this.start;
    2. 在start方法中,按照事件分析来说,就需要绑定时间,而为了避免在鼠标移动过快的过程中,脱离了对象o。所以像document绑定事件,
document.onmousemove = JeskTopDrag.move;
document.onmouseup = JeskTopDrag.end;
在这里有些细节需要留意,由于鼠标点击的地方与对象o的边缘是有一定距离的,所以在开始时,我用o的x属性和y属性进行保存,以便移动的时候保持位,
o.x = e.clientX - JeskTopDrag.o.offsetLeft;
o.y = e.clientY - JeskTopDrag.o.offsetTop;
    3. 先来分析move方法,要对象o跟着鼠标运动?其实很简单,只需要把鼠标的位置放入对象o的top和left中就可以了,
o.style.left = e.clientX - o.x +'px';
o.style.top = e.clientY - o.y+ 'px'
    4. 最后一步则是当鼠标放开时,也就是触发事件onmouseup,当事件触发时运行end方法,只需要在这里把所有绑定的事件全部移除即可:
JeskTopDrag.o = document.onmousemove = document.onmouseup = null;

程序细节:

    下面将会分析下一些细节上的问题,往往也是最让最困惑,和最难解决的。有时候浏览器就不报错,就让你去找,结果还要翻过好几本出才能发现问题。
【关于this指针】
    关于this的讲解,很多书上都给于很详细的解释了。所以在这里我就不进一步去分析,毕竟我也只算的上一个新手。
    先从程序原理中的onmousedown中的this.start来说,这个时候的this指向谁?或者换个方向来说,谁有start方法?很明显就是类,也就是JeskTopDrag,那就是this=JeskTopDrag了?现在又有一个疑问了,那在逐步分析里,为什么还要用JeskTopDrag.move和JeskTopDrag.end呢?直接用this不就可以啦。现在先看看this的定义,“this指针是面向对象程序设计中的一项重要概念,它表示当前运行的对象。在实现对象的方法时,可以使用this指针来获得该对象自身的引用。”所以从概念可以得知,在onmousedown的start方法中使用this则是指向对象o,而move方法和end方法则是指向document,所以在使用this时一定要观察对象自身是指哪个!
【关于取消默认操作】
    什么是默认操作!也就是当你点击鼠标然后移动就可以把你要选择的字框起来,点击连接就发生连接事件,点击键盘上下键可以操作滚动条等等。
    以上的都称为默认操作。那为什么要取消默认操作?在刚开始写拖放的时候,没有取消默认操作就发生了一个严重的问题,在FireFox里,第二次拖放时,mousedown事件不能触发,原因很简单,就是默认操作所以影响的。在IE里,拖动时,会自动选取文字。很显然这些都不是我们所希望发生的。一开始我去寻求解决方法,然后发现了如何解决,就是使用取消默认操作的方法,方法如下:
Event.preventDefault();(W3C的取消默认方法)
Event.returnValue=false;(IE中的取消默认方法)
    好了,有了这2个我只要把他们放入onmousedown里就可以啦!放了后,发现FireFox的问题解决了。可是IE的问题仍然存在,哦。我把它们在放入onmousemove里,好!所有问题解决。
    然后用了一段时间后,在用<a>时发现了一个东西,只要return false;就可以取消<a>的默认操作了,然后我把return false;放入onmousedown和onmousemove中,也可以取消默认操作了。这样一来,只要使用return false;就可以轻松却消默认操作,而且还完全跨平台。
 
程序代码
 
Code
var JeskTopDrag = {
    o:
null,
 
    init:
function(o,minX,maxX,minY,maxY){
        o.onmousedown 
= this.start;
        o.minX 
= typeof minX != 'undefined'?minX:null;
        o.maxX 
= typeof maxX != 'undefined'?maxX:null;
        o.minY 
= typeof minY != 'undefined'?minY:null;
        o.maxY 
= typeof maxY != 'undefined'?maxY:null;
    },
    start:
function(e){
        
var o;
        e 
= JeskTopDrag.fixEvent(e);
        JeskTopDrag.o 
= o = this;
        o.x 
= e.clientX - JeskTopDrag.o.offsetLeft;
        o.y 
= e.clientY - JeskTopDrag.o.offsetTop;
        document.onmousemove 
= JeskTopDrag.move;
        document.onmouseup 
= JeskTopDrag.end;
        
return false;
    },
    move:
function(e){
        e 
= JeskTopDrag.fixEvent(e);
        
var oLeft,oTop,ex,ey,o = JeskTopDrag.o;
        ex 
= e.clientX - o.x;
        ey 
= e.clientY - o.y;
        
if( o.minX != null ) ex = Math.max( ex,o.minX );
        
if( o.maxX != null ) ex = Math.min( ex,o.maxX - o.offsetWidth );
        
if( o.minY != null ) ey = Math.max( ey,o.minY );
        
if( o.maxY != null ) ey = Math.min( ey,o.maxY - o.offsetHeight );
        o.style.left 
= ex + 'px';
        o.style.top 
= ey + 'px';
        
return false;
    },
 end:
function(e){
        e 
= JeskTopDrag.fixEvent(e);
        JeskTopDrag.o 
= document.onmousemove = document.onmouseup = null;
    },
    fixEvent: 
function(e){
        
if (!e) {
            e 
= window.event;
            e.target 
= e.srcElement;
            e.layerX 
= e.offsetX;
            e.layerY 
= e.offsetY;
        }
        
return e;
    }
}
 
 

转载于:https://www.cnblogs.com/jesktop/archive/2009/06/21/1507786.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值