使用触摸事件
如今,大多数 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);
someElement.addEventListener("touchmove", process_touchmove);
someElement.addEventListener("touchcancel", process_touchcancel);
someElement.addEventListener("touchend", process_touchend);
在事件处理程序中处理事件,实现应用程序的手势语义。
// 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 (const touch of ev.targetTouches) {
process_target(touch.target);
}
});
阻止浏览器处理模拟的鼠标事件。
// touchmove handler
function process_touchmove(ev) {
// Set call preventDefault()
ev.preventDefault();
}
最佳实践
以下是使用触摸事件时需要考虑的一些最佳实践:
- 尽量减少在触摸处理程序中完成的工作量。
- 将触摸点处理程序添加到特定的目标元素(而不是整个文档或文档树中更高的节点)。
- 在
touchstart中添加touchmove、touchend和touchcancel事件处理程序。 - 目标触摸元素或节点应足够大,以便容纳手指触摸。如果目标区域太小,触摸它可能会导致相邻元素触发其他事件。
实现和部署状态
触摸事件浏览器兼容性数据表明,移动浏览器对触摸事件的支持相对广泛,而桌面浏览器的支持则滞后,尽管正在进行其他实现。
关于触摸点的 触摸区域(用户与触摸表面之间的接触区域)的一些新功能正在标准化过程中。新功能包括最能概括触摸点与触摸表面接触区域的椭圆的X和Y半径。触摸点的旋转角度(描述椭圆以使其与接触区域对齐所需的旋转度数)以及施加到触摸点的压力量也正在标准化。
指针事件呢?
新输入机制的引入增加了处理各种输入事件(如按键事件、鼠标事件、笔/触控笔事件和触摸事件)的应用程序的复杂性。为了帮助解决这个问题,指针事件 API 定义了用于处理来自鼠标、笔、触摸屏等设备的硬件无关指针输入的事件和相关接口。也就是说,抽象的指针创建了一个统一的输入模型,可以表示手指、笔/触控笔或鼠标的接触点。
指针事件模型可以简化应用程序的输入处理,因为指针代表来自任何输入设备的输入。此外,指针事件类型与鼠标事件类型(例如 pointerdown 和 pointerup)非常相似,因此处理指针事件的代码与鼠标处理代码非常接近。
指针事件在浏览器中的实现状态相对较高,Chrome、Firefox、IE11 和 Edge 具有完整的实现。
另见
- 触摸事件
- 指针事件
- 在 web.dev 上为您的网站添加触摸功能
- 为您的网站添加触摸屏支持(简单方法)
- 绘画程序 (Rick Byers)
- 触摸/指针测试和演示 (Patrick H. Lauke)
- 触摸事件社区组
- 邮件列表
- W3C #touchevents IRC 频道