js学习笔记29----拖拽
原理:先计算鼠标与拖拽目标的左侧距离 跟 上面距离,再计算拖动后的位置。
示例代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <title>拖拽原理</title> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <style type="text/css"> 8 #moveBlock{ 9 width:100px;height:100px;background-color:#f00;position:absolute 10 } 11 </style> 12 <script> 13 14 window.onload = function(){ 15 var oDiv = document.getElementById("moveBlock"); 16 oDiv.onmousedown = function(ev){ 17 var ev = ev || event; 18 var disX = ev.clientX - this.offsetLeft; //计算鼠标与当前div左侧距离 19 var disY = ev.clientY - this.offsetTop; //计算鼠标与当前div顶侧距离 20 21 document.onmousemove = function(ev){ 22 var ev = ev || event; 23 oDiv.style.left = ev.clientX - disX + "px";//计算拖动后与左侧的距离 24 oDiv.style.top = ev.clientY - disY + "px";//计算拖动后与顶部的距离 25 } 26 27 document.onmouseup = function(){ 28 document.onmousemove = document.onmouseup = null; 29 } 30 31 } 32 } 33 34 </script> 35 </head> 36 <body> 37 <div id="moveBlock"> 38 39 </div> 40 </body> 41 </html>
我们运行上面的代码如果只是一个单纯的div没什么问题,但是如果同时有文字选中之后,再拖动div会发现有问题。
那是因为当鼠标按下的时候,如果页面中有文字被选中,那么会触发浏览器默认的文字拖拽效果。
解决方案:
标准:用return false; 阻止事件默认行为
非标准ie :用setCapture()设置全局捕获,当我们给一个元素设置全局捕获以后,那么这个元素就会监听后续发生的所有事情,当有事件发生的时候,就会被当前设置了全局捕获的元素所触发。
setCapture()兼容性:
ie : 有,并且有效果
ff : 有,但是没效果
chorme : 没有
具体代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <title>拖拽改进版</title> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <style type="text/css"> 8 #moveBlock{ 9 width:100px;height:100px;background-color:#f00;position:absolute 10 } 11 </style> 12 <script> 13 14 window.onload = function(){ 15 var oDiv = document.getElementById("moveBlock"); 16 oDiv.onmousedown = function(ev){ 17 var ev = ev || event; 18 var disX = ev.clientX - this.offsetLeft; 19 var disY = ev.clientY - this.offsetTop; 20 //设置全局捕获 21 if(oDiv.setCapture){ 22 oDiv.setCapture(); 23 } 24 25 document.onmousemove = function(ev){ 26 var ev = ev || event; 27 oDiv.style.left = ev.clientX - disX + "px"; 28 oDiv.style.top = ev.clientY - disY + "px"; 29 } 30 31 document.onmouseup = function(){ 32 document.onmousemove = document.onmouseup = null; 33 //释放事件捕获 releaseCapture(); 34 if(oDiv.releaseCapture){ 35 oDiv.releaseCapture(); 36 } 37 } 38 39 return false; //阻止事件默认行为 40 41 } 42 } 43 44 </script> 45 </head> 46 <body> 47 <p> 48 原因:当鼠标按下的时候,如果页面中有文字被选中,那么会触发浏览器默认的文字拖拽效果。<br> 49 解决: 用return false; 阻止事件默认行为. 50 </p> 51 <div id="moveBlock"> 52 53 </div> 54 </body> 55 </html>
封装成一个拖拽函数:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <title>拖拽封装</title> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <style type="text/css"> 8 #moveBlock{ 9 width:100px;height:100px;background-color:#f00;position:absolute 10 } 11 </style> 12 <script> 13 14 window.onload = function(){ 15 16 var oDiv = document.getElementById("moveBlock"); 17 drag(oDiv); 18 19 function drag(obj){ 20 obj.onmousedown = function(ev){ 21 var ev = ev || event; 22 var disX = ev.clientX - this.offsetLeft; 23 var disY = ev.clientY - this.offsetTop; 24 25 if(obj.setCapture){ 26 obj.setCapture; 27 } 28 29 document.onmousemove = function(ev){ 30 var ev = ev || event; 31 obj.style.left = ev.clientX - disX + "px"; 32 obj.style.top = ev.clientY - disY + "px"; 33 } 34 35 document.onmouseup = function(){ 36 document.onmousemove = document.onmouseup = null; 37 //释放事件捕获 releaseCapture(); 38 if(obj.releaseCapture){ 39 obj.releaseCapture(); 40 } 41 } 42 43 return false; //阻止事件默认行为 44 45 } 46 } 47 48 } 49 50 </script> 51 </head> 52 <body> 53 <p> 54 原因:当鼠标按下的时候,如果页面中有文字被选中,那么会触发浏览器默认的文字拖拽效果。<br> 55 解决: 用return false; 阻止事件默认行为. 56 </p> 57 <div id="moveBlock"> 58 59 </div> 60 </body> 61 </html>