输入事件规范 第2级

W3C 工作草案

有关此文档的更多详细信息
此版本:
https://www.w3.org/TR/2026/WD-input-events-2-20261015/
最新发布版本:
https://www.w3.org/TR/input-events-2/
最新编辑草案:
https://w3c.github.io/input-events/
历史记录:
https://www.w3.org/standards/history/input-events-2/
提交历史
编辑:
(受邀专家)
前任编辑:
Ben Peters (微软) - 截至
反馈:
GitHub w3c/input-events (拉取请求, 新问题, 开放问题)
public-editing-tf@w3.org 主题行 [input-events-2] … 主题内容 … (存档)
按级别发布的最新版本
第2级
按级别发布的最新编辑草案
第2级

摘要

本规范定义了文本及相关输入的事件扩展,以便在文本编辑器应用程序和其他处理文本输入及文本格式化的应用程序中,监控和操作默认的浏览器行为。本规范基于UI事件规范 [UI-EVENTS]。

本文件的状态

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

输入事件规范 第2级 取代了输入事件的第一个版本 [INPUT-EVENTS],并包含:

输入事件规范的 测试套件 和 实现报告 仍在进行中。

本文件由 Web 编辑工作组 作为工作草案发布,使用了推荐轨道。

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

本文档为草案,可能随时被其他文档更新、替换或废弃。将本文件作为除“进行中工作”之外的引用是不合适的。

本文档由一组遵循 W3C 专利政策 的成员编写。 W3C 维护着一个 有关本小组成果的公开专利披露列表; 该页面还包括专利披露说明。任何个人若实际知晓某项专利并认为其包含 必要权利要求(Essential Claim(s)), 必须根据 W3C 专利政策第 6 节 披露相关信息。

本文件受 2025年8月18日 W3C 流程文件 的约束。

1. 简介

本文档描述了与编辑相关的两个事件的扩展 - input 和 beforeinput,这些事件在 UI 事件规范中进行了描述 [UI-EVENTS]。这些事件的目的是允许开发者理解和/或覆盖编辑行为的默认处理,编辑操作在执行前或执行后。

2. 一致性

除标记为非规范性的章节外,本规范中的所有作者指南、图表、示例和注释均为非规范性内容。其他所有内容均为规范性内容。

本文档中的关键词 MAY、MUST 和 MUST NOT 应按照 BCP 14 [RFC2119] [RFC8174] 的说明进行解释,仅当这些词以如上所示全部大写形式出现时,才按上述定义解释。

3. 定义

表达意图
用户可以通过键盘、输入法(IME)、语音或类似方法表达执行特定编辑操作的意图。特定的输入操作根据平台特定的约定映射为意图。
杀死缓冲区

此定义为非规范性内容。

杀死缓冲区 是一个与剪贴板分开的内存存储区域,用于暂存通过特定删除命令删除的富文本内容。用户可以通过表达“提取杀死缓冲区”的意图,将杀死缓冲区中的内容替换当前选中的内容。

4. 解决的问题

本节为非规范性内容。

创建一个基于Web的文本编辑器需要在浏览器代码之上编写大量的JavaScript,部分原因是:

  1. 各个浏览器对编辑操作的处理方式不尽相同。
  2. 浏览器在处理某些编辑操作时通常存在问题。
  3. 各个网站可能对某些编辑操作有自定义的处理偏好。
  4. 浏览器在开发高级文本编辑功能时未完全遵循可扩展Web宣言中提出的原则,因为这些功能的开发未始终与Web开发者社区的需求相协调。

本规范旨在通过提供一种简单的方法,允许Web开发者通过 beforeinput 事件覆盖浏览器对所有与文本编辑相关的用户输入的处理,并通过 input 事件监控浏览器因用户输入而对DOM的更改,从而缓解这一问题。

5. 使用案例

本节为非规范性内容。

  1. 创建一个JavaScript文本编辑器,其中使用<strong>标签代替<b>标签来标记用户选择为粗体的文本,使用浏览器内置的任何方式来标记文本为粗体,而不需要访问所有现有的浏览器。
  2. 创建一个JavaScript文本编辑器,该编辑器在后台使用数据模型,JavaScript负责将对编辑文本的更改渲染到DOM中。
  3. 创建一个只允许部分富文本编辑的JavaScript编辑器(例如:允许使用粗体,但不允许使用斜体)。
  4. 创建一个协作编辑器,JavaScript根据用户意图渲染对DOM的更改,用户使用不同的浏览器来表达具体意图的方式各不相同。
  5. 创建一个具有不同用户访问选项的JavaScript编辑器,其中一些用户只能添加或删除文本,而其他用户只能添加或删除某些类型的格式。

6. 输入事件类型

输入事件在用户尝试编辑标记之前(beforeinput事件)和之后(input事件)发送。这包括内容的插入和删除,以及格式更改。

输入事件会在作为 编辑主机(editing hosts) 的元素上分派,包括设置了 contenteditable 属性的元素、textarea 元素,以及允许文本输入的 input 元素。

6.1 接口 InputEvent

WebIDLpartial interface InputEvent {
   readonly attribute DataTransfer? dataTransfer;
   sequence<StaticRange> getTargetRanges();
};

partial dictionary InputEventInit {
   DataTransfer? dataTransfer = null;
   sequence<StaticRange> targetRanges = [];
};

属性 inputType 和 dataTransfer 属于 InputEventInit ,用于初始化相应属性,这些属性属于 InputEvent 对象。

该 targetRanges 属性属于 InputEventInit ,用于初始化 目标范围,这些范围属于 InputEvent 对象,并由 getTargetRanges() 返回。

6.1.1 概览

本节为非规范性内容。

下表概述了 data 和 dataTransfer 属性何时包含 内容以及何时为 null,还概述了基于 inputType,getTargetRanges() 方法何时返回 空 Array 或非空 Array。

编辑主机 inputType data dataTransfer getTargetRanges()
Contenteditable "insertText", "insertCompositionText", "formatSetBlockTextDirection", "formatSetInlineTextDirection", "formatBackColor", "formatFontColor", "formatFontName", "insertLink" Yes null 非空数组
Contenteditable "insertFromPaste", "insertFromPasteAsQuotation", "insertFromDrop", "insertReplacementText", "insertFromYank" null Yes 非空数组
<textarea>, <input type="text"> "insertText", "insertCompositionText", "insertFromPaste", "insertFromPasteAsQuotation", "insertFromDrop", "insertReplacementText", "insertFromYank", "formatSetBlockTextDirection", "formatSetInlineTextDirection", "formatBackColor", "formatFontColor", "formatFontName", "insertLink" Yes null 空数组
所有 "historyUndo", "historyRedo" null null 空数组
Contenteditable 所有剩余 null null 非空数组
<textarea>, <input type="text"> 所有剩余 null null 空数组

6.1.2 属性

beforeinput事件是否可取消取决于inputType。

inputType的选择取决于用户的意图表达,编辑是否在IME组合过程中进行,以及选择的状态。

本规范将inputType值定义为下表中的inputType列中的值。

inputType 用户的意图表达 IME组合的一部分 beforeinput是否可取消 选择的状态
"insertText" 插入键入的纯文本 否 是 任何
"insertReplacementText" 通过拼写检查器、自动更正、书写建议或类似方式插入或替换现有内容 否 是 任何
"insertLineBreak" 插入换行符 否 是 任何
"insertParagraph" 插入段落符 否 是 任何
"insertOrderedList" 插入编号列表 否 是 任何
"insertUnorderedList" 插入项目符号列表 否 是 任何
"insertHorizontalRule" 插入水平线 否 是 任何
"insertFromYank" 用存储在kill buffer中的内容替换当前选择 否 是 任何
"insertFromDrop" 通过拖放插入内容 否 是 任何
"insertFromPaste" 从剪贴板粘贴内容或从客户端提供的图像库粘贴图像 否 是 任何
"insertFromPasteAsQuotation" 作为引用从剪贴板粘贴内容 否 是 任何
"insertTranspose" 调换最后输入的两个字素簇(grapheme cluster)的顺序。 否 是 任何
"insertCompositionText" 替换当前组合字符串 是 否 任何
"insertLink" 插入链接 否 是 任何
"deleteWordBackward" 删除光标位置前的单词 否 是 折叠
"deleteWordForward" 删除光标位置后的单词 否 是 折叠
"deleteSoftLineBackward" 从光标位置删除到最近的视觉换行符之前 否 是 折叠
"deleteSoftLineForward" 从光标位置删除到最近的视觉换行符之后 否 是 折叠
"deleteEntireSoftLine" 从光标位置之前的最近视觉换行符删除到光标位置之后的最近视觉换行符 否 是 折叠
"deleteHardLineBackward" 从光标位置删除到块元素的最近开头或 br 元素之前 否 是 折叠
"deleteHardLineForward" 从光标位置删除到块元素的最近结尾或 br 元素之后 否 是 折叠
"deleteByDrag" 通过拖动从DOM中删除内容 否 是 任何
"deleteByCut" 作为剪切的一部分删除当前选择 否 是 任何
"deleteContent" 删除选择而不指定删除的方向,并且此意图不被另一个inputType涵盖 否 是 未折叠
"deleteContentBackward" 删除光标位置前的内容,并且此意图不被另一个inputType涵盖,或者删除选择,选择在删除后折叠到其开始位置 否 是 任何
"deleteContentForward" 删除光标位置后的内容,并且此意图不被另一个inputType涵盖,或者删除选择,选择在删除后折叠到其结束位置 否 是 任何
"historyUndo" 撤销最后的编辑操作 否 是 任何
"historyRedo" 重做最后撤销的编辑操作 否 是 任何
"formatBold" 启动粗体文本 否 是 任何
"formatItalic" 启动斜体文本 否 是 任何
"formatUnderline" 启动下划线文本 否 是 任何
"formatStrikeThrough" 启动删除线文本 否 是 任何
"formatSuperscript" 启动上标文本 否 是 任何
"formatSubscript" 启动下标文本 否 是 任何
"formatJustifyFull" 将当前选择完全对齐 否 是 任何
"formatJustifyCenter" 将当前选择居中对齐 否 是 任何
"formatJustifyRight" 将当前选择右对齐 否 是 任何
"formatJustifyLeft" 将当前选择左对齐 否 是 任何
"formatIndent" 缩进当前选择 否 是 任何
"formatOutdent" 减少当前选择的缩进 否 是 任何
"formatRemove" 删除当前选择的所有格式 否 是 任何
"formatSetBlockTextDirection" 设置文本块方向 否 是 任何
"formatSetInlineTextDirection" 设置文本行方向 否 是 任何
"formatBackColor" 更改背景颜色 否 是 任何
"formatFontColor" 更改字体颜色 否 是 任何
"formatFontName" 更改字体家族 否 是 任何
注意
其他规范可能会扩展此定义。
注意
上述 inputTypes 的存在并不意味着所有实现都必须支持全部这些类型。但如果某个浏览器支持某种可能导致 DOM 发生变化的编辑操作,则它 MUST 分派 相应的 beforeinput 和 input 事件。
注意
如果选择被折叠,"deleteContentBackward"将用于用户请求在文本节点内删除文本时,以及当用户表示删除更复杂的元素或在光标位于文本节点开头时合并段落时。
注意
如果选择被折叠,"deleteContentForward"将用于用户请求在文本节点内删除文本时,以及当用户表示删除更复杂的元素或在光标位于文本节点末尾时合并段落时。

data 保存与要添加到文档中的内容相关的纯文本数据。

inputType 编辑主机 data
"insertText" 或 "insertCompositionText" 任意 要插入的纯文本字符串
"insertFromPaste", "insertFromPasteAsQuotation", "insertFromDrop", "insertTranspose", "insertReplacementText" 或 "insertFromYank" input 或 textarea 要插入的纯文本字符串
"formatSetInlineTextDirection" 或 "formatSetBlockTextDirection" 任意 "ltr","rtl","auto" 或"null"
"formatBackColor" 或 "formatFontColor" 任意 包含序列化CSS组件值的字符串 [CSSOM] 用于建议的颜色
"formatFontName" 任意 提议的字体家族CSS属性值
"insertLink" 任意 提议的链接URL
所有其他 任意 null

dataTransfer 属性在有相关数据时,将关于富文本和纯文本数据的信息保存在 DataTransfer 对象中,用于从文档提取或向文档添加数据。

inputType 编辑主机 dataTransfer
"insertFromPaste", "insertFromPasteAsQuotation", "insertFromDrop", "insertTranspose", "insertReplacementText" 或 "insertFromYank" contenteditable 预先填充的 DataTransfer 对象,具体如下:
  1. DataTransfer 对象的 拖拽数据存储(drag data store)处于 只读模式。[HTML]
  2. 如果粘贴内容为文件,则 DataTransfer 对象的 拖拽数据存储项目列表(drag data store item list) 包含一个条目,其 数据项类型字符串(drag data item type string) 为文件的 MIME 类型,类型(kind)为 File,其数据为与粘贴文件对应的 File 对象。[HTML]
  3. DataTransfer 对象的 拖拽数据存储项目列表(drag data store item list)包含一个条目,其 数据项类型字符串为 "text/html",类型为 纯 Unicode 字符串(Plain Unicode string),其数据为剪贴板或kill buffer中内容的 HTML 表示,或将被插入的内容的 HTML 表示。[HTML]
  4. DataTransfer 对象的 拖拽数据存储项目列表包含一个条目,其 数据项类型字符串为 "text/plain",类型为 纯 Unicode 字符串,其数据为将要粘贴、拖拽或添加的内容的纯文本表示。[HTML]
  5. 如果要粘贴的内容为链接,则 DataTransfer 对象的 拖拽数据存储项目列表包含一个条目,其 数据项类型字符串为 "text/uri-list",类型为 纯 Unicode 字符串,其数据为将被插入或添加的链接的纯文本表示。[HTML]
所有其他 任意 null

getTargetRanges() 返回 目标范围 ,这些范围属于 InputEvent 对象。

每个 InputEvent 对象都具有 关联的 目标范围, 它是由 StaticRanges 组成的序列。当创建 InputEvent 对象时,其 目标范围 被设置为 该 targetRanges 属性的值,该属性属于 InputEventInit 字典;如果未提供该属性,则将其设置为空序列。

用户代理 必须 按如下规则设置其所分发的 目标范围,这些范围属于 受信任的 InputEvent 事件, 即其所 分发的事件,具体规则 如下:

由 目标范围 所属的 InputEvent 被 分发 时,如果是 用户代理 发起的,则 必须 仅涵盖 码点,即 用户代理 在 正常情况下会替换的码点,即使它们仅是某个 字素簇的一部分。

当 InputEvent 对象由 脚本创建时,其 目标范围 为创建该对象的脚本通过 以下 targetRanges 属性设置的值,该属性属于 InputEventInit 字典。用户 代理 不得 修改这些范围,也 不得 根据 编辑宿主、 inputType 或 DOM 的状态推导这些范围。特别是,目标 范围 所属的 InputEvent 如果不是 受信任的,则在 其 创建脚本未设置这些范围时,这些范围为空序列,即使该事件在 编辑宿主 上分发,并且 具有 inputType, 对于该属性, 用户代理 本来 会计算 目标范围。

注

本注释不具有规范性。

能够创建一个 InputEvent,并使其具有已知的 目标范围,使编辑器能够表达一种输入 意图,而 用户代理 无法将该意图映射为用户手势。 例如,界面具有“向后删除单词” 按钮的编辑器可以分发一个 beforeinput 事件,其 inputType 为 "deleteWordBackward", 并带有 目标范围,该范围是它为插入符之前的单词 计算得到的,使事件处理器能够像处理 受信任的 事件一样处理该事件。

注

本注释不具有规范性。

根据脚本和平台的不同,在具有折叠选区的文本节点中向后或 向前删除内容,可能影响一个或 多个 码 点,也可能影响整个 字素簇。例 如,在文本节点中向后删除时, 如果该节点包含“café”,则可能仅移除尖音符,也可能移除整个 “é”字符,具体取决于脚本和平台。

6.1.3 方法

inputType 编辑主机 getTargetRanges() 的响应
"historyUndo" 或 "historyRedo" 任意 空数组
其他所有 contenteditable 一个包含 StaticRanges 的数组 [DOM] 与事件相关联
其他所有 input 或 textarea 空数组

下表描述了 目标范围,这些范围由 用户代理 设置在其 InputEvent 对象上;这些对象由其 分发, 并作为 受信任的 事件。

对于由脚本创建的 InputEvent 对象, 其 目标范围 是 在 InputEventInit 字典中设置的范围,而不受 inputType 或 编辑宿主 的影响。

6.2 事件定义

beforeinput
类型 beforeinput
接口 InputEvent
同步 / 异步 同步
冒泡 是
受信目标 任何作为 Element 的 编辑主机(editing host)。
默认操作 [UI-EVENTS]
上下文
(受信事件)

用户代理(user agent) MUST 在用户尝试在 contenteditable 元素中输入时 分派 此事件。这并不一定意味着 用户代理会随即更新 DOM。

用户代理 MUST NOT 因非用户输入尝试引发的事件(如系统事件)而 分派 此事件。

这并不妨碍脚本 分发 一个 beforeinput 事件。此类事件不是 受信任的,因此其 目标范围 是在 InputEvent 对象创建时设置的范围,getTargetRanges() 会返回这些范围。

注

本注释不具有规范性。

第三方浏览器扩展,例如拼写或语法 检查工具,可能通过以下方式修改可编辑元素的内容: 分发合成的 beforeinput 事件 (即 其 isTrusted 属性为 false 的事件), 因为 用户 代理 不会为此类修改 分发 事件 来响应这类 修改。为了保持与这些扩展的兼容性, 建议 JavaScript 开发者监听这些 合成的 beforeinput 事件,并处理 其中 inputType 为 "insertReplacementText"、 "insertFromPaste"、"deleteContent"、 "deleteContentBackward" 或 "deleteContentForward" 的事件,并以与 相应受信任事件相同的方式处理它们。

这同样适用于使用 EditContext 编辑宿主 的编辑器:即使通常无需处理删除操作的 inputTypes "deleteContent"、 "deleteContentBackward" 和 "deleteContentForward", 因为在此类编辑宿主中,用户代理 会通过 以下机制处理这些操作: EditContext,但编辑器仍应处理合成的 beforeinput 事件中的这些 inputTypes, 即由扩展分发的事件。同样,当第三方 扩展以类似粘贴操作的方式插入内容时, 监听合成的 beforeinput 事件, 其 inputType 为 "insertFromPaste",比 监听合成的 paste [CLIPBOARD-APIS] 事件更可取,因为 paste 事件不 携带目标范围。

input
类型 input
接口 InputEvent
同步/异步 同步
冒泡 是
可信目标 任何启用了 contenteditable 属性的 Element。
默认操作 [UI-EVENTS] 无
上下文
(可信事件)

一个 user agent MUST dispatch 此事件, 应在 DOM 因用户明确表达的意图而被更新、且该意图导致的文档内容更改已由浏览器处理之后, 立即触发。如果 浏览器没有进行任何 DOM 更改,可能是因为编辑 宿主是一个 EditContext editing host(它不会自动进行 DOM 更改),或者是因为 user agent 认定不需要进行 DOM 更改,则用户代理 MUST NOT 触发此事件。

与 beforeinput 事件一样,由脚本创建的 InputEvent,如果其类型为 input,则其 目标范围 为 InputEventInit 字典中指定的范围,getTargetRanges() 将返回这些范围。

7. 输入事件在合成期间的顺序

合成的开始通过调度 compositionstart 事件标记。

在合成会话期间,每当文本合成系统更新其活动文本段落时,都会调度 compositionupdate 事件。

在每个 compositionupdate 事件之后,会调度一对 beforeinput 和 input 事件。 beforeinput 和 input 事件:

活动文本段落的 DOM 内容在调度 beforeinput 事件后,input 事件之前更新。

合成会话的结束通过调度 compositionend 事件标记。

8. 使用 "insertFromPaste" 时的事件顺序

当调度 "insertFromPaste" beforeinput 事件时,它 必须 之前已经调度了 paste 事件。[CLIPBOARD-APIS]

9. 隐私和安全考虑

本节不是规范性的。

除了现有事件(如 keydown 和 keypress [UI-EVENTS] 事件)中已存在的 浏览器指纹识别 [fingerprinting-guidance] 技术外,此功能没有已知的安全或隐私影响。

如果此功能替换现有事件,它 可能 导致可用的 指纹识别 技术减少,因为记录的是用户的意图,而不是他们使用的特定硬件类型来 表达 这个意图。

10. 致谢

感谢:Michael Aufreiter, Adrian Bateman, Oliver Buchtala, Robin Berjon, Enrica Casucci, Bo Cupp, Domenic Denicola, Emil Eklund, Olivier Forget, Aryeh Gregor, Marijn Haverbeke, Yoshifumi Inoue, Koji Ishii, Gary Kacmarcik, Ian Kilpatrick, Frederico Caldeira Knabben, Takayoshi Kochi, Piotrek Koszuliński, Travis Leithead, Grisha Lyukshin, Miles Maxfield, Chaals McCathie Nevile, Masayuki Nakano, Ryosuke Niwa, Julie Parent, Ben Peters, Florian Rivoal, Morgan Smith, Hallvord R. M. Steen, Johan Sörlin, Cristian Talau, Dave Tapuska, Ojan Vafai, Léonie Watson, Xiaoqian Wu, Chong Zhang, Joanmarie 以及编辑任务组中的所有人为他们的意见和反馈。

A. 参考文献

A.1 规范性参考文献

[CLIPBOARD-APIS]
剪贴板 API 和事件. Rakesh Goulikar; Rohan Raja. W3C. 2026 年 6 月 24 日. W3C 工作草案. URL: https://www.w3.org/TR/clipboard-apis/
[CSSOM]
CSS 对象模型(CSSOM). Daniel Glazman; Emilio Cobos Álvarez. W3C. 2021 年 8 月 26 日. W3C 工作草案. URL: https://www.w3.org/TR/cssom-1/
[DOM]
DOM 标准. Anne van Kesteren. WHATWG. 现行标准. URL: https://dom.spec.whatwg.org/
[FileAPI]
文件 API. Marijn Kruisselbrink. W3C. 12 9 月 2026 年. W3C 工作草案. URL: https://www.w3.org/TR/FileAPI/
[fingerprinting-guidance]
缓解浏览器指纹识别在 Web 规范中的影响. Nick Doty; Tom Ritter. W3C. 2025 年 9 月 25 日. W3C 工作 组说明. URL: https://www.w3.org/TR/fingerprinting-guidance/
[HTML]
HTML 标准. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 现行 标准. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra 标准. Anne van Kesteren; Domenic Denicola. WHATWG. 现行标准. URL: https://infra.spec.whatwg.org/
[mimesniff]
MIME 嗅探标准. Gordon P. Hemsley. WHATWG. 现行标准. URL: https://mimesniff.spec.whatwg.org/
[RFC2119]
RFC 中用于表示 要求级别的关键词. S. Bradner. IETF. 1997 年 3 月. 当前最佳实践. URL: https://www.rfc-editor.org/info/rfc2119/
[RFC8174]
RFC 中大写与小写形式的歧义 2119 关键词. B. Leiba. IETF. 2017 年 5 月. 当前最佳实践. URL: https://www.rfc-editor.org/info/rfc8174/
[UI-EVENTS]
UI 事件. Xiaoqian Wu. W3C. 21 2 月 2026 年. W3C 工作草案. URL: https://www.w3.org/TR/uievents/
[WEBIDL]
Web IDL 标准. Edgar Chen; Timothy Gu. WHATWG. 现行标准. URL: https://webidl.spec.whatwg.org/

A.2 参考资料

[i18n-glossary]
国际化术语表. Richard Ishida; Addison Phillips. W3C. 2024 年 10 月 17 日. W3C 工作组说明. URL: https://www.w3.org/TR/i18n-glossary/
[INPUT-EVENTS]
输入事件第 2 级. Johannes Wilm. W3C. 2026 年 5 月 1 日. W3C 工作草案. URL: https://www.w3.org/TR/input-events-2/