前段时间研究移动开发框架研究了好久,发现它们的确很强大,只需要简单的几行代码就能实现各种手势的功能,可谓是相当的牛B,但是,我只是想做一个类似于地图功能的东西,试了各种框架都没有我想要的效果,原因是那些框架都有一个共性,在拖动的元素上都使用了position:absolute;的属性,导致拖动图层总处于最上层,如果改变z-index又会导致拖动的位置发生严重的偏移。几经周折,决定自己试着用js写一下,看能不能实现。参考资料均来自互联网,这里就不贴出来了。
点看下效果:
单指向右滑动的效果:
html部分注意要点:
(1)首先我们要禁止页面的缩放功能,只需要一行代码就可以搞定,在head标签之间加入以下代码即可:
1 <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=2">
我们可以看到 user-scalable=no,这个就是禁用缩放的。
完整html代码贴上来:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=2"> 5 <link rel="stylesheet" href="ui/css/style.css" /> 6 <title>无标题文档</title> 7 </head> 8 9 <body> 10 <div id="outerBox" > 11 <img src="ui/images/map.png" id="mapObj" onTouchStart="touchStart(event);" onTouchMove="touchMove(event);" onGestureChange="mapScale(event);" /> 12 </div> 13 <script type="text/javascript" src="ui/js/jq.mobi.min.js"></script> 14 <script type="text/javascript" src="ui/js/script.js"></script> 15 </body> 16 </html>
我这里为了方便直接使用了jq.mobi(jquery的手机版),使用纯js实现也挺简单的,有兴趣的可以修改成纯js。
img是一张已经画好的地图,给它添加事件,onTouchStart和onTouchMove事件。(什么?你还没见过这两个事件?传送门:移动webApp开发(触摸屏)中的常用js事件)。
如果要实现在一个小的窗口中拖拉,那肯定要给一个“窗口”,outerBox就是一个Div做的“小窗口”,你将看到地图就在这个小窗口中拖来拖去。
我们给窗口一些必要的样式:
1 #outerBox{ 2 width: auto; 3 height: 300px; 4 overflow: hidden; 5 border: #000 2px solid; 6 }
地图图片也给一些必要的样式:
1 #mapObj{ 2 position: relative; 3 width: 150%; 4 top: 0; 5 left: 0; 6 }
下面进入关键的js部分。
先贴出代码再作解释:
var startX = 0; //触摸开始时X坐标(相对于页面起始左上角位置) var startY = 0; //触摸开始时Y坐标(相对于页面起始左上角位置) var mapObj; $(document).ready(function() { mapObj = $("#mapObj"); }); //触摸开始时候调用 function touchStart(ev){ var touch = ev.touches[0]; //我们使用单根手指滑动地图,所以要取到touchList第一个 var mapLeft = parseInt(mapObj.css("left")); //取触摸开始时候地图的相对left var mapTop = parseInt(mapObj.css("top")); //取触摸开始时候地图的相对top //触摸的坐标减去地图的相对位置得到的就是地图左上角的实际坐标 startX = touch.pageX - mapLeft; startY = touch.pageY - mapTop; } //移动手指时候调用 function touchMove(ev){ ev.preventDefault(); //取消事件的默认动作(重要) var touch = ev.touches[0]; mapObj.css("left",touch.pageX - startX + "px"); //将位移值付给地图实现拖拉效果 mapObj.css("top",touch.pageY - startY + "px"); }
注意要点:我们在调用touch事件的时候必须传入event参数,否则会出错。
<img src="ui/images/map.png" id="mapObj" onTouchStart="touchStart(event);" onTouchMove="touchMove(event);" onGestureChange="mapScale(event);" />
到这,我们的拖拉功能已经做完了,瑕疵不少,很粗糙。地图滑动到边缘禁止继续滑动这个我一直很头疼,做了好多个效果不理想,园子里有哪位朋友有好的方法请告诉我一下。
本文实现的是拖拽效果,当然,要做成一个比较实用的地图怎么少得了缩放功能。时间有限,如果有哪位朋友已经有更好的例子,欢迎联系我,我也学习下好的方法。
业余时间使用了css3的一个属性实现了放大缩小的功能,不过没用到手势(本人大三星的webview居然不支持两指,不知道是手机的问题还是我哪里设置不对)。
附上检测是多点触控的方法:
在touchStart的时候alert一下touchList的长度即可,touchList这个数组里面存储了触摸时候的触摸对象。
alert(ev.touches.length);
我手机上的效果:
弹出了1,不知道是不是我哪里设置除了问题还是webview不知道多点触控。用单根手指触摸是1,多根手指触摸还是1,但是放到iphone5上面的safari浏览器里面使用三根手指同时触摸显示就是3,很是郁闷。有知道的朋友告知一下,不胜感激。ok,就到这,说的有不对的地方请及时指正,作者:一只猿。