鼠标拖拽的处理

下面代码中展示了"拖拽"应用

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>拖拽</title>
        <style>
            #box1{
                width:200px;
                height:200px;
                background-color:#bfa;
                position:absolute;
            }

            #box2{
                width:200px;
                height:200px;
                background-color:pink;
                position:absolute;
                left:300px;
                top:300px;
            }
        </style>

        <script>
            // 为onload绑定函数
            window.onload = function(){
                var box1 = document.getElementById("box1");
                box1.onmousedown = function(){
                    // alert("鼠标被按下了");
                    document.onmousemove = function(event){
                        // 兼容浏览器
                        event = event || window.event;
                        var left = event.clientX;
                        var top = event.clientY;
                        box1.style.left = left + "px";
                        box1.style.top = top + "px";
                    }
                }

                box1.onmouseup = function(){
                    document.onmousemove = null;
                }
            }
        </script>
    </head>
    <body>
        <div id="box1"></div>
        <div id="box2"></div>
    </body>
</html>

上面代码中,这个地方会有点问题

在这里插入图片描述

onmouseup不能绑定给box1,因为,当鼠标移动到box2的这个位置,由于position层级的原因,导致此时,鼠标已经脱离了box1,但是并不会触发.onmousemove事件,因为这句话此时绑定的对象是box1,意思是,我们要将鼠标直接接触box1,并松开鼠标左键时,才生效果,显然,上面虽然鼠标在box2上面(直接接触box2),但是,由于没有直接接触box1时,才松开的鼠标左键,所以,此时box1.onmousemove事件不会被触发,但是,此时由于事件的冒泡,导致,box1仍然可以移动也即是说,obj.onmouseup,obj.onmousemove、obj.onmousedown均需要直接接触到前面的DOM的对象"obj",这样才能触发响应的事件,当然即使是不直接的接触DOM中对应的obj,通过事件的冒泡得到的也可以

在这里插入图片描述

但是,上面,并不能满足我们想让box1,在鼠标移动到box2上时,就直接触发.onmouseup事件,而且.onmousemove不会被执行,最终的结果就是,.box1直接停在.box2的下面,因此,我们需要如下修改代码

<!DOCTYPE html>
<html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>拖拽</title>
        <style>
            #box1{
                width:200px;
                height:200px;
                background-color:#bfa;
                position:absolute;
            }

            #box2{
                width:200px;
                height:200px;
                background-color:pink;
                position:absolute;
                left:300px;
                top:300px;
            }
        </style>

        <script>
            // 为onload绑定函数
            window.onload = function(){
                var box1 = document.getElementById("box1");
                box1.onmousedown = function(){
                    // alert("鼠标被按下了");
                    document.onmousemove = function(event){
                        // 兼容浏览器
                        event = event || window.event;
                        var left = event.clientX;
                        var top = event.clientY;
                        box1.style.left = left + "px";
                        box1.style.top = top + "px";
                    }
                }

                document.onmouseup = function(){
                    console.log("触发了吗?");
                    document.onmousemove = null;
                }
            }
        </script>
    </head>
    <body>
        <div id="box1"></div>
        <div id="box2"></div>
    </body>
</html>

在这里插入图片描述

另外,需要特别注意的是,此时取消document.onmousemove的方法是,直接对该属性赋值为null,这个比较好理解,原来的document.onmousemove的属性值是一个函数对象的地址,指向的是函数,我们将该document.onmousemove的属性值修改为null之后,它将不会指向任何函数了

上面有个不完善的地方在于 ,我们将box1.onmouseup修改为document.onmouseup之后,产生了一个问题就是,我们会在文档的任何一个点击鼠标后,又松开后,就触发document.onmouseup事件,因此,我们需要在document.onmouseup里面添加如下代码

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>拖拽</title>
    <style>
        #box1 {
            width: 200px;
            height: 200px;
            background-color: #bfa;
            position: absolute;
        }

        #box2 {
            width: 200px;
            height: 200px;
            background-color: pink;
            position: absolute;
            left: 300px;
            top: 300px;
        }
    </style>

    <script>
        // 为onload绑定函数
        window.onload = function () {
            var box1 = document.getElementById("box1");
            box1.onmousedown = function () {
                // alert("鼠标被按下了");
                document.onmousemove = function (event) {
                    // 兼容浏览器
                    event = event || window.event;
                    var left = event.clientX;
                    var top = event.clientY;
                    box1.style.left = left + "px";
                    box1.style.top = top + "px";
                }

                // 一定要注意,这个要写在box1.onmousedown里面,不能写在box1.onmousedown的外面
                document.onmouseup = function () {
                    document.onmousemove = null;
                    alert("被触发了");
                    document.onmouseup = null;
                }
            }


        }
    </script>
</head>

<body>
    <div id="box1"></div>
    <div id="box2"></div>
</body>

</html>

在这里插入图片描述

另外,需要特别注意的一点时,我们写代码时,要注意应该把代码放在哪个位置,比如:上面红圈里面提到的内容,另外,特别要注意的一点是,虽然document.onmouseup要在box1.onmousedown触发之后,才有可能触发,但是由于onmouseup我绑定的对象是document,因此,只要在box1.onmousedown执行过之后,我们无论点击哪里再松开,就会触发document.onmouseup事件,因此,为了防止上面的情况发生,我们需要加入这个代码?,目的是为了让box1.onmousedown触发后,document.onmouseup只是执行一次,因为,如果,不加入下面这行代码的话,我们就没有取消document.onmouseup这个事件对应的函数

在这里插入图片描述

鼠标拖拽(二):解决鼠标点击后,位置不在原来在box1处的位置

在这里插入图片描述

修改代码如下所示:

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>拖拽(二)</title>
    <style>
        #box1 {
            width: 200px;
            height: 200px;
            background-color: #bfa;
            position: absolute;
        }

        #box2 {
            width: 200px;
            height: 200px;
            background-color: pink;
            position: absolute;
            left: 300px;
            top: 300px;
        }
    </style>

    <script>
        // 为onload绑定函数
        window.onload = function () {
            var box1 = document.getElementById("box1");
            box1.onmousedown = function (event) {
                // 兼容浏览器
                event = event || window.event;
                // 获取相对的位移
                /* 注意: 下面的offsetLeft和offsetRight是给此处的box1设置的,而不是给event设置的,*/
                var ol = event.clientX - box1.offsetLeft;
                var ot = event.clientY - box1.offsetTop;

                document.onmousemove = function (event) {
                    // 兼容浏览器
                    event = event || window.event;
                    var left = event.clientX;
                    var top = event.clientY;
                    box1.style.left = left -ol + "px";
                    box1.style.top = top - ot + "px";
                    /* box1.style.left = left - ol + "px";
                    box1.style.top = top - ot + "px"; */

                    // console.log("触发了吗???");
                }

                // 一定要注意,这个要写在box1.onmousedown里面,不能写在box1.onmousedown的外面
                document.onmouseup = function () {
                    document.onmousemove = null;
                    // alert("被触发了");
                    document.onmouseup = null;
                    // alert("被触发了");
                }
            }
        }
    </script>
</head>

<body>
    <div id="box1"></div>
    <div id="box2"></div>
</body>

</html>

但是,要思考的是,什么时候需要用到事件对象event

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

响应函数里面需要加上event这个时,也就是需要用到事件对象时,这意味着为某个DOM对象绑定事件句柄时,我们需要浏览器给我们提供该事件句柄对应的事件对象的某些属性时,因为,我们不知到这个是多少,浏览器是知道的,我们需要通过浏览器告诉我们,比如上面的event.clientX返回的是mouse(鼠标的水平偏移位置)

但是,上面的代码仍然有一部分问题

在这里插入图片描述

当我们用力按住box1时,并拖动时,会触发浏览器的默认"拖拽事件",也就是如下所述

在这里插入图片描述

出现上面这种情况是,并不会触发document.onmouseup对应的响应函数,造成不好的体验,为了,解决这个问题,可以在box1.onmousedown对应的响应函数里面加上"return false"来取消这种默认的行为

下面的这种情况,也是会出现这样的情况,具体可以参见视频的出现的情况

但是,值得注意的是,return false(针对上述的这种情况)这种取消默认的行为,在IE8里面不起作用
<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>拖拽(二)</title>
    <style>
        #box1 {
            width: 200px;
            height: 200px;
            background-color: #bfa;
            position: absolute;
        }

        #box2 {
            width: 200px;
            height: 200px;
            background-color: pink;
            position: absolute;
            left: 300px;
            top: 300px;
        }
    </style>

    <script>
        // 为onload绑定函数
        window.onload = function () {
            var box1 = document.getElementById("box1");
            box1.onmousedown = function (event) {
                // 兼容浏览器
                event = event || window.event;
                // 获取相对的位移
                /* 注意: 下面的offsetLeft和offsetRight是给此处的box1设置的,而不是给event设置的,*/
                var ol = event.clientX - box1.offsetLeft;
                var ot = event.clientY - box1.offsetTop;

                document.onmousemove = function (event) {
                    // 兼容浏览器
                    event = event || window.event;

                    /* if(box1.setCapture){
                        box1.setCapture();
                    } */

                    // 下面这种方法
                    box1.setCapture && box1.setCapture();
                    
                    var left = event.clientX;
                    var top = event.clientY;
                    box1.style.left = left -ol + "px";
                    box1.style.top = top - ot + "px";
                    /* box1.style.left = left - ol + "px";
                    box1.style.top = top - ot + "px"; */

                    // console.log("触发了吗???");
                }

                // 一定要注意,这个要写在box1.onmousedown里面,不能写在box1.onmousedown的外面
                document.onmouseup = function () {
                    document.onmousemove = null;
                    // alert("被触发了");
                    document.onmouseup = null;
                    // alert("被触发了");

                    /* if(box1.releaseCapture){
                        box1.releaseCapture();
                    } */

                    box1.releaseCapture && box1.releaseCapture();
                }
                return false;
            }
        }
    </script>
</head>

<body>
    加油
    <div id="box1"></div>
    <div id="box2"></div>
</body>

</html>

注意思考以下几个问题

1. 上面代码中的document.onmousemove放在了box1.onmousedown的里面,也就是说当box1.onmousedown被触发后,document.onmousemove这句话才可能被执行,也就是说,此时document.onmousemove对应的响应函数才能执行,同理,.document.onmousemove被执行后,只要它对应的响应函数不被去掉,那么,该响应函数,只要条件满足,随时可以被触发

2. 取消document.onmousemove的方法和取消box1.setCapture的方式不一样,个人觉得,差别在于document.onmousemove是我们自己创建的,setCapture是浏览器自带的

3. 注意&&和||的运用

在这里插入图片描述

上面的&&,||的运用均是针对利用||和&&两边是非布尔值的情况来用的,但是,蓝色方框和红色方框不一样的是,针对同一个属性的选择,这种触发是上面蓝色框上面的注释提到的情况,否则容易因程序出错,导致程序终止运行的情况

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值