针对移动屏幕的 TouchEvent

近几年智能手机普及,很多用户都用手机上的一个屏幕进行操作。手机上用手,电脑上用鼠标,那么有什么区别别,原先在电脑上写的 mouseovermouseoutclick 之类的事件还能正常使用吗?

其实要看浏览器怎么实现的了,目前手机浏览器太多了,随便找了几个就发现实现的不一样,一般来说 click 事件还是有的(一般情况下是300毫秒延时),鼠标事件有些浏览器也做了兼容。

但为什么不专门针对移动浏览器再做适配呢?

移动设备的触摸事件

事件 说明
touchstart 手指接触
touchmove 手指移动
touchend 手指离开
touchcancel 动作被打断(出现场景和系统,浏览器有关,比如一个通知过来什么的,高风险,慎用)

产生的事件类型 :TouchEvent

TouchEvent 的事件属性:

首先是三个轨迹触点:全是TouchList类型,可以理解为Array类型,即Touch [];

属性 说明
touches 正在触摸的
ChangeTouches 发生改变的
targetTouches 正在触摸且在当前元素范围之内的,是touches的子集,你在一个元素上监听了touch事件,就最好用这个

说明一下 : 在可多点触摸的设备上,如果你用多个手指操作,这个array的长度就会有多个。

TouchList 类型除了可以当array操作外,还有一个方法,如果此事件中有此标识的Touch,则返回这个Touch对象。这个方法通常在判定一个手指是否在一个系列操作里面会比较有用。

1
2
function identifiedTouch(identifier){
}

参数identifier可以从 Touch 对象中取到。Touch对象如下

属性 说明
clientX X坐标,不计滚动条
clientY Y坐标,不计滚动条
identifier 唯一标识
pageX X坐标,计滚动条
pageY Y坐标,计滚动条
screenX 设备的X坐标
screenY 设备的Y坐标
target 触摸的对象:说明,这个元素是touchstart时的事件对象,在touchmove过程中离开了对象范围,也是那个对象

另外,TouchEvent还有其它的几个属性:

altKey、 ctrlKey、 metaKey、 shiftKey 代表触摸时 alt、ctrl、 shift键是否按住,由于是手机没有这些键,所以基本都是false.没什么用

OK,关于Touch就介绍到这

模拟设备操作

不计touchcancel事件,通过start,move,cancel事件来看,还是不满足我们对设备的操作习惯。目前常用的操作如下:

点击:可以理解为click,不建议使用click事件,可以通过touchstart和touchend中间的间隔时间计算

长按:和点击一样,如果touchstart超过指定时间都没有touchend则可以认为是长按

拖拽:即touchmove

上下左右划动:也是touchmove,如果在短时间内从start move到了 end,且平行垂直角度偏差小,则可以判定为上下左右划动

放大/缩小:两根手指,按住,同时往里靠拢或往外拉伸,多用于图片查看。

旋转:两根及以上手指,按住,围绕中心,顺时针或逆时针移动,多用于图片查看。

自定义手势:当然也可自己写算法判定用户行为,比如解锁,轨迹事件等,

自定义屏幕事件

由于时间问题就不自己实现了,目前有很多框架已经实现了上面那些,如果不满意,自己也可以根据上面那些原理去实现 pan、tap、drag、swipe 等动作。

出于手机上性能及流量的考虑,但使用框架的过程中有几点是要清楚的:

  1. 如果只针对移动设备,建议使用基于 touch 的框架,有很多框架兼容电脑版使用了click,mouse事件,性能并不怎么样,特别是 click 事件,天生300ms延时。

  2. 框架也是基于原生,然后计算,有些计算是很耗费性能的,特别是多点的情况,比如放大缩小旋转等,如果没有这些需求,建议不要使用这些API,甚至不要使用框架。因为基础事件做些简单控制还是比较容易的。有空自己写个框架也不算难事。

  3. 如果使用canva开发游戏或其它,不要指望这些事件能监听到画布内的元素,呵呵。就这些了