使用触摸事件
如今,大多数 Web 内容都是为键盘和鼠标输入而设计的。但是,配备触摸屏的设备(尤其是便携式设备)已成为主流,Web 应用程序可以通过使用触摸事件直接处理基于触摸的输入,或者应用程序可以使用解释的鼠标事件作为应用程序输入。使用鼠标事件的一个缺点是它们不支持并发用户输入,而触摸事件支持多个同时输入(可能在触摸表面上的不同位置),从而增强用户体验。
触摸事件接口支持应用程序特定的单点和多点触控交互,例如双指手势。多点触控交互从手指(或触笔)第一次接触接触表面开始。其他手指随后可能会接触表面,并可以选择在触摸表面上移动。当手指从表面上移开时,交互结束。在此交互过程中,应用程序在开始、移动和结束阶段接收触摸事件。应用程序可以对其自己的语义应用于触摸输入。
接口
触摸事件包含三个接口(Touch
、TouchEvent
和 TouchList
)以及以下事件类型
touchstart
- 当触摸点放置在触摸表面上时触发。touchmove
- 当触摸点沿触摸表面移动时触发。touchend
- 当触摸点从触摸表面上移开时触发。touchcancel
- 当触摸点以实现特定的方式中断时触发(例如,创建了太多触摸点)。
Touch
接口表示触摸敏感设备上的单个接触点。接触点通常称为触摸点或简称触摸。触摸通常由触摸屏、笔或触控板上的手指或触笔生成。触摸点的属性包括一个唯一标识符、触摸点的目标元素以及触摸点位置相对于视口、页面和屏幕的X和Y坐标。
TouchList
接口表示触摸表面的列表接触点,每个接触点对应一个触摸点。因此,如果用户用一根手指激活触摸表面,则列表将包含一个项目,如果用户用三根手指触摸表面,则列表长度将为三。
TouchEvent
接口表示当与触摸敏感表面的接触状态发生变化时发送的事件。状态变化包括开始与触摸表面接触、在保持与表面的接触的同时移动触摸点、释放触摸点以及取消触摸事件。此接口的属性包括多个修饰键(例如shift键)的状态以及以下触摸列表
touches
- 当前屏幕上所有触摸点的列表。targetTouches
- 目标DOM 元素上的触摸点的列表。changedTouches
- 触摸点的列表,其项目取决于关联的事件类型- 对于
touchstart
事件,它是随当前事件变为活动状态的触摸点的列表。 - 对于
touchmove
事件,它是自上次事件以来已更改的触摸点的列表。 - 对于
touchend
事件,它是已从表面上移除的触摸点的列表(即,对应于不再触摸表面的手指的触摸点集)。
- 对于
这些接口共同定义了一组相对低级的功能,但它们支持多种基于触摸的交互,包括熟悉的多点触控手势,例如多指滑动、旋转、捏合和缩放。
从接口到手势
应用程序在定义手势的语义时可能会考虑不同的因素。例如,触摸点从其起始位置到触摸结束时的位置所移动的距离。另一个潜在因素是时间;例如,触摸开始到触摸结束之间经过的时间,或旨在创建双击手势的两个连续点击之间的时间间隔。滑动的方向性(例如从左到右、从右到左等)是另一个需要考虑的因素。
应用程序使用哪个触摸列表取决于应用程序手势的语义。例如,如果应用程序支持在一个元素上进行单点触控(点击),它将在touchstart
事件处理程序中使用targetTouches
列表以应用程序特定的方式处理触摸点。如果应用程序支持任何两个触摸点的双指滑动,它将在touchmove
事件处理程序中使用changedTouches
列表来确定两个触摸点是否已移动,然后以应用程序特定的方式实现该手势的语义。
当只有一个活动触摸点时,浏览器通常会调度模拟的鼠标和点击事件。涉及两个或多个活动触摸点得多点触控交互通常只会生成触摸事件。要防止发送模拟的鼠标事件,请在触摸事件处理程序中使用preventDefault()
方法。如果您想同时与鼠标和触摸进行交互,请改用指针事件。
基本步骤
本节包含使用上述接口的基本用法。有关更详细的示例,请参阅触摸事件概述。
为每种触摸事件类型注册事件处理程序。
// 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);
在事件处理程序中处理事件,实现应用程序的手势语义。
// 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;
}
}
访问触摸点的属性。
// 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,
);
阻止浏览器处理模拟的鼠标事件。
// touchmove handler
function process_touchmove(ev) {
// Set call preventDefault()
ev.preventDefault();
}
最佳实践
以下是一些使用触摸事件时需要考虑的最佳实践
- 最大程度减少触摸处理程序中完成的工作量。
- 将触摸点处理程序添加到特定目标元素(而不是整个文档或文档树中较高级别的节点)。
- 在
touchstart
中添加touchmove
、touchend
和touchcancel
事件处理程序。 - 目标触摸元素或节点应足够大以容纳手指触摸。如果目标区域太小,触摸它可能会导致为相邻元素触发其他事件。
实施和部署状态
触摸事件浏览器兼容性数据 指示移动浏览器之间的触摸事件支持相对广泛,尽管桌面浏览器支持滞后,但正在进行其他实现。
一些关于触摸点的触摸区域(用户与触摸表面之间的接触区域)的新功能正在标准化过程中。新功能包括最接近地外接触摸点与触摸表面接触区域的椭圆的X和Y半径。触摸点的旋转角度(应用于所描述椭圆以与接触区域对齐的旋转度数)以及施加到触摸点的压力量也将被标准化。
指针事件怎么样?
新输入机制的引入导致应用程序复杂性增加,以处理各种输入事件,例如键盘事件、鼠标事件、笔/触笔事件和触摸事件。为了帮助解决此问题,指针事件标准定义了处理来自包括鼠标、笔、触摸屏等设备的硬件无关指针输入的事件和相关接口。也就是说,抽象的指针创建了一个统一的输入模型,可以表示手指、笔/触笔或鼠标的接触点。请参阅指针事件 MDN 文章。
指针事件模型可以简化应用程序的输入处理,因为指针表示来自任何输入设备的输入。此外,指针事件类型与鼠标事件类型非常相似(例如,pointerdown
和 pointerup
),因此处理指针事件的代码与处理鼠标事件的代码非常接近。
浏览器中指针事件的实现状态相对较高,Chrome、Firefox、IE11 和 Edge 都有完整的实现。
示例和演示
以下文档介绍了如何使用触摸事件并包含示例代码
触摸事件演示