移动开发之touch event篇

一、前言

如今,智能手机和平板电脑越来越普及, 越来越多的人用过移动设备浏览网页。移动设备的流量已经占到北美网络总流量的20%(http://allthingsd.com/20120525/mobile-devices-now-make-up-about-20-percent-of-u-s-web-traffic/)。幸好目前最流行的两大移动操作系统IOS和Android都具备了解析标准的HTML、CSS和JS的能力,网页开发者还是可以用桌面浏览器来开发网页。通过这两个系统上的浏览器看到的网页和我们桌面浏览器上看到的网页几乎是一致的。虽然看起来是一致的,但是在交互上面还是有一些区别的,最大的区别就是,这些移动设备都没有鼠标,我们平时在桌面浏览器上用的鼠标事件,在移动设备浏览器上用起来怪怪的。想要发挥移动设备触摸屏的特点,给用户提供良好的体验,就要用到浏览器的触摸事件。

二、开发准备(Android)

Android设备可以使用ADB(Android Debug Bridge)来调试android程序,也可以通过ADB来调试移动版Chrome中的网页。

ADB调试说明

http://developer.android.com/tools/help/adb.html

远程调试使用说明

https://developers.google.com/chrome-developer-tools/docs/remote-debugging


三、Touch Event介绍

标准文档:

http://www.w3.org/TR/touch-events/

相关的最重要的三个事件是:

touchstart        触摸开始(手指放在触摸屏上)

touchmove       拖动(手指在触摸屏上移动)

touchend 触摸结束(手指从触摸屏上移开)

当然还有一个touchcancel,是在拖动中断时候触发。

下面是触发事件的例子(下面的代码都是在Google Nexus 7的Chrome中测试过的,IOS设备的情况不清楚,有iPhone或者iPad的同学可以自己试一下)

Demo:  http://page.china.alibaba.com/html/xutao/test.html

HTML:

<div id=”screen”></div>

 CSS:

#screen{height:400px;background-color:#CCC;}​

 JS:

$(‘#screen’).on(‘touchstart touchmove touchend touchcancel’,function(e){
e.preventDefault();
console.log(e.originalEvent.type+’:’+e.originalEvent.timeStamp);
});

手指在屏幕上灰色区域轻轻划过,控制台输出如下

来看下touchstart事件

Demo:  http://page.china.alibaba.com/html/xutao/test2.html

还是上面的例子HTML和CSS不变,JS如下

JS:

$(‘#screen’).on(‘touchstart’,function(e){                     console.log(e.originalEvent);
});

控制台输出如图

可以看到每个事件里都包含3个重要的触摸列表,就是touches, targetTouches, changedTouches。

touches是当前屏幕上所有触摸点的列表;targetTouches是当前对象上所有触摸点的列表;changedTouches是涉及当前事件的触摸点的列表。

它们都是一个数组,每个元素代表一个触摸点。

点开touches后如下。

每个触摸点对应的Touch都有三对重要的属性,clientX/client、pageX/pageY、screenX/screenY。其中screenX/screenY代表事件发生的位置对于屏幕的偏移量,clientX/client和pageX/pageY都代表事件发生位置对应对象的偏移量,不过区别是clientX/clientY不包括对象滚动而隐藏的偏移量,而pageX/pageY包括对象滚动而隐藏的偏移量。

四、扩展

touch事件看似非常简单,但是已经强大的能够实现复杂的多点触摸的操作了。

在实际的使用过程中,我遇到了一些问题,也列出来和大家分享一下。

1.触摸支持检测:

使用前要先检测浏览器是否支持触摸,很简单,一句话,jQuery Mobile里看来的

‘ontouchstart’ in window

可以在桌面版的Chrome中,勾选模拟Touch Events来试一下

2.关于touchend事件

移开屏幕的那个触摸点,只会包含在changedTouches列表中,而不会包含在touches 和targetTouches 列表中。

http://page.china.alibaba.com/html/xutao/test3.html

 

3.轻拍和单击的关系

在移动版Chrome中,已经对轻拍做了处理,会出发发单击的操作。当然还有鼠标事件也会触发,他们触发的先后关系如下

而手指在屏幕上移动则不会触发鼠标事件和单击事件

从事件触发的先后顺序看,我认为,Chrome移动版,在用户完成轻拍操作后,将虚拟的光标移动到对象上,然后再模拟点击操作。因此,touch事件中如果使用了preventDefault,会阻止浏览器的模拟单击。

 

4.浏览器默认的缩放和滚动

默认情况下,用户在屏幕上拖动手指,浏览器会滚动屏幕,同时触发touchcancel中断拖动操作。要禁用也很简单,在touchmove事件中加入preventDefault就可以了,不要在touchstart和touchend里加,上面已经说了,会影响模拟的单击事件的。

 

五、演示

Canvas绘图   http://page.china.alibaba.com/html/xutao/test4.html

Category: 前端

15 responses

Leave a Reply

Your email address will not be published. Required fields are marked *

  1. 第二线 says:

    不错,来了http://118.244.169.6/

  2. eeg平台 says:

    楼主经验之谈,分析很到位啊,让人受益匪浅!楼主加油!!

  3. 是是 says:

    13213

  4. 南禾网络 says:

    很有技术性的文章,很不错,转走了

    南禾网络:http://www.cssao.com/

  5. 不夜城手机报价 says:

    您好,我是不夜城手机报价网的,您的文章写的不错,过来学习了!欢迎回访

    http://www.9zonline.com

  6. 电信通 says:

    博主支持一下 写的真不错。 http://www.520116.com/

  7. 丫丫 陈 says:

    test文件都访问不了,
    http://www.jiaxingweb.com

  8. 烛前 says:

    在touchmove事件中加入preventDefault来禁止缩放,其实应该附加一句话:同时也会禁止拖动页面(如果够长能被拖动的话)

  9. JC says:

    神仙姐姐说“兼容WP的触屏操作”才是好文章!

  10. Wenhua Zhang says:

    http://www.w3.org/TR/touch-events/#touchevent-interface中关于pageX的介绍:

    pageX of type long, readonly
    The horizontal coordinate of point relative to the viewport in pixels,
    including any scroll offset
    pageY of type long, readonly
    The vertical coordinate of point relative to the viewport in pixels,
    including any scroll offset
    看起来pageX的值应该是针对viewpoint的相对值。

    在测试中发现,为了获得触摸点相对于canvas的值,应该使用pageX减去canvas的left值:

    var rect = canvas.getBoundingClientRect();
    endX = event.changedTouches[0].pageX – rect.left;

    不知道我的这个理解是否正确。
    求指导。多谢

  11. Wenhua Zhang says:

    请问楼主,是如何远程调试手机端web页面console.log信息的?
    firefox的远程调试看不到console的信息。
    使用的chrome的remove debug吗?
    我的手机不支持chrome,有别的办法吗?
    多谢。

  12. 163贵州人事考试信息网 says:

    http://www.0851gx.com/

  13. 大雄 says:

    LZ 请问你个问题:在移动端Web页面,我想给动态添加的li(num不确定)绑定单击事件,我是这样写的:
    $(document).ready(function() {
    $(“#newli”).live(‘click’, function() {
    alert($(“#newli”).text())
    });
    });
    结果:当点击动态生成的li时 没有一点反应
    最后换了这种:
    $(“#newli”).live(‘touchstart’, function() {
    alert($(“#newli”).text())
    });
    求解 。。。多谢LZ!