-
webapp手机站开发,苹果系统的手势事件讲解
网络 2014/6/6 15:18:19多触式网页开发中对手势(Gesture)事件的处理。
苹果设备中的Gesture,广义的说包括手指点击(click),轻拂(flick),双击(double-click),两只手指的分开、闭合(scale)、转动(rotate)等一切手指能在屏幕上做的事情。iOS上设计了了一系列手势来模拟和扩展鼠标操作,比如手指放下后迅速提起会触发click事件,手指向上滑动,停止,会触发body的onscroll事件等等。但是,狭义的Gesture事件,也就是能够addEventListener的GestureEvent对象,却并不是一个非常强大的存在,它只在有两根或多根手指放在屏幕上的时候触发,并且只包含手指分开比例(scale)和手指转动角度(rotation)信息。对于其他各种常用的手势,我们必须利用别的事件来处理。
下面从单根手指的事件开始说起。。。
我们先来考虑一个最简单的手势,手指放下后迅速提起,这个手势做出来后会发生什么?大家当然会想到click,其实在click发生以前,还有很多事情发生,请看下图:
这里先解释一下什么是clickable element,就是一个绑定了click, mousedown, mouseup, mousemove事件的任何html element(注意,没有绑定事件处理的element不算clickable element)。从这张图可以看出,手指提起的一刹那,首先触发的并不是click事件,而是mouseover和mousemove。然后,系统会判断接收到事件的element的内容是否被改变,如果内容被改变,接下来的事件都不会触发,如果没有改变,会按照mousedown,mouseup,click的顺序触发事件。什么?你问mouseout在哪?这个事件的处理,比较尴尬,上面说的一系列事件都完了以后,如果你再点击一个clickable element,就会触发上一个clickable element的mouseout事件了。。。比较纠结,建议不要在多触版网页上使用mouseout。
那么,如果手指放下后不提起又会发生什么呢?什么都不会发生,没有任何事件会被触发。但是,如果对象是一个img并且有alt属性的话,这个动作将会显示img的alt字符串。如果是一个link的话,这个动作会显示“在
新窗口打开连接”选项,但是,不会有任何用户定义事件触发。最后一种关于单根手指的事件,是放下后滑动手指。注意,在滑动的过程当中,不会触发除touchmove以外的任何事件(请不要试图在这时处理mousemove)。手指在滑动的时候,整个page应该会跟着移动,除非你preventDefault了body的touchmove。当手指停下来后,page的onscroll将会触发。除此之外,没有什么我们熟悉的事情会发生。
下面着重介绍多触式设备上特有的gesture event(android和iOS对这个事件的封装大同小异)。这个事件是对touch event的更高层的封装,和touch一样,它同样包括gesturestart,gesturechange,gestureend三个事件回调:
gesturestart // 当有两根或多根手指放到屏幕上的时候触发 gesturechange // 当有两根或多根手指在屏幕上,并且有手指移动的时候触发 gestureend // 当倒数第二根手指提起的时候触发,结束gesture
事件处理函数中会得到一个GestureEvent类型的参数,它包含了手指的scale(两根移动过程中分开的比例)信息和rotation(两根手指间连线转动的角度)信息。
当两根或以上的手指在屏幕上活动的时候,我们可以做出一些较为复杂的手势。这将涉及到普通的mouse事件,touch事件和gesture事件,情况比较复杂。touch已经在第一篇文章里详细介绍,这里就简单带过。
我们还是先看看当分别将两根手指放到屏幕上的时候,会触发哪些事件吧:
1、第一根手指放下,触发touchstart,除此之外什么都不会发生(请参照第二篇文章,手指提起才会触发mouse的各事件)
2、第二根手指放下,触发gesturestart
3、触发第二根手指的touchstart
4、立即触发gesturechange
5、手指移动,持续触发gesturechange,就像鼠标在屏幕上移动的时候不停触发mousemove一样
6、第二根手指提起,触发gestureend,以后将不会再触发gesturechange
7、触发第二根手指的touchend
8、触发touchstart!注意,和第一篇文章里介绍的一样,多根手指在屏幕上,提起一根,会刷新一次全局touch!重新触发第一根手指的touchstart,这点和苹果官方网站上介绍的不同。
9、提起第一根手指,触发touchend
Gesture事件的处理和Touch类似,我们一般会在gesturechange的时候利用GestureEvent对象中的信息来做一些事情:
var angle = event.rotation; var scale = event.scale;
这样能够取得scale和rotation信息,然后我们可以:
e.target.style.webkitTransform = 'scale(' + e.scale + startScale + ') rotate(' + e.rotation + startRotation + 'deg)';
这段代码能让element随着你的两根手指的运动而转动、伸展。以下是一段测试代码,请用ipad/iphone/android打开: http://wanglingshu.com/wp-content/uploads/ios-gesture.html
还有一件要说明的事情是,对于复杂手势,是否会触发某些鼠标事件?确实有,不过我只找到了一个。不管你的两根手指在屏幕上伸缩还是转动,都不会有任何鼠标事件触发,但当你的两根手指同时朝上或者朝下移动的时候,则会触发某些事件。请看下图:
两根手指同时向上或向下滚动,如果target element是一个scrollable element(也就是绑定了mousewheel的element)的话,将会触发mousewheel事件。如果不是scrollable element,则当手指停止移动的时候,会触发onscoll。
这里请和第二篇文章的body scroll区别一下,如果你要滚动body,只需要一根手指轻轻拂动屏幕,但是你要滚动一个内部div或者iframe,则需要动用两根手指。 这也是多触式设备一个不太方便的地方。而对于我们开发者来说,这种不方便被放大了。。。因为从用户体验角度来说,要求用户使用两根手指滚动一个内部element显然是不合适的,而要实现像滚动body一样用一根手指优雅地滚动,我们必须利用touchevent,在它的回调函数中用代码来实现scroll。
这里介绍一个段很不错的多触式滚动组件:iscroll-4
http://cubiq.org/scrolling-div-on-iphone-ipod-touch
用起来很简单,new一个iScroll对象,传入需要滚动的inner element作为参数就行了。阅读(923) 分享(0)