触摸事件

触摸点

每个Touch对象代表一个触摸点,每个触摸点都由其位置、大小、形状、压力大小和目标元素描述。

触摸点的目标元素

触摸点的目标元素open in new windowtarget element,即Touch对象的touch.target属性),是触摸点最开始被追踪时(即发生touchstart事件时)触摸点所位于的 DOM 元素。哪怕在触摸点移动过程中,触摸点的位置已经离开了这个元素的有效交互区域,或者这个元素已经被从文档中移除。

需要注意的是,如果这个元素在触摸过程中被移除,这个事件仍然会指向它,但是不会再冒泡这个事件到windowdocument对象。因此,如果有元素在触摸过程中可能被移除,最佳实践是将触摸事件的监听器绑定到这个元素本身,防止元素被移除后,无法再从它的上一级元素上侦测到从该元素冒泡的事件。

事件的目标元素

无论是发生touchstart/touchmove/touchend事件时,触摸事件的目标元素touchEvent.target的值始终是触摸点发生touchstart事件时所位于的 DOM 元素,事件的目标元素在触摸点离开触摸平面之前,不会改变。

经测试,以touchstart事件为例

  • 若两个手指同一时间点击同一个元素,则只触发一次touchstart事件
  • 若两个手指同一时间点击两个不同的元素,则会触发两次touchstart事件

TODO: 具体关于浏览器在多个手指同时触发事件后是如何确定事件目标的,待以后详细了解。

touches/targetTouches/changedTouches

  • touchEvent.touches
    • TouchList列表,含有所有当前在与触摸平面接触的Touch对象,不管触摸点是否已经改变或其目标元素是否处于touchstart阶段
  • touchEvent.targetTouches
    • 只读的TouchList列表,列出了当前接触屏幕的所有触摸点所对应的Touch对象,这些触摸点需要满足以下两个条件:
      • 触摸事件发生时,这些触摸点仍与触摸平面接触着,且这些触摸点自touchstart事件后,未曾离开触摸平面(但是可以移动到触摸点目标元素之外)
      • 这些触摸点的目标元素(即这些触摸点发生touchstart事件时所处于的 DOM 元素)与此次触摸事件的目标元素touchEvent.target是同一元素
    • targetTouches元素是touches的严格子集
  • touchEvent.changedTouches
    • 只读的TouchList列表,包含了所有从上一次触摸事件到此次事件过程中,状态发生了改变的触点的Touch对象。
      • 对于touchstart事件, 列出在此次事件中新增加的触点
      • 对于touchmove事件,列出和上一次事件相比较,发生了变化的触点
      • 对于touchend事件,列出离开触摸平面的触点(这些触点对应已经不接触触摸平面的手指)

假设只有一个触摸点发生touchstart/touchmove/touchend事件,touches/targetTouches/changedTouches的变化情况如下:

  • 针对touchstart事件,假设新增的触摸点位于el元素上
    • touchEvent.touches列表里会新增这个新的触摸点
    • touchEvent.targetTouches会改变,列出所有在el元素上发生了touchstart事件且未曾离开触摸平面的触摸点(包括已经移动到el元素之外的触摸点),包括这个新增的触摸点
    • touchEvent.changedTouches会改变,列出导致触发touchstart事件的触摸点,此时只有这个新增的触摸点
  • 针对touchmove事件
    • touchEvent.touches/touchEvent.targetTouches不会改变
    • touchEvent.changedTouches会改变,列出导致触发touchmove事件的触摸点,此时只有这个移动的触摸点
  • 针对touchend事件
    • touchEvent.touches