单指手势事件的实现

时间:2015-06-24 作者:剧中人

伴随着移动端的发展,触摸交互的手势也越来越丰富,从起初最简单的点击发展到现在的长按、侧滑、拖动等,更为复杂的还会有双指缩放等事件。可以说,手势设计在移动页面上起到了简化界面元素,增加交互多样性的重要角色。

原生基础事件

尝试写过原生手势的同学应该都知道,和手势相关的基本事件其实只有这么四个:touchstarttouchendtouchmovetouchcancel。几乎所有复杂的交互都是通过这几个简单的事件来完成的。

模拟高级事件

在单指手势中,不同的手势动作都会有对应的特定的操作行为。下面列出的是期望模拟出来的几种手势。

模拟手势逻辑

上面列举了移动WEB的原生基础手势事件和期望达到的高级手势事件。那么如何通过简单的事件模拟更为丰富的手势事件呢?这里简单写下小剧梳理出来的事件触发逻辑。

模拟手势逻辑

事件之间互斥

这里模拟出的事件原则上都是互斥的,即:单次手势交互,仅仅触发一个事件,而不会同时响应多个事件。这样的好处极为明显,举个例子:实现一个使用手势操作的图片查看器。

要实现上面的要求,就必须保证每一次手势交互的事件都是单一的,如区分轻击关闭与双击缩放,轻击、双击、长按相互独立。

解决互斥引起的问题

除了双击事件,其余各个事件在手指移动、抬起的一瞬间即可判定完成。然而要实现双击与轻击间的互斥,代码上必须要通过延时触发事件来完成,因此轻击事件必然会有一点点儿的延迟(其实也只有190ms而已)。

如何解决这个延迟呢?最简单粗暴的方式就是在手指抬起的一瞬间,主动触发轻击事件,然而这样就无法保证轻击与双击事件的互斥。因此这个方案不可行,否决。

既然延迟是为了模拟双击事件,那么在没有绑定双击事件的时候就无需通过延时来触发轻击事件,因此可以在双击事件判定的逻辑前,检测是否绑定了双击事件,若无则直接触发,若有,则会使用延时处理。

处理拖拽事件

为了处理拖拽事件,这里新增了swipeStartswipeEndswipe三个事件,这三个事件并不遵循互斥原则,swipeStartswipeEnd事件在每次触摸交互中都会触发,swipe事件在拖动过程中会持续触发。

另外因为拖动过程中常常会牵涉到手指当前位置与初始位置的关系,这里小剧已经主动计算了event.moveXevent.moveY,避免重复性的计算,可供调用者使用。


本文经验来自于小剧开发的一款面向移动端的手势类库 toucher:http://bh-lay.github.io/toucher ,欢迎 star!