触摸事件

背景

限于鼠标事件的局限性,无法并发,也就是说只能有一个鼠标供移动,现代终端设备更多的支持触摸屏,且出于物理因素,无法给这些设备配置鼠标

touch interface

  • clientX: 水平方向到左边视图的距离,不包含任何滚动offset
  • clientY: 垂直方向,同上
  • identifier: 标识符,number类型,针对唯一的一个触摸点,该标识从触摸开始到结束都不会变,但不同的触摸点,标识符唯一
  • pageX: 水平方向到左边视图的距离,包含滚动offset
  • pageY: 垂直方向,同上
  • screenX: 水平方向到左边屏幕的距离,超出了文档视图
  • screenY: 垂直方向,同上
  • target: 触摸开始时所在的元素,即使后面移动了,该target也不会变

touch list interface

  • length: 触摸点的个数
  • item(index: number): 获取指定第n个触摸事件

touch event interface

  • altKey: 是否按下了alt按键
  • changedTouches: 改变了的touch list,如果是touchstart则代表所有触摸点,如果是touchmove则代表所有移动过的触摸点,如果是touchend或touchcancel也是代表响应的含义
  • ctrlKey: 是否按下了ctrl按键
  • metaKey: 是否按下了meta按键
  • shiftKey: 是否按下了shift按键
  • targetTouches: 所有从该元素触发的touch list
  • touches: 所有touch list

从浏览器角度看touch事件

用户代理必须要为每一个touch事件分配一个活跃的文档上下文,用来选取元素,如果下一次触摸开始于另一个文档,则要忽略之前的touch事件对象

举个例子

  • touchstart:
    • e.targetTouches[0] === e.touches[0]
    • 如果e.targetTouches.length === e.touches.length,则所有触摸点都在元素上
    • 如果e.touches.length > 1,则触摸点有多个,需要屏幕支持多点触控
  • touchend:
    • 有e.changedTouches.length个触摸点被移除
    • 有e.targetTouches.length个触摸点仍在元素上
    • 有e.touches.length个触摸点剩余

default action

  • touchstart: undefined
  • touchend: 通常伴随mousemove,mouseup,mousedown,click等
  • touchmove: undefined
  • touchcancel: none,不可取消

touchstart

  1. 当用户触摸屏幕时触发
  2. 如果触摸的是iframe内的元素,则该事件会分发在该iframe的文档上,不会对主文档产生影响
  3. 如果preventDefault,会取消所有因该触摸点引起的默认行为,如mouse事件,scroll事件

touchend

  • 当用户手指离开屏幕时触发
  • target与touchstart相同,即使已经移到该元素外部
  • 被移除的触摸点会放在changedTouches中,但不会存在于targetTouches

touchmove

  • 当用户移动触摸点时触发
  • target与touchstart相同
  • 事件产生频率由硬件性能或者其他因素决定
  • 如果preventDefault发生在某个触摸点的第一次touchmove上,会取消该触摸点引起的默认行为,如scroll事件

touchcancel

  • 有以下几种触发方式:
    1. 被来自UA的同步事件或者操作中断
    2. 用户触摸点移动到了非文档区域,如浏览器的原生界面,或者插件
    3. 触摸点个数大于UA所支持的上限,会取消更早的触摸点
  • target与touchstart相同
  • 被取消的触摸点会放在changedTouches中,但不会存在于targetTouches
  • >

对document的扩展

  1. createTouch: 创建触摸点对象
  2. createTouchList: 创建触摸点列表
  3. 用于手动触发touch事件

与mouse事件交互

  • 用户的一次操作,touch和mouse事件都会触发
  • touchstart要优先于所有mouse事件,所以在touchstart调用preventDefault之后,click和mousedown也无法触发
  • 如果UA将touch一系列事件当做click,则在touchend的时候,要按顺序触发mousedown, mousemove, mouseup ,click事件,如果过程中文档发生变化,则mouse事件的target也会跟着改变
  • else如果长时间触摸,顺序待定(文档没写)

术语

  • 活跃的触摸点: 在touchstart触发之后,触摸点变为活跃状态,持续被UA监测,如果touchend或者touchcancel触发,则不在活跃
  • 触摸点: 触摸屏幕上的一个点坐标,由用户手指或其他交互产生