使用触摸事件

如今,大多数 Web 内容都是为键盘和鼠标输入而设计的。但是,配备触摸屏的设备(尤其是便携式设备)已成为主流,Web 应用程序可以通过使用触摸事件直接处理基于触摸的输入,或者应用程序可以使用解释的鼠标事件作为应用程序输入。使用鼠标事件的一个缺点是它们不支持并发用户输入,而触摸事件支持多个同时输入(可能在触摸表面上的不同位置),从而增强用户体验。

触摸事件接口支持应用程序特定的单点和多点触控交互,例如双指手势。多点触控交互从手指(或触笔)第一次接触接触表面开始。其他手指随后可能会接触表面,并可以选择在触摸表面上移动。当手指从表面上移开时,交互结束。在此交互过程中,应用程序在开始、移动和结束阶段接收触摸事件。应用程序可以对其自己的语义应用于触摸输入。

接口

触摸事件包含三个接口(TouchTouchEventTouchList)以及以下事件类型

  • touchstart - 当触摸点放置在触摸表面上时触发。
  • touchmove - 当触摸点沿触摸表面移动时触发。
  • touchend - 当触摸点从触摸表面上移开时触发。
  • touchcancel - 当触摸点以实现特定的方式中断时触发(例如,创建了太多触摸点)。

Touch 接口表示触摸敏感设备上的单个接触点。接触点通常称为触摸点或简称触摸。触摸通常由触摸屏、笔或触控板上的手指或触笔生成。触摸点的属性包括一个唯一标识符、触摸点的目标元素以及触摸点位置相对于视口、页面和屏幕的XY坐标。

TouchList 接口表示触摸表面的列表接触点,每个接触点对应一个触摸点。因此,如果用户用一根手指激活触摸表面,则列表将包含一个项目,如果用户用三根手指触摸表面,则列表长度将为三。

TouchEvent 接口表示当与触摸敏感表面的接触状态发生变化时发送的事件。状态变化包括开始与触摸表面接触、在保持与表面的接触的同时移动触摸点、释放触摸点以及取消触摸事件。此接口的属性包括多个修饰键(例如shift键)的状态以及以下触摸列表

  • touches - 当前屏幕上所有触摸点的列表。
  • targetTouches - 目标DOM 元素上的触摸点的列表。
  • changedTouches - 触摸点的列表,其项目取决于关联的事件类型
    • 对于touchstart 事件,它是随当前事件变为活动状态的触摸点的列表。
    • 对于touchmove 事件,它是自上次事件以来已更改的触摸点的列表。
    • 对于touchend 事件,它是已从表面上移除的触摸点的列表(即,对应于不再触摸表面的手指的触摸点集)。

这些接口共同定义了一组相对低级的功能,但它们支持多种基于触摸的交互,包括熟悉的多点触控手势,例如多指滑动、旋转、捏合和缩放。

从接口到手势

应用程序在定义手势的语义时可能会考虑不同的因素。例如,触摸点从其起始位置到触摸结束时的位置所移动的距离。另一个潜在因素是时间;例如,触摸开始到触摸结束之间经过的时间,或旨在创建双击手势的两个连续点击之间的时间间隔。滑动的方向性(例如从左到右、从右到左等)是另一个需要考虑的因素。

应用程序使用哪个触摸列表取决于应用程序手势的语义。例如,如果应用程序支持在一个元素上进行单点触控(点击),它将在touchstart 事件处理程序中使用targetTouches 列表以应用程序特定的方式处理触摸点。如果应用程序支持任何两个触摸点的双指滑动,它将在touchmove 事件处理程序中使用changedTouches 列表来确定两个触摸点是否已移动,然后以应用程序特定的方式实现该手势的语义。

当只有一个活动触摸点时,浏览器通常会调度模拟的鼠标和点击事件。涉及两个或多个活动触摸点得多点触控交互通常只会生成触摸事件。要防止发送模拟的鼠标事件,请在触摸事件处理程序中使用preventDefault() 方法。如果您想同时与鼠标和触摸进行交互,请改用指针事件

基本步骤

本节包含使用上述接口的基本用法。有关更详细的示例,请参阅触摸事件概述

为每种触摸事件类型注册事件处理程序。

js
// Register touch event handlers
someElement.addEventListener("touchstart", process_touchstart, false);
someElement.addEventListener("touchmove", process_touchmove, false);
someElement.addEventListener("touchcancel", process_touchcancel, false);
someElement.addEventListener("touchend", process_touchend, false);

在事件处理程序中处理事件,实现应用程序的手势语义。

js
// touchstart handler
function process_touchstart(ev) {
  // Use the event's data to call out to the appropriate gesture handlers
  switch (ev.touches.length) {
    case 1:
      handle_one_touch(ev);
      break;
    case 2:
      handle_two_touches(ev);
      break;
    case 3:
      handle_three_touches(ev);
      break;
    default:
      gesture_not_supported(ev);
      break;
  }
}

访问触摸点的属性。

js
// Create touchstart handler
someElement.addEventListener(
  "touchstart",
  (ev) => {
    // Iterate through the touch points that were activated
    // for this element and process each event 'target'
    for (let i = 0; i < ev.targetTouches.length; i++) {
      process_target(ev.targetTouches[i].target);
    }
  },
  false,
);

阻止浏览器处理模拟的鼠标事件

js
// touchmove handler
function process_touchmove(ev) {
  // Set call preventDefault()
  ev.preventDefault();
}

最佳实践

以下是一些使用触摸事件时需要考虑的最佳实践

  • 最大程度减少触摸处理程序中完成的工作量。
  • 将触摸点处理程序添加到特定目标元素(而不是整个文档或文档树中较高级别的节点)。
  • touchstart 中添加touchmovetouchendtouchcancel 事件处理程序。
  • 目标触摸元素或节点应足够大以容纳手指触摸。如果目标区域太小,触摸它可能会导致为相邻元素触发其他事件。

实施和部署状态

触摸事件浏览器兼容性数据 指示移动浏览器之间的触摸事件支持相对广泛,尽管桌面浏览器支持滞后,但正在进行其他实现。

一些关于触摸点的触摸区域(用户与触摸表面之间的接触区域)的新功能正在标准化过程中。新功能包括最接近地外接触摸点与触摸表面接触区域的椭圆的XY半径。触摸点的旋转角度(应用于所描述椭圆以与接触区域对齐的旋转度数)以及施加到触摸点的压力量也将被标准化。

指针事件怎么样?

新输入机制的引入导致应用程序复杂性增加,以处理各种输入事件,例如键盘事件、鼠标事件、笔/触笔事件和触摸事件。为了帮助解决此问题,指针事件标准定义了处理来自包括鼠标、笔、触摸屏等设备的硬件无关指针输入的事件和相关接口。也就是说,抽象的指针创建了一个统一的输入模型,可以表示手指、笔/触笔或鼠标的接触点。请参阅指针事件 MDN 文章

指针事件模型可以简化应用程序的输入处理,因为指针表示来自任何输入设备的输入。此外,指针事件类型与鼠标事件类型非常相似(例如,pointerdownpointerup),因此处理指针事件的代码与处理鼠标事件的代码非常接近。

浏览器中指针事件的实现状态相对较高,Chrome、Firefox、IE11 和 Edge 都有完整的实现。

示例和演示

社区