原来这样可以实现鼠标拖拽

引言: 上次弄了图片放大镜效果(图片放大镜原来是这么回事),当时用到了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 属性,所以要在这里做浏览器判断,先判断是否支持此属性

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

原文地址:https://www.cnblogs.com/wxhhts/p/9706170.html