在日常业务中有很多时候会用到拖拽,比如弹窗什么的,还有一些导航什么的拖动组成自己喜欢的导航。今天就写了两个小例子带大家了解PC端和移动端的拖拽是怎么实现的。
PC端拖拽
pc端拖动主要是onmouse事件,当你鼠标对拖动目标点下时触发拖动目标的onmousedown事件,此时记录下鼠标点击的位置坐标和拖动目标的右上角坐标,得到二者之差,鼠标点下并且拖动触发document的onmousemove事件,获得不断移动的鼠标位置坐标,再减去之前得到的差值,把得到的Y轴移动值赋给top,X轴移动值赋给left;当鼠标松开时触发onmouseup事件,此时销毁document.onmousemove和拖动目标的onmousemove和事件,一个简单的拖拽就完成了。注意一下,当拖动是会有默认事件发生,比如往下拖动,如果有滚动条的话,会使滚动条滚动,这时需要阻止一下默认事件,event.preventDefault();
当然,如果你要限制范围的话,可以在onmousemove中吧Y轴移动值和X轴移动值用判断限制一下,我限制的是不能超过文档窗口,有兴趣可以改一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| function touch(id){ var obj = document.getElementById(id); obj.onmousedown = function(event){ var disX = event.pageX - obj.offsetLeft; var disY = event.pageY - obj.offsetTop; var W = document.documentElement.clientWidth-obj.offsetWidth; var H = document.documentElement.clientHeight-obj.offsetHeight; document.onmousemove = function(event){ event.preventDefault(); var l = event.pageX - disX; var t = event.pageY - disY; if(l<0){ l = 0; } if(l>W){ l = W ; } if(t<0){ t = 0; } if(t>H){ t = H; } obj.style.top = t+ 'px'; obj.style.left = l+'px'; } obj.onmouseup = function(){ document.onmousemove = null; obj.onmouseup = null; } } };
|
移动端拖拽
移动端的拖拽是由touch事件完成的,和PC的onmouse事件大致一样,touchstart是手指按下,可以通过event.targetTouches.length获得有多少手指按下,一般拖动一根手指,于是当event.targetTouches.length == 1时才能触发拖拽事件,event.targetTouches[0]相当于鼠标的event,通过这个可以获取手指按下的坐标,其余的大致和PC差不多。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| function touch(id){ var obj = document.getElementById(id); obj.addEventListener('touchstart', function(event) { if (event.targetTouches.length == 1) { var touch = event.targetTouches[0]; var disX=touch.pageX-obj.offsetLeft; var disY=touch.pageY-obj.offsetTop; var W = document.documentElement.clientWidth-obj.offsetWidth; var H = document.documentElement.clientHeight-obj.offsetHeight; obj.addEventListener('touchmove',move); function move(event){ event.preventDefault(); var touch2=event.targetTouches[0]; var l=touch2.pageX-disX; var t=touch2.pageY-disY; if(l<0){ l=0; }; if(l>W){ l=W; }; if(t<0){ t=0; }; if(t>H){ t=H; }; obj.style.left=l+'px'; obj.style.top=t+'px'; }; obj.addEventListener('touchend',chend); function chend(event){ obj.removeEventListener('touchmove',move); obj.removeEventListener('touchend',chend); }; }; }, false); };
|
不过有个地方要注意一下,移动端如果使用event.preventDefault();阻止默认事件的话,可能会对流畅度有点影响,如果你想应用到高级的浏览器上的话,就不要使用event.preventDefault();了,推荐的做法是用css中的touch-action来阻止默认事件,touch-action:none使触控事件发生在元素上时,不进行任何操作。也就是当touchstart发生时让html的touch-action为none,拖动完成touchend时,把html的touch-action改成auto就行了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| function touch(id){ var obj = document.getElementById(id); obj.addEventListener('touchstart', function(event) { if (event.targetTouches.length == 1) { var touch = event.targetTouches[0]; var disX=touch.pageX-obj.offsetLeft; var disY=touch.pageY-obj.offsetTop; obj.addEventListener('touchmove',move); function move(event){ document.documentElement.style.touchAction = 'none'; var touch2=event.targetTouches[0]; var l=touch2.pageX-disX; var t=touch2.pageY-disY; if(l<0){ l=0; }; if(l>document.documentElement.clientWidth-obj.offsetWidth){ l=document.documentElement.clientWidth-obj.offsetWidth }; if(t<0){ t=0; }; if(t>document.documentElement.clientHeight-obj.offsetHeight){ t=document.documentElement.clientHeight-obj.offsetHeight; }; obj.style.left=l+'px'; obj.style.top=t+'px'; }; obj.addEventListener('touchend',chend); function chend(event){ document.documentElement.style.touchAction = 'auto'; obj.removeEventListener('touchmove',move); obj.removeEventListener('touchend',chend); }; }; }, false); };
|
本文代码地址:链接