专栏名称: 鲨叔
web前端工程师
目录
相关文章推荐
今天看啥  ›  专栏  ›  鲨叔

【译】UI Events(W3C Working Draft, 30 May 2019)

鲨叔  · 掘金  ·  · 2020-01-13 02:20
阅读 19

【译】UI Events(W3C Working Draft, 30 May 2019)

前言

本文为意译,翻译过程中掺杂本人的理解,如有误导,请放弃继续阅读。

原文地址:SyntheticEvent

摘要

这个文档定义了UI Events的相关规范。UI Events继承了定义在DOM中的DOM Event objects。UI Events 的相关规范将会被那些负责处理用户交互行为(比如:通过鼠标和键盘来输入信息)的user agents (翻译为终端设备?)来实现。

文档状态声明

这个章节声明了这个文档被发布时候的状态。其他文档可能会取代这个文档。大量的当前已经发布的W3C标准和最后一个版本的技术报告可以到https://www.w3.org/TR/的W3C technical reports index 查看。

这篇文档是由Web Applications Working Group作为工作草案(Working Draft)来发布的。这篇文档里面所描述的规范是志在于成为W3C的推荐标准( W3C Recommendation )的。

GitHub Issues是讨论这个规范的首选地方。

经发布后成为工作草案,并不意味着得到W3C成员(W3C Membership)的认可。这是一份草稿类型的文档,它将来随时都有被更新,替代或者被其他文档宣称为废弃的可能。所以,在其他还在进行中的工作里面引用这份文档的行为是不恰当的,我们建议你不要这么做。

本文档由一个工作小组在遵循W3C专利政策下前提下编写而成的。W3C 维护着一份跟本工作小组存在利益关联的公开的专利公开列表。这个链接在的页面还包含了关于一些正在披露进程中的专利的介绍。如果一个个人认为某项专利符合基本要求且他对该项专利是相当知情的话,那么他必须按照W3C专利政策第6节去披露相关的信息。

本文档由1 March 2019 W3C Process Document.负责管理。

1.介绍

1.1 概览

UI Events的设计是为了两个主要的目标。

  • 第一个是:设计一个允许注册事件监听器和通过树结构来描述事件流的事件系统。除此之外,本文档还会给出在用户界面控制和文档修改通知方面的标准事件模块的规范。包括了为每个事件模块定义的上下文信息。
  • 第二是:为已经应用在现有浏览器中的事件系统提供一个公共子集。这个目的是为了促进现有脚本和文档内容之间的互操作性。满足完全向后兼容不是我们的目标。尽管如此,本文档还是尽可能地去达成这一点(指向后兼容)。

1.2 Conformance(不译)

2. Stylistic Conventions(不译)

3.DOM Event架构

这个章节所描述的内容是非标准的(non-normative)。想要查阅关于DOM Event的标准描述,请查阅DOM

3.1 事件分发和DOM事件流

这个章节大概描述一下事件分发机制(dispatch mechanism)和事件是如何沿着DOM树上传播(propagate )的。软件应用可以使用dispatchEvent()来分发一个事件对象(event objects),然后这个事件对象就会沿着DOM事件流的方向在DOM树上传播。

遵循DOM事件流的事件分发机制图示如下:

事件分发,事件分发,分发的是什么呢?分发的是event object,分发的目标是event taget。但是在分发之前,event object的传播路径(propaagation path)必须先被确认下来。

什么是传播路径?传播路径是一个由current event targets组成的有序列表。而这个current event targets就是事件传播过程所途经的DOM 节点。传播路径是对文档的树状层次结构的一种映射。在这里有序列表里面,最后的那个元素就是event target;而在event target前面的元素,我们称之为event target的祖先节点(target’s ancestors)。在event target之前,并紧挨着它的那个元素我们称之为event target的父节点(target’s parent)。

一旦传播路径被确定下来,那么event object就会沿着一个或多个事件阶段(event phase)传播。我们有三个事件阶段:捕获阶段(capture phase),目标对象阶段(target phase)和冒泡阶段(bubble phase)。如果某个阶段不被当前实现环境所支持或者event object的传播被阻止后,那么这个阶段就会被跳过。举个例子说,如果event object的bubbles属性被设置为false,那么事件的冒泡阶段就会被跳过;又或者,我们在事件分发前就手动调用了stopPropagation()的话,那么所有的事件阶段将会被跳过。

event object会完成以下的三个阶段:

  • 捕获阶段: event object会沿着从[window对象]到[目标元素的父节点]的方向传播。这个阶段也常称之为“capturing phase”。
  • 目标对象阶段:event object传播到event target时,我们称之为target phase。目标对象阶段通常也称之为“at-target phase”。如果某种类型的事件不支持事件冒泡的话,那么event object的分发在完成这个阶段后就中断,停止了。
  • 冒泡阶段:event object的传播方向与捕获阶段相反。也即是沿着从[event target的父节点]到[window对象]的方向传播。这个阶段也常被称之为“bubbing phase”。

3.2. 默认行为与可取消事件

其实取消事件,就是取消事件的默认行为

通常来说,event object的分发是作为对用户的某个动作,某项任务的完成,或者某些异步活动处理进度(比如:网络请求)作响应而触发的。有些事件会被用来控制某些实现环境(implementation)上可能即将发生的行为(或者取消某个已经完成的动作)。对于类型的事件,我们说它是“可取消的”,这种行为,我们称之为“默认行为”(default action)。一个可取消的事件可以有一个或者多个的默认行为。我们可以通过调用“preventDefault()”事件来取消默认行为。

例子1:

一个mousedown事件会在用户按压一个指点设备(pointing device)上的按钮的时候触发。这个时候,实现环境有可能为其指定这样的一个默认行为:将当前状态机设置为允许用户对图片进行拖曳或者选中文本。下一个默认行为是什么取决于用户下一步做什么。打个比方,如果用户的指点设备划过的文本的话,那么文本选择事件(selection)就会触发了。如果用户的指点设备划过的是一张图片,那么一个图片拖曳的行为就发生了。取消默认行为就是阻止后续事件的发生。

默认行为通常来说是在事件分发完成后(也就是浏览器调用了你的event listener之后)才发生的。但是在一些特殊的情况下,默认行为可能会比事件的分发更加先前地发生。

例子2:

元素上的click事件的默认行为就是切换checked IDL的属性值。如果click事件的默认行为被取消了,这个属性值就会被重置为它先前的状态(也就是说,从界面来看,没有任何改变)。

当一个事件被取消之后,与此事件相关联的条件性的默认行为就会被跳过(或者像上面所提到的那样,如果一个默认行为是在事件分发之前发生的,那么最终产生的效果就如“撤销”(undone)那样)。一个事件(的默认行为)是否是可以取消的,由event object的cancelable属性决定。手动调用preventDefault()方法会阻止所有的默认行为的发生。事件对象的defaultPrevented属性指示的是该事件是否已经被取消了(例如:被先前的event listener取消了)。如果一个DOM application自己初始化了一次分发,那么dispatchEvent()方法的返回值就是指示了事件的默认行为是否已经被取消了。

注意:许多实现环境会把event listener的返回值(比如,返回false)当作为取消某个可取消事件的默认行为的凭证(虽然,window.onerror的事件处理器返回true时候才是取消默认行为)。

3.3. 同步事件与异步事件

event object的分发既可以以同步的方式进行,也可以以异步的方式来进行的。

什么是同步事件呢?我们可以把同步事件理解为放置到一个具有先进先出模型虚拟列表中的事件。这个列表中的顺序是由其他事件,DOM里面某些改变而触发的事件,或者用户的交互行为而触发的事件等等事件发生的先后顺序而决定的。整个列表里面的事件的分发都是阻塞的。也就是说,只有前一个事件完成了它的传播(或者它被手动地取消了),后一个事件才会被分发,否则的话,该事件的分发就会处于延滞状态。有一些事件的分发是由相关的设备或者进程所驱动的,比如说鼠标事件。这种类型的事件会被它所遵行的事件顺序算法event order所管理。user agent会按照这种顺序来分发事件。

什么是异步事件呢?异步事件可以认为是那些跟其他事件发生的先后顺序,DOM里面某些改变而触发的事件,或者用户的交互行为没有关系的,只是作为某项耗时的任务或者行为完成的结果而触发的那些事件。

例子3:

在文档加载的过程中,当遇到一个行内script元素的时候,它所包含的脚本就会被解析和执行。这个script元素上的load事件就会被入队,等待被触发。然而,因为script元素上load事件是一个异步事件,所以它与其他文档加载过程中触发的同步事件触发的先后顺序是无法得到保证的。

3.4. 可信任的事件(trusted events)

无论是作为用户交互的结果,还是作为DOM发生变动后的结果,凡是由user agent来定义生成的事件都是可信任的。事件是可信任的,则意味着这个事件可以享用一些由user agent提供的特权(privileges)。这些特权是不会提供给软件应用的自定义事件的。自定义事件是指那些通过使用createEvent(),initEvent()和dispatchEvent()方法所定义,所分发的事件。事件对象的isTrusted属性的值就是用于指示该事件是否可以被信任的。

大部分不被信任的事件是不会触发默认行为的,click事件除外。即使在事件对象的isTrusted属性是false的情况下,click事件还是会触发默认行为(这么做是为了向后兼容)。除了click事件,所有的其他不可信任事件的默认行为都表现得好像在event listener上调用了preventDefault()方法那样,也就是说没有了默认行为。

3.5. Activation triggers and behavior

如果将Activation翻译为“激活”,那么“Activation triggers”就会被翻译为“激活开关”或者“激活触发器”。从中文的语义俩看,会给人高深莫测,一头雾水的感觉。再没有想到更为贴切的翻译之前,保持原词,理解效果会更好。

特定的event targets(比如说,链接或者button元素)可能会有相应的activation behavior(比如链接追踪)。实现环境执行这些activation behavior是为了响应那些activation trigger (比如说,点击了一个链接就是一个activation trigger)。

例子4:

HTML和SVG这两种标记语言都有一个叫<a>标签的元素,在这两种语言中,这个元素都是指示着这是一个链接的意思。对<a>元素的文本类型或者图片类型的内容进行点击而触发的click事件,或者在<a>元素聚焦的前提下按下“enter”键时触发的keydown事件,这些都是<a>元素的activation trigger。而作为activation trigger响应,在这个例子中,具体指的是什么呢?答曰:如果链接是指向外部的话,那么activation behavior指的是将窗口(比如,浏览器窗口)的内容切换为新的文档内容的这个行为;如果链接指向的是内部的话,那么activation behavior指的是将文档的锚点重定位到最新的位置上的这个行为。

activation trigger就是一个用户动作或者一个事件。一旦这些动作或者事件发生了,那么就是相当于在告诉是实现环境:“activation behavior你得着手初始化啦,我准备要触发了”。由用户触发(user-initiated)的activation trigger有:

  • 在一个activatable element上点击了鼠标
  • 在一个activatable element处于focus状态下,按下了“enter”键
  • 甚至是在某个activatable element(比如,“hotkey”或者“access key”)不处于focus状态下,但是却按下了能链接到该元素的按键。

由事件触发的(event-based)activation trigger包括:

  • timer-based事件。在某个特定的时间点或者过了某段时间段会激活某个元素(activate an element)的事件称之为timer-based事件。
  • 进度事件(progress 事件)。某个特定的动作完成后触发的事件。
  • 条件性事件(condition-based event)。
  • 状态事件(state-based events)。

3.6. Constructing Mouse and Keyboard Events(不译)




原文地址:访问原文地址
快照地址: 访问文章快照