移动端的touch事件详解

触摸事件:

三种在规范中列出并获得跨移动设备广泛实现的基本触摸事件:

1.touchstart:手指放在一个DOM元素上。

2.touchmove:手指拖曳一个DOM元素。

3.touchend:手指从一个DOM元素上移开。

每个触摸事件都包括了三个触摸列表:

1.touches:当前位于屏幕上的所有手指的一个列表。

2.targetTouches:位于当前DOM元素上的手指的一个列表。

3.changedTouches:涉及当前事件的手指的一个列表。

例如,在一个touchend事件中,这就会是移开的手指。

这些列表由包含了触摸信息的对象组成:

1.identifier:一个数值,唯一标识触摸会话(touchsession)中的当前手指。

2.target:DOM元素,是动作所针对的目标。

3.客户/页面/屏幕坐标:动作在屏幕上发生的位置。

4.半径坐标和rotationAngle:画出大约相当于手指形状的椭圆形。

可触控应用:

touchstart、touchmove和touchend事件提供了一组足够丰富的功能来支持几乎是任何类型的基于触摸的交互——其中包括常见的多点触摸手势,比如说捏缩放、旋转等待。下面的这段代码让你使用单指触摸来四处拖曳一个DOM元素:

var obj = document.getElementById('id');

obj.addEventListener( 'touchmove',function(event){
     //如果这个元素的位置内只有一个手指的话
     if( event.targetTouches.length == 1 ){
          var touch = event.targetTouches[ 0 ];
          //把元素放在手指所在的位置
          obj.style.left = touch.pageX+'px';
          obj.style.top = touch.pageY+'px';
      }
}, false );

下面是一个示例,该例子显示了屏幕上当前所有的触点,它的作用就是用来感受一下设备的响应性。

//设置画布并通过ctx变量来暴露上下文复制代码

canvas.addEventListener( 'touchmove',function( event ){

     for(var i=0;i){

     var touch=event.touches;

     ctx.beginPath();

     ctx.arc(touch.pageX,touch.pageY,20,0,2*Math.PI,true);

      ctx.fill();

      ctx.stroke();

     }

},false);

到处都有着许多有意思的多点触摸演示,比如说这个由PaulIrish和其他人实现的基于画布的绘画演示。

还有BrowserNinja,一个技术演示,是一个使用了CSS3的转换、过渡和画布的FruitNinja克隆。

最佳做法

阻止缩放:

缺省的多点触摸设置不是特别的好用,因为你的滑动和手势往往与浏览器的行为有关联,比如说滚动和缩放。

要禁用缩放功能的话,使用下面的元标记设置你的视图区(viewport),这样其对于用户来说就是不可伸缩的了:

content = "width=device-width,initial-scale=1.0,user-scalable=no">

阻止滚动:

一些移动设备有缺省的touchmove行为,比如说经典的iOSoverscroll效果,当滚动超出了内容的界限时就引发视图反弹。这种做法在许多多点触控应用中会带来混乱,但要禁用它很容易。

document.body.addEventListener('touchmove',function(event){

       event.preventDefault();

},false);

细心渲染:

如果你正在编写的多点触控应用涉及了复杂的多指手势的话,要小心地考虑如何响应触摸事件,因为一次要处理这么多的事情。考虑一下前面一节中的在屏幕上画出所有触点的例子,你可以在有触摸输入的时候就立刻进行绘制:

canvas.addEventListener('touchmove',function(event){

     renderTouches(event.touches);

},

不过这一技术并不是要随着屏幕上的手指个数的增多而扩充,替代做法是,可以跟踪所有的手指,然后在一个循环中做渲染,这样可获得更好的性能:

vartouches=[ ]

canvas.addEventListener('touchmove',function(event){

      touches=event.touches;

},false);

//设置一个每秒60帧的定时器

timer=setInterval(function(){

     renderTouches(touches);

},15);

提示:setInterval不太适合于动画,因为它没有考虑到浏览器自己的渲染循环。现代的桌面浏览器提供了requestAnimationFrame这一函数,基于性能和电池工作时间原因,这是一个更好的选择。一但浏览器提供了对该函数的支持,那将是首选的处理事情的方式。

使用targetTouches和changedTouches

要记住的一点是,event.touches是与屏幕接触的所有手指的一个数组,而不仅是位于目标DOM元素上的那些。你可能会发现使用event.targetTouches和event.changedTouches来代替event.touches更有用一些。

最后一点,因为你是在为移动设备做开发,因此你应该要留心移动的最佳做法,这些在EricBidelman的文章中有论及,以及要了解这一W3C文档

设备支持:

遗憾的是,触摸事件的实现在完备性和质量方面的差别很大。我编写了一个诊断脚本来显示一些关于触摸API实现的基本信息,其中包括哪些事件是支持的,以及touchmove事件触发的解决方案。我在NexusOne和NexusS硬件上测试了Android2.3.3,在Xoom上测试了Android3.0.1,以及在iPad和iPhone上测试了iOS4.2。

简而言之,所有被测试的浏览器都支持touchstart、touchend和touchmove事件。

规范提供了额外的三个触摸事件,但被测试的浏览器没有支持它们:

1.touchenter:移动的手指进入一个DOM元素。

2.toucheleave:移动手指离开一个DOM元素。

3.touchcancel:触摸被中断(实现规范)。

被测试的浏览器还在每个触摸列表内部都提供了touches、targetTouches和changedTouches列表。不过,被测试的浏览器没有支持radiusX、radiusY或是rotationAngle属性,这些属性指明触摸屏幕的手指的形状。在一次touchmove期间,事件大约一秒钟触发60次,所有的被测试设备都是这样。

Android2.3.3(Nexus)

Android的Gingerbread浏览器(在NexusOne和NexusS上测试)不支持多点触摸,这是一个已知的问题。

Android3.0.1(Xoom)

Xoom的浏览器对多点触摸有一个基本的支持,不过只能是在单个的DOM元素上起作用。浏览器不能正确响应同时发生在不同DOM元素上的两处触摸,换句话说,下面的代码会对两个同时发生的触摸的给出反应:复制代码

obj1.addEventListener('touchmove',function(event){

for(var i=0;i

     var touch = event.targetTouches;

    console.log('touched'+touch.identifier);

    }

},false);

但下面的代码则不会:复制代码

var objs=[obj1,obj2];

for(vari=0;i

    var  obj=objs;

    obj.addEventListener('touchmove',function(event){

    if(event.targetTouches.length==1){

    console.log('touched'+

    event.targetTouches[0].identifier);

    }

   },false);

}

iOS4.x(iPad,iPhone)

iOS设备完全支持多点触摸,能够跟踪多个手指,并在浏览器中提供一个非常敏感的触摸体验。

开发者工具:

在移动开发中,一种较为容易的做法是,先在桌面上开始原型设计,然后再在打算要支持的设备上处理移动特有的部分。多点触摸正是难以在PC上进行测试的那些功能之一,因为大部分的PC都没有触摸输入。

不得不在移动设备上进行的测试有可能会拉长你的开发周期,因为你所做的每项改变都需要提交代码到服务器上,接着再加载到设备上。然后,一旦运行后,对应用也就没有太多的调试了,因为平板电脑和智能手机都很缺乏web开发者所用的工具。

这个问题的一个解决方案是在开发机器上模拟触发事件。对于单点触摸,触摸事件可以基于鼠标事件来模拟。如果你有触摸输入设备的话,比如说现代的AppMacBook,那么多点触摸也可以被模拟。

单点触摸事件:

如果你想在桌面上模拟单点触摸事件的话,试一下PhantomLimb,该程序在网页上模拟触摸事件并提供一只巨手来引导。

另外还有Touchable这一jQuery插件,该插件跨平台地统一了触摸和鼠标事件。

多点触摸事件:

为了能够让你的多点触摸web应用在你的浏览器或是多点触摸控板(比如说AppleMacBook或是MagicPad)上起作用,我创建了这一个MagicTouch.js填充工具,其捕捉来自触控板的触摸事件,然后把它们转换成标准兼容的触摸事件。

1.下载npTuioClientNPAPI插件并把它安装到~/Library/InternetPlug-Ins/目录下。

2.下载这一MacMagicPad的TongSengTUIO应用并启动这一服务器。

3.下载MagicTouch.js这一javascript库来基于npTuioClient回调模拟规范兼容的触摸事件

4.以如下方式把magictouch.js脚本和npTuioClient插件包含到你的应用中:

...

kesrc="/path/to/magictouch.js">

...

Touchinputpluginfailedtoload!

我只在Chrome10上测试了这一方法,不过只要稍做调整它应该能够在其他的现代浏览器上工作。

如果你的计算机没有多点触摸输入的话,你可以使用其他的TUIO跟踪器,比如

reacTIVision来模拟触摸事件。欲了解更多信息,请参阅TUIO项目页面

需要注意的一点是,你的手势可以是和OS层面的多点触摸手势相同的。在OSX上,你可以通过进入SystemPreferences中的Trackpad偏好设定版面来配置系统范围的事件。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 触摸事件 三种在规范中列出并获得跨移动设备广泛实现的基本触摸事件:1. touchstart:手指放在一个DOM元...
    越长大就越孤单阅读 1,261评论 0 2
  • touchstart:触摸开始的时候触发 touchmove:手指在屏幕上滑动的时候触发 touchend:触摸结...
    DaveWeiYong阅读 486评论 0 0
  • 事件流 IE和Netscape开发团队提出了完全相反的两种事件流的概念,事件冒泡流和事件捕获流。 事件冒泡 事件由...
    exialym阅读 924评论 0 9
  • 端午节回家了,周六提前跑路,坐上了最晚一班从珠海去株洲的高铁,晚上9点多下车后,顺便去以前读书的大学转了下,当...
    彬彬杨阅读 224评论 0 0
  • 我想把每天的生活都过得热气腾腾。 每天,我都在看书,因为,现实生活实在是太无聊了,只有在书中,看看别人的生活,听听...
    小辉辉xhh阅读 878评论 0 1