手机网页上实现类地图拖放效果

前段时间研究移动开发框架研究了好久,发现它们的确很强大,只需要简单的几行代码就能实现各种手势的功能,可谓是相当的牛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,就到这,说的有不对的地方请及时指正,作者:一只猿。

你可能感兴趣的:(实现)