手机端touch事件实现元素拖拽效果

这段时间在做一个手机相册的效果,然后网上各种搜,而结果不尽人意,后来我突然想手机事件是否可以自己写,就开始从拖拽做起了

我先从网上搜到了一份手机的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{ 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);

  以上!在此特意感谢--剧中人的帮助。