这段时间在做一个手机相册的效果,然后网上各种搜,而结果不尽人意,后来我突然想手机事件是否可以自己写,就开始从拖拽做起了
我先从网上搜到了一份手机的touchstart和touchmove的方法。如下:
//touchstart事件 function touchSatrtFunc(e) { e.preventDefault(); //阻止触摸时浏览器的缩放、滚动条滚动等 var touch = e.touches[0]; //获取第一个触点 var x = Number(touch.pageX); //页面触点X坐标 var y = Number(touch.pageY); //页面触点Y坐标 //记录触点初始位置 startX = x; startY = y; } //touchmove事件 function touchMoveFunc(e) { e.preventDefault(); //阻止触摸时浏览器的缩放、滚动条滚动等 var touch = e.touches[0]; //获取第一个触点 var x = Number(touch.pageX); //页面触点X坐标 var y = Number(touch.pageY); //页面触点Y坐标 //判断滑动方向 if (x - startX != 0) { console.log('左右滑动 :' + (x - startX) )//左右滑动 } if (y - startY != 0) { console.log('上下滑动 : '+ (y - startY) ) //上下滑动 } }
然后在此基础上我又写了需要的html结构代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" name="viewport"> <style type="text/css"> *{margin: 0;padding: 0} div{width: 100px;height: 100px;background: #f00;position: absolute;top: 5%;left: 5%} </style> </head> <body> <input type="text"> <input type="text"> <div></div> </body> </html>
我一开始的思路是:
1,div实现拖动就要计算出div的left与top
2,首先我取到触摸屏幕的点的坐标
3,其次我通过触摸屏幕点的坐标和div的offsetTop与offsetLeft计算出触摸点相对div顶部边缘与左侧边缘的距离
4,最后我用触摸点的坐标减去触摸点相对div顶部边缘与左侧边缘的距离得到div元素的位置坐标赋值,以达到定位div的目的
5,将touchstart与touchmove事件绑定在document对象上,来实现最终拖动效果
然后是我依照此思路写的代码,如下:
var oDiv = document.getElementsByTagName('div')[0]; //获取可拖动元素 var oIpt = document.getElementsByTagName('input')[0]; //记录拖动元素位置 var oIpt1 = document.getElementsByTagName('input')[1]; //记录触点位置 var oL,oT; //touchstart事件 function touchSatrtFunc(e) { e.preventDefault(); //阻止触摸时浏览器的缩放、滚动条滚动等 var touch = e.touches[0]; //获取第一个触点 var x = Number(touch.pageX); //页面触点X坐标 var y = Number(touch.pageY); //页面触点Y坐标 //记录触点初始位置 startX = x; startY = y; } //touchmove事件 function touchMoveFunc(e) { e.preventDefault(); //阻止触摸时浏览器的缩放、滚动条滚动等 oL = oDiv.offsetLeft; //可拖动元素距离页面左侧的距离 oT = oDiv.offsetTop; //可拖动元素距离页面顶部的距离 var touch = e.touches[0]; //获取第一个触点 var x = Number(touch.pageX); //页面触点X坐标 var y = Number(touch.pageY); //页面触点Y坐标 var sL = x - oL; //获取页面触点距离div左侧的距离 var sT = y - oT; //获取页面触点距离div顶部的距离 oDiv.style.left = (x-sL) +'px'; oDiv.style.top = (y-sT)+'px'; alert(e.touches.length) oIpt1.value = "触点位置:" +x +":"+y; oIpt.value = "元素位置:"+oL+":"+oT+","+sL+":"+sT; } oDiv.addEventListener('touchstart',touchSatrtFunc,false); oDiv.addEventListener('touchmove',touchMoveFunc,false);
然而实际测试时,这个出现了很大的问题,最主要的div拖动效果一点反应也没有,一开始可是愁苦了我,我一直在想没怎么回事,然而一直没有寻到问题所在。
这个时候经过请教,修改后的思路:
1,首先在touchstart时得到div的offsetTop与offsetLeft的值
2,然后计算出touchmove时的实时触摸坐标和一开始touchstart时的坐标的差值坐标
3,将差值坐标与一开始touchstart时的div的offsetTop和offsetLeft相加得到新的div的位置坐标
4,将touchstart与touchmove事件绑定在div元素上
具体代码如下:
var oDiv = document.getElementsByTagName('div')[0], //获取可拖动元素 oIpt = document.getElementsByTagName('input')[0], //记录拖动元素位置 oIpt1 = document.getElementsByTagName('input')[1], //记录触点位置 startX = "", startY = "", startPositionX = "", startPositionY = ""; //touchstart事件 function touchSatrtFunc(e) { e.preventDefault(); //阻止触摸时浏览器的缩放、滚动条滚动等 var touch = e.touches[0]; //获取第一个触点 var x = Number(touch.pageX); //页面触点X坐标 var y = Number(touch.pageY); //页面触点Y坐标 //记录触点初始位置 startX = x; startY = y; //可拖动元素距离页面顶部的距离 startPositionY = oDiv.offsetTop; //可拖动元素距离页面左侧的距离 startPositionX = oDiv.offsetLeft; } //touchmove事件 function touchMoveFunc(e) { e.preventDefault(); //阻止触摸时浏览器的缩放、滚动条滚动等 var touch = e.touches[0]; //获取第一个触点 var x = Number(touch.pageX); //页面触点X坐标 var y = Number(touch.pageY); //页面触点Y坐标 oIpt.value = "元素位置:" +startPositionX +":"+startPositionY; oIpt1.value = "触点位置:" +x +":"+y; oDiv.style.left = startPositionX + (x-startX) +'px'; oDiv.style.top = startPositionY + (y-startY)+'px'; // oIpt.value = "元素位置:"+oL+":"+oT+","+sL+":"+sT; //判断滑动方向 if (x - startX != 0) {console.log('左右滑动 :' + (x - startX) )//左右滑动 } if (y - startY != 0) { console.log('上下滑动 : '+ (y - startY) ) //上下滑动 //} } oDiv.addEventListener('touchstart',touchSatrtFunc,false); oDiv.addEventListener('touchmove',touchMoveFunc,false);
经过测试,这个能够完美的执行出我想要的效果。
然而我依旧被原先的思路所困扰,因此我又从新梳理了一遍我以前的代码流程,最后终于发现问题所在,问题所在就是(这里只提供水平坐标,纵坐标同理):
我赋值给div横坐标的值为:x-sL,然而sL = x - oL;因此最后得到的值为固定的oL,因此我之前写的div一直无法拖动。
最后我又对最初代码进行更改,终于实现了,如下:
var oDiv = document.getElementsByTagName('div')[0]; //获取可拖动元素 var oIpt = document.getElementsByTagName('input')[0]; //记录拖动元素位置 var oIpt1 = document.getElementsByTagName('input')[1]; //记录触点位置 var oL,oT,sL,sT; //touchstart事件 function touchSatrtFunc(e) { e.preventDefault(); //阻止触摸时浏览器的缩放、滚动条滚动等 var touch = e.touches[0]; //获取第一个触点 var x = Number(touch.pageX); //页面触点X坐标 var y = Number(touch.pageY); //页面触点Y坐标 //记录触点初始位置 startX = x; startY = y; oL = oDiv.offsetLeft; //可拖动元素距离页面左侧的距离 oT = oDiv.offsetTop; //可拖动元素距离页面顶部的距离 sL = x - oL; //获取页面触点距离div左侧的距离 sT = y - oT; //获取页面触点距离div顶部的距离 } //touchmove事件 function touchMoveFunc(e) { e.preventDefault(); //阻止触摸时浏览器的缩放、滚动条滚动等 var touch = e.touches[0]; //获取第一个触点 var x = Number(touch.pageX); //页面触点X坐标 var y = Number(touch.pageY); //页面触点Y坐标 oDiv.style.left = (x-sL) +'px'; oDiv.style.top = (y-sT)+'px'; oIpt1.value = "触点位置:" +x +":"+y; oIpt.value = "元素位置:"+oL+":"+oT+","+sL+":"+sT; } oDiv.addEventListener('touchstart',touchSatrtFunc,false); oDiv.addEventListener('touchmove',touchMoveFunc,false);
以上!在此特意感谢--剧中人的帮助。