zoukankan      html  css  js  c++  java
  • 原来这样可以实现鼠标拖拽

    引言: 上次弄了图片放大镜效果(图片放大镜原来是这么回事),当时用到了clientX clientY 后来查询了一下这两个属性,发现居原来还可以用来做简单的拖拽。实现原理与放大镜那里一样,改变left 与top 的数值让 div 移动。

     1   #box{
     2          100px;
     3         height: 100px;
     4         border: 1px solid  red ;
     5         background: rgba(24,41,254,0.71);
     6         position: absolute;/* 使用绝对定位或者相对定位,使left和top起效达到移动效果。不过用绝对定位可以脱离文档流不影响布局。*/
     7         /*z-index: 9999;*/
     8     }
     9     #box2{
    10          100px;
    11         height: 100px;
    12         border: 2px darkcyan dashed;
    13         background: rgba(84,254,80,0.71);
    14         left: 200px;
    15         position: relative;
    16         top: 100px;
    17     }
    18 </style>
    19 <body>
    20         <div id="box">
    21 
    22         </div>
    23         <div id="box2">
    24 
    25         </div>
    26 
    27         <script>
    28             var box=document.getElementById("box");
    29 
    30             box.onmousedown=function () { // 鼠标按下触发事件
    31 
    32                 document.onmousemove=function (event) {  // 鼠标移动时获取焦点坐标,并赋予给box ,至于为什么用document不用box,我试过box,拖拽过快会出现box跟不上,
    33 
    34                     var event=event||window.event
    35 
    36                     var left=event.clientX; // 获取鼠标焦点坐标
    37                     var top=event.clientY;
    38 
    39                     box.style.left=left+'px'; // 焦点赋予给left 改变box 的left 已达到移动
    40                     box.style.top=top+'px';
    41 
    42                  /*  box.style.width=left+'px';// 使用这个还可以改变  box  的大小哦。。。。
    43                    box.style.height=top+'px';*/
    44                 };
    45                 document.onmouseup=function () { // 鼠标放开后停止移动
    46                     document.onmousemove=null;
    47                     document.onmouseup=null;
    48                 }
    49             }

    ps:  demo 演示平台又挂了,暂时不能演示demo 效果。

    --------------------------------------------------------------------2018-9-27更新补充-----------------------------------------------------------------

    上面的拖拽虽然成功了,但是却有一个问题,那就是

    var left=event.clientX; // 获取鼠标焦点坐标
    var top=event.clientY; box.style.left=left+'px'; // 焦点赋予给left 改变box 的left 已达到移动 box.style.top=top+'px';

    这里的意思是获取鼠标的焦点的 X Y坐标,然后将其赋值给 box 这个拖动块,所以就会造成一个问题,例如:当我们点击box 中间进行拖动时,鼠标焦点并不会停留在box 中间的点击位置,而是出现在右上角。就像这样:

    (图 ——1)

    所以为了避免这样糟糕的拖拽体验。我们要计算box 拖拽块的移动距离,也就是当鼠标点击块中间时,box 需要移动到鼠标点击的位置,这样在后面的跟随中就不会让自己的右上角变成鼠标的点击位置了。看图:

    (L表示left . T表示top):红线+绿线=焦点到边距的距离。假如此时我们拖拽box ,鼠标焦点会从中间跑到右上角如 图——1 那样,那么为了让鼠标保持在中间位置,我们需要让box  移动 绿线这么长的距离,而绿线距离等于焦点到边距的距离(红+绿)-红(box到边框的距离)=绿线。

    而如何获取红+绿的距离呢?上面代码中  event.clientX 就可以了,而红线的距离可以使用  event.clientX-box.getBoundingClientRect().left;  这个 getBoundingClientRect().left / top 可以获取box 到边距的距离,当然这里也可以使用 offset 来获取,二者区别是 如果有父级元素,且父级元素定位的话,offset

    获取的距离就是边框到父级元素的距离,如果父元素不是定位元素,那么子元素的offset值相对于 可视区窗口。而 getBoundingClientRect() 的值只相对于可视去窗口。

    直接上更新后的代码:

     1 <style>
     2     #box{
     3          100px;
     4         height: 100px;
     5         border: 1px solid  red ;
     6         background: rgba(24,41,254,0.71);
     7         position: absolute;/* 使用绝对定位或者相对定位,使left和top起效达到移动效果。不过用绝对定位可以脱离文档流不影响布局。*/
     8         /*z-index: 9999;*/
     9     }
    10     #box2{
    11          100px;
    12         height: 100px;
    13         border: 2px darkcyan dashed;
    14         background: rgba(84,254,80,0.71);
    15         left: 200px;
    16         position: relative;
    17         top: 100px;
    18     }
    19 </style>
    20 <body>
    21 拖拽测试
    22         <div id="box">
    23             拖动块
    24         </div>
    25         <div id="box2">
    26             固定块
    27         </div>
    28 
    29         <script>
    30             var box=document.getElementById("box");
    31 
    32             box.onmousedown=function (event) { // 鼠标按下触发事件
    33                 var event=event||window.event
    34 
    35                 var bf=event.clientX-box.getBoundingClientRect().left;
    36                 var bp=event.clientY-box.getBoundingClientRect().top;
    37 
    38                 box.setCapture && box.setCapture(); // 阻止鼠标全选影响拖拽的方法,此为了兼容IE8,别的浏览器不支持 setCapture 属性,所以要在这里做浏览器判断,先判断是否支持此属性
    39 
    40 
    41 
    42                 document.onmousemove=function (event) {  // 鼠标移动时获取焦点坐标,并赋予给box ,至于为什么用document不用box,我试过box,拖拽过快会出现box跟不上,
    43 
    44                     var event=event||window.event
    45 
    46                     var left=event.clientX-bf; // 获取鼠标焦点坐标
    47                     var top=event.clientY-bp;
    48 
    49                     box.style.left=left+'px'; // 焦点赋予给left 改变box 的left 已达到移动
    50                     box.style.top=top+'px';
    51 
    52                  /*  box.style.width=left+'px';// 还可以改变box 的大小。。。。
    53                    box.style.height=top+'px';*/
    54                 };
    55                 document.onmouseup=function () { // 鼠标放开后停止移动
    56                     document.onmousemove=null;
    57                     document.onmouseup=null;
    58 
    59                     box.releaseCapture&&box.releaseCapture()  // 去除 setCapture,防止反复触发该属性,兼容IE8,也只有IE 支持所以这里也要判断
    60 
    61 }
    62
    63 return false;// 浏览器全选时影响拖拽,此时用这个可以阻止
    64 }
    65
    66
    67 </script>
    68 </body>

    补充 上面的  提到的 :return false;// 浏览器全选时影响拖拽,此时用这个可以阻止  

    以及 : box.setCapture && box.setCapture(); // 阻止鼠标全选影响拖拽的方法,此为了兼容IE8,别的浏览器不支持 setCapture 属性,所以要在这里做浏览器判断,先判断是否支持此属性

    如果不加,这个就会导致下面这种情况,当全选时,拖动移动框会影响周边元素的影子一起动,加了上面的代码声明可以阻止浏览器的行为,阻止下面情况发生:

  • 相关阅读:
    mysql慢查询日志
    VS中MFC连接MySQL的方法【转】
    localtime函数时区问题
    gethostbyname()函数【转】
    剪切板操作
    C/C++字符串查找函数 【转】
    vs2013出现IntelliSense错误,但是错误又不影响使用的消除办法
    c语言基础精讲加实例(个人觉得复习基础挺好的,)
    vs2013下qt工程调用自建的lib库函数教程
    取出16进制位对应位数的数字是0还是1(C语言)
  • 原文地址:https://www.cnblogs.com/wxhhts/p/9706170.html
Copyright © 2011-2022 走看看