请检查勘误表,查看自发布以来报告的任何错误或问题。
Copyright © 2019 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.
本规范中的功能扩展或修改了指针事件中的那些功能,这是一项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流程文档的约束。
本节为非规范性内容。
如今,大多数[HTML5]内容是使用和/或设计用于鼠标输入的。那些以自定义方式处理输入的内容通常使用到[UIEVENTS]鼠标事件。然而,今天的新计算设备整合了其他形式的输入,包括触摸屏、触控笔等。已经提出了用于分别处理这些输入形式的事件类型。然而,这种方法在为新输入类型添加支持时,往往会导致不必要的逻辑重复和事件处理开销。当内容仅针对一种设备类型编写时,这通常会产生兼容性问题。此外,为了与现有基于鼠标的内容兼容,大多数用户代理为所有输入类型触发鼠标事件。这使得鼠标事件是否代表实际的鼠标设备,还是为了兼容性而从其他输入类型生成,变得模糊不清,这使得同时针对两种设备类型进行编码变得困难。
为了降低针对多种输入类型编码的成本,并帮助解决上述鼠标事件的模糊问题,本规范定义了一种更抽象的输入形式,称为指针。指针可以是屏幕上由鼠标光标、笔、触摸(包括多点触控)或其他指点输入设备产生的任何接触点。这个模型使得编写适用于任何硬件的站点和应用程序变得更容易。在需要特定设备处理的场景下,本规范还定义了用于检查产生事件的设备类型的属性。主要目标是提供一组统一的事件和接口,便于跨设备指针输入的编写,同时仅在需要增强体验时允许特定设备的处理。
另一个关键目标是使多线程用户代理能够处理默认的触摸操作,如滚动,而不会因脚本执行而阻塞。
虽然本规范定义了用于各种指针输入的统一事件模型,但该模型不涵盖其他形式的输入,如键盘或类键盘接口(例如,运行在仅有触摸屏设备上的屏幕阅读器或类似辅助技术,使用户能够依次导航焦点控件和元素)。尽管用户代理可能选择响应这些接口生成指针事件,但这种情况不在本规范的范围内。
首先,鼓励作者通过响应诸如focus
、blur
和click
等高级事件为所有形式的输入提供等效的功能。然而,在使用低级事件(如指针事件)时,鼓励作者确保支持所有类型的输入。在键盘和类键盘接口的情况下,这可能需要添加显式的键盘事件处理。有关详细信息,请参见WCAG 2.0 指南 2.1。
处理通用指针输入的事件看起来很像鼠标事件:pointerdown、pointermove、pointerup、pointerover、pointerout等。这有助于将内容从鼠标事件迁移到指针事件。 指针事件提供了鼠标事件中存在的所有常用属性(客户端坐标、目标元素、按钮状态等),并新增了用于其他形式输入的属性:压力、接触几何、倾斜等。因此,作者可以轻松地编写指针事件,以在不同输入类型之间共享逻辑,并在必要时针对特定输入类型进行定制,以获得最佳体验。
尽管指针事件源自多种输入设备,但它们并不是从其他设备特定的事件集中生成的。虽然为了兼容性鼓励这样做,但本规范不要求支持其他设备特定的事件(例如鼠标事件、触摸事件等)。用户代理可以支持指针事件而不支持任何其他设备事件。为了与仅针对鼠标特定事件编写的内容兼容,本规范确实提供了一个可选部分,描述了如何基于来自非鼠标设备的指针输入生成兼容鼠标事件。
本规范未对同时支持触摸事件(如[TOUCH-EVENTS]中定义的)和指针事件的用户代理的预期行为提供任何建议。有关这两个规范之间关系的更多信息,请参阅触摸事件社区组。
除了标记为非规范性的部分外,本规范中的所有编写指南、图表、示例和注释都是非规范性的。 本规范中的其他内容都是规范性的。
关键字MAY(可以)、MUST(必须)、MUST NOT(不得)、OPTIONAL(可选)、SHOULD(应该)和 SHOULD NOT(不应该)应按照[RFC2119]中的描述进行解释。
本节为非规范性内容。
以下是一些示例代码,展示了如何使用本规范中的API。
/* 绑定到指针事件或传统的触摸/鼠标事件 */
if (window.PointerEvent) {
// 如果支持指针事件,只监听指针事件
target.addEventListener("pointerdown", function(e) {
// 如果需要,为不同的触摸/笔/鼠标行为应用单独的逻辑
...
});
...
} else {
// 传统的触摸/鼠标事件处理程序
target.addEventListener('touchstart', function(e) {
// 防止兼容性鼠标事件和点击
e.preventDefault();
...
});
...
target.addEventListener('mousedown', ...);
...
}
// 键盘处理的其他事件监听器
...
window.addEventListener("pointerdown", detectInputType);
function detectInputType(event) {
switch(event.pointerType) {
case "mouse":
/* 检测到鼠标输入 */
break;
case "pen":
/* 检测到笔/触控笔输入 */
break;
case "touch":
/* 检测到触摸输入 */
break;
default:
/* pointerType为空(无法检测到)或UA特定的自定义类型 */
}
}
<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>
<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>
var event = new PointerEvent("pointerover",
{ bubbles: true,
cancelable: true,
composed: true,
pointerId: 42,
pointerType: "pen",
clientX: 300,
clientY: 500
});
eventTarget.dispatchEvent(event);
本节为非规范性内容。
buttons
属性值非零时的情况。对于鼠标,这是设备至少有一个按钮被按下时。对于触摸,这是与数字化仪有物理接触时。对于笔,这是当笔与数字化仪有物理接触时,或悬停时按下了至少一个按钮的情况。
pointerId
标识)可能在文档中产生额外的事件,那么该指针仍然被视为活动状态。示例:
preventDefault()
阻止,通过在事件处理程序中返回false
或其他方式(如[UIEVENTS]和[HTML5]中定义)取消的事件。
PointerEvent
接口dictionaryPointerEventInit
: MouseEventInit { long pointerId = 0; double width = 1; double height = 1; float pressure = 0; float tangentialPressure = 0; long tiltX = 0; long tiltY = 0; long twist = 0; DOMString pointerType = ""; boolean isPrimary = false; }; [Constructor(DOMString type, optionalPointerEventInit
eventInitDict), Exposed=Window] interfacePointerEvent
: MouseEvent { readonly attribute longpointerId
; readonly attribute doublewidth
; readonly attribute doubleheight
; readonly attribute floatpressure
; readonly attribute floattangentialPressure
; readonly attribute longtiltX
; readonly attribute longtiltY
; readonly attribute longtwist
; readonly attribute DOMStringpointerType
; readonly attribute booleanisPrimary
; };
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。
tiltY
在X-Z平面和包含传感器(例如笔触)轴与X轴的平面之间的平面角度(以度为单位,范围为[-90,90])。正的tiltY
表示向用户方向倾斜。tiltY
可以与tiltX
一起使用,以表示传感器与数字化仪法线之间的倾斜。对于不报告倾斜的硬件和平台,该值必须为0。
twist
传感器(例如笔触)的顺时针旋转(以度为单位,范围为[0,359])。对于不报告旋转的硬件和平台,该值必须为0。
pointerType
指示引发事件的设备类型(鼠标、笔、触摸等)。如果用户代理要触发指针事件,则pointerType
的值必须按照以下表格:
指针设备类型 | pointerType 值 |
---|---|
鼠标 | mouse |
笔触 | pen |
触摸接触 | touch |
如果用户代理无法检测设备类型,则该值必须为空字符串。如果用户代理支持上面未列出的指针设备类型,则pointerType
的值应当使用供应商前缀,以避免为不同类型的设备使用冲突的名称。未来的规范可以为其他设备类型提供其他规范值。
pointerType
的基本用法。此外,开发人员应包括某种形式的默认处理,以覆盖可能已经实现其自定义pointerType
值的用户代理,并处理pointerType
为空字符串的情况。
isPrimary
指示该指针是否表示此指针类型的主要指针。
PointerEventInit
字典用于PointerEvent
接口的构造函数,以提供构造不可信(合成)指针事件的机制。它继承自[UIEVENTS]中定义的MouseEventInit
字典。构造事件的步骤在[DOM4]中定义。参见示例,以获取触发不可信指针事件的示例代码。
在多指针(例如多点触控)场景中,isPrimary
属性用于在每种指针类型的 活动指针 集合中识别主指针。
pointerType
一个)被视为主指针。例如,触控接触和鼠标光标同时移动将产生两个都被视为主指针的指针。isPrimary
的值为 false
。PointerEvent
接口触发事件“触发名为e的指针事件”是指按照[DOM4]的定义触发名为e的事件,该事件使用PointerEvent
接口,其属性设置如PointerEvent
接口和属性和默认行为中定义。
如果事件不是gotpointercapture
或lostpointercapture
,则运行处理待处理的指针捕获步骤。
触发事件的目标对象按以下方式确定:
如果这是pointerdown
事件,关联设备为直接操作设备且目标为Element
,则为此pointerId
设置指针捕获至目标元素,如隐式指针捕获中所述。
向确定的目标触发事件。
在本规范中定义的事件类型的bubbles
和cancelable
属性以及默认行为如下表所示。每种事件类型的详细信息在指针事件类型中提供。
事件类型 | 可冒泡 | 可取消 | 默认行为 |
---|---|---|---|
pointerover |
是 | 是 | 无 |
pointerenter |
否 | 否 | 无 |
pointerdown |
是 | 是 | 不同:当指针为主要指针时,所有mousedown 事件的默认行为
取消此事件还会为此 pointerType 设置PREVENT MOUSE EVENT 标志,从而阻止随后触发某些兼容鼠标事件。
|
pointermove |
是 | 是 | 不同:当指针为主要指针时,所有mousemove 的默认行为
|
pointerup |
是 | 是 | 不同:当指针为主要指针时,所有mouseup 的默认行为
|
pointercancel |
是 | 否 | 无 |
pointerout |
是 | 是 | 无 |
pointerleave |
否 | 否 | 无 |
gotpointercapture |
是 | 否 | 无 |
lostpointercapture |
是 | 否 | 无 |
对于上表中的所有指针事件,pointerenter
和pointerleave
除外,composed
([DOM4]) 属性应当为true
。
对于上表中的所有指针事件,detail
[UIEVENTS]属性应当为0。
fromElement
和toElement
以支持遗留内容。在这些用户代理中,PointerEvents中这些(继承的)属性的值必须为null
,以鼓励使用标准化的替代方案(即target
和relatedTarget
)。
类似于MouseEvents
[UIEVENTS],relatedTarget
应初始化为指针刚刚离开的元素(在pointerover
或pointerenter
事件的情况下)或指针即将进入的元素(在pointerout
或pointerleave
事件的情况下)。对于其他指针事件,此值将默认为null。请注意,当元素接收到指针捕获时,该指针的所有后续事件都将被视为在捕获元素的边界内。
对于gotpointercapture
和lostpointercapture
,除了上表中定义的属性外,其他所有属性应与导致用户代理运行处理待处理的指针捕获并触发gotpointercapture
和lostpointercapture
事件的指针事件相同。
在隐式释放指针捕获以及触发非gotpointercapture
或lostpointercapture
的指针事件时,用户代理必须运行以下步骤。
lostpointercapture
的指针事件。
gotpointercapture
的指针事件。
以下是本规范中定义的事件类型。
在主要指针的情况下,这些事件(gotpointercapture
和
lostpointercapture
除外)也可能触发兼容鼠标事件。
pointerover
事件当指针设备移入元素的命中测试边界时,用户代理必须触发一个名为pointerover
的指针事件。请注意,setPointerCapture
或releasePointerCapture
可能已更改命中测试目标,而当指针被捕获时,为触发边界事件的目的,指针始终被视为在捕获元素的边界内。对于不支持悬停的设备,在触发pointerdown
事件之前,用户代理必须触发此事件(请参见pointerdown
)。
pointerenter
事件当指针设备移入元素或其后代的命中测试边界时,用户代理必须触发一个名为pointerenter
的指针事件,包括由于来自不支持悬停的设备的pointerdown
事件(请参见pointerdown
)。请注意,setPointerCapture
或releasePointerCapture
可能已更改命中测试目标,而当指针被捕获时,为触发边界事件的目的,指针始终被视为在捕获元素的边界内。此事件类型类似于pointerover
,但不同之处在于它不会冒泡。
pointerdown
事件当指针进入激活按钮状态时,用户代理必须触发一个名为pointerdown
的指针事件。对于鼠标,这是设备从没有按钮按下过渡到至少有一个按钮按下时的情况。对于触摸,这是与数字化仪进行物理接触的情况。对于笔,当笔与数字化仪进行物理接触而没有任何按钮按下时,或从没有按钮按下过渡到悬停时至少有一个按钮按下的情况。
对于不支持悬停的输入设备,用户代理必须在分派pointerdown
事件之前,触发名为pointerover
的指针事件,然后触发名为pointerenter
的指针事件。
pointerdown
事件(如果isPrimary
属性为true
),防止触发某些兼容鼠标事件。这会在指针上设置PREVENT MOUSE EVENT
标志。然而,请注意,这不会阻止mouseover
、mouseenter
、mouseout
或mouseleave
事件的触发。
pointermove
事件当指针改变坐标时,用户代理必须触发一个名为pointermove
的指针事件。此外,当指针改变按钮状态、压力、切向压力、倾斜、旋转或接触几何(例如width
和height
)且情况下不会产生本规范中定义的其他指针事件时,用户代理必须触发一个名为pointermove
的指针事件。
pointerup
事件当指针离开激活按钮状态时,用户代理必须触发一个名为pointerup
的指针事件。对于鼠标,这是设备从至少一个按钮按下过渡到没有按钮按下的情况。对于触摸,这是物理接触从数字化仪中移除的情况。对于笔,这是当笔从与数字化仪的物理接触中移除而没有任何按钮按下时,或从悬停时至少有一个按钮按下的情况过渡到没有按钮按下的情况。
对于不支持悬停的输入设备,用户代理必须在分派pointerup
事件后,触发名为pointerout
的指针事件,然后触发名为pointerleave
的指针事件。
pointercancel
事件用户代理必须在以下情况下触发一个名为pointercancel
的指针事件:
pointerdown
事件后,如果指针随后用于操作页面视口(例如平移或缩放)。
dragstart
事件上的preventDefault
)阻止拖动操作的开始,则不会触发pointercancel
事件。
在触发pointercancel
事件后,用户代理必须还触发一个名为pointerout
的指针事件,然后触发一个名为pointerleave
的指针事件。
本节为非规范性内容。
用户代理可能确定指针不太可能继续产生事件的场景示例包括:
更改设备屏幕方向、识别意外输入或使用指针操作视口(例如平移或缩放)的方法不在本规范的范围内。
pointerout
事件当发生以下任何一种情况时,用户代理必须触发一个名为pointerout
的指针事件:
setPointerCapture
或releasePointerCapture
可能已更改命中测试目标,而当指针被捕获时,为触发边界事件的目的,指针始终被视为在捕获元素的边界内。
pointerup
事件后(请参见pointerup
)。
pointercancel
事件后(请参见pointercancel
)。
pointerleave
事件当指针设备移出了元素及其所有后代的命中测试边界时,用户代理必须触发一个名为pointerleave
的指针事件,包括由于来自不支持悬停的设备的pointerup
和pointercancel
事件(请参见pointerup
和pointercancel
)。请注意,setPointerCapture
或releasePointerCapture
可能已更改命中测试目标,而当指针被捕获时,为触发边界事件的目的,指针始终被视为在捕获元素的边界内。用户代理必须还应在笔离开数字化仪可检测的悬停范围时触发一个指针事件,名为pointerleave
。此事件类型类似于pointerout
,但不同之处在于它不会冒泡,并且在指针设备离开元素边界及其所有后代的边界之前,必须不触发此事件。
gotpointercapture
事件当元素接收到指针捕获时,用户代理必须触发一个名为gotpointercapture
的指针事件。此事件在接收到指针捕获的元素上触发。此后,该指针的后续事件将在该元素上触发。请参见设置指针捕获和处理待处理的指针捕获部分。
lostpointercapture
事件在释放指针的指针捕获后,用户代理必须触发一个名为lostpointercapture
的指针事件。此事件必须在释放捕获后触发指针的任何后续事件之前触发。此事件在从中移除指针捕获的元素上触发。指针的后续事件遵循确定事件目标的正常命中测试机制(不在本规范范围内)。请参见释放指针捕获、隐式释放指针捕获和处理待处理的指针捕获部分。
Element
接口的扩展以下部分描述了对[HTML5]中定义的现有Element
接口的扩展,以便于设置和释放指针捕获。
partial interface Element
{
void setPointerCapture
(long pointerId);
void releasePointerCapture
(long pointerId);
boolean hasPointerCapture
(long pointerId);
};
setPointerCapture
为由参数pointerId
标识的指针设置指针捕获,目标是调用此方法的元素。对于该指针的后续事件,捕获目标将替代正常的命中测试结果,就好像指针始终位于捕获目标上,并且它们必须始终定位于此元素,直到捕获被释放。指针必须处于激活按钮状态,此方法才能生效,否则会静默失败。当提供的方法的参数不匹配任何活动指针时,会抛出名称为NotFoundError
的DOMException
。
releasePointerCapture
释放从调用此方法的元素中由参数pointerId
标识的指针指针捕获。该指针的后续事件遵循正常的命中测试机制(不在本规范范围内)以确定事件目标。当提供的方法的参数不匹配任何活动指针时,会抛出名称为NotFoundError
的DOMException
。
hasPointerCapture
指示调用此方法的元素是否对由参数pointerId
标识的指针拥有指针捕获。具体而言,如果pointerId
的待处理指针捕获目标覆盖被设置为调用此方法的元素,则返回true
,否则返回false
。
setPointerCapture
后立即返回true。因此,它在pointerdown事件
侦听器内部检测隐式指针捕获时非常有用。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
gotpointercapture
事件类型的事件处理程序IDL属性。
onlostpointercapture
lostpointercapture
事件类型的事件处理程序IDL属性。
onpointerdown
pointerdown
事件类型的事件处理程序IDL属性。
onpointermove
pointermove
事件类型的事件处理程序IDL属性。
onpointerup
pointerup
事件类型的事件处理程序IDL属性。
onpointercancel
pointercancel
事件类型的事件处理程序IDL属性。
onpointerover
pointerover
事件类型的事件处理程序IDL属性。
onpointerout
pointerout
事件类型的事件处理程序IDL属性。
onpointerenter
pointerenter
事件类型的事件处理程序IDL属性。
onpointerleave
pointerleave
事件类型的事件处理程序IDL属性。
对于触控输入,任何指针事件的默认操作不得是视口的操作(例如平移或缩放)。
touch-action
CSS属性名称: | touch-action |
---|---|
值: | auto | none | [ pan-x || pan-y ] |
manipulation
|
初始值: | auto |
应用于: | 除非替换行内元素、表行、行组、表列和列组外的所有元素。 |
继承: | 否 |
百分比: | 不适用 |
媒体: | 视觉 |
计算值: | 与指定值相同。 |
touch-action
CSS属性决定触控输入可能触发由用户代理提供的默认行为。这包括但不限于平移或缩放等行为。请参阅touch-action
值一节。
touch-action
值。
在执行用户代理触控行为期间,用户代理不得为指针触发后续指针事件。用户代理必须触发名为pointercancel的指针事件(随后触发pointerout
事件和一个或多个pointerleave
事件),以便在以下所有条件都成立时结束该指针的事件流:
pointerdown
事件,并且pointerup
或pointercancel
事件(在上述pointerdown
之后)。
当用户触摸一个元素时,该触摸的效果由touch-action
属性的值以及该元素及其祖先的默认触控行为确定,如下所示:
touch-action
。请注意,如果应用了CSS变换,元素的坐标空间可能与屏幕坐标不同,从而影响此处的符合性;例如,X轴旋转90度的元素相对于屏幕将平行于屏幕坐标的Y轴。
touch-action
属性(包括命中测试元素和具有默认触控行为的元素),则支持触控行为。
touch-action
值的更改都将在触控行为持续期间被忽略。例如,作为pointerdown
处理程序脚本的一部分,将元素的touch-action
值从auto
程序更改为none
不会导致用户代理在该指针处于活动状态时中止或抑制该触控的任何默认触控行为。
touch-action
值不在本规范范围之内。
touch-action
值的详细信息
用户代理可以仅将触控视为滚动开始的目的,这些滚动必须在所有列出的值指定的方向中之一开始。一旦滚动开始,用户可以反转方向,即使在反转方向开始的滚动被禁止时也是如此。相比之下,当滚动限制为仅沿单个轴开始时(例如pan-y
),在滚动过程中无法更改轴。
auto
支持的任何其他行为不在本规范范围之内。
auto
或none
值的行为不在本规范范围之内。
auto
时,用户代理通常会在点击
之前添加300ms的延迟,以允许处理双击手势。在这些情况下,显式设置touch-action: none
或touch-action: manipulation
将删除此延迟。请注意,确定点击或双击手势的方法不在本规范范围之内。
<div style="touch-action: none;">
该元素接收所有触控的指针事件。
</div>
<div style="touch-action: pan-x;">
当不在水平方向平移时,该元素接收指针事件。
</div>
<div style="overflow: auto;">
<div style="touch-action: none;">
该元素接收所有触控的指针事件。
</div>
<div>
该元素上的触控可用于操作父元素。
</div>
</div>
<div style="overflow: auto;">
<div style="touch-action: pan-y;">
<div style="touch-action: pan-x;">
该元素接收所有触控的指针事件,因为它仅允许水平平移,而中间的祖先(在它和可平移元素之间)只允许垂直平移。因此,不允许任何触控行为。
</div>
</div>
</div>
本节为非规范性内容。
指针捕获允许特定指针的事件(包括任何兼容鼠标事件)重新定向到特定元素,而不是指针位置的正常命中测试结果。这在某些场景中非常有用,比如自定义滑块控件(例如类似于[HTML5]中的<input type="range">
控件)。可以在滑块拇指元素上设置指针捕获,这样即使指针从拇指上滑出,用户仍然可以来回滑动控件。
通过调用element.setPointerCapture(pointerId)
方法在元素上设置指针捕获。当调用此方法时,用户代理必须运行以下步骤:
pointerId
与任何活动指针不匹配,则抛出DOMException
,其名称为NotFoundError
。
Element
未连接
([DOM4]),则抛出名称为InvalidStateError
的异常。
InvalidStateError
的异常。
pointerId
,将待处理的指针捕获目标覆盖设置为调用此方法的Element
。
通过调用element.releasePointerCapture(pointerId)
方法在元素上显式释放指针捕获。当调用此方法时,用户代理必须运行以下步骤:
pointerId
与任何活动指针不匹配且这些步骤不是由于隐式释放指针捕获而被调用的,则抛出DOMException
,其名称为NotFoundError
。
pointerId
的Element
,hasPointerCapture为false,则终止这些步骤。
pointerId
,清除待处理的指针捕获目标覆盖,如果已设置。某些输入设备(如触摸屏)实现了“直接操作”的隐喻,其中指针主要作用于其激活的UI元素(提供直接接触的物理错觉,而不是通过概念上漂浮在UI上方的光标进行间接接触)。这些设备由InputDeviceCapabilities.pointerMovementScrolls 属性标识,并应具有如下“隐式指针捕获”行为。
直接操作设备应当像在目标元素上调用了setPointerCapture
一样行为,发生在任何pointerdown
监听器调用之前。可以使用hasPointerCapture
API(例如,在任何pointerdown
监听器内)确定是否已发生此操作。如果在下一个指针事件触发前未调用releasePointerCapture
,则将向目标派发一个gotpointercapture事件(正常情况下),表明捕获已激活。
在触发pointerup
或pointercancel
事件后,用户代理必须清除该pointerup
或pointercancel
事件刚刚调度的pointerId
的待处理的指针捕获目标覆盖,
并运行处理待处理的指针捕获步骤,如有必要,触发lostpointercapture
事件。
在运行处理待处理的指针捕获步骤后,
如果指针支持悬停,用户代理必须发送对应的边界事件以反映没有捕获情况下指针的当前位置。
如果用户代理支持触发click
事件
(请参阅兼容鼠标事件),
并且在隐式释放情况下同时触发click
和lostpointercapture
事件,
click
事件应在lostpointercapture
事件之前触发。
当指针捕获目标覆盖不再连接
时([DOM4]),
待处理的指针捕获目标覆盖和指针捕获目标覆盖节点应被清除,
并且应在文档上触发对应捕获指针的lostpointercapture
事件。
当在元素上成功应用指针锁定([PointerLock]),用户代理必须运行步骤,仿佛已经调用了releasePointerCapture()方法,如果有任何元素被设置为捕获或待捕获。
目前绝大多数的网页内容仅支持鼠标事件。以下描述了用户代理如何将通用指针输入映射到鼠标事件以实现与这些内容的兼容性的算法。
与鼠标事件的兼容性映射是本规范的可选功能。鼓励用户代理支持该功能,以便与现有的遗留内容实现最佳兼容性。不支持兼容性鼠标事件的用户代理仍然鼓励支持click
和contextmenu
事件(请参阅下面的说明)。
[UIEVENTS]中定义的click
事件和[HTML5]中定义的contextmenu
事件,不被视为兼容性鼠标事件,因为它们通常与用户界面激活相关,并且可以由其他输入设备触发,如键盘。
在支持触发click
和/或contextmenu
的用户代理中,通常在指针事件期间调用preventDefault
不会影响click
和/或contextmenu
是否会被触发。由于它们不是兼容性鼠标事件,用户代理通常会为所有指针设备触发click
和contextmenu
,包括不是主要指针的指针。
这些高级事件(click
、contextmenu
、focus
、blur
等)与指针事件的相对顺序未定义,并且在不同的用户代理之间有所不同。例如,在某些用户代理中,contextmenu
通常在pointerup
之后触发,而在其他用户代理中,它通常在pointerup
或pointercancel
之前触发,有时甚至在没有任何对应的指针事件(如键盘快捷键)的情况下触发。
除非另有说明,任何映射的鼠标事件的目标应与相应的指针事件的目标相同,除非该目标不再参与其ownerDocument
的树。在这种情况下,鼠标事件应在原始目标最近的仍参与其ownerDocument
的树的祖先节点上触发,这意味着为鼠标事件构建了一个新的事件路径(基于新的目标节点)。
作者可以通过取消pointerdown
事件来防止产生某些兼容性鼠标事件。
mouseover
、mouseout
、mouseenter
和mouseleave
事件永远不会被阻止(即使指针按下)。
虽然只有 主指针 能够生成兼容的鼠标事件,但 多个主指针
可以同时激活,每个指针产生自己的兼容鼠标事件。由于所有这些兼容事件对于 MouseEvent 代码来说似乎来自单一的鼠标设备,用户代理被鼓励保证从单一设备的角度来看,兼容鼠标事件是一致的。对于鼠标过渡事件(即
mouseover
、mouseout
、mouseenter
和
mouseleave
),这意味着每个事件目标的进入/退出状态是有效的,如 [UIEVENTS] 所暗示的。用户代理 应当
通过在文档中维护 传统鼠标指针的有效位置 来保证这一点,如下所述。
在触发 pointerdown
、pointerup
或 pointermove
事件,或在 window
上触发 pointerleave
事件之前,用户代理 应当 执行以下步骤:
T
为正在分发的 pointerdown
、pointerup
或 pointermove
事件的目标。对于 pointerleave
事件,取消设置 T
。T
和当前 有效的传统鼠标指针位置 都未设置或相等,则终止这些步骤。T
触发
mouseover
、mouseout
、mouseenter
和 mouseleave
事件。将当前 有效的传统鼠标指针位置 或 T
的未设置值视为窗口外的鼠标位置。
T
。每当用户代理为支持悬停的设备调度指针事件时,它应运行以下步骤:
isPrimary
属性为false
,则调度指针事件并终止这些步骤。pointerdown
、pointerup
或pointermove
事件,或在window
上调度的pointerleave
事件,则按照追踪传统鼠标指针的有效位置中描述的方式调度兼容性鼠标过渡事件。pointerdown
并且事件被取消,则为此pointerType
设置PREVENT MOUSE EVENT
标志。
pointerType
设置PREVENT MOUSE EVENT
标志,并且调度的指针事件是:
pointerdown
,则触发mousedown
事件。pointermove
,则触发mousemove
事件。pointerup
,则触发mouseup
事件。pointercancel
,则在window
上触发mouseup
事件。pointerup
或pointercancel
,则清除此pointerType
的PREVENT MOUSE EVENT
标志。
某些设备(如大多数触摸屏)不支持在非活动状态下悬停某个坐标(或一组坐标)。许多仅针对鼠标事件编写的现有内容假设鼠标正在产生这些事件,因此通常以下特性是真实的:
mousemove
事件。这要求用户代理为这些类型的输入设备提供不同的映射。每当用户代理为不支持悬停的设备调度指针事件时,它应运行以下步骤:
isPrimary
属性为false
,则调度指针事件并终止这些步骤。pointerover
并且尚未为此指针调度pointerdown
事件,则触发mousemove
事件(以与传统仅支持鼠标的代码兼容)。
pointerdown
、pointerup
或pointermove
事件,或在window
上调度的pointerleave
事件,则按照追踪传统鼠标指针的有效位置中描述的方式调度兼容性鼠标过渡事件。pointerdown
并且事件被取消,则为此pointerType
设置PREVENT MOUSE EVENT
标志。
pointerType
设置PREVENT MOUSE EVENT
标志,并且调度的指针事件是:
pointerdown
,则触发mousedown
事件。pointermove
,则触发mousemove
事件。pointerup
,则触发mouseup
事件。pointercancel
,则在window
上触发mouseup
事件。pointerup
或pointercancel
,则清除此pointerType
的PREVENT MOUSE EVENT
标志。
如果用户代理同时支持触摸事件(如[TOUCH-EVENTS]中定义的)和指针事件,用户代理不应按照本节中描述的方式生成兼容性鼠标事件,因为这可能会为期望按照[TOUCH-EVENTS]中概述的模型生成鼠标事件的站点引入兼容性问题。
使用不支持悬停的主要指针(例如,单指在触摸屏上)激活元素(click
)通常会产生以下事件顺序:
mousemove
pointerover
pointerenter
mouseover
mouseenter
pointerdown
mousedown
pointermove
和mousemove
事件pointerup
mouseup
click
pointerout
pointerleave
mouseout
mouseleave
然而,如果在此交互期间pointerdown
事件被取消,那么事件顺序将是:
mousemove
pointerover
pointerenter
mouseover
mouseenter
pointerdown
pointermove
事件pointerup
click
pointerout
pointerleave
mouseout
mouseleave
本附录讨论了指针事件实现的安全和隐私注意事项。讨论仅限于直接因实现本规范中定义的事件模型、API 和事件而产生的安全和隐私问题。
本规范中定义的许多事件类型是响应用户操作而调度的。这使得恶意事件监听器能够访问用户通常认为是机密的信息,例如用户与页面交互时鼠标/手写笔/手指的精确路径/移动。
指针事件包含了用户设备支持的额外信息,例如手写笔输入的角度或倾斜度、接触面的几何形状以及施加在手写笔或触摸屏上的压力。关于角度、倾斜度、几何形状和压力的信息直接与用户设备上的传感器相关,这意味着本规范允许一个源访问这些传感器。
这些传感器数据,以及确定所使用的输入机制(鼠标、触摸、手写笔)类型的能力,可能会被用来推断用户或用户设备和环境的特征。这些推断出的特征和任何设备/环境信息本身可能是敏感的——例如,它们可能允许恶意站点进一步推断用户是否在使用辅助技术。这些信息也可能被用于建立用户档案和/或尝试“指纹识别”并跟踪特定用户。
作为缓解措施,用户代理可能会考虑包括用户禁用特定传感器数据(如角度、倾斜度、压力)访问的能力,和/或仅在用户明确选择加入后才使其可用。
除了这些考虑之外,工作组认为本规范:
非常感谢许多人的提议和建议,其中一些已被纳入本文档。小组主席感谢以下现任和前任小组成员和参与者的贡献: 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。
本节为非规范性内容。
以下是相对于第一个 [PointerEvents1] 规范的版本之间的重大和主要编辑更改的说明性摘要。请参阅本规范编辑草案的完整修订历史。
[COMPAT]
标记为纯粹的说明性内容)
connected
替换关于ownerDocument
树的描述fromElement
和toElement
(继承自
MouseEvents)必须为null
的说明[Exposed=Window]
hasPointerCapture
touch-action
更改的澄清touch-action
处理模型的缩放场景