指针锁定 2.0

W3C 工作草案

关于此文档的更多详细信息
此版本:
https://www.w3.org/TR/2025/WD-pointerlock-2-20250929/
最新发布版本:
https://www.w3.org/TR/pointerlock-2/
最新编辑草案:
https://w3c.github.io/pointerlock/
历史记录:
https://www.w3.org/standards/history/pointerlock-2/
提交历史
测试套件:
https://github.com/web-platform-tests/wpt/tree/master/pointerlock
编辑:
Mustaq Ahmed (谷歌)
Vincent Scheib (谷歌)
前编辑:
Navid Zolghadr (谷歌)
反馈:
GitHub w3c/pointerlock (拉取请求, 新问题, 打开的问题)
浏览器支持:
caniuse.com

摘要

本规范定义了一个 API,提供了脚本化访问原始鼠标移动数据的功能,同时将鼠标事件的目标锁定在单个元素上,并将光标从视图中移除。对于某些类别的应用程序,尤其是第一人称视角的 3D 应用程序和 3D 建模软件,这是一个必不可少的输入模式。

本文档状态

本节描述了本文件在发布时的状态。当前 W3C 发布的文档列表以及本技术报告的最新修订版可在 W3C 标准与草案索引中找到。

本文档的变更历史可见 https://github.com/w3c/pointerlock/commits/gh-pages/index.html

W3C 推荐标准 2016年10月27日以来的变更摘要:

本文档由Web 应用工作组依据 推荐标准流程发布为工作草案。

作为工作草案发布,并不意味着 W3C 及其成员的认可。

本文档为草案文件,可能随时被更新、替换或废止。引用本文件时仅可视为正在进行中的工作。

本文件由遵循 W3C 专利政策的工作组制作。 W3C 维护了 与本组成果相关的专利公开列表, 该页面同时包含专利披露的说明。任何知晓某专利且认为其包含 必要声明 的个人,必须根据 W3C 专利政策第6节披露相关信息。

本文件受 2025年8月18日 W3C 流程文件管理。

1. 引言

本节为非规范性内容。

Pointer Lock API 允许应用程序直接解释鼠标移动作为输入方式,而不仅仅是读取鼠标光标的位置。一个流行的例子是 第一人称视角的三维图形应用程序(如游戏)中的运动控制:鼠标移动用于控制玩家摄像头的旋转/方向;不显示鼠标光标, 并且移动不受传统边界(如用户代理窗口或整个屏幕)的限制,这意味着鼠标移动可以在任何方向上无限跟踪。

Pointer Lock 与 Mouse Capture 相关 [MDN-SETCAPTURE](Mouse Capture 未指定:bug 14600)。 Capture 提供了在拖动鼠标时持续向目标元素传递事件的能力,但在鼠标按钮释放时停止。 Pointer Lock 的区别在于它是持久的,不受屏幕边界限制,无论鼠标按钮状态如何都发送事件,隐藏光标, 并且直到通过 API 调用或用户执行特定的 默认解锁手势 才会释放。

Pointer Lock 处理捕获单个资源并将其与单个元素关联。这类似于 Fullscreen API [FULLSCREEN], 它将单个元素提升为全屏。Pointer Lock API 选择尽可能紧密地仿照 Fullscreen API 的资源捕获、状态更改和释放 API。

Pointer Lock 交互模式以前称为鼠标锁定。名称更改的原因是,除了鼠标之外,许多不同的控制器类型都可以操纵屏幕上的指针光标, 并且它们都会受到影响。

2. 指针锁定和接口

2.1 指针锁定状态 定义

指针锁定状态 是一个状态, 在该状态下,单个 DOM 元素(我们称之为 指针锁定目标)接收所有鼠标事件,并且光标被隐藏。

一旦进入 指针锁定状态用户代理 将有一个 指针锁定目标、 一个 指针锁定选项, 它是 PointerLockOptions, 以及 光标位置,这是代表进入指针锁定状态时系统鼠标光标位置的一对数字 (与 screenXscreenY 中报告的位置相同)。指针锁定目标 将接收所有相关的用户生成的MouseEvent事件, 即所有用户生成的mousemovemousedownmouseupclickdblclickauxclickwheel [ui-events]。 在 指针锁定状态 下,其他元素不会接收这些事件。 不会分派需要鼠标光标概念的事件:即 mouseentermouseleavemouseovermouseoutdragdrop

Issue 97 :第 2.1 节应提及锁定对 PointerEvents 的影响

这是在 此线程中提出的: #49

是否可以以规范的方式列出这些事件,而不仅仅是举一些例子?

我认为当前文本是可以的,因为这里缺乏精确性只是鼠标事件规范中更大问题的症状。该问题在某些方面正在得到改善, 例如在 w3c/uievents#200 中有一些进展, 如果它被实现,那么最终这段内容可以作为 UI 事件规范的一部分。

但是,在此期间,如果您能准确列出这些事件,将有助于实现互操作性。

例如,我不确定指针事件是否会受到此更改的影响。

当处于 指针锁定状态 时, 如果 指针锁定选项中的 unadjustedMovement成员为true, 则事件坐标不会受到底层平台行为(如鼠标加速)的影响。换句话说,用户代理使用底层平台提供的 API 来确保获取原始事件。 如果PointerLockOptionsunadjustedMovement成员为false, 则用户代理依赖底层平台的默认鼠标加速行为。

指针锁定状态 中, 系统鼠标光标被隐藏,并且窗口将保持焦点,不会因鼠标移动或按键操作而失去焦点。这是通过底层操作系统 API 直接或间接实现的。

由应用程序脚本创建的合成鼠标事件,无论锁定状态如何,行为都是一样的。

2.2 PointerLockOptions 字典

WebIDLdictionary PointerLockOptions {
  boolean unadjustedMovement = false;
};
PointerLockOptions 字典

此选项字典用于自定义指针在锁定模式下的行为。

unadjustedMovement 成员

如果此值设置为true,则指针移动将不受底层平台的修改(如鼠标加速)的影响。

2.3 pointerlockchangepointerlockerror 事件

两种事件用于传达指针锁定状态的变化或更改状态时的错误。它们分别命名为 pointerlockchangepointerlockerror。 有关详细信息,请参阅 3. Element 接口的扩展 中的算法。

放大软件会增加屏幕上内容的大小。它使用鼠标移动放大的焦点。当启动指针锁定时,放大软件需要切换为使用键盘移动放大焦点。 当触发pointerlockchange事件时, 浏览器需要确保事件传达给辅助技术,如屏幕放大器。

2.4 退出指针锁定

退出指针锁定的过程如下:

  1. 系统鼠标光标必须重新显示,并定位到光标位置
  2. 用户交互任务源排队一个元素任务, 以在指定的 element节点文档触发一个事件, 事件名为pointerlockchange
  3. 通过将pointer-lock targetpointer-lock options光标位置设为 null,退出指针锁定状态

3. Element 接口的扩展

Element 接口被扩展,以提供请求指针锁定的能力。

WebIDLpartial interface Element {
  Promise<undefined> requestPointerLock(optional PointerLockOptions options = {});
};
const lock_element = document.getElementById("lock_element");
const lock_button = document.getElementById("lock");
lock_button.addEventListener("click", async (event) => {
    try {
        await lock_element.requestPointerLock({ unadjustedMovement: true });
        console.log("successfully locked!");
    } catch (e) {
        console.log("lock failed with error: ", e);
    }
});
requestPointerLock(PointerLockOptions options) 方法

一个名为 锁请求队列(lock requests queue)并行队列 用于排队所有请求。当调用 requestPointerLock() 时,执行以下步骤:

  1. promise一个新 promise
  2. window 处于 焦点时,如果 this包含 shadow 的根节点 不是 活动文档 所在的 浏览上下文 (或有一个 祖先 浏览上下文)处于非焦点状态:
    1. 用户交互任务源排队一个元素任务,以 this 为参数,执行以下步骤:
      1. 触发一个事件 名为 pointerlockerror,事件目标为 this节点文档
      2. 拒绝 promise,错误为 "WrongDocumentError" DOMException
    2. 返回 promise
    Issue 93: 可见性状态检查

    规范不应允许隐藏文档请求指针锁定。

    此外,如果文档变为隐藏状态,则应释放指针锁定。

  3. 如果相关全局对象没有瞬时激活,且 Document 之前未通过 exitPointerLock() 释放过成功的指针锁定:
    1. 用户交互任务源排队一个元素任务,以 this 为参数,执行以下步骤:
      1. 触发一个事件 名为 pointerlockerror,事件目标为 this节点文档
      2. 拒绝 promise,错误为 "NotAllowedError" DOMException
    2. 返回 promise
  4. 如果 this节点文档活动沙箱标志集 含有 sandboxed pointer lock browsing context flag 标志:
    1. 用户交互任务源排队一个元素任务,以 this 为参数,执行以下步骤:
      1. 触发一个事件 名为 pointerlockerror,事件目标为 this节点文档
      2. 拒绝 promise,错误为 "SecurityError" DOMException
    2. 返回 promise
  5. 如果 options["unadjustedMovement"] 为 true 且平台不支持 unadjustedMovement
    1. 用户交互任务源排队一个元素任务,以 this 为参数,执行以下步骤:
      1. 触发一个事件 名为 pointerlockerror,事件目标为 this节点文档
      2. 拒绝 promise,错误为 "NotSupportedError" DOMException
    2. 返回 promise
    Issue 90: 建议添加静态字段用于指示是否支持 `unadjustedMovement`。

    在 PR #49 中引入了 PointerLockOptions。但 PointerLockOptionsunadjustedMovement 可能并非所有平台都支持。静态字段可用于在直接在 PointerLockOptions 里使用前判断是否支持,以避免不支持报错。

  6. 将以下步骤加入 锁请求队列
    1. 如果用户代理的 pointer-lock target 是一个其 包含 shadow 的根节点 不等于 this包含 shadow 的根节点 的元素,则:
      1. 用户交互任务源排队一个元素任务,以 this 为参数,执行以下步骤:
        1. 触发一个事件 名为 pointerlockerror,事件目标为 this节点文档
        2. 拒绝 promise,错误为 "InvalidStateError" DOMException
    2. 如果用户代理的 pointer-lock target包含 shadow 的根节点 等于 this包含 shadow 的根节点 且 options 与当前 pointer-lock options 等价,则:
      1. pointer-lock target 设为 this
      2. 用户交互任务源排队一个元素任务,以 this 为参数,执行以下步骤:
        1. 触发一个事件 名为 pointerlockchange,事件目标为 this节点文档
        2. 解决 promise
    3. 如果 pointer-lock target 为 null,或 options 不等价于当前 pointer-lock options,则处理锁请求并在完成后处理响应:
      1. 如果锁请求失败:
        1. 用户交互任务源排队一个元素任务,以 this 为参数,执行以下步骤:
          1. 触发一个事件 名为 pointerlockerror ,事件目标为 this节点文档
          2. 拒绝 promise,错误为 "NotSupportedError" DOMException
        Issue 91: 如果后续 requestPointerLock 被拒绝,已锁定目标应否退出锁定状态?

        在 PR #49requestPointerLock 算法中,目前没有描述如下场景:
        当后续请求失败(出于任何原因),已锁定目标是否应退出锁定状态?

      2. 如果锁请求成功:
        1. 通过执行以下操作进入 指针锁定状态
          1. 将用户代理的 pointer-lock target 设为 this
          2. 将用户代理的 光标位置 设为当前系统鼠标位置。
          3. pointer-lock options 设为 options。
        2. 用户交互任务源排队一个元素任务,以 this 为参数,执行以下步骤:
          1. 触发一个事件 名为 pointerlockchange ,事件目标为 this节点文档
          2. 解决 promise
    Issue 96: 锁请求队列处理不完整

    在 PR #49 的 requestPointerLock 算法中,目前没有描述 lock requests queue 中条目的处理方式。缺少明确文本可能导致所有条目在末尾同步出队的错误(?)假设。

  7. 返回 promise

4. Document 接口的扩展

WebIDLpartial interface Document {
  attribute EventHandler onpointerlockchange;
  attribute EventHandler onpointerlockerror;
  undefined exitPointerLock();
};
onpointerlockchange 属性

用于事件处理程序 IDL 属性, 监听pointerlockchange事件。

onpointerlockerror 属性

用于事件处理程序 IDL 属性, 监听pointerlockerror事件。

exitPointerLock() 方法
  1. 如果用户代理的 pointer-lock target 为 null,则返回。
  2. 如果pointer-lock target包含 shadow 的根节点不等于 this节点文档,则返回。
  3. 使用用户代理的pointer-lock target 退出指针锁定

5. DocumentOrShadowRoot 混入的扩展

WebIDLpartial interface mixin DocumentOrShadowRoot {
  readonly attribute Element? pointerLockElement;
};
pointerLockElement

当指针被锁定时,返回对该元素进行重定向的结果,该元素是鼠标事件的目标。如果结果和this元素在同一棵树中,则返回该元素,否则返回 null。

如果锁定正在等待中或指针未被锁定,则返回 null。

<body>
  <div id="host1">
    <shadow-root id="root1">
      <canvas id="canvas1"></canvas>
    </shadow-root>
  </div>
  <div id="host2">
    <shadow-root id="root2">
      <canvas id="canvas2"></canvas>
    </shadow-root>
  </div>
</body>

本示例使用虚构的 shadow-root 元素来表示shadow root 实例。

如果 #canvas1 是目标,document.pointerLockElement 返回 #host1,而 root1.pointerLockElement 返回 #canvas1。将 重定向 #canvas1#root2 的结果是 #host1,但由于 #host1 不在与 #root2 相同的树中,因此 root2.pointerLockElement 会返回 null。

6. MouseEvent 接口的扩展

WebIDLpartial interface MouseEvent {
  readonly attribute double movementX;
  readonly attribute double movementY;
};
movementX 属性
movementY 属性

movementXmovementY 属性必须提供指针位置的变化量,相当于在两个连续的 mousemove 事件 eNowePrevious 之间,screenXscreenY 的值被保存,并取其差值 movementX = eNow.screenX - ePrevious.screenX

movementXmovementY 在所有鼠标事件中(除了 mousemovepointermove)必须为零。所有运动数据必须通过 mousemove 事件传递,这样在任意两个鼠标事件 earlierEventcurrentEvent 之间,currentEvent.screenX - earlierEvent.screenX 的值等价于 earlierEvent 之后所有事件的 movementX 的和,唯一的例外是当 screenX 无法更新时(因为指针被 用户代理 的屏幕边界裁剪)。

movementXmovementY 必须在无论是否处于指针锁定状态下都进行更新。

当未锁定时,系统光标可以离开并重新进入用户代理窗口。如果发生这种情况,且用户代理不是操作系统鼠标移动事件的目标,则用户代理将无法获知最近的指针位置,movementX/movementY 也无法计算,必须设为零。

当启用指针锁定时,clientXclientYscreenXscreenY 必须保持恒定值,好像进入指针锁定后指针根本未移动。但 movementXmovementY 必须继续像未锁定时一样提供指针位置的变化量。如果鼠标持续向一个方向移动,movementXmovementY 的值不会有上限。此时鼠标光标的概念已被移除,它不会移出窗口,也不会被屏幕边缘限制。

movementXmovementY 的未初始化值必须为 0

在鼠标输入被中断(如鼠标光标离开窗口后又在另一位置重新进入)时,不应出现大的 movement 值。如果用户代理 遇到从操作系统接收鼠标输入数据的间隙,则下一个生成的 mousemove 事件必须将 movementXmovementY 设为 0。例如,当用户代理在窗口系统 API 收到鼠标离开事件时就可能出现这种间隙。作为例外,鼠标捕获可能允许用户代理在光标移出窗口时继续接收鼠标事件。

7. MouseEventInit 字典的扩展

WebIDLpartial dictionary MouseEventInit {
  double movementX = 0;
  double movementY = 0;
};
movementX 成员
movementY 成员
movementXmovementY 成员用于初始化 MouseEvent 的对应成员。

8. 要求

必须始终提供一个 默认解锁手势, 用于通过 退出指针锁定, 使用 用户代理指针锁定目标

注意

如果pointer-lock target变为断开,或用户代理、窗口或标签失去焦点,则必须退出指针锁定。在 活动文档的各元素之间切换焦点,包括在浏览上下文之间切换,并不会退出指针锁定。例如,使用键盘在 frame 或 iframe 的内容之间切换焦点不会导致退出。

当进入或退出全屏 [FULLSCREEN] 时, 除非指针需要启用与 用户代理 图形用户界面的交互, 使用 默认解锁手势 退出了全屏和指针锁定,或者窗口或标签页失去焦点,则不得退出指针锁定。

9. 用例

本节为非规范性内容。

9.1 自由移动虚拟角色的相对视口旋转

玩家在第一/第三人称游戏中需要控制视口的方向。一个广泛使用的方法是使用鼠标移动来控制视角。 这种应用可以使用 Pointer Lock API 来允许对视口的偏航和俯仰进行完全自由的控制,即使用户没有按下鼠标按钮。 这些按钮可以用于其他操作,而鼠标移动可以持续提供导航。

9.2 自由旋转 3D 模型或平移 2D 层

三维建模应用的用户需要旋转模型。应用程序可以使用 Pointer Lock API 允许作者在拖动操作中自由旋转模型,而不会限制运动。 如果没有指针锁定,当鼠标光标受到屏幕边缘的限制时,拖动将停止提供运动数据。

同样,绝对运动的平移操作可以在不受光标/屏幕限制的单次拖动中完成,适用于大的二维图像。

9.3 角色的相对运动

在快速反应游戏中,玩家控制一个球拍将球反弹回对手,同时允许该球拍根据按下的不同鼠标按钮执行动作。 应用程序可以使用 Pointer Lock API 允许玩家快速反应,而无需担心鼠标光标离开游戏区域并点击其他系统应用程序,从而打断游戏流程。

9.4 在旋转控制器上的快进运动

在应用程序中修改数值时,有时用户会更喜欢通过拖动按钮手柄来增减数值。 例如,一个带有数字输入文本框和上下箭头的旋转器,可以点击或拖动来改变数值。 应用程序可以使用 Pointer Lock API 允许修改数值超过逻辑屏幕边界。这个方法同样适用于类似“快进”或“倒退”视频或音频流的控制。

9.5 与 HTML DOM UI 进行合成光标交互

一些游戏使用经典光标,但他们希望对其进行限制或控制。例如,限制在游戏范围内,或者由游戏进行移动。 锁定指针使这一点成为可能,如果应用程序创建自己的光标。但是 HTML 和 DOM 仍应可用于用户界面。 应该允许合成鼠标事件使应用定义的光标能够与 DOM 交互。例如,以下代码应允许自定义光标在指针锁定时发送点击事件:

document.addEventListener("click", function (e) {
  if (e._isSynthetic)
    return;
  // send a synthetic click
  var ee = document.createEvent("MouseEvents");
  ee._isSynthetic = true;
  x = myCursor.x;
  y = myCursor.y;
  ee.initMouseEvent("click", true, true, null, 1,
                    x + e.screenX - e.clientX,
                    y + e.screenY - e.clientY,
                    x,
                    y);
  var target = document.elementFromPoint(x, y);
  if (target)
    target.dispatchEvent(ee);
});

注意,合成点击可能不被 用户代理 允许产生与非合成点击相同的默认操作。 但是,应用程序处理程序仍然可以采取行动,并使用现有的 HTML 和 DOM 机制提供用户界面。

9.6 通过将鼠标光标移动到视口边界来进行视口平移

即时战略游戏通常使用这种技术。当玩家将光标移动到视口边界时,如果他们通过鼠标移动“推动”边界, 视口将根据他们移动鼠标的距离在游戏区域内平移。当在视口范围内移动鼠标光标时,它的行为与通常系统中的行为类似。 应用程序可以选择使用指针锁定和之前的用例“与 HTML DOM UI 进行合成光标交互”来完全控制光标行为。

9.7 游戏大厅中基于计时器的指针锁定

使用指针锁定的游戏可能希望在玩家在游戏大厅准备期间,提供传统的用户界面和系统光标。当所有玩家准备就绪后,游戏通常会在一个简短的倒计时后开始。理想情况下,游戏此时可以无需用户激活直接切换到指针锁定模式。 玩家应能够无缝地从游戏大厅进入游戏操作。

9.8 游戏门户

游戏门户和其他网站(如 Facebook 和 Google Plus)托管供用户玩的游戏。 这些游戏可能托管在与门户网站不同的来源。嵌入式游戏应能够在非全屏模式下锁定指针。

10. 安全

本节为非规范性内容。

安全问题:

应对措施:

建议:

指针锁定是某些应用程序类型所需的用户交互模式,但如果被恶意使用,可能会带来可用性问题。 攻击者可能会移除用户在其系统上控制鼠标光标的能力。用户代理 将通过始终提供退出机制、告知用户如何退出并限制指针锁定的进入方式来防止这种情况。

用户代理 将根据设备或用户选项自行确定适当的策略,这些策略可能因设备或用户选项而有所不同。

11. 常见问题解答

本节为非规范性内容。

11.1 为什么不与 Mouse Capture: setCapture() 合并?

Mouse Capture [MDN-SETCAPTURE] 处理了鼠标拖动手势期间低安全风险的鼠标事件目标锁定。 指针锁定移除了光标的概念,并将所有事件指向给定的目标。它们是相关的,但不同。

如果浏览器实现了两者,支持功能组合是合理的:自动释放锁定的安全简化功能,以及对鼠标输入的完全控制和移除系统光标的增强功能。 该安全特性允许应用程序在拖动事件期间仅需短暂的指针锁定时,更宽松地使用该功能。

这种功能在该规范的初始版本中被省略,因为它仅帮助了窗口模式下的小众用例,但我们仍然没有解决主要用例的实现方案。 而且,要实现这一点,浏览器必须同时实现这两者,而目前没有浏览器这样做。尚不清楚该功能应属于 .lock 还是 .setCapture。 如果两者都实现了,任何 API 都可以很容易地扩展以提供混合功能。

11.2 为什么不重新利用 MouseEvent 的 .clientX/Y .screenX/Y?

即使在非锁定状态下,鼠标移动的增量值也是有用的。根据锁定状态改变 .client 或 .screen 的含义还会导致代码中容易出现错误, 特别是在不仔细监控锁定状态时。

11.3 为什么使用 .movementX/Y 而不是 .deltaX/Y?

当指针锁定时,“wheel”事件应与“mousemove”事件一样发送到 指针锁定目标 元素。 与 DOM 3 “wheel”事件中定义的 .deltaX/Y/Z 存在命名冲突。

11.4 为什么将所有功能(隐藏光标、提供鼠标增量)捆绑在一起,而不是使用 CSS 隐藏光标、始终提供增量值并提供限制光标移动到网页某部分的 API?

提供更精细控制的方法是合理的。例如,“通过将鼠标光标移动到视口边界来进行视口平移”这一用例并不需要隐藏光标, 只需限制光标并始终提供增量值即可。此外,本规范定义了从系统鼠标光标移动中获取的运动增量, 该增量包含操作系统对鼠标移动数据的过滤和加速。应用程序可能希望访问更原始的移动数据形式, 即在适合鼠标光标的调整之前的数据。此外,原始数据可能提供比像素级别更高的移动精度,以及更高频率的更新。 提供原始增量运动不需要用户的特殊权限或模式,对于不需要限制光标的一些应用程序来说,可能会减少所需的安全屏障和提示。

推迟这种精细控制方法的原因有两个。首先是关于鼠标移动数据的单位问题。 本规范定义了 .movementX/Y 与鼠标未锁定时的 .screenX/Y 变化相同的值。各个 用户代理 和操作系统可以轻松满足这一要求,并为应用程序开发者和用户提供一致的体验。 此外,用户已预先配置了硬件输入和操作系统选项,从而使得系统鼠标光标控制更为舒适。 通过将 .movementX/Y 规定为与鼠标锁定 API 应用程序相同的单位,所有用户都可以立即使用这些应用程序,因为他们已经调整了他们的偏好。

其次,实现精细控制方法的运动数据和光标限制更为困难。捆绑这些功能为实现提供了自由, 使其可以根据每个操作系统使用各种技术,并且更容易实现。在主要桌面平台(Windows、Mac OS X、Linux)上没有直接的 API 来将光标限制到特定的矩形区域,并且尚未开发出通过例如使用 不可见窗口Xlib 进行原型构建来演示这一行为。未加速的增量值已经提出通过读取原始人机界面设备(HID)数据来访问。 例如,Windows 上的 WM_INPUT 消息,以及 Mac OS X / Linux 上的 USB 设备 API。 挑战在于解释和规范单位为一致且可指定的尺度。此外,迄今为止考虑的大多数 API 都仅限于 USB 设备。

考虑到当前规范的指针锁定 API 在未来实现这些精细控制的增量和限制功能时可以轻松继续支持, 添加这些功能在未来是合理的。

捆绑的 API 选择了实现的实用性,因为支持了预期的用例,并且不会与此处讨论的未来改进发生冲突。

11.5 高分辨率增量/高频更新?

还没有,原因与上一个问题相同:“为什么将所有功能(隐藏光标、提供鼠标增量)捆绑在一起,而不是使用 CSS 隐藏光标、 始终提供增量值并提供限制光标移动到网页某部分的 API?”

11.6 为什么修改 MouseEvent 并重用现有鼠标事件而不是创建 Mouse Delta 事件?

在指针锁定时,许多鼠标事件仍然相关,例如 click、mousedown 等。它们都共享相同的事件数据结构 MouseEvent。 如果通过一个新数据结构报告移动数据,那么将需要一个新事件来报告增量移动。 新的数据结构将与 MouseEvent 有许多相似之处,例如按钮和修改键状态的便利性。 在处理 click、down 和 up 事件时是否使用现有的 mousedown 和 mouseup? 如果是,它们将提供无用的 .clientX/Y 和 .screenX/Y 数据,但缺乏包含当前运动数据的便利性。 否则,当鼠标锁定时,将需要新的事件。

此外,即使鼠标未锁定,movementX/Y 也是方便的。本规范要求即使光标存在,运动成员始终有效。 这减少了在应用程序希望利用鼠标的增量运动时,跟踪最后的光标状态和 mouseover/mouseout 过渡所需的代码。

将 movementX/Y 添加到 MouseEvent 的唯一缺点似乎是在指针锁定时 clientX/Y 和 screenX/Y 中的未使用值。 这似乎不是一个重要问题。

因此,选择了向 MouseEvent 添加 movementX/Y 这一最小变更,以减少 API 和实现的复杂性。

11.7 为什么在指针锁定下为鼠标事件和键盘输入焦点分离目标?

考虑一个通过移动鼠标光标控制 3D 视图的游戏,同时用户仍可以通过文本控制台与其他用户聊天。 应用程序接受文本输入到与分派鼠标事件的元素不同的元素是合理的。这类似于在页面上填写表单时接收 mousemove 事件的预先行为。

12. 一致性

与标记为非规范的章节一样,本规范中的所有作者指南、图表、示例和注释都是非规范的。除此之外,本规范中的所有内容都是规范性的。

本规范定义了一些一致性标准,适用于单个产品:用户代理,即实现了其中包含的接口的用户代理。

A. 致谢

本节为非规范性内容。

非常感谢众多对本规范讨论做出贡献的人们:

B. 参考文献

B.1 规范性参考

[dom]
DOM 标准。Anne van Kesteren。WHATWG。 现行标准。URL:https://dom.spec.whatwg.org/
[FULLSCREEN]
全屏 API 标准。Philip Jägenstedt。WHATWG。 现行标准。URL:https://fullscreen.spec.whatwg.org/
[html]
HTML 标准。Anne van Kesteren;Domenic Denicola;Dominic Farolino;Ian Hickson;Philip Jägenstedt;Simon Pieters。WHATWG。现行标准。网址:https://html.spec.whatwg.org/multipage/
[ui-events]
UI 事件。Gary Kacmarcik;Travis Leithead。W3C。2024年9月7日。W3C 工作草案。网址:https://www.w3.org/TR/uievents/
[WEBIDL]
Web IDL 标准。Edgar Chen;Timothy Gu。WHATWG。现行标准。网址:https://webidl.spec.whatwg.org/

B.2 信息性参考

[MDN-SETCAPTURE]
Element.setCapture()。 Eric Shepherd 等人。URL:https://developer.mozilla.org/en-US/docs/Web/API/Element/setCapture