JavaScript动画-模拟拖拽
模拟拖拽的原理:
x1等于div.offsetLeft
y1等于div.offsetTop
x2等于ev.clientX(ev表示event事件)
y2等于ev.clientY
当我们在方块上按下鼠标的时候,x2-x1即可确定。移动鼠标之后,我们用鼠标当前的位置即x4、y4减去x2-x1、y2-y1就可以得到方块现在的位置。
效果图:点击查看
代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 #box{ 8 width: 100px; 9 height: 100px; 10 background: red; 11 position: absolute; 12 } 13 </style> 14 </head> 15 <body> 16 17 <div id="box"></div> 18 <script type="text/javascript"> 19 var oBox = document.getElementById('box'); 20 21 oBox.onmousedown = function(ev){ 22 // 鼠标按下 23 24 var ev = ev || event; 25 26 // 获取鼠标离div得距离 27 var mouseBoxleft = ev.clientX - this.offsetLeft; 28 var mouseBoxTop = ev.clientY - this.offsetTop; 29 30 oBox.onmousemove = function(ev){ 31 // 鼠标按下左键并移动 32 33 var ev = ev || event; 34 35 // 设置div移动时,它的位置 36 oBox.style.left = ev.clientX - mouseBoxleft + 'px'; 37 oBox.style.top = ev.clientY - mouseBoxleft + 'px'; 38 39 } 40 41 oBox.onmouseup = function(){ 42 // 鼠标左键抬起 43 44 oBox.onmousemove = oBox.onmouseup = null; 45 } 46 } 47 </script> 48 </body> 49 </html>
优化代码:
【1】鼠标移动快的时候,鼠标会移出方块,这时方块就不会再跟随鼠标动了。
解决办法:就是将onmousemove和onmouseup加到document对象上
效果:点击查看
代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 #box{ 8 width: 100px; 9 height: 100px; 10 background: red; 11 position: absolute; 12 } 13 </style> 14 </head> 15 <body> 16 17 <div id="box"></div> 18 <script> 19 var oBox = document.getElementById('box'); 20 21 oBox.onmousedown = function(ev){ 22 // 鼠标按下 23 24 var ev = ev || event; 25 26 // 获取鼠标离div得距离 27 var mouseBoxleft = ev.clientX - this.offsetLeft; 28 var mouseBoxTop = ev.clientY - this.offsetTop; 29 30 document.onmousemove = function(ev){ 31 // 鼠标按下左键并移动 32 33 var ev = ev || event; 34 35 // 设置div移动时,它的位置 36 oBox.style.left = ev.clientX - mouseBoxleft + 'px'; 37 oBox.style.top = ev.clientY - mouseBoxleft + 'px'; 38 39 } 40 41 document.onmouseup = function(){ 42 // 鼠标左键抬起 43 44 document.onmousemove = document.onmouseup = null; 45 } 46 } 47 </script> 48 </body> 49 </html>
【2】当要拖动的方块中有文字时会触发浏览器的默认行为
解决办法:1、使用return false添加到onmousedown事件中阻止浏览器的默认行为(IE除外)
2、使用全局捕获(IE)
1、使用return false添加到onmousedown事件中阻止浏览器的默认行为(IE除外)
效果:点击查看
代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 #box{ 8 width: 100px; 9 height: 100px; 10 background: red; 11 position: absolute; 12 top: 0; 13 left: 0; 14 } 15 </style> 16 </head> 17 <body> 18 19 <div id="box">模拟拖拽</div> 20 <script> 21 var oBox = document.getElementById('box'); 22 23 oBox.onmousedown = function(ev){ 24 // 鼠标按下 25 26 var ev = ev || event; 27 // 获取鼠标离div得距离 28 var mouseBoxleft = ev.clientX - this.offsetLeft; 29 var mouseBoxTop = ev.clientY - this.offsetTop; 30 31 document.onmousemove = function(ev){ 32 // 鼠标按下左键并移动 33 34 var ev = ev || event; 35 36 // 设置div移动时,它的位置 37 oBox.style.left = ev.clientX - mouseBoxleft + 'px'; 38 oBox.style.top = ev.clientY - mouseBoxleft + 'px'; 39 40 } 41 42 document.onmouseup = function(){ 43 // 鼠标左键抬起 44 45 document.onmousemove = document.onmouseup = null; 46 } 47 48 // 阻止默认行为 49 return false; 50 } 51 </script> 52 </body> 53 </html>
2、使用全局捕获(IE)
全局捕获:当我们给一个元素这只全局捕获后,改元素会监听后续发生的所有事件,当有事件发生的时候就会触发改元素的事件
举个栗子:点击查看
代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 </head> 7 <body> 8 <input type="button" id="button1" value="弹出1" /> 9 <input type="button" id="button2" value="弹出2" /> 10 <script type="text/javascript"> 11 window.onload = function(){ 12 var Btn1 = document.getElementById('button1'); 13 var Btn2 = document.getElementById('button2'); 14 15 Btn1.setCapture(); 16 17 Btn1.onclick = function(){ 18 alert(1); 19 } 20 Btn2.onclick = function(){ 21 alert(2); 22 } 23 24 25 } 26 </script> 27 </body> 28 </html>
给Btn1设置了全局捕获之后,即使我们点击了Btn2还是会触发Btn1的点击事件
在模拟拖拽中,给要拖拽的方块onmousedown添加全局捕获然后再onmouseup中取消全局捕获
效果:点击查看
代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 #box{ 8 width: 100px; 9 height: 100px; 10 background: red; 11 position: absolute; 12 13 } 14 </style> 15 </head> 16 <body> 17 18 <div id="box">模拟拖拽</div> 19 <script> 20 var oBox = document.getElementById('box'); 21 22 oBox.onmousedown = function(ev){ 23 // 鼠标按下 24 25 var ev = ev || event; 26 27 // 获取鼠标离div得距离 28 var mouseBoxleft = ev.clientX - this.offsetLeft; 29 var mouseBoxTop = ev.clientY - this.offsetTop; 30 31 // IE浏览器,全局捕获 32 if(oBox.setCapture){ 33 oBox.setCapture(); 34 } 35 36 document.onmousemove = function(ev){ 37 // 鼠标按下左键并移动 38 39 var ev = ev || event; 40 41 // 设置div移动时,它的位置 42 oBox.style.left = ev.clientX - mouseBoxleft + 'px'; 43 oBox.style.top = ev.clientY - mouseBoxleft + 'px'; 44 45 } 46 47 document.onmouseup = function(){ 48 // 鼠标左键抬起 49 50 document.onmousemove = document.onmouseup = null; 51 52 //IE下,释放全局捕获 releaseCapture(); 53 if ( oBox.releaseCapture ) { 54 oBox.releaseCapture(); 55 } 56 } 57 58 // 阻止默认行为 59 return false; 60 } 61 </script> 62 </body> 63 </html>
【3】封装模拟拖拽函数
效果:点击查看
代码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 #box{ 8 width: 100px; 9 height: 100px; 10 background: red; 11 position: absolute; 12 13 } 14 </style> 15 </head> 16 <body> 17 18 <div id="box">模拟拖拽</div> 19 <script> 20 var oBox = document.getElementById('box'); 21 22 drag(oBox); 23 24 function drag(obj){ 25 obj.onmousedown = function(ev){ 26 // 鼠标按下 27 28 var ev = ev || event; 29 30 // 获取鼠标离div得距离 31 var mouseBoxleft = ev.clientX - this.offsetLeft; 32 var mouseBoxTop = ev.clientY - this.offsetTop; 33 34 // IE浏览器,全局捕获 35 if(obj.setCapture){ 36 obj.setCapture(); 37 } 38 39 document.onmousemove = function(ev){ 40 // 鼠标按下左键并移动 41 42 var ev = ev || event; 43 44 // 设置div移动时,它的位置 45 obj.style.left = ev.clientX - mouseBoxleft + 'px'; 46 obj.style.top = ev.clientY - mouseBoxleft + 'px'; 47 48 } 49 50 document.onmouseup = function(){ 51 // 鼠标左键抬起 52 53 document.onmousemove = document.onmouseup = null; 54 55 //IE下,释放全局捕获 releaseCapture(); 56 if ( obj.releaseCapture ) { 57 obj.releaseCapture(); 58 } 59 } 60 61 // 阻止默认行为 62 return false; 63 } 64 } 65 66 </script> 67 </body> 68 </html>
不要在该奋斗的年纪而选择了安逸