指针事件

级别 2

W3C 推荐标准

此版本:
https://www.w3.org/TR/2019/REC-pointerevents2-20190404/
最新发布版本:
https://www.w3.org/TR/pointerevents2/
最新编辑草案:
https://w3c.github.io/pointerevents/
测试套件:
https://wpt.fyi/pointerevents/
实现报告:
http://w3c.github.io/test-results/pointerevents/all.html
先前版本:
https://www.w3.org/TR/2019/PR-pointerevents2-20190221/
最新推荐标准:
https://www.w3.org/TR/pointerevents1/
编辑:
Matt Brubeck (Mozilla)
Rick Byers (Google)
Patrick H. Lauke (The Paciello Group)
Navid Zolghadr (Google)
参与:
GitHub w3c/pointerevents
提交Bug
提交历史
拉取请求
邮件列表:
邮件列表存档

请检查勘误表,查看自发布以来报告的任何错误或问题。


摘要

本规范中的功能扩展或修改了指针事件中的那些功能,这是一项W3C推荐标准,描述了用于处理硬件无关的指针输入(如鼠标、触控笔、触摸屏等)的事件和相关接口。为了与现有基于鼠标的内容兼容,本规范还描述了为其他指针设备类型触发鼠标事件的映射。

本文档状态

本节描述了本文档在发布时的状态。其他文档可能会取代本文档。当前W3C 出版物列表和本技术报告的最新修订版可在W3C技术报告索引中找到:https://www.w3.org/TR/。

本文档由Pointer Events 工作组发布为推荐标准。 实现报告 展示了互操作性。 本文档取代了 [PointerEvents1]。

本规范是对[PointerEvents1]的更新,该规范主要由微软Internet Explorer和微软Edge广泛支持(尽管在Pointer Events规范作为W3C推荐标准发布时,Mozilla Firefox的预发布版本中也存在一个进一步独立且大多互操作的实现)。第2级包括编辑澄清、新功能和小的破坏性更改,旨在解决关于设计某些方面提出的某些限制和担忧,以促进更广泛的浏览器采用。

自上次发布以来没有进行任何更改。

GitHub Issues是讨论本规范的首选方式。 或者,您也可以发送评论至我们的邮件列表。 请将其发送至 public-pointer-events@w3.org (存档)。

本文档已经由W3C成员、软件开发人员以及其他W3C小组和感兴趣的各方审查,并由主任批准为W3C推荐标准。它是一个稳定的文档,可以用作参考资料或在其他文档中引用。W3C在制定推荐标准中的作用是引起对规范的关注并促进其广泛部署。这增强了Web的功能和互操作性。

本文档由 根据 W3C 专利政策运作的小组编写。 W3C 维护着 与本小组交付成果相关的任何专利披露的公共列表 该页面还包括 专利披露说明。任何知晓包含 必要权利要求 的专利的个人必须根据 W3C专利政策第6节披露信息。

本文档受 2019年3月1日 W3C流程文档的约束。

1. 简介

本节为非规范性内容。

如今,大多数[HTML5]内容是使用和/或设计用于鼠标输入的。那些以自定义方式处理输入的内容通常使用到[UIEVENTS]鼠标事件。然而,今天的新计算设备整合了其他形式的输入,包括触摸屏、触控笔等。已经提出了用于分别处理这些输入形式的事件类型。然而,这种方法在为新输入类型添加支持时,往往会导致不必要的逻辑重复和事件处理开销。当内容仅针对一种设备类型编写时,这通常会产生兼容性问题。此外,为了与现有基于鼠标的内容兼容,大多数用户代理为所有输入类型触发鼠标事件。这使得鼠标事件是否代表实际的鼠标设备,还是为了兼容性而从其他输入类型生成,变得模糊不清,这使得同时针对两种设备类型进行编码变得困难。

为了降低针对多种输入类型编码的成本,并帮助解决上述鼠标事件的模糊问题,本规范定义了一种更抽象的输入形式,称为指针。指针可以是屏幕上由鼠标光标、笔、触摸(包括多点触控)或其他指点输入设备产生的任何接触点。这个模型使得编写适用于任何硬件的站点和应用程序变得更容易。在需要特定设备处理的场景下,本规范还定义了用于检查产生事件的设备类型的属性。主要目标是提供一组统一的事件和接口,便于跨设备指针输入的编写,同时仅在需要增强体验时允许特定设备的处理。

另一个关键目标是使多线程用户代理能够处理默认的触摸操作,如滚动,而不会因脚本执行而阻塞。

注意

虽然本规范定义了用于各种指针输入的统一事件模型,但该模型不涵盖其他形式的输入,如键盘或类键盘接口(例如,运行在仅有触摸屏设备上的屏幕阅读器或类似辅助技术,使用户能够依次导航焦点控件和元素)。尽管用户代理可能选择响应这些接口生成指针事件,但这种情况不在本规范的范围内。

首先,鼓励作者通过响应诸如focusblurclick等高级事件为所有形式的输入提供等效的功能。然而,在使用低级事件(如指针事件)时,鼓励作者确保支持所有类型的输入。在键盘和类键盘接口的情况下,这可能需要添加显式的键盘事件处理。有关详细信息,请参见WCAG 2.0 指南 2.1

指针输入结合了来自鼠标、笔、触摸等的输入。
1 指针是输入设备的一种与硬件无关的表示形式,它可以定位在屏幕上的特定坐标(或坐标集)。

处理通用指针输入的事件看起来很像鼠标事件:pointerdown、pointermove、pointerup、pointerover、pointerout等。这有助于将内容从鼠标事件迁移到指针事件。 指针事件提供了鼠标事件中存在的所有常用属性(客户端坐标、目标元素、按钮状态等),并新增了用于其他形式输入的属性:压力、接触几何、倾斜等。因此,作者可以轻松地编写指针事件,以在不同输入类型之间共享逻辑,并在必要时针对特定输入类型进行定制,以获得最佳体验。

尽管指针事件源自多种输入设备,但它们并不是从其他设备特定的事件集中生成的。虽然为了兼容性鼓励这样做,但本规范不要求支持其他设备特定的事件(例如鼠标事件、触摸事件等)。用户代理可以支持指针事件而不支持任何其他设备事件。为了与仅针对鼠标特定事件编写的内容兼容,本规范确实提供了一个可选部分,描述了如何基于来自非鼠标设备的指针输入生成兼容鼠标事件

注意

本规范未对同时支持触摸事件(如[TOUCH-EVENTS]中定义的)和指针事件的用户代理的预期行为提供任何建议。有关这两个规范之间关系的更多信息,请参阅触摸事件社区组

2. 一致性

除了标记为非规范性的部分外,本规范中的所有编写指南、图表、示例和注释都是非规范性的。 本规范中的其他内容都是规范性的。

关键字MAY(可以)、MUST(必须)、MUST NOT(不得)、OPTIONAL(可选)、SHOULD(应该)和 SHOULD NOT(不应该)应按照[RFC2119]中的描述进行解释。

3. 示例

本节为非规范性内容。

以下是一些示例代码,展示了如何使用本规范中的API。

示例 1: 功能检测和事件绑定
/* 绑定到指针事件或传统的触摸/鼠标事件 */
    
    if (window.PointerEvent) {
        // 如果支持指针事件,只监听指针事件
        target.addEventListener("pointerdown", function(e) {
            // 如果需要,为不同的触摸/笔/鼠标行为应用单独的逻辑
            ...
        });
        ...
    } else {
        // 传统的触摸/鼠标事件处理程序
        target.addEventListener('touchstart', function(e) {
            // 防止兼容性鼠标事件和点击
            e.preventDefault();
            ...
        });
        ...
        target.addEventListener('mousedown', ...);
        ...
    }
    
    // 键盘处理的其他事件监听器
    ...
示例 2: 检测用户输入类型
window.addEventListener("pointerdown", detectInputType);
    
    function detectInputType(event) {
        switch(event.pointerType) {
            case "mouse":
                /* 检测到鼠标输入 */
                break;
            case "pen":
                /* 检测到笔/触控笔输入 */
                break;
            case "touch":
                /* 检测到触摸输入 */
                break;
            default:
                /* pointerType为空(无法检测到)或UA特定的自定义类型 */
        }
    }
示例 3: 基本的HTML5画布绘画应用程序
<style>
      /* 禁用固有的用户代理触摸行为(如平移或缩放),以便将画布元素上的所有事件传递给应用程序。 */
    
      canvas { touch-action: none; }
    </style>
    
    <canvas id="drawSurface" width="500px" height="500px" style="border:1px solid black;"></canvas>
    
    <script>
        var canvas = document.getElementById("drawSurface"),
        context = canvas.getContext("2d");
    
        if (window.PointerEvent) {
            canvas.addEventListener("pointermove", paint);
            if(window.navigator.maxTouchPoints>1)
               // 用户代理和硬件支持多点触控
               ...
        } else {
            // 为不支持指针事件的用户代理提供回退
            canvas.addEventListener("mousemove", paint);
        }
    
        function paint(event) {
            if(event.buttons>0)
               context.fillRect(event.clientX, event.clientY, 5, 5);
        }
    
        // 键盘处理的其他事件监听器/函数
        ...
    </script>
示例 4: 调整元素大小以匹配接触几何
<div style="position:absolute; top:0px; left:0px; width:100px;height:100px;"></div>
    <script>
    window.addEventListener("pointerdown", checkPointerSize);
    
    function checkPointerSize(event) {
        event.target.style.width = event.width + "px";
        event.target.style.height = event.height + "px";
    }
    </script>
示例 5: 从脚本触发不可信的指针事件
var event = new PointerEvent("pointerover",
      { bubbles: true,
        cancelable: true,
        composed: true,
        pointerId: 42,
        pointerType: "pen",
        clientX: 300,
        clientY: 500
      });
    eventTarget.dispatchEvent(event);

4. 术语表

本节为非规范性内容。

活动按钮状态
指针的buttons属性值非零时的情况。对于鼠标,这是设备至少有一个按钮被按下时。对于触摸,这是与数字化仪有物理接触时。对于笔,这是当笔与数字化仪有物理接触时,或悬停时按下了至少一个按钮的情况。
活动指针
任何能够产生事件的触摸接触、笔触、鼠标光标或其他指针。如果给定的指针(由唯一的pointerId标识)可能在文档中产生额外的事件,那么该指针仍然被视为活动状态。示例:
  • 连接到设备的鼠标始终处于活动状态。
  • 屏幕上的触摸接触被视为活动状态。
  • 如果触摸接触或笔触超出了数字化仪的范围,则不再视为活动状态。
注意
在某些平台上,活动指针的集合包括设备的所有指针输入,包括任何不针对用户代理的输入(例如那些针对其他应用程序的输入)。
注意
顶级浏览上下文(如[HTML5]中定义的)范围内,每个活动指针应具有相同的id。然而,在多个顶级浏览上下文中,没有这样的保证。
已取消事件
默认操作被preventDefault()阻止,通过在事件处理程序中返回false或其他方式(如[UIEVENTS]和[HTML5]中定义)取消的事件。
接触几何
输入(最常见的是触摸)在数字化仪上的边界框。这通常指的是分辨率比单个像素更粗糙的指针输入设备。一些设备根本不报告这些数据。
数字化仪
一种输入感应设备,其中表面可以检测接触和/或接近的输入。最常见的是,指感应触摸接触或笔触输入的表面。
命中测试
用户代理确定指针事件目标元素的过程。通常,通过考虑指针的位置以及文档中元素在屏幕媒体上的视觉布局来确定。
指针
能够定位屏幕上特定坐标(或坐标集)的输入设备的与硬件无关的表示形式,例如鼠标、笔或触摸接触。
用户代理
一种程序,如浏览器或内容编写工具,通常运行在客户端机器上,代表用户执行内容的检索、解释、执行、呈现或创建。
排队任务
将任务添加到相关事件循环的事件任务队列中,如[HTML5]中定义。

5. 指针事件和接口

5.1 PointerEvent接口

pointerId

指引发事件的指针的唯一标识符。该标识符必须活动指针 中与其他所有指针唯一(如[HTML5]中定义的顶级浏览上下文)。如果需要,用户代理可以从先前活动的指针中回收以前的pointerId值。

注意

pointerId选择算法是实现特定的。因此,作者不能假定这些值传达了除指针的标识符之外的任何特殊含义。用户代理可能会简单地为每个活动的指针分配一个从1开始的数字,按激活的顺序排列,但这些值不保证是单调递增的。其他用户代理可能会选择为每个活动指针分配一个完全随机且唯一的数字。然而,在后一种情况下,用户代理必须确保分配的pointerId在当前页面的生命周期内保持不变,并且任何新的pointerId值都是不可预测的(例如,通过使用密码学上强随机性生成),以最大限度地减少用户在不同页面上被唯一指纹识别和跟踪的可能性。

width

指针接触几何的宽度(X轴方向的大小),单位为CSS像素(参见[CSS21])。对于给定的指针,此值可以在每个事件上更新。对于通常缺少接触几何的输入(如传统鼠标),以及在硬件未检测到输入的实际几何形状的情况下,用户代理必须返回默认值1。

height

指针接触几何的高度(Y轴方向的大小),单位为CSS像素(参见[CSS21])。对于给定的指针,此值可以在每个事件上更新。对于通常缺少接触几何的输入(如传统鼠标),以及在硬件未检测到输入的实际几何形状的情况下,用户代理必须返回默认值1。

pressure

指针输入的归一化压力,范围为[0,1],其中0和1分别代表硬件能够检测到的最小和最大压力。对于不支持压力的硬件和平台,当处于活动按钮状态时,该值必须为0.5,否则为0。注意:所有pointerup事件的压力值为0。

tangentialPressure

指针输入的归一化切向压力(也称为桶形压力),通常由额外的控制装置(例如气笔触控笔上的指轮)设置,范围为[-1,1],其中0是控制装置的中立位置。请注意,某些硬件可能仅支持范围为[0,1]的正值。对于不支持切向压力的硬件和平台,该值必须为0。

tiltX

在Y-Z平面和包含传感器(例如笔触)轴与Y轴的平面之间的平面角度(以度为单位,范围为[-90,90])。正的tiltX表示向右倾斜。tiltX可以与tiltY一起使用,以表示传感器与数字化仪法线之间的倾斜。对于不报告倾斜的硬件和平台,该值必须为0。

tiltX解释图
2 正的tiltX
tiltY

在X-Z平面和包含传感器(例如笔触)轴与X轴的平面之间的平面角度(以度为单位,范围为[-90,90])。正的tiltY表示向用户方向倾斜。tiltY可以与tiltX一起使用,以表示传感器与数字化仪法线之间的倾斜。对于不报告倾斜的硬件和平台,该值必须为0。

tiltY解释图
3 负的tiltY
twist

传感器(例如笔触)的顺时针旋转(以度为单位,范围为[0,359])。对于不报告旋转的硬件和平台,该值必须为0。

pointerType

指示引发事件的设备类型(鼠标、笔、触摸等)。如果用户代理要触发指针事件,则pointerType的值必须按照以下表格:

指针设备类型 pointerType
鼠标 mouse
笔触 pen
触摸接触 touch

如果用户代理无法检测设备类型,则该值必须为空字符串。如果用户代理支持上面未列出的指针设备类型,则pointerType的值应当使用供应商前缀,以避免为不同类型的设备使用冲突的名称。未来的规范可以为其他设备类型提供其他规范值。

注意
请参阅示例 2,了解pointerType的基本用法。此外,开发人员应包括某种形式的默认处理,以覆盖可能已经实现其自定义pointerType值的用户代理,并处理pointerType为空字符串的情况。
isPrimary

指示该指针是否表示此指针类型的主要指针

PointerEventInit字典用于PointerEvent接口的构造函数,以提供构造不可信(合成)指针事件的机制。它继承自[UIEVENTS]中定义的MouseEventInit字典。构造事件的步骤在[DOM4]中定义。参见示例,以获取触发不可信指针事件的示例代码。

注意
PointerEvent接口继承自[UIEVENTS]中定义并由[CSSOM-VIEW]扩展的MouseEvent

5.1.1 按钮状态

5.1.1.1 组合按钮交互

一些指针设备,如鼠标或笔触,支持多个按钮。在[UIEVENTS]鼠标事件模型中,每次按下按钮都会产生mousedownmouseup事件。为了更好地抽象此硬件差异并简化跨设备输入的编写,指针事件不会为组合按钮按下(在指针设备的另一个按钮已经按下时再按下另一个按钮)触发重叠的pointerdownpointerup事件。

相反,可以通过检查buttonbuttons属性的变化来检测组合按钮按下。buttonbuttons属性继承自[UIEVENTS]中的MouseEvent接口,但语义和值有所变化,如以下章节所述。

注意
buttonbuttons属性的修改仅适用于指针事件。对于任何兼容鼠标事件buttonbuttons的值应遵循[UIEVENTS]。
5.1.1.2 The button 属性

为了识别任何指针事件中的按钮状态转换(不仅仅是pointerdownpointerup),button属性指示触发事件的设备按钮。

设备按钮更改 button
自上次事件以来,按钮或触摸/笔接触均未发生变化 -1
左键鼠标,
触摸接触,
笔接触
0
中键鼠标 1
右键鼠标,
笔桶按钮
2
X1(后退)鼠标 3
X2(前进)鼠标 4
笔擦除按钮 5
注意
在鼠标拖动过程中,pointermove事件中的button属性值与mousemove事件中的值会有所不同。例如,在按住右键拖动鼠标时,pointermove事件的button值为-1,而mousemove事件的button值为2。
5.1.1.3 The buttons 属性

buttons属性以位掩码的形式给出设备按钮的当前状态(与MouseEvent相同,但扩展了一组可能的值)。

设备按钮的当前状态 buttons
移动鼠标时未按下任何按钮,
笔在悬停时移动且未按下任何按钮
0
左键鼠标,
触摸接触,
笔接触
1
中键鼠标 4
右键鼠标,
笔桶按钮
2
X1(后退)鼠标 8
X2(前进)鼠标 16
笔擦除按钮 32

5.1.2 主指针Primary Pointer

在多指针(例如多点触控)场景中,isPrimary 属性用于在每种指针类型的 活动指针 集合中识别主指针。

  • 在任何给定时刻,每种指针类型最多只能有一个主指针。
  • 对于特定指针类型,第一个变为活动状态的指针(例如,在多点触控交互中,第一个触摸屏幕的手指)将成为该指针类型的主指针。
  • 只有主指针会产生 兼容鼠标事件。如果存在多个 主指针,这些指针将同时产生 兼容鼠标事件
注意
希望实现单指针交互的作者可以通过忽略非主指针来实现(但是,请参阅下面关于 多个主指针 的注释)。
注意
当两种或更多种指针设备类型同时使用时,多个指针(每种 pointerType 一个)被视为主指针。例如,触控接触和鼠标光标同时移动将产生两个都被视为主指针的指针。
注意
某些设备、操作系统和用户代理可能会忽略同时使用多种指针输入,以避免意外交互。例如,支持触摸和笔交互的设备可能在使用笔时忽略触摸输入,以允许用户在使用笔时将手放在触摸屏上(通常称为“手掌拒绝”)。目前,作者无法抑制这种行为。
注意
在某些情况下,用户代理可以触发没有任何指针标记为主指针的指针事件。例如,当有多个特定类型的活动指针(如多点触控)且主指针被移除(例如离开屏幕)时,将不会有主指针事件。此外,在通过设备上的所有活动指针确定主指针的平台上(包括针对用户代理以外的应用程序的指针),如果第一个触摸交互目标在用户代理之外而第二个(多点触控)触摸交互目标在用户代理内部,则用户代理可能会触发第二次接触的指针事件,isPrimary 的值为 false
注意
当前的操作系统和用户代理通常没有多个鼠标输入的概念。当存在多个鼠标设备时(例如,在同时使用触摸板和外部鼠标的笔记本电脑上),所有鼠标设备通常被视为单一设备——在任何设备上的移动都转换为单个鼠标指针的移动,且不同鼠标设备上的按钮按下没有区别。因此,通常只会有一个鼠标指针,该指针将是主指针。

5.1.3 使用PointerEvent接口触发事件

触发名为e的指针事件”是指按照[DOM4]的定义触发名为e的事件,该事件使用PointerEvent接口,其属性设置如PointerEvent接口属性和默认行为中定义。

如果事件不是gotpointercapturelostpointercapture,则运行处理待处理的指针捕获步骤。

触发事件的目标对象按以下方式确定:

如果这是pointerdown事件,关联设备为直接操作设备且目标为Element,则为此pointerId设置指针捕获至目标元素,如隐式指针捕获中所述。

向确定的目标触发事件。

注意
使用指针捕获目标覆盖作为目标而不是正常的命中测试结果可能会触发一些边界事件。这与指针离开其先前目标并进入此新捕获目标相同——如果它们是不同的目标,则应首先分派边界事件。当捕获被释放时,可能会发生同样的情况,因为指针正在离开捕获目标并进入命中测试目标。
5.1.3.1 属性和默认行为

在本规范中定义的事件类型的bubblescancelable属性以及默认行为如下表所示。每种事件类型的详细信息在指针事件类型中提供。

事件类型 可冒泡 可取消 默认行为
pointerover
pointerenter
pointerdown 不同:当指针为主要指针时,所有mousedown事件的默认行为
取消此事件还会为此pointerType设置PREVENT MOUSE EVENT标志,从而阻止随后触发某些兼容鼠标事件
pointermove 不同:当指针为主要指针时,所有mousemove的默认行为
pointerup 不同:当指针为主要指针时,所有mouseup的默认行为
pointercancel
pointerout
pointerleave
gotpointercapture
lostpointercapture

对于上表中的所有指针事件,pointerenterpointerleave除外,composed ([DOM4]) 属性应当true。 对于上表中的所有指针事件,detail [UIEVENTS]属性应当为0。

注意
许多用户代理在MouseEvents中暴露非标准属性fromElementtoElement以支持遗留内容。在这些用户代理中,PointerEvents中这些(继承的)属性的值必须为null,以鼓励使用标准化的替代方案(即targetrelatedTarget)。

类似于MouseEvents [UIEVENTS],relatedTarget应初始化为指针刚刚离开的元素(在pointeroverpointerenter事件的情况下)或指针即将进入的元素(在pointeroutpointerleave事件的情况下)。对于其他指针事件,此值将默认为null。请注意,当元素接收到指针捕获时,该指针的所有后续事件都将被视为在捕获元素的边界内。

对于gotpointercapturelostpointercapture,除了上表中定义的属性外,其他所有属性应与导致用户代理运行处理待处理的指针捕获并触发gotpointercapturelostpointercapture事件的指针事件相同。

5.1.3.2 处理待处理的指针捕获

隐式释放指针捕获以及触发非gotpointercapturelostpointercapture的指针事件时,用户代理必须运行以下步骤。

  1. 如果此指针的指针捕获目标覆盖已设置且不等于待处理的指针捕获目标覆盖,则在指针捕获目标覆盖节点上触发一个名为lostpointercapture的指针事件。
  2. 如果此指针的待处理的指针捕获目标覆盖已设置且不等于指针捕获目标覆盖,则在待处理的指针捕获目标覆盖节点上触发一个名为gotpointercapture的指针事件。
  3. 指针捕获目标覆盖设置为待处理的指针捕获目标覆盖(如果已设置)。否则,清除指针捕获目标覆盖

5.2 指针事件类型

以下是本规范中定义的事件类型。

主要指针的情况下,这些事件(gotpointercapturelostpointercapture除外)也可能触发兼容鼠标事件

5.2.1 pointerover事件

当指针设备移入元素的命中测试边界时,用户代理必须触发一个名为pointerover的指针事件。请注意,setPointerCapturereleasePointerCapture可能已更改命中测试目标,而当指针被捕获时,为触发边界事件的目的,指针始终被视为在捕获元素的边界内。对于不支持悬停的设备,在触发pointerdown事件之前,用户代理必须触发此事件(请参见pointerdown)。

5.2.2 pointerenter事件

当指针设备移入元素或其后代的命中测试边界时,用户代理必须触发一个名为pointerenter的指针事件,包括由于来自不支持悬停的设备的pointerdown事件(请参见pointerdown)。请注意,setPointerCapturereleasePointerCapture可能已更改命中测试目标,而当指针被捕获时,为触发边界事件的目的,指针始终被视为在捕获元素的边界内。此事件类型类似于pointerover,但不同之处在于它不会冒泡。

注意
此事件类型与[UIEVENTS]中描述的mouseenter事件以及[CSS21]中描述的CSS:hover伪类之间存在相似之处。另请参见pointerleave事件。

5.2.3 pointerdown事件

当指针进入激活按钮状态时,用户代理必须触发一个名为pointerdown的指针事件。对于鼠标,这是设备从没有按钮按下过渡到至少有一个按钮按下时的情况。对于触摸,这是与数字化仪进行物理接触的情况。对于笔,当笔与数字化仪进行物理接触而没有任何按钮按下时,或从没有按钮按下过渡到悬停时至少有一个按钮按下的情况。

注意
对于鼠标(或其他多按钮指针设备),这意味着并非所有与mousedownmouseup相同的情况下都会触发pointerdownpointerup。有关更多信息,请参见和弦按钮

对于不支持悬停的输入设备,用户代理必须在分派pointerdown事件之前,触发名为pointerover的指针事件,然后触发名为pointerenter的指针事件。

注意
作者可以通过取消pointerdown事件(如果isPrimary属性为true),防止触发某些兼容鼠标事件。这会在指针上设置PREVENT MOUSE EVENT标志。然而,请注意,这不会阻止mouseovermouseentermouseoutmouseleave事件的触发。

5.2.4 pointermove事件

当指针改变坐标时,用户代理必须触发一个名为pointermove的指针事件。此外,当指针改变按钮状态、压力、切向压力、倾斜、旋转或接触几何(例如widthheight)且情况下不会产生本规范中定义的其他指针事件时,用户代理必须触发一个名为pointermove的指针事件

5.2.5 pointerup事件

当指针离开激活按钮状态时,用户代理必须触发一个名为pointerup的指针事件。对于鼠标,这是设备从至少一个按钮按下过渡到没有按钮按下的情况。对于触摸,这是物理接触从数字化仪中移除的情况。对于笔,这是当笔从与数字化仪的物理接触中移除而没有任何按钮按下时,或从悬停时至少有一个按钮按下的情况过渡到没有按钮按下的情况。

对于不支持悬停的输入设备,用户代理必须在分派pointerup事件后,触发名为pointerout的指针事件,然后触发名为pointerleave的指针事件。

注意
对于鼠标(或其他多按钮指针设备),这意味着并非所有与mousedownmouseup相同的情况下都会触发pointerdownpointerup。有关更多信息,请参见和弦按钮

5.2.6 pointercancel事件

用户代理必须在以下情况下触发一个名为pointercancel的指针事件

  • 用户代理已确定指针不太可能继续产生事件(例如,由于硬件事件)。
  • 在触发pointerdown事件后,如果指针随后用于操作页面视口(例如平移或缩放)。
    注意
    用户代理可以通过多种指针类型(例如触摸和笔)触发平移或缩放操作,因此平移或缩放操作的开始可能会导致取消各种指针,包括具有不同指针类型的指针。
  • 拖动操作开始之前[HTML],对于导致拖动操作的指针,触发此事件。
    注意
    如果通过任何方式(例如调用dragstart事件上的preventDefault)阻止拖动操作的开始,则不会触发pointercancel事件。

在触发pointercancel事件后,用户代理必须还触发一个名为pointerout的指针事件,然后触发一个名为pointerleave的指针事件。

注意

本节为非规范性内容。

用户代理可能确定指针不太可能继续产生事件的场景示例包括:

  • 设备的屏幕方向在指针活动时发生了变化。
  • 用户输入的同时指针数量超过了设备支持的数量。
  • 用户代理将输入解释为意外(例如,硬件支持手掌拒绝)。
  • 用户代理将输入解释为平移或缩放手势。

更改设备屏幕方向、识别意外输入或使用指针操作视口(例如平移或缩放)的方法不在本规范的范围内。

5.2.7 pointerout事件

当发生以下任何一种情况时,用户代理必须触发一个名为pointerout的指针事件

  • 指针设备移出了元素的命中测试边界。请注意,setPointerCapturereleasePointerCapture可能已更改命中测试目标,而当指针被捕获时,为触发边界事件的目的,指针始终被视为在捕获元素的边界内。
  • 对于不支持悬停的设备,在触发pointerup事件后(请参见pointerup)。
  • 在触发pointercancel事件后(请参见pointercancel)。
  • 当笔离开数字化仪可检测的悬停范围时。

5.2.8 pointerleave事件

当指针设备移出了元素及其所有后代的命中测试边界时,用户代理必须触发一个名为pointerleave的指针事件,包括由于来自不支持悬停的设备的pointeruppointercancel事件(请参见pointeruppointercancel)。请注意,setPointerCapturereleasePointerCapture可能已更改命中测试目标,而当指针被捕获时,为触发边界事件的目的,指针始终被视为在捕获元素的边界内。用户代理必须还应在笔离开数字化仪可检测的悬停范围时触发一个指针事件,名为pointerleave。此事件类型类似于pointerout,但不同之处在于它不会冒泡,并且在指针设备离开元素边界及其所有后代的边界之前,必须不触发此事件。

注意
此事件类型与[UIEVENTS]中描述的mouseleave事件以及[CSS21]中描述的CSS:hover伪类之间存在相似之处。另请参见pointerenter事件。

5.2.9 gotpointercapture 事件

当元素接收到指针捕获时,用户代理必须触发一个名为gotpointercapture的指针事件。此事件在接收到指针捕获的元素上触发。此后,该指针的后续事件将在该元素上触发。请参见设置指针捕获处理待处理的指针捕获部分。

5.2.10 lostpointercapture 事件

在释放指针的指针捕获后,用户代理必须触发一个名为lostpointercapture的指针事件。此事件必须在释放捕获后触发指针的任何后续事件之前触发。此事件在从中移除指针捕获的元素上触发。指针的后续事件遵循确定事件目标的正常命中测试机制(不在本规范范围内)。请参见释放指针捕获隐式释放指针捕获处理待处理的指针捕获部分。

6. Element接口的扩展

以下部分描述了对[HTML5]中定义的现有Element接口的扩展,以便于设置和释放指针捕获。

partial interface Element {
      void setPointerCapture (long pointerId);
      void releasePointerCapture (long pointerId);
      boolean hasPointerCapture (long pointerId);
    };
setPointerCapture

由参数pointerId标识的指针设置指针捕获,目标是调用此方法的元素。对于该指针的后续事件,捕获目标将替代正常的命中测试结果,就好像指针始终位于捕获目标上,并且它们必须始终定位于此元素,直到捕获被释放。指针必须处于激活按钮状态,此方法才能生效,否则会静默失败。当提供的方法的参数不匹配任何活动指针时,会抛出名称为NotFoundErrorDOMException

releasePointerCapture

释放从调用此方法的元素中由参数pointerId标识的指针指针捕获。该指针的后续事件遵循正常的命中测试机制(不在本规范范围内)以确定事件目标。当提供的方法的参数不匹配任何活动指针时,会抛出名称为NotFoundErrorDOMException

hasPointerCapture

指示调用此方法的元素是否对由参数pointerId标识的指针拥有指针捕获。具体而言,如果pointerId待处理指针捕获目标覆盖被设置为调用此方法的元素,则返回true,否则返回false

注意
即使该元素尚未收到gotpointercapture事件,此方法仍将在调用setPointerCapture后立即返回true。因此,它在pointerdown事件侦听器内部检测隐式指针捕获时非常有用。

7. GlobalEventHandlers混入的扩展

以下部分描述了对现有的GlobalEventHandlers混入的扩展,这些扩展在[HTML5]中定义,以便于事件处理程序的注册。

partial interface mixin GlobalEventHandlers {
        attribute EventHandler ongotpointercapture;
        attribute EventHandler onlostpointercapture;
        attribute EventHandler onpointerdown;
        attribute EventHandler onpointermove;
        attribute EventHandler onpointerup;
        attribute EventHandler onpointercancel;
        attribute EventHandler onpointerover;
        attribute EventHandler onpointerout;
        attribute EventHandler onpointerenter;
        attribute EventHandler onpointerleave;
    };
ongotpointercapture
[HTML5]中定义的gotpointercapture事件类型的事件处理程序IDL属性。
onlostpointercapture
[HTML5]中定义的lostpointercapture事件类型的事件处理程序IDL属性。
onpointerdown
[HTML5]中定义的pointerdown事件类型的事件处理程序IDL属性。
onpointermove
[HTML5]中定义的pointermove事件类型的事件处理程序IDL属性。
onpointerup
[HTML5]中定义的pointerup事件类型的事件处理程序IDL属性。
onpointercancel
[HTML5]中定义的pointercancel事件类型的事件处理程序IDL属性。
onpointerover
[HTML5]中定义的pointerover事件类型的事件处理程序IDL属性。
onpointerout
[HTML5]中定义的pointerout事件类型的事件处理程序IDL属性。
onpointerenter
[HTML5]中定义的pointerenter事件类型的事件处理程序IDL属性。
onpointerleave
[HTML5]中定义的pointerleave事件类型的事件处理程序IDL属性。

8. Navigator接口的扩展

Navigator接口在[HTML5]中定义。本规范扩展了Navigator接口,以提供设备检测支持。

partial interface Navigator {
        readonly  attribute long maxTouchPoints;
    };
maxTouchPoints

设备支持的最大同时触控点数。如果设备具有多个数字转换器(例如,多个触摸屏),则该值必须是每个单独数字转换器支持的最大触控点数中的最大值。

例如,假设一台设备有3个触摸屏,分别支持2个、5个和10个同时触控点数。那么maxTouchPoints的值应该是10

注意
虽然maxTouchPoints值大于0表示用户的设备能够支持触摸输入,但这并不一定意味着用户使用触摸输入。作者在考虑系统上可能存在的其他输入模式(如鼠标、笔、屏幕阅读器等)时应谨慎。
注意
maxTouchPoints通常用于确保内容的交互模型可以被当前硬件识别。可以向硬件能力较低的用户提供用户界面功能。在精确的触控点数未知的平台上,提供保证被识别的最小点数。因此,可能会出现识别的触控点数超过maxTouchPoints值的情况。

9. 声明默认触控行为的候选区域

对于触控输入,任何指针事件的默认操作不得是视口的操作(例如平移或缩放)。

注意
触控操作故意不是指针事件的默认操作。取消事件依赖性有助于用户代理进行性能优化。
注意
虽然使用指针操作视口的问题通常仅限于触控输入(用户的手指可以与内容交互并平移/缩放页面),但某些用户代理也可能允许其他指针类型进行相同类型的(直接或间接)操作。例如,在移动/平板设备上,用户也可以使用触控笔进行平移。本节也适用于这些场景(尽管规范使用了“触控”一词)。

9.1 touch-action CSS属性

名称: touch-action
值: auto | none | [ pan-x || pan-y ] | manipulation
初始值: auto
应用于: 除非替换行内元素、表行、行组、表列和列组外的所有元素。
继承:
百分比: 不适用
媒体: 视觉
计算值: 与指定值相同。

touch-action CSS属性决定触控输入可能触发由用户代理提供的默认行为。这包括但不限于平移或缩放等行为。请参阅touch-action一节。

注意
如前所述,在允许其他指针类型进行默认操作(如平移或缩放)的用户代理中,这些用户代理必须为这些指针类型应用相同的考虑。例如,如果一个用户代理允许使用触控笔进行平移/缩放,则用户代理必须在确定应处理哪些默认行为时考虑相关的touch-action值。

在执行用户代理触控行为期间,用户代理不得为指针触发后续指针事件。用户代理必须触发名为pointercancel的指针事件(随后触发pointerout事件和一个或多个pointerleave事件),以便在以下所有条件都成立时结束该指针的事件流:

注意
用户代理可能会为默认行为实现复杂的手势,这些手势涉及一系列独立的离散手势,但它们都被视为单个连续手势的一部分。例如,考虑在触摸屏上的“快速滑动以滚动”手势:用户通过快速手指移动开始平移文档,然后从触摸屏上抬起手指,文档会继续以模拟惯性滚动。当文档仍在移动时,用户可能会将手指放在触摸屏上并执行另一个“快速滑动”以进一步增加滚动的动量,或抵消当前的滚动以减慢速度、完全停止滚动或反转滚动方向。由于本规范没有规范性地定义手势和默认行为的实现,因此由用户代理决定在解释为第二次“快速滑动”或抵消当前滚动之前,是否应触发指针事件。

9.2 确定支持的触控行为

当用户触摸一个元素时,该触摸的效果由touch-action属性的值以及该元素及其祖先的默认触控行为确定,如下所示:

注意
某些用户代理支持通过多个并发指针的交互触发的触控行为(例如多点触控)。如何处理或关联多个并发指针的touch-action值不在本规范范围之内。

9.3 touch-action值的详细信息

auto
用户代理可以确定任何允许的触控行为,例如触控开始时的视口平移和缩放。
none
开始于元素上的触控不得触发默认触控行为。
pan-x
pan-y

用户代理可以仅将触控视为滚动开始的目的,这些滚动必须在所有列出的值指定的方向中之一开始。一旦滚动开始,用户可以反转方向,即使在反转方向开始的滚动被禁止时也是如此。相比之下,当滚动限制为仅沿单个轴开始时(例如pan-y),在滚动过程中无法更改轴。

manipulation
用户代理可以仅将触控视为滚动和连续缩放的目的。auto支持的任何其他行为不在本规范范围之内。
注意
实现中的其他touch-action值在[COMPAT]中定义
注意
“平移”和“滚动”这两个术语被视为同义词。定义触发平移或滚动的交互或手势,或触发autonone值的行为不在本规范范围之内。
注意
touch-action属性仅适用于同时支持CSS宽度高度属性的元素(参见[CSS21])。此限制旨在促进用户代理对低延迟触控操作的优化。对于默认不支持的元素(如<span>,这是一个非替换行内元素(参见[HTML5]),作者可以将CSSdisplay属性设置为支持宽度高度的值,例如。未来的规范可以将此API扩展到所有元素。
注意
禁用某些默认触控行为可以使用户代理更快地响应其他行为。例如,使用auto时,用户代理通常会在点击之前添加300ms的延迟,以允许处理双击手势。在这些情况下,显式设置touch-action: nonetouch-action: manipulation将删除此延迟。请注意,确定点击或双击手势的方法不在本规范范围之内。
示例 6: 禁止所有触控行为
<div style="touch-action: none;">
        该元素接收所有触控的指针事件。
    </div>
示例 7: 仅允许水平平移
<div style="touch-action: pan-x;">
        当不在水平方向平移时,该元素接收指针事件。
    </div>
示例 8: 禁止触控行为的子区域
<div style="overflow: auto;">
        <div style="touch-action: none;">
            该元素接收所有触控的指针事件。
        </div>
        <div>
            该元素上的触控可用于操作父元素。
        </div>
    </div>
示例 9: 禁止触控行为的中间父级
<div style="overflow: auto;">
        <div style="touch-action: pan-y;">
            <div style="touch-action: pan-x;">
                该元素接收所有触控的指针事件,因为它仅允许水平平移,而中间的祖先(在它和可平移元素之间)只允许垂直平移。因此,不允许任何触控行为。
            </div>
        </div>
    </div>

10. 指针捕获

10.1 介绍

本节为非规范性内容。

指针捕获允许特定指针的事件(包括任何兼容鼠标事件)重新定向到特定元素,而不是指针位置的正常命中测试结果。这在某些场景中非常有用,比如自定义滑块控件(例如类似于[HTML5]中的<input type="range">控件)。可以在滑块拇指元素上设置指针捕获,这样即使指针从拇指上滑出,用户仍然可以来回滑动控件。

自定义音量滑块
4 自定义滑块控件的示例,通过来回滑动拇指元素来选择值。在拇指元素上触发pointerdown后,可以使用指针捕获允许用户在指针滑出拇指后继续滑动。

10.2 设置指针捕获

通过调用element.setPointerCapture(pointerId)方法在元素上设置指针捕获。当调用此方法时,用户代理必须运行以下步骤:

  1. 如果作为方法参数提供的pointerId与任何活动指针不匹配,则抛出DOMException,其名称为NotFoundError
  2. 如果调用此方法的Element连接([DOM4]),则抛出名称为InvalidStateError的异常。
  3. 如果在文档有锁定元素时调用此方法([PointerLock]),则抛出名称为InvalidStateError的异常。
  4. 如果指针未处于活动按钮状态,则终止这些步骤。
  5. 对于指定的pointerId,将待处理的指针捕获目标覆盖设置为调用此方法的Element

10.3 释放指针捕获

通过调用element.releasePointerCapture(pointerId)方法在元素上显式释放指针捕获。当调用此方法时,用户代理必须运行以下步骤:

  1. 如果作为方法参数提供的pointerId与任何活动指针不匹配且这些步骤不是由于隐式释放指针捕获而被调用的,则抛出DOMException,其名称为NotFoundError
  2. 如果对于具有指定pointerIdElementhasPointerCapture为false,则终止这些步骤。
  3. 对于指定的pointerId,清除待处理的指针捕获目标覆盖,如果已设置。

10.4 隐式指针捕获

某些输入设备(如触摸屏)实现了“直接操作”的隐喻,其中指针主要作用于其激活的UI元素(提供直接接触的物理错觉,而不是通过概念上漂浮在UI上方的光标进行间接接触)。这些设备由InputDeviceCapabilities.pointerMovementScrolls 属性标识,并应具有如下“隐式指针捕获”行为。

直接操作设备应当像在目标元素上调用了setPointerCapture一样行为,发生在任何pointerdown监听器调用之前。可以使用hasPointerCapture API(例如,在任何pointerdown监听器内)确定是否已发生此操作。如果在下一个指针事件触发前未调用releasePointerCapture,则将向目标派发一个gotpointercapture事件(正常情况下),表明捕获已激活。

注意
这与[PointerEvents1]有重大变化,但不会影响绝大多数现有内容。除了匹配典型的平台用户体验惯例外,这种隐式捕获设计还使用户代理能够进行性能优化,从而避免在没有开发人员显式选择的情况下,在触摸移动事件上调用命中测试(与现有的主要本地和Web API的触摸输入性能属性一致)。
注意
此外,用户代理可以为特定的UI小部件(如输入范围控件)对所有输入设备实现隐式指针捕获行为(允许在交互期间,手指移动部分偏离表单控件本身)。

10.5 隐式释放指针捕获

在触发pointeruppointercancel事件后,用户代理必须清除该pointeruppointercancel事件刚刚调度的pointerId待处理的指针捕获目标覆盖, 并运行处理待处理的指针捕获步骤,如有必要,触发lostpointercapture事件。 在运行处理待处理的指针捕获步骤后, 如果指针支持悬停,用户代理必须发送对应的边界事件以反映没有捕获情况下指针的当前位置。

如果用户代理支持触发click事件 (请参阅兼容鼠标事件), 并且在隐式释放情况下同时触发clicklostpointercapture事件, click事件lostpointercapture事件之前触发。

指针捕获目标覆盖不再连接时([DOM4]), 待处理的指针捕获目标覆盖指针捕获目标覆盖节点被清除, 并且应在文档上触发对应捕获指针的lostpointercapture事件。

当在元素上成功应用指针锁定([PointerLock]),用户代理必须运行步骤,仿佛已经调用了releasePointerCapture()方法,如果有任何元素被设置为捕获或待捕获。

11. 与鼠标事件的兼容性映射

目前绝大多数的网页内容仅支持鼠标事件。以下描述了用户代理如何将通用指针输入映射到鼠标事件以实现与这些内容的兼容性的算法。

与鼠标事件的兼容性映射是本规范的可选功能。鼓励用户代理支持该功能,以便与现有的遗留内容实现最佳兼容性。不支持兼容性鼠标事件的用户代理仍然鼓励支持clickcontextmenu事件(请参阅下面的说明)。

注意

[UIEVENTS]中定义的click事件和[HTML5]中定义的contextmenu事件,不被视为兼容性鼠标事件,因为它们通常与用户界面激活相关,并且可以由其他输入设备触发,如键盘。

在支持触发click和/或contextmenu的用户代理中,通常在指针事件期间调用preventDefault不会影响click和/或contextmenu是否会被触发。由于它们不是兼容性鼠标事件,用户代理通常会为所有指针设备触发clickcontextmenu,包括不是主要指针的指针。

这些高级事件(clickcontextmenufocusblur等)与指针事件的相对顺序未定义,并且在不同的用户代理之间有所不同。例如,在某些用户代理中,contextmenu通常在pointerup之后触发,而在其他用户代理中,它通常在pointeruppointercancel之前触发,有时甚至在没有任何对应的指针事件(如键盘快捷键)的情况下触发。

除非另有说明,任何映射的鼠标事件的目标与相应的指针事件的目标相同,除非该目标不再参与其ownerDocument的树。在这种情况下,鼠标事件应在原始目标最近的仍参与其ownerDocument的树的祖先节点上触发,这意味着为鼠标事件构建了一个新的事件路径(基于新的目标节点)。

作者可以通过取消pointerdown事件来防止产生某些兼容性鼠标事件。

注意
鼠标事件只能在指针按下时被阻止。悬停的指针(例如,未按下任何按钮的鼠标)无法阻止其鼠标事件。此外,mouseovermouseoutmouseentermouseleave事件永远不会被阻止(即使指针按下)。

11.1 跟踪传统鼠标指针的有效位置

虽然只有 主指针 能够生成兼容的鼠标事件,但 多个主指针 可以同时激活,每个指针产生自己的兼容鼠标事件。由于所有这些兼容事件对于 MouseEvent 代码来说似乎来自单一的鼠标设备,用户代理被鼓励保证从单一设备的角度来看,兼容鼠标事件是一致的。对于鼠标过渡事件(即 mouseovermouseoutmouseentermouseleave),这意味着每个事件目标的进入/退出状态是有效的,如 [UIEVENTS] 所暗示的。用户代理 应当 通过在文档中维护 传统鼠标指针的有效位置 来保证这一点,如下所述。

在触发 pointerdownpointeruppointermove 事件,或在 window 上触发 pointerleave 事件之前,用户代理 应当 执行以下步骤:

  1. T 为正在分发的 pointerdownpointeruppointermove 事件的目标。对于 pointerleave 事件,取消设置 T
  2. 如果 T 和当前 有效的传统鼠标指针位置 都未设置或相等,则终止这些步骤。
  3. 根据 [UIEVENTS] 为鼠标从当前 有效的传统鼠标指针位置 移动到 T 触发 mouseovermouseoutmouseentermouseleave 事件。将当前 有效的传统鼠标指针位置T 的未设置值视为窗口外的鼠标位置。
  4. 有效的传统鼠标指针位置 设置为 T

11.2 支持悬停的设备的映射

每当用户代理为支持悬停的设备调度指针事件时,它运行以下步骤:

  1. 如果要调度的指针事件的isPrimary属性为false,则调度指针事件并终止这些步骤。
  2. 如果要调度的指针事件是pointerdownpointeruppointermove事件,或在window上调度的pointerleave事件,则按照追踪传统鼠标指针的有效位置中描述的方式调度兼容性鼠标过渡事件。
  3. 调度指针事件。
  4. 如果调度的指针事件是pointerdown并且事件被取消,则为此pointerType设置PREVENT MOUSE EVENT标志。
  5. 如果未为此pointerType设置PREVENT MOUSE EVENT标志,并且调度的指针事件是:
    • pointerdown,则触发mousedown事件。
    • pointermove,则触发mousemove事件。
    • pointerup,则触发mouseup事件。
    • pointercancel,则在window上触发mouseup事件。
  6. 如果调度的指针事件是pointeruppointercancel,则清除此pointerTypePREVENT MOUSE EVENT标志。

11.3 不支持悬停的设备的映射

某些设备(如大多数触摸屏)不支持在非活动状态下悬停某个坐标(或一组坐标)。许多仅针对鼠标事件编写的现有内容假设鼠标正在产生这些事件,因此通常以下特性是真实的:

注意
悬停有时用于在为鼠标设计的内容中切换UI元素的可见性(例如,“悬停菜单”)。此内容通常与不支持悬停的设备不兼容。本规范未定义与这种情况兼容的映射或行为。这将在规范的未来版本中考虑。

这要求用户代理为这些类型的输入设备提供不同的映射。每当用户代理为不支持悬停的设备调度指针事件时,它运行以下步骤:

  1. 如果要调度的指针事件的isPrimary属性为false,则调度指针事件并终止这些步骤。
  2. 如果要调度的指针事件是pointerover并且尚未为此指针调度pointerdown事件,则触发mousemove事件(以与传统仅支持鼠标的代码兼容)。
  3. 如果要调度的指针事件是pointerdownpointeruppointermove事件,或在window上调度的pointerleave事件,则按照追踪传统鼠标指针的有效位置中描述的方式调度兼容性鼠标过渡事件。
  4. 调度指针事件。
  5. 如果调度的指针事件是pointerdown并且事件被取消,则为此pointerType设置PREVENT MOUSE EVENT标志。
  6. 如果未为此pointerType设置PREVENT MOUSE EVENT标志,并且调度的指针事件是:
    • pointerdown,则触发mousedown事件。
    • pointermove,则触发mousemove事件。
    • pointerup,则触发mouseup事件。
    • pointercancel,则在window上触发mouseup事件。
  7. 如果调度的指针事件是pointeruppointercancel,则清除此pointerTypePREVENT MOUSE EVENT标志。
注意

如果用户代理同时支持触摸事件(如[TOUCH-EVENTS]中定义的)和指针事件,用户代理不应按照本节中描述的方式生成兼容性鼠标事件,因为这可能会为期望按照[TOUCH-EVENTS]中概述的模型生成鼠标事件的站点引入兼容性问题。

注意

使用不支持悬停的主要指针(例如,单指在触摸屏上)激活元素(click)通常会产生以下事件顺序:

  1. mousemove
  2. pointerover
  3. pointerenter
  4. mouseover
  5. mouseenter
  6. pointerdown
  7. mousedown
  8. 根据指针的移动情况,零个或多个pointermovemousemove事件
  9. pointerup
  10. mouseup
  11. click
  12. pointerout
  13. pointerleave
  14. mouseout
  15. mouseleave

然而,如果在此交互期间pointerdown事件被取消,那么事件顺序将是:

  1. mousemove
  2. pointerover
  3. pointerenter
  4. mouseover
  5. mouseenter
  6. pointerdown
  7. 根据指针的移动情况,零个或多个pointermove事件
  8. pointerup
  9. click
  10. pointerout
  11. pointerleave
  12. mouseout
  13. mouseleave

12. 安全和隐私注意事项

本附录讨论了指针事件实现的安全和隐私注意事项。讨论仅限于直接因实现本规范中定义的事件模型、API 和事件而产生的安全和隐私问题。

本规范中定义的许多事件类型是响应用户操作而调度的。这使得恶意事件监听器能够访问用户通常认为是机密的信息,例如用户与页面交互时鼠标/手写笔/手指的精确路径/移动。

指针事件包含了用户设备支持的额外信息,例如手写笔输入的角度或倾斜度、接触面的几何形状以及施加在手写笔或触摸屏上的压力。关于角度、倾斜度、几何形状和压力的信息直接与用户设备上的传感器相关,这意味着本规范允许一个源访问这些传感器。

这些传感器数据,以及确定所使用的输入机制(鼠标、触摸、手写笔)类型的能力,可能会被用来推断用户或用户设备和环境的特征。这些推断出的特征和任何设备/环境信息本身可能是敏感的——例如,它们可能允许恶意站点进一步推断用户是否在使用辅助技术。这些信息也可能被用于建立用户档案和/或尝试“指纹识别”并跟踪特定用户。

作为缓解措施,用户代理可能会考虑包括用户禁用特定传感器数据(如角度、倾斜度、压力)访问的能力,和/或仅在用户明确选择加入后才使其可用。

除了这些考虑之外,工作组认为本规范:

A. 致谢

非常感谢许多人的提议和建议,其中一些已被纳入本文档。小组主席感谢以下现任和前任小组成员和参与者的贡献: Mustaq Ahmed, Arthur Barstow, Matt Brubeck, Rick Byers, Cathy Chan, Ted Dinklocker, Dave Fleck, Ella Ge, Scott González, Philippe Le Hégaret, Hayato Ito, Patrick Kettner, Patrick H. Lauke, Scott Low, Sangwhan Moon, Olli Pettay, Jacob Rossi, Doug Schepers, Ming-Chou Shih, Brenton Simpson, Dave Tapuska, Asir Vedamuthu, Lan Wei, Navid Zolghadr

特别感谢那些帮助开创此模型第一版的人,特别是:Charu Chandiram, Peter Freiling, Nathan Furtwangler, Thomas Olsen, Matt Rakow, Ramu Ramanathan, Justin Rogers, Jacob Rossi, Reed Townsend 和 Steve Wright。

B. 修订历史

本节为非规范性内容。

以下是相对于第一个 [PointerEvents1] 规范的版本之间的重大和主要编辑更改的说明性摘要。请参阅本规范编辑草案的完整修订历史

C. 参考文献

C.1 规范性引用

[CSS21]
层叠样式表等级 2 修订版 (CSS 2.1) 规范. Bert Bos; Tantek Çelik; Ian Hickson; Håkon Wium Lie 等人. W3C. 2011 年 6 月 7 日. W3C 推荐. URL: https://www.w3.org/TR/CSS2/
[DOM4]
DOM 标准. Anne van Kesteren. WHATWG. 现行标准. URL: https://dom.spec.whatwg.org/
[HTML]
HTML 标准. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 现行标准. URL: https://html.spec.whatwg.org/multipage/
[HTML5]
HTML5. Steve Faulkner; Arron Eicholz; Travis Leithead; Alex Danilo; Sangwhan Moon. W3C. 2017 年 12 月 14 日. W3C 推荐. URL: https://www.w3.org/TR/html5/
[PointerLock]
指针锁定. Vincent Scheib. W3C. 2016 年 10 月 27 日. W3C 推荐. URL: https://www.w3.org/TR/pointerlock/
[RFC2119]
在 RFC 中使用的关键字以指示要求级别. S. Bradner. IETF. 1997 年 3 月. 最佳当前实践. URL: https://tools.ietf.org/html/rfc2119
[UIEVENTS]
UI 事件. Gary Kacmarcik; Travis Leithead; Doug Schepers. W3C. 2018 年 11 月 8 日. W3C 工作草案. URL: https://www.w3.org/TR/uievents/
[WEBIDL]
Web IDL. Cameron McCormack; Boris Zbarsky; Tobie Langel. W3C. 2016 年 12 月 15 日. W3C 编辑草案. URL: https://heycam.github.io/webidl/

C.2 说明性引用

[COMPAT]
兼容性标准. Mike Taylor. WHATWG. 现行标准. URL: https://compat.spec.whatwg.org/
[CSSOM-VIEW]
CSSOM 视图模块. Simon Pieters. W3C. 2016 年 3 月 17 日. W3C 工作草案. URL: https://www.w3.org/TR/cssom-view-1/
[PointerEvents1]
指针事件. Jacob Rossi; Matt Brubeck. W3C. 2015 年 2 月 24 日. W3C 推荐. URL: https://www.w3.org/TR/pointerevents1/
[TOUCH-EVENTS]
触摸事件. Doug Schepers; Sangwhan Moon; Matt Brubeck; Arthur Barstow. W3C. 2013 年 10 月 10 日. W3C 推荐. URL: https://www.w3.org/TR/touch-events/