《JavaScript学习笔记》:拖拽

《JavaScript学习笔记》:拖拽

拖拽在我们的生活中比较常见,原理也不难,如下:

假设有一个框,我们想要这个框有拖拽行为,拖拽行为就是跟着我们的鼠标移动而移动,而获取鼠标的位置的方法为:

var x = oEvent.clientX;
var y = oEvent.clientY;

当我们鼠标点击(鼠标点击对应onmousedown事件)时,我们记录鼠标此时的位置与框的距离(即图示中所表明的disX,disY),而disX是有鼠标所在的位置的横坐标和框的left决定,而disY是由鼠标所在的位置的纵坐标和框的top决定,因此,如下

var disX = oEvent.clientX-oDiv.offsetLeft;
var disY = oEvent.clientY-oDiv.offsetTop;

在我们移动鼠标的过程中,我们只需要保持框的left和top与鼠标的距离始终保存在disX、disY的距离即可。

下面我们就来看看拖拽的具体实现:

<font color='red' size=4>1、下面是拖拽的第一个版本</font>

    <!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>无标题文档</title>
    <style>
    #div1 {width:200px;height:200px;background:red;display:block;position:absolute;}
    </style>

    <script>
    window.onload=function()
    {
        var oDiv = document.getElementById('div1');


        oDiv.onmousedown=function(ev)
        {
            var oEvent = ev||event;
            var disX = oEvent.clientX - oDiv.offsetLeft;
            var disY = oEvent.clientY - oDiv.offsetTop;
            oDiv.onmousemove=function(ev)
            {
                var oEvent = ev||event;
                var l=oEvent.clientX - disX;
                var t=oEvent.clientY - disY;

                oDiv.style.left=l+'px';
                oDiv.style.top=t+'px';
            };
            oDiv.onmouseup=function()
            {
                oDiv.onmousemove=null;
                oDiv.onmouseup=null;
            };

            return false;

        };
    };
    </script>
    </head>

    <body>
    <div id="div1">

    </div>
    </body>
    </html>

这个版本中有三个事件,分别是在div中的onmousedown、onmouseomve、onmouseup.即鼠标按键、鼠标移动、鼠标按键抬起。

这个版本有一点bug:这个版本只能满足缓慢的拖拽,当我们的鼠标移动的速度比较快时,鼠标就会移动出去,而框体就不能跟着我们鼠标移动了。

为解决这个问题,我们只需要将onmousemove和onmouseup这个事件绑定在document上就可以解决。具体看第二个版本的代码

2、第二个版本

代码如下:

        <!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>无标题文档</title>
    <style>
    #div1 {width:200px;height:200px;background:red;display:block;position:absolute;}
    </style>

    <script>
    window.onload=function()
    {
        var oDiv = document.getElementById('div1');


        oDiv.onmousedown=function(ev)
        {
            var oEvent = ev||event;
            var disX = oEvent.clientX - oDiv.offsetLeft;
            var disY = oEvent.clientY - oDiv.offsetTop;
            document.onmousemove=function(ev)
            {
                var oEvent = ev||event;
                var l=oEvent.clientX - disX;
                var t=oEvent.clientY - disY;

                oDiv.style.left=l+'px';
                oDiv.style.top=t+'px';
            };
            document.onmouseup=function()
            {
                document.onmousemove=null;
                document.onmouseup=null;
            };

            return false;

        };
    };
    </script>
    </head>

    <body>
    <div id="div1">

    </div>
    </body>
    </html>

3、第三个版本

拖拽,拖拽,我们拖拽的范围只允许在其界面中,而不允许被拖拽到界面之外,因此我们需要在第二个版本上加上一些限制条件。

例如,宽度的限制条件如下:

0<=oDiv.style.left<=document.documentElement.clientWidth-oDiv.offsetWidth;

高度限制条件也类似

0<=oDiv.style.top<=document.documentElement.clientHeight-oDiv.offsetHeight;

完整代码代码如下:

    <!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>无标题文档</title>
    <style>
    #div1 {width:200px;height:200px;background:red;display:block;position:absolute;}
    </style>

    <script>
    window.onload=function()
    {
        var oDiv = document.getElementById('div1');


        oDiv.onmousedown=function(ev)
        {
            var oEvent = ev||event;
            var disX = oEvent.clientX - oDiv.offsetLeft;
            var disY = oEvent.clientY - oDiv.offsetTop;
            document.onmousemove=function(ev)
            {
                var oEvent = ev||event;
                var l=oEvent.clientX - disX;
                var t=oEvent.clientY - disY;
                /*
                以下的一些判断处理时防止拖拽被拖出界面之外
                */
                if(l<0)//限制不能移出界面的左边
                {
                    l=0;
                }
                else if(l>document.documentElement.clientWidth-oDiv.offsetWidth)//限制不能移出界面的右边
                {
                    l=document.documentElement.clientWidth-oDiv.offsetWidth;
                }
                oDiv.style.left=l+'px';
                if(t<0)//限制不能移出界面的上边
                {
                    t=0;
                }
                else if(t>document.documentElement.clientHeight-oDiv.offsetHeight)//限制不能移出界面的下边
                {
                    t=document.documentElement.clientHeight-oDiv.offsetHeight;
                }
                oDiv.style.top=t+'px';
            };
            document.onmouseup=function()
            {
                document.onmousemove=null;
                document.onmouseup=null;
            };

            return false;

        };
    };
    </script>
    </head>

    <body>
    <div id="div1">

    </div>
    </body>
    </html>

以上基本上就是简单的一个面向过程的拖拽实现。

继承和拖拽

上面从第二个版本的拖拽到第三个版本的拖拽,只是多了一些限制条件,对于这个我们可以用面向对象的继承来尝试的解决这个问题。

首先,我们将第二个版本的拖拽改为面向对象的程序。将面向过程的程序更改为面向对象的程序的方法见博文《第一个面向对象的程序》。

更改后的代码如下:


    // JavaScript Document
    function Drag(id)
    {
        _this=this;
        this.oDiv = document.getElementById(id);
        this.disX=0;
        this.disY=0;

        this.oDiv.onmousedown=function(ev)
        {
            _this.fnDown(ev);
        };
    };
    Drag.prototype.fnDown=function (ev)
    {
        _this=this;
        var oEvent = ev||event;
        this.disX = oEvent.clientX - this.oDiv.offsetLeft;
        this.disY = oEvent.clientY - this.oDiv.offsetTop;
        document.onmousemove=function(ev)
        {
            _this.fnMove(ev);
        };
        document.onmouseup=function(ev)
        {
            _this.fnUp(ev);
        };

    };
    Drag.prototype.fnMove=function (ev)
    {
        var oEvent = ev||event;
        var l=oEvent.clientX - this.disX;
        var t=oEvent.clientY - this.disY;

        this.oDiv.style.left=l+'px';
        this.oDiv.style.top=t+'px';
    };
    Drag.prototype.fnUp=function ()
    {
        document.onmousemove=null;
        document.onmouseup=null;
    };

再利用上篇博文介绍了继承的相关知识,就可以得到第三个版本面向对象的程序,代码如下:

    // JavaScript Document
    function LimitDrag(id)//得到Drag的属性
    {
        Drag.call(this,id);
    };
    for(var i in Drag.prototype)
    {
        LimitDrag.prototype[i]=Drag.prototype[i];
    }

    //重写Drag的fnMove方法
    LimitDrag.prototype.fnMove=function(ev)
    {
        var oEvent = ev||event;
        var l=oEvent.clientX - this.disX;
        var t=oEvent.clientY - this.disY;
        /*
        以下的一些判断处理时防止拖拽被拖出界面之外
        */
        if(l<0)//限制不能移出界面的左边
        {
            l=0;
        }
        else if(l>document.documentElement.clientWidth-this.oDiv.offsetWidth)//限制不能移出界面的右边
        {
            l=document.documentElement.clientWidth-this.oDiv.offsetWidth;
        }
        this.oDiv.style.left=l+'px';
        if(t<0)//限制不能移出界面的上边
        {
            t=0;
        }
        else if(t>document.documentElement.clientHeight-this.oDiv.offsetHeight)//限制不能移出界面的下边
        {
            t=document.documentElement.clientHeight-this.oDiv.offsetHeight;
        }
        this.oDiv.style.top=t+'px';
    };

以上就是关于拖拽用面向对象和继承相关知识来实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值