现行标准 — 最后更新 2024年10月1日
a
元素
em
元素
strong
元素small
元素s
元素
cite
元素q
元素
dfn
元素
abbr
元素ruby
元素rt
元素
rp
元素
data
元素time
元素code
元素var
元素samp
元素kbd
元素sub
和sup
元素i
元素
b
元素
u
元素
mark
元素bdi
元素bdo
元素span
元素br
元素
wbr
元素a
和 area
元素创建的链接a
和 area
元素的 APIalternate
"author
"bookmark
"canonical
"dns-prefetch
"expect
"external
"help
"icon
"license
"manifest
"modulepreload
"nofollow
"noopener
"noreferrer
"opener
"pingback
"preconnect
"prefetch
"preload
"privacy-policy
"search
"stylesheet
"tag
"terms-of-service
"picture
元素source
元素img
元素source
、img
和 link
元素的共同属性
iframe
元素embed
元素object
元素video
元素audio
元素track
元素TrackEvent
接口map
元素area
元素form
元素label
元素input
元素
type
属性的状态
type=hidden
)type=text
) 状态和搜索状态
(type=search
)type=tel
)type=url
)type=email
)type=password
)type=date
)type=month
)type=week
)type=time
)type=datetime-local
)type=number
)type=range
)type=color
)type=checkbox
)type=radio
)type=file
)type=submit
)type=image
)type=reset
)type=button
)input
元素属性
input
元素 APIbutton
元素select
元素datalist
元素optgroup
元素option
元素textarea
元素output
元素progress
元素meter
元素fieldset
元素legend
元素script
元素
noscript
元素template
元素
slot
元素canvas
元素
Path2D
对象ImageBitmap
渲染上下文
OffscreenCanvas
接口
canvas
元素的安全性Window
、WindowProxy
和 Location
对象的安全基础设施
Window
对象
WindowProxy
特殊对象
Location
接口
History
接口NotRestoredReasons
接口X-Frame-Options
` 头部Refresh
`
头部WindowOrWorkerGlobalScope
混入button
元素details
和 summary
元素input
元素作为文本输入控件input
元素作为特定领域的控件input
元素作为范围控制input
元素作为颜色选择器input
元素作为复选框和单选按钮部件input
元素作为文件上传控件input
元素作为按钮marquee
元素meter
元素progress
元素select
元素textarea
元素该规范定义了网页平台的大部分内容,详细程度很高。它在网页平台规范堆栈中的位置相对于其他规范可以总结如下:
本节为非规范性内容。
简而言之:是的。
更详细地说:“HTML5”这一术语广泛用作现代网页技术的流行词,其中许多(尽管并非全部)是由 WHATWG 开发的。本文档即为其中之一;其他文档可在 WHATWG 标准概览 中找到。
本节为非规范性内容。
HTML 是万维网的核心标记语言。最初,HTML 主要被设计为一种用于语义描述科学文档的语言。然而,它的总体设计使得它在随后的几年中被适应为描述其他多种文档类型甚至应用程序的语言。
本节为非规范性内容。
本规范旨在为使用本规范中定义的特性的文档和脚本的作者、操作使用本规范中定义特性的页面的工具的实现者,以及希望确认文档或实现是否符合本规范要求的个人提供参考。
本文件可能不适合没有至少基础了解网络技术的读者,因为在某些地方,它牺牲了清晰性以追求精确性,牺牲了简洁性以求完整性。更易于接近的教程和创作指南可以为读者提供更温和的入门介绍。
特别是,对于本规范中一些更技术性的部分,了解 DOM 的基础知识是必要的。理解 Web IDL、HTTP、XML、Unicode、字符编码、JavaScript 和 CSS 在某些地方也会有所帮助,但不是必须的。
本节为非规范性内容。
本规范的范围限于提供一个语义级别的标记语言和相关的语义级别脚本 API,用于创建从静态文档到动态应用的可访问网页。
本规范的范围不包括提供媒体特定的呈现定制机制(尽管规范末尾包括了默认的网页浏览器渲染规则,并且提供了若干与 CSS 相关的钩子机制)。
本规范的范围也不包括描述整个操作系统。特别是,硬件配置软件、图像处理工具以及用户预期在高端工作站上日常使用的应用程序均不在范围之内。就应用程序而言,本规范特别针对那些预期用户偶尔使用的应用程序,或定期但在不同地点使用的应用程序,并且对 CPU 的要求较低。这类应用程序的例子包括在线购物系统、搜索系统、游戏(尤其是多人在线游戏)、公共电话簿或地址簿、通信软件(电子邮件客户端、即时消息客户端、讨论软件)、文档编辑软件等。
本节为非规范性内容。
在其最初的五年(1990-1995),HTML经历了若干次修订和扩展,最初由CERN主办,之后转到IETF。
随着W3C的成立,HTML的开发再次发生了变化。1995年第一次尝试扩展HTML的HTML 3.0未能成功,随后出现了更为务实的HTML 3.2,完成于1997年。同年晚些时候,HTML4紧随其后。
次年,W3C会员决定停止对HTML的演进,转而开始开发基于XML的等效语言,称为XHTML。这个工作从HTML4在XML中的重新表述,即XHTML 1.0开始,这没有增加新功能,只是新的序列化,并于2000年完成。在XHTML 1.0之后,W3C的重点转向使其他工作组更容易扩展XHTML,名为XHTML模块化。与此同时,W3C还致力于一种与早期HTML和XHTML语言不兼容的新语言,称为XHTML2。
在1998年停止HTML演进的同时,浏览器供应商开发的HTML API部分被指定并发布,称为DOM Level 1(1998年)和DOM Level 2 Core及DOM Level 2 HTML(从2000年开始,直至2003年)。这些努力逐渐减弱,2004年发布了一些DOM Level 3规范,但工作组在所有Level 3草案完成之前就关闭了。
2003年,XForms的发布引发了对HTML自身演进的重新关注,这种技术被定位为下一代网页表单。这种兴趣源于XML作为网页技术的部署被局限于完全新技术(如RSS和后来的Atom),而不是作为现有技术(如HTML)的替代品。
一个概念验证显示扩展HTML4表单以提供XForms 1.0引入的许多功能,而无需浏览器实现与现有HTML网页不兼容的渲染引擎,是这种重新关注的第一个结果。在这一早期阶段,尽管草案已经公开,并且正在从各方征求意见,规范仅由Opera Software拥有版权。
在2004年的W3C研讨会上,HTML演进应该重新开放的想法得到了测试,一些HTML5工作的基本原则(如下所述)以及早期草案提案(仅涉及表单相关功能)由Mozilla和Opera联合向W3C提出。该提案因与之前选择的网页演进方向相冲突而被拒绝;W3C工作人员和会员投票决定继续开发基于XML的替代品。
不久之后,Apple、Mozilla和Opera共同宣布他们打算在一个名为WHATWG的新平台下继续工作。创建了一个公开的邮件列表,草案转移到WHATWG网站。版权随后被修改为由三家供应商共同拥有,并允许重新使用规范。
WHATWG基于几个核心原则,特别是技术需要向后兼容,规范和实现需要匹配,即使这意味着更改规范而不是实现,并且规范需要详细到实现可以实现完全的互操作性,而不必相互逆向工程。
特别是,后一个要求需要HTML5规范的范围包括之前在三个独立文档中规定的内容:HTML4、XHTML1和DOM2 HTML。这也意味着包含比之前考虑的更多细节。
2006年,W3C表示有兴趣参与HTML5的开发,2007年成立了一个工作组,与WHATWG合作开发HTML5规范。Apple、Mozilla和Opera允许W3C在W3C版权下发布规范,同时在WHATWG网站上保留一个具有较少限制的版本。
随后,两个小组一起工作了几年。然而,2011年,两个小组得出结论,他们的目标不同:W3C希望发布“完成”的“HTML5”版本,而WHATWG希望继续在HTML的Living Standard上工作,持续维护规范,而不是将其冻结在存在已知问题的状态,并根据需要添加新功能以发展平台。
2019年,WHATWG和W3C 签署了协议,共同协作开发一个单一版本的HTML,即本文档。
本节为非规范性内容。
必须承认,HTML的许多方面乍一看似乎是毫无意义和不一致的。
HTML及其支持的DOM API,以及许多支持技术,已经由一系列不同优先级的人们在数十年的时间里开发完成,在很多情况下,这些人彼此之间并不知道对方的存在。
因此,特性来源于多个来源,并且设计方式并不总是特别一致。此外,由于网页的独特特性,实施错误往往成为事实上的标准,甚至现在是法定标准,因为内容通常会在修复这些错误之前以依赖它们的方式被无意中编写。
尽管如此,仍然努力坚持某些设计目标。这些目标将在接下来的几个小节中进行描述。
本节为非规范性内容。
为了避免将多线程的复杂性暴露给网页作者,HTML和DOM API的设计使得脚本无法检测到其他脚本的同时执行。即使在工作线程中,设计的意图也是使实现行为可以被认为是完全串行化所有脚本在所有全局上下文中的执行。
这一通用设计原则的例外是JavaScript SharedArrayBuffer
类。使用 SharedArrayBuffer
对象,实际上可以观察到其他代理中的脚本同时执行。此外,由于JavaScript内存模型,存在一些情况不仅不能通过序列化的脚本执行来表示,而且不能通过序列化的语句执行来表示这些脚本中的内容。
本节为非规范性内容。
本规范与许多其他规范进行交互并依赖于它们。在某些情况下,不幸的是,冲突的需求导致本规范违反了这些其他规范的要求。每当发生这种情况时,违规行为都会被标注为“故意违反”,并说明违反的原因。
本节为非规范性内容。
HTML 提供了多种扩展机制,可以安全地添加语义:
作者可以使用 class
属性来扩展元素,实际上创建自己的元素,同时使用最适用的现有“真实” HTML 元素,以便浏览器和其他不知晓扩展的工具仍能较好地支持它。这就是微格式使用的方法。
作者可以通过 data-*=""
属性包含供客户端脚本或服务器端站点脚本处理的数据。这些属性保证不会被浏览器触及,允许脚本在 HTML 元素上包含数据,然后脚本可以查找和处理这些数据。
作者可以使用 <meta name="" content="">
机制包含页面范围的元数据。
作者可以使用 rel=""
机制通过注册 预定义链接类型的扩展
来注释链接的具体含义。这也被微格式使用。
作者可以使用 <script type="">
机制和自定义类型嵌入原始数据,供内联或服务器端脚本进一步处理。
作者可以使用 JavaScript 原型机制扩展 API。这被脚本库广泛使用。
作者可以使用微数据功能(itemscope=""
和
itemprop=""
属性)嵌入嵌套的名称-值对数据,以便与其他应用程序和网站共享。
作者可以定义、共享和使用 自定义元素 来扩展 HTML 的词汇。有效自定义元素名称 的要求确保了向前兼容性(因为未来不会在 HTML、SVG 或 MathML 中添加包含连字符的本地名称的元素)。
本节为非规范性内容。
本规范定义了一种用于描述文档和应用程序的抽象语言,以及一些用于与使用该语言的资源的内存表示进行交互的 API。
这种内存中的表示称为“DOM HTML”,简称“DOM”。
有多种具体语法可以用于传输使用该抽象语言的资源,其中两种在本规范中有定义。
第一种具体语法是 HTML 语法。这是建议大多数作者使用的格式。它与大多数传统网页浏览器兼容。如果文档以 text/html
MIME
类型 传输,那么它将被网页浏览器作为 HTML 文档处理。本规范定义了最新的 HTML 语法,简称“HTML”。
第二种具体语法是 XML。当文档以 XML MIME 类型(例如 application/xhtml+xml
)传输时,它将被网页浏览器视为
XML 文档,由 XML 处理器进行解析。作者需要注意 XML 和 HTML 的处理方式不同;特别是,即使是小的语法错误也会导致标记为 XML 的文档无法完全呈现,而在 HTML 语法中这些错误会被忽略。
HTML 的 XML 语法以前被称为“XHTML”,但本规范不使用该术语(其中一个原因是,MathML 和 SVG 的 HTML 语法中没有使用该术语)。
DOM、HTML 语法和 XML 语法无法完全表示相同的内容。例如,HTML 语法无法表示命名空间,但 DOM 和 XML 语法支持。类似地,使用 noscript
特性的文档可以使用 HTML 语法表示,但无法使用 DOM 或 XML 语法表示。包含字符串 "-->
" 的注释只能在 DOM 中表示,而不能在 HTML 和 XML 语法中表示。
本节为非规范性内容。
本规范分为以下主要部分:
EventSource
的服务器推送事件流机制,以及一种名为 Web Sockets 的双向全双工套接字协议。此外,还有一些附录,列出了 过时的特性 和 IANA 注意事项,以及几个索引。
阅读本规范的方法与其他规范类似。首先,应该全面阅读多次。然后,至少要反向阅读一次。接着,可以通过从目录中随机挑选章节并跟踪所有交叉引用来进行阅读。
如下面的合规要求部分所述,本规范描述了多种合规类别的合规标准。特别是,有些合规要求适用于 生产者,例如作者及其创建的文档,还有些合规要求适用于 消费者,例如网页浏览器。它们可以通过要求的内容来区分:对生产者的要求说明了允许的内容,而对消费者的要求则说明了软件应该如何行动。
例如,“foo
属性的值必须是一个 有效整数”是对生产者的要求,因为它规定了允许的值;相比之下,“foo
属性的值必须按照
解析整数的规则
进行解析”的要求是对消费者的要求,因为它描述了如何处理内容。
对生产者的要求对消费者没有任何影响。
继续上述示例,一个声明特定属性值受限于 有效整数 的要求明确地 不 意味着对消费者的要求。可能消费者实际上被要求将属性视为不透明字符串,完全不受值是否符合要求的影响。也可能(如上例所示),消费者被要求使用特定规则解析值,定义如何处理无效(在此情况下为非数字)值。
这是一个定义、要求或解释。
这是一个备注。
这是一个示例。
这是一个未解决的问题。
这是一个警告。
[Exposed =Window ]
interface Example {
// 这是一个IDL定义
};
variable = object.method([optionalArgument])
这是一个描述接口使用的注释。
/* 这是一个CSS片段 */
术语的定义实例标记为 这样。该术语的使用标记为 这样 或 这样。
元素、属性或API的定义实例标记为 这样
。对该元素、属性或API的引用标记为 这样
。
其他代码片段标记为 这样
。
变量标记为 这样。
在算法中,同步部分中的步骤标记为 ⌛。
在某些情况下,要求以带有条件和对应要求的列表形式给出。在这种情况下,适用于条件的要求始终是紧跟在条件后的第一组要求,即使对于这些要求有多个条件组。这样的情况呈现如下:
本节非规范性。
一个基本的HTML文档如下所示:
<!DOCTYPE html>
< html lang = "en" >
< head >
< title > Sample page</ title >
</ head >
< body >
< h1 > Sample page</ h1 >
< p > This is a < a href = "demo.html" > simple</ a > sample.</ p >
<!-- this is a comment -->
</ body >
</ html >
HTML文档由元素和文本构成的树状结构组成。每个元素在源代码中由一个开始标签(如“<body>
”)和一个结束标签(如“</body>
”)表示。
(在某些情况下,某些开始标签和结束标签可以省略,由其他标签隐含。)
标签必须嵌套在一起,确保所有元素完全包含在彼此之内,不可重叠:
<p>This is <em>very <strong>wrong</em>!</strong></p>
<p>This <em>is <strong>correct</strong>.</em></p>
本规范定义了一组可以在HTML中使用的元素,以及有关元素嵌套方式的规则。
元素可以具有属性,这些属性控制元素的功能。在下面的示例中,有一个超链接,
使用了a
元素及其href
属性:
<a href="demo.html">simple</a>
属性放在开始标签内,由一个名称和一个值组成,中间用"=
"字符分隔。
如果属性值不包含ASCII 空白字符或任何"
'
`
=
<
或>
,则属性值可以保持未加引号。否则,属性值必须使用单引号或双引号括起来。如果值为空字符串,则可以省略值和"=
"字符。
<!-- empty attributes -->
< input name = address disabled >
< input name = address disabled = "" >
<!-- attributes with a value -->
< input name = address maxlength = 200 >
< input name = address maxlength = '200' >
< input name = address maxlength = "200" >
HTML 用户代理(例如,网页浏览器)会解析这些标记,将其转换为 DOM(文档对象模型)树。DOM 树是文档的内存中的表示。
DOM 树包含几种类型的节点,特别是一个DocumentType
节点,Element
节点,Text
节点,Comment
节点,以及在某些情况下的ProcessingInstruction
节点。
本节顶部的标记片段将被转换为以下 DOM 树:
这个树的 文档元素 是 html
元素,这是在 HTML 文档中始终出现在该位置的元素。它包含两个元素,
head
和 body
,
以及它们之间的一个 文本
节点。
在 DOM 树中,文本
节点比最初预期的要多,因为源代码中包含了许多空格(在这里表示为“␣”)和换行符(“⏎”),这些最终都会成为 文本
节点。然而,由于历史原因,并非所有的空格和换行符在原始标记中都会出现在 DOM 中。特别是,head
起始标签之前的所有空白会被静默丢弃,
而 body
结束标签之后的所有空白则会被放置在 body
元素的末尾。
head
元素包含一个 title
元素,它本身包含一个
文本
节点,文本内容为 "Sample page"。类似地,body
元素
包含一个 h1
元素,一个 p
元素,以及一个注释。
这个 DOM 树可以通过页面中的脚本进行操作。脚本(通常是 JavaScript)是可以嵌入的程序,使用 script
元素或使用 事件处理程序内容属性 嵌入。例如,这里是一个表单和一个脚本,该脚本将表单的 output
元素的值设置为 "Hello World":
< form name = "main" >
Result: < output name = "result" ></ output >
< script >
document. forms. main. elements. result. value = 'Hello World' ;
</ script >
</ form >
DOM 树中的每个元素由一个对象表示,这些对象具有 API 以便进行操作。例如,链接(例如上面树中的 a
元素)可以通过几种方式更改其 "href
"
属性:
var a = document. links[ 0 ]; // obtain the first link in the document
a. href = 'sample.html' ; // change the destination URL of the link
a. protocol = 'https' ; // change just the scheme part of the URL
a. setAttribute( 'href' , 'https://example.com/' ); // change the content attribute directly
由于 DOM 树是用于表示 HTML 文档的方式,尤其是在交互式实现(如网页浏览器)中处理和呈现文档时,本规范大多以 DOM 树的术语来描述,而不是上面描述的标记。
HTML 文档代表了一个与媒体无关的互动内容描述。HTML 文档可能会被渲染到屏幕上,或者通过语音合成器,或者在盲文显示器上。为了精确控制渲染方式,作者可以使用样式语言,如 CSS。
在以下示例中,页面使用 CSS 被设置为黄底蓝字。
<!DOCTYPE html>
< html lang = "en" >
< head >
< title > Sample styled page</ title >
< style >
body { background : navy ; color : yellow ; }
</ style >
</ head >
< body >
< h1 > Sample styled page</ h1 >
< p > This page is just a demo.</ p >
</ body >
</ html >
有关如何使用 HTML 的更多详细信息,建议作者查阅教程和指南。虽然本规范中包含的一些示例可能也会有所帮助,但新手作者需注意,本规范为了必要性,以一种可能难以理解的细节水平定义了语言。
本节为非规范性内容。
当 HTML 被用于创建交互式网站时,需要注意避免引入漏洞,通过这些漏洞攻击者可以破坏网站自身或用户的安全。
对这一问题的全面研究超出了本文档的范围,强烈建议作者更详细地研究这一问题。然而,本节尝试提供对 HTML 应用开发中一些常见陷阱的快速介绍。
网络的安全模型基于“来源”概念,相应地,许多对网络的潜在攻击涉及跨源操作。 [ORIGIN]
在接受不可信的输入时,例如用户生成的内容如文本评论、URL 参数中的值、来自第三方网站的消息等,必须在使用之前对数据进行验证,并在显示时正确转义。否则,恶意用户可能会执行各种攻击,从可能无害的提供虚假用户信息(如负年龄),到严重的情况,例如每当用户查看包含信息的页面时运行脚本,可能在过程中传播攻击,到灾难性的情况,例如删除服务器中的所有数据。
在编写验证用户输入的过滤器时,必须确保过滤器始终基于白名单,允许已知安全的构造,拒绝所有其他输入。基于黑名单的过滤器,仅拒绝已知的恶意输入而允许其他所有输入是不安全的,因为并不是所有的恶意内容都是已知的(例如,可能是未来发明的)。
例如,假设一个页面查看其 URL 的查询字符串来确定要显示的内容,然后网站将用户重定向到该页面以显示消息,如下所示:
< ul >
< li >< a href = "message.cgi?say=Hello" > Say Hello</ a >
< li >< a href = "message.cgi?say=Welcome" > Say Welcome</ a >
< li >< a href = "message.cgi?say=Kittens" > Say Kittens</ a >
</ ul >
如果消息只是显示给用户而没有转义,恶意攻击者可能会构造一个包含脚本元素的 URL:
https://example.com/message.cgi?say=%3Cscript%3Ealert%28%27Oh%20no%21%27%29%3C/script%3E
如果攻击者成功地说服受害用户访问此页面,攻击者选择的脚本将在页面上运行。这样的脚本可以执行任何数量的恶意操作,仅受网站提供的功能的限制:例如,如果网站是电子商务商店,这样的脚本可能导致用户在不知情的情况下进行任意多的购买。
这被称为跨站脚本攻击。
有许多构造可以用来尝试欺骗网站执行代码。以下是一些作者在编写白名单过滤器时被鼓励考虑的:
img
这样的看似无害的元素时,必须对任何提供的属性进行白名单过滤。如果允许所有属性,那么攻击者可以例如使用 onload
属性来运行任意脚本。javascript:
",但用户代理可以实现(并且确实在历史上实现过)其他方案。
base
元素意味着页面中的任何带有相对链接的 script
元素都可能被劫持,同样地,任何表单提交都可能被重定向到一个恶意网站。如果网站允许用户进行具有用户特定副作用的表单提交,例如在论坛上以用户的名义发布消息、进行购买或申请护照,则必须验证请求是否确实由用户自愿发出,而不是由其他网站欺骗用户无意中发出请求。
这个问题存在是因为 HTML 表单可以提交到其他来源。
网站可以通过填充带有用户特定的隐藏令牌的表单,或通过检查 `Origin
`
头来防止此类攻击。
提供用户执行他们可能不愿意执行的操作的接口的页面需要设计得足够谨慎,以避免用户被欺骗以激活该接口。
一种用户可能被欺骗的方法是,如果恶意网站将受害网站放在一个小的 iframe
中,然后通过让用户玩反应游戏来说服用户点击。例如,一旦用户开始玩游戏,恶意网站可以快速将 iframe 定位到鼠标指针下方,正当用户准备点击时,从而欺骗用户点击受害网站的界面。
为了避免这种情况,建议不期望在框架中使用的站点仅在检测到它们不在框架中时启用其接口(例如,通过将 window
对象与 top
属性的值进行比较)。
本节为非规范性内容。
HTML 中的脚本具有“执行完成”语义,这意味着浏览器通常会在执行其他操作之前运行脚本,例如触发更多事件或继续解析文档。
另一方面,HTML 文件的解析是增量进行的,这意味着解析器可以在任何点暂停以运行脚本。这通常是有益的,但这也意味着作者需要小心,以避免在事件可能已被触发后才挂钩事件处理程序。
有两种可靠的方法可以做到这一点:使用 事件处理程序内容属性,或者在同一个脚本中创建元素并添加事件处理程序。后一种方法是安全的,因为如前所述,脚本会在进一步事件触发之前完成执行。
这种情况可能会在 img
元素和 load
事件中体现。该事件可能会在元素被解析后立即触发,特别是当图像已经被缓存时(这种情况很常见)。
在这里,作者在一个 img
元素上使用 onload
处理程序来捕捉 load
事件:
<img src="games.png" alt="Games" onload="gamesLogoHasLoaded(event)">
如果元素是由脚本添加的,只要在同一个脚本中添加事件处理程序,事件仍然不会丢失:
< script >
var img = new Image();
img. src = 'games.png' ;
img. alt = 'Games' ;
img. onload = gamesLogoHasLoaded;
// img.addEventListener('load', gamesLogoHasLoaded, false); // would work also
</ script >
然而,如果作者先创建了 img
元素,然后在一个单独的脚本中添加事件监听器,就有可能在事件触发之间丢失 load
事件:
<!-- Do not use this style, it has a race condition! -->
< img id = "games" src = "games.png" alt = "Games" >
<!-- the 'load' event might fire here while the parser is taking a
break, in which case you will not see it! -->
< script >
var img = document. getElementById( 'games' );
img. onload = gamesLogoHasLoaded; // might never fire!
</ script >
本节为非规范性内容。
建议作者使用合规检查器(也称为 验证器)来捕捉常见错误。WHATWG 维护了一个此类工具的列表:https://whatwg.org/validator/
本节为非规范性内容。
与之前版本的 HTML 规范不同,本规范详细定义了无效文档和有效文档的处理要求。
然而,即使无效内容的处理在大多数情况下是明确的,文档的合规要求仍然很重要:实际上,互操作性(即所有实现以可靠和相同或等效的方式处理特定内容)并不是文档合规要求的唯一目标。本节详细说明了仍然区分符合规范的文档和有错误的文档的一些常见原因。
本节为非规范性内容。
以前版本的 HTML 中大多数表现性特性现在已不再允许。表现性标记通常存在一些问题:
虽然可以以提供给辅助技术(AT)用户可接受体验的方式使用表现性标记(例如,使用 ARIA),但这样做比使用语义上合适的标记要困难得多。此外,即使使用这些技术,也无法帮助非 AT 用户,如文本模式浏览器用户,使页面变得可访问。
另一方面,使用与媒体无关的标记可以提供一种简单的方法,使文档能够以更适合更多用户(例如文本浏览器用户)的方式编写。
维护风格无关的站点要容易得多。例如,更改整个站点中使用 <font color="">
的颜色需要对整个站点进行更改,而对基于 CSS 的站点进行类似更改只需更改一个文件。
表现性标记往往更加冗余,因此导致文档大小更大。
由于这些原因,表现性标记在这一版本的 HTML 中已被移除。这一变化并不令人惊讶;HTML4 很多年前已弃用了表现性标记,并提供了一种模式(HTML4 Transitional)来帮助作者摆脱表现性标记;随后,XHTML 1.1 进一步将这些特性完全废弃。
HTML 中唯一剩余的表现性标记特性是 style
属性和 style
元素。style
属性在生产环境中使用有些不被推荐,但在快速原型制作(其规则可以随后直接移入单独的样式表)和在特定情况下提供特殊样式时(在这种情况下使用单独的样式表可能不方便)是有用的。类似地,style
元素在聚合或页面特定样式中可能很有用,但一般来说,当样式适用于多个页面时,外部样式表可能更为方便。
还值得注意的是,一些以前被认为是表现性的元素在本规范中被重新定义为与媒体无关:b
、i
、hr
、s
、small
和
u
。
本节为非规范性内容。
HTML 的语法被约束以避免各种问题。
某些无效的语法构造在解析时,会生成非常不直观的 DOM 树。
为了使用户代理在受控环境中使用而无需实现更奇异和复杂的错误处理规则,允许用户代理在遇到 解析错误 时失败。
一些错误处理行为,例如上面提到的 <table><hr>...
示例,不兼容流式用户代理(即以单次传递处理 HTML
文件的用户代理,不存储状态)。为了避免与这些用户代理的互操作性问题,任何导致这种行为的语法都被视为无效。
当基于 XML 的用户代理连接到 HTML 解析器时,可能会出现违反 XML 强制的某些不变性(例如,元素或属性名称从不包含多个冒号)的情况。这需要解析器将 HTML DOM 强制转换为与 XML 兼容的 infoset。大多数需要这种处理的语法构造被视为无效。(包含两个连续连字符或以连字符结尾的注释是 HTML 语法中允许的例外。)
某些语法构造可能导致性能显著下降。为了防止使用这些构造,通常会将其标记为不符合规范。
例如,以下标记导致性能下降,因为所有未闭合的 i
元素必须在每个段落中重建,从而导致每个段落中的元素逐渐增多:
< p >< i > She dreamt.
< p >< i > She dreamt that she ate breakfast.
< p >< i > Then lunch.
< p >< i > And finally dinner.
这个片段生成的 DOM 将是:
有些语法构造由于历史原因,较为脆弱。为了减少用户偶然遇到此类问题的数量,这些构造被设为不符合规范。
例如,某些命名字符引用在属性中的解析即使在省略了结束分号的情况下也会发生。可以安全地包含一个紧跟着非命名字符引用字母的与号,但如果字母被更改为一个确实形成命名字符引用的字符串,它们将被解释为该字符。
在以下片段中,属性的值是 "?bill&ted
":
< a href = "?bill&ted" > Bill and Ted</ a >
然而,在以下片段中,属性的值实际上是 "?art©
",而不是预期的
"?art©
",因为即使没有最终的分号,"©
" 也会被处理为 "©
",从而被解释为
"©
":
< a href = "?art©" > Art and Copy</ a >
为避免此问题,所有命名字符引用必须以分号结束,且未以分号结束的命名字符引用将被标记为错误。
因此,上述情况的正确表示方式如下:
< a href = "?bill&ted" > Bill and Ted</ a > <!-- &ted is ok, since it's not a named character reference -->
< a href = "?art&copy" > Art and Copy</ a > <!-- the & has to be escaped, since © is a named character reference -->
某些语法构造已知会在旧版用户代理中引发特别微妙或严重的问题,因此被标记为不符合规范,以帮助作者避免这些问题。
例如,这就是为什么 U+0060 GRAVE ACCENT 字符(`)不允许出现在未加引号的属性中。在某些旧版用户代理中,它有时被当作引号字符处理。
某些限制纯粹是为了避免已知的安全问题。
例如,限制使用 UTF-7 的规定纯粹是为了避免作者受到利用 UTF-7 的已知跨站脚本攻击的威胁。 [UTF7]
作者意图非常不明确的标记通常被标记为不符合规范。尽早纠正这些错误可以使后续维护更容易。
当用户犯简单的打字错误时,如果能够及早捕捉到错误,这将有助于节省作者大量的调试时间。因此,本规范通常将使用与规范中定义的名称不匹配的元素名称、属性名称等视为错误。
例如,如果作者输入了 <capton>
而不是 <caption>
,这将被标记为错误,作者可以立即纠正这个打字错误。
为了允许将来扩展语言语法,某些原本无害的特性被禁止。
例如,结束标签中的“属性”目前被忽略,但它们是无效的,以防将来对语言进行修改时,使用该语法特性而不与已经部署的(并且有效的!)内容冲突。
一些作者发现,总是引用所有属性并始终包括所有可选标签的做法是有帮助的,他们更倾向于从这种习惯中获得的一致性,而不是利用HTML语法的灵活性所带来的微小好处。为了帮助这些作者,符合性检查工具可以提供一种操作模式,其中强制执行这些约定。
本节是非规范性的。
除了语言的语法之外,本规范还对如何指定元素和属性进行限制。这些限制存在的原因类似:
为了避免误用具有明确意义的元素,定义了内容模型以限制元素在这种嵌套不太可能有价值的情况下的嵌套方式。
同样,为了引起作者对元素使用错误的注意,明确的语义矛盾也被视为符合性错误。
例如,在下面的片段中,语义是不合理的:分隔符不能同时是单元格,单选按钮也不能是进度条。
< hr role = "cell" >
< input type = radio role = progressbar >
另一个例子是ul
元素的内容模型限制,该模型只允许li
元素作为子元素。列表按定义仅由零个或多个列表项组成,因此如果一个ul
元素包含除li
元素以外的内容,就不清楚其含义了。
某些元素具有默认样式或行为,这使得某些组合可能会导致混淆。如果这些问题可以通过使用没有这些问题的等效替代方案来避免,则混淆的组合将不被允许。
例如,div
元素作为块盒显示,而span
元素作为行内盒显示。在一个
块盒中放置一个
行内盒是不必要的混淆;因为无论是仅嵌套div
元素,还是仅嵌套span
元素,或者在div
元素中嵌套span
元素,都可以达到相同的目的。因此,div
元素嵌套在span
元素中是被禁止的。
另一个例子是交互内容
不能嵌套。例如,button
元素不能包含textarea
元素。这是因为这种嵌套交互元素的默认行为对用户来说会非常混乱。相反,这些元素可以并排放置。
有时,一些东西被禁止是因为允许它会导致作者的混淆。
例如,将disabled
属性设置为false
是禁止的,因为尽管看起来是表示元素是启用的,但实际上表示元素是禁用的(对于实现来说,重要的是属性的存在,而不是其值)。
某些符合性错误简化了作者需要学习的语言。
例如,area
元素的shape
属性,尽管在实践中circ
和circle
值作为同义词接受,但禁止使用circ
值,以简化教程和其他学习工具。允许两者没有任何好处,但会在教授语言时引起额外的混淆。
某些元素以有些古怪的方式解析(通常是历史原因),其内容模型限制旨在避免作者暴露于这些问题。
某些错误旨在帮助防止难以调试的脚本问题。
例如,这就是为什么具有相同值的两个id
属性是非规范的。重复的ID会导致选择错误的元素,有时会导致难以确定原因的灾难性效果。
某些构造被禁止是因为它们在历史上已导致了大量的创作时间浪费,通过鼓励作者避免犯这些错误,可以在未来的工作中节省时间。
例如,一个script
元素的src
属性会导致元素的内容被忽略。然而,这并不明显,特别是当元素的内容看起来像可执行脚本时——这会导致作者花费大量时间尝试调试内联脚本,而没有意识到它没有执行。为了减少这个问题,本规范使在存在src
属性时,在script
元素中包含可执行脚本为非规范。这意味着验证其文档的作者不太可能在这种错误上浪费时间。
有些作者喜欢编写可以同时作为XML和HTML解释并具有类似结果的文件。尽管这种做法在一般情况下由于涉及的各种微妙复杂性(尤其是涉及脚本、样式或任何形式的自动化序列化)而不鼓励,但本规范有一些限制旨在至少在某种程度上缓解这些困难。这使得作者在HTML和XML语法之间迁移时可以更轻松地使用此过渡步骤。
例如,围绕lang
和xml:lang
属性的规则相对复杂,旨在保持两者同步。
另一个例子是HTML序列化中xmlns
属性值的限制,旨在确保无论是作为HTML还是XML处理,符合规范的文档中的元素最终都会位于相同的命名空间中。
与旨在允许将来修订语言的新语法的语法限制一样,对元素的内容模型和属性值的某些限制旨在允许HTML词汇的未来扩展。
例如,限制以U+005F下划线字符(_)开头的target
属性的值仅限于特定的预定义值,以便将来可以引入新的预定义值,而不会与作者定义的值冲突。
某些限制旨在支持其他规范的限制。
例如,要求使用媒体查询列表的属性仅使用有效的媒体查询列表,加强了遵循该规范的符合性规则的重要性。
本节是非规范性的。
以下文档可能对本规范的读者感兴趣。
本架构规范为规范的作者、软件开发人员和内容开发人员提供了一个共同的参考,用于在万维网上进行可互操作的文本处理,基于Unicode标准和ISO/IEC 10646共同定义的通用字符集。涉及的主题包括“字符”、“编码”和“字符串”的使用术语、参考处理模型、字符编码的选择和标识、字符转义和字符串索引。
由于Unicode包含了大量字符并结合了世界上各种书写系统,不正确的使用可能会使程序或系统面临潜在的安全攻击。这在越来越多的产品国际化时尤为重要。本文件描述了程序员、系统分析员、标准开发人员和用户应考虑的一些安全问题,并提供了具体的建议以降低问题的风险。
网页内容无障碍指南 (WCAG) 涵盖了一系列使网页内容更具可访问性的建议。遵循这些指南将使内容对更多有残疾的人更易访问,包括盲人和低视力者、聋人和听力损失者、学习障碍者、认知限制者、行动不便者、言语障碍者、光敏感者及其组合。遵循这些指南通常也会使您的网页内容对一般用户更易用。
本规范提供了设计更易于残障人士使用的网页内容创作工具的指南。符合这些指南的创作工具将通过为残障作者提供可访问的用户界面以及通过启用、支持和促进所有作者创作可访问的网页内容来促进无障碍。
本文件提供了设计用户代理的指南,以降低残障人士在网页无障碍方面的障碍。用户代理包括浏览器和其他类型的检索和呈现网页内容的软件。符合这些指南的用户代理将通过其自身的用户界面和其他内部功能(包括与其他技术(尤其是辅助技术)通信的能力)促进无障碍。此外,所有用户,不仅仅是残障用户,都会发现符合这些指南的用户代理更易用。
本规范依赖于 Infra。[INFRA]
本规范提到HTML和XML属性以及IDL属性时,通常在同一上下文中使用。当不清楚所指为何时,HTML和XML属性被称为内容属性,而IDL接口中定义的那些则被称为IDL属性。同样,"属性"一词既用于JavaScript对象属性,也用于CSS属性。当这些术语有歧义时,会分别限定为对象属性和CSS属性。
通常,当规范说明某个功能适用于HTML语法 或XML语法时,它也包括另一种语法。当某个功能仅适用于两种语言中的一种时,会明确指出它不适用于另一种格式,例如“对于HTML,...(这不适用于XML)”。
本规范使用术语文档来指代任何使用HTML的情况,从短的静态文档到带有丰富多媒体的长篇文章或报告,以及完全成熟的交互式应用程序。该术语用于指代Document
对象及其后代DOM树,以及根据上下文使用HTML语法或XML语法的序列化字节流。
在DOM结构的上下文中,术语HTML文档和XML文档按照DOM中的定义使用,特指Document
对象可能处于的两种不同模式。[DOM](此类用法总是超链接到其定义。)
在字节流的上下文中,术语HTML文档指的是标记为text/html
的资源,术语XML文档指的是标记为XML MIME类型的资源。
为了简化,术语如显示、呈现和可见有时可能用于指代文档呈现给用户的方式。这些术语并不意味着特指视觉媒介;它们必须被视为在其他媒介中具有等效的应用。
按照定义并行执行步骤,意味着这些步骤在标准中的其他逻辑(例如,事件循环)同时运行。该标准未定义实现这一目标的精确机制,无论是时间共享协作多任务处理、纤程、线程、进程、使用不同的超线程、核心、CPU、机器等。相比之下,立即运行的操作必须中断当前正在运行的任务,自己运行,然后恢复之前正在运行的任务。
有关编写利用并行处理规范的指南,请参见其他规范中的事件循环处理。
为了避免不同并行算法在操作相同数据时产生竞争条件,可以使用并行队列。
并行队列表示必须按顺序运行的一系列算法步骤。
要将步骤加入队列到并行队列,加入算法步骤到并行队列的算法队列。
要启动一个新的并行队列,请运行以下步骤:
并行运行的步骤本身可以并行运行其他步骤。例如,在并行队列内并行运行一系列步骤可能是有用的。
设想一个标准定义的nameList(一个列表),以及一个方法将name添加到nameList,除非nameList已经 包含name,在这种情况下,它将拒绝。
以下解决方案存在竞态条件:
按以下步骤并行运行:
返回p。
以上两个调用可以同时运行,这意味着在步骤 2.1 中name不在nameList中,但在步骤 2.3 运行之前,它 可能被添加,这意味着name最终在nameList中出现了两次。
并行队列解决了这个问题。标准将让nameListQueue作为 启动一个新并行队列的结果,然后:
将以下步骤加入队列到nameListQueue:
返回p。
这些步骤现在会排队,竞态得以避免。
本规范使用术语支持的来指用户代理是否具有能够解码外部资源语义的实现。当实现能够处理某种格式或类型的外部资源而不会忽略资源的关键方面时,该格式或类型被称为支持的。特定资源是否支持的可能取决于资源格式中使用的功能。
例如,如果可以解码并渲染PNG图像的像素数据,即使实现不知道图像还包含动画数据,该图像也被认为是支持的格式。
如果使用的压缩格式不支持,即使实现可以从文件的元数据中确定电影的尺寸,MPEG-4视频文件也不会被认为是支持的格式。
某些规范(特别是HTTP规范)所指的表示在本规范中被称为资源。[HTTP]
资源的关键子资源是指资源需要可用以便被正确处理的那些资源。哪些资源被认为是关键资源由定义资源格式的规范规定。
对于CSS样式表,我们在此暂时定义它们的关键子资源是通过@import
规则导入的其他样式表,包括由其他导入的样式表间接导入的样式表。
此定义尚未完全互操作;此外,一些用户代理似乎将背景图像或网页字体等资源视为关键子资源。理想情况下,CSS工作组将定义这一点;请参见w3c/csswg-drafts issue #1088以跟踪此方面的进展。
为了简化从HTML到XML的迁移,符合本规范的用户代理将在DOM和CSS的目的下,将HTML中的元素放置在http://www.w3.org/1999/xhtml
命名空间中。术语"HTML元素"指的是该命名空间中的任何元素,即使是在XML文档中。
除非另有说明,本规范中定义或提到的所有元素都在HTML命名空间
("http://www.w3.org/1999/xhtml
")中,且本规范中定义或提到的所有属性都没有命名空间。
术语元素类型用于指具有给定本地名称和命名空间的元素集。例如,button
元素是具有元素类型button
的元素,这意味着它们具有本地名称"button
",并且(如上所述隐含)在HTML命名空间中。
如果属性名称与XML中定义的Name
生产匹配,并且不包含U+003A冒号字符(:),则称这些属性名称为XML兼容。[XML]
当声明某个元素或属性被忽略,或被视为其他值,或处理为其他内容时,这仅指节点在DOM中处理的情况。在这种情况下,用户代理不得更改DOM。
只有当内容属性的新值与其先前的值不同,才说内容属性改变了值;将属性设置为它已经具有的值不会改变它。
当术语空用于属性值、文本
节点或字符串时,表示文本的长度为零(即,不包含控制字符或U+0020空格)。
HTML 元素可以具有特定的 HTML 元素插入步骤、HTML 元素连接后步骤 和 HTML 元素移除步骤,这些步骤都是根据元素的 本地名称 定义的。
HTML标准的插入步骤,给定insertedNode,定义如下:
如果insertedNode是一个元素,并且其命名空间是HTML 命名空间,并且本标准为insertedNode的本地名称定义了HTML 元素插入步骤,则运行相应的HTML 元素插入步骤,给定insertedNode。
如果insertedNode是一个不在打开元素栈中的HTML解析器的Element
,则处理内部资源链接,给定insertedNode的节点文档。
连接后的步骤对于 HTML 标准,给定 insertedNode,定义如下:
如果 insertedNode 是一个元素,并且其 命名空间是 HTML 命名空间,且本标准为 insertedNode 的 本地名称定义了HTML 元素连接后的步骤,则在给定 insertedNode 的情况下运行相应的 HTML 元素连接后的步骤。
HTML标准的移除步骤,给定removedNode和oldParent,定义如下:
令document为removedNode的节点文档。
如果document的聚焦区域是removedNode,则将document的聚焦区域设置为document的视口,并将document的相关全局对象的导航API的正在进行导航期间焦点更改设置为false。
如果removedNode是其命名空间为 HTML命名空间的元素,并且本标准为removedNode的本地名称定义了HTML元素移除步骤,则运行对应的HTML元素移除步骤,给定removedNode和oldParent。
如果removedNode的弹出框
属性不在无弹出框状态,则运行隐藏弹出框算法,给定removedNode、false、false和false。
当插入步骤以某个节点作为参数调用时,并且该节点现在在文档树中,则称该节点已插入文档。类似地,当移除步骤以某个节点作为参数调用时,并且该节点现在不再在文档树中,则称该节点已从文档中移除。
当插入步骤以某个节点作为参数调用时,并且该节点现在已连接,则该节点变为连接状态。类似地,当移除步骤以某个节点作为参数调用时,并且该节点现在不再已连接,则该节点变为断开状态。
当某个节点已连接且其包含阴影根的浏览上下文非空时,该节点是浏览上下文连接的。当插入步骤以某个节点作为参数调用时,并且该节点现在浏览上下文连接的,则该节点变为浏览上下文连接的。当移除步骤以某个节点作为参数调用时,并且该节点现在不再浏览上下文连接的,或当其包含阴影根的浏览上下文变为空时,该节点变为浏览上下文断开的。
构造 "一个 Foo
对象",其中 Foo
实际上是一个接口,有时被用于代替更准确的 "实现接口 Foo
的对象"。
当IDL属性的值被检索(例如通过作者脚本)时,称该属性正在获取值,当为其赋予新值时,称其正在设置值。
如果某个DOM对象被称为实时的,则该对象上的属性和方法必须操作实际的底层数据,而不是数据的快照。
术语插件是指由用户代理使用的一组实现定义的内容处理程序,这些处理程序可以参与用户代理对文档
对象的渲染,但既不作为文档
的子导航,也不会向文档
的DOM引入任何节点
对象。
通常,这些内容处理程序由第三方提供,但用户代理也可以将内置的内容处理程序指定为插件。
用户代理不得将类型text/plain
和application/octet-stream
视为已注册的插件。
插件的一个例子是当用户导航到PDF文件时,在导航器中实例化的PDF查看器。无论PDF查看器组件的实现方与用户代理的实现方是否相同,这都算作插件。然而,与用户代理分开的启动的PDF查看器应用程序(而不是使用相同的界面)不符合插件的定义。
本规范未定义与插件交互的机制,因为这被认为是用户代理和平台特定的。一些用户代理可能选择支持诸如Netscape插件API之类的插件机制;其他可能使用远程内容转换器或内置支持某些类型。事实上,本规范并不要求用户代理支持插件。[NPAPI]
浏览器在与外部内容(例如插件)交互时应格外小心。当第三方软件与用户代理本身具有相同的权限运行时,第三方软件中的漏洞变得与用户代理中的漏洞一样危险。
由于不同用户拥有不同的插件集提供了一个跟踪向量,增加了唯一识别用户的可能性,建议用户代理为每个用户支持完全相同的插件集。
字符编码,或在不产生歧义的情况下仅称为编码,是一种在字节流和Unicode字符串之间转换的定义方式,如编码中定义的那样。一个编码具有一个编码名称和一个或多个编码标签,在编码标准中被称为编码的名称和标签。[ENCODING]
本规范描述了与实现者相关的用户代理和与作者及创作工具实现者相关的文档的合规标准。
合规文档是指符合所有文档合规标准的文档。为了便于阅读,这些合规要求中的一些被表述为对作者的合规要求;这些要求隐含为对文档的要求:根据定义,所有文档都假定由某个作者创建。(在某些情况下,作者本身可能是用户代理——此类用户代理需要遵守下面解释的额外规则。)
例如,如果某个要求规定“作者不得使用foobar
元素”,则意味着文档中不允许包含名为foobar
的元素。
文档合规要求与实现合规要求之间没有隐含关系。用户代理不得自由处理不合规的文档;无论输入文档是否合规,本规范描述的处理模型都适用于实现。
用户代理分为几类(重叠),具有不同的合规要求。
支持XML语法的Web浏览器必须按本规范描述的方式处理XML文档中HTML命名空间中的元素和属性,以便用户可以与之交互,除非这些元素的语义已被其他规范覆盖。
一个合规的Web浏览器在XML文档中发现script
元素时,会执行该元素中包含的脚本。然而,如果该元素在用XSLT表示的转换中被找到(假设用户代理也支持XSLT),则处理器会将script
元素视为转换的一部分的透明元素。
支持HTML语法的Web浏览器必须按本规范描述的方式处理带有HTML MIME类型标签的文档,以便用户可以与之交互。
支持脚本的用户代理还必须是本规范中IDL片段的合规实现,如Web IDL中所述。[WEBIDL]
除非明确说明,覆盖HTML元素语义的规范不会覆盖表示这些元素的DOM对象的要求。例如,上述示例中的script
元素仍将实现HTMLScriptElement
接口。
纯粹为了呈现非交互式版本的HTML和XML文档的用户代理必须遵守与Web浏览器相同的合规标准,只是它们不需要遵守有关用户交互的要求。
非交互式呈现用户代理的典型例子是打印机(静态用户代理)和投影显示器(动态用户代理)。大多数静态非交互式呈现用户代理预计也会选择不支持脚本。
一个非交互但动态的呈现用户代理仍会执行脚本,允许表单动态提交等等。然而,由于用户无法与文档交互,“焦点”概念无关紧要,用户代理不需要支持任何与焦点相关的DOM API。
用户代理,无论是交互式的还是非交互式的,都可以(可能作为用户选项)被指定为支持本规范定义的建议默认渲染。
这不是强制性的。特别是,即使实现了建议的默认渲染的用户代理,也鼓励提供设置,以覆盖此默认设置,从而改善用户体验,例如改变颜色对比度,使用不同的焦点样式,或以其他方式使体验对用户更具可访问性和可用性。
指定为支持建议默认渲染的用户代理在指定时,必须实现渲染部分定义的用户代理应当实现的规则。
不支持脚本的实现(或完全禁用其脚本功能的实现)不需要支持本规范中提到的事件和DOM接口。对于以事件模型或DOM为基础定义的规范部分,此类用户代理仍必须表现得好像支持事件和DOM一样。
脚本可以构成应用程序的一个组成部分。不支持脚本的Web浏览器或禁用脚本的Web浏览器可能无法完全传达作者的意图。
合规检查器必须验证文档是否符合本规范描述的适用合规标准。自动化合规检查器不需要检测需要解释作者意图的错误(例如,虽然如果blockquote
元素的内容不是引用,文档就不合规,但没有人工判断输入的合规检查器不必检查blockquote
元素是否只包含引用材料)。
合规检查器必须在没有浏览上下文的情况下(意味着不运行脚本,解析器的脚本标志被禁用)检查输入文档的合规性,还应检查在有浏览上下文并且脚本执行时输入文档的合规性,并且脚本在执行期间不会导致除瞬态状态外的非合规状态。(这是一个“应当”而不是“必须”要求,因为它已被证明是不可能的。[COMPUTABLE])
术语“HTML验证器”可以用来指代符合本规范适用要求的合规检查器。
XML DTD无法表达本规范的所有合规要求。因此,验证XML处理器和DTD不能构成合规检查器。此外,由于本规范定义的两种创作格式都不是SGML的应用程序,因此验证SGML系统也不能构成合规检查器。
换句话说,有三种类型的合规标准:
合规检查器必须检查前两类错误。简单的基于DTD的验证器只能检查第一类错误,因此根据本规范不构成合规检查器。
为了渲 染文档或检查其合规性之外的目的处理HTML和XML文档的应用程序和工具,应根据其处理的文档的语义行事。
创作工具和标记生成器必须生成合规文档。适用于作者的合规标准在适当时也适用于创作工具。
创作工具不受严格使用元素只用于其指定目的的要求的限制,但仅限于创作工具尚无法确定作者意图的情况。然而,创作工具不得自动滥用元素或鼓励其用户这样做。
例如,使用address
元素标记任意联系信息是不合规的;该元素只能用于标记其最近的article
或body
元素祖先的联系信息。然而,由于创作工具可能无法区分,创作工具对此要求免除。这并不意味着创作工具可以将address
元素用于任何斜体文本块(例如);这仅意味着创作工具不必验证用户在插入article
元素的联系信息工具时,用户确实在插入联系信息而不是插入其他内容。
在合规检查方面,编辑器必须输出符合与合规检查器将验证的程度相同的文档。
当使用创作工具编辑不合规文档时,它可以在编辑过程中未编辑的文档部分保留合规错误(即编辑工具可以原样保存错误内容)。然而,如果错误被这样保留,创作工具不得声称输出是合规的。
创作工具预计分为两大类:基于结构或语义数据的工具和基于所见即所得的媒体特定编辑工具(WYSIWYG)。
前者是创作HTML工具的首选机制,因为源信息中的结构可以用于在HTML元素和属性的选择上做出明智的选择。
然而,所见即所得工具也是合法的。所见即所得工具应使用它们知道合适的元素,并且不应使用它们不知道合适的元素。这在某些极端情况下可能意味着将流元素的使用限制在少数几个元素,如div
,b
,i
和span
,并广泛使用style
属性。
无论是所见即所得还是其他类型的创作工具,都应尽最大努力使用户能够创建结构良好、语义丰富、与媒体无关的内容。
为了与现有内容和先前规范兼容,本规范描述了两种创作格式:一种基于XML,另一种使用自定义格式,受到SGML的启发(称为HTML语法)。实现必须至少支持这两种格式中的一种,尽管鼓励支持两者。
一些合规要求表述为对元素、属性、方法或对象的要求。这些要求分为两类:描述内容模型限制的要求和描述实现行为的要求。前者是对文档和创作工具的要求。后者是对用户代理的要求。同样,一些合规要求表述为对作者的要求;这些要求应解释为对作者生成的文档的合规要求。(换句话说,本规范不区分对作者的合规标准和对文档的合规标准。)
本规范依赖于几个其他的基础规范。
以下术语在基础结构(Infra)中定义:[INFRA]
Unicode字符集用于表示文本数据,Encoding定义了与字符编码相关的要求。 [UNICODE]
本规范引入了 基于这些规范中定义的术语,如前所述。
以下术语在Encoding中定义:[ENCODING]
支持HTML的XML语法的实现必须支持某个版本的XML及其对应的命名空间规范,因为该语法使用带有命名空间的XML序列化。[XML] [XMLNS]
在不运行脚本、不评估CSS或XPath表达式,或不将结果DOM暴露给任意内容的情况下执行内容操作的数据挖掘工具和其他用户代理,可以通过仅断言其DOM节点类似物在某些命名空间中来“支持命名空间”,而无需实际暴露命名空间字符串。
在HTML语法中,命名空间前缀和命名空间声明与XML中的效果不同。例如,冒号在HTML元素名称中没有特殊含义。
在XML命名空间中名称为space
的属性由可扩展标记语言
(XML)定义。[XML]
本规范还引用了与XML文档关联样式表中定义的<?xml-stylesheet?>
处理指令。[XMLSSPI]
本规范还非规范性地提及了XSLTProcessor
接口及其transformToFragment()
和transformToDocument()
方法。[XSLTP]
以下术语在URL中定义:[URL]
application/x-www-form-urlencoded
formatapplication/x-www-form-urlencoded
serializer本规范还引用了多个方案和协议:
about:
方案
[ABOUT]
blob:
方案
[FILEAPI]
data:
方案
[RFC2397]
http:
方案
[HTTP]
https:
方案
[HTTP]
mailto:
方案
[MAILTO]
sms:
方案
[SMS]
urn:
方案
[URN]
媒体片段语法在媒体片段URI中定义。[MEDIAFRAG]
以下术语在HTTP规范中定义:[HTTP]
Accept
` 头部Accept-Language
`
头部Cache-Control
`
头部Content-Disposition
` 头部Content-Language
`
头部Content-Range
`
头部Last-Modified
`
头部Range
` 头部Referer
` 头部以下术语在HTTP State Management Mechanism中定义:[COOKIES]
以下术语在Web Linking中定义:[WEBLINK]
以下术语在Structured Field Values for HTTP中定义:[STRUCTURED-FIELDS]
以下术语在MIME Sniffing中定义:[MIMESNIFF]
以下术语在Fetch中定义:[FETCH]
about:blank
User-Agent
`值
Origin
`头部Cross-Origin-Resource-Policy
`头部
RequestCredentials
枚举
RequestDestination
枚举
fetch()
方法以下术语在Referrer Policy中定义:[REFERRERPOLICY]
Referrer-Policy
`HTTP头
Referrer-Policy
`头解析引用者政策算法
no-referrer
`,`no-referrer-when-downgrade
`,`origin-when-cross-origin
`,`unsafe-url
`引用者政策
以下术语在Mixed Content中定义:[MIX]
以下术语在Subresource Integrity中定义:[SRI]
Paint Timing 中定义了以下术语:[PAINTTIMING]
Navigation Timing 中定义了以下术语:[NAVIGATIONTIMING]
NavigationTimingType
及其 "navigate
",
"reload
",
和 "back_forward
"
值。Resource Timing 中定义了以下术语: [RESOURCETIMING]
Performance Timeline 中定义了以下术语: [PERFORMANCETIMELINE]
Long Animation Frames 中定义了以下术语: [LONGANIMATIONFRAMES]
Long Tasks 中定义了以下术语: [LONGTASKS]
本规范中的 IDL 片段必须按照 Web IDL 的要求进行解释,以符合 IDL 片段的要求。 [WEBIDL]
以下术语在 Web IDL 中定义:
[Global]
[LegacyFactoryFunction]
[LegacyLenientThis]
[LegacyNullToEmptyString]
[LegacyOverrideBuiltIns]
[LegacyTreatNonObjectAsNull]
[LegacyUnenumerableNamedProperties]
[LegacyUnforgeable]
Web IDL 还定义了以下在本规范的 Web IDL 片段中使用的类型:
ArrayBuffer
ArrayBufferView
boolean
DOMString
double
Function
long
object
Promise
Uint8ClampedArray
unrestricted double
unsigned long
USVString
VoidFunction
本规范中术语 throw 的使用定义见 Web
IDL。DOMException
类型和以下异常名称由 Web
IDL 定义,并由本规范使用:
IndexSizeError
"HierarchyRequestError
"
InvalidCharacterError
"
NoModificationAllowedError
"
NotFoundError
"NotSupportedError
"InvalidStateError
"SyntaxError
"InvalidAccessError
"
SecurityError
"NetworkError
"AbortError
"QuotaExceededError
"
DataCloneError
"EncodingError
"NotAllowedError
"当本规范要求用户代理创建一个表示特定时间(可能是特殊值 NaN)的 Date 对象 时,该时间的毫秒部分(如果有)必须截断为整数,新创建的
Date
对象的时间值必须表示截断后的时间。
例如,给定 2000 年 1 月 1 日 01:00 UTC 后 23045 微秒的时间,即 2000-01-01T00:00:00.023045Z 的时间,则表示该时间的新创建的
Date
对象将表示与表示 2000-01-01T00:00:00.023Z 的对象相同的时间,提前 45 微秒。如果给定的时间是 NaN,则结果是表示时间值为 NaN 的 Date
对象(表示该对象不代表特定的时间点)。
本规范描述的某些语言部分仅支持 JavaScript 作为底层脚本语言。[JAVASCRIPT]
术语“JavaScript”用来指代 ECMA-262,而不是正式术语 ECMAScript,因为 JavaScript 这个术语更广为人知。
以下术语在 JavaScript 规范中定义,并在本规范中使用:
Atomics
对象
Atomics.waitAsync
对象Date
类FinalizationRegistry
类RegExp
类
SharedArrayBuffer
类
SyntaxError
类TypeError
类RangeError
类WeakRef
类
eval()
函数WeakRef.prototype.deref()
函数import()
import.meta
typeof
运算符delete
运算符
支持 JavaScript 的用户代理还必须实现 动态代码品牌检查 提案。以下术语在那里定义,并在本规范中使用: [JSDYNAMICCODEBRANDCHECKS]
支持 JavaScript 的用户代理还必须实现 ECMAScript 国际化 API。[JSINTL]
支持 JavaScript 的用户代理还必须实现 导入属性 提案。以下术语在那里定义,并在本规范中使用: [JSIMPORTATTRIBUTES]
支持 JavaScript 的用户代理还必须实现 JSON 模块 提案。以下术语在那里定义,并在本规范中使用: [JSJSONMODULES]
支持 JavaScript 的用户代理还必须实现 可调整大小的 ArrayBuffer 和可增长的 SharedArrayBuffer 提案。以下术语在那里定义,并在本规范中使用: [JSRESIZABLEBUFFERS]
支持 JavaScript 的用户代理还必须实现 Temporal 提案。以下术语在那里定义,并在本规范中使用: [JSTEMPORAL]
以下术语在 WebAssembly JavaScript Interface 中定义:[WASMJS]
文档对象模型 (DOM) 是文档及其内容的表示——一种模型。DOM 不仅仅是一个 API;HTML 实现的符合性标准在本规范中以对 DOM 的操作来定义。[DOM]
实现必须支持 DOM 和在 UI Events 中定义的事件,因为本规范是根据 DOM 定义的,并且一些功能被定义为对 DOM 接口的扩展。[DOM] [UIEVENTS]
特别地,以下功能在 DOM 中定义:[DOM]
Attr
接口CharacterData
接口Comment
接口DOMImplementation
接口Document
接口及其 doctype
属性DocumentOrShadowRoot
接口
DocumentFragment
接口DocumentType
接口ChildNode
接口Element
接口attachShadow()
方法。
Node
接口NodeList
接口ProcessingInstruction
接口ShadowRoot
接口Text
接口Range
接口
HTMLCollection
接口,其
length
属性,以及其 item()
和 namedItem()
方法
DOMTokenList
接口及其 value
属性和 supports
操作createDocument()
方法createHTMLDocument()
方法createElement()
方法
createElementNS()
方法getElementById()
方法getElementsByClassName()
方法append()
方法
appendChild()
方法cloneNode()
方法importNode()
方法preventDefault()
方法
id
属性setAttribute()
方法
textContent
属性slotchange
事件CharacterData
节点及其 replace data
算法Event
接口
Event
和派生接口的构造行为
EventTarget
接口EventInit
字典类型type
属性currentTarget
属性bubbles
属性cancelable
属性composed
属性isTrusted
属性
initEvent()
方法addEventListener()
方法EventListener
回调接口
Document
Node
及其使用的 cloning
steps 概念is
valueMutationObserver
接口及 mutation
observers 的一般概念AbortController
及其 signalAbortSignal
以下功能在 UI Events 中定义:[UI EVENTS]
MouseEvent
接口MouseEvent
接口的 relatedTarget
属性MouseEventInit
字典类型
FocusEvent
接口FocusEvent
接口的 relatedTarget
属性UIEvent
接口UIEvent
接口的 view
属性auxclick
事件beforeinput
事件click
事件contextmenu
事件dblclick
事件input
事件mousedown
事件mouseenter
事件mouseleave
事件mousemove
事件mouseout
事件mouseover
事件mouseup
事件wheel
事件keydown
事件keypress
事件keyup
事件以下功能在 Touch Events 中定义:[TOUCH]
Touch
接口touchend
事件以下功能在 Pointer Events 中定义:[POINTEREVENTS]
PointerEvent
接口PointerEvent
接口的 pointerType
属性pointerdown
事件
pointerup
事件pointercancel
事件以下事件在 Clipboard API and events 中定义:[CLIPBOARD-APIS]
本规范有时使用术语 name 来指代事件的 type;例如,“一个名为
click
的事件”或“如果事件名称是 keypress
”。术语“name”和“type”对于事件是同义的。
以下功能在 DOM Parsing and Serialization 中定义:[DOMPARSING]
以下功能在 Selection API 中定义:[SELECTION]
鼓励用户代理实现 execCommand 中描述的功能。[EXECCOMMAND]
以下功能在 Fullscreen API 中定义:[FULLSCREEN]
requestFullscreen()
fullscreenchange
High Resolution Time 提供了以下功能:[HRT]
本规范使用 File API 中定义的以下功能:[FILEAPI]
Blob
接口及其
type
属性
File
接口及其
name
和
lastModified
属性
FileList
接口Blob
的
快照状态 概念
本规范使用 Indexed Database API 定义的 清理 Indexed Database 事务。 [INDEXEDDB]
以下术语在 Media Source Extensions 中定义: [MEDIASOURCE]
以下术语在 Media Capture and Streams 中定义: [MEDIASTREAM]
MediaStream
接口以下术语在 Reporting 中定义:[REPORTING]
以下功能和术语在 XMLHttpRequest 中定义: [XHR]
XMLHttpRequest
接口及其 responseXML
属性
ProgressEvent
接口及其
lengthComputable
、loaded
和 total
属性
FormData
接口及其关联的
条目列表
以下功能在 Battery Status API 中定义:[BATTERY]
getBattery()
方法实现必须支持 Media Queries。其中定义了 <media-condition> 特性。[MQ]
虽然本规范的实现不要求完全支持 CSS(尽管我们鼓励支持,尤其是对 web 浏览器而言),但有些特性是根据特定的 CSS 要求定义的。
当本规范要求按照特定的 CSS 语法解析某些内容时,必须遵循 CSS Syntax 中相关的算法,包括错误处理规则。[CSSSYNTAX]
例如,用户代理在意外发现样式表末尾时,需要关闭所有未闭合的结构。因此,当解析字符串
"rgb(0,0,0
"(缺少闭合括号)作为颜色值时,根据此错误处理规则,闭合括号是隐含的,并且会得到一个值(颜色为 '黑色')。然而,类似的结构
"rgb(0,0,
"(既缺少括号又缺少 "蓝色" 值)不能被解析,因为闭合未闭合的结构不会得到一个有效的值。
以下术语和特性在 Cascading Style Sheets(CSS)中定义:[CSS]
基本版本的'display'属性在CSS中定义,并且该属性由其他CSS模块扩展。[CSS] [CSSRUBY] [CSSTABLE]
以下术语和功能在CSS Box Model中定义:[CSSBOX]
以下功能在CSS逻辑属性中定义:[CSSLOGICAL]
以下术语和功能在CSS颜色中定义:[CSSCOLOR]
以下术语在CSS Images中定义:[CSSIMAGES]
术语paint source在CSS Images Level 4中定义,用于定义某些HTML元素与CSS 'element()'函数的交互。[CSSIMAGES4]
以下功能在CSS Backgrounds and Borders中定义:[CSSBG]
CSS Backgrounds and Borders还定义了以下边框属性:[CSSBG]
以下功能在CSS Box Alignment中定义:[CSSALIGN]
以下术语和功能在CSS Display中定义:[CSSDISPLAY]
以下功能在CSS Flexible Box Layout中定义:[CSSFLEXBOX]
以下术语和功能在CSS Fonts中定义:[CSSFONTS]
以下功能在CSS Grid Layout中定义:[CSSGRID]
以下术语在CSS Inline Layout中定义:[CSSINLINE]
以下术语和功能在CSS Box Sizing中定义:[CSSSIZING]
以下功能在CSS Lists and Counters中定义:[CSSLISTS]
以下功能在CSS Overflow中定义:[CSSOVERFLOW]
以下术语和功能在CSS Positioned Layout中定义:[CSSPOSITION]
以下功能在CSS Multi-column Layout中定义:[CSSMULTICOL]
'ruby-base'值的'display'属性在CSS Ruby Layout中定义。[CSSRUBY]
以下功能在CSS Table中定义:[CSSTABLE]
以下功能在CSS Text中定义:[CSSTEXT]
以下功能在CSS Writing Modes中定义:[CSSWM]
以下功能在CSS Basic User Interface中定义:[CSSUI]
更新动画并发送事件算法在Web Animations中定义。[WEBANIMATIONS]
支持脚本的实现必须支持CSS对象模型。以下功能和术语在CSSOM规范中定义:[CSSOM] [CSSOMVIEW]
Screen
接口LinkStyle
接口CSSStyleDeclaration
接口
style
IDL属性
cssText
的CSSStyleDeclaration
属性
StyleSheet
接口CSSStyleSheet
接口
CSSStyleSheet
CSSStyleSheet
的规则
resize
事件scroll
事件
scrollend
事件
以下功能和术语在CSS Syntax中定义:[CSSSYNTAX]
以下术语在Selectors中定义:[SELECTORS]
以下功能在CSS Values and Units中定义:[CSSVALUES]
以下功能在CSS View Transitions中定义:[CSSVIEWTRANSITIONS]
术语style attribute在CSS Style Attributes中定义。[CSSATTR]
以下术语在CSS Cascading and Inheritance中定义:[CSSCASCADE]
CanvasRenderingContext2D
对象对字体的使用依赖于CSSFonts和Font
Loading规范中描述的功能,特别是FontFace
对象和字体来源概念。[CSSFONTS] [CSSFONTLOAD]
以下接口和术语在Geometry Interfaces中定义:[GEOMETRY]
DOMMatrix
接口及相关的m11元素、m12元素、m21元素、m22元素、m41元素和m42元素DOMMatrix2DInit
和DOMMatrixInit
字典
DOMMatrix
和从2D字典创建DOMMatrix
算法,用于DOMMatrix2DInit
或DOMMatrixInit
DOMPointInit
字典及相关的x和y成员以下术语在CSS Scoping中定义:[CSSSCOPING]
以下术语和功能在CSS Color Adjustment中定义:[CSSCOLORADJUST]
以下术语在CSS Pseudo-Elements中定义:[CSSPSEUDO]
以下术语在CSS Containment中定义:[CSSCONTAIN]
以下术语在Intersection Observer中定义:[INTERSECTIONOBSERVER]
以下术语在Resize Observer中定义:[RESIZEOBSERVER]
以下接口在WebGL规范中定义:[WEBGL]
以下接口在WebGPU中定义:[WEBGPU]
实现可能支持将WebVTT作为字幕、说明、元数据等的文本轨格式,用于媒体资源。[WEBVTT]
本规范中使用的以下术语在WebVTT中定义:
role
属性在Accessible Rich
Internet Applications(ARIA)中定义,如下角色也是:[ARIA]
此外,以下aria-*
内容属性在ARIA中定义:[ARIA]
最后,以下术语在ARIA中定义:[ARIA]
以下术语在Content Security Policy中定义:[CSP]
report-uri
directiveframe-ancestors
directivesandbox
directiveSecurityPolicyViolationEvent
接口
securitypolicyviolation
事件
以下术语在Service Workers中定义:[SW]
以下算法在Secure Contexts中定义:[SECURE-CONTEXTS]
以下术语在Permissions Policy中定义:[PERMISSIONSPOLICY]
以下功能在Payment Request API中定义:[PAYMENTREQUEST]
虽然本规范不要求全面支持MathML(尽管至少鼓励网页浏览器支持),某些功能依赖于实现MathML的一小部分。[MATHML]
以下功能在Mathematical Markup Language(MathML)中定义:
虽然本规范不要求全面支持SVG(尽管至少鼓励网页浏览器支持),但某些功能依赖于实现SVG的部分内容。
实现SVG的用户代理必须实现SVG 2规范,而不是任何早期版本。
以下功能在SVG 2规范中定义:[SVG]
SVGElement
接口
SVGImageElement
接口
SVGScriptElement
接口
SVGSVGElement
接口
a
元素desc
元素foreignObject
元素image
元素script
元素svg
元素title
元素use
元素text-rendering
属性以下功能在Filter Effects中定义:[FILTERS]
以下功能在Compositing and Blending中定义:[COMPOSITE]
以下功能在Cooperative Scheduling of Background Tasks中定义:[REQUESTIDLECALLBACK]
以下术语在Screen Orientation中定义:[SCREENORIENTATION]
以下术语在Storage中定义:[STORAGE]
以下功能在Web App Manifest中定义:[MANIFEST]
以下术语在WebAssembly JavaScript 接口:ESM 集成中定义:[WASMESM]
以下功能在WebCodecs中定义:[WEBCODECS]
以下术语在WebDriver中定义:[WEBDRIVER]
以下术语在WebDriver BiDi中定义:[WEBDRIVERBIDI]
以下术语在Web Cryptography API中定义: [WEBCRYPTO]
以下术语在WebSockets中定义:[WEBSOCKETS]
以下术语在WebTransport中定义:[WEBTRANSPORT]
以下术语在Web Authentication: An API for accessing Public Key Credentials中定义:[WEBAUTHN]
以下术语在Credential Management中定义:[CREDMAN]
以下术语在Console中定义:[CONSOLE]
以下术语在Web Locks API中定义:[WEBLOCKS]
本规范使用在Trusted Types中定义的以下功能: [TRUSTED-TYPES]
本规范并不要求支持任何特定的网络协议、样式表语言、脚本语言或超出上述列表中要求的任何 DOM 规范。然而,本规范描述的语言倾向于使用 CSS 作为样式语言,JavaScript 作为脚本语言,以及 HTTP 作为网络协议,并且多个功能假定这些语言和协议正在使用。
实现 HTTP 协议的用户代理必须同时实现HTTP State Management Mechanism(Cookies)。[HTTP] [COOKIES]
本规范可能在各自的章节中对字符编码、图像格式、音频格式和视频格式有某些额外要求。
强烈不建议对本规范进行厂商特定的专有用户代理扩展。文档不得使用此类扩展,因为这样做会降低互操作性并分裂用户群体,导致只有特定用户代理的用户才能访问相关内容。
所有扩展必须定义为使用扩展既不矛盾也不导致规范中定义的功能不合格。
例如,尽管强烈不建议这样做,但实现可以向控件添加一个新的 IDL 属性 "typeTime
",该属性返回用户选择当前控件值所花费的时间。另一方面,定义一个出现在表单的 elements
数组中的新控件将违反上述要求,因为它将违反本规范中给出的 elements
的定义。
当需要对本规范进行中立扩展时,可以相应地更新本规范,或者可以编写一个扩展规范来覆盖本规范中的要求。当某人将本规范应用于其活动时,决定认可此类扩展规范的要求时,它将成为本规范符合性要求目的的 适用规范。
有人可以编写一个规范,定义任何任意字节流都是合格的,然后声称他们的随机垃圾是合格的。然而,这并不意味着他们的随机垃圾实际上对所有人的目的都是合格的:如果其他人决定该规范不适用于他们的工作,那么他们可以很合法地说上述随机垃圾只是垃圾,根本不合格。就符合性而言,特定社区中的重要问题是该社区 同意 适用的是什么。
用户代理必须将不理解的元素和属性视为语义中性;将它们留在 DOM 中(对于 DOM 处理器),并根据 CSS 进行样式设置(对于 CSS 处理器),但不从中推断任何意义。
当某个功能的支持被禁用时(例如作为减轻安全问题的紧急措施,或为开发提供帮助,或出于性能原因),用户代理必须表现得好像他们完全不支持该功能,并且该功能未在本规范中提及。例如,如果通过 Web IDL 接口中的属性访问某个特定功能,该属性本身将从实现该接口的对象中省略——将属性留在对象上但使其返回 null 或抛出异常是不足够的。
在根据本规范描述的方式解析或创建的 HTML 文档上操作的 XPath 1.0
实现(例如,作为 document.evaluate()
API 的一部分)必须表现得好像已对 XPath 1.0 规范应用了以下编辑。
首先,删除以下段落:
节点测试中的 QName 使用表达式上下文中的命名空间声明扩展为 扩展名称。这与在开始和结束标签中为元素类型名称进行扩展的方式相同,只是未使用
xmlns
声明的默认命名空间:如果 QName 没有前缀,则命名空间 URI 为 null(这与属性名称的扩展方式相同)。如果 QName 有一个前缀,但在表达式上下文中没有命名空间声明,则这是一个错误。
然后,将其替换为以下内容:
节点测试中的 QName 使用表达式上下文中的命名空间声明扩展为扩展名称。如果 QName 有前缀,则该前缀必须在表达式上下文中有命名空间声明,并且相应的命名空间 URI 是与该前缀关联的命名空间 URI。如果 QName 有一个前缀,但在表达式上下文中没有命名空间声明,则这是一个错误。
如果 QName 没有前缀并且轴的主要节点类型是元素,则使用默认元素命名空间。否则,如果 QName 没有前缀,则命名空间 URI 为 null。默认元素命名空间是 XPath 表达式上下文的成员。在通过 DOM3 XPath API 执行 XPath 表达式时,默认元素命名空间的值按以下方式确定:
- 如果上下文节点来自 HTML DOM,则默认元素命名空间为 "http://www.w3.org/1999/xhtml"。
- 否则,默认元素命名空间 URI 为 null。
这相当于将 XPath 2.0 的默认元素命名空间功能添加到 XPath 1.0 中,并将 HTML 命名空间用作 HTML 文档的默认元素命名空间。这样做的目的是希望实现能够与遗留 HTML 内容兼容,同时支持本规范引入的有关 HTML 元素使用的命名空间的更改,并希望使用 XPath 1.0 而不是 XPath 2.0。
此更改是 XPath 1.0 规范的故意违反,目的是希望实现能够与遗留内容兼容,同时支持本规范引入的有关 HTML 元素使用的命名空间的更改。[XPATH10]
当输出方法为 "html"(无论是显式还是通过 XSLT 1.0 中的默认规则)时,将输出到 DOM 的 XSLT 1.0 处理器受以下影响:
如果转换程序输出的元素没有命名空间,则处理器在构造相应的 DOM 元素节点之前,必须将该元素的命名空间更改为HTML 命名空间,将元素的本地名称转换为 ASCII 小写,并将元素上的任何非命名空间属性的名称转换为 ASCII 小写。
此要求是 XSLT 1.0 规范的故意违反,因为本规范更改了 HTML 的命名空间和大小写规则,否则这将与基于 DOM 的 XSLT 转换不兼容。(序列化输出的处理器不受影响。)[XSLT10]
本规范未明确说明 XSLT 处理如何与HTML
解析器基础结构交互(例如,XSLT 处理器是否表现为将任何元素放入打开元素堆栈)。然而,XSLT 处理器在成功完成时必须停止解析,并且在中止时必须首先将当前文档的准备状态更新为
"interactive
",然后更新为 "complete
"。
本规范未规定 XSLT 如何与导航算法、如何适应事件循环以及如何处理错误页面(例如,是否用 XSLT 错误替换增量 XSLT 输出,或内联呈现等)。
在 script 元素部分中以及在 template 元素部分中,还对 XSLT 和 HTML 以及 XSLT、XPath 和 HTML 的交互进行了额外的非规范性注释。
Headers/Permissions-Policy/document-domain
仅在一个引擎中支持。
本文档定义了以下策略控制的功能:
Headers/Feature-Policy/autoplay
Headers/Permissions-Policy/autoplay
仅在一个引擎中支持。
HTML 中有很多地方接受特定的数据类型,例如日期或数字。本节描述了这些格式内容的符合性标准以及如何解析它们。
强烈建议实现者仔细检查可能考虑使用的任何第三方库,以实现以下描述的语法解析。例如,日期库可能会实现与本规范要求不同的错误处理行为,因为描述类似于本规范中使用的日期语法的规范中通常未定义错误处理行为,因此实现往往在如何处理错误方面存在很大差异。
下面描述的一些微解析器遵循一种模式,即具有一个保存解析字符串的 input 变量,以及一个指向 input 中下一个要解析的字符的 position 变量。
有许多属性是 布尔属性。元素上存在布尔属性表示真值,而不存在该属性表示假值。
如果该属性存在,其值必须是空字符串或与属性规范名称进行 ASCII 大小写不敏感 匹配的值,且没有前导或尾随空格。
布尔属性上不允许使用值 "true" 和 "false"。要表示假值,必须完全省略该属性。
以下是一个已选中且禁用的复选框示例。checked
和 disabled
属性是布尔属性。
< label >< input type = checkbox checked name = cheese disabled > Cheese</ label >
这也可以等效地写成这样:
< label >< input type = checkbox checked = checked name = cheese disabled = disabled > Cheese</ label >
你也可以混合使用样式;以下内容仍然等效:
< label >< input type = 'checkbox' checked name = cheese disabled = "" > Cheese</ label >
一些属性称为枚举属性,它们取一组有限的状态。此类属性的状态通过将属性值、每个属性规范中给出的关键字/状态映射集和属性规范中可能给出的两种特殊状态结合起来得出。这些特殊状态是无效值默认值和缺失值默认值。
多个关键字可以映射到同一状态。
空字符串可以是有效的关键字。注意,缺失值默认值仅在属性缺失时适用,而不是当它以空字符串值存在时。
要确定属性的状态,请使用以下步骤:
如果未指定该属性:
如果属性的值与为该属性定义的关键字之一进行ASCII大小写不敏感匹配,则返回该关键字表示的状态。
不返回任何状态。
出于编写符合性目的,如果指定了枚举属性,则属性的值必须与该属性的一个合规关键字进行ASCII大小写不敏感匹配,且没有前导或尾随空格。
出于反射目的,有任何关键字映射到的状态被称为具有规范关键字。其确定方式如下:
如果只有一个关键字映射到给定状态,则为该关键字。
如果只有一个合规关键字映射到给定状态,则为该合规关键字。
否则,该状态的规范关键字将在属性规范中明确给出。
如果一个字符串由一个或多个ASCII数字组成,并且可以选择以U+002D连字符-字符(-)为前缀,则该字符串是有效整数。
没有U+002D连字符-前缀的有效整数表示由该数字字符串表示的十进制数。有U+002D连字符-前缀的有效整数表示由跟随U+002D连字符-的数字字符串表示的十进制数,从零减去。
解析整数的规则如下所示。当调用时,必须按给定顺序执行步骤,在返回值的第一个步骤中中止。该算法将返回一个整数或一个错误。
令input为正在解析的字符串。
令position为input中的指针,最初指向字符串的开头。
令sign的值为“positive”。
跳过ASCII空白字符在input中给定position。
如果position超过input的末尾,则返回错误。
如果position指示的字符(第一个字符)是U+002D连字符-字符(-):
否则,如果position指示的字符(第一个字符)是U+002B加号字符(+):
+
”被忽略,但它不符合规范。)如果position指示的字符不是ASCII数字,则返回错误。
收集一系列代码点,这些代码点是input中给定position的ASCII数字,并将结果序列解释为十进制整数。令value为该整数。
如果sign为“positive”,则返回value,否则返回从零减去value的结果。
如果一个字符串由一个或多个ASCII数字组成,则该字符串是有效非负整数。
一个有效非负整数表示由该数字字符串表示的十进制数。
解析非负整数的规则如下所示。当调用时,必须按给定顺序执行步骤,在返回值的第一个步骤中中止。该算法将返回零、正整数或错误。
令input为正在解析的字符串。
令value为使用解析整数的规则解析input的结果。
如果value是一个错误,则返回错误。
如果value小于零,则返回错误。
返回value。
如果一个字符串包含以下内容,则该字符串是有效浮点数:
可选的U+002D HYPHEN-MINUS字符(-)。
以下两项之一或两项,按给定顺序:
可选的:
U+0065拉丁小写字母E字符(e)或U+0045拉丁大写字母E字符(E)。
可选的U+002D HYPHEN-MINUS字符(-)或U+002B PLUS SIGN字符(+)。
一系列一个或多个ASCII数字。
一个有效浮点数表示通过将有效数字乘以10的指数次方获得的数,其中有效数字是第一个数,解释为十进制(包括小数点和小数点后的数字,如果有的话,并解释为负数,如果整个字符串以U+002D HYPHEN-MINUS字符(-)开头并且该数字不为零),其中指数是E之后的数字,如果有的话(如果在E和数字之间有U+002D HYPHEN-MINUS字符(-)并且该数字不为零,则解释为负数,或者如果在E和数字之间有U+002B PLUS SIGN字符(+),则忽略该字符)。如果没有E,则指数视为零。
无穷大和非数字(NaN)值不是有效浮点数。
有效浮点数的概念通常仅用于限制作者允许的内容,而用户代理要求使用以下解析浮点数值的规则(例如,max
属性的progress
元素)。但是,在某些情况下,用户代理要求包括检查字符串是否为有效浮点数(例如,值清理算法的数字状态的input
元素,或解析srcset属性的算法)。
作为浮点数的最佳表示是运行ToString(n)获得的字符串。抽象操作ToString不是唯一确定的。当存在多个可能的字符串可以从ToString获得特定值时,用户代理必须始终返回该值的相同字符串(尽管它可能与其他用户代理使用的值不同)。
解析浮点数值的规则如下所示。该算法必须在返回值的第一个步骤中中止。该算法将返回数字或错误。
令input为正在解析的字符串。
令position为指向input的指针,最初指向字符串的开头。
令value的值为1。
令divisor的值为1。
令exponent的值为1。
跳过ASCII空白,在input中给定position。
如果position超过input的末尾,则返回错误。
如果position指示的字符是U+002D HYPHEN-MINUS字符(-):
否则,如果position指示的字符(第一个字符)是U+002B PLUS SIGN字符(+):
+
”被忽略,但不符合规范。)如果position指示的字符是U+002E FULL STOP(.),并且不是input中的最后一个字符,并且position指示的字符后的字符是ASCII数字,则 将value设为零并跳转到标记为fraction的步骤。
如果position指示的字符不是ASCII数字,则返回错误。
收集一系列代码点,这些代码点是ASCII数字,从input中给定position,并将结果序列解释为十进制整数。将value乘以该整数。
Fraction:如果position指示的字符是U+002E FULL STOP(.),请运行这些子步骤:
将position前移到下一个字符。
如果position超过input的末尾,或者position指示的字符不是ASCII数字,U+0065拉丁小写字母E(e),或U+0045拉丁大写字母E(E),则跳转到标记为conversion的步骤。
如果position指示的字符是U+0065拉丁小写字母E字符(e)或U+0045拉丁大写字母E字符(E),则跳过这些子步骤的其余部分。
Fraction loop:将divisor乘以10。
将position前移到下一个字符。
如果position超过input的末尾,则跳转到标记为conversion的步骤。
如果position指示的字符是ASCII数字,则跳回这些子步骤中标记为fraction loop的步骤。
如果position指示的字符是U+0065(e)或U+0045(E),则:
将position前移到下一个字符。
如果position超过input的末尾,则跳转到标记为conversion的步骤。
如果position指示的字符是U+002D HYPHEN-MINUS字符(-):
如果position超过input的末尾,则跳转到标记为conversion的步骤。
否则,如果position指示的字符是U+002B PLUS SIGN字符(+):
如果position超过input的末尾,则跳转到标记为conversion的步骤。
如果position指示的字符不是ASCII数字,则跳转到标记为conversion的步骤。
收集一系列代码点,这些代码点是ASCII数字,从input中给定position,并将结果序列解释为十进制整数。将exponent乘以该整数。
将value乘以10的exponent次方。
Conversion:令S为一组有限的IEEE 754双精度浮点值,除了-0,但增加了两个特殊值:21024和-21024。
令rounded-value为S中最接近value的数,如果有两个同样接近的值,则选择有效数字为偶数的数。(这两个特殊值21024和-21024被视为具有偶数有效数字)。
如果rounded-value是21024或-21024,则返回错误。
返回rounded-value。
解析尺寸值的规则如下所示。调用时,必须按给定顺序执行这些步骤,在返回值的第一个步骤中中止。该算法将返回大于或等于0.0的数字或失败;如果返回数字,则进一步分类为百分比或长度。
令input为正在解析的字符串。
令position为input的位置变量,最初指向input的开头。
跳过ASCII空白,在input中给定position。
如果position超过input的末尾或input中position处的代码点不是ASCII数字,则返回失败。
收集一系列代码点,这些代码点是ASCII数字,从input中给定position,并将结果序列解释为十进制整数。令value为该数字。
如果position超过input的末尾,则返回value作为长度。
如果input中position处的代码点是U+002E (.),则:
返回带有value、input和position的当前尺寸值。
给定value、input和position,确定当前尺寸值如下:
如果position超过input的末尾,则返回value作为长度。
如果input中position处的代码点是U+0025 (%),则返回value作为百分比。
返回value作为长度。
解析非零尺寸值的规则如下所示。调用时,必须按给定顺序执行这些步骤,在返回值的第一个步骤中中止。该算法将返回大于0.0的数字或错误;如果返回数字,则进一步分类为百分比或长度。
令input为正在解析的字符串。
令value为使用解析尺寸值的规则解析input的结果。
如果value是错误,则返回错误。
如果value为零,则返回错误。
如果value是百分比,则返回value作为百分比。
返回value作为长度。
一个有效的浮点数列表是由U+002C逗号字符分隔的多个有效的浮点数,不包含其他字符(例如没有ASCII空白字符)。此外,还可能对可以给出的浮点数的数量或允许的值范围有限制。
解析浮点数列表的规则如下:
令input为正在解析的字符串。
令position为input中的一个指针,初始指向字符串的开始。
令numbers为一个初始为空的浮点数列表。该列表将是此算法的结果。
收集一系列代码点,这些代码点是input中的ASCII空白字符、U+002C逗号或U+003B分号字符,位置由position指示。此操作会跳过任何前导分隔符。
当position未越过input的末尾时:
收集一系列代码点,这些代码点不是ASCII空白字符、U+002C逗号、U+003B分号、ASCII数字、U+002E句号或U+002D连字符,位置由position指示。这会跳过前导的无效字符。
收集一系列代码点,这些代码点不是ASCII空白字符、U+002C逗号或U+003B分号字符,位置由position指示,并将结果命名为unparsed number。
使用解析浮点数值的规则解析unparsed number,得到number。
如果number是错误,则将number设为零。
将number附加到numbers中。
收集一系列代码点,这些代码点是input中的ASCII空白字符、U+002C逗号或U+003B分号字符,位置由position指示。这会跳过分隔符。
返回numbers。
解析维度列表的规则如下。这些规则返回零个或多个由一个数字和一个单位组成的对,其中单位可以是百分比、相对或绝对。
令raw input为正在解析的字符串。
如果raw input的最后一个字符是U+002C逗号字符(,),则移除该字符。
按逗号分割字符串raw input。令raw tokens为结果的标记列表。
令result为一个空的数字/单位对列表。
对于raw tokens中的每个标记,运行以下子步骤:
令input为该标记。
令position为input中的一个指针,初始指向字符串的开始。
令value为数字0。
令unit为绝对。
如果position已超出input的末尾,则将unit设为相对并跳至最后一个子步骤。
如果position处的字符是ASCII数字,则收集一系列代码点,这些代码点是input中的ASCII数字,将结果解释为一个以十进制表示的整数,并将value增加该整数。
如果position处的字符是U+002E(.),则:
跳过ASCII空白字符,在input中的position。
如果position处的字符是U+0025百分号字符(%),则将unit设为百分比。
否则,如果position处的字符是U+002A星号字符(*),则将unit设为相对。
将一个由value给定的数字和unit给定的单位组成的条目添加到result中。
返回列表result。
在以下算法中,年份year的月份month中的天数为:如果month是1、3、5、7、8、10或12,则为31;如果month是4、6、9或11,则为30;如果month是2且year是能被400整除的数,或year是能被4整除但不能被100整除的数,则为29;否则为28。这考虑到了格里高利历中的闰年。[GREGORIAN]
当在本节定义的日期和时间语法中使用ASCII数字时,它们表示十进制的数字。
虽然此处描述的格式旨在作为相应ISO8601格式的子集,但本规范对解析规则的定义比ISO8601更详细。因此,建议实现者在使用任何日期解析库来实现以下描述的解析规则之前仔细检查这些库;ISO8601库可能不会以完全相同的方式解析日期和时间。[ISO8601]
本规范所指的前置格里高利历指的是现代格里高利历,向前推算到1年。前置格里高利历中的日期,有时明确称为前置格里高利日期,即使用该历法描述的日期,即使该历法在当时(或地点)尚未使用。[GREGORIAN]
在本规范中使用格里高利历作为线格式是由于参与决策的人员的文化偏见而做出的任意选择。另请参阅讨论日期、时间和数字格式的部分(作者部分)、有关表单控件本地化的实现注释,以及time
元素。
月份由一个特定的前置格里高利日期组成,没有时区信息,并且日期信息仅限于年份和月份。[GREGORIAN]
如果字符串包含以下顺序的组件,则表示一个年份year和月份month的有效月份字符串:
解析月份字符串的规则如下。这将返回一个年份和月份,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。
令input为要解析的字符串。
令position为指向input的指针,最初指向字符串的开始。
解析月份组件以获得year和month。如果返回为空,则失败。
如果position不在input的结尾之外,则失败。
返回year和month。
解析月份组件的规则如下,给定一个input字符串和一个position。这将返回一个年份和月份,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。
收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不足四个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为year。
如果year不是大于零的数值,则失败。
如果position超出input的结尾或position处的字符不是U+002D连字符,则失败。否则,将position前移一个字符。
收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不正好是两个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为month。
如果month不是范围在1 ≤ month ≤ 12之间的数值,则失败。
返回year和month。
日期由一个特定的前置格里高利日期组成,没有时区信息,由年、月和日组成。[GREGORIAN]
如果字符串包含以下顺序的组件,则表示一个年份year、月份month和日期day的有效日期字符串:
解析日期字符串的规则如下。这将返回一个日期,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。
令input为要解析的字符串。
令position为指向input的指针,最初指向字符串的开始。
解析日期组件以获得year、month和day。如果返回为空,则失败。
如果position不在input的结尾之外,则失败。
令date为具有year、month和day的日期。
返回date。
解析日期组件的规则如下,给定一个input字符串和一个position。这将返回一个年份、月份和日期,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。
解析月份组件以获得year和month。如果返回为空,则失败。
令maxday为该年该月的天数。
如果position超出input的结尾或position处的字符不是U+002D HYPHEN-MINUS字符,则失败。否则,将position前移一个字符。
收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不正好是两个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为day。
如果day不是范围在1 ≤ day ≤ maxday之间的数值,则失败。
返回year、month和day。
无年份的日期由一个公历月份和该月份中的一天组成,但没有关联的年份信息。[GREGORIAN]
如果字符串包含以下顺序的组件,则表示一个月份month和日期day的有效无年份日期字符串:
换句话说,如果month是“02
”,表示二月,那么日期可以是29日,就像该年份是闰年一样。
解析无年份日期字符串的规则如下。这将返回一个月份和日期,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。
令input为要解析的字符串。
令position为指向input的指针,最初指向字符串的开始。
解析无年份日期组件以获得month和day。如果返回为空,则失败。
如果position不在input的结尾之外,则失败。
返回month和day。
解析无年份日期组件的规则如下,给定一个input字符串和一个position。这将返回一个月份和日期,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。
收集一系列码点,这些码点是input中的U+002D HYPHEN-MINUS字符(-),根据position。如果收集的序列长度不正好是零个或两个字符,则失败。
收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不正好是两个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为month。
如果month不是范围在1 ≤ month ≤ 12之间的数值,则失败。
令maxday为该月份的天数,以任意闰年(例如4或2000年)为准。
如果position超出input的结尾或position处的字符不是U+002D HYPHEN-MINUS字符,则失败。否则,将position前移一个字符。
收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不正好是两个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为day。
如果day不是范围在1 ≤ day ≤ maxday之间的数值,则失败。
返回month和day。
时间由具体的时间组成,不包含时区信息,包括小时、分钟、秒和秒的小数部分。
如果字符串包含以下顺序的组件,则表示一个小时hour、分钟minute和秒second的有效时间字符串:
秒second组件不能为60或61;无法表示闰秒。
解析时间字符串的规则如下。这将返回一个时间或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。
令input为要解析的字符串。
令position为指向input的指针,最初指向字符串的开始。
解析时间组件以获得hour、minute和second。如果返回为空,则失败。
如果position不在input的结尾之外,则失败。
令time为具有小时hour、分钟minute和秒second的时间。
返回time。
解析时间组件的规则如下,给定一个input字符串和一个position。这将返回一个小时、分钟和秒,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。
收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不正好是两个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为hour。
如果hour不是范围在0 ≤ hour ≤ 23之间的数值,则失败。
如果position超出input的结尾或position处的字符不是U+003A COLON字符,则失败。否则,将position前移一个字符。
收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不正好是两个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为minute。
如果minute不是范围在0 ≤ minute ≤ 59之间的数值,则失败。
令second为0。
如果position不在input的结尾之外且position处的字符是U+003A COLON字符(:),则:
将position前移至input中的下一个字符。
如果position超出input的结尾,或在input的最后一个字符,或如果position开始的两个字符都不是ASCII数字,则失败。
收集一系列码点,这些码点是input中的ASCII数字或U+002E FULL STOP字符。根据position。如果收集的序列长度为三字符,或如果它长于三字符并且第三个字符不是U+002E FULL STOP字符,或如果它包含多个U+002E FULL STOP字符,则失败。否则,将结果序列解释为十进制数(可能包含小数部分)。将second设置为该数值。
如果second不是范围在0 ≤ second < 60之间的数值,则失败。
返回hour、minute和second。
本地日期和时间由一个特定的前置格里高利日期(包括年份、月份和日期)和一个时间(包括小时、分钟、秒和秒的小数部分)组成,但不包含时区信息。[GREGORIAN]
如果字符串包含以下顺序的组件,则表示日期和时间的有效本地日期和时间字符串:
如果字符串包含以下顺序的组件,则表示日期和时间的有效规范化本地日期和时间字符串:
解析本地日期和时间字符串的规则如下。这将返回一个日期和时间,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。
令input为要解析的字符串。
令position为指向input的指针,最初指向字符串的开始。
解析日期组件以获得year、month和day。如果返回为空,则失败。
如果position超出input的结尾或position处的字符既不是U+0054拉丁大写字母T字符(T)也不是U+0020空格字符,则失败。否则,将position前移一个字符。
解析时间组件以获得hour、minute和second。如果返回为空,则失败。
如果position不在input的结尾之外,则失败。
令date为具有年份year、月份month和日期day的日期。
令time为具有小时hour、分钟minute和秒second的时间。
返回date和time。
时区偏移由若干小时和分钟组成。
如果字符串符合以下任意一种情况,则表示一个有效的时区偏移字符串:
一个U+005A拉丁大写字母Z字符(Z),仅在时区为UTC时允许
或者,以下顺序的组件:
此格式允许时区偏移范围为-23:59到+23:59。目前,实际时区的偏移范围为-12:00到+14:00,且偏移的分钟部分通常为00、30或45。然而,由于时区是政治因素的产物,可能会发生变化。
有关使用时区偏移表示历史时间的详细信息,请参阅全局日期和时间部分中的使用说明和示例。
解析时区偏移字符串的规则如下。这将返回一个时区偏移,或者不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。
令input为要解析的字符串。
令position为指向input的指针,最初指向字符串的开始。
解析时区偏移组件以获得timezonehours和timezoneminutes。如果返回无,则失败。
如果position未超出input的结尾,则失败。
返回与UTC相差timezonehours小时和timezoneminutes分钟的时区偏移。
解析时区偏移组件的规则如下,给定一个input字符串和一个position。这将返回时区小时和分钟,或者不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。
如果position处的字符为U+005A拉丁大写字母Z字符(Z),则:
令timezonehours为0。
令timezoneminutes为0。
将position前移到input中的下一个字符。
否则,如果position处的字符是U+002B加号(+)或U+002D连字符(-),则:
如果position处的字符是U+002B加号(+),则令sign为“positive”。否则,它是U+002D连字符(-);令sign为“negative”。
将position前移到input中的下一个字符。
如果s恰好为两个字符长,则:
将s解释为十进制整数。令该数为timezonehours。
如果position超出input的结尾或position处的字符不是U+003A冒号字符,则失败。否则,将position前移一个字符。
收集从position开始的input中ASCII数字序列。如果收集的序列不恰好为两个字符长,则失败。否则,将结果序列解释为十进制整数。令该数为timezoneminutes。
如果s恰好为四个字符长,则:
将s的前两个字符解释为十进制整数。令该数为timezonehours。
将s的后两个字符解释为十进制整数。令该数为timezoneminutes。
否则,失败。
否则 ,失败。
返回timezonehours和timezoneminutes。
全球日期和时间包括一个特定的 前置格里高利日期,包括年份、月份和日期,以及时间,包括小时、分钟、秒和秒的小数部分,用时区偏移量表示,包括一个带符号的小时数和分钟数。 [GREGORIAN]
如果一个字符串包含以下顺序的组件,则表示一个日期、时间和时区偏移量,它是一个有效的全球日期和时间字符串:
在20世纪中期UTC形成之前的日期中的时间必须用UT1(在0°经度的当代地球太阳时间)表示和解释,而不是UTC(以SI秒计时的UT1的近似)。在时区形成之前的时间必须用显式时区的UT1时间表示和解释,这些时区近似于当代格林威治伦敦所在地时间和适当本地时间之间的差异。
以下是一些用有效全球日期和时间字符串书写的日期示例。
0037-12-13 00:00Z
"1979-10-14T12:00:00.001-04:00
"8592-01-01T02:09+02:09
"这些日期有几个显著之处:
T
"被替换为一个空格,它必须是一个单一的空格字符。字符串"2001-12-21 12:00Z
"(组件之间有两个空格)不会被成功解析。
解析全球日期和时间字符串的规则如下。这将返回UTC时间,以及用于回溯或显示目的的相关时区偏移信息,或什么也不返回。如果算法中任何一点指出它"失败",这意味着它在该点中止并返回什么也没有。
让input成为被解析的字符串。
让position成为input中的一个指针,最初指向字符串的开始。
解析日期组件以获得year、month和day。如果没有返回值,则失败。
如果position超出input的末尾或position处的字符既不是U+0054拉丁大写字母T字符(T),也不是U+0020空格字符,则失败。否则,将position向前移动一个字符。
解析时间组件以获得hour、minute和second。如果没有返回值,则失败。
如果position超出input的末尾,则失败。
解析时区偏移组件以获得timezonehours和timezoneminutes。如果没有返回值,则失败。
如果position不超出input的末尾,则失败。
让time成为year年、month月、day日、hour时、minute分、second秒的时间,减去timezonehours小时和timezoneminutes分钟。这个时间点是UTC时区的时间点。
让timezone成为比UTC快timezonehours小时和timezoneminutes分钟的时区偏移量。
返回time和timezone。
周由一个周年编号和一个周编号组成,表示一个从星期一开始的七天周期。在该日历系统中,每个周年有52或53个这样的七天周期,如下所定义。1969年12月29日(1969-12-29)格里高利日期的星期一被定义为1970年周年的第1周。连续的周按顺序编号。周年编号为1的前一周是前一个周年的最后一周,反之亦然。[GREGORIAN]
如果一个周年编号year对应于一个在前置格里高利日历中以星期四(1月1日)为第一天的年份,或一个在前置格里高利日历中以星期三(1月1日)为第一天且year是400的倍数或4的倍数但不是100的倍数的年份,则该周年编号year有53周。所有其他周年编号都有52周。
一个有53周的周年最后一天的周编号为53;一个有52周的周年最后一天的周编号为52。
一个特定日期的周年编号可能与包含该日期的年份在前置格里高利日历中的编号不同。周年y的第一周是包含格里高利年y的第一个星期四的那一周。
对于现代用途,这里定义的周等同于ISO 8601中定义的ISO周。[ISO8601]
如果一个字符串包含以下顺序的组件,则表示一个周年编号year和周week,它是一个有效的周字符串:
解析周字符串的规则如下。这将返回一个周年编号和周编号,或者返回空值。如果在任何时候算法指示"失败",这意味着它在该点中止并返回空值。
令input为被解析的字符串。
令position为input中的指针,最初指向字符串的开头。
收集一系列代码点,这些代码点是ASCII数字,从position处的input中收集。如果收集到的序列不超过四个字符,则失败。否则,将结果序列解释为十进制整数。令该数为year。
如果year不是大于零的数字,则失败。
如果position超出input的末尾或position处的字符不是U+002D连字符,则失败。否则,将position向前移动一个字符。
如果position超出input的末尾或position处的字符不是U+0057拉丁大写字母W字符,则失败。否则,将position向前移动一个字符。
收集一系列代码点,这些代码点是ASCII数字,从position处的input中收集。如果收集到的序列不是恰好两个字符,则失败。否则,将结果序列解释为十进制整数。令该数为week。
令maxweek为年份year的最后一天的周编号。
如果week不是1 ≤ week ≤ maxweek范围内的数字,则失败。
如果position未超出input的末尾,则失败。
返回周年编号year和周编号week。
持续时间由若干秒组成。
由于月份和秒不可比较(一个月不是一个精确的秒数,而是一个其精确长度取决于从何时开始测量的时间段),本规范中定义的持续时间不能包括月份(或等同于十二个月的年份)。只能描述特定秒数的持续时间。
如果字符串符合以下任一形式,则表示持续时间t,且该字符串为有效持续时间字符串:
一个U+0050拉丁大写字母P字符,后跟以下子组件之一或多个,按给定顺序,其中天数、小时、分钟和秒数对应于t中的相同秒数:
一个或多个ASCII数字,后跟一个U+0044拉丁大写字母D字符,表示天数。
一个U+0054拉丁大写字母T字符,后跟以下子组件之一或多个,按给定顺序:
这与本规范中定义的其他一些日期和时间相关的微语法一样,基于ISO 8601定义的格式之一。[ISO8601]
一个或多个持续时间时间组件,每个组件具有不同的持续时间时间组件刻度,顺序不限;表示的秒数总和等于t中的秒数。
持续时间时间组件是一个字符串,由以下组件组成:
零个或多个ASCII空白字符。
一个或多个ASCII数字,表示若干时间单位,按指定的持续时间时间组件刻度(见下文)缩放,以表示若干秒。
如果指定的持续时间时间组件刻度为1(即单位为秒),则可选地,一个U+002E全停止符(.),后跟一个、两个或三个ASCII数字,表示秒的小数部分。
零个或多个ASCII空白字符。
以下字符之一,表示时间单位的持续时间时间组件刻度:
零个或多个ASCII空白字符。
这不是基于ISO 8601中的任何格式。它旨在成为ISO 8601持续时间格式的更易于理解的替代方案。
解析持续时间字符串的规则如下。这将返回一个持续时间或返回空值。如果在任何时候算法指示"失败",这意味着它在该点中止并返回空值。
令input为被解析的字符串。
令position为input中的指针,最初指向字符串的开头。
令months、seconds和component count均为零。
令M-disambiguator为minutes。
此标志的另一个值为months。它用于消除ISO8601持续时间中"M"单位的歧义,这些持续时间使用相同的单位表示月份和分钟。月份不允许,但解析为了未来的兼 容性,并避免误解在其他上下文中有效的ISO8601持续时间。
跳过ASCII空白字符在input中给定position。
如果position超出input的末尾,则失败。
如果input中position指向的字符是U+0050拉丁大写字母P字符,则将position前进到下一个字符,将M-disambiguator设置为months,并跳过ASCII空白字符在input中给定position。
当条件为真时,执行以下操作:
令units未定义。它将被赋值为以下值之一:years、months、weeks、days、hours、minutes和seconds。
令next character未定义。它用于处理input中的字符。
如果position超出input的末尾,则中断。
如果input中position指向的字符是U+0054拉丁大写字母T字符,则将position前进到下一个字符,将M-disambiguator设置为minutes,跳过ASCII空白字符在input中给定position,并继续。
将next character设置为input中position指向的字符。
如果next character是U+002E全停止符(.),则令N等于零。(不要前进position。稍后会处理这一点。)
否则,如果next character是ASCII数字,则收集一系列代码点,这些代码点是ASCII数字,从position处的input中收集,将结果序列解释为十进制整数,并将N设置为该数。
否则,next character不是数字的一部分;失败。
如果position超出input的末尾,则失败。
将next character设置为input中position指向的字符,并将position前进到下一个字符。(如果next character之前是U+002E全停止符(.),这次仍将是该字符。)
如果next character是U+002E(.),则:
如果s是空字符串,则失败。
令length为s中的字符数。
令fraction为将s解释为十进制整数,然后将该数除以10length的结果。
将N增加fraction。
跳过ASCII空白字符在input中给定position。
如果position超出input的末尾,则失败。
将next character设置为input中position指向的字符,并将position前进到下一个字符。
如果next character既不是U+0053拉丁大写字母S字符,也不是U+0073拉丁小写字母s字符,则失败。
将units设置为seconds。
否则:
如果next character是ASCII空白字符,则跳过ASCII空白字符在input中给定position,将next character设置为input中position指向的字符,并将position前进到下一个字符。
如果next character是U+0059拉丁大写字母Y字符或U+0079拉丁小写字母y字符,将units设置为years,并将M-disambiguator设置为months。
如果next character是U+004D拉丁大写字母M字符或U+006D拉丁 小写字母m字符,并且M-disambiguator是months,则将units设置为months。
如果next character是U+0057拉丁大写字母W字符或U+0077拉丁小写字母w字符,将units设置为weeks,并将M-disambiguator设置为minutes。
如果next character是U+0044拉丁大写字母D字符或U+0064拉丁小写字母d字符,将units设置为days,并将M-disambiguator设置为minutes。
如果next character是U+0048拉丁大写字母H字符或U+0068拉丁小写字母h字符,将units设置为hours,并将M-disambiguator设置为minutes。
如果next character是U+004D拉丁大写字母M字符或U+006D拉丁小写字母m字符,并且M-disambiguator是minutes,则将units设置为minutes。
如果next character是U+0053拉丁大写字母S字符或U+0073拉丁小写字母s字符,将units设置为seconds,并将M-disambiguator设置为minutes。
否则,如果next character不是上述任何一个字符,则失败。
增加component count。
令multiplier为1。
如果units是years,则将multiplier乘以12,并将units设置为months。
如果units是months,则将N和multiplier的乘积加到months中。
否则:
如果units是weeks,则将multiplier乘以7,并将units设置为days。
如果units是days,则将multiplier乘以24,并将units设置为hours。
如果units是hours,则将multiplier乘以60,并将units设置为minutes。
如果units是minutes,则将multiplier乘以60,并将units设置为seconds。
最终,units现在是seconds。将N和multiplier的乘积加到seconds中。
跳过ASCII空白字符在input中给定position。
如果component count为零,则失败。
如果months不为零,则失败。
返回由seconds秒组成的持续时间。
如果字符串也是以下之一,则该字符串是一个有效的包含可选时间的日期字符串:
解析日期或时间字符串的规则如下。该算法将返回一个日期、一个时间、一个全球日期和时间,或什么都不返回。如果在任何时候算法说它“失败”,这意味着它在该点中止并返回什么都没有。
令input为正在解析的字符串。
令position为input中的指针,最初指向字符串的开头。
将start position设置为与position相同的位置。
将date present和time present标志设置为true。
解析日期组件以获取year、month和day。如果解析失败,则将date present标志设置为false。
如果date present为true,并且position没有超出input的末尾,并且position处的字符是U+0054拉丁大写字母T字符(T)或U+0020空格字符,则将position前进到input中的下一个字符。
否则,如果date present为true,并且position超出input的末尾或position处的字符既不是U+0054拉丁大写字母T字符(T)也不是U+0020空格字符,则将time present设置为false。
否则,如果date present为false,将position设置回与start position相同的位置。
如果time present标志为true,则解析时间组件以获取hour、minute和second。如果解析失败,则失败。
如果date present和time present标志都为true,但position超出input的末尾,则失败。
如果date present和time present标志都为true,解析时区偏移组件以获取timezonehours和timezoneminutes。如果解析失败,则失败。
如果position没有超出input的末尾,则失败。
如果date present标志为true且time present标志为false,则令date为具有year、month和day的日期,并返回date。
否则,如果time present标志为true且date present标志为false,则令time为具有hour、minute和second的时间,并返回time。
否则,令time为年year、月month、日day、小时hour、分钟minute、秒second的时间减去timezonehours小时和timezoneminutes分钟,该时间点为UTC时区的时间点;令timezone为距离UTC的timezonehours小时和timezoneminutes分钟;并返回time和timezone。
一个简单颜色由三个范围在0到255(含)之间的8位数字组成,分别代表颜色的红色、绿色和蓝色分量,在'srgb'颜色空间中。
如果字符串长度正好为七个字符,且第一个字符是U+0023号码符号字符(#),并且剩下的六个字符都是ASCII十六进制数字,那么该字符串是有效的简单颜色,其中前两个数字代表红色分量,中间两个数字代表绿色分量,最后两个数字代表蓝色分量,采用十六进制表示。
如果一个字符串是有效的简单颜色且不使用范围在U+0041拉丁大写字母A到U+0046拉丁大写字母F之间的任何字符,则该字符串是有效的小写简单颜色。
解析简单颜色值的规则如下。在调用时,必须按给定顺序执行这些步骤,在第一个返回值的步骤处中止。该算法将返回一个简单颜色或错误。
令input为正在解析的字符串。
如果input长度不是正好七个字符,则返回错误。
如果input的第一个字符不是U+0023号码符号字符(#),则返回错误。
如果input的最后六个字符不是全部为ASCII十六进制数字,则返回错误。
令result为一个简单颜色。
将第二个和第三个字符解释为十六进制数字,并将结果作为result的红色分量。
将第四个和第五个字符解释为十六进制数字,并将结果作为result的绿色分量。
将第六个和第七个字符解释为十六进制数字,并将结果作为result的蓝色分量。
返回result。
给定一个简单颜色,序列化简单颜色值的规则如下:
令result为一个由单个U+0023号码符号字符(#)组成的字符串。
将红色、绿色和蓝色分量依次转换为两位十六进制数字,使用ASCII小写十六进制数字,必要时进行零填充,并按红色、绿色、蓝色的顺序将这些数字附加到result。
返回result,它将是一个有效的小写简单颜色。
一些过时的遗留属性以更复杂的方式解析颜色,使用解析遗留颜色值的规则,如下算法所示。在调用时,必须按给定顺序执行这些步骤,在第一个返回值的步骤处中止。该算法将返回一个简单颜色或错误。
令input为正在解析的字符串。
如果input为空字符串,则返回错误。
如果input与字符串"transparent
"进行ASCII大小写不敏感匹配,则返回错误。
如果input与其中一个命名颜色进行ASCII大小写不敏感匹配,则返回与该关键字对应的简单颜色。[CSSCOLOR]
CSS2系统颜色不被识别。
如果input的代码点长度为四,并且input的第一个字符是U+0023(#),并且input的最后三个字符都是ASCII十六进制数字,则:
令result为一个简单颜色。
将input的第二个字符解释为十六进制数字;令result的红色分量为结果数字乘以 17。
将input的第三个字符解释为十六进制数字;令result的绿色分量为结果数字乘以17。
将input的第四个字符解释为十六进制数字;令result的蓝色分量为结果数字乘以17。
返回result。
将input中所有代码点大于U+FFFF的字符(即任何不在基本多语言平面中的字符)替换为两个字符的字符串"00
"。
如果input的代码点长度大于128,则截断input,只保留前128个字符。
如果input的第一个字符是U+0023号码符号字符(#),则将其移除。
将input中任何不是ASCII十六进制数字的字符替换为U+0030数字零字符(0)。
当input的代码点长度为零或不是三的倍数时,将U+0030数字零字符(0)附加到input。
将input拆分为三个相等代码点长度的字符串,以获得三个组件。令length为所有这些组件的代码点长度(input的代码点长度的三分之一)。
如果length大于8,则删除每个组件中前length-8个字符,并将length设置为8。
当length大于两个并且每个组件的第一个字符是U+0030数字零字符(0)时,移除该字符并减少length。
如果length仍大于两个,则截断每个组件,只保留每个组件的前两个字符。
令result为一个简单颜色。
将第一个组件解释为十六进制数字;令result的红色分量为结果数字。
将第二个组件解释为十六进制数字;令result的绿色分量为结果数字。
将第三个组件解释为十六进制数字;令result的蓝色分量为结果数字。
返回result。
2D图形上下文有一个单独的颜色语法,也处理不透明度。
一个 空格分隔的标记集 是一个包含零个或多个单词(称为标记)的字符串,这些单词由一个或多个 ASCII 空白字符 分隔,其中单词由一个或多个字符组成,这些字符都不是 ASCII 空白字符。
一个包含 空格分隔的标记集 的字符串可以有前导或尾随的 ASCII 空白字符。
一个 无序的唯一空格分隔标记集 是一个 空格分隔的标记集,其中的标记没有重复。
一个 有序的唯一空格分隔标记集 是一个 空格分隔的标记集,其中的标记没有重复,但标记的顺序是有意义的。
空格分隔的标记集 有时具有定义的允许值集合。当定义了允许值集合时,标记必须全部来自该允许值列表;其他值不符合规范。如果没有提供这样的允许值集合,则所有值都是符合规范的。
如何比较 空格分隔的标记集 中的标记(例如,区分大小写或不区分大小写)是按集合来定义的。
一个 逗号分隔的标记集 是一个包含零个或多个标记的字符串,每个标记之间用一个 U+002C 逗号字符(,)分隔,其中标记由零个或多个字符组成,既不以 ASCII 空白字符 开头或结尾,也不包含任何 U+002C 逗号字符(,),并且可以选择性地被 ASCII 空白字符 包围。
例如,字符串 " a ,b,,d d
" 由四个标记组成:"a","b",空字符串和
"d d"。每个标记周围的前导和尾随空白字符不计入标记的一部分,并且空字符串可以是一个标记。
逗号分隔的标记集 有时对有效标记的构成有进一步的限制。当定义了这些限制时,标记必须全部符合这些限制;其他值是不符合规范的。如果没有规定这样的限制,则所有值都是符合规范的。
一个 有效的哈希名称引用 到一个类型为 type 的元素,是一个包含 U+0023 数字符号字符 (#) 后跟一个与同一个
树 中类型为
type 的元素的 name
属性值完全匹配的字符串。
给定上下文节点 scope,解析类型为 type 的元素的哈希名称引用的 规则 如下:
如果被解析的字符串不包含 U+0023 数字符号字符,或者如果字符串中的第一个这样的字符是字符串中的最后一个字符,则返回 null。
让 s 成为从被解析字符串中第一个 U+0023 数字符号字符之后的字符到字符串末尾的字符串。
返回 scope 的 树 中按 树顺序 排列的第一个类型为
type 且其 id
或
name
属性的值为 s 的元素,如果没有这样的元素,则返回 null。
尽管在解析时会考虑 id
属性,但它们不会用于确定一个值是否为 有效的 哈希名称引用。也就是说,基于 id
引用元素的哈希名称引用是一个一致性错误(除非该元素也有一个具有相同值的 name
属性)。
如果字符串符合 Media Queries 的 <media-query-list>
生成规则,则该字符串是一个 有效的媒体查询列表。
[MQ]
如果字符串为空字符串、仅包含 ASCII 空白字符,或是一个根据 Media Queries 中定义的符合用户环境的媒体查询列表,则该字符串 符合用户环境。[MQ]
一个 唯一内部值 是一个可序列化、按值可比较且从不暴露给脚本的值。
要创建一个 新的唯一内部值,返回一个从未被此算法返回过的 唯一内部值。
如果字符串是一个 有效的 URL 字符串 且不是空字符串,则该字符串是一个 有效的非空 URL。
如果字符串在去除前导和尾随的 ASCII 空白字符 后是一个 有效的 URL 字符串,则该字符串是一个 有效的可能被空格包围的 URL。
如果字符串在去除前导和尾随的 ASCII 空白字符 后是一个 有效的非空 URL,则该字符串是一个 有效的非空 URL 可能被空格包围。
本规范将 URL about:legacy-compat
定义为一个保留的但不可解析的 about:
URL,用于在需要与 XML 工具兼容时在 DOCTYPE
中使用的 HTML 文档。[ABOUT]
本规范将 URL about:html-kind
定义为一个保留的但不可解析的 about:
URL,用作媒体轨道类型的标识符。[ABOUT]
本规范将 URL about:srcdoc
定义为一个保留的但不可解析的 about:
URL,用作 URL 的 iframe
srcdoc
文档。[ABOUT]
备用基础 URL 是 文档
对象
document 的
URL
记录,通过执行以下步骤获得:
如果 document 是 一个
iframe
srcdoc
文档,则:
断言:document 的 about 基础 URL 非空。
返回 document 的 about 基础 URL。
如果 document 的 URL 匹配
about:blank
并且 document 的 about 基础 URL 非空,则返回 document 的 about 基础 URL。
返回 document 的 URL。
文档基础 URL 是 文档
对象的
URL
记录,通过执行以下步骤获得:
URL 匹配 about:blank
如果其 方案 是 "about
",其 路径 包含单个字符串 "blank
",其 用户名 和 密码 是空字符串,且其 主机 为 null。
这样的 URL 的 查询 和 片段 可以是非空的。例如,通过 解析 "about:blank?foo#bar
" 创建的 URL 记录 匹配
about:blank
。
URL 匹配 about:srcdoc
如果其 方案 是 "about
",其 路径 包含单个字符串 "srcdoc
",其 查询 为 null,其 用户名 和 密码 是空字符串,且其 主机 为 null。
确保 匹配
about:srcdoc
的原因是因为不可能创建 一个 iframe
srcdoc
文档 其 URL 具有非空的 查询,而与 文档
的 URL 匹配 about:blank
不同。换句话说,所有 URL 只有在其 片段 上有所不同,才会 匹配 about:srcdoc
。
解析 URL 是将一个字符串转换为其表示的 URL 记录 的过程。虽然这个过程在 URL 中有定义,但 HTML 标准定义了几个封装器来抽象基础 URL 和编码。[URL]
大多数新的 API 应该使用 解析 URL。较旧的 API 和 HTML 元素可能需要使用 编码解析 URL。当需要自定义基础 URL 或不希望使用基础 URL 时,URL 解析器 也可以直接使用。
要 解析 URL,给定一个字符串 url,相对于 文档
对象或 环境设置对象 environment,执行以下步骤。这些步骤返回失败或一个 URL。
让 baseURL 为 environment 的 基础 URL,如果 environment 是一个 文档
对象;否则为
environment 的 API 基础
URL。
返回应用于 url 的 URL 解析器 的结果,使用 baseURL。
要 编码解析 URL,给定一个字符串 url,相对于一个
文档
对象或 环境设置对象 environment,执行以下步骤。这些步骤返回失败或一个 URL。
让 encoding 为 UTF-8。
如果 environment 是一个 文档
对象,则将
encoding 设置为 environment 的 字符编码。
否则,如果 environment 的 相关全局对象 是一个 Window
对象,将 encoding
设置为 environment 的 相关全局对象 的 关联
Document
的 字符编码。
让 baseURL 为 environment 的 基础 URL,如果 environment 是一个 文档
对象;否则为
environment 的 API 基础
URL。
返回应用于 url 的 URL 解析器 的结果,使用 baseURL 和 encoding。
要 编码解析并序列化 URL,给定一个字符串 url,相对于一个 文档
对象或 环境设置对象 environment,执行以下步骤。这些步骤返回失败或一个字符串。
当文档的 文档基础 URL 更改时,该文档中的所有元素 都会 受到基础 URL 更改的影响。
以下是 基础 URL 更改步骤,当元素 受到基础 URL 更改的影响(如 DOM 定义的)时执行:
如果超链接标识的 URL 正显示给用户,或者任何从该 URL 派生的数据影响了显示,则
href
属性的值应该 重新解析,相对于元素的 节点文档,并且 UI 应适当更新。
例如,CSS :link
/:visited
伪类
可能已经受到影响。
如果超链接具有 ping
属性
并且其 URL(s) 正显示给用户,则 ping
属性的标记应该 重新解析,相对于元素的 节点文档,并且 UI 应适当更新。
q
、
blockquote
、
ins
,
或
del
元素,且具有 cite
属性
如果 URL 标识的 cite
属性正在显示给用户,或者任何从该 URL 派生的数据影响了显示,
则 cite
属性的值应该 重新解析,相对于元素的 节点文档,并且 UI 应适当更新。
该元素不会直接受到影响。
例如,更改基础 URL 不会影响 img
元素显示的图像,尽管从脚本中对 src
IDL 属性的后续访问将返回一个新的 绝对
URL,可能不再对应于正在显示的图像。
一个 响应 如果其 类型 为
"basic
"、"cors
" 或
"default
",则称为 CORS-同源。
[FETCH]
一个 响应 如果其 类型 为 "opaque
"
或 "opaqueredirect
",则称为 CORS-跨源。
一个 响应 的 不安全响应 是其 内部响应,如果有的话,否则就是该 响应 本身。
要 创建一个潜在的 CORS 请求,给定一个 url、 destination、corsAttributeState 和一个可选的 同源回退标志,执行以下步骤:
如果 corsAttributeState 为 无
CORS,则让 mode 为 "no-cors
",否则为
"cors
"。
如果 同源回退标志 被设置且 mode 为 "no-cors
",则将 mode 设置为
"same-origin
"。
让 credentialsMode 为 "include
"。
如果 corsAttributeState 为 匿名,则将 credentialsMode 设置为
"same-origin
"。
让 request 为一个新的 请求,其 URL 为 url,目的地 为 destination, 模式 为 mode,凭证模式 为 credentialsMode,且 使用 URL 凭证标志 被设置。
资源的 内容类型元数据 必须以与 MIME Sniffing 要求一致的方式获取和解释。 [MIMESNIFF]
资源的 计算 MIME 类型 必须以与 MIME Sniffing 要求一致的方式确定。[MIMESNIFF]
对于 图像的嗅探规则、区分资源是文本还是二进制的规则 和 音频和视频的嗅探规则 也在 MIME Sniffing 中定义。这些规则返回一个 MIME 类型 作为结果。[MIMESNIFF]
务必严格遵守 MIME Sniffing 中的规则。当用户代理使用不同于服务器预期的内容类型检测启发式方法时,可能会发生安全问题。更多详细信息,请参见 MIME Sniffing。 [MIMESNIFF]
meta
元素中提取字符编码
给定一个字符串 s,从 meta
元素中提取字符编码的 算法 如下。它要么返回一个字符编码,要么返回无结果。
设 position 为指向 s 的指针,初始时指向字符串的开始。
循环: 找到 position 之后的 s 中前七个字符中与单词 "charset
" 的 ASCII
不区分大小写 匹配的第一个字符。如果没有找到这样的匹配,返回无结果。
跳过紧跟在单词 "charset
" 之后的任何 ASCII
空白字符(可能没有)。
如果下一个字符不是 U+003D 等号 (=),则将 position 移动到指向该下一个字符之前,并返回到标记为 循环 的步骤。
跳过紧跟在等号之后的任何 ASCII 空白字符(可能没有)。
处理下一个字符如下:
该算法与 HTTP 规范中的那些算法不同(例如,HTTP 不允许使用单引号,并且要求支持一个不被该算法支持的反斜杠转义机制)。虽然该算法用于历史上与 HTTP 相关的上下文中,但实现所支持的语法已经有一段时间偏离。[HTTP]
在所有当前引擎中均受支持。
CORS 设置属性 是一个 枚举属性, 具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
anonymous
|
匿名 | 对元素的请求 将其
模式 设置为
"cors ",并将其
凭证模式 设置为 "same-origin "。
|
(空字符串) | ||
use-credentials
|
使用凭证 | 对元素的请求 将其 模式 设置为
"cors ",并将其 凭证模式 设置为 "include "。
|
该属性的 缺失值默认值 是 无
CORS 状态,其 无效值默认值 是 匿名 状态。为了 反射 的目的,规范关键字 为
匿名 状态是 anonymous
关键字。
大多数受 CORS 设置属性 管辖的请求将通过 创建潜在 CORS 请求 算法进行。
对于更现代的功能,其中请求的 模式 始终为
"cors
",某些 CORS
设置属性 已被重新定义为具有略有不同的含义,其中它们仅影响 请求 的 凭证模式。为了进行此转换,我们定义 CORS 设置属性凭证模式 为通过切换属性状态来确定:
same-origin
"include
"引荐政策属性 是一个 枚举属性。每个 引荐政策, 包括空字符串,都是该属性的关键字,对应一个同名的状态。
该属性的 缺失值默认值 和 无效值默认值 都是空字符串状态。
这些状态对各种 fetch 请求 的处理模型的影响在本规范中有更详细的定义,包括 Fetch 和 Referrer Policy。[FETCH] [REFERRERPOLICY]
几个信号可以影响用于给定 fetch 请求 的处理模型;引荐政策属性 只是其中之一。通常,这些信号的处理顺序为:
首先,存在一个 noreferrer
链接类型;
然后是 引荐政策属性 的值;
最后是 `Referrer-Policy
`
HTTP 头部。
所有当前引擎都支持。
nonce
内容
属性表示一个加密 nonce(“仅使用一次的数字”),可以由 内容安全策略 用来决定是否允许给定的 fetch 请求继续进行。其值为文本。[CSP]
具有 nonce
内容属性的元素
确保加密 nonce 只暴露给脚本(而非通过 CSS 属性选择器等侧信道)。它通过从内容属性中获取值,将其移动到一个名为 [[CryptographicNonce]] 的内部插槽中,通过 HTMLOrSVGElement
接口混合来暴露给脚本,并将内容属性设置为空字符串。除非另有说明,插槽的值为空字符串。
element.nonce
返回 element 的加密 nonce 的值。如果没有使用 setter,这将是原始的 nonce
内容属性中的值。
element.nonce = value
更新 element 的加密 nonce 值。
nonce
IDL 属性必须在获取时返回该元素的 [[CryptographicNonce]] 的值;在设置时,将该元素的 [[CryptographicNonce]] 设置为给定的值。
注意,nonce
IDL 属性的 setter 不会更新对应的内容属性。这以及当一个元素 变为浏览上下文连接 时将 nonce
内容属性设置为空字符串,是为了防止通过容易读取内容属性的机制(如选择器)泄露 nonce 值。了解更多信息请参见 问题
#2369,该行为在此处被引入。
如果 element
不 包含 HTMLOrSVGElement
,
则返回。
如果 localName 不是 nonce
或
namespace 不为 null,则返回。
如果 value 为 null,则将 element 的 [[CryptographicNonce]] 设置为空字符串。
否则,将 element 的 [[CryptographicNonce]] 设置为 value。
每当一个元素 包含 HTMLOrSVGElement
变为浏览上下文连接 时,用户代理必须对 element 执行以下步骤:
令 CSP list 为 element 的 shadow-including root 的 策略容器 的 CSP list。
如果 CSP list 包含一个头部传递的内容安全策略,并且
element 具有一个 nonce
内容
属性 attr,其值不是空字符串,则:
令 nonce 为 element 的 [[CryptographicNonce]]。
将 element 的 [[CryptographicNonce]] 设置为 nonce。
如果 element 的 [[CryptographicNonce]] 没有恢复,那么在此时它将是空字符串。
对于 包含 HTMLOrSVGElement
的元素,克隆步骤必须将副本上的 [[CryptographicNonce]]
插槽设置为元素被克隆时插槽的值。
所有当前引擎都支持。
一个 延迟加载属性 是一个 枚举属性, 具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
lazy
|
延迟 | 用于在满足某些条件之前推迟获取资源。 |
eager
|
立即 | 用于立即获取资源;默认状态。 |
该属性指示用户代理立即获取资源,或根据属性的当前状态,在满足与元素相关的一些条件之后再获取资源。
该属性的 缺失值默认值 和 无效值默认值 都是 立即 状态。
对于给定的元素 element,将延迟加载元素步骤 如下:
如果 脚本功能被禁用,则返回 false。
这是一个反跟踪措施,因为如果用户代理在脚本功能被禁用时仍支持延迟加载,那么一个网站可以通过在页面的标记中战略性地放置图像,以便服务器可以跟踪请求的图像数量及其时间,从而在整个会话中跟踪用户的大致滚动位置。
返回 false。
每个 img
和 iframe
元素都有相关的 延迟加载恢复步骤,最初为 null。
对于那些 将延迟加载 的 img
和 iframe
元素,这些步骤会在 延迟加载交叉观察器 的回调中运行,或当其 延迟加载属性 设置为 立即 状态时。这会导致元素继续加载。
每个 文档
都有一个
延迟加载交叉观察器,最初设置为 null,但可以设置为一个 IntersectionObserver
实例。
要 开始交叉观察一个延迟加载元素 element,执行以下步骤:
将 doc 设为 element 的 节点文档。
如果 doc 的 延迟加载交叉观察器 为 null,
将其设置为一个新的 IntersectionObserver
实例,初始化如下:
意图是使用 IntersectionObserver
构造函数的原始值。然而,我们被迫使用本规范中的 JavaScript 暴露构造函数,直到 Intersection Observer
为规范中的使用提供低级钩子。请参见跟踪此问题的 bug w3c/IntersectionObserver#464。[INTERSECTIONOBSERVER]
callback 是这些步骤,参数为 entries 和 observer:
对于 entries 中的每个 entry 使用一种不会触发开发者可修改数组访问器或 迭代钩子的方法进行迭代:
将 resumptionSteps 设为 null。
如果 entry.isIntersecting
为 true,则将 resumptionSteps 设为 entry.target
的
延迟加载恢复步骤。
如果 resumptionSteps 为 null,则返回。
停止
交叉观察延迟加载元素 对于 entry.target
。
调用 resumptionSteps。
意图是使用 isIntersecting
和 target
的原始值。请参见 w3c/IntersectionObserver#464。
[INTERSECTIONOBSERVER]
options 是一个 IntersectionObserverInit
字典,具有以下字典成员:«[ "scrollMargin
" → 延迟加载滚动边距 ]»
这允许在图像尚未 — 但即将 — 与视口交叉时进行获取。
延迟加载滚动边距建议意味着值的动态变化,但 IntersectionObserver
API 不支持更改滚动边距。参见问题 w3c/IntersectionObserver#428。
调用 doc 的 延迟加载交叉观察器 的 observe
方法,以 element 作为参数。
意图是使用 observe
方法的原始值。参见 w3c/IntersectionObserver#464。
[INTERSECTIONOBSERVER]
要 停止交叉观察延迟加载元素 element,执行以下步骤:
将 doc 设为 element 的 节点文档。
调用 doc 的 延迟加载交叉观察器 的 unobserve
方法,以 element 作为参数。
意图是使用 unobserve
方法的原始值。参见 w3c/IntersectionObserver#464。
[INTERSECTIONOBSERVER]
延迟加载滚动边距 是一个
实现定义 的值,但有以下建议供参考:
设置一个最小值,以便在正常使用模式下,大多数情况下,资源会在它们进入视口之前加载。
典型的滚动速度:对于具有较快典型滚动速度的设备,增加该值。
当前滚动速度或惯性:用户代理可以尝试预测滚动将在哪个位置停止,并相应调整该值。
网络质量:对于慢速或高延迟连接,增加该值。
用户偏好可能会影响该值。
为了 保护隐私,延迟加载滚动边距 不应泄露额外的信息。例如,当前设备的典型滚动速度可能不够精确,以免引入新的指纹识别向量。
阻塞属性 明确表示在获取外部资源时应阻止某些操作。这些操作可以被阻止的由 可能的阻塞令牌 表示,这些令牌以字符串形式列于下表:
可能的阻塞令牌 | 描述 |
---|---|
"render "
|
该元素是 可能阻塞渲染 的。 |
将来可能会有更多的 可能的阻塞令牌。
一个 阻塞属性 必须具有一个值,该值是一个 唯一的以空格分隔的令牌无序集合,每个令牌都是 可能的阻塞令牌。一个 支持的令牌 是 可能的阻塞令牌。任何元素最多只能有一个 阻塞属性。
阻塞令牌集 是针对一个元素 el 的以下步骤的结果:
让 value 为 el 的 阻塞属性 的值,如果不存在这样的属性,则为 空字符串。
将 value 转换为 ASCII 小写。
让 rawTokens 为 按 ASCII 空白字符分割 value 的结果。
返回一个包含 rawTokens 中所有 可能的阻塞令牌 的集合。
一个元素如果其 阻塞令牌集
包含 "render
",
或者如果它是 隐式潜在渲染阻塞 的,这将在各个元素中定义。
默认情况下,元素不是 隐式潜在渲染阻塞 的。
获取优先级属性 是一个 枚举属性, 具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
high
|
high | 表示相对于其他具有相同 目的地 的资源,这是一个高优先级的 获取 操作。 |
low
|
low | 表示相对于其他具有相同 目的地 的资源,这是一个低优先级的 获取 操作。 |
auto
|
auto | 表示自动确定相对于其他具有相同 目的地 的 获取 优先级。 |
该属性的 缺失值默认值 和 无效值默认值 都是 auto 状态。
反射的构建块如下:
反射目标 是一个元素或 ElementInternals
对象。通常从上下文中可以清楚地确定,并且通常与
反射 IDL 属性 的接口相同。当
反射目标是 ElementInternals
对象时,它总是与该接口相同。
反射 IDL 属性 是一个属性接口成员。
反射内容属性名称 是一个字符串。当 反射目标 是一个元素时,它表示一个内容属性的本地名称,其命名空间为
null。当 反射目标 是一个 ElementInternals
对象时,它表示 反射目标 的 目标元素 的 内部内容属性映射 的一个键。
反射 IDL 属性 可以被定义为 反射 反射内容属性名称 的 反射目标。通常,这意味着 IDL 属性的 getter 返回内容属性的当前值,setter 则将内容属性的值更改为给定值。
如果 反射目标
是一个元素,则
反射
IDL 属性 还可以声明
支持 ElementInternals
。这意味着 ElementInternals
接口也有一个 反射 IDL 属性,具有相同的标识符,并且该 反射
IDL 属性 反射
相同的 反射内容属性名称。
该 fooBar
IDL 属性必须 反射
foobar
内容属性,并且 支持
ElementInternals
。
反射目标 具有以下关联算法:
对于一个 反射目标,如果它是一个元素 element,这些算法定义如下:
返回 element。
令 attribute 为运行 按命名空间和本地名称获取属性 的结果, 传入 null、反射内容属性名称 和 element。
如果 attribute 为 null,则返回 null。
返回 attribute 的 值。
按命名空间和本地名称删除属性, 传入 null、反射内容属性名称 和 element。
对于一个 反射目标,如果它是一个 ElementInternals
对象 elementInternals,这些算法定义如下:
返回 elementInternals 的 目标元素。
这会导致 ElementInternals
对象出现一些冗余的数据结构,因为其 目标元素 的 内部内容属性映射
不能直接操作,因此反射只发生在单向。这种方法尽管如此,仍被选择以减少定义在 反射目标 之间共享的 IDL 属性的错误,并从通用 API 语义中受益。
类型为 DOMString
或
DOMString?
的 IDL 属性如果 反射 枚举
内容属性,则可以
限制为仅已知值。
根据下面的处理模型,这些将导致这些 IDL 属性的 getter 仅返回这些枚举属性的关键字,或者空字符串或 null。
如果一个 反射的 IDL 属性 的
类型为 DOMString
:
getter 的步骤是:
让 attributeDefinition 成为 element 的内容属性的属性定义,该属性的命名空间为 null,局部名称为 反射内容属性名称。
如果 attributeDefinition 表示它是一个 枚举属性 并且 反射的 IDL 属性 被定义为 仅限于已知值:
如果 contentAttributeValue 为 null,则返回空字符串。
返回 contentAttributeValue。
如果一个 反射的 IDL 属性 的类型是
DOMString?
:
getter 的步骤是:
setter 的步骤是:
如果一个 反射的 IDL 属性 的类型是 USVString
:
getter 的步骤是:
让 attributeDefinition 成为 element 的内容属性的属性定义,该属性的命名空间为 null,局部名称为 反射内容属性名称。
如果 attributeDefinition 表示它包含一个 URL:
如果 contentAttributeValue 为 null,则返回空字符串。
让 urlString 成为对 contentAttributeValue 进行 编码-解析和序列化 URL 的结果,基于 element 的 节点文档。
如果 urlString 不是失败,则返回 urlString。
返回 contentAttributeValue,转换为标量值字符串。
如果一个 反射的 IDL 属性 的类型是 boolean
:
getter 的步骤是:
setter 的步骤是:
这对应于 布尔内容属性 的规则。
If a 反射的 IDL 属性 的类型是 long
,
可选地 限制为非负数 并且可选地具有 默认值
defaultValue:
getter 的步骤是:
如果 contentAttributeValue 不为 null:
让 parsedValue 成为 整数解析 contentAttributeValue 的结果,如果 反射的 IDL 属性 不是 限制为非负数;否则是 非负整数解析 contentAttributeValue 的结果。
如果 parsedValue 不是错误且在 long
范围内,则返回 parsedValue。
如果 反射的 IDL 属性 具有 默认值,则返回 defaultValue。
如果 反射的 IDL 属性 是 限制为非负数,则返回 −1。
返回 0。
setter 的步骤是:
如果 反射的 IDL 属性 是 限制为非负数
且给定的值为负,则抛出一个
"IndexSizeError
" DOMException
。
如果一个 反射的 IDL 属性 的类型是 unsigned long
,
可选地 限制为仅正数、限制为仅正数(带回退),或 夹紧到范围 [clampedMin,clampedMax],并且可选地具有 默认值
defaultValue:
getter 的步骤是:
让 minimum 为 0。
如果 反射的 IDL 属性 是 仅限正数 或 仅限正数(带回退),则将 minimum 设置为 1。
如果 反射的 IDL 属性 是 夹紧到范围,则将 minimum 设置为 clampedMin。
让 maximum 为 2147483647,如果 反射的 IDL 属性 不是 夹紧到范围;否则为 clampedMax。
如果 contentAttributeValue 不为 null:
让 parsedValue 成为 非负整数解析 contentAttributeValue 的结果。
如果 parsedValue 不是错误且在范围 minimum 到 maximum(包含)内,则返回 parsedValue。
如果 parsedValue 不是错误且 反射的 IDL 属性 是 夹紧到范围:
如果 parsedValue 小于 minimum,则返回 minimum。
返回 maximum。
如果 反射的 IDL 属性 具有 默认值,则返回 defaultValue。
返回 minimum。
setter 的步骤是:
如果 反射的 IDL 属性 是 仅限正数
且给定值为 0,则抛出一个
"IndexSizeError
" DOMException
。
让 minimum 为 0。
如果 反射的 IDL 属性 是 仅限正数 或 仅限正数(带回退),则将 minimum 设置为 1。
让 newValue 为 minimum。
如果 反射的 IDL 属性 具有 默认值,则将 newValue 设置为 defaultValue。
如果给定值在范围 minimum 到 2147483647(包含)内,则将 newValue 设置为该值。
夹紧到范围 对 setter 步骤没有影响。
如果一个 反射的 IDL 属性 的类型是 double
,
可选地 限制为仅正数,并且可选地具有 默认值 defaultValue:
getter 的步骤是:
如果 contentAttributeValue 不为 null:
让 parsedValue 成为 浮点数解析 contentAttributeValue 的结果。
如果 parsedValue 不是错误且大于 0,则返回 parsedValue。
如果 parsedValue 不是错误且 反射的 IDL 属性 不是 仅限正数,则返回 parsedValue。
如果 反射的 IDL 属性 具有 默认值,则返回 defaultValue。
返回 0。
setter 的步骤是:
如果 反射的 IDL 属性 是 仅限正数 且给定值不大于 0,则返回。
值 Infinity 和 Not-a-Number (NaN) 在设置时会抛出异常,如 Web IDL 中定义。[WEBIDL]
如果一个 反射的 IDL 属性 的类型是 DOMTokenList
,
那么它的 getter 步骤是返回一个 DOMTokenList
对象,其关联的元素是 this,关联属性的本地名称是 反射的内容属性名称。规范作者不能使用 支持
ElementInternals
来处理此类型的 IDL 属性。
如果一个 反射的 IDL 属性 的类型是
T?
,
其中 T 是 Element
或从 Element
继承的接口,则 attr 是 反射的内容属性名称:
其 反射目标 有一个 显式设置的 attr-element,这是一个对元素的弱引用或 null。初始值为 null。
其 反射目标 reflectedTarget 有一个 获取 attr-关联元素 算法,执行以下步骤:
让 element 成为运行 reflectedTarget 的 获取元素 的结果。
让 contentAttributeValue 成为运行 reflectedTarget 的 获取内容属性 的结果。
如果 reflectedTarget 的 显式设置的 attr-element 不为 null:
如果reflectedTarget的显式设置的attr-元素是任何element的后代,并且在element的包括影子的祖先中的任何一个,则返回reflectedTarget的显式设置的attr-元素。
返回 null。
否则,如果 contentAttributeValue 不为 null,则返回第一个符合以下标准的元素 candidate,按 树序 排序:
如果没有这样的元素,则返回 null。
返回 null。
getter 的步骤是返回运行 this 的 获取 attr-关联元素 的结果。
setter 的步骤是:
如果给定值为 null,则:
将 this 的 显式设置的 attr-element 设置为 null。
返回。
将 this 的 显式设置的 attr-element 设置为对给定值的弱引用。
仅对于元素 反射目标:以下 属性更改步骤,给定 element、localName、oldValue、value 和 namespace,用于同步内容属性和 IDL 属性:
如果 localName 不是 attr 或 namespace 不为 null,则返回。
将 element 的 显式设置的 attr-element 设置为 null。
反射的 IDL 属性 这种类型的属性强烈建议其标识符以
"Element
" 结尾,以保持一致性。
如果一个 反射的 IDL 属性 的类型是
FrozenArray<T>?
,其中 T 是 Element
或一个继承自 Element
的接口,那么对于 attr 作为 反射的内容属性名称:
其 反射目标
有一个 缓存的 attr-关联元素对象,它是一个
FrozenArray<T>?
。最初为 null。
其 反射目标 reflectedTarget 有一个 获取 attr-关联元素 算法,执行以下步骤:
让 elements 成为一个空的 列表。
让 element 成为运行 reflectedTarget 的 获取元素 的结果。
如果 reflectedTarget 的 显式设置的 attr-元素 不为 null:
对于 attrElement 在 reflectedTarget 的 显式设置的 attr-元素 中:
否则:
让 contentAttributeValue 成为运行 reflectedTarget 的 获取内容属性 的结果。
如果 contentAttributeValue 为 null,则返回 null。
让 tokens 为 contentAttributeValue,按 ASCII 空白拆分。
对于 id 的 tokens:
返回 elements。
getter 步骤是:
让 elements 成为运行 this 的 获取 attr-关联元素 的结果。
如果 elements 的内容等于 this 的 缓存的 attr-关联元素 的内容,则返回 this 的 缓存的 attr-关联元素对象。
让 elementsAsFrozenArray 为 elements,转换 为 FrozenArray<T>?
。
将 this 的 缓存的 attr-关联元素 设置为 elements。
将 this 的 缓存的 attr-关联元素对象 设置为 elementsAsFrozenArray。
返回 elementsAsFrozenArray。
这个额外的缓存层是必要的,以保持不变量 element.reflectedElements === element.reflectedElements
。
setter 步骤是:
仅对于元素 反射目标:以下 属性更改步骤,给定 element、localName、oldValue、value 和 namespace,用于在内容属性和 IDL 属性之间同步:
如果 localName 不是 attr 或 namespace 不为 null,则返回。
将 element 的 显式 设置的 attr-元素 设置为 null。
反射的 IDL 属性 强烈建议其标识符以
"Elements
" 结尾,以保持一致性。
反射 主要是通过给开发者提供通过 反射的 IDL 属性 类型访问内容属性,以改善开发者的使用体验。网页平台的最终事实来源是内容属性本身。也就是说,规范作者不能使用 反射的 IDL 属性 的 getter 或 setter 步骤,而应使用内容属性的存在和值。(或其上的抽象,如 枚举属性 的状态。)
两个重要的例外是 反射的 IDL 属性 其类型是以下之一:
对于这些情况,规范作者必须使用 反射目标的 获取 attr-关联元素 和 获取 attr-关联元素 的步骤。内容属性的存在和值不应使用,因为它们不能完全与 反射的 IDL 属性 同步。
反射目标的 显式设置的 attr-元素、 显式设置的 attr-元素、 缓存的 attr-关联元素 和 缓存的 attr-关联元素对象 应被视为内部实现细节,而不应基于它们进行构建。
HTMLFormControlsCollection
和 HTMLOptionsCollection
接口是从
HTMLCollection
接口派生的
集合。HTMLAllCollection
接口是一个集合,但不是这样派生的。
HTMLAllCollection
接口HTMLAllCollection
接口用于遗留的 document.all
属性。它的操作类似于 HTMLCollection
;主要区别在于它允许各种不同的(滥用)方法返回一些内容,并且它可以作为函数调用,而不是属性访问。
所有 HTMLAllCollection
对象都根植于 Document
,并具有匹配所有元素的过滤器,因此
由集合表示 的元素 HTMLAllCollection
对象由根 Document
的所有后代元素组成。
实现 HTMLAllCollection
接口的对象是 遗留平台对象,具有附加的 [[Call]] 内部方法,如下面部分所述。它们还具有 [[IsHTMLDDA]] 内部槽。
实现 HTMLAllCollection
接口的对象有几个不寻常的行为,因为它们具有 [[IsHTMLDDA]] 内部槽:
JavaScript 中的 ToBoolean 抽象操作在给定实现
HTMLAllCollection
接口的对象时返回 false。
当给定实现 HTMLAllCollection
接口的对象时,IsLooselyEqual 抽象操作与 undefined
和 null
值比较时返回 true。 (使用 IsStrictlyEqual 抽象操作的比较以及与字符串或对象等其他值的 IsLooselyEqual 比较不受影响。)
在 JavaScript 中对实现 HTMLAllCollection
接口的对象应用 typeof
运算符时,返回字符串 "undefined"
。
这些特殊行为是为了兼容两类遗留内容:一类是使用 document.all
存在来检测遗留用户代理的内容,另一类仅支持这些遗留用户代理并在不测试其存在的情况下使用 document.all
对象的内容。[JAVASCRIPT]
[Exposed =Window ,
LegacyUnenumerableNamedProperties ]
interface HTMLAllCollection {
readonly attribute unsigned long length ;
getter Element (unsigned long index );
getter (HTMLCollection or Element )? namedItem (DOMString name );
(HTMLCollection or Element )? item (optional DOMString nameOrIndex );
// Note: HTMLAllCollection objects have a custom [[Call]] internal method and an [[IsHTMLDDA]] internal slot.
};
对象的 支持的属性索引 定义与 HTMLCollection
对象相同。
支持的属性名称 由所有元素的 id
属性的非空值组成,这些元素 由集合表示,以及所有 “全部”命名元素 的 name
属性的非空值,这些元素 由集合表示,按 树顺序,忽略后续的重复项,如果一个元素同时提供
id
和 name
且它们不同且都不是早期条目的重复项,则 id
在 name
之前。
length
的 getter 步骤是返回 由集合表示 的节点数。
索引属性 getter 必须返回通过给定传递的索引 获取“全部”索引的元素 的结果 this。
namedItem(name)
方法步骤是返回 获取“全部”命名的元素 的结果 this 给定 name。
item(nameOrIndex)
方法步骤是:
如果未提供 nameOrIndex,则返回 null。
返回 获取“全部”索引或命名的元素 的结果 this 给定 nameOrIndex。
以下元素是 “全部”命名元素:a
,button
,embed
,form
,frame
,frameset
,iframe
,img
,input
,map
,meta
,object
,select
,以及textarea
从 HTMLAllCollection
collection 中 获取“全部”索引的元素 给定索引 index,返回
collection 中的第 index 个元素,如果没有这样的 index 个元素,则返回 null。
从 HTMLAllCollection
collection 中 获取“全部”命名的元素 给定名称 name,执行以下步骤:
如果 name 是空字符串,则返回 null。
让 subCollection 成为一个 HTMLCollection
对象,它以与 collection 相同的 Document
为根,其过滤器仅匹配以下任一元素:
如果 subCollection 中只有一个元素,则返回该元素。
否则,如果 subCollection 为空,则返回 null。
否则,返回 subCollection。
从 HTMLAllCollection
collection 中 获取“全部”索引或命名的元素 给定 nameOrIndex:
如果 nameOrIndex,转换 为 JavaScript 字符串值,是一个 数组索引属性名称,则返回通过给定 nameOrIndex 表示的数字从 collection 获取“全部”索引的元素 的结果。
返回通过给定 nameOrIndex 从 collection 获取“all”命名的元素 的结果。
如果 argumentsList 的 大小 为零,或者 argumentsList[0] 是 undefined,则返回 null。
将从此 HTMLAllCollection
中 获取“全部”索引或命名的元素 的结果赋值给 result,给定
nameOrIndex。
返回将 result 转换 为 ECMAScript 值的结果。
忽略 thisArgument,因此诸如 Function.prototype.call.call(document.all, null, "x")
的代码仍将搜索元素。(document.all.call
不存在,因为 document.all
不继承自 Function.prototype
。)
HTMLFormControlsCollection
接口HTMLFormControlsCollection
接口用于 集合 中
form
元素中的 列出元素。
Support in all current engines.
Support in all current engines.
[Exposed =Window ]
interface HTMLFormControlsCollection : HTMLCollection {
// inherits length and item()
getter (RadioNodeList or Element )? namedItem (DOMString name ); // shadows inherited namedItem()
};
[Exposed =Window ]
interface RadioNodeList : NodeList {
attribute DOMString value ;
};
collection.length
返回 collection 中的元素数量。
element = collection.item(index)
element = collection[index]
返回 collection 中索引为 index 的项。项按 树顺序 排序。
element = collection.namedItem(name)
HTMLFormControlsCollection/namedItem
Support in all current engines.
radioNodeList = collection.namedItem(name)
element = collection[name]
radioNodeList = collection[name]
从 collection 返回 ID 或 name
为 name 的项。
如果有多个匹配的项,则返回包含所有这些元素的 RadioNodeList
对象。
radioNodeList.value
返回 radioNodeList 所代表的第一个选中的单选按钮的值。
radioNodeList.value = value
选择第一个值为 value 的 radioNodeList 所代表的单选按钮。
The 支持的属性名称 由所有非空值组成
id
和 name
属性的所有元素由集合表示,按树顺序,忽略后续的重复项,其中id
的元素优先于其name
如果它们同时贡献,它们彼此不同,并且都不是先前条目的重复项。
namedItem(name)
方法必须按照以下算法操作:
id
属性或 name
属性等于 name,则返回该节点并停止算法。id
属性或 name
属性等于 name,则返回 null 并停止算法。RadioNodeList
对象,表示 动态 查看 HTMLFormControlsCollection
对象的视图,进一步过滤,使得 RadioNodeList
对象中的唯一节点是那些具有 id
属性或 name
属性等于 name 的节点。RadioNodeList
对象中的节点必须按 树顺序 排序。RadioNodeList
对象。RadioNodeList
接口的成员从 NodeList
接口继承,必须像在 NodeList
对象上一样表现。
Support in all current engines.
value
IDL 属性在 RadioNodeList
对象上,获取时必须返回通过运行以下步骤返回的值:
让 element 成为由 RadioNodeList
对象表示的第一个元素,在 树顺序 中是一个 input
元素,其 type
属性处于 单选按钮 状态并且其 已选中
状态为真。否则,让其为 null。
如果 element 为 null,则返回空字符串。
如果 element 是一个没有 value
属性的元素,则返回字符串 "on
"。
否则,返回 element 的 value
属性的值。
在设置时,value
IDL 属性必须运行以下步骤:
如果新值为字符串 "on
":让 element 成为由 RadioNodeList
对象表示的第一个元素,在 树顺序 中是一个 input
元素,其 type
属性处于 单选按钮 状态并且其 value
内容属性不存在,或存在且等于新值,如果有。如果不存在这样的元素,则让 element 为 null。
否则:让 element 成为由 RadioNodeList
对象表示的第一个元素,在 树顺序 中是一个 input
元素,其 type
属性处于 单选按钮 状态并且其 value
内容属性存在并等于新值,如果有。如果不存在这样的元素,则让 element 为 null。
如果 element 不为 null,则将其 已选中 状态设置为真。
HTMLOptionsCollection
接口支持所有当前引擎。
HTMLOptionsCollection
接口用于 集合 的 option
元素。它总是根植于一个 select
元素,并具有操作该元素后代的属性和方法。
[Exposed =Window ]
interface HTMLOptionsCollection : HTMLCollection {
// inherits item(), namedItem()
[CEReactions ] attribute unsigned long length ; // shadows inherited length
[CEReactions ] setter undefined (unsigned long index , HTMLOptionElement ? option );
[CEReactions ] undefined add ((HTMLOptionElement or HTMLOptGroupElement ) element , optional (HTMLElement or long )? before = null );
[CEReactions ] undefined remove (long index );
attribute long selectedIndex ;
};
collection.length
返回 collection 中的元素数量。
collection.length = value
当设置为小于现有长度的值时,截断 collection 对应容器中的 option
元素数量。
当设置为大于现有长度的值时,如果该值小于或等于100000,则向 collection 对应容器中添加新的空白 option
元素。
element = collection.item(index)
element = collection[index]
返回 collection 中索引为 index 的项。项目按 树顺序 排列。
collection[index] = element
当 index 大于 collection 中的项目数量时,在相应容器中添加新的空白 option
元素。
当设置为 null 时,从 collection 中移除索引为 index 的项。
当设置为 option
元素时,在 collection 中的索引为 index 的位置添加或替换该元素。
element = collection.namedItem(name)
element = collection[name]
返回 collection 中具有 ID 或 name
为 name 的项。
如果有多个匹配项,则返回第一个匹配项。
collection.add(element[, before])
在 before 指定的节点前插入 element。
before 参数可以是一个数字,在这种情况下,element 插入到该编号的项之前;也可以是 collection 中的一个元素,在这种情况下,element 插入到该元素之前。
如果 before 被省略、为空或为超出范围的数字 ,则 element 将添加到列表末尾。
如果 element 是要插入的元素的祖先,则抛出 "HierarchyRequestError
" DOMException
。
collection.remove(index)
从 collection 中移除索引为 index 的项。
collection.selectedIndex
返回第一个被选中项的索引(如果有),否则返回 -1。
collection.selectedIndex = index
将选项更改为 collection 中索引为 index 的 option
元素。
对象的 支持的属性索引如 HTMLCollection
对象中定义。
length
的获取步骤是返回 collection 表示的节点数。
length
的设置步骤为:
令 current 为 collection 表示的节点数。
如果给定值大于 current,则:
如果给定值小于 current,则:
令 n 为 current - value。
从其父节点中移除集合中的最后 n 个节点。
设置 length
永远不会移除或添加任何 optgroup
元素,也不会向现有的 optgroup
元素中添加新的子节点(尽管它可以从中移除子节点)。
The 支持的属性名称 由所有非空值组成
id
和 name
属性的所有元素由集合表示,按树顺序,忽略后续的重复项,其中id
的元素优先于其name
如果它们同时贡献,它们彼此不同,并且都不是先前条目的重复项。
当用户代理要 设置新索引属性的值或 设置现有索引属性的值时,必须运行以下算法:
如果 value 为 null,则调用 remove
方法,将 index 作为参数,并返回。
令 length 为 collection 表示的节点数。
令 n 为 index 减去 length。
如果 n 大于零,则 附加 一个由
n-1 个新的没有属性和子节点的 option
元素组成的 DocumentFragment
到 select
元素上。
如果 n 大于或等于零,则 附加
value 到 select
元素。否则,替换
集合中的第 index 个元素为 value。
add(element, before)
方法必须按以下算法操作:
如果 element 是 select
元素的祖先,则抛出 "HierarchyRequestError
" DOMException
。
如果 before 是一个元素,但该元素不是 select
元素的后代,则抛出 "NotFoundError
" DOMException
。
如果 element 和 before 是同一个元素,则返回。
如果 before 是一个节点,则令 reference 为该节点。否则,如果 before 是一个整数,并且集合中存在第 before 个节点,则令 reference 为该节点。否则,令 reference 为 null。
如果 reference 不为 null,则令 parent 为 reference 的父节点。否则,令 parent 为 select
元素。
预插入 element 到 parent 节点中,在 reference 之前。
remove(index)
方法必须按以下算法操作:
如果 collection 表示的节点数 为零,则返回。
如果 index 不是大于等于 0 且小于 collection 表示的节点数 的数字,则返回。
令 element 为集合中的第 index 个元素。
从其父节点中移除 element。
selectedIndex
IDL 属性必须像 select
元素上的同名属性一样操作,该 HTMLOptionsCollection
根植于该元素上。
DOMStringList
接口所有当前引擎支持。
DOMStringList
接口是一种不时髦的复古方式,用于表示字符串列表。
[Exposed =(Window ,Worker )]
interface DOMStringList {
readonly attribute unsigned long length ;
getter DOMString ? item (unsigned long index );
boolean contains (DOMString string );
};
新 API 必须使用 sequence<DOMString>
或等效的方式,而不是 DOMStringList
。
strings.length
返回 strings 中的字符串数量。
strings[index]
strings.item(index)
返回 strings 中索引为 index 的字符串。
strings.contains(string)
如果 strings 包含 string,则返回 true,否则返回 false。
每个 DOMStringList
对象都有一个关联的 列表。
DOMStringList
接口 支持索引属性。支持的属性索引是 此的关联列表的 索引。
所有当前引擎支持。
所有当前引擎支持。
item(index)
方法步骤是返回 此关联列表中的第 index 项,或者如果 index 加一大于 此关联列表的 大小,则返回 null。
所有当前引擎支持。
contains(string)
方法步骤是如果 此关联列表 包含 string,则返回
true,否则返回 false。
为了支持在不同realm边界之间传递JavaScript对象,包括平台对象,本规范定义了以下用于序列化和反序列化对象的基础设施,包括在某些情况下传输底层数据而不是复制数据。总体而言,这种序列化/反序列化过程被称为“结构化克隆”,尽管大多数API执行的是单独的序列化和反序列化步骤。(显著的例外是structuredClone()
方法。)
本节使用了JavaScript规范中的术语和排版约定。[JAVASCRIPT]
/developer.mozilla.org/en-US/docs/Glossary/Serializable_object
可序列化对象支持以独立于任何特定realm的方式进行序列化和稍后反序列化。这使得它们可以存储在磁盘上并稍后恢复,或跨代理甚至代理集群边界进行克隆。
并非所有对象都是可序列化对象,而且并非所有可序列化对象的所有方面在序列化时都会被保留。
平台对象可以是可序列化对象,如果它们的主要接口带有[Serializable]
IDL扩展属性。这些接口还必须定义以下算法:
一组步骤,将value中的数据序列化为serialized的字段。序列化到serialized中的结果数据必须独立于任何realm。
如果序列化不可能,这些步骤可能会抛出异常。
这些步骤可能执行子序列化以序列化嵌套的数据结构。它们不应直接调用StructuredSerialize,因为这样做会遗漏重要的memory参数。
如果forStorage参数与算法无关,应在引入这些步骤时省略提及。
一组步骤,将serialized中的数据反序列化,适当设置value。value将是所涉及的平台对象类型的新创建实例,其内部数据未设置;设置这些数据是这些步骤的任务。
如果反序列化不可能,这些步骤可能会抛出异常。
这些步骤可能执行子反序列化以反序列化嵌套的数据结构。它们不应直接调用StructuredDeserialize,因为这样做会遗漏重要的targetRealm和memory参数。
定义单个平台对象的数据在这些步骤中如何被序列化和反序列化是个体平台对象定义的责任。通常这些步骤是非常对称的。
[Serializable]
扩展属性不得带有任何参数,并且只能出现在接口上。在一个接口上不得出现超过一次。
对于给定的平台对象,只有对象的主要接口在(反)序列化过程中被考虑。因此,如果在定义接口时涉及继承,每个继承链中的[Serializable]
注释接口需要定义独立的序列化步骤和反序列化步骤,包括考虑任何可能来自继承接口的重要数据。
假设我们定义了一个平台对象Person
,它关联了两部分数据:
一个名称值,它是一个字符串;和
一个最好朋友值,它可以是另一个Person
实例或null。
然后我们可以通过将Person
接口注释为[Serializable]
扩展属性,并定义以下配套算法,使Person
实例成为可序列化对象:
JavaScript规范中定义的对象由StructuredSerialize抽象操作直接处理。
最初,本规范定义了“可克隆对象”的概念,可以从一个realm克隆到另一个realm。然而,为了更好地指定某些更复杂情况的行为,模型被更新为使序列化和反序列化显式化。
可转移对象支持在代理之间转移。转移实际上是重新创建对象,同时共享对底层数据的引用,然后分离被转移的对象。这对于转移昂贵资源的所有权非常有用。并非所有对象都是可转移对象,而且并非所有可转移对象的所有方面在转移时都会被保留。
转移是不可逆且非幂等的操作。一旦对象被转移,它不能再被转移,甚至不能再被使用。
平台对象可以是可转移对象,如果它们的主要接口带有[Transferable]
IDL扩展属性。这些接口还必须定义以下算法:
一组步骤,将value中的数据转移到dataHolder的字段中。保存在dataHolder中的结果数据必须独立于任何realm。
如果转移不可能,这些步骤可能会抛出异常。
一组步骤,接收dataHolder中的数据,适当设置value。value将是所涉及的平台对象类型的新创建实例,其内部数据未设置;设置这些数据是这些步骤的任务。
如果无法接收转移,这些步骤可能会抛出异常。
定义单个平台对象的数据在这些步骤中如何被转移是个体平台对象定义的责任。通常这些步骤是非常对称的。
[Transferable]
扩展属性不得带有任何参数,并且只能出现在接口上。在一个接口上不得出现超过一次。
对于给定的平台对象,只有对象的主要接口在转移过程中被考虑。因此,如果在定义接口时涉及继承,每个继承链中的[Transferable]
注释接口需要定义独立的转移步骤和接收转移步骤,包括考虑任何可能来自继承接口的重要数据。
作为可转移对象的平台对象具有一个[[Detached]]内部槽。这用于确保一旦平台对象被转移,它不能再次被转移。
JavaScript规范中定义的对象由StructuredSerializeWithTransfer抽象操作直接处理。
StructuredSerializeInternal 抽象操作以一个 JavaScript 值 value 为输入,将其序列化为一个独立于 realm 的形式,这里表示为一个 记录。这种序列化形式包含所有必要的信息,以便以后在不同的 realm 中反序列化为一个新的 JavaScript 值。
此过程可能会抛出异常,例如尝试序列化不可序列化的对象时。
如果未提供 memory,则让 memory 成为空的 map。
memory map 的目的是避免对象被序列化两次。这最终保留了图中的循环和重复对象的身份。
如果 memory[value] 存在,则返回 memory[value]。
让 deep 为 false。
如果 Type(value) 是 Undefined、Null、Boolean、Number、BigInt 或 String,则返回 { [[Type]]: "primitive", [[Value]]: value }。
如果 Type(value) 是 Symbol,则抛出
"DataCloneError
" DOMException
。
让 serialized 成为一个未初始化的值。
如果 value 有 [[BooleanData]] 内部槽,则将 serialized 设置为 { [[Type]]: "Boolean", [[BooleanData]]: value.[[BooleanData]] }。
否则,如果 value 有 [[NumberData]] 内部槽,则将 serialized 设置为 { [[Type]]: "Number", [[NumberData]]: value.[[NumberData]] }。
否则,如果 value 有 [[BigIntData]] 内部槽,则将 serialized 设置为 { [[Type]]: "BigInt", [[BigIntData]]: value.[[BigIntData]] }。
否则,如果 value 有 [[StringData]] 内部槽,则将 serialized 设置为 { [[Type]]: "String", [[StringData]]: value.[[StringData]] }。
否则,如果 value 有 [[DateValue]] 内部槽,则将 serialized 设置为 { [[Type]]: "Date", [[DateValue]]: value.[[DateValue]] }。
否则,如果 value 有 [[RegExpMatcher]] 内部槽,则将 serialized 设置为 { [[Type]]: "RegExp", [[RegExpMatcher]]: value.[[RegExpMatcher]], [[OriginalSource]]: value.[[OriginalSource]], [[OriginalFlags]]: value.[[OriginalFlags]] }。
否则,如果 value 有 [[ArrayBufferData]] 内部槽,则:
如果 IsSharedArrayBuffer(value) 是 true,则:
如果 当前设置对象 的 跨域隔离能力 为
false,则抛出 "DataCloneError
" DOMException
。
此检查仅在序列化时需要(反序列化时不需要),因为 跨域隔离能力
不能随时间改变,且 SharedArrayBuffer
不能离开一个 agent 集群。
如果 forStorage 为 true,则抛出 "DataCloneError
" DOMException
。
如果 value 有 [[ArrayBufferMaxByteLength]] 内部槽,则将 serialized 设置为 { [[Type]]: "GrowableSharedArrayBuffer", [[ArrayBufferData]]: value.[[ArrayBufferData]], [[ArrayBufferByteLengthData]]: value.[[ArrayBufferByteLengthData]], [[ArrayBufferMaxByteLength]]: value.[[ArrayBufferMaxByteLength]], [[AgentCluster]]: 周围 agent 的 agent 集群 }。
否则,将 serialized 设置为 { [[Type]]: "SharedArrayBuffer", [[ArrayBufferData]]: value.[[ArrayBufferData]], [[ArrayBufferByteLength]]: value.[[ArrayBufferByteLength]], [[AgentCluster]]: 周围 agent 的 agent 集群 }。
否则:
如果 IsDetachedBuffer(value) 是
true,则抛出 "DataCloneError
" DOMException
。
让 size 为 value.[[ArrayBufferByteLength]]。
让 dataCopy 成为 ? CreateByteDataBlock(size)。
在分配失败时,这可能会抛出 RangeError
异常。
执行 CopyDataBlockBytes(dataCopy, 0, value.[[ArrayBufferData]], 0, size)。
如果 value 有 [[ArrayBufferMaxByteLength]] 内部槽,则将 serialized 设置为 { [[Type]]: "ResizableArrayBuffer", [[ArrayBufferData]]: dataCopy, [[ArrayBufferByteLength]]: size, [[ArrayBufferMaxByteLength]]: value.[[ArrayBufferMaxByteLength]] }。
否则,将 serialized 设置为 { [[Type]]: "ArrayBuffer", [[ArrayBufferData]]: dataCopy, [[ArrayBufferByteLength]]: size }。
否则,如果 value 有 [[ViewedArrayBuffer]] 内部槽,则:
如果 IsArrayBufferViewOutOfBounds(value) 是
true,则抛出 "DataCloneError
" DOMException
。
让 buffer 成为 value 的 [[ViewedArrayBuffer]] 内部槽的值。
让 bufferSerialized 成为 ? StructuredSerializeInternal(buffer, forStorage, memory)。
断言:bufferSerialized.[[Type]] 是 "ArrayBuffer"、"ResizableArrayBuffer"、"SharedArrayBuffer" 或 "GrowableSharedArrayBuffer"。
如果 value 有 [[DataView]] 内部槽,则将 serialized 设置为 { [[Type]]: "ArrayBufferView", [[Constructor]]: "DataView", [[ArrayBufferSerialized]]: bufferSerialized, [[ByteLength]]: value.[[ByteLength]], [[ByteOffset]]: value.[[ByteOffset]] }。
否则:
断言:value 有 [[TypedArrayName]] 内部槽。
将 serialized 设置为 { [[Type]]: "ArrayBufferView", [[Constructor]]: value.[[TypedArrayName]], [[ArrayBufferSerialized]]: bufferSerialized, [[ByteLength]]: value.[[ByteLength]], [[ByteOffset]]: value.[[ByteOffset]], [[ArrayLength]]: value.[[ArrayLength]] }。
否则,如果 value 有 [[MapData]] 内部槽,则:
将 serialized 设置为 { [[Type]]: "Map", [[MapData]]: 一个新的空 列表 }。
将 deep 设置为 true。
否则,如果 value 有 [[SetData]] 内部槽,则:
将 serialized 设置为 { [[Type]]: "Set", [[SetData]]: 一个新的空 列表 }。
将 deep 设置为 true。
否则,如果 value 有 [[ErrorData]] 内部槽且 value 不是 平台对象,则:
让 name 成为 ? 获取(value, "name")。
如果 name 不是 "Error"、"EvalError"、"RangeError"、"ReferenceError"、"SyntaxError"、"TypeError" 或 "URIError" 之一,则将 name 设置为 "Error"。
让 valueMessageDesc 成为 ? value.[[GetOwnProperty]]("message")。
如果 IsDataDescriptor(valueMessageDesc) 为 false,则将 message 设置为 undefined;否则,将 message 设置为 ? ToString(valueMessageDesc.[[Value]])。
将 serialized 设置为 { [[Type]]: "Error", [[Name]]: name, [[Message]]: message }。
用户代理应将尚未指定的任何有趣的附带数据的序列化表示附加到 serialized,特别是 stack
属性。
请参见 Error Stacks 提案,了解关于指定此数据的进行中的工作。[JSERRORSTACKS]
否则,如果 value 是一个数组异类对象,则:
让 valueLenDescriptor 成为 ? OrdinaryGetOwnProperty(value, "length")。
让 valueLen 成为 valueLenDescriptor.[[Value]]。
将 serialized 设置为 { [[Type]]: "Array", [[Length]]: valueLen, [[Properties]]: 一个新的空 列表 }。
将 deep 设置为 true。
否则,如果 value 是一个 平台对象,且是一个 可序列化对象:
如果 value 有一个值为 true 的 [[Detached]] 内部槽,则抛出 "DataCloneError
" DOMException
。
让 typeString 成为 主接口 的标识符。
将 serialized 设置为 { [[Type]]: typeString }。
将 deep 设置为 true。
否则,如果 value 是一个 平台对象,则抛出 "DataCloneError
" DOMException
。
否则,如果 IsCallable(value) 为 true,则抛出 "DataCloneError
" DOMException
。
否则,如果 value 有任何内部槽,除 [[Prototype]]、[[Extensible]] 或 [[PrivateElements]] 外,则抛出 "DataCloneError
" DOMException
。
例如,一个 [[PromiseState]] 或 [[WeakMapData]] 内部槽。
否则,如果 value 是一个异类对象,且 value 不是与任何 realm 关联的 %Object.prototype% 内在对象,则抛出 "DataCloneError
" DOMException
。
例如,一个代理对象。
否则:
将 serialized 设置为 { [[Type]]: "Object", [[Properties]]: 一个新的空 列表 }。
将 deep 设置为 true。
%Object.prototype% 将通过此步骤和后续步骤进行处理。最终结果是忽略其异类性,并且在反序列化后结果将是一个空对象(不是一个 不可变原型异类对象)。
设置 memory[value] 为 serialized。
如果 deep 为 true,则:
如果 value 有 [[MapData]] 内部槽,则:
让 copiedList 成为一个新的空 列表。
对于每个 记录 { [[Key]], [[Value]] } entry 在 copiedList 中:
让 serializedKey 成为 ? StructuredSerializeInternal(entry.[[Key]], forStorage, memory)。
让 serializedValue 成为 ? StructuredSerializeInternal(entry.[[Value]], forStorage, memory)。
将 { [[Key]]: serializedKey, [[Value]]: serializedValue } 附加 到 serialized.[[MapData]]。
否则,如果 value 有 [[SetData]] 内部槽,则:
否则,如果 value 是一个 平台对象,且是一个 可序列化对象,则为 value 的 主接口 执行 序列化步骤,给定 value、serialized 和 forStorage。
序列化步骤 可能需要执行 子序列化。这是一个以值 subValue 为输入的操作,并返回 StructuredSerializeInternal(subValue, forStorage, memory)。(换句话说,一个 子序列化 是 StructuredSerializeInternal 在此次调用中的特化。)
否则,对于 ! EnumerableOwnProperties(value, key) 中的每个 key:
如果 ! HasOwnProperty(value, key) 为 true,则:
让 inputValue 成为 ? value.[[Get]](key, value)。
让 outputValue 成为 ? StructuredSerializeInternal(inputValue, forStorage, memory)。
将 { [[Key]]: key, [[Value]]: outputValue } 附加 到 serialized.[[Properties]]。
返回 serialized。
需要注意的是,记录由StructuredSerializeInternal生成的可能包含指向其他记录的“指针”,这些指针会创建循环引用。例如,当我们将以下 JavaScript 对象传递给StructuredSerializeInternal时:
const o = {};
o. myself = o;
它会生成以下结果:
{ [[Type]]: "Object", [[Properties]]: « { [[Key]]: "myself", [[Value]]: <a pointer to this whole structure> } » }
返回 ? StructuredSerializeInternal(value, false)。
返回 ? StructuredSerializeInternal(value, true)。
结构化反序列化抽象操作接受一个记录serialized作为输入,该记录之前由结构化序列化或存储用结构化序列化生成,并将其反序列化为在targetRealm中创建的新JavaScript值。
此过程可能会抛出异常,例如在尝试为新对象(尤其是ArrayBuffer
对象)分配内存时。
如果未提供memory,则将memory设为空的映射。
memory映射的目的是避免对象的两次反序列化。这最终保留了图中循环和重复对象的身份。
如果memory[serialized] 存在,则返回memory[serialized]。
将deep设为false。
将value设为未初始化的值。
如果serialized.[[Type]]是"primitive",则将value设为serialized.[[Value]]。
否则,如果serialized.[[Type]]是"Boolean",则将value设为在targetRealm中新的Boolean对象,其[[BooleanData]]内部槽值为serialized.[[BooleanData]]。
否则,如果serialized.[[Type]]是"Number",则将value设为在targetRealm中新的Number对象,其[[NumberData]]内部槽值为serialized.[[NumberData]]。
否则,如果serialized.[[Type]]是"BigInt",则将value设为在targetRealm中新的BigInt对象,其[[BigIntData]]内部槽值为serialized.[[BigIntData]]。
否则,如果serialized.[[Type]]是"String",则将value设为在targetRealm中新的String对象,其[[StringData]]内部槽值为serialized.[[StringData]]。
否则,如果serialized.[[Type]]是"Date",则将value设为在targetRealm中新的Date对象,其[[DateValue]]内部槽值为serialized.[[DateValue]]。
否则,如果serialized.[[Type]]是"RegExp",则将value设为在targetRealm中新的RegExp对象,其[[RegExpMatcher]]内部槽值为serialized.[[RegExpMatcher]],其[[OriginalSource]]内部槽值为serialized.[[OriginalSource]],其[[OriginalFlags]]内部槽值为serialized.[[OriginalFlags]]。
否则,如果serialized.[[Type]]是"SharedArrayBuffer",则:
如果targetRealm对应的代理集群不是serialized.[[AgentCluster]],则抛出"DataCloneError
" DOMException
。
否则,将value设为在targetRealm中新的SharedArrayBuffer对象,其[[ArrayBufferData]]内部槽值为serialized.[[ArrayBufferData]],其[[ArrayBufferByteLength]]内部槽值为serialized.[[ArrayBufferByteLength]]。
否则,如果serialized.[[Type]]是"GrowableSharedArrayBuffer",则:
如果targetRealm对应的代理集群不是serialized.[[AgentCluster]],则抛出"DataCloneError
" DOMException
。
否则,将value设为在targetRealm中新的SharedArrayBuffer对象,其[[ArrayBufferData]]内部槽值为serialized.[[ArrayBufferData]],其[[ArrayBufferByteLengthData]]内部槽值为serialized.[[ArrayBufferByteLengthData]],其[[ArrayBufferMaxByteLength]]内部槽值为serialized.[[ArrayBufferMaxByteLength]]。
否则,如果serialized.[[Type]]是"ArrayBuffer",则将value设为在targetRealm中新的ArrayBuffer对象,其[[ArrayBufferData]]内部槽值为serialized.[[ArrayBufferData]],其[[ArrayBufferByteLength]]内部槽值为serialized.[[ArrayBufferByteLength]]。
如果这抛出了异常,捕获它,然后抛出"DataCloneError
" DOMException
。
如果没有足够的内存可用来创建这样的ArrayBuffer对象,此步骤可能会抛出异常。
否则,如果serialized.[[Type]]是"ResizableArrayBuffer",则将value设为在targetRealm中新的ArrayBuffer对象,其[[ArrayBufferData]]内部槽值为serialized.[[ArrayBufferData]],其[[ArrayBufferByteLength]]内部槽值为serialized.[[ArrayBufferByteLength]],其[[ArrayBufferMaxByteLength]]内部槽值为serialized.[[ArrayBufferMaxByteLength]]。
如果这抛出了异常,捕获它,然后抛出"DataCloneError
" DOMException
。
如果没有足够的内存可用来创建这样的ArrayBuffer对象,此步骤可能会抛出异常。
否则,如果serialized.[[Type]]是"ArrayBufferView",则:
让deserializedArrayBuffer为? 结构化反序列化(serialized.[[ArrayBufferSerialized]], targetRealm, memory)。
如果serialized.[[Constructor]]是"DataView",则将value设为在targetRealm中新的DataView对象,其[[ViewedArrayBuffer]]内部槽值为deserializedArrayBuffer,其[[ByteLength]]内部槽值为serialized.[[ByteLength]],其[[ByteOffset]]内部槽值为serialized.[[ByteOffset]]。
否则,将value设为在targetRealm中新的类型数组对象,使用serialized.[[Constructor]]给定的构造函数,其[[ViewedArrayBuffer]]内部槽值为deserializedArrayBuffer,其[[TypedArrayName]]内部槽值为serialized.[[Constructor]],其[[ByteLength]]内部槽值为serialized.[[ByteLength]],其[[ByteOffset]]内部槽值为serialized.[[ByteOffset]],其[[ArrayLength]]内部槽值为serialized.[[ArrayLength]]。
否则,如果serialized.[[Type]]是"Map",则:
将value设为在targetRealm中新的Map对象,其[[MapData]]内部槽值为新的空列表。
将deep设为true。
否则,如果serialized.[[Type]]是"Set",则:
将value设为在targetRealm中新的Set对象,其[[SetData]]内部槽值为新的空列表。
将deep设为true。
否则,如果serialized.[[Type]]是"Array",则:
让outputProto为targetRealm.[[Intrinsics]].[[%Array.prototype%]]。
将value设为! 数组创建(serialized.[[Length]], outputProto)。
将deep设为true。
否则,如果serialized.[[Type]]是"Object",则:
将value设为在targetRealm中的新对象。
将deep设为true。
否则,如果serialized.[[Type]]是"Error",则:
让prototype为%Error.prototype%。
如果serialized.[[Name]]是"EvalError",则将prototype设为%EvalError.prototype%。
如果serialized.[[Name]]是"RangeError",则将prototype设为%RangeError.prototype%。
如果serialized.[[Name]]是"ReferenceError",则将prototype设为%ReferenceError.prototype%。
如果serialized.[[Name]]是"SyntaxError",则将prototype设为%SyntaxError.prototype%。
如果serialized.[[Name]]是"TypeError",则将prototype设为%TypeError.prototype%。
如果serialized.[[Name]]是"URIError",则将prototype设为%URIError.prototype%。
让 message为serialized.[[Message]]。
将value设为普通对象创建(prototype,«[[ErrorData]]»)。
让messageDesc为属性描述符{[[Value]]: message, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}。
如果message不为undefined,则执行! 普通定义自有属性(value, "message
",
messageDesc)。
任何附加到serialized上的有趣的附加数据都应该被反序列化并附加到value上。
否则:
让interfaceName为serialized.[[Type]]。
如果interfaceName标识的接口在targetRealm中不是暴露的,则抛出"DataCloneError
" DOMException
。
将value设为在targetRealm中创建的由interfaceName标识的接口的新实例。
将deep设为true。
设置 memory[serialized]为value。
如果deep为true,则:
如果serialized.[[Type]]是"Map",则:
否则,如果serialized.[[Type]]是"Set",则:
否则,如果serialized.[[Type]]是"Array"或"Object",则:
否则:
返回value。
让 memory 为一个空的map。
除了 StructuredSerializeInternal 正常使用外,在这个算法中 memory 还用于确保 StructuredSerializeInternal 忽略 transferList 中的项目,并让我们自己处理。
对于每个 transferable 的 transferList:
如果 transferable 既没有 [[ArrayBufferData]] 内部槽也没有[[Detached]] 内部槽,则抛出 "DataCloneError
" DOMException
。
如果 transferable 具有 [[ArrayBufferData]] 内部槽且 IsSharedArrayBuffer(transferable) 为真,则抛出 "DataCloneError
" DOMException
。
如果 memory[transferable] 存在,则抛出 "DataCloneError
" DOMException
。
设置 memory[transferable] 为 {[[Type]]: 未初始化的值}。
transferable 尚未传输,因为传输有副作用,并且 StructuredSerializeInternal 需要先能够抛出。
让 serialized 为 ? StructuredSerializeInternal(value, false, memory)。
让 transferDataHolders 为一个新的空的 List。
对于每个 transferable 的 transferList:
如果 transferable 具有 [[ArrayBufferData]] 内部槽且 IsDetachedBuffer(transferable) 为真,则抛出 "DataCloneError
" DOMException
。
如果 transferable 具有 [[Detached]] 内部槽且 transferable.[[Detached]]
为真,则抛出 "DataCloneError
" DOMException
。
让 dataHolder 为 memory[transferable]。
如果 transferable 具有 [[ArrayBufferData]] 内部槽,则:
如果 transferable 具有 [[ArrayBufferMaxByteLength]] 内部槽,则:
将 dataHolder.[[Type]] 设为 "ResizableArrayBuffer"。
将 dataHolder.[[ArrayBufferData]] 设为 transferable.[[ArrayBufferData]]。
将 dataHolder.[[ArrayBufferByteLength]] 设为 transferable.[[ArrayBufferByteLength]]。
将 dataHolder.[[ArrayBufferMaxByteLength]] 设为 transferable.[[ArrayBufferMaxByteLength]]。
否则:
将 dataHolder.[[Type]] 设为 "ArrayBuffer"。
将 data Holder.[[ArrayBufferData]] 设为 transferable.[[ArrayBufferData]]。
将 dataHolder.[[ArrayBufferByteLength]] 设为 transferable.[[ArrayBufferByteLength]]。
执行 ? DetachArrayBuffer(transferable)。
规范可以使用 [[ArrayBufferDetachKey]] 内部槽来防止 ArrayBuffer
被分离。例如,这在 WebAssembly JavaScript Interface 中使用。[WASMJS]
否则:
追加 dataHolder 到 transferDataHolders。
返回 { [[Serialized]]: serialized, [[TransferDataHolders]]: transferDataHolders }。
让 memory 为一个空的map。
类似于 StructuredSerializeWithTransfer,除了正常被 StructuredDeserialize 使用外,在这个算法中 memory 还用于确保 StructuredDeserialize 忽略 serializeWithTransferResult.[[TransferDataHolders]] 中的项目,让我们自己进行处理。
让 transferredValues 为一个新的空的List。
对于每个 transferDataHolder 的 serializeWithTransferResult.[[TransferDataHolders]]:
让 value 为一个未初始化的值。
如果 transferDataHolder.[[Type]] 是 "ArrayBuffer",则将 value 设为在 targetRealm 中创建的新 ArrayBuffer 对象,其 [[ArrayBufferData]] 内部槽值为 transferDataHolder.[[ArrayBufferData]],且 [[ArrayBufferByteLength]] 内部槽值为 transferDataHolder.[[ArrayBufferByteLength]]。
在原始内存仍可访问的情况下,这一步骤不太可能抛出异常,因为不需要分配新的内存:[[ArrayBufferData]] 占用的内存只是被转移到新的 ArrayBuffer 中。这可能在源和目标领域在同一进程中时为真。
否则,如果 transferDataHolder.[[Type]] 是 "ResizableArrayBuffer",则将 value 设为在 targetRealm 中创建的新 ArrayBuffer 对象,其 [[ArrayBufferData]] 内部槽值为 transferDataHolder.[[ArrayBufferData]],[[ArrayBufferByteLength]] 内部槽值为 transferDataHolder.[[ArrayBufferByteLength]],以及 [[ArrayBufferMaxByteLength]] 内部槽值为 transferDataHolder.[[ArrayBufferMaxByteLength]]。
与前一步相同,这一步骤也不太可能抛出异常。
否则:
让 interfaceName 为 transferDataHolder.[[Type]]。
如果由 interfaceName 标识的接口在 targetRealm 中不可用,则抛出 "DataCloneError
"
DOMException
。
将 value 设为在 targetRealm 中创建的由 interfaceName 标识的接口的新实例。
执行适当的接收转移步骤,针对由 interfaceName 标识的接口,给定 transferDataHolder 和 value。
设置 memory[transferDataHolder] 为 value。
追加 value 到 transferredValues。
让 deserialized 为 ? StructuredDeserialize(serializeWithTransferResult.[[Serialized]], targetRealm, memory)。
返回 { [[Deserialized]]: deserialized, [[TransferredValues]]: transferredValues }。
其他规范可以使用此处定义的抽象操作。以下提供了一些关于每个抽象操作通常何时有用的指导,并附有示例。
将一个值克隆到另一个realm,使用一个传输列表,但目标realm事先未知。在这种情况下,可以立即执行序列化步骤,而反序列化步骤则延迟到目标realm变得已知时再进行。
messagePort.postMessage()
使用这对抽象操作,因为直到MessagePort
已被发送后,目标realm才会变得已知。
创建一个给定值的realm独立快照,可以保存无限期的时间,然后在以后重新成为JavaScript值,可能多次。
StructuredSerializeForStorage
可用于预期要以持久方式存储序列化结果,而不是在realm之间传递。它在尝试序列化SharedArrayBuffer
对象时会抛出异常,因为存储共享内存没有意义。同样,当给定一个具有自定义序列化步骤的平台对象时,forStorage参数为true时,它可能抛出异常或具有不同的行为。
history.pushState()
和 history.replaceState()
使用StructuredSerializeForStorage
作用于作者提供的状态对象,将它们作为序列化状态存储在相应的会话历史条目中。然后,StructuredDeserialize
被用来让history.state
属性返回原始状态对象的克隆。
broadcastChannel.postMessage()
在其输入上使用StructuredSerialize,然后对结果多次使用StructuredDeserialize,以便为每个广播目的地产生一个新的克隆。请注意,在多目的地情况下,传输是不合适的。
任何用于将JavaScript值持久化到文件系统的API也会在其输入上使用StructuredSerializeForStorage,并在其输出上使用StructuredDeserialize。
一般来说,调用点可能会传递Web IDL值而不是JavaScript值;这应该理解为在调用这些算法之前执行隐式转换为JavaScript值。
那些不是因为作者代码同步调用用户代理方法而调用的调用点,必须在调用StructuredSerialize、StructuredSerializeForStorage 或 StructuredSerializeWithTransfer抽象操作之前,做好适当的准备运行脚本和准备运行回调。这是必要的,因为序列化过程可以在其最终深度序列化步骤中调用作者定义的访问器,而这些访问器可能会调用依赖于正确设置entry和incumbent概念的操作。
window.postMessage()
在其参数上执行StructuredSerializeWithTransfer,但要小心立即在其算法的同步部分内执行。因此,它可以使用这些算法,而不需要准备运行脚本和准备运行回调。
相比之下,一个假设的API,使用StructuredSerialize来定期序列化一些作者提供的对象,直接从任务在事件循环上进行,将需要确保它事先执行适当的准备。截至目前,我们知道平台上没有这样的API;通常,提前进行序列化作为作者代码的同步结果会更简单。
result = self.structuredClone(value[, { transfer }])
获取输入值并通过执行结构化克隆算法返回一个深拷贝。可转移对象列在transfer
数组中,这些对象被转移而不仅仅是克隆,这意味着它们在输入值中不再可用。
如果输入值的任何部分不是可序列化对象,则抛出一个"DataCloneError
" DOMException
。
所有当前引擎都支持。
structuredClone(value,
options)
方法步骤如下:
让serialized为 ? StructuredSerializeWithTransfer(value,
options["transfer
"])。
让deserializeRecord为 ? StructuredDeserializeWithTransfer(serialized, this的相关realm)。
返回deserializeRecord.[[Deserialized]]。
HTML UA中的每个XML和HTML文档都由一个Document
对象表示。[DOM]
Document
对象的URL在DOM中定义。它在Document
对象创建时设置,但在Document
对象的生命周期内可以更改;例如,当用户导航到页面上的片段时以及当调用pushState()
方法时URL会更改。[DOM]
交互式用户代理通常在其用户界面中显示Document
对象的URL。这是用户判断网站是否试图冒充其他网站的主要机制。
Document
对象的origin在DOM中定义。它在Document
对象创建时设置,并且只有在设置document.domain
时才能在Document
的生命周期内更改。Document
的origin可以与其URL的origin不同;例如,当创建一个子导航时,它的活动文档的origin继承自其父文档的活动文档的origin,即使其活动文档的URL是about:blank
。[DOM]
当一个Document
由脚本使用createDocument()
或createHTMLDocument()
方法创建时,Document
会立即准备好进行加载后任务。
文档的引用者是一个字符串(表示URL),可以在Document
创建时设置。如果未显式设置,则其值为空字符串。
Document
对象所有当前引擎支持。
DOM 定义了一个 Document
接口,本规范对其进行了显著扩展。
enum DocumentReadyState { "loading" , "interactive" , "complete" };
enum DocumentVisibilityState { "visible" , "hidden" };
typedef (HTMLScriptElement or SVGScriptElement ) HTMLOrSVGScriptElement ;
[LegacyOverrideBuiltIns ]
partial interface Document {
static Document
parseHTMLUnsafe ((TrustedHTML
or DOMString ) html );
// resource metadata management
[PutForwards =href , LegacyUnforgeable ] readonly attribute Location ? location ;
attribute USVString domain ;
readonly attribute USVString referrer ;
attribute USVString cookie ;
readonly attribute DOMString lastModified ;
readonly attribute DocumentReadyState readyState ;
// DOM tree accessors
getter object (DOMString name );
[CEReactions ] attribute DOMString title ;
[CEReactions ] attribute DOMString dir ;
[CEReactions ] attribute HTMLElement ? body ;
readonly attribute HTMLHeadElement ? head ;
[SameObject ] readonly attribute HTMLCollection images ;
[SameObject ] readonly attribute HTMLCollection embeds ;
[SameObject ] readonly attribute HTMLCollection plugins ;
[SameObject ] readonly attribute HTMLCollection links ;
[SameObject ] readonly attribute HTMLCollection forms ;
[SameObject ] readonly attribute HTMLCollection scripts ;
NodeList getElementsByName (DOMString elementName );
readonly attribute HTMLOrSVGScriptElement ? currentScript ; // classic scripts in a document tree only
// dynamic markup insertion
[CEReactions ] Document open (optional DOMString unused1 , optional DOMString unused2 ); // both arguments are ignored
WindowProxy ? open (USVString url , DOMString name , DOMString features );
[CEReactions ] undefined close ();
[CEReactions ] undefined write ((TrustedHTML
or DOMString )... text );
[CEReactions ] undefined writeln ((TrustedHTML
or DOMString )... text );
// user interaction
readonly attribute WindowProxy ? defaultView ;
boolean hasFocus ();
[CEReactions ] attribute DOMString designMode ;
[CEReactions ] boolean execCommand (DOMString commandId , optional boolean showUI = false , optional DOMString value = "");
boolean queryCommandEnabled (DOMString commandId );
boolean queryCommandIndeterm (DOMString commandId );
boolean queryCommandState (DOMString commandId );
boolean queryCommandSupported (DOMString commandId );
DOMString queryCommandValue (DOMString commandId );
readonly attribute boolean hidden ;
readonly attribute DocumentVisibilityState visibilityState ;
// special event handler IDL attributes that only apply to Document objects
[LegacyLenientThis ] attribute EventHandler onreadystatechange ;
attribute EventHandler onvisibilitychange ;
// also has obsolete members
};
Document includes GlobalEventHandlers ;
每个Document
都有一个policy container(policy
container),最初是一个新的policy container,其中包含适用于Document
的策略。
每个Document
都有一个权限策略,这是一个权限策略,最初为空。
每个Document
都有一个模块映射,这是一个模块映射,最初为空。
每个Document
都有一个打开策略,这是一个跨域打开策略,最初是一个新的跨域打开策略。
每个Document
都有一个是否初始about:blank
,这是一个布尔值,最初为false。
每个Document
都有一个用于WebDriver BiDi的加载中导航ID,这是一个导航ID或null,最初为null。
正如其名称所示,这用于与WebDriver BiDi规范进行接口,该规范需要在Document
生命周期的早期部分通知某些事件发生的方式,将它们与创建此Document
的导航ID联系起来。当导航被视为正在进行的导航
时,最终会将其设置回null,在WebDriver
BiDi认为加载过程已完成后。[BIDI]
每个Document
都有一个about base URL,这是一个URL或null,最初为null。
这仅适用于“about:
”协议的Document
。
每个Document
都有一个bfcache阻止详情,这是一个集合,包含未恢复原因详情,最初为空。
DocumentOrShadowRoot
接口DOM 定义了 DocumentOrShadowRoot
mixin,本规范对此进行了扩展。
partial interface mixin DocumentOrShadowRoot {
readonly attribute Element ? activeElement ;
};
document.referrer
所有当前引擎支持。
返回用户从中导航到此页面的Document
的URL,如果被阻止或没有这样的文档,则返回空字符串。
noreferrer
链接类型可用于阻止referrer。
referrer
属性必须返回文档的引用者。
document.cookie [ = value ]
返回适用于Document
的HTTP
cookies。如果没有cookies或cookies不能应用于此资源,则返回空字符串。
可以设置,以将新cookie添加到元素的HTTP cookies集中。
如果内容被沙盒化为不透明来源(例如,在具有iframe
的sandbox
属性的iframe中),则在获取和设置时会抛出DOMException
类型的"SecurityError"。
所有当前引擎支持。
cookie
属性表示由文档的URL标识的资源的cookies。
满足以下条件之一的Document
对象是cookie-averse Document
对象:
在获取时,如果文档是cookie-averse
Document
对象,则用户代理必须返回空字符串。否则,如果Document
的来源是不透明来源,用户代理必须抛出DOMException
类型的"SecurityError"。否则,用户代理必须返回文档的cookie-string,对于“非HTTP”API,使用UTF-8解码(无BOM)进行解码。[COOKIES]
在设置时,如果文档是cookie-averse
Document
对象,则用户代理必须什么也不做。否则,如果Document
的来源是不透明来源,用户代理必须抛出DOMException
类型的"SecurityError"。否则,用户代理必须按照接收文档的URL的set-cookie-string处理新值,使用UTF-8编码。[COOKIES] [ENCODING]
由于cookie
属性可跨帧访问,因此cookies的路径限制只是帮助管理cookies发送到站点不同部分的工具,而不是安全功能。
cookie
属性的getter和setter同步访问共享状态。由于没有锁机制,多个进程用户代理中的其他浏览上下文可以在脚本运行时修改cookies。例如,一个站点可以尝试读取cookie,增加其值,然后写回新值,使用cookie的新值作为会话的唯一标识符;如果该站点在两个不同的浏览器窗口中同时进行两次此操作,可能会使用相同的“唯一”标识符来表示两个会话,可能会产生灾难性后果。
document.lastModified
所有当前引擎支持。
返回服务器报告的文档的最后修改日期,格式为“MM/DD/YYYY hh:mm:ss
”,以用户的本地时区表示。
如果不知道最后的修改日期,则返回当前时间。
lastModified
属性在获取时必须返回文档源文件最后修改的日期和时间,以用户的本地时区,格式如下:
日期的月份部分。
U+002F SOLIDUS字符(/)。
日期的天部分。
U+002F SOLIDUS字符(/)。
日期的年份部分。
U+0020 SPACE字符。
时间的小时部分。
U+003A COLON字符(:)。
时间的分钟部分。
U+003A COLON字符(:)。
时间的秒部分。
上述所有的数字部分,除年份外,必须表示为基数十的两个ASCII数字,必要时填充零。年份必须表示为最短可能的字符串,至少四个ASCII数字,必要时填充零。
Document
的源文件最后修改日期和时间必须从使用的网络协议的相关特性中获取,例如从文档的HTTP
Last-Modified
标头的值或本地文件的文件系统元数据中获取。如果最后修改日期和时间未知,属性必须返回上述格式的当前日期和时间。
document.readyState
在Document
加载时返回“loading
”,解析完成但仍在加载子资源时返回“interactive
”,加载完成后返回“complete
”。
当此值发生变化时,readystatechange
事件会在Document
对象上触发。
在从“interactive
”过渡到“complete
”之前,当除async
script
元素外的所有子资源加载完成时,会触发DOMContentLoaded
事件。
所有当前引擎支持。
每个Document
都有一个当前文档准备状态,一个字符串,最初为“complete
”。
对于通过创建和初始化Document
对象算法创建的Document
对象,这将在任何脚本观察到document.readyState
值之前立即重置为“loading
”。此默认值适用于其他情况,例如初始
about:blank
Document
或没有浏览上下文的Document
。
readyState
getter步骤是返回this的当前文档准备状态。
要为Document
document更新当前文档准备状态为readinessValue:
如果document的当前文档准备状态等于readinessValue,则返回。
将document的当前文档准备状态设置为readinessValue。
如果document与HTML解析器相关联,则:
触发一个事件,名为readystatechange
在document。
如果一个Document
与尚未停止或中止的HTML解析器或XML解析器相关联,则称其具有活动解析器。
Document
有一个文档卸载时间信息 以前的文档卸载时间。
Document
有一个布尔值通过跨域重定向创建,最初为false。
DOMHighResTimeStamp
值
DOMHighResTimeStamp
值
每个Document
都有一个渲染阻塞元素集合,这是一个集合,初始为空集合。
如果Document
document的内容类型是“text/html
”并且document的body元素为null,则document允许添加渲染阻塞元素。
如果以下两个条件都为真,则Document
document被认为是渲染阻塞:
document的渲染阻塞元素集合非空,或者document允许添加渲染阻塞元素。
如果元素el的节点文档
document被渲染阻塞
并且el在document的渲染阻塞元素集合中,则el是渲染阻塞的。
要阻止渲染元素el:
令document为el的节点文档。
如果document允许添加渲染阻塞元素,则将el附加到document的渲染阻塞元素集合中。
要解除渲染阻塞元素el:
每当渲染阻塞
元素el变为浏览上下文断开,或者el的阻塞属性的值发生变化,使el不再潜在地渲染阻塞时,则解除渲染阻塞el。
文档的html
元素是它的文档元素,如果它是一个html
元素,否则为
null。
document.head
Support in all current engines.
返回head 元素。
文档的head
元素是第一个作为head
元素的子元素,如果存在,否则为
null。
在获取时,head
属性必须返回文档的head 元素(一个head
元素或
null)。
document.title [ = value ]
返回文档的标题,如由 HTML 中的title 元素和 SVG 中的SVG title 元素所给定的。
可以设置,以更新文档的标题。如果没有合适的元素可以更新,新值将被忽略。
文档的title
元素是文档中的第一个title
元素(按树顺序),如果存在,否则为 null。
Support in all current engines.
在获取时,title
属性必须运行以下算法:
去除并折叠 ASCII 空白在value中。
返回value。
在设置时,必须运行以下列表中第一个匹配条件的步骤:
svg
元素
什么也不做。
document.body [ = value ]
Support in all current engines.
返回body 元素。
可以设置,以替换body 元素。
如果新值不是body
或frameset
元素,这将抛出一个"HierarchyRequestError
" DOMException
。
文档的 body 元素是第一个作为html 元素的子元素的body 元素或frameset 元素,如果存在,否则为 null。
在获取时,body
属性必须返回文档的body 元素(一个body
元素,一个frameset
元素,或
null)。在设置时,必须运行以下算法:
body
或frameset
元素,则抛出一个"HierarchyRequestError
" DOMException
。
HierarchyRequestError
" DOMException
。
由body
获取器返回的值不总是传递给设置器的值。
在这个例子中,setter 成功地插入了一个 body
元素(虽然这不符合规范,因为 SVG 不允许 body
作为 SVG
svg
的子元素)。然而,getter 将返回 null,因为文档元素不是
html
。
< svg xmlns = "http://www.w3.org/2000/svg" >
< script >
document. body = document. createElementNS( "http://www.w3.org/1999/xhtml" , "body" );
console. assert( document. body === null );
</ script >
</ svg >
document.images
所有当前引擎都支持。
返回一个HTMLCollection
,其中包含img
元素在Document
中。
document.embeds
所有当前引擎都支持。
document.plugins
所有当前引擎都支持。
返回一个HTMLCollection
,其中包含embed
元素在Document
中。
document.links
所有当前引擎都支持。
返回一个HTMLCollection
,其中包含a
和area
元素在Document
中具有href
属性。
document.forms
所有当前引擎都支持。
返回一个 HTMLCollection
,包含在
form
元素的 Document
中。
document.scripts
所有当前引擎都支持。
返回一个HTMLCollection
,包含script
元素在Document
中。
images
属性必须返回一个根植于HTMLCollection
在Document
节点,过滤器仅匹配img
元素。
embeds
属性必须返回一个根植于HTMLCollection
在Document
节点,过滤器仅匹配embed
元素。
plugins
属性必须返回与embeds
属性返回的对象相同的对象。
links
属性必须返回一个根植于HTMLCollection
在Document
节点,过滤器仅匹配带有a
元素的href
属性和带有area
元素的href
属性。
forms
属性必须返回一个HTMLCollection
的根节点在文档
节点,过滤器仅匹配form
元素。
scripts
属性必须返回一个HTMLCollection
的根节点在文档
节点,过滤器仅匹配script
元素。
collection = document.getElementsByName(name)
Support in all current engines.
getElementsByName(elementName)
方法步骤是返回一个实时 NodeList
包含文档中所有有name
属性值为elementName的HTML 元素,按树顺序。当该方法再次在文档
对象上使用相同的参数调用时,用户代理可以返回与之前调用返回的对象相同的对象。在其他情况下,必须返回一个新的NodeList
对象。
document.currentScript
Support in all current engines.
返回script
元素,或者SVG script
元素,当前正在执行的脚本,只要该元素代表一个经典脚本。在递归脚本执行的情况下,返回最早开始执行但尚未完成执行的脚本。
如果文档
当前没有执行script
或SVG script
元素(例如,因为正在运行的脚本是事件处理程序或超时),或者当前正在执行的script
或SVG script
元素代表一个模块脚本,则返回 null。
currentScript
属性,在获取时,必须返回最近设置的值。当文档
创建时,currentScript
必须初始化为
null。
此 API 在实现者和标准社区中已经失宠,因为它全局暴露script
或SVG script
元素。因此,它在较新的上下文中不可用,例如运行模块脚本或在影子树中运行脚本时。我们正在研究在这种上下文中识别运行脚本的新解决方案,这不会使其全局可用:请参见问题#1013。
接口Document
支持命名属性。支持的属性名称在文档
对象document的任何时刻包括以下内容,按贡献它们的元素的树顺序,忽略后面的重复项,值来自id
属性在来自name
属性的值之前贡献相同时:
为了确定命名属性name的值对于文档
,用户代理必须返回使用以下步骤获得的值:
让elements成为带有name的命名元素的列表,这些元素在文档树中的文档
作为其根根。
会有至少一个这样的元素,因为该算法否则不会被由 Web IDL 调用。
如果elements只有一个元素,并且该元素是iframe
元素,并且该iframe
元素的内容可导航不为
null,则返回该元素的活动WindowProxy
。
否则,如果elements只有一个元素,则返回该元素。
否则,返回一个HTMLCollection
的根节点在文档
节点,过滤器仅匹配具有名称name的命名元素。
命名元素带有名称name,对于上述算法而言,是那些要么是:
embed
,form
,iframe
,img
或暴露的object
元素,其name
内容属性的值为name,或者
object
元素,其id
内容属性的值为name,或者
img
元素,其id
内容属性的值为name,并且该元素也具有非空的name
内容属性。
embed
或object
元素被称为暴露的如果它没有暴露的object
祖先,并且对于object
元素,此外,还没有显示其回退内容或没有object
或embed
后代。
HTML中的元素、属性和属性值被定义为具有某些意义(语义)。例如,ol
元素表示一个有序列表,lang
属性表示内容的语言。
这些定义使HTML处理器(如网络浏览器或搜索引擎)能够在作者可能没有考虑到的各种环境中展示和使用文档和应用程序。
作为一个简单的例子,考虑一个仅考虑桌面计算机网络浏览器的作者编写的网页:
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< title > My Page</ title >
</ head >
< body >
< h1 > Welcome to my page</ h1 >
< p > I like cars and lorries and have a big Jeep!</ p >
< h2 > Where I live</ h2 >
< p > I live in a small hut on a mountain!</ p >
</ body >
</ html >
因为HTML传达的是意义,而不是展示,同样的页面也可以被移动电话上的小型浏览器使用,而无需对页面进行任何更改。例如,移动电话上的浏览器可能会使用整个页面相同大小的文本,而不是像在桌面上一样的大字体,但标题部分会使用加粗。
这不仅仅是屏幕尺寸的差异:同样的页面也可以被盲人使用,他们使用基于语音合成的浏览器,这种浏览器不是在屏幕上显示页面,而是通过耳机等方式将页面读给用户听。例如,语音浏览器可能会使用不同的音量或较慢的语速来代替大字体来处理标题。
不仅如此。因为浏览器知道页面的哪些部分是标题,它们可以创建一个文档大纲,用户可以使用“跳到下一个标题”或“跳到上一个标题”的键快速导航文档。这种功能在语音浏览器中特别常见,否则用户会发现快速导航页面相当困难。
甚至超越浏览器,软件也可以利用这些信息。搜索引擎可以使用标题更有效地索引页面,或在其结果中提供到页面各部分的快速链接。工具可以使用标题创建目录(实际上,这正是本规范的目录生成方式)。
这个例子主要关注标题,但相同的原理适用于HTML中的所有语义。
作者不得将元素、属性或属性值用于其预期语义目的以外的用途,因为这样会导致软件无法正确处理页面。
例如,以下代码片段,旨在表示企业网站的标题,是不符合规范的,因为第二行不是子部分的标题,而仅仅是副标题(同一部分的从属标题)。
< body >
< h1 > ACME Corporation</ h1 >
< h2 > The leaders in arbitrary fast delivery since 1920</ h2 >
...
hgroup
元素可以用于这种情况:
< body >
< hgroup >
< h1 > ACME Corporation</ h1 >
< p > The leaders in arbitrary fast delivery since 1920</ p >
</ hgroup >
...
下一个示例中的文档尽管在语法上是正确的,但在语义上是不符合规范的,因为单元格中的数据显然不是表格数据,并且错误使用了cite
元素:
<!DOCTYPE HTML>
< html lang = "en-GB" >
< head > < title > Demonstration </ title > </ head >
< body >
< table >
< tr > < td > My favourite animal is the cat. </ td > </ tr >
< tr >
< td >
—< a href = "https://example.org/~ernest/" >< cite > Ernest</ cite ></ a > ,
in an essay from 1992
</ td >
</ tr >
</ table >
</ body >
</ html >
这会导致依赖这些语义的软件出现故障:例如,允许盲人用户导航文档中的表格的语音浏览器会将上述引用报告为表格,从而使用户感到困惑;同样,提取页面标题的工具会将“Ernest”提取为作品的标题,尽管它实际上是一个人的名字,而不是标题。
该文档的更正版本可能如下:
<!DOCTYPE HTML>
< html lang = "en-GB" >
< head > < title > Demonstration </ title > </ head >
< body >
< blockquote >
< p > My favourite animal is the cat. </ p >
</ blockquote >
< p >
—< a href = "https://example.org/~ernest/" > Ernest</ a > ,
in an essay from 1992
</ p >
</ body >
</ html >
作者不得使用本规范或其他适用规范不允许的元素、属性或属性值,因为这样会使将来扩展语言变得非常困难。
在下一个例子中,有一个不符合规范的属性值(“carpet”)和一个不符合规范的属性(“texture”),它们不被本规范允许:
< label > Carpet: < input type = "carpet" name = "c" texture = "deep pile" ></ label >
这是标记这种内容的另一种正确方式:
< label > Carpet: < input type = "text" class = "carpet" name = "c" data-texture = "deep pile" ></ label >
其节点文档的浏览上下文为null的DOM节点不受所有文档一致性要求的约束,除了HTML语法要求和XML语法要求。
特别是,template
元素的模板内容的节点文档的浏览上下文为null。例如,内容模型要求和属性值微语法要求不适用于template
元素的模板内容。在这个示例中,一个img
元素具有在template
元素之外无效的占位符属性值。
< template >
< article >
< img src = "{{src}}" alt = "{{alt}}" >
< h1 ></ h1 >
</ article >
</ template >
然而,如果上面的标记省略了</h1>
结束标签,那将违反HTML语法,并因此被一致性检查器标记为错误。
通过脚本和其他机制,属性值、文本,甚至整个文档的结构可以在用户代理处理时动态变化。某一时刻文档的语义是由该时刻文档的状态表示的,因此文档的语义可能随时间变化。用户代理必须在这种变化发生时更新其对文档的展示。
HTML有一个progress
元素描述进度条。如果其“value”属性由脚本动态更新,UA将更新渲染以显示进度的变化。
DOM中表示HTML元素的节点必须实现并向脚本公开本规范相关部分列出的接口。这包括在HTML元素在XML文档中,即使这些文档在另一个上下文中(例如在XSLT转换内)。
DOM中的元素代表事物;也就是说,它们具有内在的意义,也称为语义。
例如,一个ol
元素代表一个有序列表。
元素可以通过某种方式显式或隐式地被引用。DOM中的元素可以通过给元素一个id
属性,然后创建一个超链接,使用该id
属性的值作为片段标识符,来显式引用该元素。然而,引用并不需要超链接;任何引用该元素的方法都可以。
< figure id = "module-script-graph" >
< img src = "module-script-graph.svg"
alt = "Module A depends on module B, which depends
on modules C and D." >
< figcaption > Figure 27: a simple module graph</ figcaption >
</ figure >
As we can see in < a href = "#module-script-graph" > figure 27</ a > , ...
“如模块A、B、C和D的图中所示...”
“在图27中...”(没有超链接)
“从‘简单模块图’图的内容中...”
“在下面的图中...”(但不推荐这样做)
所有HTML元素接口继承的基本接口,并且必须由没有其他要求的元素使用的是HTMLElement
接口。
所有当前引擎支持。
所有当前引擎支持。
[Exposed =Window ]
interface HTMLElement : Element {
[HTMLConstructor ] constructor ();
// metadata attributes
[CEReactions ] attribute DOMString title ;
[CEReactions ] attribute DOMString lang ;
[CEReactions ] attribute boolean translate ;
[CEReactions ] attribute DOMString dir ;
// user interaction
[CEReactions ] attribute (boolean or unrestricted double or DOMString )? hidden ;
[CEReactions ] attribute boolean inert ;
undefined click ();
[CEReactions ] attribute DOMString accessKey ;
readonly attribute DOMString accessKeyLabel ;
[CEReactions ] attribute boolean draggable ;
[CEReactions ] attribute boolean spellcheck ;
[CEReactions ] attribute DOMString writingSuggestions ;
[CEReactions ] attribute DOMString autocapitalize ;
[CEReactions ] attribute boolean autocorrect ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString innerText ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString outerText ;
ElementInternals attachInternals ();
// The popover API
undefined showPopover ();
undefined hidePopover ();
boolean togglePopover (optional boolean force );
[CEReactions ] attribute DOMString ? popover ;
};
HTMLElement includes GlobalEventHandlers ;
HTMLElement includes ElementContentEditable ;
HTMLElement includes HTMLOrSVGElement ;
[Exposed =Window ]
interface HTMLUnknownElement : HTMLElement {
// Note: intentionally no [HTMLConstructor]
};
HTMLElement
接口包含与许多不同特性相关的方法和属性,因此该接口的成员在本规范的各个不同部分中进行了描述。
如果name是applet
、bgsound
、blink
、isindex
、keygen
、multicol
、nextid
或spacer
,则返回HTMLUnknownElement
。
如果name是acronym
、basefont
、big
、center
、nobr
、noembed
、noframes
、plaintext
、rb
、rtc
、strike
或tt
,则返回HTMLElement
。
如果name是listing
或xmp
,则返回HTMLPreElement
。
否则,如果本规范定义了与局部名称name对应的元素类型的适当接口,则返回该接口。
如果其他适用规范定义了name的适当接口,则返回它们定义的接口。
如果name是有效的自定义元素名称,则返回HTMLElement
。
在有效的自定义元素名称的情况下,使用HTMLElement
而不是HTMLUnknownElement
是为了确保任何潜在的未来升级只会导致元素原型链的线性过渡,从HTMLElement
到子类,而不是从HTMLUnknownElement
到不相关的子类的横向过渡。
HTML和SVG元素之间共享的特性使用HTMLOrSVGElement
接口混入:[SVG]
interface mixin HTMLOrSVGElement {
[SameObject ] readonly attribute DOMStringMap dataset ;
attribute DOMString nonce ; // intentionally no [CEReactions]
[CEReactions ] attribute boolean autofocus ;
[CEReactions ] attribute long tabIndex ;
undefined focus (optional FocusOptions options = {});
undefined blur ();
};
以下示例展示了一个既不是HTML元素也不是SVG元素的元素创建方式:
const el = document.createElementNS("some namespace", "example");
console.assert(el.constructor === Element);
为了支持自定义元素功能,所有HTML元素都有特殊的构造函数行为。这是通过[HTMLConstructor]
IDL扩展属性来表示的。它表明给定接口的接口对象在调用时将具有特定行为,详见以下定义。
[HTMLConstructor]
扩展属性不得带有参数,并且只能出现在构造函数操作上。它必须仅在构造函数操作上出现一次,并且接口必须仅包含单个带注释的构造函数操作,而没有其他的。带注释的构造函数操作必须声明为不带参数。
带有[HTMLConstructor]
扩展属性的构造函数操作的接口具有以下覆盖的构造函数步骤:
令registry为当前全局对象的CustomElementRegistry
对象。
如果NewTarget等于活动函数对象,则抛出TypeError
。
这种情况可能发生在使用元素接口作为其构造函数定义自定义元素时:
customElements. define( "bad-1" , HTMLButtonElement);
new HTMLButtonElement(); // (1)
document. createElement( "bad-1" ); // (2)
在这种情况下,在执行HTMLButtonElement
(显式调用如(1),或隐式调用如(2))时,活动函数对象和NewTarget都是HTMLButtonElement
。如果没有此检查,就可能创建本地名称为bad-1
的HTMLButtonElement
实例。
令definition为registry中构造函数等于NewTarget的条目。如果没有这样的定义,则抛出TypeError
。
由于registry中不能有构造函数为undefined的条目,因此此步骤还防止HTML元素构造函数作为函数被调用(因为在这种情况下NewTarget将为undefined)。
令is value为null。
如果definition的本地名称等于definition的名称(即definition是独立自定义元素),则:
如果活动函数对象不是HTMLElement
,则抛出TypeError
。
这种情况可能发生在定义不扩展任何本地名称但继承自非HTMLElement
类的自定义元素时:
customElements. define( "bad-2" , class Bad2 extends HTMLParagraphElement {});
在这种情况下,在构造Bad2
实例时发生的(隐式)super()
调用期间,活动函数对象是HTMLParagraphElement
,而不是HTMLElement
。
否则(即definition是定制内建元素),则:
令valid local names为在本规范或其他适用规范中定义的使用活动函数对象作为其元素接口的元素的本地名称列表。
如果valid local names不包含definition的本地名称,则抛出TypeError
。
这种情况可能发生在定义扩展给定本地名称但继承自错误类的自定义元素时:
customElements. define( "bad-3" , class Bad3 extends HTMLQuoteElement {}, { extends : "p" });
在这种情况下,在构造Bad3
实例时发生的(隐式)super()
调用期间,valid local names是包含q
和blockquote
的列表,但definition的本地名称是p
,它不在该列表中。
将is value设置为definition的名称。
如果definition的构造栈为空,则:
令element为内部创建一个实现接口的新对象的结果,该接口与活动函数对象对应,给定当前领域和NewTarget。
将element的节点文档设置为当前全局对象的关联的Document
。
将element的命名空间前缀设置为null。
将element的自定义元素状态设置为“custom
”。
将element的自定义元素定义设置为definition。
将element的is
值设置为is value。
返回element。
当作者脚本直接构造新的自定义元素时,例如通过new MyCustomElement()
,会发生这种情况。
如果类型(prototype)不是对象,则:
活动函数对象的领域可能不是realm,因此我们使用跨领域的“相同接口”的更一般概念;我们不是在寻找接口对象的等同性。这种后备行为,包括使用NewTarget的领域并在那里查找适当的原型,旨在匹配JavaScript内置和Web IDL的内部创建实现接口的新对象算法的类似行为。
令element为definition的构造栈中的最后一个条目。
如果 element 是一个 已构造 标记,则抛出一个 TypeError
。
这种情况可能发生在自定义元素构造函数中的作者代码不合规地在调用super()
之前构造另一个正在构造的类的实例时:
let doSillyThing = true ;
class DontDoThis extends HTMLElement {
constructor() {
if ( doSillyThing) {
doSillyThing = false ;
new DontDoThis();
// Now the construction stack will contain an already constructed marker.
}
// This will then fail with a TypeError:
super ();
}
}
执行?element.[[SetPrototypeOf]](prototype)。
返回element。
此步骤通常在升级自定义元素时到达;现有元素被返回,以便在自定义元素构造函数内的super()
调用将该现有元素分配给this。
除了[HTMLConstructor]
隐含的构造函数行为外,一些元素还具有命名构造函数(实际上是具有修改过的prototype
属性的工厂函数)。
HTML元素的命名构造函数也可以在定义自定义元素构造函数时用在extends
子句中:
class AutoEmbiggenedImage extends Image {
constructor( width, height) {
super ( width * 10 , height * 10 );
}
}
customElements. define( "auto-embiggened" , AutoEmbiggenedImage, { extends : "img" });
const image = new AutoEmbiggenedImage( 15 , 20 );
console. assert( image. width === 150 );
console. assert( image. height === 200 );
本规范中的每个元素都有一个定义,包含以下信息:
元素所属类别的列表。这些类别用于定义每个元素的内容模型。
元素可以使用的上下文的非规范性描述。这些信息与允许此元素作为子元素的元素的内容模型是冗余的,仅为方便提供。
为简洁起见,仅列出了最具体的期望。
例如,所有短语内容都是流内容。因此,属于短语内容的元素将仅列为“在期望短语内容的地方”,因为这是更具体的期望。任何期望流内容的地方也期望短语内容,因此也符合此期望。
规范性描述了必须作为子元素和后代元素包含的内容。
在 text/html
语法中,是否可以省略开始和结束标签的非规范性描述。这些信息与规范要求是冗余的,仅为方便提供。
规范性列出了可以在元素上指定的属性(除非另有禁止),以及这些属性的非规范性描述。(破折号左边的内容是规范性的,右边的内容则不是。)
对于作者:ARIA 角色和 aria-* 属性的符合性要求定义在 ARIA in HTML 中。[ARIA] [ARIAHTML]
对于实现者:用户代理实现无障碍 API 语义的要求定义在 HTML Accessibility API Mappings 中。[HTMLAAM]
元素必须实现的 DOM 接口的规范性定义。
随后是元素代表什么的描述,以及可能适用于作者和实现的任何其他规范性符合标准。有时还包括示例。
属性值是一个字符串。除非另有规定,HTML 元素上的属性值可以是任何字符串值,包括空字符串,对于这些属性值中可以指定的文本没有限制。
本规范中定义的每个元素都有一个内容模型:该元素预期内容的描述。HTML元素必须包含符合其内容模型中描述的要求的内容。元素的内容是其在DOM中的子节点。
ASCII空白字符始终允许出现在元素之间。用户代理会在源标记中的这些字符之间表示为DOM中的文本
节点。仅包含这些字符序列的空文本
节点被视为元素间空白。
元素间空白、注释节点和处理指令节点在确定元素的内容是否符合其内容模型时,必须忽略这些节点,在遵循定义文档和元素语义的算法时,也必须忽略这些节点。
因此,如果元素A和第二个元素B具有相同的父节点,并且它们之间没有其他元素节点或文本节点(除了元素间空白),则可以说元素A是B的前驱或后继。同样,如果一个元素仅包含元素间空白、注释节点和处理指令节点,则该节点是该元素的唯一子节点。
作者不得在未明确允许的地方使用HTML元素,除非其他规范明确要求。对于XML复合文档,如果这些上下文是在其他命名空间中的元素内定义的,那么这些上下文可以在这些元素内。
Atom订阅格式定义了一个content
元素。当其type
属性的值为xhtml
时,Atom订阅格式要求它包含一个HTML
div
元素。因此,div
元素在该上下文中是允许的,尽管这并未明确地由本规范规范化地陈述。[ATOM]
此外,HTML元素可以是孤立的节点(即没有父节点)。
例如,在脚本中创建一个td
元素并将其存储在全局变量中是符合规范的,尽管td
元素通常只应该在tr
元素中使用。
var data = {
name: "Banana" ,
cell: document. createElement( 'td' ),
};
当一个元素的内容模型为nothing时,该元素不得包含任何文本
节点(除了元素间空白)和任何元素节点。
大多数内容模型为“nothing”的HTML元素,为了方便起见,也是空元素(在HTML语法中没有结束标签的元素)。然而,这些概念是完全独立的。
HTML中的每个元素属于一个或多个类别,这些类别将具有相似特征的元素分组在一起。本规范中使用了以下广泛类别:
一些元素也属于其他类别,这些类别在本规范的其他部分定义。
这些类别的关系如下:
分区内容、标题内容、短语内容、嵌入内容和交互内容都是流内容的一种。元数据有时是流内容。元数据和交互内容有时是短语内容。嵌入内容也是一种短语内容,有时是交互内容。
其他类别也用于特定目的,例如,表单控件使用多个类别来定义通用要求。一些元素具有独特的要求,不属于任何特定类别。
元数据内容是设置其余内容的呈现或行为,或者设置文档与其他文档之间的关系,或者传递其他“带外”信息的内容。
来自其他命名空间的元素,其语义主要与元数据相关(例如RDF),也属于元数据内容。
因此,在XML序列化中,可以这样使用RDF:
< html xmlns = "http://www.w3.org/1999/xhtml"
xmlns:r = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" xml:lang = "en" >
< head >
< title > Hedral's Home Page</ title >
< r:RDF >
< Person xmlns = "http://www.w3.org/2000/10/swap/pim/contact#"
r:about = "https://hedral.example.com/#" >
< fullName > Cat Hedral</ fullName >
< mailbox r:resource = "mailto:hedral@damowmow.com" />
< personalTitle > Sir</ personalTitle >
</ Person >
</ r:RDF >
</ head >
< body >
< h1 > My home page</ h1 >
< p > I like playing with string, I guess. Sister says squirrels are fun
too so sometimes I follow her to play with them.</ p >
</ body >
</ html >
然而,在HTML序列化中,这是不可能的。
大多数在文档和应用程序主体中使用的元素被归类为流内容。
a
abbr
address
area
(如果它是map元素的后代)article
aside
audio
b
bdi
bdo
blockquote
br
button
canvas
cite
code
data
datalist
del
details
dfn
dialog
div
dl
em
embed
fieldset
figure
footer
form
h1
h2
h3
h4
h5
h6
header
hgroup
hr
i
iframe
img
input
ins
kbd
label
link
(如果它是允许在body中)main
(如果它是层次结构正确的main
元素)map
mark
math
menu
meta
(如果存在itemprop
属性)
meter
nav
noscript
object
ol
output
p
picture
pre
progress
q
ruby
s
samp
script
search
section
select
slot
small
span
strong
sub
sup
svg
table
template
textarea
time
u
ul
var
video
wbr
分节内容是定义header
和footer
元素作用范围的内容。
标题内容定义了一个部分的标题(无论是显式标记为分节内容元素,还是由标题内容本身隐含)。
内联内容是文档的文本,以及在段内级别标记这些文本的元素。内联内容的连续部分形成段落。
a
abbr
area
(if it is a descendant of a map
element)audio
b
bdi
bdo
br
button
canvas
cite
code
data
datalist
del
dfn
em
embed
i
iframe
img
input
ins
kbd
label
link
(if it is allowed
in the body)map
mark
math
meta
(if the itemprop
attribute is present)meter
noscript
object
output
picture
progress
q
ruby
s
samp
script
select
slot
small
span
strong
sub
sup
svg
template
textarea
time
u
var
video
wbr
大多数被归类为短语内容的元素只能包含本身也是短语内容的元素,而不能包含任何流内容。
文本在内容模型的上下文中,意味着要么没有内容,要么包含文本
节点。文本有时被单独用作内容模型,但也属于短语内容,并且可以是元素间空白(如果文本
节点是空的或仅包含ASCII空白)。
文本
节点和属性值必须由标量值组成,不包括非字符和控制字符,除ASCII空白外。
本规范根据具体上下文对文本
节点和属性值的确切值提出了额外的约束。
嵌入内容是将其他资源导入文档,或将来自其他词汇的内容插入文档的内容。
来自HTML命名空间以外的命名空间且传递内容但不传递元数据的元素,在本规范定义的内容模型中被视为嵌入内容。(例如,MathML或SVG。)
一些嵌入内容元素可以有后备内容:当外部资源无法使用时(例如,由于格式不支持),使用的内容。元素定义会说明后备内容的情况(如果有的话)。
交互内容是专为用户交互设计的内容。
a
(如果存在href
属性)
audio
(如果存在controls
属性)
button
details
embed
iframe
img
(如果存在usemap
属性)
input
(如果type
属性不处于 状态)label
select
textarea
video
(如果存在controls
属性)
作为一般规则,允许任何流内容或短语内容的元素,其内容模型中应至少有一个节点是可感知内容,并且未指定 属性。
可感知内容通过提供一些后代非空的文本,使元素非空,或者提供用户可以听到的内容(如音频元素),或用户可以看到的内容(如视频、图片或画布元素),或与之交互的内容(例如,交互式表单控件)。
这一要求并不是硬性规定,因为在许多情况下,元素可以合法地为空,例如用作占位符,稍后会由脚本填充,或当元素是模板的一部分时,在某些页面上通常会填充,但在其他页面上可能不相关。
鼓励符合性检查器为作者提供一种机制,帮助他们查找未满足此要求的元素,作为一种创作辅助工具。
以下元素是可感知内容:
a
abbr
address
article
aside
audio
(如果存在controls
属性)
b
bdi
bdo
blockquote
button
canvas
cite
code
data
del
details
dfn
div
dl
(如果元素的子元素包含至少一个名称-值组)
em
embed
fieldset
figure
footer
form
h1
h2
h3
h4
h5
h6
header
hgroup
i
iframe
img
input
(如果type
属性不处于 状态)ins
kbd
label
main
map
mark
math
menu
(如果元素的子元素包含至少一个li
元素)meter
nav
object
ol
(如果元素的子元素包含至少一个li
元素)output
p
picture
pre
progress
q
ruby
s
samp
search
section
select
small
span
strong
sub
sup
svg
table
textarea
time
u
ul
(如果元素的子元素包含至少一个li
元素)var
video
脚本支持元素是那些本身不表示任何内容的元素(即它们不被渲染),而是用于支持脚本,例如为用户提供功能。
以下元素是脚本支持元素:
有些元素被描述为透明;它们的内容模型描述中包含“透明”一词。一个透明元素的内容模型源自其父元素的内容模型:在透明部分所需的元素与透明元素所在的父元素内容模型中所需的元素相同。
在某些情况下,透明元素嵌套在彼此之中,需要迭代地应用此过程。
考虑以下标记片段:
< p >< object >< param >< ins >< map >< a href = "/" > Apples</ a ></ map ></ ins ></ object ></ p >
要检查"Apples"是否允许在a
元素内,需要检查内容模型。a
元素的内容模型是透明的,map
元素的内容模型也是透明的,ins
元素的内容模型也是透明的,以及object
元素中包含ins
元素的部分也是透明的。object
元素包含在p
元素中,p元素的内容模型是短语内容。因此,
"Apples"是允许的,因为文本是短语内容。
当一个透明元素没有父元素时,其内容模型中“透明”的部分必须改为接受任何流内容。
本节定义的段落术语不仅仅用于p
元素的定义。这里定义的段落概念用于描述如何解释文档。p
元素只是标记段落的几种方式之一。
段落通常是一段形成文本块的短语内容,包含一个或多个讨论特定主题的句子,就像在排版中一样,但也可以用于更一般的主题分组。例如,一个地址也是一个段落,一个表单的一部分,一个署名,或诗的一节。
在以下示例中,有两段在一个部分中。还有一个标题,其中包含不是段落的短语内容。注意评论和元素间空白不构成段落。
< section >
< h2 > Example of paragraphs</ h2 >
This is the < em > first</ em > paragraph in this example.
< p > This is the second.</ p >
<!-- This is not a paragraph. -->
</ section >
在流内容中的段落相对于没有a
、
ins
、del
和map
元素的文档外观来定义,因为这些元素及其混合内容模型可以跨越段落边界,如下面的前两个示例所示。
通常,最好避免元素跨越段落边界。维护这样的标记可能很困难。
以下示例采用早期示例中的标记,并在一些标记周围放置ins
和
del
元素,显示文本已更改(尽管在这种情况下,这些更改确实没有多大意义)。请注意,本示例与前一个示例具有完全相同的段落,尽管存在ins
和
del
元素——ins
元素跨越标题和第一个段落,del
元素跨越两个段落之间的边界。
< section >
< ins >< h2 > Example of paragraphs</ h2 >
This is the < em > first</ em > paragraph in</ ins > this example< del > .
< p > This is the second.</ p ></ del >
<!-- This is not a paragraph. -->
</ section >
让view成为DOM的视图,用文档中的内容替换所有a
、
ins
、
del
和
map
元素。然后,在view中,对于每个由其他类型内容不间断的兄弟短语内容节点组成的运行,在一个接受内容类型不仅限于短语内容以及短语内容的元素中,令first为运行的第一个节点,令
last为运行的最后一个节点。对于每个由至少一个既不是嵌入内容也不是元素间空白的节点组成的运行,原始DOM中的一个段落存在于first之前到last之后。(因此段落可以跨越a
、
ins
、
del
和
map
元素。)
符合性检查器可能会警告作者他们有段落相互重叠的情况(这种情况可能发生在object
、
video
、
audio
和
canvas
元素中,及通过允许HTML进一步嵌入其中的其他命名空间中的元素间接发生,如SVG svg
或
MathML
math
)。
p
元素可以用来包装单个段落,当除了短语内容外没有其他内容将段落彼此分开时。
在以下示例中,链接跨越了第一个段落的一半、分隔两个段落的标题和第二个段落的一半。它跨越了段落和标题。
< header >
Welcome!
< a href = "about.html" >
This is home of...
< h1 > The Falcons!</ h1 >
The Lockheed Martin multirole jet fighter aircraft!
</ a >
This page discusses the F-16 Fighting Falcon's innermost secrets.
</ header >
这是另一种标记方法,这次显示段落,并将一个链接元素拆分为三个:
< header >
< p > Welcome! < a href = "about.html" > This is home of...</ a ></ p >
< h1 >< a href = "about.html" > The Falcons!</ a ></ h1 >
< p >< a href = "about.html" > The Lockheed Martin multirole jet
fighter aircraft!</ a > This page discusses the F-16 Fighting
Falcon's innermost secrets.</ p >
</ header >
在使用某些定义回退内容的元素时,段落可能会重叠。例如,在以下部分中:
< section >
< h2 > My Cats</ h2 >
You can play with my cat simulator.
< object data = "cats.sim" >
To see the cat simulator, use one of the following links:
< ul >
< li >< a href = "cats.sim" > Download simulator file</ a >
< li >< a href = "https://sims.example.com/watch?v=LYds5xY4INU" > Use online simulator</ a >
</ ul >
Alternatively, upgrade to the Mellblom Browser.
</ object >
I'm quite proud of it.
</ section >
共有五个段落:
object
元素。
第一个段落被其他四个段落重叠。支持“cats.sim”资源的用户代理只会显示第一个段落,但显示回退内容的用户代理将混淆地显示第一个段落的第一句话,好像它在第二段落中一样,并将显示最后一个段落,好像它在第一段落的第二句的开头一样。
为了避免这种混淆,可以使用显式的p
元素。例如:
< section >
< h2 > My Cats</ h2 >
< p > You can play with my cat simulator.</ p >
< object data = "cats.sim" >
< p > To see the cat simulator, use one of the following links:</ p >
< ul >
< li >< a href = "cats.sim" > Download simulator file</ a >
< li >< a href = "https://sims.example.com/watch?v=LYds5xY4INU" > Use online simulator</ a >
</ ul >
< p > Alternatively, upgrade to the Mellblom Browser.</ p >
</ object >
< p > I'm quite proud of it.</ p >
</ section >
以下属性是所有HTML元素(即使那些未在本规范中定义的元素)共有的,并且可以在所有HTML元素上指定:
accesskey
autocapitalize
autocorrect
autofocus
contenteditable
dir
draggable
enterkeyhint
inert
inputmode
is
itemid
itemprop
itemref
itemscope
itemtype
lang
nonce
popover
spellcheck
style
tabindex
title
translate
writingsuggestions
这些属性仅在本规范中定义为HTML元素的属性。当本规范提到元素具有这些属性时,不应将未定义为具有这些属性的命名空间中的元素视为具有这些属性的元素。
例如,在以下XML片段中,"bogus
"元素没有一个dir
属性,尽管它具有一个字面名称为"dir
"的属性。因此,内层span
元素的方向性是'rtl',间接从div
元素继承,通过"bogus
"元素。
< div xmlns = "http://www.w3.org/1999/xhtml" dir = "rtl" >
< bogus xmlns = "https://example.net/ns" dir = "ltr" >
< span xmlns = "http://www.w3.org/1999/xhtml" >
</ span >
</ bogus >
</ div >
Support in all current engines.
DOM定义了用户代理对任何命名空间中的任何元素的class
、id
和slot
属性的要求。
[DOM]
class
、id
和slot
属性可以在所有HTML元素上指定。
在HTML元素上指定时,class
属性必须具有一个值,该值是由空格分隔的标记集,表示元素所属的各种类。
为元素分配类会影响CSS选择器中的类匹配、DOM中的getElementsByClassName()
方法等功能。
作者可以在class
属性中使用的标记没有其他限制,但鼓励作者使用描述内容性质的值,而不是描述内容所需呈现的值。
在HTML元素上指定时,id
属性值在元素的树中的所有ID中必须是唯一的,并且必须包含至少一个字符。该值不得包含任何ASCII空白字符。
ID可以采取任何形式;特别是,ID可以仅由数字组成,以数字开头,以下划线开头,仅由标点符号组成等。
元素的唯一标识符可以用于多种目的,最著名的是作为使用片段链接到文档特定部分的方式,作为脚本定位元素的方式,以及从CSS样式化特定元素的方式。
标识符是不可解释的字符串。不应从id
属性的值中推导出特定含义。
这个slot
属性用于分配插槽给一个元素:具有slot
属性的元素被分配给由slot
元素创建的插槽,其name属性的值与该slot
属性的值匹配——但前提是该slot
元素在其影子树中的根的宿主具有相应的slot
属性值。
为了使辅助技术产品能够提供比HTML元素和属性更细粒度的接口,可以指定一组辅助技术产品的注释(ARIA role
和aria-*
属性)。
[ARIA]
以下事件处理程序内容属性可以在任何HTML元素上指定:
onauxclick
onbeforeinput
onbeforematch
onbeforetoggle
onblur
*
oncancel
oncanplay
oncanplaythrough
onchange
onclick
onclose
oncontextlost
oncontextmenu
oncontextrestored
oncopy
oncuechange
oncut
ondblclick
ondrag
ondragend
ondragenter
ondragleave
ondragover
ondragstart
ondrop
ondurationchange
onemptied
onended
onerror
*
onfocus
*
onformdata
oninput
oninvalid
onkeydown
onkeypress
onkeyup
onload
*
onloadeddata
onloadedmetadata
onloadstart
onmousedown
onmouseenter
onmouseleave
onmousemove
onmouseout
onmouseover
onmouseup
onpaste
onpause
onplay
onplaying
onprogress
onratechange
onreset
onresize
*
onscroll
*
onscrollend
*
onsecuritypolicyviolation
onseeked
onseeking
onselect
onslotchange
onstalled
onsubmit
onsuspend
ontimeupdate
ontoggle
onvolumechange
onwaiting
onwheel
带星号的属性在body
元素上指定时有不同的含义,因为这些元素公开具有相同名称的事件处理程序的Window
对象。
虽然这些属性适用于所有元素,但并不是在所有元素上都有用。例如,只有媒体元素才会接收到由用户代理触发的volumechange
事件。
自定义数据属性(例如data-foldername
或data-msgid
)可以在任何HTML元素上指定,用于存储自定义数据、状态、注释等与页面相关的内容。
在HTML文档中,HTML命名空间中的元素可以指定xmlns
属性,但仅当且仅当其值为http://www.w3.org/1999/xhtml
时才可以。这不适用于XML文档。
在HTML中,xmlns
属性绝对没有效果。它基本上是一个护身符。允许它仅仅是为了使迁移到XML和从XML迁移变得稍微容易一些。当由HTML解析器解析时,该属性最终不在任何命名空间中,而不像XML中的命名空间声明属性那样位于http://www.w3.org/2000/xmlns/
命名空间中。
在XML中,xmlns
属性是命名空间声明机制的一部分,而一个元素实际上不能有一个未指定命名空间的xmlns
属性。
XML还允许在XML命名空间中的任何元素上使用xml:space
属性,该属性适用于XML文档。该属性对HTML元素没有影响,因为HTML中的默认行为是保留空白。[XML]
在text/html
语法中,没有办法序列化HTML元素上的xml:space
属性。
title
属性在所有当前引擎中支持。
title
属性表示元素的建议信息,例如适合作为工具提示的信息。在链接上,这可以是目标资源的标题或描述;在图像上,它可以是图像来源或描述;在段落上,它可以是文本的脚注或评论;在引文上,它可以是关于来源的进一步信息;在交互内容上,它可以是该元素的标签或使用说明;等等。值为文本。
目前不建议依赖title
属性,因为许多用户代理不按照本规范要求以可访问的方式展示该属性(例如,需要使用指针设备如鼠标才能使工具提示出现,这排除了仅使用键盘的用户和仅使用触摸的用户,如任何使用现代手机或平板电脑的人)。
如果一个元素没有这个属性,那么它意味着最近的祖先HTML
元素的title
属性也适用于该元素。设置这个属性会覆盖这种继承,明确声明任何祖先的建议信息对这个元素不适用。将该属性设置为空字符串表示该元素没有建议信息。
如果title
属性的值包含U+000A换行符(LF)字符,内容会被分成多行。每个U+000A换行符(LF)字符代表一个换行。
在title
属性中使用换行符时需要小心。
例如,以下代码段实际上定义了带有换行符的缩写解释:
< p > My logs show that there was some interest in < abbr title = "Hypertext
Transport Protocol" > HTTP</ abbr > today.</ p >
一些元素,如link
,abbr
,和input
,对title
属性定义了额外的语义。
元素的建议信息是以下算法返回的值,一旦返回值,算法将终止。当算法返回空字符串时,则表示没有建议信息。
用户代理应在元素有建议信息时通知用户,否则这些信息将不可发现。
在所有当前引擎中支持。
lang
和 xml:lang
属性在所有当前引擎中支持。
lang
属性(不在任何命名空间中)指定元素内容的主要语言以及任何包含文本的元素属性。其值必须是有效的 BCP 47 语言标签,或为空字符串。将该属性设置为空字符串表示主要语言未知。[BCP47]
lang
属性在XML 命名空间中定义于 XML 中。[XML]
如果这些属性在元素中省略,那么该元素的语言与其父元素的语言相同(如果有父元素)(slot
元素在shadow tree 中除外)。
lang
属性在 XML 命名空间中可以用于HTML 元素在XML 文档中,以及其他命名空间中的元素,如果相关规范允许的话(特别是 MathML 和 SVG 允许在其元素上指定 lang
属性在 XML 命名空间)。如果在同一元素上同时指定了没有命名空间的 lang
属性和
lang
属性在 XML 命名空间,则它们在 ASCII 大小写不敏感的情况下必须具有完全相同的值。
作者不得在HTML
元素在HTML 文档中使用lang
属性在
XML 命名空间。为了便于向 XML 的迁移,作者可以在HTML 元素在HTML 文档中指定一个没有命名空间、没有前缀且具有字面局部名“xml:lang
”的属性,但只有在同时指定了没有命名空间的
lang
属性时,才能指定这种属性,并且在 ASCII 大小写不敏感的情况下,两个属性的值必须相同。
没有命名空间、没有前缀且具有字面局部名“xml:lang
”的属性对语言处理没有影响。
为了确定节点的语言,用户代理必须使用以下列表中的第一个适用步骤:
lang
属性在 XML 命名空间的元素使用该属性的值。
lang
属性
使用该属性的值。
使用该 语言的 shadow root的 主机。
如果设置了默认语言,则该节点的语言为该语言。如果没有设置默认语言,则必须使用来自更高层协议(如 HTTP)的语言信息(如果有)作为最终的回退语言。如果没有任何这种语言信息,并且在更高层协议中报告了多种语言,则该节点的语言未知,相应的语言标签为空字符串。
如果结果值不是识别的语言标签,则必须将其视为具有给定语言标签的未知语言,与所有其他语言不同。为了进行回绕或与期望语言标签的其他服务进行通信,用户代理应该将未知的语言标签不作修改地传递,并标记为 BCP 47 语言标签,以便后续服务不会将数据解释为另一种类型的语言描述。[BCP47]
因此,例如,带有lang="xyzzy"
的元素将被选择器:lang(xyzzy)
(例如在 CSS
中)匹配,但不会被:lang(abcde)
匹配,即使两者同样无效。同样,如果网络浏览器和屏幕阅读器共同工作,浏览器会告知屏幕阅读器该元素的语言是“xyzzy”,即使它知道这是无效的,只是以防屏幕阅读器实际上支持该标签的语言。即使屏幕阅读器同时支持
BCP 47 和另一种语法来编码语言名称,并且在另一种语法中字符串“xyzzy”是一种表示白俄罗斯语的方式,屏幕阅读器将文本视为白俄罗斯语是错误的,因为“xyzzy”不是 BCP 47 编码中描述白俄罗斯语的方式(BCP 47
使用代码“be”表示白俄罗斯语)。
如果结果值为空字符串,则必须将其解释为该节点的语言明确未知。
用户代理可以使用元素的语言来确定适当的处理或渲染(例如在选择适当的字体或发音,字典选择,或表单控件如日期选择器的用户界面)。
在所有当前引擎中支持。
lang
IDL 属性必须反映没有命名空间的lang
内容属性。
translate
属性在所有当前引擎中支持。
translate
属性用于指定在页面本地化时,是否翻译元素的属性值及其文本节点子元素的值,还是保持它们不变。该属性是一个枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简短描述 |
---|---|---|
yes |
yes | 将翻译模式设置为翻译启用。 |
(空字符串) | ||
no |
no | 将翻译模式设置为不翻译。 |
每个元素(即使是非 HTML 元素)都有一个翻译模式,可以是翻译启用状态,也可以是不翻译状态。如果HTML 元素的translate
属性处于yes状态,则该元素的翻译模式处于翻译启用状态;否则,如果该元素的translate
属性处于no状态,则该元素的翻译模式处于不翻译状态。否则,元素的translate
属性处于继承状态,或者该元素不是HTML 元素,因此没有translate
属性;无论哪种情况,元素的翻译模式与其父元素的状态相同,如果有的话,或者如果元素的父元素为空,则处于翻译启用状态。
当元素处于翻译启用状态时,元素的可翻译属性及其文本节点子元素的值在页面本地化时应被翻译。
当元素处于不翻译状态时,元素的属性值及其文本节点子元素的值在页面本地化时应保持不变,例如因为该元素包含个人姓名或计算机程序的名称。
以下属性是可翻译属性:
abbr
在th
元素上
alt
在area
、img
和input
元素上
content
在meta
元素上,如果name
属性指定了已知可翻译的元数据名称
download
在a
和area
元素上
label
在optgroup
、option
和track
元素上
lang
在HTML
元素上;必须“翻译”以匹配翻译中使用的语言placeholder
在input
和textarea
元素上
srcdoc
在iframe
元素上;必须解析并递归处理
style
在HTML
元素上;必须解析并递归处理(例如,对于'content'属性的值)
title
在所有HTML 元素上value
在具有input
元素中的type
属性处于按钮状态或重置按钮状态时。其他规范可以定义其他也是可翻译属性的属性。例如,ARIA将定义aria-label
属性为可翻译属性。
translate
IDL
属性在获取时,如果元素的翻译模式是翻译启用,则返回 true,否则返回 false。设置时,如果新值为
true,则必须将内容属性的值设置为“yes
”,否则将内容属性的值设置为“no
”。
在此示例中,文档中的所有内容在页面本地化时应被翻译,除了示例键盘输入和示例程序输出:
<!DOCTYPE HTML>
< html lang = en > <!-- default on the document element is translate=yes -->
< head >
< title > The Bee Game</ title > <!-- implied translate=yes inherited from ancestors -->
</ head >
< body >
< p > The Bee Game is a text adventure game in English.</ p >
< p > When the game launches, the first thing you should do is type
< kbd translate = no > eat honey</ kbd > . The game will respond with:</ p >
< pre >< samp translate = no > Yum yum! That was some good honey!</ samp ></ pre >
</ body >
</ html >
dir
属性Support in all current engines.
The dir
attribute
是一个枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
ltr
|
ltr | 元素内容是明确方向隔离的从左到右文本。 |
rtl
|
rtl | 元素内容是明确方向隔离的从右到左文本。 |
auto
|
auto | 元素内容是明确方向隔离的文本,但方向应通过程序根据元素内容确定(如下所述)。 |
元素(任何元素,不仅是HTML元素)的方向性要么是'ltr',要么是'rtl'。给定元素element的方向性的计算方法如下:
由于dir
属性仅对HTML元素定义,它不能出现在其他命名空间的元素上。因此,其他命名空间的元素总是使用父方向性。
自动方向性表单关联元素包括:
给定元素element的自动方向性的计算方法如下:
如果 element 是一个自动方向性关联表单元素:
如果 element 是一个 slot
元素,且其 根是一个
shadow root 并且 element 的 已分配节点不为空:
返回 element 的包含文本自动方向性,其中canExcludeRoot 设置为 false。
要计算元素 element 的 包含文本自动方向性,且带有布尔值 canExcludeRoot:
返回 null。
要计算给定 Text
节点 text 的文本节点方向性:
设 codePoint 为 text 的 数据中第一个双向字符类型为 L、AL 或 R 的代码点。
如果 codePoint 的双向字符类型为 AL 或 R,则返回 'rtl'。
如果 codePoint 的双向字符类型为 L,则返回 'ltr'。
要计算给定元素 element 的父级方向性:
设 parentNode 为 element 的父节点。
如果 parentNode 是一个 shadow root,则返回 parentNode 的 方向性,即 parentNode 的 宿主的方向性。
如果 parentNode 是一个元素,则返回 parentNode 的 方向性。
返回 'ltr'。
此属性涉及使用双向算法进行渲染。
HTML元素的一个属性的方向性,在该属性的文本要以某种方式包含在渲染中时,其确定方法如下:
dir
属性处于auto状态
查找属性值的第一个双向字符类型为L、AL或R的字符(按逻辑顺序)。[BIDI]
以下属性是支持方向性的属性:
abbr
在th
元素上alt
在area
、img
和input
元素上content
在meta
元素上,如果name
属性指定的元数据名称主要是面向人类可读而不是机器可读
label
在optgroup
、option
和track
元素上
placeholder
在input
和textarea
元素上
title
在所有HTML元素上Support in all current engines.
dir
IDL属性在元素上必须反映该元素的dir
内容属性,仅限于已知值。
Support in all current engines.
dir
IDL属性在Document
对象上必须反映html
元素的dir
内容属性(如果有),仅限于已知值。如果没有这样的元素,则该属性必须返回空字符串并在设置时不执行任何操作。
作者强烈建议使用dir
属性来指示文本方向,而不是使用CSS,因为这样即使在没有CSS的情况下(例如由搜索引擎解释),文档也会继续正确呈现。
此标记片段是即时消息对话的一部分。
< p dir = auto class = "u1" >< b >< bdi > Student</ bdi > :</ b > How do you write "What's your name?" in Arabic?</ p >
< p dir = auto class = "u2" >< b >< bdi > Teacher</ bdi > :</ b > ما اسمك؟</ p >
< p dir = auto class = "u1" >< b >< bdi > Student</ bdi > :</ b > Thanks.</ p >
< p dir = auto class = "u2" >< b >< bdi > Teacher</ bdi > :</ b > That's written "شكرًا".</ p >
< p dir = auto class = "u2" >< b >< bdi > Teacher</ bdi > :</ b > Do you know how to write "Please"?</ p >
< p dir = auto class = "u1" >< b >< bdi > Student</ bdi > :</ b > "من فضلك", right?</ p >
给定一个合适的样式表和p
元素的默认对齐样式,即将文本对齐到段落的起始边缘,则生成的渲染结果可能如下所示:
如前所述,auto
值不是灵丹妙药。此示例中的最后一个段落由于以阿拉伯字符开头而被误解为从右到左的文本,这导致“right?”出现在阿拉伯文本的左侧。
style
属性支持所有当前引擎。
所有HTML元素 都可以设置style
内容属性。这是一个样式属性,定义在 CSS Style
Attributes中。[CSSATTR]
在支持CSS的用户代理中,当添加或更改属性值时,必须按照样式属性的规则解析该属性的值。 [CSSATTR]
但是,如果在执行应该通过内容安全政策阻止元素的内联行为吗?算法时返回“Blocked
”,并在属性的元素、“style attribute
”和属性的值上执行,那么属性值中定义的样式规则不得应用于元素。 [CSP]
使用任何元素的style
属性的文档,即使这些属性被删除,也必须能够理解和使用。
特别是,使用style
属性来隐藏和显示内容,或传达文档中未包含的意义,是不符合规范的。(要隐藏和显示内容,请使用
属性。)
element.style
返回元素CSSStyleDeclaration
对象的style
属性。
style
IDL属性定义在 CSS Object
Model中。[CSSOM]
在以下示例中,表示颜色的单词使用
span
元素和style
属性标记,以使这些单词在视觉媒体中显示为相关颜色。
< p > My sweat suit is < span style = "color: green; background:
transparent" > green</ span > and my eyes are < span style = "color: blue;
background: transparent" > blue</ span > .</ p >
data-*
属性
在所有当前引擎中支持。
自定义数据属性是一种没有命名空间的属性,其名称以字符串 "data-
" 开头,在连字符之后至少有一个字符,并且 XML
兼容,且不包含 ASCII 大写字母。
在 HTML 元素的 HTML 文档中,所有属性名称都会自动转换为小写 ASCII 字母,因此对 ASCII 大写字母的限制不会影响这些文档。
自定义数据属性旨在存储页面或应用程序专有的自定义数据、状态、注释等,而没有更合适的属性或元素。
这些属性不应由使用这些属性的网站管理员未知的软件使用。对于要由多个独立工具使用的通用扩展,应通过扩展此规范来明确提供该功能,或者应使用诸如 microdata 之类的技术(使用标准化的词汇表)。
例如,一个关于音乐的网站可以使用自定义数据属性来注释代表专辑中曲目的列表项,包含每首曲目的长度。然后,该信息可以由网站本身使用,以允许用户按曲目长度对列表进行排序,或根据特定长度过滤列表。
< ol >
< li data-length = "2m11s" > Beyond The Sea</ li >
...
</ ol >
然而,用户不应使用与该音乐网站无关的通用软件通过查看这些数据来搜索特定长度的曲目。
这是因为这些属性旨在由网站自己的脚本使用,而不是一个公共可用的元数据的通用扩展机制。
同样,页面作者可以编写标记来为他们打算使用的翻译工具提供信息:
< p > The third < span data-mytrans-de = "Anspruch" > claim</ span > covers the case of < span
translate = "no" > HTML</ span > markup.</ p >
在此示例中,"data-mytrans-de
" 属性为 MyTrans 产品在将短语 "claim" 翻译为德语时提供特定文本。然而,标准的 translate
属性用于告诉它在所有语言中 "HTML" 应保持不变。当有标准属性可用时,就不需要使用 自定义数据属性。
在此示例中,自定义数据属性用于存储 PaymentRequest
功能检测的结果,可以在 CSS 中用于不同地设置结账页面的样式。
< script >
if ( 'PaymentRequest' in window) {
document. documentElement. dataset. hasPaymentRequest = '' ;
}
</ script >
在这里,data-has-payment-request
属性实际上被用作 布尔属性;检查属性的存在就足够了。然而,如果作者愿意,它以后可以被填充一些值,可能是为了指示该功能的有限功能。
每个 HTML 元素可以指定任意数量的 自定义数据属性,并且可以是任何值。
作者应仔细设计此类扩展,以便在忽略这些属性并丢弃任何相关的 CSS 时,页面仍然可用。
用户代理不得从这些属性或值中派生任何实现行为。针对用户代理的规范不得定义这些属性具有任何有意义的值。
JavaScript 库可以使用 自定义数据属性,因为它们被视为使用它们的页面的一部分。鼓励被许多作者重复使用的库的作者在属性名称中包含他们的名字,以减少冲突的风险。如果合理的话,也鼓励库的作者使属性名称中的确切名称可定制,这样即使那些库的作者不知情地选择了相同的名称,也可以在同一页面上使用这些库,并且即使这些版本不相互兼容,也可以在同一页面上使用特定库的多个版本。
例如,一个名为 "DoQuery" 的库可以使用像 data-doquery-range
这样的属性名称,而一个名为 "jJo" 的库可以使用像 data-jjo-range
这样的属性名称。jJo 库还可以提供一个 API 来设置要使用的前缀(例如 J.setDataPrefix('j2')
,使属性名称变为 data-j2-range
)。
element.dataset
在所有当前引擎中支持。
在所有当前引擎中支持。
返回一个 DOMStringMap
对象,用于元素的 data-*
属性。
连字符名称将变为驼峰形式。例如,data-foo-bar=""
变为 element.dataset.fooBar
。
dataset
IDL
属性为元素上的所有 data-*
属性提供了方便的访问器。在获取时,dataset
IDL 属性必须返回一个 DOMStringMap
,其关联的元素是此元素。
DOMStringMap
接口用于 dataset
属性。每个 DOMStringMap
都有一个 关联元素。
[Exposed =Window ,
LegacyOverrideBuiltIns ]
interface DOMStringMap {
getter DOMString (DOMString name );
[CEReactions ] setter undefined (DOMString name , DOMString value );
[CEReactions ] deleter undefined (DOMString name );
};
要 获取 DOMStringMap
的名称-值对,请运行以下算法:
让 list 成为空的名称-值对列表。
对于 DOMStringMap
的 关联元素
上的每个内容属性,其前五个字符是字符串 "data-
",其余字符(如果有)不包含任何 ASCII 大写字母,按这些属性在元素的 属性列表中列出的顺序,为 list 添加一个名称-值对,其名称为去掉前五个字符后的属性名称,其值为属性的值。
对于 list 中的每个名称,对于名称中每个后面跟有一个 ASCII 小写字母 的 U+002D 连字符,将 U+002D 连字符删除,并用相同字符 转换为 ASCII 大写字母 替换其后的字符。
返回 list。
在任何时刻,支持的属性名称在DOMStringMap
对象上,是从获取DOMStringMap
的名称-值对时返回的每对名称,在返回的顺序中。
要 确定命名属性的值 name,对于 DOMStringMap
,返回名称-值对列表中名称为
name 的值部分。
要 设置新命名属性的值 或 设置现有命名属性的值 对于 DOMStringMap
,给定属性名称
name 和新值 value,运行以下步骤:
如果 name 包含一个后跟 ASCII
小写字母 的 U+002D 连字符,则抛出一个 "SyntaxError
" DOMException
。
对于 name 中的每个 ASCII 大写字母,在该字符前插入一个 U+002D 连字符,并将该字符替换为相同字符 转换为 ASCII 小写字母。
在 name 的前面插入字符串 data-
。
如果 name 不匹配 XML 名称
生成规则,则抛出一个 "InvalidCharacterError
" DOMException
。
使用 name 和 value 为 DOMStringMap
的 关联元素
设置一个属性值。
要 删除现有命名属性 name 对于 DOMStringMap
,运行以下步骤:
对于 name 中的每个 ASCII 大写字母,在该字符前插入一个 U+002D 连字符,并将该字符 替换为相同字符 转换为 ASCII 小写字母。
在 name 的前面插入字符串 data-
。
通过名称删除属性 给定 name 和 DOMStringMap
的 关联元素。
此算法只会由 Web IDL 为 获取
DOMStringMap
的名称-值对 的早期算法给定的名称调用。[WEBIDL]
如果一个网页希望一个元素代表一个飞船,例如作为游戏的一部分,它必须使用 class
属性以及 data-*
属性:
< div class = "spaceship" data-ship-id = "92432"
data-weapons = "laser 2" data-shields = "50%"
data- x = "30" data-y = "10" data-z = "90" >
< button class = "fire"
onclick = "spaceships[this.parentNode.dataset.shipId].fire()" >
Fire
</ button >
</ div >
请注意,连字符的属性名称在 API 中变为驼峰形式。
给定以下片段和具有类似结构的元素:
< img class = "tower" id = "tower5" data- x = "12" data-y = "5"
data-ai = "robotarget" data-hp = "46" data-ability = "flames"
src = "towers/rocket.png" alt = "Rocket Tower" >
...可以想象一个函数 splashDamage()
需要一些参数,第一个是要处理的元素:
function splashDamage( node, x, y, damage) {
if ( node. classList. contains( 'tower' ) && // checking the 'class' attribute
node. dataset. x == x && // reading the 'data-x' attribute
node. dataset. y == y) { // reading the 'data-y' attribute
var hp = parseInt( node. dataset. hp); // reading the 'data-hp' attribute
hp = hp - damage;
if ( hp < 0 ) {
hp = 0 ;
node. dataset. ai = 'dead' ; // setting the 'data-ai' attribute
delete node. dataset. ability; // removing the 'data-ability' attribute
}
node. dataset. hp = hp; // setting the 'data-hp' attribute
}
}
innerText
和 outerText
属性在所有当前引擎中支持。
element.innerText [ = value ]
返回元素的“渲染后”文本内容。
可以设置,替换元素的子节点为给定值,但换行符会转换为 br
元素。
element.outerText [ = value ]
返回元素的“渲染后”文本内容。
可以设置,替换元素为给定值,但换行符会转换为 br
元素。
获取文本步骤,给定 HTMLElement element,如下:
如果 element 未 被渲染 或用户代理是非 CSS 用户代理,则返回 element 的 后代文本内容。
这一步可能产生令人惊讶的结果,因为当对未 被渲染 的元素调用 innerText
getter 时,它的文本内容会被返回,但当对 被渲染
的元素访问时,其所有未 被渲染
的子元素的文本内容将被忽略。
设 results 为一个新的空的 列表。
对于 element 的每个子节点 node:
移除 results 中所有空字符串项。
移除 results 开头或结尾的任何连续的 需要的换行符计数 项。
替换 每个剩余的连续的 需要的换行符计数 项,以包含与该 需要的换行符计数 项中的最大值相同数量的 U+000A LF 码点的字符串。
返回 results 中字符串项的连接结果。
在所有当前引擎中支持。
innerText
和 outerText
getter 步骤是运行
获取文本步骤,以
this
为参数。
渲染文本收集步骤,给定 节点 node,如下:
如果 node 的 计算值的 'visibility' 不是 'visible',则返回 items。
如果 node 未 被渲染,则返回 items。对于此步骤,如果 计算值的 'display' 属性不是 'none',则以下元素必须按如下描述行为:
items 可能由于 'display:contents' 而非空。
如果 node 是 Text
节点,则对于由 node 生成的每个 CSS 文本框,按内容顺序,计算应用 CSS 'white-space' 处理规则和 'text-transform' 规则后的文本,将 items 设置为结果字符串的 列表,并返回 items。CSS 'white-space' 处理规则稍有修改:行尾的可折叠空格总是会被折叠,但只有当行是块的最后一行,或以 br
元素结尾时,才会被移除。软连字符应保留。[CSSTEXT]
如果 node 是 br
元素,则向 items 添加包含单个 U+000A LF 码点的字符串。
如果 node 的 计算值的 'display' 是 'table-cell',且 node 的 CSS 盒 不是其包围的 'table-row' 盒的最后一个 'table-cell' 盒,则向 items 添加包含单个 U+0009 TAB 码点的字符串。
如果 node 的 计算值的 'display' 是 'table-row',且 node 的 CSS 盒 不是最近的祖先 'table' 盒的最后一个 'table-row' 盒,则向 items 添加包含单个 U+000A LF 码点的字符串。
如果 node 是 p
元素,则在 items 的开头和结尾添加 2(一个需要的换行符计数)。
如果 node 的 使用值的 'display' 是 块级 或 'table-caption',则在 items 的开头和结尾添加 1(一个需要的换行符计数)。[CSSDISPLAY]
浮动和绝对定位的元素属于此类别。
返回 items。
请注意,大多数替换元素(例如 textarea
、input
和 video
—— 但不包括 button
)的后代节点严格来说不会被
CSS 渲染,因此在此算法中没有 CSS 盒。
此算法可以概括为适用于 范围。然后我们可以将其用作 Selection
的字符串化的基础,甚至可以直接在 范围 上公开它。请参阅 Bugzilla bug 10583。
设置内部文本步骤,给定 HTMLElement element 和字符串 value,如下:
innerText
setter 步骤是运行 设置内部文本步骤。
outerText
setter 步骤如下:
如果 this 的父节点为 null,则抛出 "NoModificationAllowedError
" DOMException
。
如果 fragment 没有 子节点,则 追加 一个新的 Text
节点,其 数据为空字符串,其 节点文档 是 this 的 节点文档 到
fragment。
如果 next 非空且 next 的 上一个兄弟节点 是 Text
节点,则 合并到下一个文本节点,给定 next 的 上一个兄弟节点。
如果 previous 是 Text
节点,则 合并到下一个文本节点,给定 previous。
渲染文本片段,给定字符串 input 和 Document
document,运行以下步骤:
设 fragment 为一个新的 DocumentFragment
,其
节点文档 为 document。
设 position 为 位置变量,最初指向 input 的开头。
设 text 为空字符串。
当 position 未越过 input 的末尾时:
返回 fragment。
与下一个文本节点合并,给定 Text
节点 node:
HTML元素中的文本内容,以及其内容中的文本节点
,以及HTML元素中允许自由格式文本的属性中的文本,可以包含范围为
U+202A 至 U+202E 和 U+2066 至 U+2069 的字符(双向算法格式化字符)。[BIDI]
作者被鼓励使用 dir
属性、bdo
元素和 bdi
元素,而不是手动维护双向算法格式化字符。双向算法格式化字符与 CSS 交互不佳。
用户代理必须实现 Unicode 双向算法,以确定在渲染文档和文档部分时字符的正确排序。[BIDI]
HTML 到 Unicode 双向算法的映射必须通过以下三种方式之一进行。用户代理必须实现 CSS,特别是 CSS 的 'unicode-bidi'、'direction' 和 'content' 属性,并且在其用户代理样式表中,必须包含在本规范的渲染部分中给出的使用这些属性的规则;或者,用户代理必须表现得像实现了上述属性,并且有一个包含所有上述规则的用户代理样式表,但不允许文档中指定的样式表覆盖它们;或者,用户代理必须实现另一种具有等效语义的样式语言。[CSSGC]
以下元素和属性的要求由渲染部分定义,由于本节中的要求,这些要求对所有用户代理(不仅仅是那些支持建议的默认渲染的用户代理)都是强制性的:
在HTML 元素上实现无障碍 API 语义的用户代理要求在HTML Accessibility API Mappings中定义。除了那里规定的规则外,对于一个自定义元素 element,默认的 ARIA 角色语义按如下方式确定:[HTMLAAM]
类似地,对于一个自定义元素 element,默认的 ARIA 状态和属性语义,对于名为 stateOrProperty 的状态或属性,按如下方式确定:
如果 element 的附加内部不为空:
如果 element 的附加内部的获取 stateOrProperty 关联元素存在,则返回运行结果。
如果 element 的附加内部的获取 stateOrProperty 关联元素存在,则返回运行结果。
返回 stateOrProperty 的默认值。
此处提到的“默认语义”有时在ARIA中也称为“本机”、“隐式”或“主机语言”语义。[ARIA]
这些定义的一个含义是默认语义可以随时间变化。这允许自定义元素具有与内置元素相同的表达能力;例如,比较 a
元素的默认 ARIA 角色语义在 href
属性添加或移除时如何变化。
有关实际应用的示例,请参见自定义元素部分。
在HTML 元素上检查使用 ARIA role
和 aria-*
属性的一致性检查器要求在ARIA in
HTML中定义。[ARIAHTML]
html
元素所有当前引擎均支持。
所有当前引擎均支持。
head
元素,后面跟着一个 body
元素。html
元素的 开始标签 可以省略,
如果 html
元素内的第一个内容不是 注释。html
元素的 结束标签
可以省略,前提是 html
元素后面没有紧接着一个 注释。[Exposed =Window ]
interface HTMLHtmlElement : HTMLElement {
[HTMLConstructor ] constructor ();
// also has obsolete members
};
建议作者在根 lang
元素上指定语言属性,以提供文档的语言。这有助于语音合成工具确定使用的发音、翻译工具确定使用的规则等。
下面示例中的 html
元素声明了文档的语言是英语。
<!DOCTYPE html>
< html lang = "en" >
< head >
< title > Swapping Songs</ title >
</ head >
< body >
< h1 > Swapping Songs</ h1 >
< p > Tonight I swapped some of the songs I wrote with some friends, who
gave me some of the songs they wrote. I love sharing my music.</ p >
</ body >
</ html >
head
元素支持所有当前的引擎。
支持所有当前的引擎。
html
元素中的第一个元素。iframe
srcdoc
文档 或
如果从更高层协议中可以获得标题信息:零个或多个 元数据内容
元素,其中最多一个是 title
元素,最多一个是 base
元素。title
元素,最多一个是 base
元素。head
元素的 开始标签
可以省略,如果该元素为空,或者如果 head
元素中的第一个元素是一个元素。head
元素的 结束标签
可以省略,如果 head
元素后面没有紧接着 ASCII 空白字符
或 注释。
[Exposed =Window ]
interface HTMLHeadElement : HTMLElement {
[HTMLConstructor ] constructor ();
};
head
元素中的元数据集合可以很小也可以很大。以下是一个非常短的示例:
<!doctype html>
< html lang = en >
< head >
< title > A document with a short head</ title >
</ head >
< body >
...
这是一个较长的示例:
<!DOCTYPE HTML>
< HTML LANG = "EN" >
< HEAD >
< META CHARSET = "UTF-8" >
< BASE HREF = "https://www.example.com/" >
< TITLE > An application with a long head</ TITLE >
< LINK REL = "STYLESHEET" HREF = "default.css" >
< LINK REL = "STYLESHEET ALTERNATE" HREF = "big.css" TITLE = "Big Text" >
< SCRIPT SRC = "support.js" ></ SCRIPT >
< META NAME = "APPLICATION-NAME" CONTENT = "Long headed application" >
</ HEAD >
< BODY >
...
title
元素在大多数情况下是必需的子元素,但当更高层协议提供标题信息时,例如在用作电子邮件编写格式的 HTML 的主题行中,可以省略 title
元素。
title
元素在所有当前引擎中均受支持。
在所有当前引擎中均受支持。
head
元素中包含的 title
元素。[Exposed =Window ]
interface HTMLTitleElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString text ;
};
title
元素 表示 文档的标题或名称。作者
应该使用能够在脱离上下文时(例如在用户的历史记录或书签中,或在搜索结果中)识别他们的文档的标题。文档的标题通常与其第一个标题不同,因为第一个标题不
必在脱离上下文时独立存在。
每个文档中只能有一个 title
元素。
如果文档没有标题是合理的,那么 Document
元素可能不是必需的。有关何时需要该元素,请参阅 head
元素的内容模型。
title.text [ = value ]
返回元素的 子文本内容。
可以设置,以用给定值替换元素的子节点。
text
属性的 getter 必须返回此 title
元素的 子文本内容。
text
属性的 setter 必须在此 title
元素中使用给定值进行 字符串替换。
以下是一些适当的标题示例,与可能在同一页面上使用的顶级标题进行对比。
< title > Introduction to The Mating Rituals of Bees</ title >
...
< h1 > Introduction</ h1 >
< p > This companion guide to the highly successful
< cite > Introduction to Medieval Bee-Keeping</ cite > book is...
下一页可能是同一站点的一部分。请注意,标题如何清晰地描述主题,而第一个标题假设读者知道上下文,因此不会怀疑舞蹈是 Salsa 还是 Waltz:
< title > Dances used during bee mating rituals</ title >
...
< h1 > The Dances</ h1 >
用作文档标题的字符串由 document.title
IDL 属性给出。
用户代理在用户界面中引用文档时,应使用文档的标题。当 title
元素的内容以这种方式使用时,方向性
应用于设置用户界面中文档标题的方向性。
base
元素支持所有当前引擎。
支持所有当前引擎。
head
元素的 base
元素中。href
— 文档基本 URL
target
— 默认 可导航 用于 超链接 导航 和 表单提交
[Exposed =Window ]
interface HTMLBaseElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute USVString href ;
[CEReactions ] attribute DOMString target ;
};
base
元素允许作者为解析 文档基本 URL
的目的指定基本 URL,并为 跟随超链接
的目的指定默认 可导航
的名称。该元素不 表示除这些信息之外的任何内容。
每个文档中只能有一个 base
元素。
一个 base
元素必须有一个 href
属性,一个 target
属性,或者两者都有。
href
内容
属性,如果指定,则必须包含一个 可能被空格包围的有效 URL。
一个 base
元素,如果有一个 href
属性,
必须出现在树中任何具有 URL 属性定义的其他元素之前,除了 html
元素(其
manifest
属性不受 base
元素影响)。
如果有多个 base
元素具有 href
属性,则除第一个之外的所有元素都将被忽略。
target
属性,
如果指定,则必须包含一个 有效的可导航目标名称或关键字,该名称或关键字指定
哪个 可导航 用作默认值,当 超链接 和 表单 在 文档
导致 导航。
一个 base
元素,如果有一个 target
属性,必须出现在树中代表 超链接 的任何元素之前。
如果有多个 base
元素具有 target
属性,则除第一个之外的所有元素都将被忽略。
要 获取元素的目标,给定一个 a
,area
,
或
form
元素 element,以及一个可选的字符串或空值 target
(默认为 null),请执行以下步骤:
如果 target 为 null,则:
如果 target 不为 null,并且包含一个 ASCII
制表符或换行符 和一个
U+003C (<),则将 target 设置为 "_blank
"。
返回 target。
在文档树中第一个具有 base
元素的 base
元素具有 href
内容属性的 冻结基本 URL。冻结基本 URL 必须在任何以下情况发生时 立即 为一个元素 设置:
要 设置冻结基本 URL 为元素 element:
让 document 成为 element 的 节点文档。
让 urlRecord 成为 解析 element 的 href
内容属性的结果,
使用 document 的 后备基本 URL,和
document 的 字符编码。(因此,base
元素不会受到自身的影响。)
如果以下任何情况为真:
urlRecord 失败;
urlRecord 的 方案 是
"data
" 或 "javascript
";或者
运行 文档允许的基本内容吗? 在 urlRecord 和
document 上返回 "Blocked
",
将 element 的 冻结基本 URL 设置为 urlRecord。
href
IDL
属性,在获取时,必须返回运行以下算法的结果:
让 document 成为 element 的 节点文档。
让 url 成为该元素的 href
属性的值(如果有),否则为空字符串。
让 urlRecord 成为 解析
url 的结果,使用 document 的 后备基本 URL 和
document 的 字符编码。
(因此,base
元素不会受到其他 base
元素或
自身的影响。)
如果 urlRecord 失败,则返回 url。
返回 序列化 的 urlRecord。
href
IDL
属性,在设置时,必须将 href
内容属性设置为给定的新值。
target
IDL
属性必须 反映同名的内容
属性。
在这个例子中,一个 base
元素用于设置 文档基本 URL:
<!DOCTYPE html>
< html lang = "en" >
< head >
< title > This is an example for the < base> element</ title >
< base href = "https://www.example.com/news/index.html" >
</ head >
< body >
< p > Visit the < a href = "archives.html" > archives</ a > .</ p >
</ body >
</ html >
上述示例中的链接将是一个指向 "https://www.example.com/news/archives.html
" 的链接。
link
元素支持所有当前引擎。
支持所有当前引擎。
noscript
元素中,该元素是 head
元素的子元素。href
—
超链接的地址
crossorigin
— 元素如何处理跨域请求
rel
—
包含超链接的文档与目标资源之间的关系
media
—
适用的媒体
integrity
— 在子资源完整性检查中使用的完整性元数据[SRI]
hreflang
— 链接资源的语言
type
—
引用资源的类型提示
referrerpolicy
— 为元素发起的fetch操作设置的引用者策略
sizes
—
图标的尺寸 (对于rel
="icon
")
imagesrcset
— 在不同情况下使用的图像,例如高分辨率显示器,小型监视器等(对于rel
="preload
")
imagesizes
— 针对不同页面布局的图像尺寸 (对于rel
="preload
")
as
— 预加载请求的潜在目标 (对于rel
="preload
"
和 rel
="modulepreload
")
blocking
— 元素是否为潜在渲染阻塞元素
color
—
在自定义站点图标时使用的颜色 (对于rel
="mask-icon
")
disabled
— 链接是否被禁用
fetchpriority
— 为元素发起的fetch操作设置优先级
title
属性在此元素上具有特殊语义: 链接的标题; CSS样式表集名称
[Exposed =Window ]
interface HTMLLinkElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute USVString href ;
[CEReactions ] attribute DOMString ? crossOrigin ;
[CEReactions ] attribute DOMString rel ;
[CEReactions ] attribute DOMString as ;
[SameObject , PutForwards =value ] readonly attribute DOMTokenList relList ;
[CEReactions ] attribute DOMString media ;
[CEReactions ] attribute DOMString integrity ;
[CEReactions ] attribute DOMString hreflang ;
[CEReactions ] attribute DOMString type ;
[SameObject , PutForwards =value ] readonly attribute DOMTokenList sizes ;
[CEReactions ] attribute USVString imageSrcset ;
[CEReactions ] attribute DOMString imageSizes ;
[CEReactions ] attribute DOMString referrerPolicy ;
[SameObject , PutForwards =value ] readonly attribute DOMTokenList blocking ;
[CEReactions ] attribute boolean disabled ;
[CEReactions ] attribute DOMString fetchPriority ;
// also has obsolete members
};
HTMLLinkElement includes LinkStyle ;
link
元素允许作者将文档链接到其他资源。
链接地址由 href
属性提供。如果
href
属性存在,则其值必须是 有效的非空 URL,可能被空格包围。必须存在 href
或 imagesrcset
属性中的一个或两个。
如果 href
和
imagesrcset
属性都不存在,则该元素不定义链接。
链接的类型(关系)由 rel
属性的值给出,该属性(如果存在)必须具有一个 唯一的用空格分隔的标记的无序集合。允许的关键字及其含义 在后面的部分定义。如果 rel
属性缺失、没有关键字,或使用的关键字都不符合本规范中的定义,则该元素不会创建任何链接。
rel
的 支持的标记 是在 HTML 链接类型
中定义的关键字,这些关键字在 link
元素上是被允许的,会影响处理模型,并且由用户代理支持。可能的 支持的标记 包括 alternate
、dns-prefetch
、expect
、icon
、manifest
、modulepreload
、next
、pingback
、preconnect
、prefetch
、preload
、search
和 stylesheet
。rel
的 支持的标记 必须仅包括用户代理实现处理模型的标记。
理论上,用户代理可以支持 canonical
关键字的处理模型——如果它是执行 JavaScript 的搜索引擎。但实际上这非常不可能。因此,在大多数情况下,canonical
不应包含在 rel
的
支持的标记 中。
link
元素必须具有 rel
属性或 itemprop
属性,但不能同时具有这两个属性。
如果 link
元素具有 itemprop
属性,或者具有仅包含 body-ok 关键字的 rel
属性,则该元素被认为是
允许在主体中使用。这意味着该元素可以在预期 短语内容 的位置使用。
如果使用了 rel
属性,则该元素仅在页面的
body
中有时可以使用。当与 itemprop
属性一起使用时,该元素可以在 head
元素和
body
中使用,前提是遵守微数据模型的约束。
使用 link
元素可以创建两类链接:外部资源链接 和 超链接。链接类型部分
定义了特定链接类型是外部资源还是超链接。一个 link
元素可以创建多个链接(其中一些可能是 外部资源链接,一些可能是
超链接);具体创建哪些链接以及创建多少链接取决于 rel
属性中给出的关键字。用户代理必须逐个链接地处理这些链接,而不是逐个元素地处理。
每个为 link
元素创建的链接都是单独处理的。例如,如果有两个 link
元素,其
rel="stylesheet"
,它们每个都计为一个单独的外部资源,并且每个都受其自身属性的独立影响。同样,如果一个 link
元素的
rel
属性的值为
next stylesheet
,它将同时创建一个 超链接(对应 next
关键字)和一个 外部资源链接(对应
stylesheet
关键字),并且它们会受到其他属性(如 media
或 title
)的不同影响。
例如,下面的 link
元素创建了两个 超链接(指向相同的页面):
< link rel = "author license" href = "/about" >
这个元素创建的两个链接分别具有以下语义:一个是目标页面有关于当前页面作者的信息,另一个是目标页面有关于当前页面提供的许可证的信息。
使用 link
元素及其
rel
属性创建的 超链接 适用于整个文档。这与 rel
属性在
a
和 area
元素中的作用不同,后者指示了链接的类型,其上下文由链接在文档中的位置决定。
与 a
和 area
元素创建的链接不同,超链接 由 link
元素创建时,默认情况下不会在文档中显示(在支持 建议默认渲染 的用户代理中)。即使通过 CSS 强制显示,它们也没有 激活行为。它们主要提供语义信息,可能被页面或其他使用页面内容的软件利用。此外,用户代理可以 提供自己的用户界面以跟随这些超链接。
外部资源链接 的确切行为取决于具体的关系,按相关 链接类型 定义。
crossorigin
属性是一个 CORS
设置属性。它旨在用于 外部资源链接。
media
属性指定资源适用于哪些媒体。其值必须是一个 有效的媒体查询列表。
支持所有当前的浏览器。
integrity
属性表示此元素负责的请求的 完整性元数据。该值为文本。该属性只能在具有 rel
属性且包含 stylesheet
、preload
或
modulepreload
关键字的 link
元素上指定。
[SRI]
hreflang
属性在 link
元素上具有与
hreflang
属性在
a
元素 上相同的语义。
type
属性提供了链接资源的 MIME 类型。它纯属建议。该值必须是 有效的 MIME
类型字符串。
对于 外部资源链接,type
属性作为提示提供给用户代理,以便它们可以避免获取不支持的资源。
referrerpolicy
属性是一个 引荐策略属性。它用于 外部资源链接,帮助设置 引荐策略,该策略在 获取和处理链接资源 时使用。[REFERRERPOLICY]
title
属性提供了链接的标题。除一个例外外,它纯属建议。该值为文本。唯一的例外是样式表链接,这些链接位于 文档树 中,对于这些链接,title
属性定义了 CSS 样式表集合。
title
属性在
link
元素上的行为与大多数其他元素的全局 title
属性不同:没有标题的链接不会继承父元素的标题;它只是没有标题。
imagesrcset
属性可以存在,并且是一个 srcset 属性。
imagesrcset
和 href
属性(如果没有使用 宽度描述符)共同构成 图像源 的 源集合。
如果 imagesrcset
属性存在且具有任何使用 宽度描述符 的
图像候选字符串,则
imagesizes
属性也必须存在,并且是一个 sizes
属性。imagesizes
属性贡献了 源大小 到 源集合。
imagesrcset
和 imagesizes
属性只能在 link
元素上指定,这些元素具有 rel
属性,该属性指定
preload
关键字,以及一个处于 "image
" 状态的 as
属性。
这些属性允许预加载适当的资源,稍后由具有相应值的 img
元素使用,其
srcset
和
sizes
属性如下:
< link rel = "preload" as = "image"
imagesrcset = "wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w"
imagesizes = "50vw" >
<!-- ... later, or perhaps inserted dynamically ... -->
< img src = "wolf.jpg" alt = "A rad wolf"
srcset = "wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w"
sizes = "50vw" >
注意我们省略了 href
属性,因为它仅在不支持 imagesrcset
的浏览器中才相关,在那些情况下,它可能会导致错误的图像被预加载。
imagesrcset
属性可以与 media
属性组合使用,以预加载从 picture
元素的源中选择的适当资源,用于 艺术方向:
< link rel = "preload" as = "image"
imagesrcset = "dog-cropped-1x.jpg, dog-cropped-2x.jpg 2x"
media = "(max-width: 800px)" >
< link rel = "preload" as = "image"
imagesrcset = "dog-wide-1x.jpg, dog-wide-2x.jpg 2x"
media = "(min-width: 801px)" >
<!-- ... later, or perhaps inserted dynamically ... -->
< picture >
< source srcset = "dog-cropped-1x.jpg, dog-cropped-2x.jpg 2x"
media = "(max-width: 800px)" >
< img src = "dog-wide-1x.jpg" srcset = "dog-wide-2x.jpg 2x"
alt = "An awesome dog" >
</ picture >
sizes
属性提供视觉媒体图标的大小。如果存在,其值仅为建议性。用户代理可以使用该值来决定在多个图标可用时使用哪个图标。如果指定,则属性值必须是一个 唯一的、以空格分隔的令牌的无序集合,并且是 ASCII 不区分大小写。每个值必须是 "any
"
字符串的 ASCII 不区分大小写 匹配,或者由两个 有效的非负整数 组成,这些整数没有前导的 U+0030 DIGIT ZERO (0) 字符,并且用一个 U+0078
LATIN SMALL LETTER X 或 U+0058 LATIN CAPITAL LETTER X 字符分隔。该属性仅在具有 rel
属性,并且该属性指定了
icon
关键字或
apple-touch-icon
关键字的 link
元素上指定。
`apple-touch-icon
` 关键字是一个注册的 预定义链接类型集合的扩展,但用户代理并不要求以任何方式支持它。
as
属性指定了一个 潜在的目标,用于预加载通过 href
属性指定的资源。
它是一个 枚举属性。每个 潜在目标
是该属性的一个关键字,映射到一个同名的状态。该属性必须在 link
元素上指定,这些元素具有一个 rel
属性,该属性包含
preload
关键字。它可以在 link
元素上指定,这些元素具有一个 rel
属性,该属性包含
modulepreload
关键字;在这种情况下,它必须具有一个 类似脚本的目标 值。对于其他 link
元素,不能指定此属性。
关于 as
属性如何使用的处理模型在每个链接类型的 获取和处理链接资源 算法中给出。
该属性没有 缺失值默认值 或
无效值默认值,这意味着无效或缺失的属性值不会映射到任何状态。这在处理模型中已被考虑。对于 preload
链接,两种情况都是错误的;对于 modulepreload
链接,缺失值将被视为 "script
"。
blocking
属性是一个 阻塞属性。它用于链接类型 stylesheet
和 expect
,并且只能在具有包含这些关键字的
rel
属性的链接元素上指定。
color
属性用于
mask-icon
链接类型。该属性只能在具有包含 mask-icon
关键字的 rel
属性的 link
元素上指定。其值必须是一个符合 CSS <color> 生成规则的字符串,定义一个建议的颜色,用户代理可以使用它来定制用户在固定网站时看到的图标的显示。
本规范对 color
属性没有任何用户代理要求。
mask-icon
关键字是对预定义链接类型集的一个注册 扩展,但用户代理并不要求以任何方式支持它。
link
元素具有一个关联的 显式启用 布尔值。初始值为 false。
disabled
属性是一个 布尔属性,用于 stylesheet
链接类型。该属性只能在具有 rel
属性包含 stylesheet
关键字的 link
元素上指定。
每当 disabled
属性被移除时,应将 link
元素的 显式启用 属性设置为 true。
例如,通过动态移除 disabled
属性,例如使用 document.querySelector("link").removeAttribute("disabled")
,将会获取并应用样式表:
< link disabled rel = "alternate stylesheet" href = "css/pooh" >
fetchpriority
属性是一个 获取优先级属性,旨在与 外部资源链接
一起使用,用于设置 请求优先级,该优先级在 获取和处理链接资源 时使用。
在所有当前引擎中支持。
IDL 属性
href
、
hreflang
、
integrity
、
media
、
rel
、
sizes
、
type
、
blocking
和
disabled
必须 反映 同名的内容属性。
对于 color
属性,没有反映的 IDL 属性,但这可能会在以后添加。
在所有当前引擎中支持。
as
IDL 属性必须 反映 as
内容属性,仅限于已知值。
crossOrigin
IDL 属性必须 反映 crossorigin
内容属性,仅限于已知值。
HTMLLinkElement/referrerPolicy
所有当前引擎都支持。
referrerPolicy
IDL 属性必须
反映 referrerpolicy
内容属性,仅限于已知值。
fetchPriority
IDL 属性必须
反映 fetchpriority
内容属性,仅限于已知值。
imageSrcset
IDL 属性必须 反映 imagesrcset
内容属性。
imageSizes
IDL 属性必须 反映 imagesizes
内容属性。
所有当前引擎都支持。
relList
属性可以用于功能检测,通过调用其 supports()
方法检查支持的 链接类型。
media
属性如果链接是 超链接,那么 media
属性仅为建议性质,描述了文档设计的媒体类型。
然而,如果链接是 外部资源链接,那么
media
属性是规定性的。当 media
属性的值
匹配环境
且其他相关条件适用时,用户代理必须应用
外部资源,否则不得应用。
如果省略了 media
属性,则默认值为 "all
",意味着默认情况下链接适用于所有媒体。
外部资源可能在该限制内定义了进一步的适用性限制。例如,CSS 样式表可能有一些 @media
块。本规范不会覆盖这些进一步的限制或要求。
type
属性如果 type
属性存在,则用户代理必须假设资源是给定类型的(即使那不是一个 有效的 MIME
类型字符串,例如空字符串)。如果属性被省略,但 外部资源链接 类型有一个默认类型定义,则用户代理必须假设资源是该类型。如果用户代理不支持给定的 MIME 类型 对于给定的链接关系,则用户代理应该 获取和处理链接资源;如果用户代理支持给定的 MIME 类型 对于给定的链接关系,则用户代理应该 获取和处理链接资源,按照为 外部资源链接
特定类型指定的适当时间进行。如果属性被省略,而 外部资源链接 类型没有默认类型定义,但用户代理会 获取和处理链接资源
如果类型已知且被支持,则用户代理应该 获取和处理链接资源,假设它将被支持。
用户代理不得将 type
属性视为权威 — 在获取资源时,用户代理不得使用 type
属性来确定其实际类型。只有实际类型(如下一段定义)用于确定是否应用 资源,而不是上述假设的类型。
如果 外部资源链接 类型定义了处理资源的 Content-Type 元数据 的规则,则适用这些规则。否则,如果资源预期是图像,用户代理可以应用 图像嗅探规则,官方类型为从资源的 Content-Type 元数据 确定的类型,并使用结果的 计算出的资源类型,就像它是实际类型一样。否则,如果这些条件都不适用或用户代理选择不应用图像嗅探规则,则用户代理必须使用资源的 Content-Type 元数据 来确定资源的类型。如果没有类型元数据,但 外部资源链接 类型有默认类型定义,则用户代理必须假设资源是该类型。
stylesheet
链接类型定义了处理资源的 Content-Type 元数据 的规则。
一旦用户代理确定了资源的类型,如果资源是受支持的类型且满足其他相关条件,则用户代理必须应用该资源,否则必须忽略该资源。
如果文档包含如下标签的样式表链接:
< link rel = "stylesheet" href = "A" type = "text/plain" >
< link rel = "stylesheet" href = "B" type = "text/css" >
< link rel = "stylesheet" href = "C" >
...那么一个仅支持 CSS 样式表的符合规范的用户代理将获取 B 和 C 文件,并跳过 A 文件(因为 text/plain
不是 CSS 样式表的 MIME 类型)。
对于文件 B 和 C,用户代理会检查服务器返回的实际类型。对于那些以 text/css
发送的文件,用户代理会应用样式,但对于那些标记为 text/plain
或其他类型的文件,则不会应用。
如果其中一个文件没有 Content-Type 元数据,或具有像
Content-Type: "null"
这样的语法不正确的类型,那么 stylesheet
链接的默认类型将会生效。由于默认类型是 text/css
,样式表 仍然会 被应用。
link
元素获取和处理资源所有的 外部资源链接 都有一个 获取和处理链接资源
算法,它接收一个 link
元素 el。它们还具有 链接资源获取设置步骤,它们接收一个 link
元素 el 和 请求 request。各个链接类型可能提供自己的 获取和处理链接资源
算法,但除非明确说明,否则它们使用 默认的获取和处理链接资源
算法。
同样,各个链接类型可能提供自己的 链接资源获取设置步骤,但除非明确说明,否则这些步骤仅返回
true。
给定一个 link
元素 el,默认的获取和处理链接资源 如下:
让 options 成为从 el 创建链接选项 的结果。
让 request 成为给定 options 的 创建链接请求 的结果。
如果 request 为 null,则返回。
设置 request 的 同步标志。
运行 链接资源获取设置步骤,给定 el 和 request。如果结果为 false,则返回。
如果 el 的 rel
属性包含关键字 stylesheet
,则将
request 的 发起者类型 设置为 "css
";否则设置为 "link
"。
获取 request,将 processResponseConsumeBody 设置为以下步骤,给定 响应 response 和 null、失败,或 字节序列 bodyBytes:
给定一个 链接处理选项 options 来 创建链接请求:
如果 options 的 destination 为 null,则返回 null。
让 url 成为给定 options 的 编码解析 URL 的结果,相对于 options 的 基本 URL。
传递基本 URL 而不是文档或环境的问题由 issue #9715 跟踪。
如果 url 失败,则返回 null。
让 request 成为给定 url、options 的 创建潜在 CORS 请求 的结果,以及 options 的 destination 和 crossorigin。
返回 request。
用户代理可以选择仅在需要时尝试 获取和处理 这些资源,而不是主动获取所有未应用的 外部资源。
类似于 获取和处理链接资源
算法,所有 外部资源链接 都有一个 处理链接资源 算法,该算法接受一个 link
元素 el,一个布尔值 success,一个 响应 response,以及一个 字节序列
bodyBytes。各个链接类型可以提供自己的 处理链接资源
算法,但除非明确声明,否则该算法不执行任何操作。
除非对给定的 rel
关键字另有说明,否则元素必须 延迟元素的加载事件,直到所有尝试 获取和处理链接资源
及其 关键子资源
完成。(用户代理尚未尝试获取和处理的资源,例如因为等待资源被需要,这些资源不会 延迟加载事件。)
Link
`
头部所有可以作为 外部资源链接 的链接类型都定义了一个
处理链接头部 算法,该算法接收 链接处理选项。这个算法定义了这些链接在 HTTP `Link
`
响应头部中出现时的反应方式。
对于大多数链接类型,这个算法不会执行任何操作。总结表 是快速了解某个链接类型是否定义了 处理链接头部 步骤的良好参考。
link
")Document
Document
auto
)
一个 链接处理选项 具有一个 基本 URL 和一个 href,而不是解析后的 URL,因为 URL 可能是选项的 source set 的结果。
要从一个 link
元素
el 创建链接选项:
令 document 为 el 的 节点文档。
令 options 为一个新的 链接处理选项,其值为:
as
属性的状态。
crossorigin
内容属性的状态referrerpolicy
内容属性的状态
fetchpriority
内容属性的状态如果 el 有一个 integrity
属性,则将 options 的 integrity 设置为 el 的 integrity
内容属性的值。
断言:options 的 href 不能为空字符串,或者 options 的 source set 不能为 null。
一个既没有 href
属性,也没有 imagesrcset
属性的 link
元素不代表一个链接。
返回 options。
要从头部中 提取链接,给定一个 头部列表 headers:
要 处理链接头部,给定一个 文档
doc,一个 响应 response,以及一个
"pre-media
" 或 "media
" phase:
对于每个 linkObject 在 links 中:
令 rel 为 linkObject["relation_type
"]。
令 attribs 为 linkObject["target_attributes
"]。
令 expectedPhase 为 "media
" 如果 "srcset
",
"imagesrcset
",
或 "media
"
存在 于 attribs 中;否则为 "pre-media
"。
如果 expectedPhase 不是 phase,则 继续。
令 options 为一个新的 链接处理选项,其具有:
将解析头部属性的链接选项应用 于 options 给定 attribs。
如果 attribs["imagesrcset
"]
存在 且 attribs["imagesizes
"]
存在,则将 options 的 源集 设置为结果 创建源集 的结果,给定
linkObject["target_uri
"]、attribs["imagesrcset
"]、
attribs["imagesizes
"],
和 null。
运行 处理链接头部 步骤,以 rel 和 options 进行。
将从解析的头部属性中获取的链接选项 应用 于 链接处理选项 options 给定 attribs:
如果 attribs["as
"]
存在,则将 options 的 目标 设置为 翻译 attribs["as
"] 的结果。
如果 attribs["crossorigin
"]
存在 并且是某个 ASCII
不区分大小写 匹配的 CORS
设置属性 关键词,
则将 options 的 crossorigin 设置为与该关键词对应的 CORS 设置属性 状态。
如果 attribs["integrity
"]
存在,则将 options 的 完整性 设置为 attribs["integrity
"]。
如果 attribs["referrerpolicy
"]
存在 并且是某个 ASCII
不区分大小写 匹配的 引荐政策,则将 options 的 引荐政策 设置为该 引荐政策。
如果 attribs["nonce
"]
存在,则将 options 的 nonce
设置为 attribs["nonce
"]。
如果 attribs["type
"]
存在,则将 options 的 type 设置为
attribs["type
"]。
如果 attribs["fetchpriority
"]
存在 并且是某个 ASCII
不区分大小写 匹配的 获取优先级属性 关键词,则将
options 的 获取优先级 设置为该 获取优先级属性 关键词。
早期提示 允许用户代理执行一些操作,例如在导航请求被服务器完全处理和响应码返回之前,推测性地加载文档可能会使用的资源。服务器可以通过在发送最终的响应之前,先发送一个状态码为103的响应来指示早期提示。[RFC8297]
出于兼容性原因,早期提示通常通过 HTTP/2 或更高版本传输,但为了可读性,下面使用 HTTP/1.1 风格的表示法。
例如,给定以下响应序列:
103 Early Hint Link: </image.png>; rel=preload; as=image
200 OK Content-Type: text/html <!DOCTYPE html> ... <img src="/image.png">
图片将在 HTML 内容到达之前开始加载。
在导航期间仅处理第一个早期提示响应,如果它被跨源重定向所取代,则会被丢弃。
除了 `Link
`
头部之外,103 响应可能包含一个内容安全策略头部,在处理早期提示时会强制执行。
例如,给定以下响应序列:
103 Early Hint Content-Security-Policy: style-src: self; Link: </style.css>; rel=preload; as=style
103 Early Hint Link: </image.png>; rel=preload; as=image
302 Redirect Location: /alternate.html
200 OK Content-Security-Policy: style-src: none; Link: </font.ttf>; rel=preload; as=font
字体和样式会被加载,而图片会被丢弃,因为在最终重定向链中只有第一个早期提示响应被尊重。晚到的内容安全策略头部在请求样式的操作已经完成之后才到达,但样式将无法在文档中访问。
要处理给定响应 response 和一个环境 reservedEnvironment的早期提示头部:
早期提示的 `Link
`
头部总是在最终响应的 `Link
`
头部之前处理,然后是 `link
` 元素。这相当于将早期和最终
`Link
`
头部的内容添加到文档的 `Document
` 的 `head
` 元素中,按相应顺序。
让 earlyPolicyContainer 成为创建策略容器从 fetch 响应的结果,给定 response 和 reservedEnvironment。
让 earlyHints 成为空的列表。
对于每个 linkObject 在 links 中:
一旦我们收到早期提示链接头部,我们就开始 获取 earlyRequest。如果在 Document
创建之前返回,我们将
earlyResponse 设置为该 响应 的结果,并且一旦 Document
被创建,我们就提交它(通过将其在 预加载资源映射中可用,仿佛它是一个 link
元素)。如果
Document
首先被创建,一旦 响应 可用时立即提交。
让 rel 为 linkObject["relation_type
"]。
让 options 成为一个新的 链接处理选项,包括
让 attribs 为 linkObject["target_attributes
"]。
只有 as
,crossorigin
,integrity
,和
type
属性作为早期提示处理的一部分。其他属性,特别是 blocking
,imagesrcset
,imagesizes
和 media
只有在 Document
被创建后才适用。
从解析的头部属性中应用链接选项 到 options 给定 attribs。
运行 处理链接头部 步骤给 rel 给定 options。
附加 options 到 earlyHints。
根据 Document
返回以下子步骤
doc:对于每个 options 在 earlyHints 中:
如果 options 的 on document ready 为 null,则将 options 的 document 设置为 doc。
否则,使用 doc 调用 options 的 on document ready。
link
元素创建的超链接进行访问的方式
交互式用户代理可以在其用户界面的某处为用户提供通过link
元素创建的超链接访问的方式。此类超链接访问算法的调用必须将userInvolvement参数设置为"browser UI
"。该规范未定义具体界面,但它可以包括以下信息(从元素的属性中获取,如下所述),以某种形式或另一种形式(可能简化),用于文档中每个使用link
元素创建的超链接:
rel
属性给出)
title
属性给出)。
href
属性给出)。
hreflang
属性给出)。
media
属性给出)。
用户代理还可以包括其他信息,例如资源的类型(由type
属性给出)。
meta
元素支持所有当前引擎。
支持所有当前引擎。
itemprop
属性:
流内容。
itemprop
属性:
短语内容。
charset
属性,或元素的http-equiv
属性处于编码声明状态:在head
元素中。
http-equiv
属性但不在编码声明状态中:在head
元素中。
http-equiv
属性但不在编码声明状态中:在作为head
元素子元素的noscript
元素中。
name
属性: 在期望元数据内容的地方。itemprop
属性:
在期望元数据内容的地方。
itemprop
属性:
在期望短语内容的地方
。name
—
元数据名称http-equiv
— 指令content
—
元素的值charset
— 字符编码声明media
—
适用的媒体[Exposed =Window ]
interface HTMLMetaElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString name ;
[CEReactions ] attribute DOMString httpEquiv ;
[CEReactions ] attribute DOMString content ;
[CEReactions ] attribute DOMString media ;
// also has obsolete members
};
The meta
元素 表示各种无法通过 title
,base
,link
,style
和script
元素表示的元数据。
The meta
元素可以通过
name
属性表示文档级元数据,通过 http-equiv
属性表示指令,通过 字符编码声明 表示 HTML 文档在序列化为字符串形式(例如用于网络传输或磁盘存储)时的文件编码,并使用
charset
属性表示。
必须指定 name
,http-equiv
,charset
和
itemprop
属性中的一个。
如果指定了 name
,http-equiv
,或
itemprop
,则必须指定
content
属性。否则,必须省略它。
The charset
属性指定文档使用的字符编码。这是一个字符编码声明。如果存在此属性,其值必须与字符串"utf-8
"进行ASCII 不区分大小写匹配。
charset
属性在meta
元素在 XML 文档中没有作用,但允许在 XML 文档中使用,以便于向 XML 迁移和从 XML 迁移。
每个文档中不应有多个带有 charset
属性的 meta
元素。
The content
属性在元素用于文档元数据或指令时提供其值。允许的值取决于具体的上下文,如本规范后续部分所述。
如果 meta
元素具有 name
属性,则它设置文档元数据。文档元数据以名称-值对的形式表示,name
属性在 meta
元素上给出名称,content
属性在同一元素上给出值。名称指定设置元数据的哪个方面;有效名称及其值的含义在后续部分中描述。如果 meta
元素没有
content
属性,则元数据名称-值对的值部分为空字符串。
The media
属性说明元数据适用的媒体。其值必须是有效的媒体查询列表。除非
name
是 theme-color
,media
属性对处理模型没有影响,作者不得使用。
The name
,content
,和 media
IDL 属性必须反映同名的相应内容属性。IDL 属性 httpEquiv
必须
反映内容属性 http-equiv
。
Support in all current engines.
本规范定义了一些用于 name
属性的
meta
元素名称。
名称不区分大小写,并且必须以 ASCII 不区分大小写 的方式进行比较。
application-name
值必须是一个简短的自由格式字符串,表示页面所代表的 Web 应用程序的名称。如果页面不是 Web 应用程序,则 application-name
元数据名称不得使用。可以使用 lang
属性指定每个名称的语言,提供 Web 应用程序名称的翻译。
每个文档中,不应有多个带有给定语言并且 name
属性值与 application-name
ASCII 不区分大小写匹配的 meta
元素。
用户代理可能会在 UI 中优先使用应用程序名称,而不是页面的 title
,因为标题可能包含与页面特定时间点相关的状态消息等信息,而不仅仅是应用程序的名称。
为了在给定语言列表(例如英国英语、美式英语和英语)中找到要使用的应用程序名称,用户代理必须执行以下步骤:
设 languages 为语言列表。
如果有 default language,并且该语言与 languages 中的任何语言不同,则将其追加到 languages。
设 winning language 为 languages 中第一个有 meta
元素的语言,其中 name
属性值与 application-name
ASCII 不区分大小写匹配,并且其语言是相关语言。
如果没有语言具有这样的 meta
元素,则返回;没有给定的应用程序名称。
返回 content
属性的值,该值是 Document
中第一个
meta
元素的值,该元素的 name
属性值与 application-name
ASCII 不区分大小写匹配,并且其语言是
winning language。
此算法将在浏览器需要页面名称时使用,例如用于标记书签。浏览器会将用户的首选语言提供给算法。
author
值必须是一个自由格式字符串,表示页面的某个作者的名字。
description
值必须是一个自由格式字符串,描述页面的内容。该值必须适合用于页面目录中,例如在搜索引擎中。每个文档中,不应有多个 meta
元素,其 name
属性值与 description
ASCII 不区分大小写匹配。
generator
值必须是一个自由格式字符串,标识生成文档所使用的某个软件包。如果页面的标记不是由软件生成的,例如由用户在文本编辑器中编写的页面,则不应使用此值。
这是一个名为“Frontweaver”的工具在页面的 head
元素中包含的内容,以识别自己为生成页面的工具:
< meta name = generator content = "Frontweaver 8.2" >
keywords
值必须是一个 逗号分隔的令牌集,其中每个令牌都是与页面相关的关键字。
这个关于英国高速公路字体的页面使用一个 meta
元素来指定一些用户可能用来查找页面的关键字:
<!DOCTYPE HTML>
< html lang = "en-GB" >
< head >
< title > Typefaces on UK motorways</ title >
< meta name = "keywords" content = "british,type face,font,fonts,highway,highways" >
</ head >
< body >
...
许多搜索引擎不考虑此类关键字,因为这种功能历史上被不可靠甚至误导性地用于通过使用不适合用户的关键字来垃圾搜索引擎结果。
为了获取作者指定为页面适用的关键字列表,用户代理必须运行以下步骤:
设 keywords 为一个空列表。
对于每个具有 name
属性和 content
属性的 meta
元素,并且其 name
属性值与 keywords
ASCII 不区分大小写匹配:
将生成的令牌(如果有)添加到 keywords。
从 keywords 中删除任何重复项。
返回 keywords。这是作者指定为页面适用的关键字列表。
当信息的可靠性不足时,用户代理不应使用此信息。
例如,内容管理系统在系统内页面中使用关键字信息来填充站点搜索引擎的索引是合理的,但大型内容聚合器使用此信息可能会发现某些用户会尝试通过使用不合适的关键字来操纵其排名机制。
referrer
值必须是一个 referrer policy,它定义了 Document
的默认 referrer policy。[REFERRERPOLICY]
如果任何 meta
元素 element 被 插入到文档中,或其 name
或 content
属性发生变化,用户代理必须运行以下算法:
如果 element 未 在文档树中,则返回。
如果 element 没有 content
属性,或者该属性的值为空字符串,则返回。
设 value 为 element 的 content
属性的值,转换为
ASCII 小写。
如果 value 是以下表格第一列中的值之一,则将 value 设置为第二列中的值:
旧值 | 引用政策 |
---|---|
never
|
no-referrer
|
default
|
默认引用政策 |
always
|
unsafe-url
|
origin-when-crossorigin
|
origin-when-cross-origin
|
由于历史原因,与其他标准元数据名称不同,referrer
的处理模型对元素移除不敏感,并且不使用 树顺序。只有最新插入或最近修改的 meta
元素在此状态下有效。
theme-color
值必须是与 CSS <color> 生产规则匹配的字符串,定义一个建议的颜色,用户代理应使用该颜色来自定义页面或周围用户界面的显示。例如,浏览器可能会使用指定的值来为页面的标题栏着色,或者在标签栏或任务切换器中使用它作为颜色高亮。
在 HTML 文档中,media
属性值必须在所有 meta
元素中唯一,这些元素的 name
属性值与 theme-color
ASCII 不区分大小写匹配。
本标准本身使用“WHATWG 绿色”作为其主题颜色:
<!DOCTYPE HTML>
< title > HTML Standard</ title >
< meta name = "theme-color" content = "#3c790a" >
...
media
属性可用于描述应使用提供颜色的上下文。
如果我们只想在黑暗模式下使用“WHATWG 绿色”作为本标准的主题颜色,可以使用 prefers-color-scheme
媒体功能:
<!DOCTYPE HTML>
< title > HTML Standard</ title >
< meta name = "theme-color" content = "#3c790a" media = "(prefers-color-scheme: dark)" >
...
为了获取页面的主题颜色,用户代理必须运行以下步骤:
设 candidate elements 为满足以下条件的所有 meta
元素列表,按 树顺序 排列:
该元素在 文档树中;
该元素具有一个 name
属性,其值与 theme-color
ASCII 不区分大小写匹配;
该元素具有 content
属性。
对于 candidate elements 中的每个 element:
返回无(页面没有主题颜色)。
如果任何 meta
元素被插入到文档中或从文档中移除,或现有的 meta
元素的 name
、content
或 media
属性发生变化,或者环境变化导致任何 meta
元素的 media
属性的值现在可能与环境匹配或不匹配,用户代理必须重新运行上述算法并将结果应用于任何受影响的 UI。
在 UI 中使用主题颜色时,用户代理可能会以实现特定的方式调整它,使其更适合相应的 UI。例如,如果用户代理打算使用主题颜色作为背景并在其上显示白色文本,则可能会在 UI 的该部分中使用较深的主题颜色变体,以确保足够的对比度。
color-scheme
为了帮助用户代理立即以所需的配色方案渲染页面背景(而不是等待页面中的所有CSS加载完成),可以在‘color-scheme’值中提供在meta
元素中。
该值必须是符合CSS‘color-scheme’属性值语法的字符串。它决定了页面支持的配色方案。
每个文档中不得有多个meta
元素,其name
属性值设置为color-scheme
的ASCII不区分大小写匹配。
以下声明指示页面可以处理具有深色背景和浅色前景颜色的颜色方案:
< meta name = "color-scheme" content = "dark" >
为了获取页面支持的颜色方案,用户代理必须运行以下步骤:
设 candidate elements 为满足以下条件的所有 meta
元素列表,按 树顺序 排列:
该元素在 文档树中;
该元素具有一个 name
属性,其值与 color-scheme
ASCII 不区分大小写匹配;
该元素具有 content
属性。
对于 candidate elements 中的每个 element:
content
属性的值。返回 null。
如果任何 meta
元素被 插入到文档中或 从文档中移除,或者现有的 meta
元素的 name
或 content
属性发生变化,用户代理必须重新运行上述算法。
由于这些规则会检查连续的元素直到找到匹配项,因此作者可以提供多个这样的值以处理旧版用户代理的回退。与 CSS 属性的回退方式相反,多个 meta 元素需要按旧版值在新值之后的顺序排列。
任何人都可以创建并使用他们自己的扩展预定义的元数据名称集合。没有要求必须注册这些扩展。
但是,在以下任何情况下都不应创建新的元数据名称:
如果名称是URL,或者其附带的 content
属性的值是 URL;在这些情况下,建议将其注册为扩展预定义的链接类型集合(而不是创建新的元数据名称)。
如果该名称用于期望在用户代理中具有处理要求的内容;在这种情况下,它应该被标准化。
此外,在创建和使用新的元数据名称之前,建议咨询 WHATWG Wiki MetaExtensions 页面 — 以避免选择已经在使用的元数据名称,避免重复已经在使用的元数据名称的目的,并避免新标准化名称与您选择的名称冲突。[WHATWGWIKI]
任何人都可以随时编辑 WHATWG Wiki MetaExtensions 页面以添加元数据名称。新的元数据名称可以用以下信息来指定:
实际定义的名称。名称不应与任何其他定义的名称相似(例如,仅在大小写上不同)。
元数据名称含义的简短非规范性描述,包括值所需的格式。
具有完全相同处理要求的其他名称列表。作者不应使用定义为同义词的名称(它们仅用于允许用户代理支持旧内容)。任何人都可以删除实际上未使用的同义词;仅需要为了与旧内容兼容而处理为同义词的名称应以这种方式注册。
以下之一:
如果发现元数据名称与现有值重复,则应将其删除并列为现有值的同义词。
如果元数据名称在“已提议”状态下添加一个月或更长时间而未使用或未规范,则可以将其从 WHATWG Wiki MetaExtensions 页面中删除。
如果元数据名称在“已提议”状态下添加,并被发现与现有值重复,则应将其删除并列为现有值的同义词。如果元数据名称在“已提议”状态下添加并被发现有害,则应将其更改为“已停用”状态。
任何人都可以随时更改状态,但应仅按照上述定义进行更改。
当http-equiv
属性在
meta
元素上指定时,该元素即为一个pragma指令。
http-equiv
属性是一个枚举属性,具有以下关键字和状态:
关键字 | 符合 | 状态 | 简要描述 |
---|---|---|---|
content-language |
否 | 内容语言 | 设置pragma-set默认语言。 |
content-type |
编码声明 | 设置charset 的另一种形式。
|
|
default-style |
默认样式 | 设置默认CSS样式表集的名称。 | |
refresh |
刷新 | 充当定时重定向。 | |
set-cookie |
否 | 设置Cookie | 无效。 |
x-ua-compatible |
X-UA-Compatible | 实际上,鼓励Internet Explorer更严格地遵循规范。 | |
content-security-policy |
内容安全策略 | 强制实施 内容安全策略于 文档 。 |
当一个 meta
元素被插入到文档中时,如果其http-equiv
属性存在并且表示上述某个状态,则用户代理必须运行与该状态相对应的算法,如下列表所述:
http-equiv="content-language
"
)
此功能不符合规范。建议作者使用 lang
属性代替。
此pragma设置pragma-set默认语言。在此类pragma成功处理之前,没有pragma-set默认语言。
如果元素的 content
属性包含U+002C逗号字符(,),则返回。
令input为元素的 content
属性的值。
令position指向 input 的第一个字符。
跳过ASCII空白字符在input中给定position。
收集一系列码点,这些码点不是ASCII 空白字符,从input给定的position。
令candidate为前一步骤结果的字符串。
如果candidate为空字符串,则返回。
将pragma-set默认语言设置为candidate。
如果该值包含多个以空格分隔的标记,则忽略第一个之后的标记。
此pragma与同名的HTTP Content-Language
标头几乎完全不同。[HTTP]
http-equiv="content-type
"
)
编码声明状态只是设置 charset
属性的另一种形式:它是一个字符编码声明。此状态的用户代理要求全部由规范的解析部分处理。
对于 meta
元素,其 http-equiv
属性处于编码声明状态,其 content
属性的值必须是与以下字符串ASCII不区分大小写匹配的字符串:“text/html;
”,后面可以跟任意数量的ASCII空白,然后是“charset=utf-8
”。
一个文档不得同时包含meta
元素,其http-equiv
属性处于编码声明状态和一个具有charset
属性的meta
元素。
编码声明状态可以在HTML文档中使用,但在http-equiv
属性处于该状态的元素不得在XML文档中使用。
http-equiv="default-style
"
)
仅在一个引擎中支持。
更改首选CSS样式表集名称,名称为元素的content
属性的值。
[CSSOM]
http-equiv="refresh
"
)
此pragma充当定时重定向。
一个文档
对象具有一个关联的将声明性刷新(一个布尔值)。最初为false。
令input为元素的content
属性的值。
给定一个文档
对象document、字符串input和可选的meta
元素meta,共享声明性刷新步骤如下:
如果document的将声明性刷新为true,则返回。
令position指向input的第一个码点。
跳过ASCII空白在input中给定position。
令time为0。
如果timeString为空字符串,则:
如果input中position指向的码点不是U+002E (.),则返回。
否则,将time设置为使用解析非负整数的规则解析timeString的结果。
收集一系列码点,这些码点是ASCII数字和U+002E全停止字符(.)从input中给定position。忽略任何收集到的字符。
令urlRecord为document的URL。
如果position不在input的末尾,则:
如果position不在input的末尾,则:
令urlString为input的子字符串,从position的码点到字符串的末尾。
如果input中position指向的码点是U+0055 (U)或U+0075 (u),则将position前进到下一个码点。否则,跳到标签为skip quotes的步骤。
如果input中position指向的码点是U+0052 (R)或U+0072 (r),则将position前进到下一个码点。否则,跳到标签为parse的步骤。
如果input中position指向的码点是U+004C (L)或U+006C (l),则将position前进到下一个码点。否则,跳到标签为parse的步骤。
跳过ASCII空白在input中给定position。
如果input中position指向的码点是U+003D(=),则将position前进到下一个码点。否则,跳到标签为parse的步骤。
跳过ASCII空白在input中给定position。
跳过引号:如果input中position指向的码点是U+0027(')或U+0022("),则令quote为该码点,并将position前进到下一个码点。否则,令quote为空字符串。
将urlString设置为input的子字符串,从position的码点到字符串的末尾。
如果quote不是空字符串,并且urlString中有一个码点等于quote,则在该码点处截断urlString,以便将其及所有后续码点移除。
解析:将urlRecord设置为编码解析URL的结果给定urlString,相对于document。
如果urlRecord失败,则返回。
将document的将声明性刷新设置为true。
执行以下一个或多个步骤:
在刷新到期后(定义如下),如果用户未取消重定向,并且如果给定meta,document的活动沙箱标志集没有沙箱自动功能浏览上下文标志设置,则导航至document的节点可导航至urlRecord使用document,历史处理设置为"替换
"。
为了上段的目的,刷新被认为是到期的,只要以下两个条件中的较晚一个发生:
此处使用document非常重要,而不是meta的节点文档,因为在初始步骤和刷新到期之间可能已更改,并且meta并不总是给定(在HTTPRefresh
标头的情况下)。
什么都不做。
此外,用户代理可以像任何操作一样,通知用户其操作的任何和所有方面,包括定时器的状态、任何定时重定向的目的地等。
对于meta
元素,其http-equiv
属性处于刷新状态,其content
属性的值必须是以下之一:
URL
"不区分大小写的匹配,后跟一个U+003D等号字符(=),后跟一个有效的URL字符串,该字符串不以文字U+0027撇号(')或U+0022引号(")字符开头。在前一种情况下,整数表示页面重新加载之前的秒数;在后一种情况下,整数表示页面替换为给定URL页面之前的秒数。
新闻组织的首页可能会在页面的head
元素中包含以下标记,以确保页面每五分钟自动从服务器重新加载一次:
< meta http-equiv = "Refresh" content = "300" >
一系列页面 可以用作自动幻灯片放映,每个页面使用类似以下的标记刷新到序列中的下一个页面:
< meta http-equiv = "Refresh" content = "20; URL=page4.html" >
http-equiv="set-cookie
"
)
此pragma不符合规范且无效。
用户代理必须忽略此pragma。
http-equiv="x-ua-compatible
"
)
实际上,此pragma鼓励Internet Explorer更紧密地遵循规范。
对于meta
元素,其http-equiv
属性处于X-UA-Compatible 状态,其content
属性的值必须与字符串"IE=edge
" ASCII不区分大小写的匹配。
用户代理必须忽略此pragma。
http-equiv="content-security-policy
"
)
此pragma 强制执行 内容安全策略在一个文档
上。[CSP]
令policy为执行内容安全策略的解析序列化内容安全策略算法的结果,针对meta
元素的content
属性的值,来源为"meta",并且处置为"enforce"。
从policy中移除所有report-uri
、
frame-ancestors
和
sandbox
的
指令。
强制执行策略policy。
对于具有meta
元素中的http-equiv
属性的元素在内容安全策略状态中,content
属性必须具有由有效内容安全策略组成的值,但不得包含任何report-uri
、frame-ancestors
或sandbox
指令。在content
属性中给出的内容安全策略将被强制执行于当前文档。[CSP]
在将meta
元素插入到文档中时,一些资源可能已经被获取。例如,在动态插入具有http-equiv
属性的meta
元素之前,图像可能已存储在可用图像列表中。已经获取的资源不保证被内容安全策略阻止,这些策略被强制执行得较晚。
一个页面可能选择通过阻止内联JavaScript的执行以及阻止所有插件内容来降低跨站点脚本攻击的风险,使用如下策略:
< meta http-equiv = "Content-Security-Policy" content = "script-src 'self'; object-src 'none'" >
文档中同一时间不应有多个meta
元素处于任何特定状态。
字符编码声明是一种用于指定存储或传输文档时所使用的字符编码的机制。
编码标准要求使用UTF-8字符编码,并要求使用“utf-8
”编码标签来标识它。这些要求使得文档的字符编码声明,如果存在的话,必须使用一个与“utf-8
”进行ASCII大小写不敏感匹配的编码标签来指定。无论是否存在字符编码声明,用于编码文档的实际字符编码必须是UTF-8。[ENCODING]
为了执行上述规则,创作工具必须默认使用UTF-8 来创建新文档。
以下限制也适用:
此外,由于meta
元素上的一些限制,每个文档只能有一个基于meta
的字符编码声明。
如果一个HTML文档没有以BOM开始,且其编码没有被内容类型元数据显式给出,且该文档不是iframe的srcdoc文档,那么必须使用带有charset
属性的meta
元素或带有http-equiv
属性的meta
元素来指定编码状态。
字符编码声明是必需的(无论是在内容类型元数据中还是在文件中显式声明),即使所有字符都在ASCII范围内,因为处理用户在表单中输入的非ASCII字符、脚本生成的URL等时需要字符编码。
使用非UTF-8编码在表单提交和URL编码上可能会产生意外结果,这些默认使用文档的字符编码。
如果文档是iframe的srcdoc文档,则文档不得有字符编码声明。(在这种情况下,源代码已经解码,因为它是包含iframe
的文档的一部分。)
在XML中,如果需要内联字符编码信息,应使用XML声明。
在HTML中,要声明字符编码为UTF-8,作者可以在文档顶部附近(在head
元素中)包含以下标记:
< meta charset = "utf-8" >
在XML中,应该使用XML声明,位于标记的最顶部:
<?xml version="1.0" encoding="utf-8"?>
style
元素支持所有当前引擎。
支持所有当前引擎。
media
— 适用的媒体blocking
— 元素是否可能阻碍渲染title
属性在该元素上具有特殊语义:CSS样式表集名称[Exposed =Window ]
interface HTMLStyleElement : HTMLElement {
[HTMLConstructor ] constructor ();
attribute boolean disabled ;
[CEReactions ] attribute DOMString media ;
[SameObject , PutForwards =value ] readonly attribute DOMTokenList blocking ;
// also has obsolete members
};
HTMLStyleElement includes LinkStyle ;
style
元素允许作者在文档中嵌入CSS样式表。style
元素是样式处理模型的多个输入之一。该元素不表示用户内容。
支持所有当前引擎。
disabled
获取器步骤如下:
disabled
设置器步骤如下:
重要的是,只有当style
元素具有关联的CSS样式表时,disabled
属性分配才会生效:
const style = document. createElement( 'style' );
style. disabled = true ;
style. textContent = 'body { background-color: red; }' ;
document. body. append( style);
console. log( style
. disabled); // false
media
属性指示样式适用于哪些媒体。值必须是有效的媒体查询列表。用户代理必须在media
属性的值与环境匹配且其他相关条件适用时应用样式,否则不得应用。
样式可能在范围内进一步受限,例如在CSS中使用@media
块。本规范不覆盖此类进一步的限制或要求。
默认情况下,如果省略media
属性,则为"all
",即默认样式适用于所有媒体。
blocking
属性是一个阻碍属性。
仅在一个引擎中支持。
title
属性在style
元素上定义了CSS样式表集。如果style
元素没有title
属性,则它没有标题;祖先的title
属性不适用于style
元素。如果style
元素不在文档树中,则忽略title
属性。[CSSOM]
title
属性在style
元素上,与title
属性在link
元素上不同,全局title
属性不适用于没有标题的style
块:它只是没有标题。
style
元素如果是由其节点文档的解析器创建的,则隐含地可能阻碍渲染。
用户代理必须在发生以下任何情况时运行更新style
块算法:
更新style
块算法如下:
让element成为style
元素。
如果element不是连接状态,则返回。
如果element的type
属性存在且其值既不是空字符串也不是text/css
的ASCII大小写不敏感匹配,则返回。
特别是,具有参数的type
值,如"text/css; charset=utf-8
",将导致此算法提前返回。
如果内容安全策略应阻止元素的内联行为吗?算法在style
元素、"style
"和style
元素的子文本内容上执行时返回"Blocked
",则返回。[CSP]
创建一个CSS样式表,具有以下属性:
如果element贡献了阻止脚本的样式表,则将element追加到其节点文档的阻止脚本样式表集中。
一旦尝试获取样式表的关键子资源(如果有)完成,或者,如果样式表没有关键子资源,则一旦样式表已解析和处理,用户代理必须运行这些步骤:
获取关键子资源未明确定义;可能问题#968是对此的最佳解决方案。同时,任何关键子资源请求应根据当前style
元素是否阻碍渲染来设置其阻碍渲染标志。
让element成为style
元素,与样式表关联。
让success为true。
如果获取样式表的任何关键子资源的尝试因任何原因(例如,DNS错误、HTTP 404响应、连接过早关闭、不支持的Content-Type)失败,则将success设置为false。
请注意,内容特定的错误,例如CSS解析错误或PNG解码错误,不会影响success。
该元素必须延迟加载事件,直到所有尝试获取样式表的关键子资源(如果有)完成。
本规范未指定样式系统,但大多数网页浏览器预计会支持CSS。[CSS]
支持所有当前引擎。
media
和blocking
IDL属性必须分别反映同名的内容属性。
以下文档将强调部分样式为亮红色文本,而非斜体文本,同时保持作品标题和拉丁文的默认斜体。它展示了如何使用适当的元素来简化文档的重新样式化。
<!DOCTYPE html>
< html lang = "en-US" >
< head >
< title > My favorite book</ title >
< style >
body { color : black ; background : white ; }
em { font-style : normal ; color : red ; }
</ style >
</ head >
< body >
< p > My < em > favorite</ em > book of all time has < em > got</ em > to be
< cite > A Cat's Life</ cite > . It is a book by P. Rahmel that talks
about the < i lang = "la" > Felis catus</ i > in modern human society.</ p >
</ body >
</ html >
如果样式表未引用其他资源(例如,它是由没有@import
规则的style
元素给出的内部样式表),则样式规则必须立即提供给脚本;否则,样式规则必须在事件循环到达其更新渲染步骤时才提供给脚本。
在文档
的上下文中,一个元素el如果满足以下所有条件,则贡献了阻止脚本的样式表:
el是由该文档
的解析器创建的。
el要么是style
元素,要么是当el由解析器创建时是一个外部资源链接(贡献到样式处理模型)的link
元素。
el的media
属性的值与环境匹配。
el的样式表在元素创建时是启用的。
用户代理尚未放弃加载那个特定的样式表。用户代理可以在任何时候放弃加载样式表。
如果在样式表加载之前放弃样式表,则即使样式表最终加载,脚本也可能最终使用不正确的信息。例如,如果样式表将一个元素的颜色设置为绿色,但在样式表加载之前执行了检查结果样式的脚本,则脚本会发现元素是黑色(或其他默认颜色),可能因此做出错误的选择(例如,决定在页面其他地方使用黑色,而不是绿色)。实现者必须平衡脚本使用不正确信息的可能性与等待慢速网络请求完成时的不作为对性能的影响。
预计上述规则的对应规则也适用于<?xml-stylesheet?>
处理指令。但是,这尚未彻底调查。
如果以下步骤返回true,则文档
document有一个阻止脚本的样式表:
如果document的节点可导航对象为null,则返回false。
如果containerDocument非null且containerDocument的阻止脚本的样式表集不为空,则返回true。
返回false。
如果一个文档
没有阻止脚本的样式表,则它不有一个阻止脚本的样式表。
Introduction_to_HTML/Document_and_website_structure#HTML_for_structuring_content
所有当前引擎支持。
body
元素所有当前引擎支持。
所有当前引擎支持。
html
元素中的第二个元素。body
元素内的第一个内容不是 ASCII 空白 或 注释,则可以省略 body
元素的开始标签,除非 body
元素内的第一个内容是 meta
、noscript
、link
、script
、style
或
template
元素。
body
元素后面不是紧跟一个 注释,则可以省略
body
元素的结束标签。
onafterprint
onbeforeprint
onbeforeunload
onhashchange
onlanguagechange
onmessage
onmessageerror
onoffline
ononline
onpageswap
onpagehide
onpagereveal
onpageshow
onpopstate
onrejectionhandled
onstorage
onunhandledrejection
onunload
[Exposed =Window ]
interface HTMLBodyElement : HTMLElement {
[HTMLConstructor ] constructor ();
// also has obsolete members
};
HTMLBodyElement includes WindowEventHandlers ;
在符合规范的文档中,只有一个 body
元素。document.body
IDL 属性为脚本提供了访问文档的 body
元素的便捷方法。
一些 DOM 操作(例如,拖放模型的某些部分)是根据“body 元素”定义的。这指的是
DOM 中的特定元素,而不是任意的 body
元素。
body
元素将 事件处理程序内容属性 作为多个 事件处理程序 的公开。它还反映了这些事件处理程序的 事件处理程序 IDL 属性。
Window
对象的 事件处理程序,在 Window
-反射 body 元素事件处理程序集
中命名的,由 body
元素公开,替换了普通 事件处理程序
的相同名称,通常由 HTML 元素 支持。
因此,例如,在一个 error
事件冒泡到 body 元素
的子元素时,会首先触发该元素的 onerror
事件处理程序内容属性,然后触发根 html
元素的事件处理程序,最后才会触发 onerror
事件处理程序内容属性 在
body
元素上。这是因为事件会从目标冒泡到 body
,再到
html
,再到
Document
,再到 Window
,并且 事件处理程序 在 body
上是监视
Window
而不是 body
。然而,附加到
body
的常规事件监听器使用 addEventListener()
,会在事件通过 body
冒泡时运行,而不是在它到达 Window
对象时运行。
此页面更新指示器以显示用户是否在线:
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< title > Online or offline?</ title >
< script >
function update( online) {
document. getElementById( 'status' ). textContent =
online ? 'Online' : 'Offline' ;
}
</ script >
</ head >
< body ononline = "update(true)"
onoffline = "update(false)"
onload = "update(navigator.onLine)" >
< p > You are: < span id = "status" > (Unknown)</ span ></ p >
</ body >
</ html >
article
元素在所有当前引擎中支持。
HTMLElement
.article
元素 表示
文档、页面、应用程序或网站中的一个完整或自包含的组成部分,并且原则上可以独立分发或重用,例如,在联合发布中。这可以是论坛帖子、杂志或报纸文章、博客条目、用户提交的评论、互动小部件或设备,或任何其他独立的内容项。
当article
元素嵌套时,内部的 article
元素表示与外部文章内容相关的文章。例如,一个允许用户提交评论的网站上的博客条目可以将评论表示为在该博客条目的article
元素内嵌套的article
元素。
与article
元素关联的作者信息(见 address
元素)不适用于嵌套的 article
元素。
当特定用于要在联合发布中重新分发的内容时,article
元素的用途类似于 Atom 中的 entry
元素。[ATOM]
可以使用 schema.org 微数据词汇提供 article
元素的出版日期,使用 CreativeWork 子类型之一。
当页面的主要内容(即不包括页脚、页眉、导航块和侧边栏)完全是一个自包含的组成部分时,可以使用article
标记这些内容,但在这种情况下,它在技术上是多余的(因为页面本身就是一个单一的文档,很明显它是一个单一的组成部分)。
此示例展示了一个使用article
元素的博客帖子,并附有一些
schema.org 注释:
< article itemscope itemtype = "http://schema.org/BlogPosting" >
< header >
< h2 itemprop = "headline" > The Very First Rule of Life</ h2 >
< p >< time itemprop = "datePublished" datetime = "2009-10-09" > 3 days ago</ time ></ p >
< link itemprop = "url" href = "?comments=0" >
</ header >
< p > If there's a microphone anywhere near you, assume it's hot and
sending whatever you're saying to the world. Seriously.</ p >
< p > ...</ p >
< footer >
< a itemprop = "discussionUrl" href = "?comments=1" > Show comments...</ a >
</ footer >
</ article >
这是同一个博客帖子,但显示了一些评论:
< article itemscope itemtype = "http://schema.org/BlogPosting" >
< header >
< h2 itemprop = "headline" > The Very First Rule of Life</ h2 >
< p >< time itemprop = "datePublished" datetime = "2009-10-09" > 3 days ago</ time ></ p >
< link itemprop = "url" href = "?comments=0" >
</ header >
< p > If there's a microphone anywhere near you, assume it's hot and
sending whatever you're saying to the world. Seriously.</ p >
< p > ...</ p >
< section >
< h1 > Comments</ h1 >
< article itemprop = "comment" itemscope itemtype = "http://schema.org/Comment" id = "c1" >
< link itemprop = "url" href = "#c1" >
< footer >
< p > Posted by: < span itemprop = "creator" itemscope itemtype = "http://schema.org/Person" >
< span itemprop = "name" > George Washington</ span >
</ span ></ p >
< p >< time itemprop = "dateCreated" datetime = "2009-10-10" > 15 minutes ago</ time ></ p >
</ footer >
< p > Yeah! Especially when talking about your lobbyist friends!</ p >
</ article >
< article itemprop = "comment" itemscope itemtype = "http://schema.org/Comment" id = "c2" >
< link itemprop = "url" href = "#c2" >
< footer >
< p > Posted by: < span itemprop = "creator" itemscope itemtype = "http://schema.org/Person" >
< span itemprop = "name" > George Hammond</ span >
</ span ></ p >
< p >< time itemprop = "dateCreated" datetime = "2009-10-10" > 5 minutes ago</ time ></ p >
</ footer >
< p > Hey, you have the same first name as me.</ p >
</ article >
</ section >
</ article >
注意使用了footer
来提供每条评论的信息(例如,谁写的以及何时写的):footer
元素可以在其部分的开头出现,当情况合适时,例如在这种情况下。(在这种情况下使用header
也不会错误;这主要是作者的个人偏好问题。)
在这个示例中,article
元素用于在门户页面上托管小部件。这些小部件被实现为自定义内置元素,以获得特定的样式和脚本行为。
<!DOCTYPE HTML>
< html lang = en >
< title > eHome Portal</ title >
< script src = "/scripts/widgets.js" ></ script >
< link rel = stylesheet href = "/styles/main.css" >
< article is = "stock-widget" >
< h2 > Stocks</ h2 >
< table >
< thead > < tr > < th > Stock < th > Value < th > Delta
< tbody > < template > < tr > < td > < td > < td > </ template >
</ table >
< p > < input type = button value = "Refresh" onclick = "this.parentElement.refresh()" >
</ article >
< article is = "news-widget" >
< h2 > News</ h2 >
< ul >
< template >
< li >
< p >< img > < strong ></ strong >
< p >
</ template >
</ ul >
< p > < input type = button value = "Refresh" onclick = "this.parentElement.refresh()" >
</ article >
section
元素所有当前浏览器均支持。
HTMLElement
.section
元素 表示文档或应用程序中的一个通用部分。在这种上下文中,一个部分是内容的主题分组,通常带有标题。
部分的示例包括章节、选项卡对话框中的各个选项卡页面,或论文的编号部分。一个网站的主页可以分成几个部分,如介绍、新闻项目和联系信息。
建议作者在可能进行内容转载的情况下使用article
元素,而不是section
元素。
section
元素不是一个通用的容器元素。当仅需要一个元素用于样式目的或作为脚本的便利时,建议作者使用 div
元素。一般规则是,section
元素只有在其内容将在文档的 大纲 中明确列出时才合适。
在以下示例中,我们看到一篇关于苹果的文章(网页的一个部分),包含两个简短的部分。
< article >
< hgroup >
< h2 > Apples</ h2 >
< p > Tasty, delicious fruit!</ p >
</ hgroup >
< p > The apple is the pomaceous fruit of the apple tree.</ p >
< section >
< h3 > Red Delicious</ h3 >
< p > These bright red apples are the most common found in many
supermarkets.</ p >
</ section >
< section >
< h3 > Granny Smith</ h3 >
< p > These juicy, green apples make a great filling for
apple pies.</ p >
</ section >
</ article >
这是一个毕业典礼程序,其中包含两个部分,一个是毕业人员名单,另一个是仪式的描述。 (这个示例中的标记使用了一种不常见的样式,有时用于最小化 元素间空白。)
<!DOCTYPE Html>
< Html Lang = En
>< Head
>< Title
> Graduation Ceremony Summer 2022</ Title
></ Head
>< Body
>< H1
> Graduation</ H1
>< Section
>< H2
> Ceremony</ H2
>< P
> Opening Procession</ P
>< P
> Speech by Valedictorian</ P
>< P
> Speech by Class President</ P
>< P
> Presentation of Diplomas</ P
>< P
> Closing Speech by Headmaster</ P
></ Section
>< Section
>< H2
> Graduates</ H2
>< Ul
>< Li
> Molly Carpenter</ Li
>< Li
> Anastasia Luccio</ Li
>< Li
> Ebenezar McCoy</ Li
>< Li
> Karrin Murphy</ Li
>< Li
> Thomas Raith</ Li
>< Li
> Susan Rodriguez</ Li
></ Ul
></ Section
></ Body
></ Html >
在这个示例中,书籍作者将一些部分标记为章节,另一些标记为附录,并使用 CSS 对这两类部分的标题进行不同的样式设置。
< style >
section { border : double medium ; margin : 2 em ; }
section . chapter h2 { font : 2 em Roboto , Helvetica Neue , sans-serif ; }
section . appendix h2 { font : small-caps 2 em Roboto , Helvetica Neue , sans-serif ; }
</ style >
< header >
< hgroup >
< h1 > My Book</ h1 >
< p > A sample with not much content</ p >
</ hgroup >
< p >< small > Published by Dummy Publicorp Ltd.</ small ></ p >
</ header >
< section class = "chapter" >
< h2 > My First Chapter</ h2 >
< p > This is the first of my chapters. It doesn't say much.</ p >
< p > But it has two paragraphs!</ p >
</ section >
< section class = "chapter" >
< h2 > It Continues: The Second Chapter</ h2 >
< p > Bla dee bla, dee bla dee bla. Boom.</ p >
</ section >
< section class = "chapter" >
< h2 > Chapter Three: A Further Example</ h2 >
< p > It's not like a battle between brightness and earthtones would go
unnoticed.</ p >
< p > But it might ruin my story.</ p >
</ section >
< section class = "appendix" >
< h2 > Appendix A: Overview of Examples</ h2 >
< p > These are demonstrations.</ p >
</ section >
< section class = "appendix" >
< h2 > Appendix B: Some Closing Remarks</ h2 >
< p > Hopefully this long example shows that you < em > can</ em > style
sections, so long as they are used to indicate actual sections.</ p >
</ section >
nav
元素在所有当前的引擎中都支持。
HTMLElement
.
nav
元素表示一个页面的部分,该部分链接到其他页面或页面内的部分:一个包含导航链接的部分。
并不是页面上的所有链接组都需要放在 nav
元素中——该元素主要用于包含主要导航块的部分。特别是,脚注中通常有一个简短的链接列表,链接到网站的各种页面,例如服务条款、主页和版权页面。在这种情况下,仅使用 footer
元素就足够了;虽然在这种情况下可以使用 nav
元素,但通常是不必要的。
用户代理(如屏幕阅读器)可以利用此元素来确定在初始渲染时应跳过哪些页面内容,或者在请求时提供哪些内容(或两者兼有),以便为需要从导航信息中受益的用户提供帮助。
在以下示例中,有两个 nav
元素,一个用于站点的主要导航,一个用于页面本身的次要导航。
< body >
< h1 > The Wiki Center Of Exampland</ h1 >
< nav >
< ul >
< li >< a href = "/" > Home</ a ></ li >
< li >< a href = "/events" > Current Events</ a ></ li >
...more...
</ ul >
</ nav >
< article >
< header >
< h2 > Demos in Exampland</ h2 >
< p > Written by A. N. Other.</ p >
</ header >
< nav >
< ul >
< li >< a href = "#public" > Public demonstrations</ a ></ li >
< li >< a href = "#destroy" > Demolitions</ a ></ li >
...more...
</ ul >
</ nav >
< div >
< section id = "public" >
< h2 > Public demonstrations</ h2 >
< p > ...more...</ p >
</ section >
< section id = "destroy" >
< h2 > Demolitions</ h2 >
< p > ...more...</ p >
</ section >
...more...
</ div >
< footer >
< p >< a href = "?edit" > Edit</ a > | < a href = "?delete" > Delete</ a > | < a href = "?Rename" > Rename</ a ></ p >
</ footer >
</ article >
< footer >
< p >< small > © copyright 1998 Exampland Emperor</ small ></ p >
</ footer >
</ body >
在以下示例中,页面上有几个地方包含链接,但其中只有一个地方被视为导航区域。
< body itemscope itemtype = "http://schema.org/Blog" >
< header >
< h1 > Wake up sheeple!</ h1 >
< p >< a href = "news.html" > News</ a > -
< a href = "blog.html" > Blog</ a > -
< a href = "forums.html" > Forums</ a ></ p >
< p > Last Modified: < span itemprop = "dateModified" > 2009-04-01</ span ></ p >
< nav >
< h2 > Navigation</ h2 >
< ul >
< li >< a href = "articles.html" > Index of all articles</ a ></ li >
< li >< a href = "today.html" > Things sheeple need to wake up for today</ a ></ li >
< li >< a href = "successes.html" > Sheeple we have managed to wake</ a ></ li >
</ ul >
</ nav >
</ header >
< main >
< article itemprop = "blogPosts" itemscope itemtype = "http://schema.org/BlogPosting" >
< header >
< h2 itemprop = "headline" > My Day at the Beach</ h2 >
</ header >
< div itemprop = "articleBody" >
< p > Today I went to the beach and had a lot of fun.</ p >
...more content...
</ div >
< footer >
< p > Posted < time itemprop = "datePublished" datetime = "2009-10-10" > Thursday</ time > .</ p >
</ footer >
</ article >
...more blog posts...
</ main >
< footer >
< p > Copyright ©
< span itemprop = "copyrightYear" > 2010</ span >
< span itemprop = "copyrightHolder" > The Example Company</ span >
</ p >
< p >< a href = "about.html" > About</ a > -
< a href = "policy.html" > Privacy Policy</ a > -
< a href = "contact.html" > Contact Us</ a ></ p >
</ footer >
</ body >
您还可以在上述示例中看到使用 schema.org 词汇的微数据注释,这些注释提供了有关博客文章的发布日期和其他元数据。
一个 nav
元素不必包含列表,它也可以包含其他类型的内容。在这个导航块中,链接以散文形式提供:
< nav >
< h1 > Navigation</ h1 >
< p > You are on my home page. To the north lies < a href = "/blog" > my
blog</ a > , from whence the sounds of battle can be heard. To the east
you can see a large mountain, upon which many < a
href = "/school" > school papers</ a > are littered. Far up thus mountain
you can spy a little figure who appears to be me, desperately
scribbling a < a href = "/school/thesis" > thesis</ a > .</ p >
< p > To the west are several exits. One fun-looking exit is labeled < a
href = "https://games.example.com/" > "games"</ a > . Another more
boring-looking exit is labeled < a
href = "https://isp.example.net/" > ISP™</ a > .</ p >
< p > To the south lies a dark and dank < a href = "/about" > contacts
page</ a > . Cobwebs cover its disused entrance, and at one point you
see a rat run quickly out of the page.</ p >
</ nav >
在这个例子中,nav
用于电子邮件应用程序中,让用户切换文件夹:
< p >< input type = button value = "Compose" onclick = "compose()" ></ p >
< nav >
< h1 > Folders</ h1 >
< ul >
< li > < a href = "/inbox" onclick = "return openFolder(this.href)" > Inbox</ a > < span class = count ></ span >
< li > < a href = "/sent" onclick = "return openFolder(this.href)" > Sent</ a >
< li > < a href = "/drafts" onclick = "return openFolder(this.href)" > Drafts</ a >
< li > < a href = "/trash" onclick = "return openFolder(this.href)" > Trash</ a >
< li > < a href = "/customers" onclick = "return openFolder(this.href)" > Customers</ a >
</ ul >
</ nav >
aside
元素支持所有当前引擎。
HTMLElement
.
aside
元素 表示 页面的一部分,其中包含与aside
元素周围的主要内容仅间接相关的内容,这些内容可以被认为是与该内容分开的。这种部分通常在印刷排版中表示为侧边栏。
该元素可用于排版效果,如引用或侧边栏,广告,nav
元素组,以及其他被认为与页面主要内容分开的内容。
不应仅将aside
元素用于括号内容,因为这些内容是文档的主要流程的一部分。
以下示例展示了如何使用aside来标记有关瑞士的背景材料,该材料位于关于欧洲的更长新闻故事中。
< aside >
< h2 > Switzerland</ h2 >
< p > Switzerland, a land-locked country in the middle of geographic
Europe, has not joined the geopolitical European Union, though it is
a signatory to a number of European treaties.</ p >
</ aside >
以下示例展示了如何使用aside
来标记一篇较长文章中的引言摘录。
...
< p > He later joined a large company, continuing on the same work.
< q > I love my job. People ask me what I do for fun when I'm not at
work. But I'm paid to do my hobby, so I never know what to
answer. Some people wonder what they would do if they didn't have to
work... but I know what I would do, because I was unemployed for a
year, and I filled that time doing exactly what I do now.</ q ></ p >
< aside >
< q > People ask me what I do for fun when I'm not at work. But I'm
paid to do my hobby, so I never know what to answer.</ q >
</ aside >
< p > Of course his work — or should that be hobby? —
isn't his only passion. He also enjoys other pleasures.</ p >
...
以下摘录展示了aside
如何用于博客的博客列表和其他侧边内容:
< body >
< header >
< h1 > My wonderful blog</ h1 >
< p > My tagline</ p >
</ header >
< aside >
<!-- this aside contains two sections that are tangentially related
to the page, namely, links to other blogs, and links to blog posts
from this blog -->
< nav >
< h2 > My blogroll</ h2 >
< ul >
< li >< a href = "https://blog.example.com/" > Example Blog</ a >
</ ul >
</ nav >
< nav >
< h2 > Archives</ h2 >
< ol reversed >
< li >< a href = "/last-post" > My last post</ a >
< li >< a href = "/first-post" > My first post</ a >
</ ol >
</ nav >
</ aside >
< aside >
<!-- this aside is tangentially related to the page also, it
contains twitter messages from the blog author -->
< h1 > Twitter Feed</ h1 >
< blockquote cite = "https://twitter.example.net/t31351234" >
I'm on vacation, writing my blog.
</ blockquote >
< blockquote cite = "https://twitter.example.net/t31219752" >
I'm going to go on vacation soon.
</ blockquote >
</ aside >
< article >
<!-- this is a blog post -->
< h2 > My last post</ h2 >
< p > This is my last post.</ p >
< footer >
< p >< a href = "/last-post" rel = bookmark > Permalink</ a >
</ footer >
</ article >
< article >
<!-- this is also a blog post -->
< h2 > My first post</ h2 >
< p > This is my first post.</ p >
< aside >
<!-- this aside is about the blog post, since it's inside the
<article> element; it would be wrong, for instance, to put the
blogroll here, since the blogroll isn't really related to this post
specifically, only to the page as a whole -->
< h2 > Posting</ h2 >
< p > While I'm thinking about it, I wanted to say something about
posting. Posting is fun!</ p >
</ aside >
< footer >
< p >< a href = "/first-post" rel = bookmark > Permalink</ a >
</ footer >
</ article >
< footer >
< p >< a href = "/archives" > Archives</ a > -
< a href = "/about" > About me</ a > -
< a href = "/copyright" > Copyright</ a ></ p >
</ footer >
</ body >
h1
、h2
、h3
、h4
、h5
和 h6
元素
支持所有当前的浏览器引擎。
支持所有当前的浏览器引擎。
支持所有当前的浏览器引擎。
支持所有当前的浏览器引擎。
支持所有当前的浏览器引擎。
支持所有当前的浏览器引擎。
支持所有当前的浏览器引擎。
hgroup
元素的子元素。[Exposed =Window ]
interface HTMLHeadingElement : HTMLElement {
[HTMLConstructor ] constructor ();
// also has obsolete members
};
这些元素 代表 其部分的标题。
这些元素的语义和意义定义在 标题和大纲 部分。
这些元素有一个 标题级别,由其名称中的数字给出。
标题
级别 对应于嵌套部分的级别。h1
元素用于顶级部分,h2
用于子部分,h3
用于
子子部分,依此类推。
就各自的文档大纲(标题和部分结构)而言,这两个片段在语义上是等效的:
< body >
< h1 > Let's call it a draw(ing surface)</ h1 >
< h2 > Diving in</ h2 >
< h2 > Simple shapes</ h2 >
< h2 > Canvas coordinates</ h2 >
< h3 > Canvas coordinates diagram</ h3 >
< h2 > Paths</ h2 >
</ body >
< body >
< h1 > Let's call it a draw(ing surface)</ h1 >
< section >
< h2 > Diving in</ h2 >
</ section >
< section >
< h2 > Simple shapes</ h2 >
</ section >
< section >
< h2 > Canvas coordinates</ h2 >
< section >
< h3 > Canvas coordinates diagram</ h3 >
</ section >
</ section >
< section >
< h2 > Paths</ h2 >
</ section >
</ body >
作者可能会因为前一种风格的简洁性而偏好它,或者因为后一种风格的额外样式钩子而偏好它。哪种更好完全是作者个人风格的选择问题。
hgroup
元素所有当前引擎都支持。
p
元素,接着一个h1
、h2
、h3
、h4
、h5
或h6
元素,之后跟零个或多个p
元素,可能夹杂有脚本支持元素。HTMLElement
.
hgroup
元素 表示 一个标题和相关内容。该元素可用于将一个或多个
h1
–h6
元素与一个或多个包含子标题、替代标题或标语内容的 p
元素组合在一起。
以下是包含在 hgroup
元素中的一些有效标题示例。
< hgroup >
< h1 > The reality dysfunction</ h1 >
< p > Space is not the only void</ p >
</ hgroup >
< hgroup >
< h1 > Dr. Strangelove</ h1 >
< p > Or: How I Learned to Stop Worrying and Love the Bomb</ p >
</ hgroup >
header
元素所有当前引擎都支持。
header
或 footer
元素的后代。HTMLElement
.header
元素通常旨在包含一个标题(h1
–h6
元素或 hgroup
元素),但这不是强制要求的。header
元素也可以用于包装一个部分的目录、一个搜索表单或任何相关的徽标。
以下是一些示例标题。第一个是为一个游戏设计的:
< header >
< p > Welcome to...</ p >
< h1 > Voidwars!</ h1 >
</ header >
下面的片段展示了如何使用该元素标记规范的头部:
< header >
< hgroup >
< h1 > Fullscreen API</ h1 >
< p > Living Standard — Last Updated 19 October 2015< p >
</ hgroup >
< dl >
< dt > Participate:</ dt >
< dd >< a href = "https://github.com/whatwg/fullscreen" > GitHub whatwg/fullscreen</ a ></ dd >
< dt > Commits:</ dt >
< dd >< a href = "https://github.com/whatwg/fullscreen/commits" > GitHub whatwg/fullscreen/commits</ a ></ dd >
</ dl >
</ header >
`header>`元素不是 分节内容;它不会引入一个新节。
在这个例子中,页面有一个由`h1>`元素给出的页面标题,以及两个由 `h2>` 元素给出的子部分。`header>` 元素后的内容仍然是上一个由 `header>` 元素开始的子部分的一部分,因为 `header>` 元素不会参与 大纲 算法。
< body >
< header >
< h1 > Little Green Guys With Guns</ h1 >
< nav >
< ul >
< li >< a href = "/games" > Games</ a >
< li >< a href = "/forum" > Forum</ a >
< li >< a href = "/download" > Download</ a >
</ ul >
</ nav >
< h2 > Important News</ h2 > <!-- this starts a second subsection -->
<!-- this is part of the subsection entitled "Important News" -->
< p > To play today's games you will need to update your client.</ p >
< h2 > Games</ h2 > <!-- this starts a third subsection -->
</ header >
< p > You have three active games:</ p >
<!-- this is still part of the subsection entitled "Games" -->
...
footer
元素支持所有当前引擎。
header
或 footer
元素的后代。HTMLElement
。footer
元素 表示 它最近的祖先 分区内容
元素的页脚,或者如果没有这样的祖先,则为 主体元素。页脚通常包含有关其部分的信息,如撰写者、相关文档的链接、版权数据等。
当 footer
元素包含整个部分时,它们 表示
附录、索引、长篇后记、详细的许可协议以及其他类似内容。
部分的作者或编辑的联系信息应放在 address
元素中,该元素可能位于一个 footer
元素内部。署名和其他可能适合于 header
或 footer
的信息可以放在任意一个(或都不放)。这些元素的主要目的是帮助作者编写自解释的标记,易于维护和样式化;它们并不打算对作者强加特定的结构。
页脚不一定非得出现在部分的 末尾,尽管通常会这样。
当没有祖先 sectioning content 元素时,它适用于整个页面。
footer
元素本身不是 sectioning
content;它不会引入一个新部分。
这是一个页面,上面和下面都有两个 footer,内容相同:
< body >
< footer >< a href = "../" > Back to index...</ a ></ footer >
< hgroup >
< h1 > Lorem ipsum</ h1 >
< p > The ipsum of all lorems</ p >
</ hgroup >
< p > A dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.</ p >
< footer >< a href = "../" > Back to index...</ a ></ footer >
</ body >
这是一个示例,展示了 footer
元素同时用于站点范围的页脚和部分页脚的用法。
<!DOCTYPE HTML>
< HTML LANG = "en" >< HEAD >
< TITLE > The Ramblings of a Scientist</ TITLE >
< BODY >
< H1 > The Ramblings of a Scientist</ H1 >
< ARTICLE >
< H1 > Episode 15</ H1 >
< VIDEO SRC = "/fm/015.ogv" CONTROLS PRELOAD >
< P >< A HREF = "/fm/015.ogv" > Download video</ A > .</ P >
</ VIDEO >
< FOOTER > <!-- footer for article -->
< P > Published < TIME DATETIME = "2009-10-21T18:26-07:00" > on 2009/10/21 at 6:26pm</ TIME ></ P >
</ FOOTER >
</ ARTICLE >
< ARTICLE >
< H1 > My Favorite Trains</ H1 >
< P > I love my trains. My favorite train of all time is a Köf.</ P >
< P > It is fun to see them pull some coal cars because they look so
dwarfed in comparison.</ P >
< FOOTER > <!-- footer for article -->
< P > Published < TIME DATETIME = "2009-09-15T14:54-07:00" > on 2009/09/15 at 2:54pm</ TIME ></ P >
</ FOOTER >
</ ARTICLE >
< FOOTER > <!-- site wide footer -->
< NAV >
< P >< A HREF = "/credits.html" > Credits</ A > —
< A HREF = "/tos.html" > Terms of Service</ A > —
< A HREF = "/index.html" > Blog Index</ A ></ P >
</ NAV >
< P > Copyright © 2009 Gordon Freeman</ P >
</ FOOTER >
</ BODY >
</ HTML >
一些网站设计有时被称为“肥大页脚”——包含大量内容的页脚,包括图片、指向其他文章的链接、反馈页面的链接、特别优惠……在某种程度上,页脚就像是整个“首页”。
这个片段展示了一个网站页面底部的“肥大页脚”:
...
< footer >
< nav >
< section >
< h1 > Articles</ h1 >
< p >< img src = "images/somersaults.jpeg" alt = "" > Go to the gym with
our somersaults class! Our teacher Jim takes you through the paces
in this two-part article. < a href = "articles/somersaults/1" > Part
1</ a > · < a href = "articles/somersaults/2" > Part 2</ a ></ p >
< p >< img src = "images/kindplus.jpeg" > Tired of walking on the edge of
a clif<!-- sic --> ? Our guest writer Lara shows you how to bumble
your way through the bars. < a href = "articles/kindplus/1" > Read
more...</ a ></ p >
< p >< img src = "images/crisps.jpeg" > The chips are down, now all
that's left is a potato. What can you do with it? < a
href = "articles/crisps/1" > Read more...</ a ></ p >
</ section >
< ul >
< li > < a href = "/about" > About us...</ a >
< li > < a href = "/feedback" > Send feedback!</ a >
< li > < a href = "/sitemap" > Sitemap</ a >
</ ul >
</ nav >
< p >< small > Copyright © 2015 The Snacker —
< a href = "/tos" > Terms of Service</ a ></ small ></ p >
</ footer >
</ body >
address
元素所有当前浏览器都支持。
header
、footer
或address
元素的后代。
HTMLElement
。address
元素 表示 其最近的 article
或 body
元素祖先的联系信息。如果该祖先是 body 元素,则联系信息适用于整个文档。
例如,W3C 网站上的与 HTML 相关的页面可能包含以下联系信息:
< ADDRESS >
< A href = "../People/Raggett/" > Dave Raggett</ A > ,
< A href = "../People/Arnaud/" > Arnaud Le Hors</ A > ,
contact persons for the < A href = "Activity" > W3C HTML Activity</ A >
</ ADDRESS >
address
元素不能用于表示任意地址(例如邮政地址),除非这些地址确实是相关的联系信息。(p
元素是标记邮政地址的合适元素。)
address
元素不得包含除联系信息以外的其他信息。
例如,以下是 address
元素的非规范用法:
< ADDRESS > Last Modified: 1999/12/24 23:37:50</ ADDRESS >
通常,address
元素会与其他信息一起包含在 footer
元素中。
节点 node 的联系信息是由以下列表中第一个适用条目定义的 address
元素的集合:
article
元素body
元素联系信息包括所有以 node 为祖先的 address
元素,并且这些元素没有其他 body
或 article
元素祖先是 node 的后代。
article
元素body
元素node 没有联系信息。
用户代理可以向用户公开节点的联系信息,或将其用于其他目的,例如基于部分的联系信息对部分进行索引。
在这个例子中,页脚包含了联系信息和版权声明。
< footer >
< address >
For more details, contact
< a href = "mailto:js@example.com" > John Smith</ a > .
</ address >
< p >< small > © copyright 2038 Example Corp.</ small ></ p >
</ footer >
这些元素 表示 标题。标题的 标题级别 越低,该标题拥有的祖先部分就越少。
大纲 应用于生成文档大纲,例如生成目录时。当创建交互式目录时,条目应跳转到相关的 标题。
如果文档中有一个或多个 标题,则 大纲 中至少应有一个 标题 具有标题级别 1。
每个跟随另一个 标题 的标题 lead 在 大纲 中必须具有一个小于、等于或比 lead 的 标题级别 多 1 的标题级别。
以下示例是不符合规范的:
< body >
< h1 > Apples</ h1 >
< p > Apples are fruit.</ p >
< section >
< h3 > Taste</ h3 >
< p > They taste lovely.</ p >
</ section >
</ body >
可以按以下方式编写,这样它就符合规范:
< body >
< h1 > Apples</ h1 >
< p > Apples are fruit.</ p >
< section >
< h2 > Taste</ h2 >
< p > They taste lovely.</ p >
</ section >
</ body >
以下标记片段:
< body >
< hgroup id = "document-title" >
< h1 > HTML: Living Standard</ h1 >
< p > Last Updated 12 August 2016</ p >
</ hgroup >
< p > Some intro to the document.</ p >
< h2 > Table of contents</ h2 >
< ol id = toc > ...</ ol >
< h2 > First section</ h2 >
< p > Some intro to the first section.</ p >
</ body >
…结果产生了 3 个文档标题:
<h1>HTML: Living Standard</h1>
<h2>Table of contents</h2>
.
<h2>First section</h2>
.
渲染后的 大纲 可能如下所示:
首先,这里是一个文档,内容是一本章节非常短且包含子章节的书:
<!DOCTYPE HTML>
< html lang = en >
< title > The Tax Book (all in one page)</ title >
< h1 > The Tax Book</ h1 >
< h2 > Earning money</ h2 >
< p > Earning money is good.</ p >
< h3 > Getting a job</ h3 >
< p > To earn money you typically need a job.</ p >
< h2 > Spending money</ h2 >
< p > Spending is what money is mainly used for.</ p >
< h3 > Cheap things</ h3 >
< p > Buying cheap things often not cost-effective.</ p >
< h3 > Expensive things</ h3 >
< p > The most expensive thing is often not the most cost-effective either.</ p >
< h2 > Investing money</ h2 >
< p > You can lend your money to other people.</ p >
< h2 > Losing money</ h2 >
< p > If you spend money or invest money, sooner or later you will lose money.
< h3 > Poor judgement</ h3 >
< p > Usually if you lose money it's because you made a mistake.</ p >
它的大纲可以如下所示:
一个文档可以包含多个顶级标题:
<!DOCTYPE HTML>
< html lang = en >
< title > Alphabetic Fruit</ title >
< h1 > Apples</ h1 >
< p > Pomaceous.</ p >
< h1 > Bananas</ h1 >
< p > Edible.</ p >
< h1 > Carambola</ h1 >
< p > Star.</ p >
文档的大纲可以呈现如下:
<!DOCTYPE HTML>
< html lang = "en" >
< title > We're adopting a child! — Ray's blog</ title >
< h1 > Ray's blog</ h1 >
< article >
< header >
< nav >
< a href = "?t=-1d" > Yesterday</ a > ;
< a href = "?t=-7d" > Last week</ a > ;
< a href = "?t=-1m" > Last month</ a >
</ nav >
< h2 > We're adopting a child!</ h2 >
</ header >
< p > As of today, Janine and I have signed the papers to become
the proud parents of baby Diane! We've been looking forward to
this day for weeks.</ p >
</ article >
</ html >
文档的大纲可以呈现如下:
以下示例符合规范,但不推荐使用,因为它没有任何标题,其标题级别为1:
<!DOCTYPE HTML>
< html lang = en >
< title > Alphabetic Fruit</ title >
< section >
< h2 > Apples</ h2 >
< p > Pomaceous.</ p >
</ section >
< section >
< h2 > Bananas</ h2 >
< p > Edible.</ p >
</ section >
< section >
< h2 > Carambola</ h2 >
< p > Star.</ p >
</ section >
该文档的大纲可以如下呈现:
以下示例符合规范,但不推荐,因为第一个标题的标题级别不是1:
<!DOCTYPE HTML>
< html lang = en >
< title > Feathers on The Site of Encyclopedic Knowledge</ title >
< h2 > A plea from our caretakers</ h2 >
< p > Please, we beg of you, send help! We're stuck in the server room!</ p >
< h1 > Feathers</ h1 >
< p > Epidermal growths.</ p >
文档的大纲可以呈现如下:
鼓励用户代理向用户暴露页面大纲,以帮助导航。这对于非视觉媒体尤其重要,例如屏幕阅读器。
例如,用户代理可以将箭头键映射如下:
本节为非规范性内容。
元素 | 目的 |
---|---|
示例 | |
body
|
文档的内容。 |
|
|
article
|
文档、页面、应用程序或站点中的一个完整或自包含的组成部分,原则上可以独立分发或重用,例如在联合发布中。这可以是论坛帖子、杂志或报纸文章、博客条目、用户提交的评论、互动小部件或工具,或任何其他独立的内容项。 |
|
|
section
|
文档或应用程序中的一个通用部分。在此上下文中,部分是内容的主题性分组,通常带有标题。 |
|
|
nav
|
一个链接到其他页面或页面内部部分的页面部分:一个包含导航链接的部分。 |
|
|
aside
|
一个页面部分,包含与围绕aside 元素的内容间接相关的内容,且这些内容可以被认为是独立于该内容的。这些部分通常在印刷排版中表现为侧边栏。
|
|
|
h1 –h6
|
一个标题 |
|
|
hgroup
|
一个标题及相关内容。该元素可用于将一个或多个 h1 –h6
元素与一个或多个 p
元素组合在一起,这些元素包含表示子标题、替代标题或标语的内容。 |
|
|
header
|
一组引导性或导航性辅助工具。 |
|
|
footer
|
其最近祖先的分区内容元素的页脚,或者如果没有这样的祖先,则为body元素。页脚通常包含有关其部分的信息,例如作者、相关文档的链接、版权数据等。 |
|
本节为非规范性内容。
section
是其他内容的一部分。article
是一个独立的内容。但如何区分这两者呢?大多数情况下,真正的答案是“这取决于作者的意图”。
例如,可以想象一本书中有一章关于“格兰尼·史密斯”苹果,只提到“这些多汁的绿色苹果是制作苹果派的绝佳填料”;这将是一个 section
,因为还有很多其他章节(可能)讲述其他种类的苹果。
另一方面,可以想象一条推文或Reddit评论或Tumblr帖子或报纸分类广告只说了“格兰尼·史密斯。这些多汁的绿色苹果是制作苹果派的绝佳填料”;这将是 article
,因为这就是全部内容。
对文章的评论不是其所在 article
的一部分,因此它是自己的 article
。
p
元素在所有当前引擎中都支持。
在所有当前引擎中都支持。
p
元素的结束标签 可以省略,如果该p
元素后面紧跟着一个 address
、article
、aside
、blockquote
、details
、div
、dl
、fieldset
、figcaption
、figure
、footer
、form
、h1
、h2
、h3
、h4
、h5
、h6
、header
、hgroup
、hr
、main
、menu
、nav
、ol
、p
、pre
、search
、section
、table
,或
ul
元素,或者如果父元素没有更多内容且父元素是一个HTML
元素(不是 a
、audio
、del
、ins
、map
、noscript
,或
video
元素,或一个自主自定义元素。
[Exposed =Window ]
interface HTMLParagraphElement : HTMLElement {
[HTMLConstructor ] constructor ();
// also has obsolete members
};
虽然段落通常在视觉媒体中通过与相邻块之间通过空行物理分隔的文本块表示,样式表或用户代理同样可以用不同的方式来呈现段落分隔,例如使用行内段落标记 (¶)。
以下示例是符合规范的 HTML 片段:
< p > The little kitten gently seated herself on a piece of
carpet. Later in her life, this would be referred to as the time the
cat sat on the mat.</ p >
< fieldset >
< legend > Personal information</ legend >
< p >
< label > Name: < input name = "n" ></ label >
< label >< input name = "anon" type = "checkbox" > Hide from other users</ label >
</ p >
< p >< label > Address: < textarea name = "a" ></ textarea ></ label ></ p >
</ fieldset >
< p > There was once an example from Femley,< br >
Whose markup was of dubious quality.< br >
The validator complained,< br >
So the author was pained,< br >
To move the error from the markup to the rhyming.</ p >
p
元素不应在更具体的元素更为合适的情况下使用。
以下示例在技术上是正确的:
< section >
<!-- ... -->
< p > Last modified: 2001-04-23</ p >
< p > Author: fred@example.com</ p >
</ section >
然而,最好标记为:
< section >
<!-- ... -->
< footer > Last modified: 2001-04-23</ footer >
< address > Author: fred@example.com</ address >
</ section >
或者:
< section >
<!-- ... -->
< footer >
< p > Last modified: 2001-04-23</ p >
< address > Author: fred@example.com</ address >
</ footer >
</ section >
列表元素(特别是 ol
和 ul
元素)不能作为
p
元素的子元素。因此,当一个句子包含项目符号列表时,可能会想知道应该如何标记。
例如,这个精彩的句子有与以下内容相关的项目符号:
并在下面进一步讨论。
解决方案是认识到,在 HTML 术语中,段落 不是一个逻辑概念,而是一个结构概念。在上面的精彩例子中,实际上有 五个 段落,根据本规范定义:一个在列表之前,一个对应每个项目符号,以及一个在列表之后。
因此,上述示例的标记可以是:
< p > For instance, this fantastic sentence has bullets relating to</ p >
< ul >
< li > wizards,
< li > faster-than-light travel, and
< li > telepathy,
</ ul >
< p > and is further discussed below.</ p >
希望方便地为由多个“结构性”段落组成的这种“逻辑”段落设置样式的作者可以使用 div
元素,而不是
p
元素。
因此,上述示例可以变为如下:
< div > For instance, this fantastic sentence has bullets relating to
< ul >
< li > wizards,
< li > faster-than-light travel, and
< li > telepathy,
</ ul >
and is further discussed below.</ div >
这个示例仍然有五个结构段落,但现在作者可以只对 div
进行样式设置,而不必单独考虑示例的每个部分。
hr
元素所有当前引擎均支持。
所有当前引擎均支持。
select
元素的子元素。[Exposed =Window ]
interface HTMLHRElement : HTMLElement {
[HTMLConstructor ] constructor ();
// also has obsolete members
};
hr
元素 表示 一个 段落
级别的主题分隔线,例如故事中的场景变换,或参考书中某部分主题的过渡;或者,它表示一个 select
元素中的选项集之间的分隔符。
以下是一个项目手册的虚构摘录,展示了两个使用 hr
元素来分隔部分中的主题的部分。
< section >
< h1 > Communication</ h1 >
< p > There are various methods of communication. This section
covers a few of the important ones used by the project.</ p >
< hr >
< p > Communication stones seem to come in pairs and have mysterious
properties:</ p >
< ul >
< li > They can transfer thoughts in two directions once activated
if used alone.</ li >
< li > If used with another device, they can transfer one's
consciousness to another body.</ li >
< li > If both stones are used with another device, the
consciousnesses switch bodies.</ li >
</ ul >
< hr >
< p > Radios use the electromagnetic spectrum in the meter range and
longer.</ p >
< hr >
< p > Signal flares use the electromagnetic spectrum in the
nanometer range.</ p >
</ section >
< section >
< h1 > Food</ h1 >
< p > All food at the project is rationed:</ p >
< dl >
< dt > Potatoes</ dt >
< dd > Two per day</ dd >
< dt > Soup</ dt >
< dd > One bowl per day</ dd >
</ dl >
< hr >
< p > Cooking is done by the chefs on a set rotation.</ p >
</ section >
以下摘自彼得·F·汉密尔顿的《潘多拉的星辰》一书,展示了两个场景变换前的段落以及一个变换后的段落。场景变换在印刷书籍中由第二段和第三段之间的一个孤立的居中星星空隙表示,而在这里则使用 hr
元素来表示。
< p > Dudley was ninety-two, in his second life, and fast approaching
time for another rejuvenation. Despite his body having the physical
age of a standard fifty-year-old, the prospect of a long degrading
campaign within academia was one he regarded with dread. For a
supposedly advanced civilization, the Intersolar Commonwealth could be
appallingly backward at times, not to mention cruel.</ p >
< p >< i > Maybe it won't be that bad</ i > , he told himself. The lie was
comforting enough to get him through the rest of the night's
shift.</ p >
< hr >
< p > The Carlton AllLander drove Dudley home just after dawn. Like the
astronomer, the vehicle was old and worn, but perfectly capable of
doing its job. It had a cheap diesel engine, common enough on a
semi-frontier world like Gralmond, although its drive array was a
thoroughly modern photoneural processor. With its high suspension and
deep-tread tyres it could plough along the dirt track to the
observatory in all weather and seasons, including the metre-deep snow
of Gralmond's winters.</ p >
pre
` 元素所有当前引擎均支持。
所有当前引擎均支持。
[Exposed =Window ]
interface HTMLPreElement : HTMLElement {
[HTMLConstructor ] constructor ();
// also has obsolete members
};
>
pre
元素 表示 一块预格式化文本,其中结构由排版约定而非元素表示。
在 HTML 语法 中,紧跟在 pre
元素起始标签之后的前导换行符会被删除。
一些使用 pre
元素的示例:
建议作者考虑当格式丢失时预格式化文本的体验情况,例如对于语音合成器、盲文显示器等用户。对于像 ASCII 艺术这样的情况,可能更普遍可访问的替代展示方式,例如文本描述,会更适合读者。
要表示一块计算机代码,可以将 pre
元素与 code
元素一起使用;要表示一块计算机输出,可以将 pre
元素与
samp
元素一起使用。类似地,kbd
元素可以在 pre
元素内使用,以指示用户要输入的文本。
此元素 具有涉及双向算法的渲染要求。
在以下片段中,展示了一段计算机代码。
< p > This is the < code > Panel</ code > constructor:</ p >
< pre >< code > function Panel(element, canClose, closeHandler) {
this.element = element;
this.canClose = canClose;
this.closeHandler = function () { if (closeHandler) closeHandler() };
}</ code ></ pre >
在以下片段中,samp
和
kbd
元素混合在一个 pre
元素的内容中,以展示 Zork I 的会话。
< pre >< samp > You are in an open field west of a big white house with a boarded
front door.
There is a small mailbox here.
></ samp > < kbd > open mailbox</ kbd >
< samp > Opening the mailbox reveals:
A leaflet.
></ samp ></ pre >
以下展示了一首现代诗,使用了 pre
元素来保留其独特的格式,这些格式是诗歌本身的固有部分。
< pre > maxling
it is with a heart
heavy
that i admit loss of a feline
so loved
a friend lost to the
unknown
(night)
~cdr 11dec07</ pre >
blockquote
元素支持所有当前的浏览器。
支持所有当前的浏览器。
cite
— 链接到引用的来源或更多关于编辑的信息[Exposed =Window ]
interface HTMLQuoteElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute USVString cite ;
};
HTMLQuoteElement
接口也被 q
元素使用。
blockquote
元素 表示 从其他来源引用的部分。
在 blockquote
内部的内容必须从其他来源引用,其地址(如果有的话)可以在 cite
属性中注明。
如果存在 cite
属性,它必须是一个 有效的 URL,可能被空格包围。为了获得相应的引用链接,属性的值必须 解析
相对于元素的 节点文档。用户代理可能允许用户跟随这些引用链接,但它们主要用于私人用途(例如,服务器端脚本收集有关站点使用引用的统计数据),而不是供读者使用。
blockquote
的内容可以被省略或按照文本语言的传统方式添加上下文。
例如,在英语中,这通常使用方括号来完成。考虑一个页面,其中包含句子“Jane ate the cracker. She then said she liked apples and fish.”;它可以被引用为:
< blockquote >
< p > [Jane] then said she liked [...] fish.</ p >
</ blockquote >
如果有的话,引用的归属必须放置在 blockquote
元素之外。
例如,这里归属是在引用之后的段落中给出的:
< blockquote >
< p > I contend that we are both atheists. I just believe in one fewer
god than you do. When you understand why you dismiss all the other
possible gods, you will understand why I dismiss yours.</ p >
</ blockquote >
< p > — Stephen Roberts</ p >
下面的其他示例展示了其他几种表示归属的方式。
cite
IDL 属性必须 反映 元素的 cite
内容属性。
这里使用了一个 blockquote
元素与一个 figure
元素及其 figcaption
一起使用,以明确地将引用与其归属关系联系起来(归属不是引用的一部分,因此不应包含在 blockquote
内部):
< figure >
< blockquote >
< p > The truth may be puzzling. It may take some work to grapple with.
It may be counterintuitive. It may contradict deeply held
prejudices. It may not be consonant with what we desperately want to
be true. But our preferences do not determine what's true. We have a
method, and that method helps us to reach not absolute truth, only
asymptotic approaches to the truth — never there, just closer
and closer, always finding vast new oceans of undiscovered
possibilities. Cleverly designed experiments are the key.</ p >
</ blockquote >
< figcaption > Carl Sagan, in "< cite > Wonder and Skepticism</ cite > ", from
the < cite > Skeptical Inquirer</ cite > Volume 19, Issue 1 (January-February
1995)</ figcaption >
</ figure >
下一个示例展示了 cite
与 blockquote
一起使用的情况:
< p > His next piece was the aptly named < cite > Sonnet 130</ cite > :</ p >
< blockquote cite = "https://quotes.example.org/s/sonnet130.html" >
< p > My mistress' eyes are nothing like the sun,< br >
Coral is far more red, than her lips red,< br >
...
这个示例展示了一个论坛帖子如何使用 blockquote
来显示用户回复的帖子。每个帖子使用 article
元素来标记线程。
< article >
< h1 >< a href = "https://bacon.example.com/?blog=109431" > Bacon on a crowbar</ a ></ h1 >
< article >
< header >< strong > t3yw</ strong > 12 points 1 hour ago</ header >
< p > I bet a narwhal would love that.</ p >
< footer >< a href = "?pid=29578" > permalink</ a ></ footer >
< article >
< header >< strong > greg</ strong > 8 points 1 hour ago</ header >
< blockquote >< p > I bet a narwhal would love that.</ p ></ blockquote >
< p > Dude narwhals don't eat bacon.</ p >
< footer >< a href = "?pid=29579" > permalink</ a ></ footer >
< article >
< header >< strong > t3yw</ strong > 15 points 1 hour ago</ header >
< blockquote >
< blockquote >< p > I bet a narwhal would love that.</ p ></ blockquote >
< p > Dude narwhals don't eat bacon.</ p >
</ blockquote >
< p > Next thing you'll be saying they don't get capes and wizard
hats either!</ p >
< footer >< a href = "?pid=29580" > permalink</ a ></ footer >
< article >
< article >
< header >< strong > boing</ strong > -5 points 1 hour ago</ header >
< p > narwhals are worse than ceiling cat</ p >
< footer >< a href = "?pid=29581" > permalink</ a ></ footer >
</ article >
</ article >
</ article >
</ article >
< article >
< header >< strong > fred</ strong > 1 points 23 minutes ago</ header >
< blockquote >< p > I bet a narwhal would love that.</ p ></ blockquote >
< p > I bet they'd love to peel a banana too.</ p >
< footer >< a href = "?pid=29582" > permalink</ a ></ footer >
</ article >
</ article >
</ article >
这个示例展示了如何使用 blockquote
来表示短片段,演示了在 blockquote
元素内部不必使用 p
元素:
< p > He began his list of "lessons" with the following:</ p >
< blockquote > One should never assume that his side of
the issue will be recognized, let alone that it will
be conceded to have merits.</ blockquote >
< p > He continued with a number of similar points, ending with:</ p >
< blockquote > Finally, one should be prepared for the threat
of breakdown in negotiations at any given moment and not
be cowed by the possibility.</ blockquote >
< p > We shall now discuss these points...
如何表示对话的示例 会在后面的章节中展示;不适合使用 cite
和 blockquote
元素来实现这一目的。
ol
元素Support in all current engines.
Support in all current engines.
li
元素:可触及内容。li
元素和 支持脚本的 元素。reversed
—
反向编号列表start
— 列表的
起始值
type
— 列表标记的类型
[Exposed =Window ]
interface HTMLOListElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute boolean reversed ;
[CEReactions ] attribute long start ;
[CEReactions ] attribute DOMString type ;
// also has obsolete members
};
ol
元素表示一系列项目,其中项目经过刻意排序,改变顺序会改变文档的意义。
Support in all current engines.
reversed
属性是一个布尔属性。如果存在,它表示列表是降序的(...,
3, 2, 1)。如果省略该属性,列表是升序的(1, 2, 3, ...)。
start
属性如果存在,必须是一个有效整数。它用于确定列表的起始值。
ol
元素有一个起始值,这是一个按以下方式确定的整数:
令parsed为解析属性值为整数的结果。
如果parsed没有错误,则返回parsed。
返回1。
type
属性可以用来指定在列表中使用的标记类型,在某些情况下这很重要(例如,因为项目要按其编号/字母引用)。如果指定了该属性,其值必须与下表中某行第一列给出的字符相同。type
属性表示与第一列匹配的行的第二列给定的状态;如果没有单元格匹配,或者省略该属性,则该属性表示十进制状态。
关键字 | 状态 | 描述 | 值为 1-3 和 3999-4001 的示例 | |||||||
---|---|---|---|---|---|---|---|---|---|---|
1
(U+0031)
|
十进制 | 十进制数字 | 1. | 2. | 3. | ... | 3999. | 4000. | 4001. | ... |
a (U+0061)
|
小写字母 | 小写拉丁字母 | a. | b. | c. | ... | ewu. | ewv. | eww. | ... |
A (U+0041)
|
大写字母 | 大写拉丁字母 | A. | B. | C. | ... | EWU. | EWV. | EWW. | ... |
i (U+0069)
|
小写罗马数字 | 小写罗马数字 | i. | ii. | iii. | ... | mmmcmxcix. | i̅v̅. | i̅v̅i. | ... |
I (U+0049)
|
大写罗马数字 | 大写罗马数字 | I. | II. | III. | ... | MMMCMXCIX. | I̅V̅. | I̅V̅I. | ... |
用户代理应以与type
属性的状态一致的方式呈现ol
元素的列表项。小于或等于零的数字应始终使用十进制系统,而不管type
属性。
对于CSS用户代理,在'list-style-type' CSS属性中,提供了此属性的映射在渲染部分(映射很简单:上述状态与其对应的CSS值名称相同)。
在CSS用户代理中,可以重新定义用于实现此属性的默认CSS列表样式;这样做会影响列表项的呈现方式。
reversed
和type
IDL属性必须反映同名的相应内容属性。
这意味着在start
IDL属性与列表的起始值不一定匹配的情况下,当start
内容属性被省略且reversed
内容属性被指定时。
以下标记显示了一个顺序重要的列表,因此ol
元素是合适的。将此列表与ul
部分中的等效列表进行比较,以查看使用ul
元素的相同项目示例。
< p > I have lived in the following countries (given in the order of when
I first lived there):</ p >
< ol >
< li > Switzerland
< li > United Kingdom
< li > United States
< li > Norway
</ ol >
注意改变列表顺序如何改变文档的意义。在以下示例中,改变前两个项目的相对顺序改变了作者的出生地:
< p > I have lived in the following countries (given in the order of when
I first lived there):</ p >
< ol >
< li > United Kingdom
< li > Switzerland
< li > United States
< li > Norway
</ ol >
ul
元素支持所有当前引擎。
支持所有当前引擎。
li
元素:
可感知内容。
li
和脚本支持元素。[Exposed =Window ]
interface HTMLUListElement : HTMLElement {
[HTMLConstructor ] constructor ();
// also has obsolete members
};
ul
元素表示一系列项目,这些项目的顺序并不重要——也就是说,改变顺序不会实质性地改变文档的意义。
以下标记显示了一个顺序不重要的列表,因此ul
元素是合适的。将此列表与ol
部分中的等效列表进行比较,以查看使用ol
元素的相同项目示例。
< p > I have lived in the following countries:</ p >
< ul >
< li > Norway
< li > Switzerland
< li > United Kingdom
< li > United States
</ ul >
请注意,改变列表的顺序不会改变文档的意义。上面的项目按字母顺序排列,但在下面的片段中,它们按2007年当前账户余额的大小排列,而不会改变文档的意义:
< p > I have lived in the following countries:</ p >
< ul >
< li > Switzerland
< li > Norway
< li > United Kingdom
< li > United States
</ ul >
menu
元素支持所有当前引擎。
支持所有当前引擎。
li
元素:可感知内容。li
和脚本支持元素。[Exposed =Window ]
interface HTMLMenuElement : HTMLElement {
[HTMLConstructor ] constructor ();
// also has obsolete members
};
menu
元素表示一个由其内容组成的工具栏,以无序项目列表的形式(由li
元素表示),每个项目代表用户可以执行或激活的命令。
menu
元素只是ul
的语义替代,用于表示命令的无序列表("工具栏")。
在这个示例中,一个文本编辑应用程序使用menu
元素提供一系列编辑命令:
< menu >
< li >< button onclick = "copy()" >< img src = "copy.svg" alt = "Copy" ></ button ></ li >
< li >< button onclick = "cut()" >< img src = "cut.svg" alt = "Cut" ></ button ></ li >
< li >< button onclick = "paste()" >< img src = "paste.svg" alt = "Paste" ></ button ></ li >
</ menu >
请注意,将其样式化为传统工具栏菜单的样式取决于应用程序。
li
元素支持所有当前引擎。
支持所有当前引擎。
ol
元素中。
ul
元素中。
menu
元素中。li
元素后面紧跟另一个 li
元素,或者父元素中没有更多内容,则 结束标签
可以省略。
ul
或 menu
元素的子元素: value
— 列表项的序数值
[Exposed =Window ]
interface HTMLLIElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute long value ;
// also has obsolete members
};
li
元素 代表 列表项。如果它的父元素是 ol
、ul
或 menu
元素,那么该元素就是父元素列表中的一项,如这些元素的定义所示。否则,该列表项与任何其他 li
元素没有定义的列表相关关系。
value
属性(如果存在)必须是有效整数。当 li
的 列表所有者 是 ol
元素时,用于确定列表项的序数值。
任何其 计算值 为 'display' 为 'list-item' 的元素都有一个 列表所有者,其确定方式如下:
让 ancestor 成为该元素的父元素。
返回 ancestor 最近的包含祖先元素,该祖先元素生成一个 CSS 框。
要确定由给定的 列表所有者 owner 拥有的每个元素的 序数值,请执行以下步骤:
设 i 为 1。
如果 owner 是 ol
元素,则将
numbering 设置为 owner 的起始值。否则,将 numbering 设置为 1。
如果 item 是具有 value
属性的
li
元素,则:
将 parsed 设置为解析 该属性的值为整数的结果。
如果 parsed 没有错误,则将 numbering 设置为 parsed。
item 的 序数值 为 numbering。
如果 owner 是 ol
元素,且
owner 具有 reversed
属性,则将 numbering 减 1;否则,将 numbering 加 1。
将 i 加 1。
转到标记为 循环 的步骤。
value
IDL 属性必须反映 value
内容属性的值。
元素的 value
IDL
属性不直接对应其 序数值;它只是反映内容属性。例如,给定此列表:
< ol >
< li > Item 1
< li value = "3" > Item 3
< li > Item 4
</ ol >
以下示例中列出了前十名电影(按逆序)。请注意,通过使用 figure
元素及其 figcaption
元素为列表提供标题的方式。
< figure >
< figcaption > The top 10 movies of all time</ figcaption >
< ol >
< li value = "10" >< cite > Josie and the Pussycats</ cite > , 2001</ li >
< li value = "9" >< cite lang = "sh" > Црна мачка, бели мачор</ cite > , 1998</ li >
< li value = "8" >< cite > A Bug's Life</ cite > , 1998</ li >
< li value = "7" >< cite > Toy Story</ cite > , 1995</ li >
< li value = "6" >< cite > Monsters, Inc</ cite > , 2001</ li >
< li value = "5" >< cite > Cars</ cite > , 2006</ li >
< li value = "4" >< cite > Toy Story 2</ cite > , 1999</ li >
< li value = "3" >< cite > Finding Nemo</ cite > , 2003</ li >
< li value = "2" >< cite > The Incredibles</ cite > , 2004</ li >
< li value = "1" >< cite > Ratatouille</ cite > , 2007</ li >
</ ol >
</ figure >
此标记也可以如下编写,在 reversed
属性的 ol
元素上:
< figure >
< figcaption > The top 10 movies of all time</ figcaption >
< ol reversed >
< li >< cite > Josie and the Pussycats</ cite > , 2001</ li >
< li >< cite lang = "sh" > Црна мачка, бели мачор</ cite > , 1998</ li >
< li >< cite > A Bug's Life</ cite > , 1998</ li >
< li >< cite > Toy Story</ cite > , 1995</ li >
< li >< cite > Monsters, Inc</ cite > , 2001</ li >
< li >< cite > Cars</ cite > , 2006</ li >
< li >< cite > Toy Story 2</ cite > , 1999</ li >
< li >< cite > Finding Nemo</ cite > , 2003</ li >
< li >< cite > The Incredibles</ cite > , 2004</ li >
< li >< cite > Ratatouille</ cite > , 2007</ li >
</ ol >
</ figure >
虽然在 li
元素中包含标题元素(例如
h1
)是符合规范的,但这可能不会传达作者想要表达的语义。标题会开启一个新的部分,因此列表中的标题会隐式地将列表分割成多个部分。
dl
元素支持所有当前引擎。
支持所有当前引擎。
dt
元素组成,后跟一个或多个
dd
元素,可选地夹杂
脚本支持元素。
div
元素,可选地夹杂
脚本支持元素。
[Exposed =Window ]
interface HTMLDListElement : HTMLElement {
[HTMLConstructor ] constructor ();
// also has obsolete members
};
dl
元素 代表
一个关联列表,由零个或多个名称-值组(描述列表)组成。名称-值组由一个或多个名称(dt
元素,可能是 div
元素的子元素)后跟一个或多个值(dd
元素,可能是 div
元素的子元素),忽略除 dt
和 dd
元素以外的所有节点,以及作为 div
元素子元素的
dt
和 dd
元素。在单个 dl
元素中,每个名称不应有多个
dt
元素。
名称-值组可以是术语和定义、元数据主题和值、问题和答案,或任何其他名称-值数据组。
组内的值是替代的;构成同一值的多个段落必须都包含在同一 dd
元素中。
组列表的顺序以及每个组内名称和值的顺序可能很重要。
为了用 微数据 属性或其他适用于整个组的 全局属性
注释组,或仅用于样式目的,dl
元素中的每个组都可以包含在
div
元素中。这不会改变 dl
元素的语义。
dl
元素
dl 的名称-值组是使用以下算法确定的。名称-值组有一个名称(dt
元素列表,最初为空)和一个值(dd
元素列表,最初为空)。
设 groups 为一个空的名称-值组列表。
设 current 为一个新的名称-值组。
设 seenDd 为 false。
设 child 为 dl 的第一个子节点。
设 grandchild 为 null。
当 child 不为 null 时:
如果 child 是 div
元素,则:
设 grandchild 为 child 的第一个子节点。
当 grandchild 不为 null 时:
处理
dt
或 dd
以处理 grandchild。
将 grandchild 设置为 grandchild 的下一个兄弟节点。
否则,处理
dt
或 dd
以处理 child。
将 child 设置为 child 的下一个兄弟节点。
如果 current 不为空,则将 current 追加到 groups。
返回 groups。
要处理 dt
或 dd
节点 node,需执行以下步骤:
设 groups、current 和 seenDd 为调用这些步骤的算法中同名的变量。
如果 node 是 dt
元素,则:
如果 seenDd 为 true,则将 current 追加到 groups,将 current 设置为一个新的名称-值组,并将 seenDd 设置为 false。
将 node 追加到 current 的名称中。
否则,如果 node 是 dd
元素,则将
node 追加到 current 的值中,并将 seenDd 设置为 true。
当名称-值组的名称或值为空列表时,通常是因为错误地在 dd
元素的位置使用了
dt
元素,反之亦然。合规检查器可以发现此类错误,并可能建议作者如何正确使用标记。
在以下示例中,一个条目(“作者”)链接到两个值(“约翰”和“卢克”)。
< dl >
< dt > Authors
< dd > John
< dd > Luke
< dt > Editor
< dd > Frank
</ dl >
在以下示例中,一个定义链接到两个术语。
< dl >
< dt lang = "en-US" > < dfn > color</ dfn > </ dt >
< dt lang = "en-GB" > < dfn > colour</ dfn > </ dt >
< dd > A sensation which (in humans) derives from the ability of
the fine structure of the eye to distinguish three differently
filtered analyses of a view. </ dd >
</ dl >
以下示例展示了使用 dl
元素标记各种元数据。在示例的末尾,一个组有两个元数据标签(“作者”和“编辑”)和两个值(“Robert Rothman”和“Daniel Jackson”)。此示例还使用 div
元素将
dt
和 dd
元素组围起来,以帮助样式化。
< dl >
< div >
< dt > Last modified time </ dt >
< dd > 2004-12-23T23:33Z </ dd >
</ div >
< div >
< dt > Recommended update interval </ dt >
< dd > 60s </ dd >
</ div >
< div >
< dt > Authors </ dt >
< dt > Editors </ dt >
< dd > Robert Rothman </ dd >
< dd > Daniel Jackson </ dd >
</ div >
</ dl >
以下示例显示了使用 dl
元素来提供一组指令。这里指令的顺序很重要(在其他示例中,区块的顺序并不重要)。
< p > Determine the victory points as follows (use the
first matching case):</ p >
< dl >
< dt > If you have exactly five gold coins </ dt >
< dd > You get five victory points </ dd >
< dt > If you have one or more gold coins, and you have one or more silver coins </ dt >
< dd > You get two victory points </ dd >
< dt > If you have one or more silver coins </ dt >
< dd > You get one victory point </ dd >
< dt > Otherwise </ dt >
< dd > You get no victory points </ dd >
</ dl >
以下代码片段显示了使用 dl
元素作为词汇表。请注意使用 dfn
来表示正在定义的词。
< dl >
< dt >< dfn > Apartment</ dfn > , n.</ dt >
< dd > An execution context grouping one or more threads with one or
more COM objects.</ dd >
< dt >< dfn > Flat</ dfn > , n.</ dt >
< dd > A deflated tire.</ dd >
< dt >< dfn > Home</ dfn > , n.</ dt >
< dd > The user's login directory.</ dd >
</ dl >
此示例在 dl
元素中使用了 微数据 属性,并结合 div
元素,来标注一家法国餐馆的冰淇淋甜点。
< dl >
< div itemscope itemtype = "http://schema.org/Product" >
< dt itemprop = "name" > Café ou Chocolat Liégeois
< dd itemprop = "offers" itemscope itemtype = "http://schema.org/Offer" >
< span itemprop = "price" > 3.50</ span >
< data itemprop = "priceCurrency" value = "EUR" > €</ data >
< dd itemprop = "description" >
2 boules Café ou Chocolat, 1 boule Vanille, sauce café ou chocolat, chantilly
</ div >
< div itemscope itemtype = "http://schema.org/Product" >
< dt itemprop = "name" > Américaine
< dd itemprop = "offers" itemscope itemtype = "http://schema.org/Offer" >
< span itemprop = "price" > 3.50</ span >
< data itemprop = "priceCurrency" value = "EUR" > €</ data >
< dd itemprop = "description" >
1 boule Crème brûlée, 1 boule Vanille, 1 boule Caramel, chantilly
</ div >
</ dl >
如果没有 div
元素,标记将需要使用 itemref
属性来将 dd
元素中的数据与项链接,如下所示。
< dl >
< dt itemscope itemtype = "http://schema.org/Product" itemref = "1-offer 1-description" >
< span itemprop = "name" > Café ou Chocolat Liégeois</ span >
< dd id = "1-offer" itemprop = "offers" itemscope itemtype = "http://schema.org/Offer" >
< span itemprop = "price" > 3.50</ span >
< data itemprop = "priceCurrency" value = "EUR" > €</ data >
< dd id = "1-description" itemprop = "description" >
2 boules Café ou Chocolat, 1 boule Vanille, sauce café ou chocolat, chantilly
< dt itemscope itemtype = "http://schema.org/Product" itemref = "2-offer 2-description" >
< span itemprop = "name" > Américaine</ span >
< dd id = "2-offer" itemprop = "offers" itemscope itemtype = "http://schema.org/Offer" >
< span itemprop = "price" > 3.50</ span >
< data itemprop = "priceCurrency" value = "EUR" > €</ data >
< dd id = "2-description" itemprop = "description" >
1 boule Crème brûlée, 1 boule Vanille, 1 boule Caramel, chantilly
</ dl >
dl
元素不适合用于标记对话。请参阅一些如何标记对话的示例。
dt
元素支持所有当前引擎。
dl
元素中,在
dd
或 dt
元素之前。
dl
元素的子元素 div
元素中,在 dd
或
dt
元素之前。
header
、footer
、分区内容 或 标题内容 的后代。dt
元素后面紧跟另一个 dt
元素或 dd
元素,则其结束标签可以省略。HTMLElement
。
dt
元素表示描述列表(dl
元素)中术语-描述组的术语或名称部分。
dt
元素本身在 dl
元素中使用时,并不表示其内容是被定义的术语,但可以使用 dfn
元素来表示这一点。
此示例展示了使用 dt
元素表示问题,使用 dd
元素表示答案的常见问题(FAQ)列表。
< article >
< h1 > FAQ</ h1 >
< dl >
< dt > What do we want?</ dt >
< dd > Our data.</ dd >
< dt > When do we want it?</ dt >
< dd > Now.</ dd >
< dt > Where is it?</ dt >
< dd > We are not sure.</ dd >
</ dl >
</ article >
dd
元素支持所有当前引擎。
dl
元素中,在
dt
或 dd
元素之后。
dl
元素的子元素 div
元素中,在 dt
或
dd
元素之后。
dd
元素后面紧跟另一个 dd
元素或 dt
元素,或者父元素中没有更多内容,则其结束标签可以省略。
HTMLElement
。
dd
元素表示描述列表(dl
元素)中术语-描述组的描述、定义或值部分。
dl
可以用于定义词汇表,就像在字典中一样。在以下示例中,每个条目由带有 dt
的 dfn
给出,并有多个
dd
,展示定义的各个部分。
< dl >
< dt >< dfn > happiness</ dfn ></ dt >
< dd class = "pronunciation" > /ˈhæpinəs/</ dd >
< dd class = "part-of-speech" >< i >< abbr > n.</ abbr ></ i ></ dd >
< dd > The state of being happy.</ dd >
< dd > Good fortune; success. < q > Oh < b > happiness</ b > ! It worked!</ q ></ dd >
< dt >< dfn > rejoice</ dfn ></ dt >
< dd class = "pronunciation" > /rɪˈdʒɔɪs/</ dd >
< dd >< i class = "part-of-speech" >< abbr > v.intr.</ abbr ></ i > To be delighted oneself.</ dd >
< dd >< i class = "part-of-speech" >< abbr > v.tr.</ abbr ></ i > To cause one to be delighted.</ dd >
</ dl >
figure
元素支持所有当前引擎。
figcaption
元素后跟 流内容。figcaption
元素。HTMLElement
。figure
元素表示一些独立的流内容,可选地带有标题,通常作为单一单元从文档的主流中引用。
在此上下文中,“独立”并不一定意味着独立。例如,段落中的每个句子都是独立的;作为句子一部分的图像不适合使用 figure
,但由图像构成的完整句子则是合适的。
因此,该元素可以用来注释插图、图表、照片、代码列表等。
当 figure
从文档的主要内容中通过标题(例如,通过图号)进行引用时,这样的内容可以很容易地从主内容中移开,例如,移到页面侧边、专用页面或附录,而不会影响文档的流。
如果 figure
元素通过其相对位置引用,例如,“在上面的照片中”或“如下一图所示”,则移动图形会破坏页面的意义。鼓励作者使用标签引用图形,而不是使用此类相对引用,以便可以轻松地重新设计页面而不影响页面的意义。
元素的第一个 figcaption
元素子元素(如果有),表示 figure
元素内容的标题。如果没有 figcaption
子元素,则没有标题。
figure
元素的内容是周围流的一部分。如果页面的目的是显示图形,例如图片共享网站上的照片,则可以使用 figure
和 figcaption
元素明确提供该图形的标题。对于仅与周围流略有相关或具有不同目的的内容,应使用 aside
元素(它本身可以包含 figure
)。例如,重复来自
article
内容的拉引引用会更适合放在 aside
中,而不是 figure
中,因为它不是内容的一部分,而是为了吸引读者或突出关键主题而重复内容。
此示例展示了使用 figure
元素来标记代码列表。
< p > In < a href = "#l4" > listing 4</ a > we see the primary core interface
API declaration.</ p >
< figure id = "l4" >
< figcaption > Listing 4. The primary core interface API declaration.</ figcaption >
< pre >< code > interface PrimaryCore {
boolean verifyDataLine();
undefined sendData(sequence< byte> data);
undefined initSelfDestruct();
}</ code ></ pre >
</ figure >
< p > The API is designed to use UTF-8.</ p >
在这里,我们看到使用 figure
元素来标记作为页面主要内容的照片(如在画廊中)。
<!DOCTYPE HTML>
< html lang = "en" >
< title > Bubbles at work — My Gallery™</ title >
< figure >
< img src = "bubbles-work.jpeg"
alt = "Bubbles, sitting in his office chair, works on his
latest project intently." >
< figcaption > Bubbles at work</ figcaption >
</ figure >
< nav >< a href = "19414.html" > Prev</ a > — < a href = "19416.html" > Next</ a ></ nav >
在此示例中,我们看到一个不是 figure 的图像,以及一个是 figure 的图像和视频。第一个图像实际上是示例第二句话的一部分,因此它不是一个独立的单元,因此使用 figure
是不合适的。
< h2 > Malinko's comics</ h2 >
< p > This case centered on some sort of "intellectual property"
infringement related to a comic (see Exhibit A). The suit started
after a trailer ending with these words:
< blockquote >
< img src = "promblem-packed-action.png" alt = "ROUGH COPY! Promblem-Packed Action!" >
</ blockquote >
< p > ...was aired. A lawyer, armed with a Bigger Notebook, launched a
preemptive strike using snowballs. A complete copy of the trailer is
included with Exhibit B.
< figure >
< img src = "ex-a.png" alt = "Two squiggles on a dirty piece of paper." >
< figcaption > Exhibit A. The alleged < cite > rough copy</ cite > comic.</ figcaption >
</ figure >
< figure >
< video src = "ex-b.mov" ></ video >
< figcaption > Exhibit B. The < cite > Rough Copy</ cite > trailer.</ figcaption >
</ figure >
< p > The case was resolved out of court.
这里使用 figure
元素标记了一部分诗。
< figure >
< p > 'Twas brillig, and the slithy toves< br >
Did gyre and gimble in the wabe;< br >
All mimsy were the borogoves,< br >
And the mome raths outgrabe.</ p >
< figcaption >< cite > Jabberwocky</ cite > (first verse). Lewis Carroll, 1832-98</ figcaption >
</ figure >
在此示例中,这可能是讨论城堡的一个更大作品的一部分,使用嵌套的 figure
元素为组中的每个图形提供了一个组标题和单独的标题:
< figure >
< figcaption > The castle through the ages: 1423, 1858, and 1999 respectively.</ figcaption >
< figure >
< figcaption > Etching. Anonymous, ca. 1423.</ figcaption >
< img src = "castle1423.jpeg" alt = "The castle has one tower, and a tall wall around it." >
</ figure >
< figure >
< figcaption > Oil-based paint on canvas. Maria Towle, 1858.</ figcaption >
< img src = "castle1858.jpeg" alt = "The castle now has two towers and two walls." >
</ figure >
< figure >
< figcaption > Film photograph. Peter Jankle, 1999.</ figcaption >
< img src = "castle1999.jpeg" alt = "The castle lies in ruins, the original tower all that remains in one piece." >
</ figure >
</ figure >
上一个示例也可以更简洁地写成如下形式(使用 title
属性代替嵌套的
figure
/figcaption
对):
< figure >
< img src = "castle1423.jpeg" title = "Etching. Anonymous, ca. 1423."
alt = "The castle has one tower, and a tall wall around it." >
< img src = "castle1858.jpeg" title = "Oil-based paint on canvas. Maria Towle, 1858."
alt = "The castle now has two towers and two walls." >
< img src = "castle1999.jpeg" title = "Film photograph. Peter Jankle, 1999."
alt = "The castle lies in ruins, the original tower all that remains in one piece." >
< figcaption > The castle through the ages: 1423, 1858, and 1999 respectively.</ figcaption >
</ figure >
图形有时仅通过内容隐式地引用:
< article >
< h1 > Fiscal negotiations stumble in Congress as deadline nears</ h1 >
< figure >
< img src = "obama-reid.jpeg" alt = "Obama and Reid sit together smiling in the Oval Office." >
< figcaption > Barack Obama and Harry Reid. White House press photograph.</ figcaption >
</ figure >
< p > Negotiations in Congress to end the fiscal impasse sputtered on Tuesday, leaving both chambers
grasping for a way to reopen the government and raise the country's borrowing authority with a
Thursday deadline drawing near.</ p >
...
</ article >
figcaption
元素
支持所有当前引擎。
figure
元素的第一个或最后一个子元素。HTMLElement
。
figcaption
元素表示其父 figure
元素内容的标题或说明(如果有)。
该元素可以包含有关来源的附加信息:
< figcaption >
< p > A duck.</ p >
< p >< small > Photograph courtesy of 🌟 News.</ small ></ p >
</ figcaption >
< figcaption >
< p > Average rent for 3-room apartments, excluding non-profit apartments</ p >
< p > Zürich’s Statistics Office — < time datetime = 2017-11-14 > 14 November 2017</ time ></ p >
</ figcaption >
main
元素支持所有当前引擎。
main
元素。HTMLElement
。
文档中不能有多个未指定 main
元素。
层次结构正确的 main
元素 是指其祖先元素仅限于 html
、body
、div
、没有可访问名称的 form
元素和 自主自定义元素。每个 main
元素都必须是层次结构正确的 main
元素。
在此示例中,作者使用了一种将页面的每个组件呈现在一个框中的布局。为了包装页面的主要内容(而不是页眉、页脚、导航栏和侧边栏),使用了 main
元素。
<!DOCTYPE html>
< html lang = "en" >
< title > RPG System 17</ title >
< style >
header , nav , aside , main , footer {
margin : 0.5 em ; border : thin solid ; padding : 0.5 em ;
background : #EFF ; color : black ; box-shadow : 0 0 0.25 em #033 ;
}
h1 , h2 , p { margin : 0 ; }
nav , main { float : left ; }
aside { float : right ; }
footer { clear : both ; }
</ style >
< header >
< h1 > System Eighteen</ h1 >
</ header >
< nav >
< a href = "../16/" > ← System 17</ a >
< a href = "../18/" > RPXIX →</ a >
</ nav >
< aside >
< p > This system has no HP mechanic, so there's no healing.
</ aside >
< main >
< h2 > Character creation</ h2 >
< p > Attributes (magic, strength, agility) are purchased at the cost of one point per level.</ p >
< h2 > Rolls</ h2 >
< p > Each encounter, roll the dice for all your skills. If you roll more than the opponent, you win.</ p >
</ main >
< footer >
< p > Copyright © 2013
</ footer >
</ html >
在以下示例中,使用了多个 main
元素,并使用脚本使导航在不进行服务器往返的情况下工作,并为非当前元素设置 属性:
<!doctype html>
< html lang = en-CA >
< meta charset = utf-8 >
< title > … </ title >
< link rel = stylesheet href = spa.css >
< script src = spa.js async ></ script >
< nav >
< a href = / > Home</ a >
< a href = /about > About</ a >
< a href = /contact > Contact</ a >
</ nav >
< main >
< h1 > Home</ h1 >
…
</ main >
< main hidden >
< h1 > About</ h1 >
…
</ main >
< main hidden >
< h1 > Contact</ h1 >
…
</ main >
< footer > Made with ❤️ by < a href = https://example.com/ > Example 👻</ a > .</ footer >
search
元素当前引擎不支持。
HTMLElement
。search
元素表示文档或应用程序中包含一组与执行搜索或过滤操作相关的表单控件或其他内容的部分。这可以是网站或应用程序的搜索;在当前网页上搜索或过滤搜索结果的方法;或全局或互联网范围的搜索功能。
仅用于呈现搜索结果是不合适的,尽管可以将建议和链接作为“快速搜索”结果的一部分包含在搜索功能中。而是期望将返回的搜索结果网页作为该网页主要内容的一部分呈现。
在以下示例中,作者在网页的header
中包含了一个搜索表单:
< header >
< h1 >< a href = "/" > My fancy blog</ a ></ h1 >
...
< search >
< form action = "search.php" >
< label for = "query" > Find an article</ label >
< input id = "query" name = "q" type = "search" >
< button type = "submit" > Go!</ button >
</ form >
</ search >
</ header >
在这个示例中,作者完全使用 JavaScript 实现了其网络应用程序的搜索功能。没有使用 form
元素来执行服务器端提交,但包含的 search
元素在语义上标识了其后代内容的目的是表示搜索功能。
< search >
< label >
Find and filter your query
< input type = "search" id = "query" >
</ label >
< label >
< input type = "checkbox" id = "exact-only" >
Exact matches only
</ label >
< section >
< h3 > Results found:</ h3 >
< ul id = "results" >
< li >
< p >< a href = "services/consulting" > Consulting services</ a ></ p >
< p >
Find out how can we help you improve your business with our integrated consultants, Bob and Bob.
</ p >
</ li >
...
</ ul >
<!--
when a query returns or filters out all results
render the no results message here
-->
< output id = "no-results" ></ output >
</ section >
</ search >
在以下示例中,页面有两个搜索功能。第一个位于网页的header
中,作为一个全局机制来搜索网站的内容。其目的通过指定的title
属性来指示。第二个是页面主要内容的一部分,表示一个搜索和过滤当前页面内容的机制。它包含一个标题来指示其目的。
< body >
< header >
...
< search title = "Website" >
...
</ search >
</ header >
< main >
< h1 > Hotels near your location</ h1 >
< search >
< h2 > Filter results</ h2 >
...
</ search >
< article >
<!-- search result content -->
</ article >
</ main >
</ body >
div
元素支持所有当前引擎。
支持所有当前引擎。
dl
元素的子元素。dl
元素的子元素:一个或多个 dt
元素,后跟一个或多个
dd
元素,可以与 脚本支持元素 混合。
dl
元素的子元素:流内容。[Exposed =Window ]
interface HTMLDivElement : HTMLElement {
[HTMLConstructor ] constructor ();
// also has obsolete members
};
div
元素本身没有任何特殊含义。它表示其子元素。它可以与 class
、lang
和 title
属性一起使用,以标记一组连续元素的语义。它还可以在 dl
元素中使用,包裹 dt
和 dd
元素的组。
强烈建议作者将 div
元素视为最后的手段,当没有其他合适的元素时才使用。使用更合适的元素而不是 div
元素,可以提高读者的可访问性,并且更易于作者维护。
例如,一篇博客文章可以使用 article
来标记,一个章节可以使用 section
来标记,一个页面的导航可以使用 nav
来标记,一组表单控件可以使用 fieldset
来标记。
另一方面,div
元素可以用于样式目的,或者用于包裹章节中的多个段落,这些段落都需要以类似的方式进行注释。在下面的例子中,我们看到 div
元素被用来一次设置两个段落的语言,而不是分别设置两个段落元素的语言:
< article lang = "en-US" >
< h1 > My use of language and my cats</ h1 >
< p > My cat's behavior hasn't changed much since her absence, except
that she plays her new physique to the neighbors regularly, in an
attempt to get pets.</ p >
< div lang = "en-GB" >
< p > My other cat, coloured black and white, is a sweetie. He followed
us to the pool today, walking down the pavement with us. Yesterday
he apparently visited our neighbours. I wonder if he recognises that
their flat is a mirror image of ours.</ p >
< p > Hm, I just noticed that in the last paragraph I used British
English. But I'm supposed to write in American English. So I
shouldn't say "pavement" or "flat" or "colour"...</ p >
</ div >
< p > I should say "sidewalk" and "apartment" and "color"!</ p >
</ article >
a
元素所有当前引擎支持。
所有当前引擎支持。
href
属性:
交互内容。
a
元素后代,或具有 tabindex
属性的后代。
href
—
超链接 的地址
target
— 可导航对象 用于 超链接 导航
download
— 是否下载资源而不是导航到它,以及如果是则下载的文件名
ping
— 要 ping 的 URL
rel
—
包含 超链接 的文档位置与目标资源之间的关系
hreflang
— 链接资源的语言
type
—
被引用资源的类型提示
referrerpolicy
— 元素发起的 引用策略 对 fetches
href
属性: 作者; 实现者。[Exposed =Window ]
interface HTMLAnchorElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString target ;
[CEReactions ] attribute DOMString download ;
[CEReactions ] attribute USVString ping ;
[CEReactions ] attribute DOMString rel ;
[SameObject , PutForwards =value ] readonly attribute DOMTokenList relList ;
[CEReactions ] attribute DOMString hreflang ;
[CEReactions ] attribute DOMString type ;
[CEReactions ] attribute DOMString text ;
[CEReactions ] attribute DOMString referrerPolicy ;
// also has obsolete members
};
HTMLAnchorElement includes HTMLHyperlinkElementUtils ;
如果 a
元素有 href
属性,那么它 表示 一个 超链接(超文本锚点),由其内容标示。
如果 a
元素没有 href
属性,那么该元素 表示
一个占位符,表示如果相关的话,本来可以放置一个链接的位置,仅包含该元素的内容。
如果没有 href
属性,则
target
、download
、ping
、rel
、hreflang
、type
和
referrerpolicy
属性必须省略。
如果 itemprop
属性在 a
元素上被指定,则必须同时指定 href
属性。
如果一个网站在每个页面上使用一致的导航工具栏,那么通常链接到页面本身的链接可以使用 a
元素进行标记:
< nav >
< ul >
< li > < a href = "/" > Home</ a > </ li >
< li > < a href = "/news" > News</ a > </ li >
< li > < a > Examples</ a > </ li >
< li > < a href = "/legal" > Legal</ a > </ li >
</ ul >
</ nav >
href
、target
、download
、ping
和 referrerpolicy
属性影响用户 跟随超链接 或
下载超链接
时发生的事情,这些超链接是使用 a
元素创建的。rel
、hreflang
和 type
属性可用于在用户跟随链接之前向其指示目标资源的可能性质。
a.text
Same as textContent
.
支持所有当前的引擎。
支持所有当前的引擎。
IDL 属性 download
、ping
、target
、rel
、hreflang
和 type
,必须反映同名的相应内容属性。
支持所有当前的引擎。
IDL 属性 relList
必须 反映
rel
内容属性。
HTMLAnchorElement/referrerPolicy
支持所有当前的引擎。
IDL 属性 referrerPolicy
必须 反映 referrerpolicy
内容属性,仅限已知值。
text
属性的 getter
必须返回该元素的 后代文本内容。
text
属性的 setter 必须 用给定的值替换所有字符串。
a
元素可以包裹整个段落、列表、表格等,甚至整个部分,只要其中没有交互内容(例如按钮或其他链接)。此示例展示了如何将整个广告块变成一个链接:
< aside class = "advertising" >
< h1 > Advertising</ h1 >
< a href = "https://ad.example.com/?adid=1929&pubid=1422" >
< section >
< h1 > Mellblomatic 9000!</ h1 >
< p > Turn all your widgets into mellbloms!</ p >
< p > Only $9.99 plus shipping and handling.</ p >
</ section >
</ a >
< a href = "https://ad.example.com/?adid=375&pubid=1422" >
< section >
< h1 > The Mellblom Browser</ h1 >
< p > Web browsing at the speed of light.</ p >
< p > No other browser goes faster!</ p >
</ section >
</ a >
</ aside >
以下示例展示了如何使用一点脚本将职位列表表格中的整行有效地变成一个超链接:
< table >
< tr >
< th > Position
< th > Team
< th > Location
< tr >
< td >< a href = "/jobs/manager" > Manager</ a >
< td > Remotees
< td > Remote
< tr >
< td >< a href = "/jobs/director" > Director</ a >
< td > Remotees
< td > Remote
< tr >
< td >< a href = "/jobs/astronaut" > Astronaut</ a >
< td > Architecture
< td > Remote
</ table >
< script >
document. querySelector( "table" ). onclick = ({ target }) => {
if ( target. parentElement. localName === "tr" ) {
const link = target. parentElement. querySelector( "a" );
if ( link) {
link. click();
}
}
}
</ script >
em
元素支持所有当前引擎。
HTMLElement
。
特定内容的强调程度由其祖先 em
元素的数量决定。
强调位置的变化会改变句子的含义。因此,该元素是内容的一个组成部分。具体的强调使用方式取决于语言。
这些例子展示了如何通过改变强调来改变意思。首先,一个一般的事实陈述,没有任何强调:
< p > Cats are cute animals.</ p >
通过强调第一个词,声明暗示讨论的动物种类有问题(也许有人在断言狗是可爱的):
< p >< em > Cats</ em > are cute animals.</ p >
将重音移到动词上,突出的是整个句子的真实性受到质疑(也许有人在说猫不可爱):
< p > Cats < em > are</ em > cute animals.</ p >
通过将重音移到形容词上,猫的具体性质再次被强调(也许有人暗示猫是凶猛的动物):
< p > Cats are < em > cute</ em > animals.</ p >
同样地,如果有人断言猫是蔬菜,纠正这种说法的人可能会强调最后一个词:
< p > Cats are cute < em > animals</ em > .</ p >
通过强调整个句子,可以看出说话者在努力传达这个观点。这种强调通常也会影响标点符号,因此这里用了感叹号。
< p >< em > Cats are cute animals!</ em ></ p >
愤怒中带有对可爱程度的强调,可能会导致如下的标记:
< p >< em > Cats are < em > cute</ em > animals!</ em ></ p >
strong
元素Support in all current engines.
HTMLElement
。重要性:strong
元素可以用在标题、说明或段落中,以区分真正重要的部分与其他可能更详细、更幽默或只是例行公事的部分。(这与标记子标题不同,子标题适合使用 hgroup
元素。)
例如,前一段的第一个词用 strong
标记,以将其与段落中其他更详细的文字区分开来。
严肃性:strong
元素可以用来标记警告或注意事项。
紧迫性:strong
元素可以用来表示用户需要比文档其他部分更早看到的内容。
内容的相对重要级别由其祖先 strong
元素的数量决定;每个 strong
元素都会增加其内容的重要性。
用 strong
元素改变文本的重要性不会改变句子的含义。
在这里,“chapter”一词和实际的章节号只是例行公事,实际的章节名称用 strong
标记:
< h1 > Chapter 1: < strong > The Praxis</ strong ></ h1 >
在下面的例子中,说明中的图名用 strong
标记,以将其与例行公事的文本(前)和描述(后)区分开来:
< figcaption > Figure 1. < strong > Ant colony dynamics</ strong > . The ants in this colony are
affected by the heat source (upper left) and the food source (lower right).</ figcaption >
在这个例子中,标题实际上是“Flowers, Bees, and Honey”,但是作者在标题中添加了轻松愉快的部分。使用 strong
元素标记第一部分,以将其与后面的部分区分开来。
< h1 >< strong > Flowers, Bees, and Honey</ strong > and other things I don't understand</ h1 >
这是一个游戏中警告通知的示例,其中各个部分根据它们的重要性进行了标记:
< p >< strong > Warning.</ strong > This dungeon is dangerous.
< strong > Avoid the ducks.</ strong > Take any gold you find.
< strong >< strong > Do not take any of the diamonds</ strong > ,
they are explosive and < strong > will destroy anything within
ten meters.</ strong ></ strong > You have been warned.</ p >
在这个示例中,使用了 strong
元素来表示用户首先需要阅读的部分文本。
< p > Welcome to Remy, the reminder system.</ p >
< p > Your tasks for today:</ p >
< ul >
< li >< p >< strong > Turn off the oven.</ strong ></ p ></ li >
< li >< p > Put out the trash.</ p ></ li >
< li >< p > Do the laundry.</ p ></ li >
</ ul >
small
元素Support in all current engines.
HTMLElement
.
小字打印通常包括免责声明、警告、法律限制或版权声明。小字打印有时也用于归属,或满足许可要求。
small
元素并不会“降低”或减少通过 em
元素强调的文本或通过
strong
元素标记为重要的文本的重要性。要标记文本为不强调或不重要,只需不要使用 em
或 strong
元素即可。
small
元素不应用于长时间的文本,例如多个段落、列表或文本部分。它仅适用于短文本。例如,列出使用条款的页面中的文本不适合使用 small
元素:在这种情况下,文本不是旁注,它是页面的主要内容。
small
元素不得用于子标题;为此,使用 hgroup
元素。
在此示例中,small
元素用于指示酒店房间价格中不包含增值税:
< dl >
< dt > Single room
< dd > 199 € < small > breakfast included, VAT not included</ small >
< dt > Double room
< dd > 239 € < small > breakfast included, VAT not included</ small >
</ dl >
在第二个示例中,small
元素用于文章中的附注。
< p > Example Corp today announced record profits for the
second quarter < small > (Full Disclosure: Foo News is a subsidiary of
Example Corp)</ small > , leading to speculation about a third quarter
merger with Demo Group.</ p >
这与侧边栏不同,侧边栏可能包含多个段落,并且与正文的主要流动分开。在以下示例中,我们看到同一篇文章中的侧边栏。该侧边栏也有小字,指明了侧边栏中信息的来源。
< aside >
< h1 > Example Corp</ h1 >
< p > This company mostly creates small software and Web
sites.</ p >
< p > The Example Corp company mission is "To provide entertainment
and news on a sample basis".</ p >
< p >< small > Information obtained from < a
href = "https://example.com/about.html" > example.com</ a > home
page.</ small ></ p >
</ aside >
在最后一个示例中,small
元素被标记为 重要的 小字。
< p >< strong >< small > Continued use of this service will result in a kiss.</ small ></ strong ></ p >
s
元素所有当前引擎均支持。
HTMLElement
。s
元素不适用于指示文档编辑;要标记一段文本为已从文档中删除,请使用del
元素。
在这个示例中,建议零售价已被标记为不再相关,因为相关产品有了新的销售价格。
< p > Buy our Iced Tea and Lemonade!</ p >
< p >< s > Recommended retail price: $3.99 per bottle</ s ></ p >
< p >< strong > Now selling for just $2.99 a bottle!</ strong ></ p >
cite
元素所有当前引擎均支持。
HTMLElement
。
cite
元素表示一个作品的标题(例如:
一本书,
一篇论文,
一篇文章,
一首诗,
一份乐谱,
一首歌曲,
一部剧本,
一部电影,
一档电视节目,
一款游戏,
一件雕塑,
一幅画,
一场戏剧制作,
一部剧,
一部歌剧,
一部音乐剧,
一次展览,
一份法律案件报告,
一个计算机程序,
等等)。这可以是被引用或详细引用的作品(即,引用),也可以只是随意提到的作品。
一个人的名字不是作品的标题——即使人们称那个人人为“作品”——因此,该元素不应用于标记人名。(在某些情况下,b
元素可能适用于名字;例如,在一篇关于名人的八卦文章中,名人名字作为关键字以不同样式呈现,以吸引注意。在其他情况下,如果确实需要元素,可以使用span
元素。)
下一个示例展示了cite
元素的典型用法:
< p > My favorite book is < cite > The Reality Dysfunction</ cite > by
Peter F. Hamilton. My favorite comic is < cite > Pearls Before
Swine</ cite > by Stephan Pastis. My favorite track is < cite > Jive
Samba</ cite > by the Cannonball Adderley Sextet.</ p >
这是正确的用法:
< p > According to the Wikipedia article < cite > HTML</ cite > , as it
stood in mid-February 2008, leaving attribute values unquoted is
unsafe. This is obviously an over-simplification.</ p >
然而,以下用法是不正确的,因为这里的cite
元素包含的内容远超作品的标题:
<!-- do not copy this example, it is an example of bad usage! -->
< p > According to < cite > the Wikipedia article on HTML</ cite > , as it
stood in mid-February 2008, leaving attribute values unquoted is
unsafe. This is obviously an over-simplification.</ p >
cite
元素是参考文献中引用的关键部分,但仅用于标记标题:
< p >< cite > Universal Declaration of Human Rights</ cite > , United Nations,
December 1948. Adopted by General Assembly resolution 217 A (III).</ p >
引用 不是 引述(对于引述,q
元素更为合适)。
这是不正确的用法,因为cite
不用于引述:
< p >< cite > This is wrong!</ cite > , said Ian.</ p >
这也是不正确的用法,因为一个人不是一个作品:
< p >< q > This is still wrong!</ q > , said < cite > Ian</ cite > .</ p >
正确的用法不使用cite
元素:
< p >< q > This is correct</ q > , said Ian.</ p >
如上所述,b
元素可能适用于在某些类型的文档中标记名字作为关键词:
< p > And then < b > Ian</ b > said < q > this might be right, in a
gossip column, maybe!</ q > .</ p >
q
元素
在所有当前的引擎中均有支持。
cite
—
链接到引用的来源或有关编辑的更多信息HTMLQuoteElement
.
引用标点(如引号)不应立即出现在 q
元素之前、之后或内部;这些标点将由用户代理在渲染时插入。
q
元素中的内容必须是从另一个来源引用的,其地址(如果有)可以在 cite
属性中引用。来源可以是虚构的,比如在小说或剧本中引用的角色。
如果存在 cite
属性,它必须是一个
有效的 URL,可能被空格包围。要获得相应的引用链接,属性的值必须 解析 相对于元素的 节点文档。用户代理可能允许用户跟随这些引用链接,但这些链接主要用于私人用途(例如,由收集站点引用统计的服务器端脚本),而不是供读者使用。
q
元素不得用于代替不表示引用的引号;例如,使用 q
元素标记讽刺性陈述是不合适的。
使用 q
元素标记引用完全是可选的;仅使用明确的引用标点而不使用 q
元素同样是正确的。
这是 q
元素的一个简单示例:
< p > The man said < q > Things that are impossible just take
longer</ q > . I disagreed with him.</ p >
这是一个示例,其中 q
元素中包含了一个显式的引用链接,以及一个在外部的显式引用:
< p > The W3C page < cite > About W3C</ cite > says the W3C's
mission is < q cite = "https://www.w3.org/Consortium/" > To lead the
World Wide Web to its full potential by developing protocols and
guidelines that ensure long-term growth for the Web</ q > . I
disagree with this mission.</ p >
在下面的示例中,引用本身包含了另一个引用:
< p > In < cite > Example One</ cite > , he writes < q > The man
said < q > Things that are impossible just take longer</ q > . I
disagreed with him</ q > . Well, I disagree even more!</ p >
在下面的示例中,使用了引号而不是 q
元素:
< p > His best argument was ❝I disagree❞, which
I thought was laughable.</ p >
在下面的示例中,没有引号——引号用于命名一个词。在这种情况下使用 q
元素是不适当的。
< p > The word "ineffable" could have been used to describe the disaster
resulting from the campaign's mismanagement.</ p >
dfn
元素所有当前引擎均支持。
dfn
元素的后代。
title
属性
在此元素上具有特殊语义:
术语的完整形式或缩写的扩展。
HTMLElement
.
dfn
元素 表示 术语的定义实例。最近的 段落、描述列表组 或 部分,即 dfn
元素的最近祖先,必须还包含 术语 的定义,该术语由
dfn
元素给出。
定义术语: 如果 dfn
元素有一个 title
属性,那么该属性的确切值就是正在定义的术语。否则,如果它包含恰好一个子元素节点且没有子 Text
节点,并且该子元素是带有 title
属性的 abbr
元素,那么
该 属性的确切值就是正在定义的术语。否则,就是 后代文本内容,即 dfn
元素给出的定义术语。
如果 title
属性存在,那么它必须仅包含正在定义的术语。
一个链接到 dfn
元素的 a
元素表示由 dfn
元素定义的术语的实例。
在下面的片段中,术语“Garage Door Opener”首先在第一段中被定义,然后在第二段中使用。在这两种情况下,它的缩写才是实际显示的内容。
< p > The < dfn >< abbr title = "Garage Door Opener" > GDO</ abbr ></ dfn >
is a device that allows off-world teams to open the iris.</ p >
<!-- ... later in the document: -->
< p > Teal'c activated his < abbr title = "Garage Door Opener" > GDO</ abbr >
and so Hammond ordered the iris to be opened.</ p >
< p > The < dfn id = gdo >< abbr title = "Garage Door Opener" > GDO</ abbr ></ dfn >
is a device that allows off-world teams to open the iris.</ p >
<!-- ... later in the document: -->
< p > Teal'c activated his < a href = #gdo > < abbr title = "Garage Door Opener" > GDO</ abbr > </ a >
and so Hammond ordered the iris to be opened.</ p >
abbr
元素在所有当前引擎中均受支持。
title
属性在此元素上具有 特殊语义:缩写的完整术语或扩展
HTMLElement
.
元素 abbr
表示 缩写或首字母缩略词,通常带有其扩展形式。title
属性可用于提供缩写的扩展形式。该属性(如果指定)必须包含缩写的扩展形式,且仅此而已。
下面的段落包含了一个使用 abbr
元素标记的缩写。该段落 定义了术语 “Web
Hypertext Application Technology Working Group”。
< p > The < dfn id = whatwg >< abbr
title = "Web Hypertext Application Technology Working Group" > WHATWG</ abbr ></ dfn >
is a loose unofficial collaboration of web browser manufacturers and
interested parties who wish to develop new technologies designed to
allow authors to write and deploy Applications over the World Wide
Web.</ p >
另一种写法是:
< p > The < dfn id = whatwg > Web Hypertext Application Technology
Working Group</ dfn > (< abbr
title = "Web Hypertext Application Technology Working Group" > WHATWG</ abbr > )
is a loose unofficial collaboration of web browser manufacturers and
interested parties who wish to develop new technologies designed to
allow authors to write and deploy Applications over the World Wide
Web.</ p >
这个段落中有两个缩写。请注意,只有一个被定义了;另一个没有相关的扩展,因此没有使用 abbr
元素。
< p > The
< abbr title = "Web Hypertext Application Technology Working Group" > WHATWG</ abbr >
started working on HTML5 in 2004.</ p >
这个段落将一个缩写链接到它的定义。
< p > The < a href = "#whatwg" >< abbr
title = "Web Hypertext Application Technology Working Group" > WHATWG</ abbr ></ a >
community does not have much representation from Asia.</ p >
这个段落标记了一个缩写,但没有提供扩展,可能作为一个挂钩来应用缩写的样式(例如小型大写字母)。
< p > Philip` and Dashiva both denied that they were going to
get the issue counts from past revisions of the specification to
backfill the < abbr > WHATWG</ abbr > issue graph.</ p >
如果一个缩写是复数形式的,则扩展的语法数量(复数与单数)必须与元素内容的语法数量一致。
这里复数形式在元素外部,因此扩展使用的是单数形式:
< p > Two < abbr title = "Working Group" > WG</ abbr > s worked on
this specification: the < abbr > WHATWG</ abbr > and the
< abbr > HTMLWG</ abbr > .</ p >
这里复数形式在元素内部,因此扩展使用的是复数形式:
< p > Two < abbr title = "Working Groups" > WGs</ abbr > worked on
this specification: the < abbr > WHATWG</ abbr > and the
< abbr > HTMLWG</ abbr > .</ p >
不必使用此元素来标记缩写。它在以下情况下被认为是有用的:
abbr
元素和
title
属性是一种替代方案,可以避免在文中直接包含扩展(例如括号中的内容)。
abbr
元素和
title
属性,或者在第一次使用缩写时在文本中直接包含扩展。
abbr
元素而不带
title
属性。
在 title
属性中提供一次扩展不会导致同一文档中其他具有相同内容但没有 title
属性的
abbr
元素表现得像具有相同扩展一样。每个 abbr
元素都是独立的。
ruby
元素在所有当前引擎中均受支持。
HTMLElement
。
ruby
元素允许一个或多个短语内容的片段被标记为
ruby 注释。Ruby 注释是与基础文本并排显示的短文本片段,主要用于东亚排版,作为发音指南或包含其他注释。在
日语中,这种排版形式也被称为 furigana。
ruby
元素的内容模型由以下一种或多种
序列组成:
以下之一:
以下之一:
ruby
和 rt
元素可以用于多种类型的注释,尤其包括(但不限于)下述描述的那些。有关特别是日语 Ruby 的更多细节,以及如何为日语渲染 Ruby,请参见
日语文本布局要求。[JLREQ]
在撰写时,CSS 还未提供完全控制 HTML ruby
元素渲染的方式。希望 CSS 能在适当的时候扩展以支持下述样式。
一个或多个平假名或片假名字符(注音标注)与每个表意字符(基本文本)一起放置。这用于提供汉字字符的读音。
< ruby > B< rt > annotation</ ruby >
这与前面的情况类似:复合词中的每个表意字符(基本文本)都用平假名或片假名字符(注音标注)给出其读音。不同之处在于,基本文本片段形成复合词,而不是彼此分离。
< ruby > B< rt > annotation</ ruby > B< rt > annotation</ rt ></ ruby >
在此示例中,再次注意每个注音如何对应一个基本字符。在这个例子中,每个复合词(熟语)对应一个ruby
元素。
这里的渲染预计是每个注音放置在对应的基本字符上方(或在垂直文本中旁边),注音不会超出相邻字符的范围。
< ruby > 鬼< rt > き</ rt > 門< rt > もん</ rt ></ ruby > の< ruby > 方< rt > ほう</ rt > 角< rt > がく</ rt ></ ruby > を< ruby > 凝< rt > ぎょう</ rt > 視< rt > し</ rt ></ ruby > する
鬼門の方角を凝視する
这在语义上与前面的情况相同(基本复合词中的每个表意字符都有其读音注音,使用平假名或片假名字符),但渲染是更复杂的熟语注音渲染。
这是与前面单字注音复合词相同的示例。不同的渲染预计通过不同的样式(例如CSS)实现,此处不作展示。
< ruby > 鬼< rt > き</ rt > 門< rt > もん</ rt ></ ruby > の< ruby > 方< rt > ほう</ rt > 角< rt > がく</ rt ></ ruby > を< ruby > 凝< rt > ぎょう</ rt > 視< rt > し</ rt ></ ruby > する
有关熟语注音渲染的更多详细信息,请参见《日本文本布局要求》中的附录F。 [JLREQ]
注音描述基本文本的含义,而不是(或除了)发音。因此,基本文本和注音都可以是多个字符长。
< ruby > BASE< rt > annotation</ ruby >
这里一个复合表意词有其对应的片假名作为注音。
< ruby > 境界面< rt > インターフェース</ ruby >
境界面
这里一个复合表意词有其英文翻译作为注音。
< ruby lang = "ja" > 編集者< rt lang = "en" > editor</ ruby >
編集者
对应于多个基本字符的语音读音,因为一对一的映射将非常困难。(在英语中,“Colonel”和“Lieutenant”这两个词是单词的例子,在某些方言中,发音与单个字母的直接映射非常不明确。)
在这个例子中,一种花的名称用组注音提供了其读音:
< ruby > 紫陽花< rt > あじさい</ ruby >
紫陽花
有时,上述注音样式会组合使用。
如果这导致两个注音覆盖同一个基本片段,则可以将注音放在一起。
< ruby > BASE< rt > annotation 1</ rt >< rt > annotation 2</ ruby >
< ruby > B< rt > a</ rt >< ruby > A< rt > a</ rt ></ ruby > S< rt > a</ rt ></ ruby > E< rt > a</ rt ></ ruby >
在这个人为的例子中,一些符号的名字用英文和法文给出。
< ruby >
♥ < rt > Heart < rt lang = fr > Cœur </ rt >
☘ < rt > Shamrock < rt lang = fr > Trèfle </ rt >
✶ < rt > Star < rt lang = fr > Étoile </ rt >
</ ruby >
在更复杂的情况下,如以下示例中,使用嵌套的ruby
元素来给出内部注音,然后整个ruby
再在“外部”层级给出一个注音。
< ruby >< ruby > B< rt > a</ rt > A< rt > n</ rt > S< rt > t</ rt > E< rt > n</ rt ></ ruby >< rt > annotation</ ruby >
在这里,语音读音和含义都用注音标注给出。嵌套ruby
元素上的注音给出了每个基本字符的单字注音,而外部rt
元素的注音给出了使用平假名表示的含义。
< ruby >< ruby > 東< rt > とう</ rt > 南< rt > なん</ rt ></ ruby >< rt > たつみ</ rt ></ ruby > の方角
東南 の方角
这是相同的例子,但意义是用英语而不是日语给出的:
< ruby >< ruby > 東< rt > とう</ rt > 南< rt > なん</ rt ></ ruby >< rt lang = en > Southeast</ rt ></ ruby > の方角
東南 の方角
在没有ruby
元素祖先的ruby
元素中,内容被分段并分为三类:基本文本段、注释段和被忽略的段。被忽略的段不构成文档的语义(它们包含一些元素间空白和rp
元素,后者用于不支持ruby的遗留用户代理)。基本文本段可以重叠(每个位置最多两个段重叠,且任何段具有早于重叠段的开始点也必须具有相同或更晚的结束点,任何段具有晚于重叠段的结束点也必须具有相同或更早的开始点)。注释段对应于rt
元素。每个注释段可以与一个基本文本段相关联,每个基本文本段也可以有注释段关联。(在符合规范的文档中,每个基本文本段都与至少一个注释段相关联,每个注释段都与一个基本文本段相关联。)ruby
元素表示它包含的基本文本段的并集,以及这些基本文本段与注释段的映射。段的描述基于DOM范围;注释段范围始终由一个元素组成。[DOM]
在任何特定时间,ruby
元素内容的分段和分类结果是运行以下算法得到的结果:
让base text segments成为一个空的基本文本段列表,每个段可能有一个基本文本子段列表。
让annotation segments成为一个空的注释段列表,每个段可能与一个基本文本段或子段相关联。
让root成为正在运行算法的ruby
元素。
如果root有一个ruby
元素祖先,则跳到标记为结束的步骤。
让current parent为root。
让index为0。
让start index为null。
让parent start index为null。
让current base text为null。
开始模式:如果index大于或等于current parent中的子节点数量,则跳到标记为结束模式的步骤。
将start index设置为index的值。
基本模式:如果current parent中的第index个节点是ruby
元素,并且current
parent是与root相同的元素,则推送一个ruby层级,然后跳到标记为开始模式的步骤。
如果current parent中的第index个节点是rt
或rp
元素,则设置当前基本文本,然后跳到标记为注释模式的步骤。
将index增加1。
基本模式后递增:如果index大于或等于current parent中的子节点数量,则跳到标记为结束模式的步骤。
跳回到标记为基本模式的步骤。
注释模式:如果current parent中的第index个节点是rt
元素,则推送一个ruby注释,然后跳到标记为注释模式递增的步骤。
如果current parent中的第index个节点是rp
元素,则跳到标记为注释模式递增的步骤。
如果current parent中的第index个节点不是Text
节点,或者是一个不是元素间空白的Text
节点,则跳到标记为基本模式的步骤。
注释模式递增:让lookahead index为index加1。
注释模式空白跳过:如果lookahead index等于current parent中的子节点数量,则跳到标记为结束模式的步骤。
如果lookahead index中的第lookahead index个节点是rt
元素或rp
元素,则将index设置为lookahead
index,并跳到标记为注释模式的步骤。
如果lookahead index中的第lookahead index个节点不是Text
节点,或者是一个不是元素间空白的Text
节点,则跳到标记为基本模式的步骤(不再增加index,所以到目前为止看到的元素间空白成为下一个基本文本段的一部分)。
将lookahead index增加1。
跳到标 记为注释模式空白跳过的步骤。
结束模式:如果current parent不是与root相同的元素,则弹出一个ruby层级,并跳到标记为基本模式后递增的步骤。
结束:返回base text segments和annotation segments。ruby
元素的任何内容如果没有被这两个列表中的段描述,则隐含在被忽略的段中。
当上述步骤提到设置当前基本文本时,意味着在算法中的那个点上执行以下步骤:
让annotation range是一个DOM范围,其开始是边界点(current parent,start index),其结束是边界点(current parent,index)。
让base text segments是一个由范围annotation range描述的基本文本段。
将base text segments添加到base text segments中。
让current base text为base text segments。
让start index为null。
当上述步骤提到推送一个ruby层级时,意味着在算法中的那个点上执行以下步骤:
让current parent为current parent中的第index个节点。
让index为0。
将saved start index设置为start index的值。
让start index为null。
当上述步骤提到弹出一个ruby层级时,意味着在算法中的那个点上执行以下步骤:
让index为current parent在root中的位置。
让current parent为root。
将index增加1。
将start index设置为saved start index的值。
让saved start index为null。
当上述步骤提到推送一个ruby注释时,意味着在算法中的那个点上执行以下步骤:
让rt是rt
元素,它是current
parent的第index个节点。
让annotation range是一个DOM范围,其开始是边界点(current parent,index),其结束是边界点(current parent,index加一)(即,仅包含rt)。
让new annotation segment是一个由范围annotation range描述的注释段。
如果current base text不为null,将new annotation segment与current base text关联。
将new annotation segment添加到annotation segments中。
在这个例子中,日文文本漢字中的每个汉字都用平假名注释其读音。
...
< ruby > 漢< rt > かん</ rt > 字< rt > じ</ rt ></ ruby >
...
这可能会被渲染为:
在这个示例中,繁体中文文本中的每个汉字都标注了其注音符号读音。
< ruby > 漢< rt > ㄏㄢˋ</ rt > 字< rt > ㄗˋ</ rt ></ ruby >
这可能会渲染成:
在这个例子中,每个简体中文文本汉字中的汉字都附有它的拼音注音。
...< ruby > 汉< rt > hàn</ rt > 字< rt > zì</ rt ></ ruby > ...
这可能会渲染成:
在这个更复杂的示例中,缩写“HTML”有四个注解:一个用于整个缩写,简要描述它是什么,一个用于字母“HT”,将其扩展为“Hypertext”,一个用于字母“M”,将其扩展为“Markup”,以及一个用于字母“L”,将其扩展为“Language”。
< ruby >
< ruby > HT< rt > Hypertext</ rt > M< rt > Markup</ rt > L< rt > Language</ rt ></ ruby >
< rt > An abstract language for describing documents and applications
</ ruby >
rt
元素在所有当前引擎中都支持。
ruby
元素的子元素。rt
元素的 结束标签 可以省略,如果该 rt
元素后面紧跟着一个
rt
或 rp
元素,或者如果父元素中没有更多内容。
HTMLElement
。
rt
元素标记了
ruby 注释的 ruby 文本组件。当它是 ruby
元素的子元素时,它本身并不 代表 任何东西,但 ruby
元素使用它作为确定
它 代表 什么的一部分。
一个不属于 ruby
元素的
rt
元素 代表 与它的子元素相同的东西。
rp
元素Support in all current engines.
ruby
元素的子元素,紧接在 rt
元素之前或之后。rp
元素的 结束标签 可以省略,如果该 rp
元素后面紧跟着一个
rt
元素或另一个
rp
元素,或者父元素中没有更多内容。
HTMLElement
。
rp
元素可用于为
ruby 注释的 ruby 文本组件提供括号或其他内容,以供不支持 ruby 注释的用户代理显示。
作为ruby
元素的子元素的rp
元素不表示任何内容。其父元素不是ruby
元素的rp
元素表示其子元素。
上面的示例中,文本 漢字 中的每个汉字都附有其语音读音,可以扩展为使用 rp
,这样在旧版用户代理中,读音将被放在括号中:
...
< ruby > 漢< rp > (</ rp >< rt > かん</ rt >< rp > )</ rp > 字< rp > (</ rp >< rt > じ</ rt >< rp > )</ rp ></ ruby >
...
在符合标准的用户代理中,渲染效果如上所示,但在不支持 ruby 的用户代理中,渲染效果将是:
... 漢(かん)字(じ)...
当一个片段有多个注释时,rp
元素也可以放置在注释之间。这里是另一个之前的虚构示例,展示了一些符号,名称以英语和法语给出,但这次也使用了 rp
元素:
< ruby >
♥< rp > : </ rp >< rt > Heart</ rt >< rp > , </ rp >< rt lang = fr > Cœur</ rt >< rp > .</ rp >
☘< rp > : </ rp >< rt > Shamrock</ rt >< rp > , </ rp >< rt lang = fr > Trèfle</ rt >< rp > .</ rp >
✶< rp > : </ rp >< rt > Star</ rt >< rp > , </ rp >< rt lang = fr > Étoile</ rt >< rp > .</ rp >
</ ruby >
这将使示例在不支持 ruby 的用户代理中呈现如下:
♥: Heart, Cœur. ☘: Shamrock, Trèfle. ✶: Star, Étoile.
data
元素支持所有当前的浏览器。
支持所有当前的浏览器。
value
— 机器可读的值[Exposed =Window ]
interface HTMLDataElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString value ;
};
data
元素
表示 其内容,并在 value
属性中提供这些内容的机器可读形式。
value
属性必须存在。其值必须是元素内容的机器可读格式的表示。
当值与日期或时间相关时,可以使用更具体的 time
元素。
该元素可以用于多种目的。
与本规范中定义的微格式或 微数据属性
结合使用时,该元素可以为数据处理器提供机器可读的值,并为网页浏览器呈现提供人类可读的值。在这种情况下,value
属性中使用的格式由所使用的微格式或微数据词汇决定。
然而,该元素也可以与页面中的脚本一起使用,当脚本需要存储与人类可读值并存的字面值时。在这种情况下,所使用的格式仅取决于脚本的需要。(data-*
属性在这种情况下也可能有用。)
支持所有当前浏览器。
value
IDL 属性必须 反映 同名的内容属性。
在这里,一个简短的表格使用了 data
元素对其数字值进行编码,以便表格排序的 JavaScript 库可以在每列上提供排序机制,尽管这些数字在一列中以文本形式呈现,而在另一列中以分解形式呈现。
< script src = "sortable.js" ></ script >
< table class = "sortable" >
< thead > < tr > < th > Game < th > Corporations < th > Map Size
< tbody >
< tr > < td > 1830 < td > < data value = "8" > Eight</ data > < td > < data value = "93" > 19+74 hexes (93 total)</ data >
< tr > < td > 1856 < td > < data value = "11" > Eleven</ data > < td > < data value = "99" > 12+87 hexes (99 total)</ data >
< tr > < td > 1870 < td > < data value = "10" > Ten</ data > < td > < data value = "149" > 4+145 hexes (149 total)</ data >
</ table >
time
元素所有当前引擎的支持。
所有当前引擎的支持。
datetime
属性: 短语内容.
datetime
— 机器可读值
[Exposed =Window ]
interface HTMLTimeElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString dateTime ;
};
time
元素 表示 它的
内容,以及这些内容的机器可读形式,存储在 datetime
属性中。内容的类型限制为各种日期、时间、时区偏移和
持续时间,如下所述。
datetime
属性可能存在。如果存在,其值必须是元素内容的机器可读格式。
一个没有 datetime
内容属性的 time
元素不得有任何元素子孙。
datetime 值 的 time
元素是元素的 datetime
内容属性的值,如果有的话,否则是 子文本内容
的值。
datetime 值
的 time
元素必须符合以下之一的语法。
< time > 2011-11</ time >
< time > 2011-11-18</ time >
< time > 11-18</ time >
< time > 14:54</ time >
< time > 14:54:39</ time >
< time > 14:54:39.929</ time >
< time > 2011-11-18T14:54</ time >
< time > 2011-11-18T14:54:39</ time >
< time > 2011-11-18T14:54:39.929</ time >
< time > 2011-11-18 14:54</ time >
< time > 2011-11-18 14:54:39</ time >
< time > 2011-11-18 14:54:39.929</ time >
没有时区偏移的带日期时间字符串对于指定在一天内各时区中相同具体时间发生的事件是有用的。例如,2020年新年是在2020-01-01 00:00在每个时区庆祝,而不是在所有时区的同一精确时刻庆祝。对于在所有时区同时发生的事件,例如视频会议,一个有效的全球日期和时间字符串可能更有用。
< time > Z</ time >
< time > +0000</ time >
< time > +00:00</ time >
< time > -0800</ time >
< time > -08:00</ time >
对于没有日期的时间(或指代在多个日期重复的事件的时间),指定控制时间的地理位置通常比指定时区偏移更有用,因为地理位置会随夏令时改变时区偏移。在某些情况下,地理位置甚至会改变时区,例如在2011年底萨摩亚发生的时区调整。存在一个描述时区边界及每个时区内适用规则的数据库,称为时区数据库。[TZDATABASE]
< time > 2011-11-18T14:54Z</ time >
< time > 2011-11-18T14:54:39Z</ time >
< time > 2011-11-18T14:54:39.929Z</ time >
< time > 2011-11-18T14:54+0000</ time >
< time > 2011-11-18T14:54:39+0000</ time >
< time > 2011-11-18T14:54:39.929+0000</ time >
< time > 2011-11-18T14:54+00:00</ time >
< time > 2011-11-18T14:54:39+00:00</ time >
< time > 2011-11-18T14:54:39.929+00:00</ time >
< time > 2011-11-18T06:54-0800</ time >
< time > 2011-11-18T06:54:39-0800</ time >
< time > 2011-11-18T06:54:39.929-0800</ time >
< time > 2011-11-18T06:54-08:00</ time >
< time > 2011-11-18T06:54:39-08:00</ time >
< time > 2011-11-18T06:54:39.929-08:00</ time >
< time > 2011-11-18 14:54Z</ time >
< time > 2011-11-18 14:54:39Z</ time >
< time > 2011-11-18 14:54:39.929Z</ time >
< time > 2011-11-18 14:54+0000</ time >
< time > 2011-11-18 14:54:39+0000</ time >
< time > 2011-11-18 14:54:39.929+0000</ time >
< time > 2011-11-18 14:54+00:00</ time >
< time > 2011-11-18 14:54:39+00:00</ time >
< time > 2011-11-18 14:54:39.929+00:00</ time >
< time > 2011-11-18 06:54-0800</ time >
< time > 2011-11-18 06:54:39-0800</ time >
< time > 2011-11-18 06:54:39.929-0800</ time >
< time > 2011-11-18 06:54-08:00</ time >
< time > 2011-11-18 06:54:39-08:00</ time >
< time > 2011-11-18 06:54:39.929-08:00</ time >
带日期和时区偏移的时间字符串对于指定特定事件或不固定在特定地理位置的虚拟活动是有用的。例如,小行星撞击的确切时间,或者在每天1400 UTC举行的一系列会议中的某次会议,无论世界上的任何特定部分是否遵守夏令时。对于时间随特定地理位置的本地时区偏移而变化的事件,结合该地理位置的有效的本地日期和时间字符串可能更有用。
< time > 2011-W47</ time >
< time > 2011</ time >
< time > 0001</ time >
< time > PT4H18M3S</ time >
< time > 4h18m 3s</ time >
元素内容的 机器可读等效 必须通过以下算法从元素的 datetime 值 获取:
如果从元素的 datetime 值 解析一个 月份字符串 返回一个 月份,那就是机器可读的等效;返回。
如果从元素的 datetime 值 解析一个 日期字符串 返回一个 日期,那就是机器可读的等效;返回。
如果从元素的 datetime 值 解析一个 无年份日期字符串 返回一个 无年份日期,那就是机器可读的等效;返回。
如果从元素的 datetime 值 解析一个 时间字符串 返回一个 时间,那就是机器可读的等效;返回。
如果从元素的 datetime 值 解析一个 本地日期和时间字符串 返回一个 本地日期和时间,那就是机器可读的等效;返回。
如果从元素的 datetime 值 解析一个 时区偏移字符串 返回一个 时区偏移,那就是机器可读的等效;返回。
如果从元素的 datetime 值 解析一个 全球日期和时间字符串 返回一个 全球日期和时间,那就是机器可读的等效;返回。
如果从元素的 datetime 值 解析一个 周字符串 返回一个 周,那就是机器可读的等效;返回。
如果元素的 datetime 值 仅由 ASCII 数字 组成,其中至少一个不是 U+0030 DIGIT ZERO (0),那么机器可读的等效是这些数字的十进制解释,代表一个年份;返回。
如果从元素的 datetime 值 解析一个 持续时间字符串 返回一个 持续时间,那就是机器可读的等效;返回。
没有机器可读的等效。
上述提到的算法旨在设计成对于任何任意字符串 s,只有一个算法会返回一个值。更高效的方法可能是创建一个算法,能够在一次操作中解析所有这些数据类型;开发这样的算法留给读者作为练习。
在所有当前引擎中都受支持。
dateTime
IDL 属性必须 反映 元素的 datetime
内容属性。
time
元素可以用于编码日期,例如在微格式中。以下展示了使用 time
元素的 hCalendar 变体来编码事件的一个假设方式:
< div class = "vevent" >
< a class = "url" href = "http://www.web2con.com/" > http://www.web2con.com/</ a >
< span class = "summary" > Web 2.0 Conference</ span > :
< time class = "dtstart" datetime = "2005-10-05" > October 5</ time > -
< time class = "dtend" datetime = "2005-10-07" > 7</ time > ,
at the < span class = "location" > Argent Hotel, San Francisco, CA</ span >
</ div >
在这里,使用了基于 Atom 词汇的虚构微数据词汇与 time
元素来标记博客文章的发布日期。
< article itemscope itemtype = "https://n.example.org/rfc4287" >
< h1 itemprop = "title" > Big tasks</ h1 >
< footer > Published < time itemprop = "published" datetime = "2009-08-29" > two days ago</ time > .</ footer >
< p itemprop = "content" > Today, I went out and bought a bike for my kid.</ p >
</ article >
在这个例子中,使用 time
元素标记了另一篇文章的发布日期,这里使用了 schema.org 微数据词汇:
< article itemscope itemtype = "http://schema.org/BlogPosting" >
< h1 itemprop = "headline" > Small tasks</ h1 >
< footer > Published < time itemprop = "datePublished" datetime = "2009-08-30" > yesterday</ time > .</ footer >
< p itemprop = "articleBody" > I put a bike bell on her bike.</ p >
</ article >
在以下代码片段中,使用 time
元素以 ISO8601 格式编码一个日期,以便后续由脚本处理:
< p > Our first date was < time datetime = "2006-09-23" > a Saturday</ time > .</ p >
在第二个代码片段中,值包含一个时间:
< p > We stopped talking at < time datetime = "2006-09-24T05:00-07:00" > 5am the next morning</ time > .</ p >
由页面加载的脚本(因此可以了解页面内部使用 time
元素标记日期和时间的约定)可以扫描整个页面,并查看其中所有的 time
元素,以创建一个日期和时间的索引。
例如,这个元素传达了字符串 "Friday" 以及附加的语义,表示 2011 年 11 月 18 日是与 "Friday" 相对应的日期:
Today is < time datetime = "2011-11-18" > Friday</ time > .
在这个示例中,指定了太平洋标准时间(PST)时区的特定时间:
Your next meeting is at < time datetime = "2011-11-18T15:00-08:00" > 3pm</ time > .
code
元素所有当前引擎都支持。
HTMLElement
.
code
元素 表示 计算机代码的片段。这可以是
一个 XML 元素名称、一个文件名、一段计算机程序,或任何计算机能够识别的字符串。
没有正式的方法来指示标记的计算机代码的语言。希望标记 code
元素并标明所用语言的作者,例如,以便语法高亮脚本可以使用正确的规则,可以使用 class
属性,例如,
通过向元素添加以 "language-
" 为前缀的类。
以下示例展示了如何在段落中使用该元素来标记元素名称和计算机代码,包括标点符号。
< p > The < code > code</ code > element represents a fragment of computer
code.</ p >
< p > When you call the < code > activate()</ code > method on the
< code > robotSnowman</ code > object, the eyes glow.</ p >
< p > The example below uses the < code > begin</ code > keyword to indicate
the start of a statement block. It is paired with an < code > end</ code >
keyword, which is followed by the < code > .</ code > punctuation character
(full stop) to indicate the end of the program.</ p >
以下示例展示了如何使用 pre
和 code
元素标记一段代码。
< pre >< code class = "language-pascal" > var i: Integer;
begin
i := 1;
end.</ code ></ pre >
在该示例中使用了一个类来指示所用的语言。
有关更多详细信息,请参见 pre
元素。
var
元素所有当前引擎都支持。
HTMLElement
.
var
元素 表示
一个变量。这可以是数学表达式或编程上下文中的实际变量、一个表示常量的标识符、一个识别物理量的符号、一个函数参数,或仅仅是用作文中占位符的术语。
在下面的段落中,字母 "n" 被用作文中的变量:
< p > If there are < var > n</ var > pipes leading to the ice
cream factory then I expect at < em > least</ em > < var > n</ var >
flavors of ice cream to be available for purchase!</ p >
对于数学,特别是对于超出最简单表达式的情况,MathML 更为合适。然而,var
元素仍然可以用来引用在 MathML 表达式中提到的特定变量。
在这个示例中,展示了一个方程,图例中引用了方程中的变量。表达式本身使用 MathML 标记,但变量在图例中使用 var
提及。
< figure >
< math >
< mi > a</ mi >
< mo > =</ mo >
< msqrt >
< msup >< mi > b</ mi >< mn > 2</ mn ></ msup >
< mi > +</ mi >
< msup >< mi > c</ mi >< mn > 2</ mn ></ msup >
</ msqrt >
</ math >
< figcaption >
Using Pythagoras' theorem to solve for the hypotenuse < var > a</ var > of
a triangle with sides < var > b</ var > and < var > c</ var >
</ figcaption >
</ figure >
在这里,描述质量-能量等价的方程被用在句子中,var
元素被用来标记该方程中的变量和常量:
< p > Then she turned to the blackboard and picked up the chalk. After a few moment's
thought, she wrote < var > E</ var > = < var > m</ var > < var > c</ var >< sup > 2</ sup > . The teacher
looked pleased.</ p >
samp
元素所有当前引擎都支持。
HTMLElement
.
samp
元素 表示 从另一个程序或计算系统中获取的示例或引用输出。
该元素可以与 output
元素进行对比,后者可用于提供 Web 应用程序中的即时输出。
此示例显示了 samp
元素的内联用法:
< p > The computer said < samp > Too much cheese in tray
two</ samp > but I didn't know what that meant.</ p >
第二个示例展示了来自控制台程序的示例输出块。嵌套的 samp
和 kbd
元素允许使用样式表对示例输出的特定元素进行样式设置。还有一些 samp
元素使用更详细的标记进行注释,以实现非常精确的样式设置。为此,使用了 span
元素。
< pre >< samp >< span class = "prompt" > jdoe@mowmow:~$</ span > < kbd > ssh demo.example.com</ kbd >
Last login: Tue Apr 12 09:10:17 2005 from mowmow.example.com on pts/1
Linux demo 2.6.10-grsec+gg3+e+fhs6b+nfs+gr0501+++p3+c4a+gr2b-reslog-v6.189 #1 SMP Tue Feb 1 11:22:36 PST 2005 i686 unknown
< span class = "prompt" > jdoe@demo:~$</ span > < span class = "cursor" > _</ span ></ samp ></ pre >
第三个示例展示了一个输入块及其相应的输出。该示例使用了 code
和 samp
元素。
< pre >
< code class = "language-javascript" > console.log(2.3 + 2.4)</ code >
< samp > 4.699999999999999</ samp >
</ pre >
kbd
元素支持所有当前引擎。
HTMLElement
.
kbd
元素 表示
用户输入(通常是键盘输入,但也可以用来表示其他输入,例如语音命令)。
当 kbd
元素嵌套在 samp
元素内时,它表示系统回显的输入。
当 kbd
元素
包含 一个 samp
元素时,它表示基于系统输出的输入,例如调用菜单项。
当 kbd
元素嵌套在另一个 kbd
元素内时,它表示一个实际的键或其他单一输入单元,具体取决于输入机制。
这里使用了 kbd
元素来指示需要按的键:
< p > To make George eat an apple, press < kbd >< kbd > Shift</ kbd > + < kbd > F3</ kbd ></ kbd ></ p >
在第二个示例中,用户被指示选择特定的菜单项。外部的 kbd
元素标记了一块输入区域,内部的 kbd
元素表示每个单独的输入步骤,而其中的 samp
元素则指示这些步骤是基于系统显示的内容进行输入的,在这个例子中是菜单标签:
< p > To make George eat an apple, select
< kbd >< kbd >< samp > File</ samp ></ kbd > |< kbd >< samp > Eat Apple...</ samp ></ kbd ></ kbd >
</ p >
这种精确度并不是必要的;以下示例也同样合适:
< p > To make George eat an apple, select < kbd > File | Eat Apple...</ kbd ></ p >
sub
和 sup
元素所有当前浏览器均支持。
所有当前浏览器均支持。
sub
元素: 给作者;给实施者。sup
元素: 给作者;给实施者。HTMLElement
。
这些元素只能用于标记具有特定含义的排版约定,而不是为了排版效果而使用。例如,将 sub
和 sup
元素用于 LaTeX 文档准备系统的名称是不适当的。一般来说,作者应仅在 缺少 这些元素会改变内容的含义时使用这些元素。
在某些语言中,上标是某些缩写的排版约定的一部分。
< p > Their names are
< span lang = "fr" >< abbr > M< sup > lle</ sup ></ abbr > Gwendoline</ span > and
< span lang = "fr" >< abbr > M< sup > me</ sup ></ abbr > Denise</ span > .</ p >
sub
元素可以在 var
元素内使用,用于表示具有下标的变量。
在这里,sub
元素用于表示识别变量族中的变量的下标:
< p > The coordinate of the < var > i</ var > th point is
(< var > x< sub >< var > i</ var ></ sub ></ var > , < var > y< sub >< var > i</ var ></ sub ></ var > ).
For example, the 10th point has coordinate
(< var > x< sub > 10</ sub ></ var > , < var > y< sub > 10</ sub ></ var > ).</ p >
数学表达式经常使用下标和上标。建议作者使用 MathML 来标记数学内容,但如果不需要详细的数学标记,作者可以选择使用 sub
和 sup
。[MATHML]
< var > E</ var > =< var > m</ var >< var > c</ var >< sup > 2</ sup >
f(< var > x</ var > , < var > n</ var > ) = log< sub > 4</ sub >< var > x</ var >< sup >< var > n</ var ></ sup >
i
元素所有当前引擎均支持。
HTMLElement
。
i
元素 表示
一段以另一种语气或情感的文本,或者以其他方式与正常的正文区分开来,表示一种不同的文本特质,如分类名称、术语、另一种语言的习惯用语、音译、思考或西方文本中的船名。
与主要文本不同的语言中的术语应使用 lang
属性(或在 XML 中,lang
属性在 XML 命名空间)进行注解。
下面的示例展示了 i
元素的用法:
< p > The < i class = "taxonomy" > Felis silvestris catus</ i > is cute.</ p >
< p > The term < i > prose content</ i > is defined above.</ p >
< p > There is a certain < i lang = "fr" > je ne sais quoi</ i > in the air.</ p >
在以下示例中,梦境序列使用了 i
元素进行标记。
< p > Raymond tried to sleep.</ p >
< p >< i > The ship sailed away on Thursday</ i > , he
dreamt. < i > The ship had many people aboard, including a beautiful
princess called Carey. He watched her, day-in, day-out, hoping she
would notice him, but she never did.</ i ></ p >
< p >< i > Finally one night he picked up the courage to speak with
her—</ i ></ p >
< p > Raymond woke with a start as the fire alarm rang out.</ p >
作者可以在 i
元素上使用
class
属性来标识使用该元素的原因,以便在将来需要更改特定用途的样式(例如,梦境序列与分类术语)时,作者不必逐一浏览整个文档(或一系列相关文档)来标注每个用途。
鼓励作者考虑是否有其他元素可能比 i
元素更适用,例如 em
元素用于标记强调,或者
dfn
元素用于标记术语的定义实例。
样式表可以用于格式化 i
元素,就像任何其他元素一样。因此,i
元素中的内容不一定会被斜体显示。
b
元素所有当前浏览器均支持。
HTMLElement
.
b
元素 表示
一段文本,该文本被用来吸引注意,但不传达额外的重要性,也没有暗示其他的声音或情绪,例如文档摘要中的关键字、评论中的产品名称、交互式文本驱动软件中的操作词,或文章的引言。
以下示例展示了如何使用 b
元素来突出显示关键字,而不将其标记为重要:
< p > The < b > frobonitor</ b > and < b > barbinator</ b > components are fried.</ p >
在以下示例中,文本冒险中的对象通过使用 b
元素来突出显示其特殊性。
< p > You enter a small room. Your < b > sword</ b > glows
brighter. A < b > rat</ b > scurries past the corner wall.</ p >
另一个b元素合适的情况是标记引言句(或引言段)。以下示例展示了如何标记一篇关于小猫领养一只兔子的BBC文章:
< article >
< h2 > Kittens 'adopted' by pet rabbit</ h2 >
< p >< b class = "lede" > Six abandoned kittens have found an
unexpected new mother figure — a pet rabbit.</ b ></ p >
< p > Veterinary nurse Melanie Humble took the three-week-old
kittens to her Aberdeen home.</ p >
[...]
与<i>元素一样,作者可以在<b>元素上使用class属性,以便标识该元素的使用原因,以便如果某个特定用途的样式在以后需要更改,作者不必逐一标注每个用途。
<b>元素应作为最后的选择使用,当没有其他更合适的元素时。特别是,标题应使用<h1>到<h6>元素,强调应使用<em>元素,重要性应使用<strong>元素,标记或高亮的文本应使用<mark>元素。
样式表可以用于格式化 b
元素,就像可以重新样式化任何其他元素一样。因此,b
元素中的内容不一定会被加粗。
u
元素在所有当前引擎中都支持。
HTMLElement
。
u
元素 表示
一段文本,该文本具有未明确表达但显式呈现的非文本注释,例如在中文文本中标记该文本为专有名称(中文专有名称标记),或标记该文本为拼写错误。
在大多数情况下,另一个元素可能更合适:用于标记强调的,应该使用 em
元素;用于标记关键词或短语,根据上下文应使用 b
元素或 mark
元素;用于标记书名,应该使用 cite
元素;用于带有明确文本注释的标记,应该使用 ruby
元素;用于技术术语、分类名称、音译、思想,或在西方文本中标记船名,应该使用 i
元素。
在视觉呈现中,u
元素的默认渲染与超链接(下划线)的传统渲染相冲突。建议作者避免在可能与超链接混淆的情况下使用 u
元素。
在这个示例中,使用了 u
元素来标记一个拼写错误的词:
< p > The < u > see</ u > is full of fish.</ p >
mark
元素在所有当前引擎中都支持。
HTMLElement
。
mark
元素
表示 文档中一段被标记或高亮的文本,用于 参考
目的,因为它在另一上下文中的相关性。当在引文或从散文中引用的其他文本块中使用时,它表示一个原本不存在但已添加的高亮,以引起读者对文本中一部分的注意,这部分可能在原作者写作时未被认为重要,但现在正受到意料之外的关注。当在文档的主要散文中使用时,它表示文档中的一部分由于其对用户当前活动的相关性而被高亮。
这个示例展示了如何使用 mark
元素来引起对引文中特定部分的注意:
< p lang = "en-US" > Consider the following quote:</ p >
< blockquote lang = "en-GB" >
< p > Look around and you will find, no-one's really
< mark > colour</ mark > blind.</ p >
</ blockquote >
< p lang = "en-US" > As we can tell from the < em > spelling</ em > of the word,
the person writing this quote is clearly not American.</ p >
(然而,如果目标是标记该元素为拼写错误,使用 u
元素,可能带有一个类,将更为合适。)
另一个 mark
元素的示例是高亮显示匹配某些搜索字符串的文档部分。如果有人查看文档,而服务器知道用户正在搜索“kitten”这个词,则服务器可能会返回一个修改过的文档,其中一个段落如下所示:
< p > I also have some < mark > kitten</ mark > s who are visiting me
these days. They're really cute. I think they like my garden! Maybe I
should adopt a < mark > kitten</ mark > .</ p >
在以下片段中,文本段落提到了代码片段的特定部分。
< p > The highlighted part below is where the error lies:</ p >
< pre >< code > var i: Integer;
begin
i := < mark > 1.1</ mark > ;
end.</ code ></ pre >
这与 语法高亮 是不同的,语法高亮更适合使用 span
元素。将两者结合,可以得到:
< p > The highlighted part below is where the error lies:</ p >
< pre >< code >< span class = keyword > var</ span > < span class = ident > i</ span > : < span class = type > Integer</ span > ;
< span class = keyword > begin</ span >
< span class = ident > i</ span > := < span class = literal >< mark > 1.1</ mark ></ span > ;
< span class = keyword > end</ span > .</ code ></ pre >
这是另一个示例,展示了如何使用 mark
来高亮显示原本未被强调的引用文本的一部分。在这个示例中,常见的排版惯例使得作者将引号中的 mark
元素明确地设置为斜体。
< style >
blockquote mark , q mark {
font : inherit ; font-style : italic ;
text-decoration : none ;
background : transparent ; color : inherit ;
}
. bubble em {
font : inherit ; font-size : larger ;
text-decoration : underline ;
}
</ style >
< article >
< h1 > She knew</ h1 >
< p > Did you notice the subtle joke in the joke on panel 4?</ p >
< blockquote >
< p class = "bubble" > I didn't < em > want</ em > to believe. < mark > Of course
on some level I realized it was a known-plaintext attack.</ mark > But I
couldn't admit it until I saw for myself.</ p >
</ blockquote >
< p > (Emphasis mine.) I thought that was great. It's so pedantic, yet it
explains everything neatly.</ p >
</ article >
顺便提一下,注意这个示例中 em
元素和 mark
元素之间的区别。em
元素是原始引用文本的一部分,而 mark
元素则用于高亮显示评论的部分。
以下示例展示了标记文本片段的 重要性(strong
)与标记文本片段的
相关性(mark
)之间的区别。这是一本教科书的摘录,其中突出显示了与考试相关的部分。尽管安全警告可能很重要,但显然与考试无关。
< h3 > Wormhole Physics Introduction</ h3 >
< p >< mark > A wormhole in normal conditions can be held open for a
maximum of just under 39 minutes.</ mark > Conditions that can increase
the time include a powerful energy source coupled to one or both of
the gates connecting the wormhole, and a large gravity well (such as a
black hole).</ p >
< p >< mark > Momentum is preserved across the wormhole. Electromagnetic
radiation can travel in both directions through a wormhole,
but matter cannot.</ mark ></ p >
< p > When a wormhole is created, a vortex normally forms.
< strong > Warning: The vortex caused by the wormhole opening will
annihilate anything in its path.</ strong > Vortexes can be avoided when
using sufficiently advanced dialing technology.</ p >
< p >< mark > An obstruction in a gate will prevent it from accepting a
wormhole connection.</ mark ></ p >
bdi
元素支持所有当前的浏览器。
dir
全局属性在此元素上具有特殊语义。HTMLElement
.
bdi
元素 表示
一段文本,这段文本将从其周围环境中隔离开来,以便进行双向文本格式化。 [BIDI]
dir
全局属性在此元素上默认为 auto
(它不会像其他元素那样从父元素继承)。
此元素 具有涉及双向算法的渲染要求。
此元素在嵌入方向性未知的用户生成内容时特别有用。
在此示例中,显示了用户名以及用户提交的帖子数量。如果没有使用 bdi
元素,阿拉伯语用户的用户名将会混淆文本(双向算法会把冒号和数字“3”放在“User”一词旁边,而不是放在“posts”一词旁边)。
< ul >
< li > User < bdi > jcranmer</ bdi > : 12 posts.
< li > User < bdi > hober</ bdi > : 5 posts.
< li > User < bdi > إيان</ bdi > : 3 posts.
</ ul >
bdi
元素时,用户名的表现如预期。bdi
元素替换为
b
元素,则用户名会混淆双向算法,第三个项目符号会显示为“User 3 :”,后面跟着阿拉伯名字(从右到左),然后是“posts”和句号。
bdo
元素在所有当前引擎中都支持。
dir
全局属性在该元素上具有特殊语义。
HTMLElement
。
bdo
元素 表示
对其子元素的显式文本方向格式控制。它允许作者通过显式指定方向覆盖来覆盖 Unicode 双向算法。[BIDI]
作者必须在该元素上指定 dir
属性,值为
ltr
以指定从左到右的覆盖,值为
rtl
以指定从右到左的覆盖。auto
值不得指定。
该元素 具有涉及双向算法的渲染要求。
span
元素在所有当前浏览器中均支持。
在所有当前浏览器中均支持。
[Exposed =Window ]
interface HTMLSpanElement : HTMLElement {
[HTMLConstructor ] constructor ();
};
span
元素本身没有特定含义,但与 全局属性(例如 class
、lang
或 dir
)一起使用时非常有用。它 表示 其子元素。
在这个示例中,代码片段使用了 span
元素和
class
属性进行标记,以便通过 CSS
对其关键字和标识符进行颜色编码:
< pre >< code class = "lang-c" >< span class = "keyword" > for</ span > (< span class = "ident" > j</ span > = 0; < span class = "ident" > j</ span > < 256; < span class = "ident" > j</ span > ++) {
< span class = "ident" > i_t3</ span > = (< span class = "ident" > i_t3</ span > & 0x1ffff) | (< span class = "ident" > j</ span > << 17);
< span class = "ident" > i_t6</ span > = (((((((< span class = "ident" > i_t3</ span > >> 3) ^ < span class = "ident" > i_t3</ span > ) >> 1) ^ < span class = "ident" > i_t3</ span > ) >> 8) ^ < span class = "ident" > i_t3</ span > ) >> 5) & 0xff;
< span class = "keyword" > if</ span > (< span class = "ident" > i_t6</ span > == < span class = "ident" > i_t1</ span > )
< span class = "keyword" > break</ span > ;
}</ code ></ pre >
br
元素所有当前引擎的支持。
所有当前引擎的支持。
[Exposed =Window ]
interface HTMLBRElement : HTMLElement {
[HTMLConstructor ] constructor ();
// also has obsolete members
};
虽然换行符在视觉媒体中通常通过将后续文本物理移动到新行来表示,但样式表或用户代理同样可以将换行符以其他方式呈现,例如作为绿色点或额外的间距。
br
元素只能用于实际作为内容一部分的换行符,例如在诗歌或地址中。
以下示例是正确使用 br
元素:
< p > P. Sherman< br >
42 Wallaby Way< br >
Sydney</ p >
br
元素不得用于分隔段落中的主题组。
以下示例是不符合规范的,因为它们滥用了 br
元素:
< p >< a ...> 34 comments.</ a >< br >
< a ...> Add a comment.</ a ></ p >
< p >< label > Name: < input name = "name" ></ label >< br >
< label > Address: < input name = "address" ></ label ></ p >
以下是上述情况的替代方案,这些方案是正确的:
< p >< a ...> 34 comments.</ a ></ p >
< p >< a ...> Add a comment.</ a ></ p >
< p >< label > Name: < input name = "name" ></ label ></ p >
< p >< label > Address: < input name = "address" ></ label ></ p >
如果一个段落仅包含一个br
元素,它
代表一个占位的空白行(例如在模板中)。这样的空白行不应被用于呈现目的。
任何在br
元素内部的内容
不应被视为周围文本的一部分。
这个元素有涉及双向算法的呈现要求。
wbr
元素支持所有当前引擎。
HTMLElement
。
在以下示例中,有人引用了某句话,这句话为了效果被写成了一个长单词。然而,为了确保文本可以以可读的方式换行,这句话中的单词使用了 wbr
元素进行分隔。
< p > So then she pointed at the tiger and screamed
"there< wbr > is< wbr > no< wbr > way< wbr > you< wbr > are< wbr > ever< wbr > going< wbr > to< wbr > catch< wbr > me"!</ p >
任何在wbr
元素内的内容都不应被视为周围文本的一部分。
var wbr = document. createElement( "wbr" );
wbr. textContent = "This is wrong" ;
document. body. appendChild( wbr);
该元素 具有涉及双向算法的渲染要求。
本节为非规范性内容。
元素 | 用途 | 示例 |
---|---|---|
a |
超链接 |
|
em |
强调重音 |
|
strong
|
重要性 |
|
small
|
附带评论 |
|
s |
不准确的文本 |
|
cite
|
作品标题 |
|
q |
引用 |
|
dfn
|
定义实例 |
|
abbr
|
缩写 |
|
ruby ,
rt , rp
|
注音标注 |
|
data
|
机器可读的等价物 |
|
time
|
日期或时间相关数据的机器可读等价物 |
|
code
|
计算机代码 |
|
var
|
变量 |
|
samp
|
计算机输出 |
|
kbd
|
用户输入 |
|
sub
|
下标 |
|
sup
|
上标 |
|
i |
替代声音 |
|
b |
关键词 |
|
u |
注解 |
|
mark
|
高亮 |
|
bdi
|
文本方向隔离 |
|
bdo
|
文本方向格式化 |
|
span
|
其他 |
|
br |
换行 |
|
wbr
|
换行机会 |
|
链接是一个概念性构造,通过 a
、area
、form
和 link
元素创建,这些元素
表示 两个资源之间的连接,其中一个是当前的 文档
。在 HTML 中有三种类型的链接:
这些链接指向需要用来增强当前文档的资源,通常由用户代理自动处理。所有 外部资源链接 都具有 获取和处理链接资源 算法,用于描述如何获取资源。
这些链接指向其他资源,通常由用户代理向用户公开,以便用户可以使用户代理 导航 到这些资源,例如访问它们或下载它们。
这些链接指向当前文档中的资源,用于赋予这些资源特殊的意义或行为。
对于具有 link
元素、href
属性和
rel
属性的链接,必须为
rel
属性的关键字创建链接,这些关键字在 链接类型 部分中定义。
类似地,对于具有 a
和
area
元素、href
属性和
rel
属性的链接,必须为 rel
属性的关键字创建链接,这些关键字在 链接类型 部分中定义。然而,与 link
元素不同的是,a
和
area
元素如果具有 href
属性,但没有 rel
属性,或者其 rel
属性没有定义为指定 超链接 的关键字,也必须创建一个 超链接。这种隐含的超链接没有特殊意义(它没有 链接类型),仅仅是将元素的 节点文档 链接到元素的 href
属性指定的资源。
类似地,对于具有 form
元素和
rel
属性的链接,必须为
rel
属性的关键字创建链接,这些关键字在 链接类型 部分中定义。没有 rel
属性的 form
元素,或者其
rel
属性没有定义为指定
超链接 的关键字,也必须创建一个 超链接。
一个 超链接 可以有一个或多个 超链接注解,这些注解修改该超链接的处理语义。
a
和 area
元素创建的链接href
属性在
a
和 area
元素上必须具有一个 有效的 URL,可能被空格包围 的值。
href
属性在 a
和 area
元素上不是必需的;当这些元素没有 href
属性时,它们不会创建超链接。
target
属性(如果存在)必须是 有效的可导航目标名称或关键字。它给出了将使用的 可导航目标 的名称。用户代理在
跟随超链接 时使用此名称。
download
属性(如果存在)表示作者打算将超链接用于 下载资源。该属性可以有一个值;如果有,该值指定作者建议用于在本地文件系统中标记资源的默认文件名。对允许的值没有限制,但作者应注意,大多数文件系统对文件名中支持的标点符号有限制,用户代理可能会相应地调整文件名。
所有当前引擎的支持。
ping
属性(如果存在)提供了希望在用户跟随超链接时收到通知的资源的 URL。其值必须是一个用空格分隔的令牌集合,每个令牌必须是一个有效的非空 URL,其方案必须是HTTP(S) 方案。该值由用户代理用于超链接审计。
rel
属性在a
和 area
元素上控制元素创建的链接类型。属性值必须是一个无序的唯一空格分隔令牌集合。允许的关键词及其含义在下文定义。
rel
的支持的令牌是HTML
链接类型中定义的允许在a
和 area
元素上使用的关键词,这些关键词影响处理模型,并由用户代理支持。可能的支持的令牌包括noreferrer
、noopener
和 opener
。rel
的支持的令牌必须仅包括用户代理实现处理模型的令牌。
rel
属性没有默认值。如果省略该属性,或者属性中的值都未被用户代理识别,则文档与目标资源之间没有特定的关系,只是两个之间存在一个超链接。
hreflang
属性在创建超链接的a
元素上(如果存在)提供了链接资源的语言。该属性仅供参考。其值必须是有效的 BCP 47 语言标签。[BCP47]
用户代理不应将该属性视为权威性——在获取资源时,用户代理必须仅使用与资源关联的语言信息来确定其语言,而不是链接中包含的元数据。
type
属性(如果存在)提供了链接资源的MIME 类型。该属性仅供参考。其值必须是有效的 MIME
类型字符串。用户代理不得将type
属性视为权威性——在获取资源时,用户代理不得使用链接中包含的元数据来确定其类型。
referrerpolicy
属性是一个referrer 策略属性。其目的是设置在跟随超链接时使用的referrer
策略。[REFERRERPOLICY]
当a
或 area
元素的激活行为 被触发时,用户代理可以允许用户表示是否希望将超链接用于导航,或者是否希望下载指定的资源。
在没有用户偏好的情况下,如果元素没有download
属性,则默认行为应为导航;如果元素具有该属性,则默认行为应为下载指定的资源。
一个a
或 area
元素的激活行为 在给定事件event 时为:
如果element没有href
属性,则返回。
将hyperlinkSuffix设为null。
将userInvolvement设为event的用户导航参与。
如果用户表示了下载超链接的偏好,则将userInvolvement设为"browser UI
"。
即,如果用户表示了特定的下载偏好,这不再被视为仅仅是"activation
"。
如果element具有download
属性,或者用户表示了下载超链接的偏好,则下载由element创建的超链接,将hyperlinkSuffix设为hyperlinkSuffix,将userInvolvement设为userInvolvement。
否则,跟随由element创建的超链接,将hyperlinkSuffix设为hyperlinkSuffix,将userInvolvement设为userInvolvement。
a
和
area
元素的 API
interface mixin HTMLHyperlinkElementUtils {
[CEReactions ] stringifier attribute USVString href ;
readonly attribute USVString origin ;
[CEReactions ] attribute USVString protocol ;
[CEReactions ] attribute USVString username ;
[CEReactions ] attribute USVString password ;
[CEReactions ] attribute USVString host ;
[CEReactions ] attribute USVString hostname ;
[CEReactions ] attribute USVString port ;
[CEReactions ] attribute USVString pathname ;
[CEReactions ] attribute USVString search ;
[CEReactions ] attribute USVString hash ;
};
hyperlink.toString()
hyperlink.href
所有当前引擎都支持。
所有当前引擎都支持。
所有当前引擎都支持。
所有当前引擎都支持。
返回超链接的 URL。
可以设置,以更改 URL。
hyperlink.origin
所有当前浏览器均支持。
所有当前浏览器均支持。
返回超链接的 URL 来源。
hyperlink.protocol
所有当前引擎都支持。
所有当前引擎都支持。
返回超链接 URL 的 scheme。
可以设置,以更改 URL 的 scheme。
hyperlink.username
所有当前引擎均支持。
所有当前引擎均支持。
返回超链接的 URL 的用户名。
可以设置,以更改 URL 的用户名。
hyperlink.password
所有当前引擎均支持。
所有当前引擎均支持。
返回超链接的 URL 的密码。
可以设置,以更改 URL 的密码。
hyperlink.host
所有当前引擎均支持。
所有当前引擎均支持。
返回超链接的 URL 的主机和端口(如果与 scheme 的默认端口不同)。
可以设置,以更改 URL 的主机和端口。
hyperlink.hostname
所有当前引擎均支持。
所有当前引擎均支持。
返回超链接的 URL 的主机。
可以设置,以更改 URL 的主机。
hyperlink.port
所有当前引擎均支持。
所有当前引擎均支持。
返回超链接的 URL 的端口。
可以设置,以更改 URL 的端口。
hyperlink.pathname
所有当前引擎均支持。
所有当前引擎均支持。
返回超链接的 URL 的路径。
可以设置,以更改 URL 的路径。
hyperlink.search
所有当前引擎均支持。
所有当前引擎均支持。
返回超链接的 URL 的查询(包括前导的 "?
",如果非空)。
可以设置,以更改 URL 的查询(忽略前导的 "?
")。
hyperlink.hash
所有当前引擎均支持。
所有当前引擎均支持。
返回超链接的 URL 的片段(包括前导的 "#
",如果非空)。
可以设置,以更改 URL 的片段(忽略前导的 "#
")。
实现了 HTMLHyperlinkElementUtils
mixin 的元素有一个关联的 url(为 null 或 URL)。初始值为 null。
实现了 HTMLHyperlinkElementUtils
mixin 的元素有一个关联的 设置 URL 算法,该算法执行以下步骤:
当实现了 HTMLHyperlinkElementUtils
mixin 的元素被创建时,以及每当这些元素的 href
内容属性被设置、修改或删除时,用户代理必须 设置 url。
这只对 blob:
URLs 可观察,因为 解析 它们涉及到一个 Blob URL 存储 查找。
实现了 HTMLHyperlinkElementUtils
mixin 的元素有一个关联的
重新初始化 url 算法,该算法执行以下步骤:
要 更新 href
,将元素的 href
内容属性的值设置为元素的 url,并进行
序列化。
href
获取器步骤如下:
返回 url,并进行 序列化。
href
设置器步骤如下:将 this 的 href
内容属性的值设置为给定的值。
origin
获取器步骤如下:
protocol
获取器步骤如下:
protocol
设置器步骤如下:
对给定值进行 基本 URL 解析,
后跟 ":
",使用 this 的 url 作为 url
和 scheme start
state 作为 state override。
因为 URL 解析器会忽略多个连续的冒号,所以提供 "https:
"(甚至 "https::::
")与提供
"https
" 是一样的。
username
获取器步骤如下:
username
设置器步骤如下:
password
获取器步骤如下:
password
设置器步骤如下:
host
获取器步骤如下:
如果 url 或 url 的 host 为 null, 返回空字符串。
host
设置器步骤如下:
如果 url 为 null 或 url 有一个 不透明路径,则 返回。
hostname
获取器步骤如下:
hostname
设置器步骤如下:
如果 url 为 null 或 url 有一个 不透明路径,则返回。
port
的getter步骤如下:
port
设置器步骤如下:
如果 url 为 null 或 url 不能包含用户名/密码/端口,则返回。
如果给定的值为空字符串,则将 url 的 端口 设置为 null。
pathname
获取器步骤如下:
pathname
设置器步骤如下:
search
获取器步骤如下:
search
设置器步骤如下:
如果 url 为 null,则终止这些步骤。
如果给定值为空字符串,则将 url 的 查询 设置为 null。
否则:
hash
获取器步骤如下:
hash
设置器步骤如下:
如果 url 为 null,则返回。
如果给定值为空字符串,则将 url 的 片段 设置为 null。
否则:
如果满足以下任意条件,则元素 element 不能导航:
这也被 表单提交 用于 form
元素。a
元素的例外是为了与网页内容兼容。
要 获取元素的 noopener,给定一个 a
、area
,或
form
元素 element 和一个字符串 target:
如果 element 的 链接类型 包含 noopener
或 noreferrer
关键字,则返回 true。
如果 element 的 链接类型 不包含 opener
关键字,并且 target 是对 "_blank
" 的 ASCII
不区分大小写 匹配,则返回 true。
返回 false。
要 跟随由元素 subject 创建的超链接,给定一个可选的 hyperlinkSuffix(默认值为 null)和一个可选的 userInvolvement(默认值为 "none
"):
如果 subject 不能导航,则返回。
将 replace 设置为 false。
将 targetAttributeValue 设置为空字符串。
如果 subject 是 a
或
area
元素,则将 targetAttributeValue 设置为 获取元素的目标 的结果,给定 subject。
将 noopener 设置为 获取元素的 noopener 的结果,使用 subject 和 targetAttributeValue。
将 targetNavigable 设置为应用 选择可导航对象的规则 的第一个返回值,给定 targetAttributeValue、subject 的 节点可导航性 和 noopener。
如果 targetNavigable 为 null,则返回。
将 urlString 设置为 编码-解析-序列化 URL 的结果,给定 subject
的 href
属性值,相对于 subject 的 节点文档。
如果 urlString 失败,则返回。
如果 hyperlinkSuffix 非 null,则将其附加到 urlString。
将 referrerPolicy 设置为 subject 的当前状态的 referrerpolicy
内容属性。
如果 subject 的 链接类型 包含 noreferrer
关键字,则将 referrerPolicy 设置为 "no-referrer
"。
导航 targetNavigable 到 urlString,使用 subject 的 节点文档,将 referrerPolicy 设置为 referrerPolicy,将 userInvolvement 设置为 userInvolvement。
与许多其他类型的导航不同,跟随超链接在文档未 完全加载 时没有特殊的 "replace
"
行为。这对于用户发起的跟随超链接实例以及通过例如 aElement.click()
触发的脚本也是如此。
所有当前引擎都支持。
在某些情况下,资源旨在用于稍后而不是立即查看。为了表示资源旨在被下载以便后续使用,而不是立即使用,可以在创建指向该资源的超链接的a
或area
元素上指定download
属性。
此外,属性还可以指定一个值,以指定用户代理在将资源存储在文件系统中时应使用的文件名。这个值可以被Content-Disposition
HTTP 头的文件名参数覆盖。[RFC6266]
在跨源情况下,download
属性必须与Content-Disposition
HTTP 头结合使用,特别是与attachment
处置类型,以避免用户被警告可能的恶意活动。(这是为了保护用户免于在没有完全理解的情况下下载敏感的个人或机密信息。)
要下载由元素subject创建的超链接,给定一个可选的hyperlinkSuffix(默认为null)和一个可选的userInvolvement(默认为"none
"):
如果subject 无法导航,则返回。
如果subject的节点文档的活动沙箱标志设置了沙箱下载浏览上下文标志,则返回。
让urlString成为编码、解析和序列化URL的结果,给定subject的href
属性值,相对于subject的节点文档。
如果urlString失败,则返回。
如果hyperlinkSuffix非空,则将其附加到urlString。
如果userInvolvement不是"browser UI
",则:
让filename成为subject的download
属性的值。
让continue成为在navigation上触发下载请求navigate
事件的结果,设置destinationURL为urlString,userInvolvement为userInvolvement,filename为filename。
如果continue为false,则返回。
并行执行以下步骤:
当用户代理需要将从fetch获取的资源作为下载处理时,如果成功获取资源,它应该提供一种方式让用户将资源保存以便后用。否则,它应该向用户报告任何下载文件时出现的问题。
如果用户代理需要为作为下载处理的资源选择一个文件名,它应使用以下算法。
该算法旨在减轻从不信任的网站下载文件的安全风险,强烈建议用户代理遵循此算法。
将filename设为未定义值。
如果资源有一个`Content-Disposition
`头部,该头部指定了attachment
处置类型,并且头部包含文件名信息,则将filename设为头部指定的值,然后跳转到下列sanitize步骤。[RFC6266]
将interface origin设为Document
中download或navigate操作发起的origin
,如果有的话。
将resource origin设为下载资源的URL的origin
,除非该URL的scheme
组件是data
,在这种情况下,将resource
origin设为interface origin,如果有的话。
如果没有interface origin,则将trusted operation设为true。否则,如果resource
origin与interface origin是相同来源
,则将trusted operation设为true,否则设为false。
如果trusted operation为true,并且资源有一个`Content-Disposition
`头部且头部包含文件名信息,则将filename设为头部指定的值,然后跳转到下列sanitize步骤。[RFC6266]
如果下载不是由a
或area
元素创建的超链接发起的,或者发起下载的超链接的元素在下载发起时没有download
属性,或者有该属性但其值在下载发起时为空字符串,则跳到标记为无建议文件名的步骤。
将proposed filename设为发起下载时hyperlink的`download
`属性的值。
如果trusted operation为true,则将filename设为proposed filename,然后跳转到下列sanitize步骤。
如果资源有一个`Content-Disposition
`头部且该头部指定了attachment
处置类型,则将filename设为proposed
filename,然后跳转到下列sanitize步骤。[RFC6266]
No proposed filename:如果trusted operation为true,或者用户表示希望下载该资源,则将filename的值从资源的URL中以实现定义的
方式派生,并跳转到下列sanitize步骤。
将filename设为用户的首选文件名或用户代理选择的文件名,然后跳转到下列sanitize步骤。
如果算法达到此步骤,则表示下载是从与资源来源不同的来源发起的,并且该来源没有标记文件为适合下载,并且下载不是由用户发起的。这可能是因为使用了`download
`属性来触发下载,或因为所涉及的资源不是用户代理支持的类型。
这可能是危险的,例如,恶意服务器可能试图让用户在不知情的情况下下载私人信息,并将其重新上传到恶意服务器,通过欺骗用户认为数据来自恶意服务器。
因此,用户的利益在于某种方式通知用户该资源来自完全不同的来源,并且为了防止混淆,任何潜在恶意的interface origin所建议的文件名应被忽略。
Sanitize:可选地,允许用户影响filename。例如,用户代理可以提示用户输入文件名,可能将上述确定的filename作为默认值。
将filename调整为适合本地文件系统的格式。
例如,这可能涉及去除文件名中不合法的字符,或修剪前导和尾随空白字符。
如果平台约定在任何方式上不使用扩展名来确定文件系统上的文件类型,则将filename作为文件名返回。
将claimed type设为资源的Content-Type元数据给出的类型(如果已知)。将named type设为filename的扩展名给出的类型(如果已知)。对于此步骤的目的,type是一个将MIME类型映射到扩展名的映射。
如果named type与用户的首选项一致(例如,因为filename的值是通过提示用户确定的),则将filename作为文件名返回。
如果claimed type和named type是相同的类型(即资源的Content-Type元数据与filename的扩展名给出的类型一致),则将filename作为文件名返回。
如果claimed type已知,则更改filename以添加与claimed type对应的扩展名。
否则,如果named
type已知为潜在危险(例如,平台约定将其视为本地可执行文件、shell脚本、HTML应用程序或可执行宏文档),则可选地更改filename以添加一个已知安全的扩展名(例如".txt
")。
最后一步可能使得无法下载可执行文件,这可能不是所期望的。正如往常一样,实现者必须在安全性和可用性之间做出平衡。
将filename作为文件名返回。
对于本算法的目的,文件扩展名指的是文件名中任何由平台约定用于识别文件类型的部分。例如,许多操作系统使用文件名中最后一个点(".
")之后的部分来确定文件的类型,并从中决定文件的打开或执行方式。
用户代理在决定将生成的文件存储在用户文件系统中的位置时,应忽略资源本身、其URL和任何download
属性提供的目录或路径信息。
如果由a
或area
元素创建的超链接具有ping
属性,并且用户跟随该超链接,而元素的href
属性的值可以相对于元素的节点文档进行解析,且解析不会失败,则用户代理必须获取ping
属性的值,在ASCII空白处拆分该字符串,相对于元素的节点文档,解析每个结果令牌,然后为每个结果URL
ping
URL运行这些步骤,忽略解析返回失败的情况:
如果ping URL的方案不是HTTP(S) 方案,则返回。
可选地,返回。(例如,用户代理可能希望根据用户表达的偏好忽略任何或所有 ping URL。)
让request成为一个新的请求,其URL是ping URL,方法是`POST
`,头部列表是
« (`Content-Type
`,
`text/ping
`)
»,主体是`PING
`,客户端是settingsObject,目标是空字符串,凭证模式是`include
`,引用者是`no-referrer
`,并且request的使用URL凭证标志被设置,且发起者类型是`ping
`。
让target URL成为对元素的href
属性的值,相对于元素的节点文档进行的编码-解析和序列化 URL的结果,然后:
获取 request。
这可以与主要获取操作并行进行,并且与该获取操作的结果无关。
用户代理应允许用户调整此行为,例如与禁用发送HTTP `Referer
`(如所写)头部的设置结合使用。根据用户的偏好,用户代理可以完全忽略 ping
属性,或者有选择地忽略列表中的URL(例如,忽略任何第三方URL);这在上述步骤中已明确考虑。
用户代理必须忽略响应中返回的任何实体主体。用户代理可以在开始接收响应主体后提前关闭连接。
当存在ping
属性时,用户代理应清楚地向用户指示,跟随该超链接还会在后台发送辅助请求,可能包括列出实际的目标URL。
例如,视觉用户代理可以在状态栏或工具提示中包含目标ping URL的主机名和超链接的实际URL。
ping
属性与现有技术如HTTP重定向和JavaScript在允许网页跟踪哪些外部链接最受欢迎或允许广告商跟踪点击率方面是冗余的。
然而,ping
属性为用户提供了相对于这些替代方案的以下优势:
因此,虽然可以在没有此功能的情况下跟踪用户,但鼓励作者使用ping
属性,以便用户代理可以使用户体验更透明。
Ping-From
` 和 `Ping-To
` 头部`Ping-From
` 和 `Ping-To
` HTTP 请求头部包含在超链接审计
请求中。它们的值是一个URL,序列化的。
所有当前引擎均支持。
下表总结了本规范定义的链接类型及其对应的关键词。此表为非规范性表格;实际的链接类型定义将在接下来的几节中给出。
在本节中,术语引用文档指的是由表示链接的元素标识的资源,而术语当前文档指的是表示链接的元素所在的资源。
要确定哪些链接类型适用于link
、a
、area
或form
元素,必须对元素的rel
属性进行ASCII 空格分割。生成的令牌即为适用于该元素的链接类型的关键词。
除非另有说明,否则每个rel
属性中不得指定重复的关键词。
一些表格下方的部分会列出某些关键词的同义词。所指示的同义词应按用户代理指定的方式处理,但不得在文档中使用(例如,关键词"copyright
")。
关键词总是ASCII 不区分大小写,并且必须按此方式进行比较。
因此,rel="next"
与rel="NEXT"
是相同的。
被标记为body-ok的关键词会影响link
元素是否可以出现在文档主体中。body-ok关键词包括dns-prefetch
、modulepreload
、pingback
、preconnect
、prefetch
、preload
和 stylesheet
。
需要由网页浏览器实现的新链接类型将被添加到此标准中。其余类型可以注册为扩展。
链接类型 | 对...的影响 | body-ok | 有 `Link `
处理 |
简要描述 | ||
---|---|---|---|---|---|---|
link
|
a 和 area |
form
|
||||
alternate |
超链接 | 不允许 | · | · | 提供当前文档的替代表示。 | |
canonical
|
超链接 | 不允许 | · | · | 提供当前文档的首选 URL。 | |
author
|
超链接 | 不允许 | · | · | 提供指向当前文档或文章作者的链接。 | |
bookmark
|
不允许 | 超链接 | 不允许 | · | · | 提供最近的祖先部分的永久链接。 |
dns-prefetch
|
外部资源 | 不允许 | 是 | · | 指定用户代理应预先执行目标资源的 来源 的 DNS 解析。 | |
expect
|
内部资源 | 不允许 | · | · | 期望当前文档中会出现目标 ID 的元素。 | |
external
|
不允许 | 注释 | · | · | 指示引用的文档不属于与当前文档相同的网站。 | |
help |
超链接 | · | · | 提供上下文相关帮助的链接。 | ||
icon |
外部资源 | 不允许 | · | · | 导入表示当前文档的图标。 | |
manifest
|
外部资源 | 不允许 | · | · | 导入或链接到 应用程序清单。[MANIFEST] | |
modulepreload
|
外部资源 | 不允许 | 是 | · | 指定用户代理必须预先获取模块脚本并将其存储在文档的模块映射中以供后续评估。可选地,模块的依赖项也可以被获取。 | |
license
|
超链接 | · | · | 指示当前文档的主要内容受所引用文档中描述的版权许可证的覆盖。 | ||
next |
超链接 | · | · | 指示当前文档是一个系列的一部分,下一个文档是所引用的文档。 | ||
nofollow
|
不允许 | 注释 | · | · | 指示当前文档的原始作者或发布者不认可所引用的文档。 | |
noopener
|
不允许 | 注释 | · | · | 如果超链接会创建一个辅助的顶级可遍历项,则创建一个非辅助浏览上下文(即具有合适的目标 属性值)。
|
|
noreferrer
|
不允许 | 注释 | · | · | 不会包含 `Referer `
(sic) 头。此外,具有与noopener 相同的效果。
|
|
opener
|
不允许 | 注释 | · | · | 如果超链接会创建一个具有非辅助浏览上下文(即具有“_blank ”作为目标 属性值)的顶级可遍历项,则创建一个辅助浏览上下文。 |
|
pingback
|
外部资源 | 不允许 | 是 | · | 提供处理当前文档的 pingback 的 pingback 服务器地址。 | |
preconnect
|
外部资源 | 不允许 | 是 | 是 | 指定用户代理应预先连接到目标资源的来源。 | |
prefetch
|
外部资源 | 不允许 | 是 | · | 指定用户代理应预先获取并缓存目标资源,因为它可能会在后续的导航中需要。 | |
preload
|
外部资源 | 不允许 | 是 | 是 | 指定用户代理必须预先获取并缓存目标资源,以便根据as 属性给出的潜在目的地(以及与相应的请求目的地相关联的优先级)进行当前导航。 |
|
prev |
超链接 | · | · | 指示当前文档是一个系列的一部分,前一个文档是所引用的文档。 | ||
privacy-policy
|
超链接 | 不允许 | · | · | 提供有关当前文档适用的数据收集和使用实践的信息链接。 | |
search
|
超链接 | · | · | 提供指向可用于搜索当前文档及其相关页面的资源的链接。 | ||
stylesheet
|
外部资源 | 不允许 | 是 | · | 导入样式表。 | |
tag |
不允许 | 超链接 | 不允许 | · | · | 提供适用于当前文档的标签(由给定地址标识)。 |
terms-of-service
|
超链接 | 不允许 | · | · | 提供指向有关当前文档提供者与希望使用当前文档的用户之间的协议的信息的链接。 |
alternate
"仅在一个引擎中支持。
alternate
关键字可以与
link
、a
和 area
元素一起使用。
这个关键字的含义取决于其他属性的值。
link
元素且
rel
属性也包含 stylesheet
关键字
alternate
关键字会修改 stylesheet
关键字的含义,如该关键字的描述所示。alternate
关键字不会创建自己的链接。
这里,一组 link
元素提供了一些样式表:
<!-- a persistent style sheet -->
< link rel = "stylesheet" href = "default.css" >
<!-- the preferred alternate style sheet -->
< link rel = "stylesheet" href = "green.css" title = "Green styles" >
<!-- some alternate style sheets -->
< link rel = "alternate stylesheet" href = "contrast.css" title = "High contrast" >
< link rel = "alternate stylesheet" href = "big.css" title = "Big fonts" >
< link rel = "alternate stylesheet" href = "wide.css" title = "Wide screen" >
alternate
关键字与
type
属性的值设置为 application/rss+xml
或 application/atom+xml
一起使用
这个关键字创建了一个 超链接,引用了一个聚合源(虽然不一定与当前页面聚合完全相同的内容)。
为了进行源自动发现,用户代理应考虑文档中所有使用 link
元素且
alternate
关键字的元素,以及其 type
属性设置为 application/rss+xml
或 application/atom+xml
的元素。如果用户代理有默认的聚合源概念,第一个这样的元素(按 树顺序)应作为默认。
以下 link
元素为博客提供了聚合源:
< link rel = "alternate" type = "application/atom+xml" href = "posts.xml" title = "Cool Stuff Blog" >
< link rel = "alternate" type = "application/atom+xml" href = "posts.xml?category=robots" title = "Cool Stuff Blog: robots category" >
< link rel = "alternate" type = "application/atom+xml" href = "comments.xml" title = "Cool Stuff Blog: Comments" >
这样的 link
元素会被用于源自动发现,首先的元素(在适用情况下)作为默认。
以下示例提供了各种不同的聚合源给用户,使用了 a
元素:
< p > You can access the planets database using Atom feeds:</ p >
< ul >
< li >< a href = "recently-visited-planets.xml" rel = "alternate" type = "application/atom+xml" > Recently Visited Planets</ a ></ li >
< li >< a href = "known-bad-planets.xml" rel = "alternate" type = "application/atom+xml" > Known Bad Planets</ a ></ li >
< li >< a href = "unexplored-planets.xml" rel = "alternate" type = "application/atom+xml" > Unexplored Planets</ a ></ li >
</ ul >
这些链接不会用于 feed 自动发现。
该关键词创建一个引用当前文档的备用表示形式的超链接。
如果alternate
关键词与hreflang
属性一起使用,并且该属性的值与文档元素的语言不同,则表示引用的文档是一个翻译版本。
如果alternate
关键词与type
属性一起使用,则表示引用的文档是当前文档在指定格式中的重新表述。
当使用alternate
关键词时,hreflang
和type
属性可以组合使用。
以下示例展示了如何指定使用替代格式、面向其他语言和其他媒体的页面版本:
< link rel = alternate href = "/en/html" hreflang = en type = text/html title = "English HTML" >
< link rel = alternate href = "/fr/html" hreflang = fr type = text/html title = "French HTML" >
< link rel = alternate href = "/en/html/print" hreflang = en type = text/html media = print title = "English HTML (for printing)" >
< link rel = alternate href = "/fr/html/print" hreflang = fr type = text/html media = print title = "French HTML (for printing)" >
< link rel = alternate href = "/en/pdf" hreflang = en type = application/pdf title = "English PDF" >
< link rel = alternate href = "/fr/pdf" hreflang = fr type = application/pdf title = "French PDF" >
此关系是可传递的——即,如果一个文档链接到两个具有"alternate
"链接类型的其他文档,那么,除了意味着这些文档是第一个文档的备用表示之外,还意味着这两个文档也是彼此的备用表示。
author
"author
关键字可以与 link
、a
和 area
元素一起使用。这个关键字创建一个 超链接。
对于 a
和
area
元素,author
关键字表示所引用的文档提供有关定义超链接的元素最近的 article
元素祖先的更多信息(如果有的话),否则提供有关整个页面的信息。
对于 link
元素,author
关键字表示所引用的文档提供有关整个页面的作者的更多信息。
"引用的文档" 可以是(并且通常是)一个 mailto:
URL,提供作者的电子邮件地址。 [MAILTO]
同义词:出于历史原因,用户代理还必须将具有 rev
属性值为 "made
" 的 link
、a
和 area
元素视为具有 author
关键字指定的链接关系。
bookmark
"bookmark
关键字可以与 a
和
area
元素一起使用。这个关键字创建一个 超链接。
bookmark
关键字为链接元素的最近祖先article
元素或链接元素最密切相关的部分提供永久链接,如果没有祖先article
元素。
以下代码段有三个永久链接。用户代理可以通过查看永久链接的位置来确定哪个永久链接适用于规范的哪个部分。
...
< body >
< h1 > Example of permalinks</ h1 >
< div id = "a" >
< h2 > First example</ h2 >
< p >< a href = "a.html" rel = "bookmark" > This permalink applies to
only the content from the first H2 to the second H2</ a > . The DIV isn't
exactly that section, but it roughly corresponds to it.</ p >
</ div >
< h2 > Second example</ h2 >
< article id = "b" >
< p >< a href = "b.html" rel = "bookmark" > This permalink applies to
the outer ARTICLE element</ a > (which could be, e.g., a blog post).</ p >
< article id = "c" >
< p >< a href = "c.html" rel = "bookmark" > This permalink applies to
the inner ARTICLE element</ a > (which could be, e.g., a blog comment).</ p >
</ article >
</ article >
</ body >
...
canonical
"canonical
关键字可以与 link
元素一起使用。这个关键字创建一个 超链接。
canonical
关键字表示由 href
属性给出的 URL 是当前文档的首选 URL。 这有助于搜索引擎减少重复内容,详细描述见 The Canonical
Link Relation。 [RFC6596]
dns-prefetch
"The dns-prefetch
关键字可以与
link
元素一起使用。此关键字创建一个外部资源链接。此关键字是body-ok。
The dns-prefetch
关键字表示,预先为指定资源的源执行DNS解析可能是有益的,因为用户很可能需要位于该源的资源,预先解决DNS解析的延迟成本将改善用户体验。
对于 dns-prefetch
关键字,没有默认的资源类型。
适合获取和处理此类链接的时间是:
此类型链接资源的获取和处理步骤,给定一个link
元素el,如下:
expect
"expect
关键字可用于link
元素。此关键字创建一个内部资源链接。
由expect
关键字创建的内部资源链接可以用来阻止渲染,直到它指示的元素连接到文档并完全解析。
expect
关键字没有默认的资源类型。
当link
元素el发生以下任何情况时:
然后处理el。
为了给定一个link
元素el处理内部资源链接,执行以下步骤:
让doc成为el的节点文档。
让indicatedElement成为给定doc和url选择指示部分的结果。
如果以下所有条件都为真:
然后阻止渲染el。
否则,取消阻止渲染el。
为了给定一个文档
doc处理内部资源链接:
以下属性更改步骤,给定element、localName、value和namespace,用于确保expect
link
元素响应动态id
和name
更改:
如果namespace不为null,则返回。
如果以下任一条件为真:
external
"external
关键字可用于a
、area
和form
元素。此关键字不会创建超链接,但会注释由该元素创建的任何其他超链接(如果没有其他关键字创建,则为隐含超链接)。
external
关键字表示该链接指向的文档不属于当前文档所在网站的一部分。
help
"help
关键字可用于link
、a
、area
和form
元素。此关键字创建一个超链接。
对于a
、area
和form
元素,help
关键字表示引用的文档为定义超链接的元素的父元素及其子元素提供进一步的帮助信息。
在以下示例中,表单控件具有相关的上下文帮助。例如,当用户按下“帮助”或“F1”键时,用户代理可以使用此信息显示引用的文档。
< p >< label > 主题: < input name = topic > < a href = "help/topic.html" rel = "help" > (帮助)</ a ></ label ></ p >
对于link
元素,help
关键字表示引用的文档为整个页面提供帮助。
对于a
和area
元素,在某些浏览器中,help
关键字会使链接使用不同的光标。
icon
"Support in all current engines.
icon
关键字可用于link
元素。此关键字创建一个外部资源链接。
指定的资源是代表页面或网站的图标,应该由用户代理在用户界面中代表页面时使用。
图标可以是听觉图标、视觉图标或其他类型的图标。如果提供了多个图标,用户代理必须根据type
、media
和sizes
属性选择最合适的图标。如果有多个同样合适的图标,用户代理必须使用在用户代理收集图标列表时树顺序中最后声明的图标。如果用户代理尝试使用一个图标但在进一步检查时发现该图标实际上不合适(例如,因为它使用了不支持的格式),那么用户代理必须尝试下一个根据属性确定的最合适的图标。
用户代理不要求在图标列表更改时更新图标,但鼓励这样做。
icon
关键字没有默认的资源类型。然而,为了确定资源类型,用户代理必须期望资源是图像。
sizes
关键字表示图标的原始像素大小(相对于CSS 像素)。
一个宽度为50 CSS 像素的图标,适用于每个CSS 像素具有两个设备像素(2x,192dpi)的显示器,其宽度为100原始像素。此功能不支持指示在小高分辨率图标与大低分辨率图标之间使用不同的资源(例如50×50 2x与100×100 1x)。
要解析和处理属性的值,用户代理必须首先在ASCII空白处拆分属性的值,然后必须解析每个结果关键字以确定它代表什么。
any
关键字表示资源包含一个可缩放的图标,例如由SVG图像提供的图标。
其他关键字必须进一步解析如下,以确定它们代表什么:
如果关键字不包含一个U+0078拉丁小写字母x或U+0058拉丁大写字母X字符,则此关键字不代表任何内容。返回该关键字。
令width string为"x
"或"X
"之前的字符串。
令height string为"x
"或"X
"之后的字符串。
如果width string或height string以U+0030数字零(0)字符开头或包含除ASCII数字以外的任何字符,则此关键字不代表任何内容。返回该关键字。
应用解析非负整数的规则到width string以获得width。
应用解析非负整数的规则到height string以获得height。
关键字表示资源包含一个宽度为width设备像素、高度为height设备像素的位图图标。
sizes
属性中指定的关键字不得表示实际不可用的图标大小。
对于给定的link
元素el和请求request,这种类型的链接资源的链接资源获取设置步骤为:
设置request的目的地为"image
"。
返回true。
这种类型的链接资源的处理链接头步骤不执行任何操作。
在没有带有link
的icon
关键字的情况下,对于HTTP(S)协议的Document
对象,用户代理可以改为并行运行以下步骤:
让request成为一个新的请求,其URL是通过将URL记录解析为"/favicon.ico
"而获得的URL,相对于Document
对象的URL,客户端是Document
对象的相关设置对象,目的地为"image
",同步标志被设置,凭证模式为"include
",并且使用URL凭证标志被设置。
令response为获取request的结果。
以下代码片段显示了带有多个图标的应用程序顶部部分。
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< title > lsForums — Inbox</ title >
< link rel = icon href = favicon.png sizes = "16x16" type = "image/png" >
< link rel = icon href = windows.ico sizes = "32x32 48x48" type = "image/vnd.microsoft.icon" >
< link rel = icon href = mac.icns sizes = "128x128 512x512 8192x8192 32768x32768" >
< link rel = icon href = iphone.png sizes = "57x57" type = "image/png" >
< link rel = icon href = gnome.svg sizes = "any" type = "image/svg+xml" >
< link rel = stylesheet href = lsforums.css >
< script src = lsforums.js ></ script >
< meta name = application-name content = "lsForums" >
</ head >
< body >
...
由于历史原因,icon
关键字前面可能有关键字"shortcut
"。如果存在"shortcut
"关键字,则rel
属性的整个值必须与字符串"shortcut icon
"(在标记之间有一个U+0020空格字符,没有其他ASCII空白)进行ASCII不区分大小写匹配。
license
"license
关键字可用于link
、a
、area
和form
元素。此关键字创建一个超链接。
license
关键字表示引用的文档提供了当前文档主要内容所依据的版权许可条款。
本规范未规定如何区分文档的主要内容和不被视为主要内容的部分。区分应向用户明确。
考虑一个照片分享网站。该网站上的页面可能描述和展示照片,页面标记如下:
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< title > Exampl Pictures: Kissat</ title >
< link rel = "stylesheet" href = "/style/default" >
</ head >
< body >
< h1 > Kissat</ h1 >
< nav >
< a href = "../" > Return to photo index</ a >
</ nav >
< figure >
< img src = "/pix/39627052_fd8dcd98b5.jpg" >
< figcaption > Kissat</ figcaption >
</ figure >
< p > One of them has six toes!</ p >
< p >< small >< a rel = "license" href = "http://www.opensource.org/licenses/mit-license.php" > MIT Licensed</ a ></ small ></ p >
< footer >
< a href = "/" > Home</ a > | < a href = "../" > Photo index</ a >
< p >< small > © copyright 2009 Exampl Pictures. All Rights Reserved.</ small ></ p >
</ footer >
</ body >
</ html >
在这种情况下,license
适用于照片(文档的主要内容),而不是整个文档。特别是页面设计的版权,页面底部给出了版权声明。这可以通过样式使其更清楚(例如,将许可证链接突出显示在照片附近,而页面底部的版权信息则使用小字体和淡色显示)。
同义词:由于历史原因,用户代理还必须将关键字"copyright
"视为license
关键字。
manifest
"仅在一个引擎中支持。
manifest
关键字可以用于 link
元素。这个关键字创建一个 外部资源链接。
manifest
关键字指示提供与当前文档相关的元数据的清单文件。
由 manifest
关键字指定的资源没有默认类型。
当Web应用程序未 安装 时,适当的时间来 获取和处理链接资源 类型的链接是当用户代理认为有必要时。例如,当用户选择 安装Web应用程序 时。
对于已 安装的Web应用程序,适当的时间来 获取和处理链接资源 类型的链接是:
在任何情况下,只有第一个 link
元素在 树顺序 中,其 rel
属性包含 manifest
标记,才能被使用。
用户代理不得为了这种链接类型 延迟加载事件。
对于这种类型的链接资源,给定一个 link
元素 el 和 请求 request,链接资源获取设置步骤 是:
如果 navigable 为空,则返回 false。
如果 navigable 不是 顶级可遍历,则返回 false。
将 request 的 发起者 设置为
"manifest
"。
将 request 的 目标
设置为 "manifest
"。
将 request 的 模式 设置为
"cors
"。
将 request 的 凭据模式 设置为 el 的 crossorigin
内容属性的 CORS设置属性凭据模式。
返回 true。
要 处理这种类型的链接资源 给定一个
link
元素 el、布尔值 success、响应 response 和 字节序列 bodyBytes:
如果 response 的 Content-Type元数据 不是 JSON MIME类型,则将 success 设置为 false。
如果 success 为 true:
让 manifest URL 成为 response 的 URL。
处理清单 给定 document URL、manifest URL 和 bodyBytes。[MANIFEST]
对于这种类型的链接资源,处理链接头 步骤是无操作。
modulepreload
"modulepreload
关键字可以用于 link
元素。这个关键字创建一个 外部资源链接。这个关键字是
body-ok。
modulepreload
关键字是 preload
关键字的专业替代,具有针对预加载 模块脚本
的处理模型。特别是,它使用特定的模块脚本获取行为(包括,例如,对 crossorigin
属性的不同解释),并将结果放入适当的 模块映射 中以便稍后评估。相比之下,使用 preload
关键字的类似 外部资源链接
会将结果放入预加载缓存中,而不会影响文档的 模块映射。
此外,实现可以利用 模块脚本
声明其依赖关系的事实来预先获取指定模块的依赖关系。这被视为一种优化机会,因为用户代理知道,很可能稍后也需要这些依赖关系。通常情况下,除非使用诸如service
workers之类的技术或在服务器端进行监控,否则不会察觉。值得注意的是,适当的 load
或 error
事件将在指定模块被获取后发生,不会等待任何依赖关系。
用户代理不得为了这种链接类型 延迟加载事件。
适当的时间来 获取和处理链接资源 类型的链接是:
与其他一些链接关系不同,更改这些 as
、crossorigin
和 referrerpolicy
相关属性不会触发新获取。这是因为文档的 模块映射 已经被之前的获取填充,因此重新获取毫无意义。
获取和处理链接资源 算法用于 modulepreload
链接,给定一个 link
元素 el,其步骤如下:
如果 el 的 href
属性的值为空字符串,则返回。
让 destination 成为 el 的 as
属性的当前状态(一个 目标),或者如果它没有状态,则为 "script
"。
如果 destination 不是 类似脚本的,则在 排队一个元素任务 上,在给定 el 的 网络任务源 上 触发一个事件 名为 error
在
el 上,并返回。
如果 url 失败,则返回。
让 credentials mode 成为 el 的 crossorigin
属性的 CORS设置属性凭据模式。
让 cryptographic nonce 成为 el.[[CryptographicNonce]]。
让 integrity metadata 成为 el 的 integrity
属性的值,如果指定的话,否则为空字符串。
如果 el 没有 integrity
属性,则将 integrity metadata 设置为 解析模块完整性元数据 的结果,给定 url 和
settings object。
让 referrer policy 成为 el 的 referrerpolicy
属性的当前状态。
让 fetch priority 成为 el 的 fetchpriority
属性的当前状态。
让 options 成为 脚本获取选项,其 密码随机数 为 cryptographic
nonce,完整性元数据 为 integrity
metadata,解析器元数据 为
"not-parser-inserted
",凭据模式 为 credentials
mode,引用策略 为 referrer
policy,获取优先级 为 fetch
priority。
获取一个modulepreload模块脚本图,给定 url,destination,settings object,options,并使用以下步骤,给定 result:
对于这种类型的链接资源,处理链接头 步骤是无操作。
以下代码段显示了具有多个模块预加载的应用程序的顶部部分:
<!DOCTYPE html>
< html lang = "en" >
< title > IRCFog</ title >
< link rel = "modulepreload" href = "app.mjs" >
< link rel = "modulepreload" href = "helpers.mjs" >
< link rel = "modulepreload" href = "irc.mjs" >
< link rel = "modulepreload" href = "fog-machine.mjs" >
< script type = "module" src = "app.mjs" >
...
假设应用程序的模块图如下所示:
这里我们看到应用程序开发人员使用 modulepreload
声明其模块图中的所有模块,确保用户代理发起对它们的获取。没有这种预加载,用户代理可能需要进行多次网络往返才能发现
helpers.mjs
,如果没有诸如HTTP/2服务器推送之类的技术。这种方式,modulepreload
link
元素可以用作应用程序模块的 "manifest"。
以下代码显示了如何将 modulepreload
链接与 import()
结合使用,以确保网络获取提前完成,因此当调用 import()
时,模块已经在 模块映射
中准备就绪(但未评估):
< link rel = "modulepreload" href = "awesome-viewer.mjs" >
< button onclick = "import('./awesome-viewer.mjs').then(m => m.view())" >
View awesome thing
</ button >
nofollow
"nofollow
关键字可以用于 a
、area
和
form
元素。这个关键字不会创建一个 超链接,而是 注释
任何其他由元素创建的超链接(如果没有其他关键字创建超链接,则为隐含的超链接)。
nofollow
关键字表示链接不被页面的原始作者或出版者认可,或者链接到引用的文档主要是由于两个页面的相关人员之间的商业关系而包含的。
noopener
"所有当前引擎均支持。
所有当前引擎均支持。
noopener
关键字可以用于 a
、area
和
form
元素。这个关键字不会创建一个 超链接,而是 注释
任何其他由元素创建的超链接(如果没有其他关键字创建超链接,则为隐含的超链接)。
这个关键字表示,通过遵循 超链接 生成的任何新创建的
顶级可遍历
不会包含 辅助浏览上下文。例如,结果
Window
的 opener
获取器将返回 null。
另见 处理模型。
这通常会创建一个带有 辅助浏览上下文
的 顶级可遍历(假设不存在目标名称为
"example
" 的现有 可导航):
< a href = help.html target = example > Help!</ a >
这会创建一个不带有 辅助浏览上下文 的 顶级可遍历(假设相同情况):
< a href = help.html target = example rel = noopener > Help!</ a >
这些是等效的,仅导航 父可导航:
< a href = index.html target = _parent > Home</ a >
< a href = index.html target = _parent rel = noopener > Home</ a >
noreferrer
"
所有当前引擎均支持。
所有当前引擎均支持。
noreferrer
关键字可以用于 a
、area
和
form
元素。这个关键字不会创建一个 超链接,而是 注释
任何其他由元素创建的超链接(如果没有其他关键字创建超链接,则为隐含的超链接)。
它表示在跟随链接时不会泄露任何引用信息,并且还暗示在相同条件下 noopener
关键字的行为。
另见直接操作引用的 处理模型。
<a href="..." rel="noreferrer" target="_blank">
与
<a href="..." rel="noreferrer noopener" target="_blank">
具有相同的行为。
opener
"opener
关键字可以用于 a
、area
和
form
元素。这个关键字不会创建一个 超链接,而是 注释
任何其他由元素创建的超链接(如果没有其他关键字创建超链接,则为隐含的超链接)。
这个关键字表示,通过遵循 超链接 生成的任何新创建的 顶级可遍历 将包含一个 辅助浏览上下文。
另见 处理模型。
在以下示例中,opener
用于允许帮助页面弹出窗口导航其打开者,例如,当用户正在寻找的内容可以在其他地方找到时。一种替代方法可能是使用命名目标,而不是 _blank
,但这可能会与现有名称冲突。
< a href = "..." rel = opener target = _blank > Help!</ a >
pingback
"pingback
关键字可以用于 link
元素。这个关键字创建一个 外部资源链接。这个关键字是 body-ok。
关于 pingback
关键字的语义,请参见 Pingback 1.0。[PINGBACK]
preconnect
"
所有当前引擎均支持。
preconnect
关键字可以用于 link
元素。这个关键字创建一个 外部资源链接。这个关键字是 body-ok。
preconnect
关键字表示预先与指定资源的 源
建立连接可能是有利的,因为用户很可能需要位于该 源
的资源,通过预先解决与建立连接相关的延迟成本可以改善用户体验。
没有资源类型的默认类型由 preconnect
关键字指定。
用户代理不得因这种链接类型 延迟加载事件。
合适的 获取和处理 此类链接的时机是:
当已经 浏览上下文连接 的
外部资源链接 的 link
元素的 crossorigin
属性被设置、改变或移除时。
获取和处理此类型链接资源 的步骤,给定一个 link
元素 el,是 从 el 创建链接选项 并给定结果进行 预连接。
对于这种类型的链接资源,给定 链接处理选项 options 的 处理链接头 步骤是给定 options 进行 预连接。
给定 链接处理选项 options 进行 预连接:
如果 options 的 href 为空字符串,则返回。
给定 options 的 href 和 options 的 基本URL,进行 编码-解析 URL 并得到 url。
将基本URL传递而不是文档或环境是由 issue #9715 追踪的。
如果 url 解析失败,则返回。
如果 url 的 方案 不是 HTTP(S) 方案,则返回。
给定 options 的 环境,确定网络分区键并得到 partitionKey。
设定 useCredentials 为 true。
如果 options 的 crossorigin 是 匿名 并且 options 的 origin 与 url 的 origin 不同源,则设定 useCredentials 为 false。
用户代理应尝试给定 partitionKey、url 的 origin 和 useCredentials,获取连接。
此连接已获取但未直接使用。它将保留在 连接池 中以供后续使用。
用户代理应尽可能尝试启动预连接并执行完整的连接握手(HTTP 为 DNS+TCP,HTTPS 源为 DNS+TCP+TLS),但由于资源限制或其他原因,允许选择执行部分握手(HTTP 仅为 DNS,HTTPS 源为 DNS 或 DNS+TCP),或完全跳过。
每个源的最佳连接数取决于协商协议、用户当前的连接配置文件、可用设备资源、全局连接限制和其他特定上下文变量。因此,多少连接应打开的决定由用户代理决定。
prefetch
"prefetch
关键字可以用于 link
元素。这个关键字创建一个 外部资源链接。这个关键字是 body-ok。
prefetch
关键字表示预先 获取 和缓存指定的资源或同站点文档可能是有益的,因为用户很可能会在将来导航中需要此资源。
没有资源类型的默认类型由 prefetch
关键字指定。
合适的 获取和处理 此类链接的时机是:
当已经 浏览上下文连接 的 外部资源链接 的 link
元素的 crossorigin
属性被设置、改变或移除时。
获取和处理此类型链接资源 的算法,给定一个 link
元素 el,如下:
如果 el 的 href
属性的值为空字符串,则返回。
将 options 设为 从 el 创建链接选项 的结果。
设定 options 的 destination 为空字符串。
将 request 设为 创建一个链接请求 并给定 options 的结果。
如果 request 为 null,则返回。
设定 request 的 initiator
为 "prefetch
"。
将 processPrefetchResponse 设为以下步骤,给定 响应 response 和 null、失败或 字节序列 bytesOrNull:
用户代理应 获取 request,并将 processResponseConsumeBody 设为 processPrefetchResponse。用户代理可以延迟获取 request 以优先处理当前文档所需的其他请求。
处理链接头 步骤对于这种类型的链接资源是无操作。
preload
"Support in one engine only.
preload
关键字可以用于 link
元素。这个关键字创建一个 外部资源链接。这个关键字是 body-ok。
preload
关键字表示用户代理会根据 as
属性给出的 潜在目的地
和 fetchpriority
属性给出的 优先级 预先 获取 和缓存指定的资源,因为用户很可能需要该资源用于当前导航。
用户代理在加载资源时可能会执行额外的操作,例如预先 解码图片 或 创建样式表。但是,这些额外的操作不能有可观察的效果。
没有资源类型的默认类型由 preload
关键字指定。
用户代理不得为了这种链接类型 延迟加载事件。
合适的 获取和处理 此类链接的时机是:
当已经 浏览上下文连接 的 外部资源链接 的 link
元素的 type
属性被设置、移除或改变时,而之前由于 type
属性指定的请求 目的地
不支持的类型导致资源未被获取。
当已经 浏览上下文连接 的 外部资源链接 的 link
元素的 media
属性被改变或移除时,而之前由于 media
属性不 匹配环境 导致资源未被获取。
Document
有一个 预加载资源的映射,这是一个 有序映射,初始为空。
same-origin
"、"cors
" 或
"no-cors
"
要 消费一个预加载的资源 给 Window
window,给定一个
URL
url、一个字符串 destination、一个字符串 mode、一个字符串 credentialsMode、一个字符串
integrityMetadata 和 onResponseAvailable,这是一个接受 响应 的算法:
让 key 成为一个 预加载键,其 URL 是 url,目的地 是 destination,模式 是 mode,凭证模式 是 credentialsMode。
让 preloads 成为 window 的 关联的 Document
的 预加载资源的映射。
如果 key 不 存在 于 preloads 中,则返回 false。
让 entry 成为 preloads[key]。
让 consumerIntegrityMetadata 成为 解析 integrityMetadata 的结果。
如果以下条件都不适用:
consumerIntegrityMetadata 是 no metadata
;
consumerIntegrityMetadata 等于 preloadIntegrityMetadata;
此比较将忽略未知的完整性选项。参见 问题 #116。
则返回 false。
预加载和消费者之间完整性元数据的差异,即使两者都匹配数据,也会导致从网络重新请求资源。
将网络错误添加到预加载缓存中是很重要的,因此如果预加载请求导致错误,错误的响应不会在稍后从网络重新请求。这也有安全方面的影响;考虑一个开发人员在预加载请求上指定了子资源完整性元数据,但在随后的资源请求上没有。如果预加载请求未通过子资源完整性验证并被丢弃,资源请求将从网络获取并使用潜在的恶意响应,而不验证其完整性。[SRI]
移除 preloads[key]。
否则,用 entry 的 响应 调用 onResponseAvailable。
返回 true。
为此部分,字符串 type 若满足以下算法,则 匹配 字符串 destination:
如果 type 是空字符串,则返回 true。
如果 destination 是 "fetch
",则返回 true。
让 mimeTypeRecord 成为 解析 type 的结果。
如果 mimeTypeRecord 是失败,则返回 false。
如果 mimeTypeRecord 不是 用户代理支持的,则返回 false。
如果以下任何一个为真:
destination 是 "audio
" 或 "video
",并且 mimeTypeRecord 是 音频或视频 MIME 类型;
destination 是 类脚本目的地,并且 mimeTypeRecord 是 JavaScript MIME 类型;
destination 是 "image
",并且 mimeTypeRecord 是 图片 MIME 类型;
destination 是 "font
",并且 mimeTypeRecord 是 字体 MIME 类型;
destination 是 "json
",并且 mimeTypeRecord 是 JSON MIME 类型;
则返回 true。
返回 false。
要为一个 请求 request 创建一个预加载键,返回一个新的 预加载键,其 URL 是 request 的 URL,目的地 是 request 的 目的地,模式 是 request 的 模式,并且 凭证模式 是 request 的 凭证模式。
要 给定一个字符串 destination 翻译预加载目的地:
如果 destination 不是
"fetch
"、"font
"、"image
"、"script
"、"style
" 或
"track
",则返回 null。
返回 翻译 destination 的结果。
要 预加载 给定一个 链接处理选项 options 和一个可选的 processResponse,这是一个接受 响应 的算法:
如果 options 的 目的地 是 "image
" 并且 options 的 源集
不是
null,则将 options 的 href 设置为
选择一个图片源 从 options 的 源集。
让 request 成为 创建一个链接请求 给定 options 的结果。
如果 request 为 null,则返回。
让 unsafeEndTime 为 0。
让 key 成为 创建一个预加载键 给定 request 的结果。
如果 options 的 文档 是
"pending
",则将 request 的 发起者类型 设置为 "early hint
"。
让 controller 为 null。
让 reportTiming 给定一个 Document
document 为 报告计时 给
document 的 相关全局对象。
将 controller 设置为 获取 request 的结果,其中 processResponseConsumeBody 设置为以下步骤,给定一个 响应 response 和 null、失败或一个 字节序列 bodyBytes:
如果 bodyBytes 是一个 字节序列,则将 response 的 主体 设置为 bodyBytes 作为主体。
通过使用 processResponseConsumeBody,我们 提取了 整个 主体。这是为了确保预加载器从网络加载整个主体,无论预加载是否会被消费(在此时是不确定的)。此步骤然后将请求的主体重置为包含相同字节的新主体,以便其他规范可以在实际消费时读取它,尽管我们已经这样做了一次。
否则,将 response 设置为一个 网络错误。
将 unsafeEndTime 设置为 不安全共享当前时间。
如果entry的on response available为null,则将entry的response设置为response;否则,调用entry的on response available并传入response。
如果给定 processResponse,则调用 processResponse 使用 response。
让 commit 成为以下步骤,给定一个 Document
document:
如果 options 的 文档 是 null,则将 options 的 文档就绪时 设置为 commit。否则,调用 commit 给定 options 的 文档。
获取和处理这种类型的链接资源的步骤,给定一个 link
元素
el,是:
为这种链接类型 处理链接头 的步骤,给定一个 链接处理选项 options 是 预加载 options。
privacy-policy
"privacy-policy
关键字可用于
link
、
a
和
area
元素。该关键字创建一个
超链接。
privacy-policy
关键字表示引用的文档包含关于适用于当前文档的数据收集和使用实践的信息,如 Additional Link Relation
Types 中更详细描述的那样。引用的文档可以是独立的隐私政策,或者是某些更通用文档的特定部分。[RFC6903]
search
"search
关键字可用于link
、
a
、
area
和
form
元素。该关键字创建一个
超链接。
search
关键字表示引用的文档提供了一个专门用于搜索该文档及其相关资源的接口。
OpenSearch 描述文档可与link
元素和search
链接类型一起使用,以使用户代理能够自动发现搜索接口。[OPENSEARCH]
stylesheet
"
stylesheet
关键字可用于link
元素。此关键字创建一个外部资源链接,它有助于样式处理模型。此关键字是body-ok。
指定的资源是一个CSS 样式表, 它描述了如何呈现文档。
仅支持一个引擎。
如果alternate
关键字也在link
元素上指定,那么该链接是一个替代样式表;在这种情况下,
title
属性必须在link
元素上指定,且其值不能为空。
stylesheet
关键字的默认资源类型是text/css
。
此类型的link
元素如果是由其节点文档的解析器创建的,
则被认为是隐含地潜在渲染阻塞。
当带有stylesheet
关键字的link
元素的disabled
属性被设置时,禁用
关联的CSS
样式表。
此类链接获取和处理的适当时机是:
当已经浏览上下文连接的外部资源链接的link
元素的crossorigin
属性被设置、更改或移除时。
当已经浏览上下文连接的外部资源链接的link
元素的type
属性被设置或更改为与之前获得的外部资源(如果有)的Content-Type
元数据不匹配时。
当已经浏览上下文连接的外部资源链接的link
元素的type
属性被移除或更改时,由于之前指定了不受支持的类型,导致未获取。
怪癖:如果文档已设置为怪癖模式,
具有与外部资源的相同来源,
且外部资源的内容类型元数据不是支持的样式表类型,
则用户代理必须将其视为text/css
。
此类链接资源的链接资源获取设置步骤,给定一个
link
元素el和
请求request,如下:
如果el的disabled
属性被设置,则返回false。
返回true。
请参见issue #968,了解使用CSSOM 获取CSS样式表算法代替
默认获取和处理链接资源算法的计划。
与此同时,任何关键子资源的
请求应将其
渲染阻塞设置为link
元素当前是否
渲染阻塞。
要处理此类型的链接资源,
给定一个link
元素el,
布尔值success,响应response,
和字节序列bodyBytes:
如果success为true,那么:
创建一个CSS样式表,具有以下属性:
response的URL列表[0]
我们在此提供一个URL,假设w3c/csswg-drafts issue #9316将会被修复。
el
el的media
属性。
这是对(此时可能不存在的)属性的引用,而不是该属性当前值的副本。CSSOM定义了当属性动态设置、更改或删除时会发生什么。
如果el在文档树中,则为el的title
属性;否则为空字符串。
同样,这是对属性的引用,而不是该属性当前值的副本。
如果链接是一个备用样式表,并且el的明确启用为false,则设置此标志;否则不设置。
如果资源是CORS同源,则设置;否则不设置。
null
保持默认值。
未初始化。
这似乎不对。大概我们应该使用bodyBytes? 跟踪于issue #2997。
CSS环境编码的结果是运行以下步骤的结果:[CSSSYNTAX]
如果el有一个charset
属性,从该属性的值中获取编码。如果成功,返回结果编码。[ENCODING]
如果el贡献了一个脚本阻塞样式表,则:
解除el的渲染阻塞。
此类链接资源的处理链接头步骤是不做任何事情。
tag
"tag
关键字可以与a
和area
元素一起使用。这个关键字创建一个超链接。
tag
关键字表示引用的文档代表的tag适用于当前文档。
由于它表示该标签适用于当前文档,因此在标签云的标记中使用此关键字是不合适的,因为标签云列出了跨多个页面的热门标签。
本文档是关于一些宝石的,所以它被标记为"https://en.wikipedia.org/wiki/Gemstone
",以明确将其归类为适用于"珠宝"类型的宝石,而不是美国的城镇、Ruby包格式或瑞士机车类:
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< title > My Precious</ title >
</ head >
< body >
< header >< h1 > My precious</ h1 > < p > Summer 2012</ p ></ header >
< p > Recently I managed to dispose of a red gem that had been
bothering me. I now have a much nicer blue sapphire.</ p >
< p > The red gem had been found in a bauxite stone while I was digging
out the office level, but nobody was willing to haul it away. The
same red gem stayed there for literally years.</ p >
< footer >
Tags: < a rel = tag href = "https://en.wikipedia.org/wiki/Gemstone" > Gemstone</ a >
</ footer >
</ body >
</ html >
在这个文档中,有两篇文章。然而,"tag
"链接适用于整个页面(无论其放置位置,包括在article
元素内时也是如此)。
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< title > Gem 4/4</ title >
</ head >
< body >
< article >
< h1 > 801: Steinbock</ h1 >
< p > The number 801 Gem 4/4 electro-diesel has an ibex and was rebuilt in 2002.</ p >
</ article >
< article >
< h1 > 802: Murmeltier</ h1 >
< figure >
< img src = "https://upload.wikimedia.org/wikipedia/commons/b/b0/Trains_de_la_Bernina_en_hiver_2.jpg"
alt = "The 802 was red with pantographs and tall vents on the side." >
< figcaption > The 802 in the 1980s, above Lago Bianco.</ figcaption >
</ figure >
< p > The number 802 Gem 4/4 electro-diesel has a marmot and was rebuilt in 2003.</ p >
</ article >
< p class = "topic" >< a rel = tag href = "https://en.wikipedia.org/wiki/Rhaetian_Railway_Gem_4/4" > Gem 4/4</ a ></ p >
</ body >
</ html >
terms-of-service
"terms-of-service
关键字可以与link
、a
和area
元素一起使用。这个关键字创建一个超链接。
terms-of-service
关键字表示引用的文档包含关于当前文档提供者与希望使用当前文档的用户之间的协议的信息,如Additional
Link Relation Types中更详细描述的那样。[RFC6903]
某些文档是文档序列的一部分。
文档序列是指每个文档可以有一个前一个兄弟文档和一个下一个兄弟文档。没有前一个兄弟文档的文档是其序列的起点,没有下一个兄弟文档的文档是其序列的终点。
一个文档可以属于多个序列。
next
"next
关键字可以与link
、a
、area
和form
元素一起使用。这个关键字创建一个超链接。
next
关键字表示文档是一个序列的一部分,并且链接指向序列中下一个逻辑文档。
当next
关键字与link
元素一起使用时,用户代理应该处理这些链接,就像它们使用dns-prefetch
、preconnect
或prefetch
关键字一样。用户代理希望使用哪个关键字取决于实现;例如,用户代理可能希望在节省数据、电池电量或处理能力时使用成本较低的preconnect
处理模型,或者可能希望根据对类似场景中过去用户行为的启发式分析来选择一个关键字。
prev
"prev
关键字可以与link
、a
、area
和form
元素一起使用。这个关键字创建一个超链接。
prev
关键字表示文档是一个序列的一部分,并且链接指向序列中上一个逻辑文档。
同义词:出于历史原因,用户代理还必须将关键字"previous
"视为prev
关键字。
预定义链接类型集的扩展 可以在 现有rel值的microformats页面上注册。[MFREL]
任何人都可以随时编辑 现有rel值的microformats页面 以添加类型。扩展类型必须指定以下信息:
实际定义的值。该值不应与任何其他定义的值混淆相似(例如,仅在大小写上有所不同)。
如果该值包含U+003A冒号字符(:),则它还必须是一个 绝对URL。
link
以下之一:
link
元素上指定关键字。link
元素上指定关键字;它创建一个 超链接。link
元素上指定关键字;它创建一个 外部资源链接。a
和
area
以下之一:
a
和 area
元素上指定关键字。a
和 area
元素上指定关键字;它创建一个 超链接。a
和 area
元素上指定关键字;它创建一个 外部资源链接。
a
和 area
元素上指定关键字;它 注释由元素创建的其他超链接。form
以下之一:
form
元素上指定关键字。form
元素上指定关键字;它创建一个 超链接。form
元素上指定关键字;它创建一个 外部资源链接。
form
元素上指定关键字;它 注释由元素创建的其他超链接。关键字含义的简短非规范性描述。
更详细描述关键字语义和要求的链接。它可以是wiki上的另一页,也可以是链接到外部页面。
具有完全相同处理要求的其他关键字值列表。作者不应使用定义为同义词的值,它们仅用于允许用户代理支持旧版内容。任何人都可以删除未实际使用的同义词;仅那些需要与旧版内容兼容处理的名称应以这种方式注册。
以下之一:
如果发现关键字与现 有值冗余,则应将其移除并列为现有值的同义词。
如果关键字在一个月或更长时间内未使用或未指定,则可以从注册表中删除。
如果添加的关键字处于建议状态并发现与现有值冗余,则应将其移除并列为现有值的同义词。如果添加的关键字处于建议状态并发现有害,则应将其状态更改为停止使用。
任何人都可以随时更改状态,但应仅根据上述定义进行。
合规检查器必须使用 现有rel值的microformats页面 上提供的信息来确定值是否被允许:本规范中定义的或标记为"建议"或"批准"的值在用于其描述的元素时必须被接受,而标记为"停止使用"或未在本规范或上述页面上列出的值必须被拒绝为无效。合规检查器可以缓存此信息(例如,为了性能原因或避免使用不可靠的网络连接)。
当作者使用本规范或wiki页面未定义的新类型时,合规检查器应提议将该值添加到wiki中,详情如上所述,状态为"建议"。
在 现有rel值的microformats页面
中以"建议"或"批准"状态定义的扩展类型,可以按照"对...的影响"字段所述的方式与 rel
属性一起用于 link
、a
和 area
元素。[MFREL]
ins
元素所有当前引擎支持。
cite
—
链接到引用的来源或有关编辑的更多信息datetime
—
更改的日期和(可选)时间HTMLModElement
。
ins
元素表示文档中的新增内容。
以下表示添加了一个段落:
< aside >
< ins >
< p > I like fruit. </ p >
</ ins >
</ aside >
以下也是,因为这里的 aside
元素中的所有内容都算作短语内容,因此这里只存在一个段落:
< aside >
< ins >
Apples are < em > tasty</ em > .
</ ins >
< ins >
So are pears.
</ ins >
</ aside >
ins
元素不应跨段落边界。
以下示例表示添加了两个段落,其中第二个段落分两部分插入。此示例中的第一个 ins
元素跨越了段落边界,这被认为是不好的做法。
< aside >
<!-- don't do this -->
< ins datetime = "2005-03-16 00:00Z" >
< p > I like fruit. </ p >
Apples are < em > tasty</ em > .
</ ins >
< ins datetime = "2007-12-19 00:00Z" >
So are pears.
</ ins >
</ aside >
这是一个更好的标记方法。它使用了更多的元素,但没有任何元素跨越隐含的段落边界。
< aside >
< ins datetime = "2005-03-16 00:00Z" >
< p > I like fruit. </ p >
</ ins >
< ins datetime = "2005-03-16 00:00Z" >
Apples are < em > tasty</ em > .
</ ins >
< ins datetime = "2007-12-19 00:00Z" >
So are pears.
</ ins >
</ aside >
del
元素所有当前引擎支持。
cite
—
链接到引用的来源或有关编辑的更多信息datetime
—
更改的日期和(可选)时间HTMLModElement
。
del
元素表示文档中的删除内容。
del
元素不应跨段落边界。
以下示例展示了一个“待办”列表,其中已完成的项目被划掉,并标注完成的日期和时间。
< h1 > To Do</ h1 >
< ul >
< li > Empty the dishwasher</ li >
< li >< del datetime = "2009-10-11T01:25-07:00" > Watch Walter Lewin's lectures</ del ></ li >
< li >< del datetime = "2009-10-10T23:38-07:00" > Download more tracks</ del ></ li >
< li > Buy a printer</ li >
</ ul >
ins
和 del
元素的公共属性cite
属性可用于指定解释更改的文档的
URL。当该文档很长时,例如会议记录,作者被鼓励包含一个 片段,指向该文档中特定讨论更改的部分。
如果存在 cite
属性,它必须是一个 有效的
URL(可能被空格包围),用于解释更改。为了获得相应的引用链接,必须相对于元素的 节点文档 解析该属性的值。用户代理可以允许用户跟随这些引用链接,但它们主要用于私有用途(例如,由服务器端脚本收集站点编辑的统计数据),而不是为读者准备的。
datetime
属性可用于指定更改的时间和日期。
如果存在,datetime
属性的值必须是 有效的日期字符串(可选时间)。
用户代理必须根据 解析日期或时间字符串 算法解析 datetime
属性。如果该算法没有返回 日期 或 全局日期和时间,那么修改没有相关联的时间戳(该值是不符合规范的;它不是 有效的日期字符串(可选时间))。否则,修改被标记为在给定的
日期
或
全局日期和时间
进行的。如果给定的值是 全局日期和时间,那么用户代理应该使用相关的时区偏移信息来确定展示给定日期时间的时区。
这个值可以展示给用户,但它主要是为了私有用途。
ins
和 del
元素必须实现 HTMLModElement
接口:
支持所有当前的引擎。
[Exposed =Window ]
interface HTMLModElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute USVString cite ;
[CEReactions ] attribute DOMString dateTime ;
};
cite
IDL 属性必须
反映 元素的 cite
内容属性。dateTime
IDL 属性必须 反映
元素的 datetime
内容属性。
本节为非规范性内容。
由于 ins
和 del
元素不影响 段落划分,在某些没有显式 p
元素的情况下,这些元素可能会跨越整个段落或其他非短语内容元素和部分另一段。例如:
< section >
< ins >
< p >
This is a paragraph that was inserted.
</ p >
This is another paragraph whose first sentence was inserted
at the same time as the paragraph above.
</ ins >
This is a second sentence, which was there all along.
</ section >
通过仅将一些段落包裹在 p
元素中,甚至可以使一个段落的结尾、整个第二段和第三段的开始被同一个 ins
或
del
元素覆盖(尽管这非常混乱,并不被认为是好的做法):
< section >
This is the first paragraph. < ins > This sentence was
inserted.
< p > This second paragraph was inserted.</ p >
This sentence was inserted too.</ ins > This is the
third paragraph in this example.
<!-- (don't do this) -->
</ section >
然而,由于 隐含段落 的定义方式,无法使用同一个
ins
或
del
元素来标记一个段落的结尾和下一个段落的开始。你需要使用一个(或两个)p
元素和两个
ins
或
del
元素,例如:
< section >
< p > This is the first paragraph. < del > This sentence was
deleted.</ del ></ p >
< p >< del > This sentence was deleted too.</ del > That
sentence needed a separate < del> element.</ p >
</ section >
部分因为上述的混乱,强烈建议作者始终使用 p
元素来标记所有段落,而不是使用跨越 隐含段落 边界的
ins
或
del
元素。
本节为非规范性内容。
ol
和 ul
元素的内容模型不允许
ins
和 del
元素作为子元素。列表总是表示所有项目,包括那些本应标记为已删除的项目。
要指示某个项目已插入或删除,可以将 ins
或 del
元素包裹在
li
元素的内容周围。要指示某个项目已被另一个替换,可以在单个 li
元素中包含一个或多个
del
元素,后跟一个或多个 ins
元素。
在以下示例中,一个最初为空的列表随着时间的推移添加和删除了项目。示例中加重显示的部分显示了列表的“当前”状态。列表项编号没有考虑编辑。
< h1 > Stop-ship bugs</ h1 >
< ol >
< li >< ins datetime = "2008-02-12T15:20Z" > Bug 225:
Rain detector doesn't work in snow</ ins ></ li >
< li >< del datetime = "2008-03-01T20:22Z" >< ins datetime = "2008-02-14T12:02Z" > Bug 228:
Water buffer overflows in April</ ins ></ del ></ li >
< li >< ins datetime = "2008-02-16T13:50Z" > Bug 230:
Water heater doesn't use renewable fuels</ ins ></ li >
< li >< del datetime = "2008-02-20T21:15Z" >< ins datetime = "2008-02-16T14:25Z" > Bug 232:
Carbon dioxide emissions detected after startup</ ins ></ del ></ li >
</ ol >
在以下示例中,最初只有水果的列表被替换为只有颜色的列表。
< h1 > List of < del > fruits</ del >< ins > colors</ ins ></ h1 >
< ul >
< li >< del > Lime</ del >< ins > Green</ ins ></ li >
< li >< del > Apple</ del ></ li >
< li > Orange</ li >
< li >< del > Pear</ del ></ li >
< li >< ins > Teal</ ins ></ li >
< li >< del > Lemon</ del >< ins > Yellow</ ins ></ li >
< li > Olive</ li >
< li >< ins > Purple</ ins ></ li >
</ ul >
本节为非规范性内容。
表格模型中的元素有复杂的内容模型要求,不允许 ins
和
del
元素,因此指示对表格的编辑可能会很困难。
要指示整行或整列已被添加或删除,可以将该行或列中每个单元格的全部内容包裹在 ins
或 del
元素中。
这里,一个表格的行被添加了:
< table >
< thead >
< tr > < th > Game name < th > Game publisher < th > Verdict
< tbody >
< tr > < td > Diablo 2 < td > Blizzard < td > 8/10
< tr > < td > Portal < td > Valve < td > 10/10
< tr > < td > < ins > Portal 2</ ins > < td > < ins > Valve</ ins > < td > < ins > 10/10</ ins >
</ table >
这里,一列被删除了(删除时间和解释原因的页面链接也一并给出):
< table >
< thead >
< tr > < th > Game name < th > Game publisher < th > < del cite = "/edits/r192" datetime = "2011-05-02 14:23Z" > Verdict</ del >
< tbody >
< tr > < td > Diablo 2 < td > Blizzard < td > < del cite = "/edits/r192" datetime = "2011-05-02 14:23Z" > 8/10</ del >
< tr > < td > Portal < td > Valve < td > < del cite = "/edits/r192" datetime = "2011-05-02 14:23Z" > 10/10</ del >
< tr > < td > Portal 2 < td > Valve < td > < del cite = "/edits/r192" datetime = "2011-05-02 14:23Z" > 10/10</ del >
</ table >
一般来说,没有好的方法可以指示更复杂的编辑(例如,删除一个单元格,移动所有后续单元格向上或向左)。
picture
元素支持所有当前引擎。
支持所有当前引擎。
source
元素,后跟一个 img
元素,可选地混合脚本支持元素。[Exposed =Window ]
interface HTMLPictureElement : HTMLElement {
[HTMLConstructor ] constructor ();
};
picture
元素是一个容器,提供多种来源给其包含的 img
元素,以便作者可以声明性地控制或给用户代理提供关于使用哪个图像资源的提示,基于屏幕像素密度、视口大小、图像格式等因素。它代表其子元素。
picture
元素与类似的 video
和 audio
元素有些不同。虽然它们都包含 source
元素,但当元素嵌套在 picture
元素中时,src
属性没有意义,并且资源选择算法也不同。此外,picture
元素本身不显示任何内容;它仅为其包含的 img
元素提供上下文,使其能够从多个 URLs 中选择。
source
元素支持所有当前引擎。
支持所有当前引擎。
picture
元素的子元素,在 img
元素之前。
track
元素之前。type
— 嵌入资源的类型media
—
适用的媒体src
(在
audio
或
video
中)
— 资源地址
srcset
(在 picture
中) — 在不同情况下使用的图像,例如高分辨率显示器,小显示器等。sizes
(在
picture
中) — 不同页面布局的图像大小
width
(在
picture
中) — 水平尺寸
height
(在 picture
中) — 垂直尺寸[Exposed =Window ]
interface HTMLSourceElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute USVString src ;
[CEReactions ] attribute DOMString type ;
[CEReactions ] attribute USVString srcset ;
[CEReactions ] attribute DOMString sizes ;
[CEReactions ] attribute DOMString media ;
[CEReactions ] attribute unsigned long width ;
[CEReactions ] attribute unsigned long height ;
};
source
元素允许作者为 img
元素指定多个替代的 source sets 或为 media 元素指定多个替代的 媒体资源。它本身不 表示任何内容。
type
属性可以存在。如果存在,其值必须是一个 有效的 MIME
类型字符串。
media
属性也可以存在。如果存在,其值必须包含一个 有效的媒体查询列表。如果值不 匹配环境,用户代理将跳到下一个 source
元素。
media
属性仅在 资源选择算法 中对 media 元素 进行一次评估。相比之下,当使用
picture
元素时,用户代理将 对环境的变化做出反应。
其余的要求取决于父元素是 picture
元素还是 media 元素:
source
元素的父元素是 picture
元素srcset
属性必须存在,并且是一个 srcset
属性。
srcset
属性在 source
元素被选中时,将 图像来源 提供给 source set。
如果 srcset
属性包含任何使用 宽度描述符
的
图像候选字符串,则 sizes
属性也可以存在。如果另外,下一个兄弟 img
元素不
允许自动尺寸,则
sizes
属性必须存在。sizes
属性是一个 sizes 属性,如果
source
元素被选中,则该属性为 source
size
贡献值。
如果 img
元素
允许自动尺寸,则可以省略前一个兄弟 source
元素上的 sizes
属性。在这种情况下,它等同于指定 auto
。
source
元素支持 尺寸属性。img
元素可以使用 width
和
height
属性来确定其渲染尺寸和纵横比,如渲染部分所定义。
type
属性指定 source set
中图像的类型,以便用户代理在不支持给定类型时跳到下一个 source
元素。
如果
未指定 type
属性,当用户代理在获取后发现不支持图像格式时,它不会选择不同的 source
元素。
当 source
元素有一个后续的兄弟 source
元素或 img
元素,并且指定了 srcset
属性时,必须满足以下至少一个条件:
指定了 media
属性,并且在 去除前导和尾随 ASCII 空白后,其值不是空字符串且不与字符串
"all
" 进行 ASCII 不区分大小写 匹配。
指定了 type
属性。
src
属性不得存在。
source
元素的父元素是 media 元素src
属性提供 URL 的
媒体资源。该值必须是 有效的非空 URL(可能被空格包围)。该属性必须存在。
type
属性指定 媒体资源
的类型,以帮助用户代理在获取之前确定是否可以播放此 媒体资源。某些 MIME
类型定义的 codecs
参数可能需要指定资源的确切编码方式。[RFC6381]
在已经插入到 video
或 audio
元素中的情况下动态修改 source
元素的 src
或
type
属性将无效。要更改正在播放的内容,只需直接在 media 元素 上使用 src
属性,可能使用
canPlayType()
方法从可用资源中选择。通常,在文档解析后手动操作 source
元素是一种不必要的复杂方法。
以下列表显示了一些如何在 codecs=
MIME 参数中使用 type
属性的示例。
< source src = 'video.mp4' type = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"' >
< source src = 'video.mp4' type = 'video/mp4; codecs="avc1.58A01E, mp4a.40.2"' >
< source src = 'video.mp4' type = 'video/mp4; codecs="avc1.4D401E, mp4a.40.2"' >
< source src = 'video.mp4' type = 'video/mp4; codecs="avc1.64001E, mp4a.40.2"' >
< source src = 'video.mp4' type = 'video/mp4; codecs="mp4v.20.8, mp4a.40.2"' >
< source src = 'video.mp4' type = 'video/mp4; codecs="mp4v.20.240, mp4a.40.2"' >
< source src = 'video.3gp' type = 'video/3gpp; codecs="mp4v.20.8, samr"' >
< source src = 'video.ogv' type = 'video/ogg; codecs="theora, vorbis"' >
< source src = 'video.ogv' type = 'video/ogg; codecs="theora, speex"' >
< source src = 'audio.ogg' type = 'audio/ogg; codecs=vorbis' >
< source src = 'audio.spx' type = 'audio/ogg; codecs=speex' >
< source src = 'audio.oga' type = 'audio/ogg; codecs=flac' >
< source src = 'video.ogv' type = 'video/ogg; codecs="dirac, vorbis"' >
source
HTML 元素插入步骤,给定
insertedNode,如下:
如果 insertedNode 的父元素是没有 src
属性且
networkState
值为 NETWORK_EMPTY
的 media 元素,则调用该 media 元素 的 资源选择算法。
如果 insertedNode 的下一个兄弟元素是 img
元素,且其父元素是 picture
元素,则将此计为该 img
元素的
相关变动。
source
HTML 元素移除步骤,给定
removedNode 和
oldParent,如下:
IDL 属性 src
,type
,srcset
,sizes
和 media
必须 反映相应名称的内容属性。
如果作者不确定用户代理是否都能渲染所提供的媒体资源,作者可以监听最后一个 error
事件并触发回退行为:
< script >
function fallback( video) {
// replace <video> with its contents
while ( video. hasChildNodes()) {
if ( video. firstChild instanceof HTMLSourceElement)
video. removeChild( video. firstChild);
else
video. parentNode. insertBefore( video. firstChild, video);
}
video. parentNode. removeChild( video);
}
</ script >
< video controls autoplay >
< source src = 'video.mp4' type = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"' >
< source src = 'video.ogv' type = 'video/ogg; codecs="theora, vorbis"'
onerror = "fallback(parentNode)" >
...
</ video >
img
元素所有当前引擎支持。
所有当前引擎支持。
usemap
属性:
交互内容。
picture
元素的子元素,在所有source
元素之后。
alt
—
图像不可用时的替代文本src
— 资源地址
srcset
—
不同情况下使用的图像,例如高分辨率显示器、小显示器等。sizes
—
不同页面布局的图像大小crossorigin
— 元素如何处理跨域请求usemap
— 要使用的图像映射的名称ismap
—
图像是否为服务器端图像映射width
—
水平尺寸height
—
垂直尺寸referrerpolicy
— 元素发起的referrer policy的fetchesdecoding
—
处理此图像进行展示时使用的解码提示loading
— 用于确定加载延迟fetchpriority
— 为元素发起的请求优先级设置fetchesalt
属性: 给作者; 给实现者。[Exposed =Window ,
LegacyFactoryFunction =Image (optional unsigned long width , optional unsigned long height )]
interface HTMLImageElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString alt ;
[CEReactions ] attribute USVString src ;
[CEReactions ] attribute USVString srcset ;
[CEReactions ] attribute DOMString sizes ;
[CEReactions ] attribute DOMString ? crossOrigin ;
[CEReactions ] attribute DOMString useMap ;
[CEReactions ] attribute boolean isMap ;
[CEReactions ] attribute unsigned long width ;
[CEReactions ] attribute unsigned long height ;
readonly attribute unsigned long naturalWidth ;
readonly attribute unsigned long naturalHeight ;
readonly attribute boolean complete ;
readonly attribute USVString currentSrc ;
[CEReactions ] attribute DOMString referrerPolicy ;
[CEReactions ] attribute DOMString decoding ;
[CEReactions ] attribute DOMString loading ;
[CEReactions ] attribute DOMString fetchPriority ;
Promise <undefined > decode ();
// also has obsolete members
};
img
元素表示一张图片。
img
元素有一个维度属性源,初始设置为元素本身。
支持所有当前引擎。
支持所有当前引擎。
由src
和srcset
属性以及任何先前兄弟source
元素的srcset
属性(如果父元素是picture
元素)给出的图像是嵌入的内容;alt
属性的值为那些无法处理图像或禁用图像加载的用户提供等效内容(即它是img
元素的回退内容)。
src
属性必须存在,并且必须包含一个有效的非空URL(可能被空格包围),引用一个非交互的、可选动画的图像资源,该资源既不是分页的也不是脚本的。
上述要求意味着图像可以是静态位图(例如PNG、GIF、JPEG)、单页矢量文档(单页PDF、包含SVG文档元素的XML文件)、动画位图(APNG、动画GIF)、动画矢量图形(包含SVG文档元素并使用声明性SMIL动画的XML文件)等。然而,这些定义排除了带有脚本的SVG文件、多页PDF文件、交互式MNG文件、HTML文档、纯文本文件等。[PNG] [GIF] [JPEG] [PDF] [XML] [APNG] [SVG] [MNG]
srcset
属性和src
属性(如果未使用宽度描述符)为图像来源提供了源集(如果未选择source
元素)。
如果srcset
属性存在且有任何使用宽度描述符的图像候选字符串,则sizes
属性也必须存在。如果未指定srcset
属性,并且loading
属性处于Lazy状态,则可以使用值“auto
”指定sizes
属性(ASCII大小写不敏感)。sizes
属性是一个sizes属性,它为源集提供源尺寸(如果未选择source
元素)。
img
元素允许自动大小如果:
loading
属性处于Lazy状态,并且sizes
属性的值为“auto
”(ASCII大小写不敏感),或以“auto,
”(ASCII大小写不敏感)开头。支持所有当前引擎。
crossorigin
属性是一个CORS设置属性。其目的是允许具有跨源访问权限的第三方网站的图像与canvas
一起使用。
referrerpolicy
属性是一个引用策略属性。其目的是设置在引用策略时使用的获取图像。[REFERRERPOLICY]
decoding
属性表示解码此图像的首选方法。如果存在,该属性必须是一个图像解码提示。此属性的缺省值和无效值都是auto状态。
HTMLImageElement/fetchPriority
fetchpriority
属性是一个获取优先级属性。其目的是设置在请求优先级时使用的获取图像。
loading
属性是一个延迟加载属性。其目的是指示视口外图像的加载策略。
当loading
属性的状态更改为Eager状态时,用户代理必须执行以下步骤:
如果resumptionSteps为null,则返回。
调用resumptionSteps。
< img src = "1.jpeg" alt = "1" >
< img src = "2.jpeg" loading = eager alt = "2" >
< img src = "3.jpeg" loading = lazy alt = "3" >
< div id = very-large ></ div > <!-- Everything after this div is below the viewport -->
< img src = "4.jpeg" alt = "4" >
< img src = "5.jpeg" loading = lazy alt = "5" >
在上述示例中,图像按如下方式加载:
1.jpeg
, 2.jpeg
, 4.jpeg
这些图像急切加载,并延迟窗口的加载事件。
3.jpeg
由于位于视口中,该图像在布局已知时加载,但不会延迟窗口的加载事件。
5.jpeg
该图像仅在滚动到视口中时加载,不会延迟窗口的加载事件。
建议开发者在延迟加载的图像上通过width
和height
属性指定首选的纵横比,即使CSS设置了图像的宽度和高度属性,以防止页面布局在图像加载后发生变化。
给定insertedNode,img
的HTML元素插入步骤如下:
给定removedNode和oldParent,img
的HTML元素移除步骤如下:
必须避免将img
元素作为布局工具使用。特别是,img
元素不应被用来显示透明图像,因为这些图像通常不会传达任何意义,也很少为文档增加有用的内容。
一个 img
元素表示的内容取决于 src
属性
和 alt
属性。
src
属性已设置,而 alt
属性设置为空字符串该图片可能是装饰性的或补充内容,和文档中的其他信息重复。
如果图片是 可用的 且用户代理被配置为显示该图片,则该元素 表示 元素的图片数据。
否则,该元素 表示 无内容,可能会完全从渲染中省略。用户代理可能会通知用户有图片存在但已被省略。
src
属性已设置,而 alt
属性设置为非空值该图片是内容的关键部分;alt
属性提供了图片的文本等效或替代。
src
属性已设置,而 alt
属性未设置该图片可能是内容的关键部分,但没有可用的文本等效物。
在符合规范的文档中,缺少 alt
属性表示图片是内容的关键部分,但在生成图片时没有可用的文本替代。
如果图片是 可用的 且用户代理被配置为显示该图片,则该元素 表示 元素的图片数据。
如果图片有一个 src
属性,其值为空字符串,则该元素 表示 无内容。
否则,用户代理应显示某种指示,表明有一张图片未被渲染,并且如果用户请求,或用户代理配置为如此,或在响应导航时需要提供上下文信息,则提供图片的标题信息,按如下方式:
如果图片有一个 title
属性,其值非空字符串,则返回该属性的值。
如果图片是 figure
元素的后代,该元素有一个子 figcaption
元素,并且忽略 figcaption
元素及其后代,如果 figure
元素没有其他 流内容 后代,除了
元素间的空白 和 img
元素,则返回第一个这样的 figcaption
元素的内容。
返回无内容。(没有标题信息。)
src
属性未设置,而 alt
属性设置为空字符串或 alt
属性完全未设置该元素 表示 无内容。
alt
属性不代表建议信息。
用户代理不得以与 alt
属性
内容相同的方式展示 title
属性的内容。
用户代理可以始终为用户提供显示任何图片或阻止显示任何图片的选项。用户代理也可以应用启发式方法来帮助用户在无法看到图片时利用图片,例如,由于视觉障碍或使用没有图形能力的文本终端。这些启发式方法可以包括,例如,对图片中找到的文本进行光学字符识别(OCR)。
虽然鼓励用户代理修复缺失的 alt
属性的情况,但作者不应依赖于这种行为。有关提供文本作为图片替代的 要求 详细描述如下。
img 元素的 img
元素的内容(如果有的话)在渲染时将被忽略。
usemap
属性(如果存在)可以指示该图片有一个相关的
图片地图。
ismap
属性,当用于一个是 a
元素的
后代元素上,并且该 href
属性存在时,表示该元素提供访问服务器端图片地图的功能。这影响了在相应的 a
元素上的事件处理。
ismap
属性是一个
布尔属性。
该属性不得在没有具有 a
元素且该元素
上没有 href
属性的元素上指定。
使用 usemap
和 ismap
属性可能会导致在与 source
元素及在 media
属性指定的 picture
元素一起使用时,行为可能会令人困惑。
在所有当前引擎中支持。
在所有当前引擎中支持。
在所有当前引擎中支持。
alt
、src
、srcset
和
sizes
IDL
属性必须
反映 相应的同名内容属性。
在所有当前引擎中支持。
crossOrigin
IDL 属性必须
反映 crossorigin
内容属性,限制为已知值。
在所有当前引擎中支持。
useMap
IDL 属性必须 反映 usemap
内容属性。
在所有当前引擎中支持。
HTMLImageElement/referrerPolicy
在所有当前引擎中支持。
referrerPolicy
IDL 属性必须
反映 referrerpolicy
内容属性,限制为已知值。
在所有当前引擎中支持。
decoding
IDL 属性必须 反映 decoding
内容属性,限制为已知值。
在所有当前引擎中支持。
loading
IDL 属性必须 反映 loading
内容属性,限制为已知值。
fetchPriority
IDL 属性
必须 反映 fetchpriority
内容属性,限制为已知值。
image.width [ = value ]
在所有当前引擎中都受支持。
image.height [ = value ]
在所有当前引擎中都受支持。
这些属性返回图像的实际渲染尺寸,如果尺寸未知则返回 0。
可以设置这些属性,以改变相应的内容属性。
image.naturalWidth
在所有当前引擎中都受支持。
image.naturalHeight
HTMLImageElement/naturalHeight
在所有当前引擎中都受支持。
这些属性返回图像的自然尺寸,如果尺寸未知则返回 0。
image.complete
在所有当前引擎中都受支持。
如果图像已经完全下载,或者没有指定图像,则返回 true;否则返回 false。
image.currentSrc
在所有当前引擎中都受支持。
返回图像的 绝对 URL。
image.decode()
在所有当前引擎中都受支持。
该方法使用户代理对图像进行 解码,以 并行 方式进行解码, 返回一个在解码完成时会被兑现的 Promise。
如果图像无法解码,Promise 将被拒绝,并返回一个 "EncodingError
"
DOMException
。
image = new Image([ width [, height ] ])
在所有当前引擎中都受支持。
IDL 属性 width
和
height
必须返回图像的实际渲染宽度和高度,单位为 CSS 像素,如果图像正在 渲染;否则返回图像的 密度修正的自然宽度和高度,单位为 CSS 像素,如果图像具有 密度修正的自然宽度和高度 并且是 可用 但未 渲染;否则返回 0,如果图像不可 可用 或没有 密度修正的自然宽度和高度。 [CSS]
在设置时,这些属性必须表现得像是反映了具有相同名称的内容属性。
IDL 属性 naturalWidth
和 naturalHeight
必须返回图像的 密度修正的自然宽度和高度,单位为 CSS 像素,如果图像具有 密度修正的自然宽度和高度 并且是 可用,否则返回 0。 [CSS]
由于图像的 密度修正的自然宽度和高度 会考虑其元数据中指定的任何方向,naturalWidth
和 naturalHeight
反映了在应用任何需要的旋转以正确定位图像后的尺寸,而不管 'image-orientation' 属性的值。
complete
获取步骤如下:
如果以下任意条件为真:
则返回 true。
返回 false。
currentSrc
IDL 属性必须返回 img
元素的 当前请求 的 当前
URL。
decode()
方法在被调用时,必须执行以下步骤:
创建一个新的 promise 对象,命名为 promise。
将一个微任务排入队列,以执行以下步骤:
这是因为更新图像数据也在微任务中进行。因此,为了使以下代码正常工作
img. src = "stars.jpg" ;
img. decode();
正确解码stars.jpg
,我们需要将任何处理延迟一个微任务。
如果以下任意条件为真:
则用 "EncodingError
" DOMException
拒绝 promise。
否则,并行地 等待以下任意情况发生,并执行相应的操作:
img
元素的 节点文档 停止 完全激活img
元素的 当前请求
更改或被修改img
元素的 当前请求 的
状态 变为 损坏
用 "EncodingError
" DOMException
拒绝 promise。
img
元素的 当前请求 的
状态 变为 完全可用
解码 图像。
如果不需要对图像进行解码(例如,因为它是矢量图形),则用 undefined 解析 promise。
如果解码失败(例如由于图像数据无效),则用 "EncodingError
" DOMException
拒绝 promise。
如果解码过程成功完成,则用 undefined 解析 promise。
用户代理应确保解码后的媒体数据保持可用,至少直到下一个成功的 更新渲染 步骤结束。这是 API 合同的重要部分,应该尽可能不被破坏。(通常,只有在低内存情况下需要驱逐解码图像数据,或当图像过大以至于无法在此期间保持解码状态时,这种情况才会被违反。)
动画图像只有在所有帧加载完毕后才会变为 完全可用。因此,即使实现可以在此之前解码第一帧,上述步骤也不会这样做,而是等待所有帧都可用。
返回 promise。
没有 decode()
方法时,加载一个 img
元素并显示它的过程可能如下所示:
const img = new Image();
img. src = "nebula.jpg" ;
img. onload = () => {
document. body. appendChild( img);
};
img. onerror = () => {
document. body. appendChild( new Text( "Could not load the nebula :(" ));
};
然而,这可能会导致明显的掉帧,因为在将图像插入到 DOM 中后发生的绘制会导致主线程上进行同步解码。
这可以使用 decode()
方法来重写:
const img = new Image();
img. src = "nebula.jpg" ;
img. decode(). then(() => {
document. body. appendChild( img);
}). catch (() => {
document. body. appendChild( new Text( "Could not load the nebula :(" ));
});
这种后者的形式避免了原始方法中的掉帧,通过允许用户代理 并行 解码图像,只有在解码过程完成后才将其插入到 DOM 中(从而导致它被绘制)。
由于 decode()
方法尝试确保解码后的图像数据至少在一个帧内可用,因此可以与 requestAnimationFrame()
API 结合使用。这意味着它可以与确保所有 DOM 修改都作为 动画帧回调 一起批处理的编码风格或框架一起使用:
const container = document. querySelector( "#container" );
const { containerWidth, containerHeight } = computeDesiredSize();
requestAnimationFrame(() => {
container. style. width = containerWidth;
container. style. height = containerHeight;
});
// ...
const img = new Image();
img. src = "supernova.jpg" ;
img. decode(). then(() => {
requestAnimationFrame(() => container. appendChild( img));
});
提供了一个遗留的工厂函数用于创建 HTMLImageElement
对象(除了 DOM 中的工厂方法,如 createElement()
):
Image(width, height)
。当被调用时,遗留工厂函数必须执行以下步骤:
让 document 为 当前的全局对象
的 关联
Document
。
返回 img。
一张图片在不同的上下文中可能需要不同的替代文本。
在以下每种情况下,使用的是相同的图片,但 alt
文本每次都不同。这张图片是瑞士日内瓦州卡鲁日市的市徽。
这里它被用作补充图标:
< p > I lived in < img src = "carouge.svg" alt = "" > Carouge.</ p >
这里它被用作代表城镇的图标:
< p > Home town: < img src = "carouge.svg" alt = "Carouge" ></ p >
这里它作为文本的一部分用于城镇:
< p > Carouge has a coat of arms.</ p >
< p >< img src = "carouge.svg" alt = "The coat of arms depicts a lion, sitting in front of a tree." ></ p >
< p > It is used as decoration all over the town.</ p >
这里它用来支持类似的文本,其中描述被给出,并且作为图像的补充,而不是替代图像:
< p > Carouge has a coat of arms.</ p >
< p >< img src = "carouge.svg" alt = "" ></ p >
< p > The coat of arms depicts a lion, sitting in front of a tree.
It is used as decoration all over the town.</ p >
这里它作为故事的一部分使用:
< p > She picked up the folder and a piece of paper fell out.</ p >
< p >< img src = "carouge.svg" alt = "Shaped like a shield, the paper had a
red background, a green tree, and a yellow lion with its tongue
hanging out and whose tail was shaped like an S." ></ p >
< p > She stared at the folder. S! The answer she had been looking for all
this time was simply the letter S! How had she not seen that before? It all
came together now. The phone call where Hector had referred to a lion's tail,
the time Maria had stuck her tongue out...</ p >
在出版时未知图像的具体内容,只知道它将是某种徽章,因此无法提供替代文本,而是仅在 title
属性中提供简短的图像说明:
< p > The last user to have uploaded a coat of arms uploaded this one:</ p >
< p >< img src = "last-uploaded-coat-of-arms.cgi" title = "User-uploaded coat of arms." ></ p >
Ideally, the author would find a way to provide real replacement text even in this case, e.g. by asking the previous user. Not providing replacement text makes the document more difficult to use for people who are unable to view images, e.g. blind users, or users or very low-bandwidth connections or who pay by the byte, or users who are forced to use a text-only web browser.
以下是一些更多的示例,展示了相同的图片在不同的上下文中使用,每次都有不同的适当替代文本。
< article >
< h1 > My cats</ h1 >
< h2 > Fluffy</ h2 >
< p > Fluffy is my favorite.</ p >
< img src = "fluffy.jpg" alt = "She likes playing with a ball of yarn." >
< p > She's just too cute.</ p >
< h2 > Miles</ h2 >
< p > My other cat, Miles just eats and sleeps.</ p >
</ article >
< article >
< h1 > Photography</ h1 >
< h2 > Shooting moving targets indoors</ h2 >
< p > The trick here is to know how to anticipate; to know at what speed and
what distance the subject will pass by.</ p >
< img src = "fluffy.jpg" alt = "A cat flying by, chasing a ball of yarn, can be
photographed quite nicely using this technique." >
< h2 > Nature by night</ h2 >
< p > To achieve this, you'll need either an extremely sensitive film, or
immense flash lights.</ p >
</ article >
< article >
< h1 > About me</ h1 >
< h2 > My pets</ h2 >
< p > I've got a cat named Fluffy and a dog named Miles.</ p >
< img src = "fluffy.jpg" alt = "Fluffy, my cat, tends to keep itself busy." >
< p > My dog Miles and I like go on long walks together.</ p >
< h2 > music</ h2 >
< p > After our walks, having emptied my mind, I like listening to Bach.</ p >
</ article >
< article >
< h1 > Fluffy and the Yarn</ h1 >
< p > Fluffy was a cat who liked to play with yarn. She also liked to jump.</ p >
< aside >< img src = "fluffy.jpg" alt = "" title = "Fluffy" ></ aside >
< p > She would play in the morning, she would play in the evening.</ p >
</ article >
本节为非规范性内容。
要在 HTML 中嵌入图像,当只有一个图像资源时,使用 img
元素及其 src
属性。
< h2 > From today's featured article</ h2 >
< img src = "/uploads/100-marie-lloyd.jpg" alt = "" width = "100" height = "150" >
< p >< b >< a href = "/wiki/Marie_Lloyd" > Marie Lloyd</ a ></ b > (1870–1922)
was an English < a href = "/wiki/Music_hall" > music hall</ a > singer, ...
然而,有许多情况下,作者可能希望使用多个图像资源供用户代理选择:
不同的用户可能具有不同的环境特征:
用户的物理屏幕尺寸可能彼此不同。
一部手机的屏幕对角线可能为4英寸,而一台笔记本电脑的屏幕对角线可能为14英寸。
这仅在图像的呈现大小依赖于视口大小时相关。
用户的屏幕像素密度可能彼此不同。
无论物理屏幕尺寸如何,一部手机的屏幕每英寸的物理像素数量可能是另一部手机的三倍。
用户的缩放级别可能彼此不同,或者单个用户的缩放级别可能随着时间而变化。
用户可能会放大某张图像,以便获得更详细的视图。
缩放级别和屏幕像素密度(前一点)都可以影响每CSS像素的物理屏幕像素数量。这个比例通常称为设备像素比。
用户的屏幕方向可能彼此不同,或者单个用户的屏幕方向可能随着时间而变化。
平板电脑可以竖着或旋转90度,因此屏幕可以是“竖屏”或“横屏”。
用户的网络速度、网络延迟和带宽成本可能彼此不同,或者单个用户的网络条件可能随时间变化。
用户可能在工作时使用快速、低延迟且成本固定的连接,在家时使用慢速、低延迟且成本固定的连接,在其他地方使用可变速度、高延迟和可变成本的连接。
作者可能希望根据通常是视口的宽度,显示相同的图像内容但呈现不同的大小。这通常称为 视口基于选择。
一个网页可能在顶部有一个横跨整个视口宽度的横幅。在这种情况下,图像的呈现大小取决于屏幕的物理大小(假设浏览器窗口最大化)。
另一个网页可能将图像分列,对于屏幕物理尺寸较小的设备使用一列,对于屏幕物理尺寸中等的设备使用两列,对于屏幕物理尺寸较大的设备使用三列,每种情况中的图像呈现大小会有所变化以填满视口。在这种情况下,即使屏幕较小,一列布局中的图像也可能比两列布局中的图像要大。
作者可能希望根据图像的呈现大小显示不同的图像内容。这通常称为艺术方向。
当网页在大物理尺寸的屏幕上查看时(假设浏览器窗口最大化),作者可能希望包括一些围绕图像关键部分的较少相关部分。当同一网页在小物理尺寸的屏幕上查看时,作者可能希望仅显示图像的关键部分。
作者可能希望使用不同的图像格式显示相同的图像内容,具体取决于用户代理支持哪些图像格式。这通常称为 图像格式基于选择。
一个网页可能有一些图像使用JPEG、WebP和JPEG XR图像格式,其中后两种格式具有比JPEG更好的压缩能力。由于不同的用户代理支持不同的图像格式,有些格式提供更好的压缩比,作者希望将更好的格式提供给支持这些格式的用户代理,同时为不支持这些格式的用户代理提供JPEG备选格式。
上述情况并不是相互排斥的。例如,将不同的资源结合使用来应对不同的设备像素比和不同的艺术方向是合理的。
虽然可以通过脚本解决这些问题,但这样做会引入一些其他问题:
一些用户代理会在脚本有机会运行之前,主动下载HTML标记中指定的图像,以便更快地完成网页加载。如果脚本更改要下载的图像,用户代理可能会开始两个独立的下载,这可能会导致更糟糕的页面加载性能。
如果作者避免在HTML标记中指定任何图像,而是通过脚本实例化单个下载,这样可以避免上述的双重下载问题,但对于禁用脚本的用户,图像将完全不会下载,同时激进的图像下载优化也将被禁用。
考虑到这些问题,本规范引入了一些功能,以声明性的方式解决上述问题。
src
和 srcset
属性可以用于 img
元素,使用 x
描述符提供多个仅在大小上有所不同的图像(较小的图像是较大图像的缩小版)。
当图像的渲染大小依赖于 视口 宽度(基于视口的选择)时,x
描述符是不适用的,但可以与 艺术方向 一起使用。
< h2 > From today's featured article</ h2 >
< img src = "/uploads/100-marie-lloyd.jpg"
srcset = "/uploads/150-marie-lloyd.jpg 1.5x, /uploads/200-marie-lloyd.jpg 2x"
alt = "" width = "100" height = "150" >
< p >< b >< a href = "/wiki/Marie_Lloyd" > Marie Lloyd</ a ></ b > (1870–1922)
was an English < a href = "/wiki/Music_hall" > music hall</ a > singer, ...
用户代理可以根据用户屏幕的像素密度、缩放级别以及可能的其他因素(如用户的网络条件)选择任何给定的资源。
为了与旧版用户代理兼容,这些用户代理尚不理解 srcset
属性,必须在 img
元素的 src
属性中指定一个 URL。
这将导致即使在旧版用户代理中也会显示一些有用的内容(尽管可能分辨率较低)。对于新的用户代理,src
属性参与资源选择,就像它是在 srcset
中以 1x
描述符指定的那样。
srcset
和 sizes
属性可以使用 w
描述符来提供多种仅在尺寸上有所不同的图像(较小的图像是较大图像的缩小版)。
在此示例中,一个横幅图像占据整个 视口 的宽度(使用适当的 CSS)。
< h1 >< img sizes = "100vw" srcset = "wolf-400.jpg 400w, wolf-800.jpg 800w, wolf-1600.jpg 1600w"
src = "wolf-400.jpg" alt = "The rad wolf" ></ h1 >
用户代理将根据指定的 w
描述符和 sizes
属性中指定的渲染尺寸来计算每个图像的实际像素密度。然后,它可以根据用户屏幕的像素密度、缩放级别以及其他可能的因素(如用户的网络条件)选择任何给定的资源。
如果用户的屏幕宽度为 320 CSS 像素,这相当于指定
wolf-400.jpg 1.25x, wolf-800.jpg 2.5x, wolf-1600.jpg 5x
。另一方面,如果用户的屏幕宽度为 1200 CSS 像素,这相当于指定
wolf-400.jpg 0.33x, wolf-800.jpg 0.67x, wolf-1600.jpg 1.33x
。通过使用 w
描述符和 sizes
属性,用户代理可以选择正确的图像源进行下载,无论用户设备的大小如何。
为了向后兼容,在 img
元素的
src
属性中指定了一个
URL。在新的用户代理中,当 srcset
属性使用 w
描述符时,src
属性会被忽略。
在此示例中,网页有三种布局,取决于 视口 的宽度。窄布局有一列图像(每个图像的宽度约为 100%),中间布局有两列图像(每个图像的宽度约为
50%),最宽布局有三列图像,并有一些页面边距(每个图像的宽度约为 33%)。在 视口 宽度分别为 30em
和
50em
时,会在这些布局之间切换。
< img sizes = "(max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)"
srcset = "swing-200.jpg 200w, swing-400.jpg 400w, swing-800.jpg 800w, swing-1600.jpg 1600w"
src = "swing-400.jpg" alt = "Kettlebell Swing" >
sizes
属性设置了在 30em
和 50em
处的布局断点,并声明在这些断点之间的图像尺寸为 100vw
、50vw
或
calc(33vw - 100px)
。这些尺寸不一定要与 CSS 中指定的实际图像宽度完全匹配。
用户代理将从 sizes
属性中选择一个宽度,使用第一个返回值为真的 <media-condition>(括号中的部分),或者如果所有条件都评估为假,则使用最后一个值(calc(33vw - 100px)
)。
例如,如果 视口 宽度为 29em
,则 (max-width: 30em)
评估为真,使用
100vw
,因此图像尺寸(用于资源选择)为 29em
。如果 视口 宽度为 32em
,则
(max-width: 30em)
评估为假,但 (max-width: 50em)
评估为真,使用
50vw
,因此图像尺寸(用于资源选择)为
16em
(视口宽度的一半)。注意,稍
宽的 视口 会因为不同的布局而导致图像变小。
用户代理可以像前一个示例一样计算实际的像素密度并选择合适的资源。
此示例与前一个示例相同,但图像是 延迟加载
的。在这种情况下,sizes
属性可以使用
auto
关键字,用户代理将使用 width
属性(或
CSS 中指定的宽度)作为 源大小。
< img loading = "lazy" width = "200" height = "200" sizes = "auto"
srcset = "swing-200.jpg 200w, swing-400.jpg 400w, swing-800.jpg 800w, swing-1600.jpg 1600w"
src = "swing-400.jpg" alt = "Kettlebell Swing" >
为了更好地向后兼容不支持 auto
关键字的旧版用户代理,可以在需要时指定后备尺寸。
< img loading = "lazy" width = "200" height = "200"
sizes = "auto, (max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)"
srcset = "swing-200.jpg 200w, swing-400.jpg 400w, swing-800.jpg 800w, swing-1600.jpg 1600w"
src = "swing-400.jpg" alt = "Kettlebell Swing" >
picture
元素和 source
元素,加上 media
属性,可以用来提供多种图像,图像内容有所不同(例如,小图像可能是大图像的裁剪版本)。
< picture >
< source media = "(min-width: 45em)" srcset = "large.jpg" >
< source media = "(min-width: 32em)" srcset = "med.jpg" >
< img src = "small.jpg" alt = "The wolf runs through the snow." >
</ picture >
用户代理将选择第一个 source
元素,其 media
属性的媒体查询匹配,然后从其 srcset
属性中选择一个合适的 URL。
图像的呈现大小取决于选择的资源。要指定用户代理在下载图像之前可以使用的尺寸,可以使用 CSS。
img { width : 300 px ; height : 300 px }
@media ( min-width: 32em) { img { width: 500px; height:300px } }
@media (min-width: 45em) { img { width: 700px; height:400px } }
type
属性在 source
元素上可以用来提供多种不同格式的图像。
< h2 > From today's featured article</ h2 >
< picture >
< source srcset = "/uploads/100-marie-lloyd.webp" type = "image/webp" >
< source srcset = "/uploads/100-marie-lloyd.jxr" type = "image/vnd.ms-photo" >
< img src = "/uploads/100-marie-lloyd.jpg" alt = "" width = "100" height = "150" >
</ picture >
< p >< b >< a href = "/wiki/Marie_Lloyd" > Marie Lloyd</ a ></ b > (1870–1922)
was an English < a href = "/wiki/Music_hall" > music hall</ a > singer, ...
在这个示例中,用户代理将选择第一个具有受支持 MIME 类型的 type
属性的
source 元素。如果用户代理支持 WebP 图像,将选择第一个 source
元素。如果不支持,但用户代理支持 JPEG XR 图像,将选择第二个 source
元素。如果这两种格式都不支持,将选择 img
元素。
本节为非规范性内容。
CSS 和媒体查询可用于构建根据用户环境动态调整的图形页面布局,特别是针对不同的 视口 尺寸和像素密度。然而,对于内容,CSS
并没有帮助;取而代之的是,我们有 img
元素的 srcset
属性和
picture
元素。本节将通过一个示例说明如何使用这些功能。
考虑一种情况,在宽屏(宽于 600 CSS 像素)上使用名为 a-rectangle.png
的 300×150 图像,但在较小屏幕(600 CSS 像素 及以下)上使用名为 a-square.png
的 100×100 图像。其标记如下所示:
< figure >
< picture >
< source srcset = "a-square.png" media = "(max-width: 600px)" >
< img src = "a-rectangle.png" alt = "Barney Frank wears a suit and glasses." >
</ picture >
< figcaption > Barney Frank, 2011</ figcaption >
</ figure >
有关在 alt
属性中放置内容的详细信息,请参阅提供文本作为图像替代的要求一节。
问题在于,当图像加载时,用户代理不一定知道使用什么尺寸的图像。为了避免在页面加载时多次重新布局,可以使用 CSS 和 CSS 媒体查询来提供尺寸:
< style >
# a { width : 300 px ; height : 150 px ; }
@ media ( max-width : 600px ) { # a { width : 100 px ; height : 100 px ; } }
</ style >
< figure >
< picture >
< source srcset = "a-square.png" media = "(max-width: 600px)" >
< img src = "a-rectangle.png" alt = "Barney Frank wears a suit and glasses." id = "a" >
</ picture >
< figcaption > Barney Frank, 2011</ figcaption >
</ figure >
或者,可以使用 width
和 height
属性来为旧版用户代理提供宽度和高度,仅使用 CSS 为支持 picture
的用户代理提供样式:
< style media = "(max-width: 600px)" >
# a { width : 100 px ; height : 100 px ; }
</ style >
< figure >
< picture >
< source srcset = "a-square.png" media = "(max-width: 600px)" >
< img src = "a-rectangle.png" width = "300" height = "150"
alt = "Barney Frank wears a suit and glasses." id = "a" >
</ picture >
< figcaption > Barney Frank, 2011</ figcaption >
</ figure >
带有img
元素的src
属性,用于提供图像的URL,以便支持不兼容picture
元素的旧版用户代理。这就引出了一个问题:在src
属性中提供哪张图片。
如果作者希望在旧版用户代理中提供最大图像,标记可以如下:
< picture >
< source srcset = "pear-mobile.jpeg" media = "(max-width: 720px)" >
< source srcset = "pear-tablet.jpeg" media = "(max-width: 1280px)" >
< img src = "pear-desktop.jpeg" alt = "The pear is juicy." >
</ picture >
然而,如果旧版移动用户代理更为重要,可以在source
元素中列出所有三个图像,完全覆盖src
属性。
< picture >
< source srcset = "pear-mobile.jpeg" media = "(max-width: 720px)" >
< source srcset = "pear-tablet.jpeg" media = "(max-width: 1280px)" >
< source srcset = "pear-desktop.jpeg" >
< img src = "pear-mobile.jpeg" alt = "The pear is juicy." >
</ picture >
由于此时,支持picture
的用户代理实际上完全忽略了src
属性,因此src
属性可以默认任何图像,包括既不是最小也不是最大的图像:
< picture >
< source srcset = "pear-mobile.jpeg" media = "(max-width: 720px)" >
< source srcset = "pear-tablet.jpeg" media = "(max-width: 1280px)" >
< source srcset = "pear-desktop.jpeg" >
< img src = "pear-tablet.jpeg" alt = "The pear is juicy." >
</ picture >
上述max-width
媒体特性用于指定图像适用的最大(视口)尺寸。也可以使用min-width
。
< picture >
< source srcset = "pear-desktop.jpeg" media = "(min-width: 1281px)" >
< source srcset = "pear-tablet.jpeg" media = "(min-width: 721px)" >
< img src = "pear-mobile.jpeg" alt = "The pear is juicy." >
</ picture >
source
、img
和 link
元素的共同属性srcset 属性 是一个在本节中定义了要求的属性。
如果存在,其值必须由一个或多个 图像候选字符串 组成,每个字符串之间用 U+002C 逗号字符 (,) 分隔。如果一个 图像候选字符串 不包含描述符且 URL 后面没有 ASCII 空白字符,则下一个 图像候选字符串(如果有的话)必须以一个或多个 ASCII 空白字符 开头。
一个 图像候选字符串 由以下组件组成,按顺序排列,并有以下列表中描述的进一步限制:
零个或多个 ASCII 空白字符。
一个 有效的非空 URL,不能以 U+002C 逗号字符 (,) 开头或结尾,引用一个非交互式的、可选动画的图像资源,该资源既不是分页的也不是脚本化的。
零个或多个 ASCII 空白字符。
零个或一个以下项:
一个 宽度描述符,由以下部分组成:ASCII 空白字符,一个 有效的非负整数,表示一个大于零的数字,代表 宽度描述符值,以及一个 U+0077 拉丁小写字母 W 字符。
一个 像素密度描述符,由以下部分组成:ASCII 空白字符,一个 有效的浮点数,表示一个大于零的数字,代表 像素密度描述符值,以及一个 U+0078 拉丁小写字母 X 字符。
零个或多个 ASCII 空白字符。
对于具有相同 宽度描述符值 的元素,不能有一个 图像候选字符串,其值与另一个 图像候选字符串 的 宽度描述符值 相同。
对于具有相同 像素密度描述符值
的元素,不能有一个 图像候选字符串,其值与另一个 图像候选字符串
的
像素密度描述符值
相同。为了满足此要求,没有描述符的 图像候选字符串
等同于具有 1x
描述符的 图像候选字符串。
如果某个元素的 图像候选字符串 指定了 宽度描述符,那么该元素的所有其他 图像候选字符串 也必须指定 宽度描述符。
在 图像候选字符串 的 宽度描述符 中指定的宽度必须与由该 图像候选字符串 的 URL 提供的资源中的 自然宽度 匹配(如果该资源具有 自然宽度)。
如果某个元素具有 sizes 属性,那么该元素的所有 图像候选字符串 必须指定 宽度描述符。
sizes 属性 是一个具有本节定义的要求的属性。
如果存在,该属性的值必须是 有效的源尺寸列表。
有效的源尺寸列表 是一个匹配以下语法的字符串:[CSSVALUES] [MQ]
< source-size-list > = < source-size > #? , < source-size-value >
< source-size > = < media-condition > < source-size-value > | auto
< source-size-value > = < length > | auto
<source-size-value> 如果是一个 <length>,必须是非负的,并且不能使用除 数学函数 之外的 CSS 函数。
关键字 auto
是一个在 解析 sizes
属性 中计算的宽度。如果存在,它必须是第一个条目,整个 <source-size-list> 值必须是字符串 "auto
"(ASCII 不区分大小写)或者以字符串 "auto,
" 开头(ASCII 不区分大小写)。
如果启动了图像加载的 img
元素(通过
更新图像数据 或 响应环境变化
算法)
允许自动尺寸 并且正在 渲染,那么 auto
就是
具体对象尺寸 宽度。否则,auto
值将被忽略,使用下一个 源尺寸(如果有)。
auto
关键字可以在 sizes
属性中指定在
source
元素中,也可以在 sizes
属性中指定在 img
元素中,前提是满足以下条件。否则,不得指定 auto
。
此外,强烈建议使用 width
和
height
属性或使用
CSS
指定尺寸。如果未指定尺寸,图像可能会以 300x150 的尺寸呈现,因为 sizes="auto"
在 渲染部分 中意味着
contain-intrinsic-size: 300px 150px
。
<source-size-value> 提供了图像的预期布局宽度。作者可以使用 <media-condition> 指定不同环境下的不同宽度。
在 <source-size-value> 中不允许使用百分比,以避免混淆其相对参照。可以使用 'vw' 单位来表示相对于 视口 宽度的尺寸。
一个 img
元素有一个 当前请求 和一个 待处理请求。
当前请求 初始设置为一个新的
图像请求。
待处理请求 初始设置为
null。
一个 图像请求 有一个 状态、一个 当前 URL 和一个 图像数据。
当一个 图像请求 的 状态 为 部分可用 或 完全可用 时,该 图像请求 被称为 可用。
当一个 img
元素的
当前请求 的 状态 为 完全可用 并且用户代理能够无错误地解码媒体数据,则该
img
元素被称为 完全可解码。
当一个 img
元素的
当前请求 为 可用 时,该 img
元素提供一个 绘图源,其宽度为图像的 密度校正自然宽度(如果有),高度为图像的 密度校正自然高度(如果有),外观为图像的自然外观。
一个 img
元素被称为 使用 srcset
或 picture
,如果它有一个指定的 srcset
属性,或者如果它的父元素是一个 picture
元素。
每个 img
元素都有一个 最后选择的源,其初始值必须为 null。
每个 图像请求 都有一个 当前像素密度,其初始值必须为 1。
每个 图像请求 都有 首选密度校正尺寸,它要么是包含宽度和高度的结构,要么为 null。初始值必须为 null。
要确定一个 img
元素
img 的 密度校正自然宽度和高度:
例如,如果 当前像素密度 为 3.125,这意味着每 CSS 英寸 有 300 个设备像素,因此如果图像数据为 300x600,则它具有 96 CSS 像素 乘 192 CSS 像素 的 密度校正自然宽度和高度。
一个 源集 是一个有序的零个或多个 图像源 和一个 源大小。
一个 图像源 是一个 URL,并且可以选择地包含一个 像素密度描述符 或一个 宽度描述符。
一个 源大小 是一个 <source-size-value>。当一个 源大小 具有相对于 视口 的单位时,必须相对于 img
元素的 节点文档 的 视口 进行解释。其他单位的解释与媒体查询中相同。[MQ]
本节中的算法的 解析错误 表示输入和要求之间的非致命性不匹配。鼓励用户代理以某种方式公开 解析错误。
在确定图像的类型及其是否为有效图像时,图像是否成功获取(例如,响应状态是否为 成功状态)必须被忽略。
这允许服务器返回带有错误响应的图像,并使其显示出来。
用户代理应该应用 图像嗅探规则 来确定图像的类型,并且图像的 关联内容类型头 给出 official type。如果这些规则没有应用,那么图像的类型必须是图像的 关联内容类型头 给出的类型。
用户代理不得使用 img
元素支持非图像资源(例如,其 文档元素 为 HTML 元素的 XML
文件)。用户代理不得运行嵌入图像资源中的可执行代码(例如,脚本)。用户代理只能显示多页资源的第一页(例如,PDF 文件)。用户代理不得允许资源以交互方式工作,但应尊重资源中的任何动画。
本规范没有指定支持哪些图像类型。
默认情况下,图像会立即获取。用户代理可以为用户提供按需获取图像的选项(例如,带宽受限的用户可能会使用此选项)。
在立即获取图像时,用户代理必须在每次创建元素或发生 相关变更 时,使用 重新启动动画 标志(如果这样规定)同步地 更新图像数据。
在按需获取图像时,用户代理必须在需要图像数据时(即按需) 更新图像数据,但仅在 img
元素的 当前请求 的 状态 为 不可用
时进行。当 img
元素经历了 相关变更
时,如果用户代理仅按需获取图像,则 img
元素的 当前请求 的 状态 必须返回到 不可用。
一个 img
元素的 相关变更 如下:
元素的 crossorigin
属性的状态发生变化。
元素的 referrerpolicy
属性的状态发生变化。
img
或 source
元素的 HTML
元素插入步骤 或 HTML 元素移除步骤 将变更计为 相关变更。
元素的父元素是 picture
元素,并且一个 source
元素作为前一个兄弟元素,其 srcset
,
sizes
,
media
,
type
,
width
或 height
属性被设置、改变或移除。
元素的 采用步骤 被执行。
如果元素 允许自动尺寸:元素开始或停止 被渲染,或其 具体对象尺寸 宽度发生变化。这必须为 更新图像数据 算法设置 可能省略事件 标志。
每个 Document
对象必须有一个 可用图像列表。列表中的每个图像由一个元组标识,该元组包括一个 绝对 URL、一个 CORS 设置属性 模式,以及(如果模式不是 无
CORS)一个 源。
每个图像还有一个 忽略更高层缓存 标志。用户代理可以在任何时候将一个 Document
对象的 可用图像列表
复制到另一个对象(例如,当 Document
被创建时,用户代理可以将其他 Document
中加载的所有图像添加到此列表),但在这样做时不得更改复制条目的键,并且必须取消设置
忽略更高层缓存
标志。用户代理也可以在任何时候从这些列表中移除图像(例如,为了节省内存)。
用户代理必须根据资源的更高层缓存语义(例如 HTTP `Cache-Control
`
响应头)适当地移除 可用图像列表 中的条目,当 忽略更高层缓存
标志未设置时。
可用图像列表 旨在支持在将 src
属性更改为先前已加载的 URL 时的同步切换,并避免在同一文档中重新下载图像,即使它们不允许 HTTP 缓存。它不用于避免在先前图像仍在加载时重新下载相同的图像。
用户代理还可以将图像数据单独存储在 可用图像列表 之外。
例如,如果一个资源具有 HTTP 响应头 `Cache-Control: must-revalidate
`,并且其 忽略更高层缓存
标志未设置,用户代理会从 可用图像列表 中移除它,但可以单独保留图像数据,并在服务器响应
`304 Not Modified
` 状态时使用该数据。
图像数据通常会被编码以减少文件大小。这意味着为了让用户代理将图像呈现到屏幕上,需要对数据进行解码。 解码 是将图像的媒体数据转换为适合屏幕呈现的位图形式的过程。请注意,这一过程相对于其他内容呈现过程可能较慢。因此,用户代理可以选择何时执行解码,以创建最佳的用户体验。
图像解码被称为同步解码如果它在完成之前阻止了其他内容的呈现。通常,这会使图像和其他内容同时原子性地呈现。然而,这种呈现会被解码所需的时间延迟。
图像解码被称为异步解码如果它不会阻止其他内容的呈现。这会使非图像内容的呈现更快。然而,直到解码完成之前,图像内容在屏幕上是缺失的。一旦解码完成,屏幕将更新为图像。
在同步和异步解码模式下,最终内容呈现到屏幕上所经过的时间相同。主要的区别在于用户代理是否在呈现最终内容之前呈现非图像内容。
为了帮助用户代理决定是否执行同步或异步解码,可以在 decoding
属性上设置在 img
元素上。decoding
属性的可能值是以下 图像解码提示 关键字:
关键字 | 状态 | 描述 |
---|---|---|
sync
|
同步 | 表示希望以同步方式 解码 图像,以便与其他内容原子性地呈现。 |
async
|
异步 | 表示希望以异步方式 解码 图像,以避免延迟其他内容的呈现。 |
auto
|
自动 | 表示对解码模式没有偏好(默认值)。 |
在 解码
图像时,用户代理应尊重 decoding
属性状态所指示的偏好。如果指示的状态是 自动,则用户代理可以自由选择任何解码行为。
也可以使用 decode()
方法来控制解码行为。由于 decode()
方法独立于负责内容呈现的过程进行 解码,因此不受 decoding
属性的影响。
此算法不能在运行并行的步骤中调用。如果用户代理需要在运行并行的步骤中调用此算法,则需要排队一个任务来实现。
当用户代理需要更新图像数据的img
元素时,可能设置重新启动动画标志,可能设置可能省略事件标志,必须执行以下步骤:
如果用户代理无法支持图像,或其图像支持已被禁用,则中止图像请求为当前请求和挂起请求,设置当前请求的状态为不可用,设置挂起请求为null,并返回。
让selected source为null,selected pixel density为未定义。
如果元素不使用srcset
或picture
并且它具有指定值不是空字符串的src
属性,则将selected
source设置为元素的src
属性的值,并将selected
pixel density设置为1.0。
将元素的最后选择的源设置为selected source。
如果selected source不为null,则:
让urlString成为编码-解析-序列化URL的结果,给定selected source,相对于元素的节点文档。
如果urlString失败,则中止这组内部步骤。
让key成为一个包含urlString,img
元素的crossorigin
属性的模式的元组,并且,如果该模式不是No
CORS,则是节点文档的来源。
如果可用图像列表中包含key的条目,则:
为该条目设置忽略上层缓存标志。
将待定请求设置为null。
给定img,准备current request进行展示。
在给定img
元素的情况下,将一个元素任务加入队列至DOM
操作任务源,包括以下步骤:
中止更新图像数据算法。
如果此实例之后启动了此算法的另一个实例(即使它中止且不再运行),则返回。
只有最后一个实例生效,以避免在例如依次设置src
、srcset
和crossorigin
属性时出现多个请求。
让selected source和selected pixel density分别为选择图像源的结果的URL和像素密度。
如果selected source为null,则:
让urlString成为编码-解析-序列化URL的结果,给定selected source,相对于元素的节点文档。
如果urlString失败,则:
如果urlString与当前请求的当前URL相同,并且当前请求的状态为部分可用,则中止图像请求为挂起请求,排队一个元素任务在DOM操作任务源上,给定img
元素以重启动画(如果设置了重启动画),并返回。
如果当前请求的状态为不可用或损坏,则将当前请求设置为image request。否则,将挂起请求设置为image request。
让request成为创建潜在的CORS请求的结果,给定urlString、"image
",以及元素的crossorigin
内容属性的当前状态。
如果元素使用srcset
或picture
,则将request的发起者设置为"imageset
"。
将request的引用策略设置为元素的referrerpolicy
属性的当前状态。
将request的优先级设置为元素的fetchpriority
属性的当前状态。
如果img
的懒加载属性处于Eager状态,或禁用脚本用于img
,则让delay
load event为true,否则为false。
开始观察懒加载元素的交叉点用于img
元素。
返回。
获取图像:获取request。从该算法返回,并作为获取的处理响应的一部分运行剩余步骤,响应response。
以这种方式获得的资源(如果有)是image request的图像数据。它可以是CORS-相同来源或CORS-跨来源;这会影响图像与其他API的交互(例如,在画布
上使用时)。
当delay load event为true时,获取图像必须延迟元素的加载事件,直到排队的任务在资源被获取后网络任务源上运行为止(定义如下)。
不幸的是,这可以用来对用户的本地网络执行一个简单的端口扫描(特别是在结合脚本时,尽管实际上不需要脚本来执行此攻击)。用户代理可能会实施比上述描述更严格的跨来源访问控制策略来减轻此攻击,但不幸的是,这些策略通常与现有的网络内容不兼容。
尽快跳转到以下列表中的第一个适用条目:
multipart/x-mixed-replace
下一个在图像被获取时由网络任务源排队的任务必须运行以下步骤:
如果image request是挂起请求,并且至少一个体被完全解码,则中止图像请求为当前请求,并将挂起请求升级为当前请求。
否则,如果image request是挂起请求,并且用户代理能够确定image request的图像在某种致命的方式中损坏,以至于无法获取图像尺寸,则中止图像请求为当前请求,将挂起请求升级为当前请求,并将当前请求的状态设置为损坏。
否则,如果image request是当前请求,其状态为不可用,并且用户代理能够确定image request的图像的宽度和高度,则将当前请求的状态设置为部分可用。
否则,如果image request是当前请求,其状态为不可用,并且用户代理能够确定image request的图像在某种致命的方式中损坏,以至于无法获取图像尺寸,则将当前请求的状态设置为损坏。
当图像正在获取时,由网络任务源
排队的每个任务都必须更新图像的显示,但随着每个新的主体部分的到来,如果用户代理能够确定图像的宽度和高度,则必须根据img
元素
准备img
元素的当前请求以供展示并替换先前的图像。一旦一个主体部分完全解码,执行以下步骤:
下一个在图像被获取时由网络任务源排队的任务必须运行以下步骤:
如果用户代理能够确定image request的图像的宽度和高度,并且image request是挂起请求,则将image request的状态设置为部分可用。
否则,如果用户代理能够确定image request的图像的宽度和高度,并且image request是当前请求,为展示准备image
request给定img
元素,并将image
request的状态设置为部分可用。
否则,如果用户代理能够确定image request的图像在某种致命的方式中损坏,以至于无法获取图像尺寸,并且image request是挂起请求:
否则,如果用户代理能够确定image request的图像在某种致命的方式中损坏,以至于无法获取图像尺寸,并且image request是当前请求:
那个任务,以及每个在图像被获取时由网络任务源排队的后续任务,如果image request是当前请求,必须适当地更新图像的展示(例如,如果图像是渐进式JPEG,每个数据包可以提高图像的分辨率)。
图像数据不是支持的文件格式;用户代理必须将image request的状态设置为损坏,中止图像请求为当前请求和挂起请求,将挂起请求升级为当前请求如果image
request是挂起请求,然后,如果没有设置可能省略事件或previousURL不等于urlString,排队一个元素任务在DOM操作任务源上,给定img
元素以触发一个事件,名称为error
。
当用户代理为元素x运行上述算法时,必须从元素的节点文档到元素x保持一个强引用,即使该元素未连接。
要中止图像请求对于一个图像请求或空的image request,意味着运行以下步骤:
将挂起请求升级为当前请求对于img
元素意味着运行以下步骤:
要为展示准备图像,对于给定的图像元素img和req的图像请求:
让physicalWidth和physicalHeight为从req的图像数据中获得的宽度和高度,由相关编解码器定义。
让dimX为exifTagMap标签0xA002
(PixelXDimension
)的值。
让dimY为exifTagMap标签0xA003
(PixelYDimension
)的值。
让resX为exifTagMap标签0x011A
(XResolution
)的值。
让resY为exifTagMap标签0x011B
(YResolution
)的值。
让resUnit为exifTagMap标签0x0128
(ResolutionUnit
)的值。
如果dimX或dimY不是正整数,则返回。
如果resX或resY不是正浮点数,则返回。
如果resUnit不等于2
(Inch
),则返回。
让widthFromDensity为physicalWidth的值,乘以72并除以resX。
让heightFromDensity为physicalHeight的值,乘以72并除以resY。
如果widthFromDensity不等于dimX或heightFromDensity不等于dimY,则返回。
将req的首选密度校正尺寸设置为一个结构,其宽度设置为dimX,高度设置为dimY。
适当地更新req的img
元素的展示。
EXIF中的分辨率相当于每英寸CSS点,因此72是根据分辨率计算大小的基础。
尚未规定如果EXIF在图像已经展示后到达的情况。见问题#4929。
要选择图像源,给定一个img
元素el:
如果el的source set为空,则返回null作为URL,并返回undefined作为像素密度。
要从source set中选择图像源,给定一个source setsourceSet:
如果sourceSet中的条目b与之前的条目a具有相同的关联像素密度描述符,则删除条目b。重复此步骤,直到sourceSet中的所有条目都不再具有与之前条目相同的关联像素密度描述符。
返回selectedSource及其关联的像素密度。
当被要求创建一个source set,给定字符串default source、字符串srcset、字符串sizes以及元素或null的img:
令source set为一个空的source set。
如果srcset不是空字符串,则将source set设置为解析srcset的结果。
令source size为解析sizes与img的结果。
如果default source不是空字符串,并且source set不包含具有像素密度描述符值为1的图像源,并且没有具有宽度描述符的图像源,则将default source附加到source set。
规范化source set的源密度。
返回source set。
当被要求为给定的img
或link
元素el更新source
set时,用户代理必须执行以下操作:
将el的source set设置为空的source set。
令elements为« el »。
如果el是img
元素,则令img为el,否则为null。
对于elements中的每个child:
如果child是el:
令default source为空字符串。
令srcset为空字符串。
令sizes为空字符串。
否则,如果el是具有imagesrcset
属性的link
元素,则将srcset设置为该属性的值。
否则,如果el是具有imagesizes
属性的link
元素,则将sizes设置为该属性的值。
令el的source set为给定default source、srcset、sizes和img时创建的source set的结果。
返回。
如果el是link
元素,那么elements仅包含el,因此此步骤将立即达到,算法的其余部分将不会运行。
解析child的srcset属性,并将返回的source set作为source set。
解析child的sizes属性,并将source set的source size设置为返回的值。
如果child具有width
或height
属性,则将el的尺寸属性源设置为child。否则,将el的尺寸属性源设置为el。
规范化source set的源密度。
将el的source set设置为source set。
返回。
每个img
元素单独考虑其前一个兄弟source
元素加上img
元素本身来选择图像源,忽略任何其他(无效的)元素,包括同一个picture
元素中的其他img
元素,或作为相关img
元素的后续兄弟的source
元素。
当被要求从元素解析srcset 属性时,解析元素的srcset 属性的值如下:
令input为传递给此算法的值。
令position为input中的指针,初始指向字符串的开头。
令candidates为初始为空的source set。
分割循环:收集由position给定的input中是ASCII空白字符或U+002C 逗号字符的代码点序列。如果收集到任何U+002C 逗号字符,这是一个解析错误。
如果position已超过input的末尾,返回candidates。
令descriptors为一个新的空列表。
如果url以U+002C (,)结尾,则:
从url中移除所有尾随的U+002C 逗号字符。如果移除了多个字符,这是一个解析错误。
否则:
描述符分词器:跳过由position给定的input中的ASCII空白字符。
令current descriptor为空字符串。
令state为在描述符中。
令c为position处的字符。根据state的值执行以下操作。对于此步骤的目的,“EOF”是一个特殊字符,表示position已超过input的末尾。
根据c的值执行以下操作:
如果current descriptor不为空,将current descriptor追加到descriptors中,并将current descriptor设为空字符串。将state设为在描述符之后。
将position推进到input中的下一个字符。如果current descriptor不为空,将current descriptor追加到descriptors中。跳到标记为描述符解析器的步骤。
将c追加到current descriptor中。将state设为在括号中。
如果current descriptor不为空,将current descriptor追加到descriptors中。跳到标记为描述符解析器的步骤。
将c追加到current descriptor中。
根据c的值执行以下操作:
将c追加到current descriptor中。将state设为在描述符中。
将current descriptor追加到descriptors中。跳到标记为描述符解析器的步骤。
将c追加到current descriptor中。
根据c的值执行以下操作:
保持在此状态。
跳到标记为描述符解析器的步骤。
将state设为在描述符中。将position设为input中的前一个字符。
将position推进到input中的下一个字符。重复此步骤。
为了与将来的添加兼容,此算法支持多个描述符和带括号的描述符。
描述符解析器:令error为否。
令width为不存在。
令density为不存在。
令future-compat-h为不存在。
对于descriptors中的每个描述符,执行以下列表中的相应步骤:
如果future-compat-h不是不存在且width是不存在,令error为是。
如果error仍然是否,则向candidates追加一个新的图像源,其URL为url,宽度为width(如果不是不存在),像素密度为density(如果不是不存在)。否则,这是一个解析错误。
返回到标记为分割循环的步骤。
当被要求从一个元素element解析sizes 属性,并且有一个img
元素或null
img时:
令unparsed sizes list为解析element的sizes 属性的值(或空字符串,如果属性不存在)后的结果。[CSSSYNTAX]
令size为null。
对于unparsed sizes list中的每个unparsed size:
从unparsed size的末尾移除所有连续的<whitespace-token>。如果unparsed size现在为空,则这是一个解析错误;继续。
如果unparsed size中的最后一个组件值是一个有效的非负<source-size-value>,则将size设为其值并从unparsed size中移除该组件值。除数学函数外的任何CSS函数都是无效的。否则,这是一个解析错误;继续。
如果size是auto
,并且img不是null,并且img正在渲染,并且img允许自动尺寸,则将size设为img的具体对象尺寸宽度,以CSS像素为单位。
如果size仍然是auto
,则它将被忽略。
从unparsed size的末尾移除所有连续的<whitespace-token>。如果unparsed size现在为空:
将unparsed size中的剩余组件值解析为<media-condition>。如果它未正确解析,或者它正确解析但<media-condition>的结果为false,继续。[MQ]
如果size不是auto
,则返回size。否则,继续。
返回100vw
。
使用一个不带<media-condition>的裸<source-size-value>(作为一个<length>)作为一个不在列表末尾的<source-size-list>条目是无效的。然而,解析
算法允许它出现在<source-size-list>中的任何位置,并且如果列表中的前一个条目未被使用,则会立即接受它作为尺寸。这是为了支持将来的扩展,并防止简单的作者错误,例如最后的尾随逗号。一个裸的auto
关键字被允许有其他条目跟在其后,以为遗留的用户代理提供回退。
图像源可以有一个像素密度描述符、一个宽度描述符,或者伴随其URL没有任何描述符。规范化源集会给每个图像源一个像素密度描述符。
当要求规范化源密度时,对于一个 源集合 source set,用户代理必须执行以下操作:
用户代理可以随时运行以下算法,以更新img
元素的图像,以应对环境变化。(用户代理不需要运行此算法;例如,如果用户不再查看页面,用户代理可能会等到用户返回页面后再确定使用哪个图像,以防在此期间环境再次变化。)
用户代理特别鼓励在用户更改视口大小(例如,通过调整窗口大小或更改页面缩放),以及将img
元素插入到文档中时运行此算法,以使密度校正后的自然宽度和高度匹配新的视口,并在涉及艺术指导时选择正确的图像。
⌛ 如果img
元素没有使用srcset
或picture
,其节点文档不完全活动,具有资源类型为multipart/x-mixed-replace
的图像数据,或挂起请求不为null,则返回。
⌛ 令selected source和selected pixel density分别为选择图像源的URL和像素密度的结果。
⌛ 如果selected source为null,则返回。
⌛ 如果selected source和selected pixel density与元素的最后选择的源和当前像素密度相同,则返回。
⌛ 令urlString为编码、解析和序列化URL的结果,给定selected source,相对于元素的节点文档。
⌛ 如果urlString失败,则返回。
⌛ 令corsAttributeState为元素的crossorigin
内容属性的状态。
⌛ 令key为一个元组,包含urlString、corsAttributeState,如果corsAttributeState不为无CORS,则包含origin。
⌛ 令元素的挂起请求为image request。
如果可用图像列表中包含key的条目,则将image request的图像数据设置为该条目的图像数据。继续下一步。
否则:
令request为创建潜在的CORS请求的结果,给定urlString、"image
"和corsAttributeState。
将request的引用策略设置为元素的referrerpolicy
属性的当前状态。
将request的优先级设置为元素的fetchpriority
属性的当前状态。
令response为获取request的结果。
如果response的不安全响应是网络错误或如果图像格式不受支持(通过应用图像嗅探规则确定),或如果用户代理能够确定image
request的图像以某种致命方式损坏,导致无法获取图像尺寸,或如果资源类型为multipart/x-mixed-replace
,则将挂起请求设为null并中止这些步骤。
否则,response的不安全响应是image request的图像数据。它可以是CORS-同源或CORS-跨源;这会影响图像与其他API的交互(例如,在canvas
上使用时)。
除非另有规定,alt
属性必须指定且其值不能为空;其值必须是图像的适当替代。alt
属性的具体要求取决于图像的表示目的,如以下部分所述。
编写替代文字时要考虑的最一般规则是:意图是用 alt
属性的文字替换每个图像不会改变页面的意义。
因此,一般来说,可以通过考虑如果不能包含图像时会写什么来编写替代文字。
由此引申出 alt
属性的值不应包含可视为图像的说明、标题或图例的文字。它应该包含用户可以替代图像使用的替代文字,而不是补充图像。title
属性可以用于补充信息。
另一个引申点是 alt
属性的值不应重复已经在图像旁边的文章中提供的信息。
考虑替代文字的一种方法是思考如何通过电话阅读包含图像的页面,而不提及存在图像。你用来替代图像的内容通常是编写替代文字的良好开端。
当创建超链接的a
元素或button
元素没有文本内容但包含一个或多个图像时,alt
属性必须包含传达链接或按钮目的的文本。
在此示例中,用户被要求从三个颜色列表中选择他们喜欢的颜色。每种颜色由图像表示,但对于配置用户代理不显示图像的用户,使用颜色名称代替:
< h1 > Pick your color</ h1 >
< ul >
< li >< a href = "green.html" > < img src = "green.jpeg" alt = "Green" > </ a ></ li >
< li >< a href = "blue.html" > < img src = "blue.jpeg" alt = "Blue" > </ a ></ li >
< li >< a href = "red.html" > < img src = "red.jpeg" alt = "Red" > </ a ></ li >
</ ul >
在此示例中,每个按钮都有一组图像以指示用户所需的颜色输出类型。每种情况下第一个图像用于提供替代文本。
< button name = "rgb" > < img src = "red" alt = "RGB" >< img src = "green" alt = "" >< img src = "blue" alt = "" > </ button >
< button name = "cmyk" > < img src = "cyan" alt = "CMYK" >< img src = "magenta" alt = "" >< img src = "yellow" alt = "" >< img src = "black" alt = "" > </ button >
由于每个图像代表文字的一部分,也可以这样写:
< button name = "rgb" > < img src = "red" alt = "R" >< img src = "green" alt = "G" >< img src = "blue" alt = "B" > </ button >
< button name = "cmyk" > < img src = "cyan" alt = "C" >< img src = "magenta" alt = "M" >< img src = "yellow" alt = "Y" >< img src = "black" alt = "K" > </ button >
但是,使用其他替代文字时,这可能行不通,在每种情况下将所有替代文字放入一个图像中可能更有意义:
< button name = "rgb" > < img src = "red" alt = "sRGB profile" >< img src = "green" alt = "" >< img src = "blue" alt = "" > </ button >
< button name = "cmyk" > < img src = "cyan" alt = "CMYK profile" >< img src = "magenta" alt = "" >< img src = "yellow" alt = "" >< img src = "black" alt = "" > </ button >
有时,图形形式可以更清晰地表达某些内容,例如流程图、图解、图形或显示方向的简单地图。在这种情况下,可以使用img
元素来提供图像,但仍必须提供较少的文本版本,以便无法查看图像的用户(例如,由于连接非常慢,或因为他们使用的是纯文本浏览器,或者因为他们通过免提汽车语音网页浏览器听取页面,或者因为他们是盲人)仍然能够理解所传达的信息。
文本必须在alt
属性中给出,必须传达与src
属性中指定的图像相同的信息。
重要的是要意识到,替代文本是图像的替代,而不是图像的描述。
在以下示例中,我们有一个以图像形式显示的流程图,alt
属性中的文本以散文形式重新表述流程图:
< p > In the common case, the data handled by the tokenization stage
comes from the network, but it can also come from script.</ p >
< p > < img src = "images/parsing-model-overview.svg" alt = "The Network
passes data to the Input Stream Preprocessor, which passes it to the
Tokenizer, which passes it to the Tree Construction stage. From there,
data goes to both the DOM and to Script Execution. Script Execution is
linked to the DOM, and, using document.write(), passes data to the
Tokenizer." > </ p >
这里是另一个示例,显示了在描述中包含图像问题的好解决方案和坏解决方案。
首先,这是好的解决方案。此示例显示了如果图像从未存在,替代文本应该是你会放在散文中的内容。
<!-- This is the correct way to do things. -->
< p >
You are standing in an open field west of a house.
< img src = "house.jpeg" alt = "The house is white, with a boarded front door." >
There is a small mailbox here.
</ p >
其次,这是坏的解决方案。在这种错误的做法中,替代文本只是图像的描述,而不是图像的文字替代。这是错误的,因为当图像不显示时,文本的流畅性不如第一个示例。
<!-- This is the wrong way to do things. -->
< p >
You are standing in an open field west of a house.
< img src = "house.jpeg" alt = "A white house, with a boarded front door." >
There is a small mailbox here.
</ p >
类似“Photo of white house with boarded door”这样的文字也会是糟糕的替代文本(尽管它可能适合用于title
属性或带有此图像的figcaption
元素中的figure
元素)。
文档可以包含图标形式的信息。图标旨在帮助视觉浏览器用户一眼就能识别功能。
在某些情况下,图标是传达相同意义的文本标签的补充。在这些情况下,alt
属性必须存在但必须为空。
这里图标在传达相同意义的文本旁边,所以它们的alt
属性为空:
< nav >
< p >< a href = "/help/" > < img src = "/icons/help.png" alt = "" > Help</ a ></ p >
< p >< a href = "/configure/" > < img src = "/icons/configuration.png" alt = "" >
Configuration Tools</ a ></ p >
</ nav >
在其他情况下,图标旁边没有描述其含义的文本;图标应是自解释的。在这些情况下,必须在alt
属性中给出等效的文本标签。
这里,新闻网站上的文章用图标标明其主题。
< body >
< article >
< header >
< h1 > Ratatouille wins < i > Best Movie of the Year</ i > award</ h1 >
< p > < img src = "movies.png" alt = "Movies" > </ p >
</ header >
< p > Pixar has won yet another < i > Best Movie of the Year</ i > award,
making this its 8th win in the last 12 years.</ p >
</ article >
< article >
< header >
< h1 > Latest TWiT episode is online</ h1 >
< p > < img src = "podcasts.png" alt = "Podcasts" > </ p >
</ header >
< p > The latest TWiT episode has been posted, in which we hear
several tech news stories as well as learning much more about the
iPhone. This week, the panelists compare how reflective their
iPhones' Apple logos are.</ p >
</ article >
</ body >
许多页面包含标志、徽章、旗帜或徽章,这些代表特定实体,如公司、组织、项目、乐队、 软件包、国家等。
如果标志用于表示实体,例如作为页面标题,alt
属性必须包含标志所代表的实体的名称。alt
属性不得包含“标志”这样的文字,因为传达的不是它是标志这一事实,而是实体本身。
如果标志用于表示其代表的实体名称旁边,则该标志是补充性的,其alt
属性必须为空。
如果标志仅作为装饰材料使用(作为品牌,或例如作为文章中提到的标志所属实体的旁边图像),则适用下文关于纯装饰图像的条目。如果标志实际上正在被讨论,则它被用作带有替代图形表示的短语或段落(标志的描述),并适用上面的第一个条目。
在以下片段中,出现了上述四种情况。首先,我们看到一个标志用于代表公司:
< h1 > < img src = "XYZ.gif" alt = "The XYZ company" > </ h1 >
接下来,我们看到一个段落,使用一个标志在公司名称旁边,所以没有任何替代文本:
< article >
< h2 > News</ h2 >
< p > We have recently been looking at buying the < img src = "alpha.gif"
alt = "" > ΑΒΓ company, a small Greek company
specializing in our type of product.</ p >
在第三个片段中,我们看到一个标志被用作旁注,作为讨论收购的更大文章的一部分:
< aside >< p >< img src = "alpha-large.gif" alt = "" ></ p ></ aside >
< p > The ΑΒΓ company has had a good quarter, and our
pie chart studies of their accounts suggest a much bigger blue slice
than its green and orange slices, which is always a good sign.</ p >
</ article >
最后,我们有一篇关于标志的评论文章,因此替代文本中详细描述了该标志。
< p > Consider for a moment their logo:</ p >
< p >< img src = "/images/logo" alt = "It consists of a green circle with a
green question mark centered inside it." ></ p >
< p > How unoriginal can you get? I mean, oooooh, a question mark, how
< em > revolutionary</ em > , how utterly < em > ground-breaking</ em > , I'm
sure everyone will rush to adopt those specifications now! They could
at least have tried for some sort of, I don't know, sequence of
rounded squares with varying shades of green and bold white outlines,
at least that would look good on the cover of a blue book.</ p >
此示例显示了替代文本应如何编写,以便如果图像不可用,使用文本时,文本能够无缝地融入周围的文本,就像图像从未存在过一样。
有时,图像仅由文本组成,图像的目的是传达文本本身,而不是突出用于呈现文本的实际排版效果。
在这种情况下,alt
属性必须存在,但其内容必须与图像本身的文本相同。
考虑一个包含“Earth Day”文本的图形,但字母上都装饰有花卉和植物。如果文本仅用作标题,为图形用户增加页面趣味,那么正确的替代文本就是相同的文本“Earth Day”,无需提及装饰:
< h1 > < img src = "earthdayheading.png" alt = "Earth Day" > </ h1 >
在照明手稿中,某些图像可能会使用图形。在这种情况下的替代文本只是图像所代表的字符。
< p >< img src = "initials/o.svg" alt = "O" > nce upon a time and a long long time ago, late at
night, when it was dark, over the hills, through the woods, across a great ocean, in a land far
away, in a small house, on a hill, under a full moon...
当图像用于表示无法用Unicode表示的字符时,例如外字、异体字或新字符(如新货币符号),替代文本应为更常规的书写方式,例如使用平假名或片假名给出字符的发音。
在1997年的这个例子中,一个看起来像带有两个横线而不是一个的花体E的新货币符号用图像表示。替代文本给出了字符的发音。
< p > Only < img src = "euro.png" alt = "euro " > 5.99!
如果字符可以达到相同的目的,则不应使用图像。只有当文本不能直接用文本表示时,例如由于装饰或没有适当的字符(如外字的情况),才应使用图像。
如果作者因为其默认系统字体不支持某个字符而想使用图像,那么网络字体比图像更好的解决方案。
在许多情况下,图像实际上只是补充,其存在只是加强了周围的文本。在这些情况下,alt
属性必须存在,但其值必须为空字符串。
一般来说,如果删除图像不会使页面的实用性降低,但包括图像会使视觉浏览器的用户更容易理解概念,那么图像就属于这一类。
以下是以图形形式重复前一段的流程图:
< p > The Network passes data to the Input Stream Preprocessor, which
passes it to the Tokenizer, which passes it to the Tree Construction
stage. From there, data goes to both the DOM and to Script Execution.
Script Execution is linked to the DOM, and, using document.write(),
passes data to the Tokenizer.</ p >
< p >< img src = "images/parsing-model-overview.svg" alt = "" ></ p >
在这些情况下,仅包含一个标题的替代文本是错误的。如果要包括标题,可以使用title
属性,或者使用figure
和figcaption
元素。在后一种情况下,图像实际上是带有替代图形表示的短语或段落,因此需要替代文本。
<!-- Using the title="" attribute -->
< p > The Network passes data to the Input Stream Preprocessor, which
passes it to the Tokenizer, which passes it to the Tree Construction
stage. From there, data goes to both the DOM and to Script Execution.
Script Execution is linked to the DOM, and, using document.write(),
passes data to the Tokenizer.</ p >
< p > < img src = "images/parsing-model-overview.svg" alt = ""
title = "Flowchart representation of the parsing model." > </ p >
<!-- Using <figure> and <figcaption> -->
< p > The Network passes data to the Input Stream Preprocessor, which
passes it to the Tokenizer, which passes it to the Tree Construction
stage. From there, data goes to both the DOM and to Script Execution.
Script Execution is linked to the DOM, and, using document.write(),
passes data to the Tokenizer.</ p >
< figure >
< img src = "images/parsing-model-overview.svg" alt = "The Network leads to
the Input Stream Preprocessor, which leads to the Tokenizer, which
leads to the Tree Construction stage. The Tree Construction stage
leads to two items. The first is Script Execution, which leads via
document.write() back to the Tokenizer. The second item from which
Tree Construction leads is the DOM. The DOM is related to the Script
Execution." >
< figcaption > Flowchart representation of the parsing model.</ figcaption >
</ figure >
<!-- This is WRONG. Do not do this. Instead, do what the above examples do. -->
< p > The Network passes data to the Input Stream Preprocessor, which
passes it to the Tokenizer, which passes it to the Tree Construction
stage. From there, data goes to both the DOM and to Script Execution.
Script Execution is linked to the DOM, and, using document.write(),
passes data to the Tokenizer.</ p >
< p >< img src = "images/parsing-model-overview.svg"
alt = "Flowchart representation of the parsing model." ></ p >
<!-- Never put the image's caption in the alt="" attribute! -->
以下是以图形形式重复前一段的图表:
< p > According to a study covering several billion pages,
about 62% of documents on the web in 2007 triggered the Quirks
rendering mode of web browsers, about 30% triggered the Almost
Standards mode, and about 9% triggered the Standards mode.</ p >
<
p >< img src = "rendering-mode-pie-chart.png" alt = "" ></ p >
有时,图像对内容并非至关重要,但也不是纯装饰或完全与文本重复。在这些情况下,alt
属性必须存在,其值应为空字符串或该图像所传达信息的文本表示。如果图像有标题说明图像的标题,那么alt
属性的值不应为空(因为这对非视觉读者来说会很困惑)。
考虑一篇关于政治人物的新闻文章,其中个人的脸部显示在图像中。图像不是纯装饰性的,因为它与故事相关。图像也不是完全与故事重复,因为它显示了政治家的外貌。是否需要提供任何替代文本是一个创作决定,取决于图像是否影响了文章的解释。
在第一个变体中,图像没有上下文,未提供替代文本:
< p > < img src = "president.jpeg" alt = "" > Ahead of today's referendum,
the President wrote an open letter to all registered voters. In it, she admitted that the country was
divided.</ p >
如果图片只是脸部,描述它可能没有意义。读者不关心这个人是红发还是金发,是白皮肤还是黑皮肤,是一只眼睛还是两只眼睛。
然而,如果图片更具动态性,例如显示政治家愤怒、特别高兴或沮丧,那么一些替代文本在设定文章基调方面会很有用,否则可能会错过这一点:
< p > < img src = "president.jpeg" alt = "The President is sad." >
Ahead of today's referendum, the President wrote an open letter to all
registered voters. In it, she admitted that the country was divided.
</ p >
< p > < img src = "president.jpeg" alt = "The President is happy!" >
Ahead of today's referendum, the President wrote an open letter to all
registered voters. In it, she admitted that the country was divided.
</ p >
总统“悲伤”还是“高兴”会影响如何解释其余的段落:她可能是在说她对国家的分裂感到不满,还是在说国家分裂的前景对她的政治生涯有利?根据图像的不同,解释也会不同。
如果图像有标题,那么包括替代文本可以避免让非视觉用户对标题所指内容感到困惑。
< p > Ahead of today's referendum, the President wrote an open letter to
all registered voters. In it, she admitted that the country was divided.</ p >
< figure >
< img src = "president.jpeg"
alt = "A high forehead, cheerful disposition, and dark hair round out the President's face." >
< figcaption > The President of Ruritania. Photo © 2014 PolitiPhoto. </ figcaption >
</ figure >
如果图像是装饰性的,但并不是特别针对页面的——例如作为整个网站设计方案的一部分——图像应该在网站的CSS中指定,而不是在文档的标记中。
然而,一个装饰性图像虽然没有被周围的文本讨论,但仍有一定的相关性,可以使用img
元素包含在页面中。这类图像是装饰性的,但仍构成内容的一部分。在这些情况下,alt
属性必须存在,但其值必须为空字符串。
尽管图像相关,但纯装饰性的示例包括在关于火人节活动的博客文章中展示黑岩城景观的照片,或者在朗诵某首诗的页面上展示受该诗启发的绘画图像。以下片段显示了后一种情况的示例(此片段仅包括第一节):
< h1 > The Lady of Shalott</ h1 >
< p >< img src = "shalott.jpeg" alt = "" ></ p >
< p > On either side the river lie< br >
Long fields of barley and of rye,< br >
That clothe the wold and meet the sky;< br >
And through the field the road run by< br >
To many-tower'd Camelot;< br >
And up and down the people go,< br >
Gazing where the lilies blow< br >
Round an island there below,< br >
The island of Shalott.</ p >
当一幅图片被切割成较小的图像文件,然后再一起显示以组成完整的图片时,其中一个图像的 alt
属性必须按照适用于整幅图片的相关规则进行设置,然后所有剩余的图像的 alt
属性必须设置为空字符串。
在以下示例中,一幅代表 XYZ Corp 公司标志的图片被切割成两部分,第一部分包含字母 "XYZ",第二部分包含单词 "Corp"。替代文本("XYZ Corp")全部在第一张图片中。
< h1 > < img src = "logo1.png" alt = "XYZ Corp" >< img src = "logo2.png" alt = "" > </ h1 >
在以下示例中,评分以三个填充的星星和两个空心的星星显示。虽然替代文本可以是 "★★★☆☆",但作者决定更有帮助地将评分以 "3 out of 5" 的形式提供。这是第一张图片的替代文本,其余图片的替代文本为空。
< p > Rating: < meter max = 5 value = 3 > < img src = "1" alt = "3 out of 5"
>< img src = "1" alt = "" >< img src = "1" alt = "" >< img src = "0" alt = ""
>< img src = "0" alt = "" > </ meter ></ p >
一般来说,应该使用图片映射,而不是切割图片来创建链接。
然而,如果图片确实被切割,并且切割后的任何组件是链接的唯一内容,则每个链接的图片必须在其alt
属性中有替代文本,表示链接的目的。
在以下示例中,一张图片展示了飞行意大利面怪物的徽标,左侧的面条状附肢和右侧的面条状附肢被分成不同的图片,以便用户可以在冒险中选择左侧或右侧。
< h1 > The Church</ h1 >
< p > You come across a flying spaghetti monster. Which side of His
Noodliness do you wish to reach out for?</ p >
< p >< a href = "?go=left" >< img src = "fsm-left.png" alt = "Left side. " ></ a
>< img src = "fsm-middle.png" alt = ""
>< a href = "?go=right" >< img src = "fsm-right.png" alt = "Right side." ></ a ></ p >
在某些情况下,图片是内容的关键部分。例如,在一个照片画廊页面中,图片是页面的整个重点。
如何为关键内容的图片提供替代文本取决于图片的来源。
当可以提供详细的替代文本时,例如图片是杂志评论中的一系列截图的一部分,或是漫画条的一部分,或是关于该照片的博客文章中的照片,必须在alt
属性中提供可以替代图片的文本。
在一个新操作系统的截图画廊中的一张截图,带有一些替代文本:
< figure >
< img src = "KDE%20Light%20desktop.png"
alt = "The desktop is blue, with icons along the left hand side in
two columns, reading System, Home, K-Mail, etc. A window is
open showing that menus wrap to a second line if they
cannot fit in the window. The window has a list of icons
along the top, with an address bar below it, a list of
icons for tabs along the left edge, a status bar on the
bottom, and two panes in the middle. The desktop has a bar
at the bottom of the screen with a few buttons, a pager, a
list of open applications, and a clock." >
< figcaption > Screenshot of a KDE desktop.</ figcaption >
</ figure >
财务报告中的一张图表:
< img src = "sales.gif"
title = "Sales graph"
alt = "From 1998 to 2005, sales increased by the following percentages
with each year: 624%, 75%, 138%, 40%, 35%, 9%, 21%" >
请注意,“销售图表”对于销售图表来说是不够的替代文本。适合作为标题的文本通常不适合作为替代文本。
在某些情况下,图像的性质可能使得提供详细的替代文本不切实际。例如,图像可能模糊不清,或是复杂的分形图案,或是详细的地形图。
在这些情况下,alt
属性必须包含一些合适的替代文本,但可以相对简短。
有时确实没有任何文本可以充分描述一张图像。例如,对于罗夏墨迹测试图,很难用有用的文字来描述。然而,即使是简短的描述,也总比没有要好:
< figure >
< img src = "/commons/a/a7/Rorschach1.jpg" alt = "A shape with left-right
symmetry with indistinct edges, with a small gap in the center, two
larger gaps offset slightly from the center, with two similar gaps
under them. The outline is wider in the top half than the bottom
half, with the sides extending upwards higher than the center, and
the center extending below the sides." >
< figcaption > A black outline of the first of the ten cards
in the Rorschach inkblot test.</ figcaption >
</ figure >
请注意,以下做法会是替代文本的非常糟糕的使用:
<!-- This example is wrong. Do not copy it. -->
< figure >
< img src = "/commons/a/a7/Rorschach1.jpg" alt = "A black outline
of the first of the ten cards in the Rorschach inkblot test." >
< figcaption > A black outline of the first of the ten cards
in the Rorschach inkblot test.</ figcaption >
</ figure >
将标题包含在替代文本中并没有什么用,因为这样做实际上是对那些无法查看图像的用户重复了一遍标题,让他们感到困扰,而不会比只读或听一次标题更有帮助。
另一个无法完全描述的图像的例子是分形图,它本质上是无限细节的。
以下示例展示了一种可能的方式来为曼德布罗特集的完整视图提供替代文本。
< img src = "ms1.jpeg" alt = "The Mandelbrot set appears as a cardioid with
its cusp on the real axis in the positive direction, with a smaller
bulb aligned along the same center line, touching it in the negative
direction, and with these two shapes being surrounded by smaller bulbs
of various sizes." >
同样,一张人的面部照片,例如在传记中,可以被认为是非常相关且关键的内容,但为其提供完全替代的文本可能很困难:
< section class = "bio" >
< h1 > A Biography of Isaac Asimov</ h1 >
< p > Born < b > Isaak Yudovich Ozimov</ b > in 1920, Isaac was a prolific author.</ p >
< p >< img src = "headpics/asimov.jpeg" alt = "Isaac Asimov had dark hair, a tall forehead, and wore glasses.
Later in life, he wore long white sideburns." ></ p >
< p > Asimov was born in Russia, and moved to the US when he was three years old.</ p >
< p > ...</ p >
</ section >
在这种情况下,在替代文本中包含对图像本身存在的引用是不必要的(实际上也是不鼓励的),因为这些文本与浏览器报告图像存在本身是重复的。例如,如果替代文本是“艾萨克·阿西莫夫的照片”,则符合标准的用户代理可能会读作“(图像)艾萨克·阿西莫夫的照片”,而不是更有用的“(图像)艾萨克·阿西莫夫有深色头发、高额头,戴着眼镜……”。
在一些不幸的情况下,可能完全没有可用的替代文本,要么是因为图像是通过某种自动化方式获取的,没有任何关联的替代文本(例如,网络摄像头),要么是因为页面是通过脚本生成的,用户提供的图像没有提供合适或可用的替代文本(例如,照片共享网站),要么是因为作者自己不知道图像代表什么(例如,一个盲人摄影师在他们的博客上分享图像)。
在这种情况下,alt
属性可以省略,但还必须满足以下条件之一:
img
元素位于一个
figure
元素中,该元素包含一个 figcaption
元素,该元素包含
除了元素间空白之外的内容,并且忽略
figcaption
元素及其后代,figure
元素没有
流内容后代,除了元素间空白和img
元素。
title
属性存在且具有非空值。
依赖于title
属性目前不推荐使用,因为许多用户代理并不以本规范要求的可访问方式公开该属性(例如,需要鼠标等指针设备来触发工具提示的显示,这排除了仅使用键盘和仅使用触摸的用户,例如使用现代手机或平板电脑的用户)。
这种情况应保持在绝对最低限度。如果作者有可能提供真实的替代文本,那么省略alt
属性是不被接受的。
在一个照片分享网站上,如果网站收到的图像没有任何元数据,只包含说明,可以这样标记:
< figure >
< img src = "1100670787_6a7c664aef.jpg" >
< figcaption > Bubbles traveled everywhere with us.</ figcaption >
</ figure >
然而,如果能够从用户那里获得图像的重要部分的详细描述并将其包含在页面上,那将更好。
一个盲人用户的博客中显示了一张由用户拍摄的照片。最初,用户可能不知道他们拍摄的照片展示了什么:
< article >
< h1 > I took a photo</ h1 >
< p > I went out today and took a photo!</ p >
< figure >
< img src = "photo2.jpeg" >
< figcaption > A photograph taken blindly from my front porch.</ figcaption >
</ figure >
</ article >
然而,用户最终可能会从他们的朋友那里获得图像的描述,并可以添加替代文本:
< article >
< h1 > I took a photo</ h1 >
< p > I went out today and took a photo!</ p >
< figure >
< img src = "photo2.jpeg" alt = "The photograph shows my squirrel
feeder hanging from the edge of my roof. It is half full, but there
are no squirrels around. In the background, out-of-focus trees fill the
shot. The feeder is made of wood with a metal grate, and it contains
peanuts. The edge of the roof is wooden too, and is painted white
with light blue streaks." >
< figcaption > A photograph taken blindly from my front porch.</ figcaption >
</ figure >
</ article >
有时,图像的全部意义在于无法提供文本描述,用户需要提供描述。例如,CAPTCHA 图像的目的就是查看用户是否能够字面上读取图形。这里是标记 CAPTCHA 的一种方式(注意 title
属性):
< p >< label > What does this image say?
< img src = "captcha.cgi?id=8934" title = "CAPTCHA" >
< input type = text name = captcha ></ label >
(If you cannot see the image, you can use an < a
href = "?audio" > audio</ a > test instead.)</ p >
另一个示例是显示图像并要求提供替代文本的软件,目的是然后编写具有正确替代文本的页面。这样的页面可以包含一个图像表格,如下所示:
< table >
< thead >
< tr > < th > Image < th > Description
< tbody >
< tr >
< td > < img src = "2421.png" title = "Image 640 by 100, filename 'banner.gif'" >
< td > < input name = "alt2421" >
< tr >
< td > < img src = "2422.png" title = "Image 200 by 480, filename 'ad3.gif'" >
< td > < input name = "alt2422" >
</ table >
请注意,即使在这个示例中,也尽可能多地在title
属性中包含有用的信息。
由于一些用户根本无法使用图像(例如,因为他们的连接非常慢,或因为他们使用的是仅文本浏览器,或因为他们正在使用免提汽车语音网页浏览器来听页面内容,或仅仅因为他们是盲人),alt
属性只允许在没有替代文本且无法提供替代文本时省略,而不是提供替代文本,如上例所示。缺乏作者的努力不是省略alt
属性的可接受理由。
一般来说,作者应避免将img
元素用于显示图像以外的其他目的。
如果img
元素用于显示图像以外的其他目的,例如作为页面浏览量统计的一部分,则alt
属性必须为空字符串。
本节不适用于公开访问的文档,或其目标受众不一定为作者个人认识的人,例如网站上的文档、发送到公开邮件列表的电子邮件或软件文档。
当图像包含在针对特定且已知能够查看图像的个人的私人通信(例如HTML电子邮件)中时,alt
属性可以省略。然而,即使在这种情况下,仍强烈建议作者包括替代文本(根据图像的类型,如上所述),以便在用户使用不支持图像的邮件客户端时,电子邮件仍然可以使用,或者在文档被转发给其他可能不易查看图像的用户时,文档仍然可用。
标记生成器(如所见即所得的创作工具)应尽可能从用户那里获取替代文本。然而,认识到在许多情况下,这可能不可行。
对于作为链接唯一内容的图像,标记生成器应检查链接目标,以确定目标的标题或目标的URL,并使用以这种方式获得的信息作为替代文本。
对于有标题的图像,标记生成器应使用figure
和figcaption
元素,或title
属性,来提供图像的标题。
作为最后的手段,实施者应将alt
属性设置为空字符串,假设图像是纯粹的装饰性图像,不添加任何信息但仍特定于周围内容,或者完全省略alt
属性,假设图像是内容的关键部分。
标记生成器可以在img
元素上指定generator-unable-to-provide-required-alt
属性,用于未能获取替代文本的情况,因此省略了alt
属性。该属性的值必须为空字符串。包含这些属性的文档不符合规范,但合规检查器将默默忽略这一错误。
这旨在避免标记生成器因省略alt
属性而被迫用更严重的错误(如提供虚假的替代文本)来替代,因为最先进的自动合规检查器无法区分虚假的替代文本和正确的替代文本。
标记生成器通常应避免使用图像本身的文件名作为替代文本。同样,标记生成器应避免从任何将同样可供呈现用户代理(例如,Web浏览器)使用的内容中生成替代文本。
这是因为一旦页面生成,它通常不会被更新,而随后读取页面的浏览器可以由用户更新,因此浏览器可能会比标记生成器在生成页面时具有更为最新和精确的启发式规则。
合规检查器必须报告缺少alt
属性为错误,除非符合以下列出的条件之一:
合规检查器已配置为假设文档是针对特定且已知能够查看图像的个人的电子邮件或文档。
img
元素有一个(不符合规范的)generator-unable-to-provide-required-alt
属性,其值为空字符串。一个不报告缺少alt
属性为错误的合规检查器,也不得报告存在空generator-unable-to-provide-required-alt
属性为错误。(这种情况不代表文档符合规范,只是生成器无法确定适当的替代文本——验证器在这种情况下不需要显示错误,因为这样的错误可能会促使标记生成器仅仅为了消除验证器的警告而包含虚假的替代文本。当然,合规检查器可以报告缺少alt
属性的错误,即使存在generator-unable-to-provide-required-alt
属性;例如,可能有用户选项报告所有合规错误,即使这些错误可能是使用标记生成器的更或少不可避免的结果。)
iframe
元素
在所有当前引擎中支持。
在所有当前引擎中支持。
src
— 资源地址
srcdoc
— 在 iframe
中渲染的文档
name
— 可导航内容的名称
sandbox
— 嵌套内容的安全规则
allow
— 应用于 iframe
内容的权限策略
allowfullscreen
— 是否允许 iframe
内容使用 requestFullscreen()
width
— 水平方向尺寸
height
— 垂直方向尺寸
referrerpolicy
— 元素发起的引用策略的fetches
loading
— 用于确定加载延迟
[Exposed =Window ]
interface HTMLIFrameElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute USVString src ;
[CEReactions ] attribute (TrustedHTML
or DOMString ) srcdoc ;
[CEReactions ] attribute DOMString name ;
[SameObject , PutForwards =value ] readonly attribute DOMTokenList sandbox ;
[CEReactions ] attribute DOMString allow ;
[CEReactions ] attribute boolean allowFullscreen ;
[CEReactions ] attribute DOMString width ;
[CEReactions ] attribute DOMString height ;
[CEReactions ] attribute DOMString referrerPolicy ;
[CEReactions ] attribute DOMString loading ;
readonly attribute Document ? contentDocument ;
readonly attribute WindowProxy ? contentWindow ;
Document ? getSVGDocument ();
// also has obsolete members
};
src
属性提供了该元素的 URL,该页面将被该元素的 可导航内容 包含。该属性(如果存在)必须是一个 有效的非空 URL,可能被空格包围。如果 itemprop
属性在一个 iframe
元素上指定,则 src
属性也必须被指定。
在所有当前引擎中支持。
srcdoc
属性提供了该元素的 可导航内容
的页面内容。该属性的值用于 构建 一个 iframe
srcdoc
文档,它是一个 文档
,其 URL 匹配 about:srcdoc
。
srcdoc
属性(如果存在)必须使用 HTML 语法,由以下语法组件按给定顺序组成:
html
元素的形式。上述要求也适用于XML 文档。
这里一个博客使用 srcdoc
属性和下面描述的 sandbox
属性结合使用,为支持此功能的用户代理提供博客文章评论中防止脚本注入的额外保护层:
< article >
< h1 > I got my own magazine!</ h1 >
< p > After much effort, I've finally found a publisher, and so now I
have my own magazine! Isn't that awesome?! The first issue will come
out in September, and we have articles about getting food, and about
getting in boxes, it's going to be great!</ p >
< footer >
< p > Written by < a href = "/users/cap" > cap</ a > , 1 hour ago.
</ footer >
< article >
< footer > Thirteen minutes ago, < a href = "/users/ch" > ch</ a > wrote: </ footer >
< iframe sandbox srcdoc = "<p>did you get a cover picture yet?" ></ iframe >
</ article >
< article >
< footer > Nine minutes ago, < a href = "/users/cap" > cap</ a > wrote: </ footer >
< iframe sandbox srcdoc = "<p>Yeah, you can see it <a href="/gallery?mode=cover&amp;page=1">in my gallery</a>." ></ iframe >
</ article >
< article >
< footer > Five minutes ago, < a href = "/users/ch" > ch</ a > wrote: </ footer >
< iframe sandbox srcdoc = "<p>hey that's earl's table.
<p>you should get earl&amp;me on the next cover." ></ iframe >
</ article >
请注意引号必须被转义的方式(否则 srcdoc
属性会提前结束),以及在沙盒内容中提到的原始符号(例如在URL或文本中)必须双重转义的方式——一次是为了在最初解析 srcdoc
属性时保留符号,另一次是为了防止在解析沙盒内容时误解符号。
此外,请注意,由于 DOCTYPE
在 iframe
srcdoc
文档 中是可选的,而 html
,head
和
body
元素有可选的开始和结束标签,并且 title
元素在 iframe
srcdoc
文档 中也是可选的,所以
srcdoc
属性中的标记可以相对简洁,尽管它代表了整个文档,因为只需要在语法中字面上出现 body
元素的内容。其他元素仍然存在,但只是隐含地存在。
在HTML 语法中,作者只需记住使用
U+0022 引号字符 (") 包裹属性内容,然后转义所有的 U+0026 符号 (&) 和 U+0022 引号 (") 字符,并指定 sandbox
属性,以确保内容安全嵌入。(记得在引号之前转义符号,以确保引号变成 " 而不是 &quot;。)
在 XML 中,U+003C 小于号字符 (<) 也需要转义。为了防止属性值规范化,一些 XML 的空白字符——特别是 U+0009 制表符 (tab)、U+000A 换行符 (LF) 和 U+000D 回车符 (CR)——也需要转义。[XML]
如果 src
属性和
srcdoc
属性同时指定,则 srcdoc
属性优先。这允许作者为不支持 srcdoc
属性的旧版用户代理提供一个后备的 URL。
iframe
HTML 元素插入步骤,给定
insertedNode,如下:
如果 insertedNode 的 shadow-including root 的 浏览上下文 为 null,则返回。
如果 insertedNode 有 sandbox
属性,则根据属性值和 insertedNode 的 iframe
沙盒标志集 解析沙盒指令。
处理
insertedNode 的 iframe
属性,并将 initialInsertion 设置为 true。
iframe
HTML 元素移除步骤,给定
removedNode,是 销毁子可导航对象,给定 removedNode。
这在没有触发任何 unload
事件的情况下发生(该元素的 内容文档被销毁,而不是卸载)。
虽然 iframe
元素在 影子树 中处理,如上所述,但其行为的其他几个方面在影子树方面没有明确规定。有关详细信息,请参见 issue #763。
每当一个具有非空 可导航内容
的 iframe
元素的 srcdoc
属性被设置、更改或移除时,用户代理必须 处理 iframe
属性。
同样,每当一个具有非空 可导航内容 但没有指定 srcdoc
属性的 iframe
元素的 src
属性被设置、更改或移除时,用户代理必须 处理 iframe
属性。
要处理 iframe
的属性,对于元素 element,可选布尔值 initialInsertion (默认为 false):
如果 element 的 srcdoc
属性已指定,则:
将 element 的 current navigation was lazy loaded 布尔值设为 false。
如果 will lazy load element steps 给定 element 返回 true,则:
将 element 的 lazy load resumption steps 设置为从标记为 navigate to the srcdoc resource 的步骤开始的算法的其余部分。
将 element 的 current navigation was lazy loaded 布尔值设为 true。
返回。
Navigate to the srcdoc resource:导航 element 的 iframe
或
frame
,about:srcdoc
,空字符串和
element 的 srcdoc
属性的值。
生成的 Document
必须被视为
一个
iframe
srcdoc
文档。
否则:
让 url 成为给定 element 和 initialInsertion 后运行共享属性处理步骤的结果。
如果 url 为 null,则返回。
如果 url 匹配
about:blank
且
initialInsertion 为 true,则:
运行iframe 加载事件步骤,给定 element。
返回。
让 referrerPolicy 成为 element 的 referrerpolicy
内容属性的当前状态。
将 element 的 current navigation was lazy loaded 布尔值设为 false。
如果 will lazy load element steps 给定 element 返回 true,则:
将 element 的 lazy load resumption steps 设置为从标记为 navigate 的步骤开始的算法的其余部分。
将 element 的 current navigation was lazy loaded 布尔值设为 true。
返回。
Navigate:导航 element 的 iframe
或
frame
,给定 url 和 referrerPolicy。
给定元素 element 和布尔值 initialInsertion,iframe
和 frame
元素的共享属性处理步骤如下:
令 url 为 URL 记录 about:blank
。
如果 element 指定了 src
属性,并且其值不是空字符串,则:
如果 element 的 节点可导航 的 包含的祖先可导航 包含一个 可导航,其 活动文档 的 URL 等于 url,且 排除片段 设置为 true,则返回 null。
如果 url 匹配
about:blank
,且 initialInsertion
为 true,则执行 URL
和历史记录更新步骤,给定 element 的 可导航内容 的 活动文档 和 url。
如果 url 是类似 about:blank?foo
的内容,这是必要的。如果 url 只是纯粹的
about:blank
,这将不做任何事情。
返回 url。
要 导航到一个 iframe
或 frame
,给定一个
元素
element,一个 URL url,一个 引荐
策略
referrerPolicy,以及一个可选的字符串或 null srcdocString(默认为
null):
让 historyHandling 为 "auto
"。
如果 element 的 内容可导航 的 活动文档
未 完全
加载,则将
historyHandling 设置为 "replace
"。
如果 element 是一个 iframe
,
则将 element 的 待处理资源计时开始时间
设置为
当前高分辨率时间,考虑到 element 的
节点文档 的 相关全局对象。
导航 element 的 内容可导航 到 url,使用 element 的 节点 文档, 其中 historyHandling 设置为 historyHandling,referrerPolicy 设置为 referrerPolicy,以及 documentResource 设置为 srcdocString。
每个 文档
都有一个 iframe 加载中 标志和一个 静音 iframe 加载 标志。当一个
文档
被
创建时,这些标志必须被取消设置。
要运行 iframe 加载事件步骤,给定一个 iframe
元素
element:
如果 childDocument 的 静音 iframe 加载 标志已设置,则 返回。
如果 element 的 待处理资源计时开始时间 不为 null,则:
设置 childDocument 的 iframe 加载中 标志。
取消设置 childDocument 的 iframe 加载中 标志。
这与脚本一起使用时,可以用于探测本地网络 HTTP 服务器的 URL 空间。用户代理可能会实现比上述描述更严格的 跨源 访问控制策略以减轻此攻击,但不幸的是,这些策略通常与现有的网页内容不兼容。
如果某个元素类型 可能延迟加载事件,则对于该类型的每个元素 element,用户代理必须 延迟 element 的 节点文档 的加载事件,如果 element 的 内容可导航 非 null,并且以下任意条件为真:
element 的 内容可导航 的 活动文档 不 准备好执行后加载任务;
element 的 内容可导航 的 正在延迟
load
事件 为真;或者
如果在处理 load
事件期间,
element 的 内容可导航 再次被 导航,这将进一步
延迟加载事件。
每个 iframe
元素有一个关联的 当前导航是惰性加载 布尔值,初始值为 false。它在 处理
iframe
属性 算法中设置和取消设置。
一个 iframe
元素,其 当前导航是惰性加载 布尔值为 false 可能延迟加载事件。
每个 iframe
元素有一个关联的 null 或
DOMHighResTimeStamp
待处理资源计时开始时间,
初始值为 null。
如果在元素创建时,srcdoc
属性未设置,而 src
属性也未设置或已设置但其值无法被 解析,则元素的 内容可导航 将保持在 初始
about:blank
文档
。
如果用户 导航
离开此页面,iframe
的
内容可导航 的 活动 WindowProxy
对象将代理新的
Window
对象用于新的
文档
对象,但 src
属性不会改变。
name
属性(如果存在)必须是一个 有效的可导航目标名称。给定的值用于命名元素的 内容可导航,如果在创建时存在该属性。
所有当前浏览器均支持。
sandbox
属性在指定时,会对由 iframe
托管的任何内容启用一组额外的限制。其值必须是 无序的唯一空格分隔的标记集合,且这些标记是 ASCII
不区分大小写。允许的值包括:
allow-downloads
allow-forms
allow-modals
allow-orientation-lock
allow-pointer-lock
allow-popups
allow-popups-to-escape-sandbox
allow-presentation
allow-same-origin
allow-scripts
allow-top-navigation
allow-top-navigation-by-user-activation
allow-top-navigation-to-custom-protocols
当设置了该属性时,内容会被视为来自一个唯一的 不透明源,表单、脚本以及各种可能令人烦恼的 API 会被禁用,且链接被防止指向其他 可导航对象。allow-same-origin
关键字使内容被视为来自其真实源,而不是强制其成为一个 不透明源;allow-top-navigation
关键字允许内容 导航 其 可遍历的可导航对象;
allow-top-navigation-by-user-activation
关键字行为类似,但只允许在浏览上下文的 活动窗口 具有 临时激活 时进行此类
导航;allow-top-navigation-to-custom-protocols
重新启用对非 fetch 协议 的导航,允许 交给外部软件;而 allow-forms
、
allow-modals
、
allow-orientation-lock
、
allow-pointer-lock
、
allow-popups
、
allow-presentation
、
allow-scripts
、
和 allow-popups-to-escape-sandbox
关键字分别重新启用表单、模态对话框、屏幕方向锁定、指针锁 API、弹出窗口、展示 API、脚本和未沙箱化的 辅助浏览上下文 的创建。allow-downloads
关键字允许内容执行下载。 [POINTERLOCK] [SCREENORIENTATION]
[PRESENTATION]
allow-top-navigation
和 allow-top-navigation-by-user-activation
关键字不能同时指定,因为这样做是多余的;在这种不符合规范的标记中,只有 allow-top-navigation
会有效。
类似地,如果指定了 allow-top-navigation-to-custom-protocols
关键字,则不能指定 allow-top-navigation
或 allow-popups
关键字,因为这样做是多余的。
要在沙箱内容中允许 alert()
、confirm()
和
prompt()
函数,必须同时指定 allow-modals
和 allow-same-origin
关键字,并且加载的 URL 需要与 同源,与 顶级源
相同。没有 allow-same-origin
关键字,内容总是被视为跨源的,跨源内容 无法显示简单对话框。
当嵌入页面与包含 iframe
的页面具有 相同源 时,同时设置 allow-scripts
和 allow-same-origin
关键字允许嵌入页面简单地删除 sandbox
属性,然后重新加载自己,从而有效地完全突破沙箱。
这些标志仅在 内容可导航 的 iframe
元素被 导航 时生效。
删除它们,或删除整个 sandbox
属性,对已加载的页面没有影响。
不应从与包含 iframe
元素的文件相同的服务器上提供潜在的恶意文件。如果攻击者能够说服用户直接访问恶意内容,而不是在 iframe
中访问,沙箱化恶意内容的帮助非常有限。为了限制恶意 HTML 内容可能造成的损害,它应该从一个单独的专用域提供。使用不同的域可以确保文件中的脚本无法攻击站点,即使用户被欺骗直接访问这些页面,也不会在没有 sandbox
属性保护的情况下。
当 iframe
元素的 sandbox
属性在具有非空 内容可导航
时被设置或更改,用户代理必须 解析沙箱指令
以获取属性值和 iframe
元素的 iframe
沙箱标志设置。
当 iframe
元素的 sandbox
属性在具有非空 内容可导航
时被移除,用户代理必须
清空 iframe
元素的 iframe
沙箱标志设置。
在这个例子中,一些完全未知、可能具有攻击性的用户提供的 HTML 内容被嵌入到一个页面中。由于它是从一个单独的域提供的,因此受到所有正常的跨站点限制。此外,嵌入的页面禁用了脚本、插件和表单,且无法导航到其他框架或窗口(除了自身或它嵌入的任何框架或窗口)。
< p > We're not scared of you! Here is your content, unedited:</ p >
< iframe sandbox src = "https://usercontent.example.net/getusercontent.cgi?id=12193" ></ iframe >
重要的是使用一个单独的域,以确保即使攻击者说服用户直接访问该页面,该页面也不会在网站的源上下文中运行,从而使用户免受页面中发现的任何攻击。
在这个例子中,一个来自其他网站的小工具被嵌入。这个小工具启用了脚本和表单,并且解除源沙箱限制,允许小工具与其源服务器通信。然而,沙箱仍然有用,因为它禁用了插件和弹出窗口,从而降低了用户暴露于恶意软件和其他干扰的风险。
< iframe sandbox = "allow-same-origin allow-forms allow-scripts"
src = "https://maps.example.com/embedded.html" ></ iframe >
假设文件 A 包含以下片段:
< iframe sandbox = "allow-same-origin allow-forms" src = B ></ iframe >
假设文件 B 也包含一个 iframe:
< iframe sandbox = "allow-scripts" src = C ></ iframe >
此外,假设文件 C 包含一个链接:
< a href = D > Link</ a >
在这个示例中,假设所有文件都以 text/html
格式提供。
在这种情况下,页面 C 的所有 sandboxing 标志都被设置。脚本被禁用,因为 A 中的 iframe
中禁用了脚本,这会覆盖 B 中 allow-scripts
关键字。表单也被禁用,因为内层的 iframe
(在
B 中)没有设置 allow-forms
关键字。
假设现在 A 中的一个脚本移除了 A 和 B 中的所有 sandbox
属性。这立即不会改变任何东西。如果用户点击 C 中的链接,将页面 D 加载到 B 中的 iframe
中,页面 D 现在将表现得好像 B 中的 iframe
设置了 allow-same-origin
和 allow-forms
关键字,因为这是在 B 加载时 A 中的 content
navigable 的状态。
一般来说,动态移除或更改 sandbox
属性是不明智的,因为这会使推测哪些内容将被允许变得相当困难。
allow
属性在指定时,决定了在 容器策略 用于 权限策略
初始化 Document
的 iframe
的 内容可导航
时使用的策略。它的值必须是一个 序列化权限策略。[PERMISSIONSPOLICY]
在这个示例中,iframe
用于嵌入来自在线导航服务的地图。allow
属性用于在嵌套上下文中启用地理位置 API。
< iframe src = "https://maps.example.com/" allow = "geolocation" ></ iframe >
allowfullscreen
属性是一个 布尔属性。当指定时,它表示
文档
对象在 iframe
元素的 内容可导航区域
将会被初始化为一个允许从任何 源 使用
"fullscreen
" 特性的权限策略。这是通过 处理权限策略属性 算法来强制执行的。 [PERMISSIONSPOLICY]
在这里,使用 iframe
嵌入了一个视频网站的播放器。需要 allowfullscreen
属性来允许播放器以全屏模式显示视频。
< article >
< header >
< p >< img src = "/usericons/1627591962735" > < b > Fred Flintstone</ b ></ p >
< p >< a href = "/posts/3095182851" rel = bookmark > 12:44</ a > — < a href = "#acl-3095182851" > Private Post</ a ></ p >
</ header >
< p > Check out my new ride!</ p >
< iframe src = "https://video.example.com/embed?id=92469812" allowfullscreen ></ iframe >
</ article >
无论是 allow
还是 allowfullscreen
都不能授予 iframe
元素的 内容可导航
访问某个功能,前提是该元素的 节点文档 尚未被允许使用该功能。
要确定一个 Document
对象
document 是否 允许使用 权限控制功能 feature,请执行以下步骤:
如果 document 的 浏览上下文 为 null,则返回 false。
如果 document 不是 完全活跃 的,则返回 false。
如果在 feature、document 和 document 的 源 上运行 是否在文档中启用功能 的结果为
"Enabled
",则返回 true。
返回 false。
由于它们仅影响 权限策略 的 内容可导航 的 活动文档,allow
和 allowfullscreen
属性仅在 内容可导航 的
iframe
被 导航 时才会生效。添加或删除这些属性对已经加载的文档没有影响。
iframe
元素支持 尺寸属性,用于嵌入内容具有特定尺寸的情况(例如广告单元具有明确的尺寸)。
iframe
元素永远不会有 回退内容,因为它将始终
创建一个新的子可导航,无论指定的初始内容是否成功使用。
referrerpolicy
属性是一个 引用来源政策属性。它的作用是设置在 处理 iframe
属性 时使用的 引用来源政策。[REFERRERPOLICY]
loading
属性是一个
延迟加载属性。它的作用是指示对于视口之外的 iframe
元素的加载策略。
当 loading
属性的状态更改为 Eager
状态时,用户代理必须执行以下步骤:
如果 resumptionSteps 为 null,则返回。
调用 resumptionSteps。
iframe
元素的后代不代表任何内容。 (在不支持 iframe
元素的传统用户代理中,这些内容会被解析为可能作为回退内容的标记。)
HTML 解析器将 iframe
元素中的标记视为文本。
支持所有当前的引擎。
IDL 属性 src
、name
、sandbox
和 allow
必须
反映 相同名称的内容属性。
支持所有当前的引擎。
srcdoc
获取器步骤如下:
让 attribute 为运行 通过命名空间和本地名称获取属性 的结果,参数为 null、srcdoc
的
本地名称,
和 this。
如果 attribute 为 null,则返回空字符串。
返回 attribute 的 值。
srcdoc
设置器步骤如下:
让 compliantString 为调用 获取受信任的类型符合字符串
算法的结果,参数为 TrustedHTML
、this 的
相关全局对象、给定值、“HTMLIFrameElement srcdoc
” 和
“script
”。
受支持的标记
对于 sandbox
的 DOMTokenList
是在 sandbox
属性中定义的允许值,并且用户代理支持的值。
allowFullscreen
IDL 属性必须 反映 allowfullscreen
内容属性。
HTMLIFrameElement/referrerPolicy
所有当前引擎都支持。
referrerPolicy
IDL 属性必须
反映 referrerpolicy
内容
属性,仅限已知值。
loading
IDL 属性必须 反映 loading
内容属性,仅限已知值。
HTMLIFrameElement/contentDocument
所有当前引擎都支持。
contentDocument
获取器的步骤是返回
此的
内容文档。
HTMLIFrameElement/contentWindow
所有当前引擎都支持。
contentWindow
获取器的步骤是返回
此的
内容窗口。
以下是一个使用iframe
来包含来自广告经纪人的广告的页面示例:
< iframe src = "https://ads.example.com/?customerid=923513721&format=banner"
width = "468" height = "60" ></ iframe >
embed
元素支持所有当前引擎。
支持所有当前引擎。
src
—
资源的地址type
—
嵌入资源的类型width
—
水平尺寸height
— 垂直尺寸[Exposed =Window ]
interface HTMLEmbedElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute USVString src ;
[CEReactions ] attribute DOMString type ;
[CEReactions ] attribute DOMString width ;
[CEReactions ] attribute DOMString height ;
Document ? getSVGDocument ();
// also has obsolete members
};
embed
元素为外部应用程序或交互内容提供了一个集成点。
src
属性提供了嵌入资源的 URL。如果存在,此属性必须包含一个 有效的非空 URL,可能会被空格包围。
如果在 itemprop
属性的 embed
元素上指定了,那么必须也指定 src
属性。
type
属性(如果存在)提供了通过插件选择实例化的 MIME 类型。其值必须是 有效的 MIME
类型字符串。如果同时存在 type
属性和
src
属性,那么
type
属性必须指定与 显式内容类型元数据 相同的类型,由
src
属性指定的资源。
当发生以下任一情况时,为元素实例化的任何 插件 必须被移除,embed
元素
不表示任何内容:
当同时满足以下条件时,embed
元素被称为 潜在活动:
每当一个 embed
元素不再 潜在活动 变为
潜在活动,以及每当一个
潜在活动 的
embed
元素保留 潜在活动
并设置了 src
属性,已更改或删除,或设置了 type
属性,已更改或删除,用户代理必须在 embed 任务源 上 排队一个元素任务,给定元素以运行该元素的 embed 元素设置步骤。
定义 embed
元素设置步骤 对于给定的 embed
元素
element 如下:
如果另一个 任务 已排队运行 embed 元素设置步骤 给定 element,则返回。
如果 element 设置了 src
属性,则:
让 url 成为 编码解析
URL 的结果,给定 element 的 src
属性的值,相对于 element 的 节点文档。
如果 url 失败,则返回。
让 request 成为一个新的 请求,其 URL 是 url,客户端 是
element 的 节点文档 的 相关设置对象,目的地
是
"embed
",凭证模式 是 "include
",模式 是 "navigate
",启动类型 是 "embed
",并且其 使用 URL 凭证标志 设置。
获取 request,设置 处理响应 的步骤,给定 响应 response:
如果另一个 任务 已排队运行 embed 元素设置步骤 给定 element,则返回。
让 type 成为确定 内容类型 的结果,给定 element 和 response。
切换 type:
否则,不显示插件 给 element。
确定给定 embed
元素
element 和 响应 response 的 内容类型,运行以下步骤:
如果 response 的 路径 组件与插件支持的模式匹配,则返回该插件可以处理的类型。
例如,一个插件可能会说它可以处理路径组件以四个字符字符串 ".swf
" 结尾的 URL。
如果 response 具有显式内容类型元数据,并且该值是插件支持的类型,则返回该值。
返回 null。
上面的算法有意允许 response 具有非 OK 状态。这允许服务器即使在错误响应中(例如,HTTP 500 内部服务器错误代码仍然可以包含插件数据)返回数据给插件。
不为 embed
元素
element 显示插件:
销毁一个子可导航内容 给定 element。
显示一个指示没有找到插件的标识,作为 element 的内容。
element 现在 表示 什么都没有。
每当一个 embed
元素
潜在活动
变为非潜在活动时,为该元素实例化的任何插件必须被卸载。
IDL 属性 src
和
type
必须分别 反映 同名的内容属性。
object
元素所有当前引擎均支持。
所有当前引擎均支持。
data
— 资源地址
type
— 嵌入资源类型
name
— 内容可导航 的名称
form
—
将元素与 表单
元素关联
width
—
水平尺寸
height
— 垂直尺寸
[Exposed =Window ]
interface HTMLObjectElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute USVString data ;
[CEReactions ] attribute DOMString type ;
[CEReactions ] attribute DOMString name ;
readonly attribute HTMLFormElement ? form ;
[CEReactions ] attribute DOMString width ;
[CEReactions ] attribute DOMString height ;
readonly attribute Document ? contentDocument ;
readonly attribute WindowProxy ? contentWindow ;
Document ? getSVGDocument ();
readonly attribute boolean willValidate ;
readonly attribute ValidityState validity ;
readonly attribute DOMString validationMessage ;
boolean checkValidity ();
boolean reportValidity ();
undefined setCustomValidity (DOMString error );
// also has obsolete members
};
根据 object
元素实例化的内容类型,节点还支持其他接口。
object
元素可以表示一个外部资源,具体取决于资源的类型,该资源将被视为图像或 子可导航内容。
data
属性指定资源的 URL。它必须存在,并且必须包含 有效的非空 URL,可能被空格包围。
type
属性(如果存在)指定资源的类型。如果存在,该属性必须是 有效的 MIME
类型字符串。
name
属性(如果存在)必须是一个
有效的可导航目标名称。给定的值用于命名元素的 内容可导航(如果适用),并且如果在元素的 内容可导航 创建时存在,则适用。
每当发生以下情况 之一时:
object
元素显示或隐藏其 后备内容,
classid
属性被设置、更改或移除,
classid
属性不存在,并且其 data
属性被设置、更改或移除,
classid
属性和 data
属性都不存在,并且其 type
属性被设置、更改或移除,
...用户代理必须 排队一个元素任务 在给定 object
元素的 DOM 操作任务源
上,运行以下步骤来重新确定 object
元素表示的内容。此任务 排队 或正在运行时,必须 延迟元素的加载事件 在其
节点文档 中。
如果用户表示希望显示此 object
元素的 后备内容
而不是元素的通常行为,那么跳转到下面标记为 后备 的步骤。
例如,用户可以要求显示元素的 后备内容,因为该内容使用用户觉得更容易访问的格式。
如果元素有一个祖先 媒体元素,或有一个祖先
object
元素未显示其 后备内容,或者元素不在其 文档中,其 浏览上下文
为非空,或者元素的 节点文档 未完全活动,或者元素仍在 打开元素栈 的 HTML 解析器 或 XML 解析器 中,或者元素未 渲染,则跳转到下面标记为 后备 的步骤。
如果 data
属性存在且其值不为空字符串,则:
如果 type
属性存在且其值不是用户代理支持的类型,则用户代理可以跳过获取内容以检查其真实类型,直接跳转到下面标记为 后备 的步骤。
令 request 为一个新的 请求,其 URL 为 url,客户端 为元素的 节点文档 的 相关设置对象,目标
为
"object
",凭证模式 为 "include
",模式 为 "navigate
",发起者类型 为 "object
",并且其 使用 URL 凭证标志 被设置。
获取 request。
获取资源必须 延迟元素的加载事件 在其 节点文档 中,直到在资源被获取(在下文中定义)后由 网络任务源 排队的 任务 被执行。
如果资源尚不可用(例如,由于资源未在缓存中,因此需要通过网络请求来加载资源),则跳转到下面标记为 后备 的步骤。资源可逐步加载;用户代理可以选择在获得足够数据以开始处理资源时认为资源“可用”。
如果加载失败(例如,出现 HTTP 404 错误,DNS 错误),触发一个事件 名为 error
在元素上,然后跳转到下面标记为 后备 的步骤。
确定 resource type,如下所示:
令 resource type 为未知。
如果用户代理配置为严格遵守此资源的 Content-Type 标头,并且资源有 关联的 Content-Type 元数据,则令 resource type 为在 资源的 Content-Type 元数据 中指定的类型,并跳转到下面标记为 处理程序 的步骤。
这可能引入一个漏洞,其中站点试图嵌入使用特定类型的资源,但远程站点覆盖了它,并为用户代理提供了触发不同类型内容的资源,具有不同的安全特性。
运行以下列表中的适当步骤集:
令 binary 为假。
如果在 资源的
Content-Type 元数据 中指定的类型是 "text/plain
",并且应用
文本或二进制资源判别规则 到资源的结果是资源不是 text/plain
,则将
binary 设置为真。
如果在 资源的
Content-Type 元数据 中指定的类型是 "application/octet-stream
",则将
binary 设置为真。
如果 binary 为假,则令 resource type 为在 资源的 Content-Type 元数据 中指定的类型,并跳转到下面标记为 处理程序 的步骤。
如果在 type
属性存在于 object
元素上,并且其值不是 application/octet-stream
,则运行以下步骤:
如果属性的值是以 "image/
" 开头的类型,而不是 XML MIME 类型,则令 resource type 为在 type
属性中指定的类型。
跳转到下面标记为 处理程序 的步骤。
如果在 type
属性存在于 object
元素上,则令 tentative type 为在 type
属性中指定的类型。
否则,令 tentative type 为 资源的计算类型。
如果 tentative type 不是 application/octet-stream
,则令
resource type 为 tentative type 并跳转到下面标记为 处理程序 的步骤。
如果应用 URL 解析器 算法到指定资源的 URL(在任何重定向之后)的结果为一个 URL 记录,其 路径 组件匹配 插件 支持的模式,则令 resource type 为该插件可以处理的类型。
例如,插件可能会说它可以处理路径组件以四字符字符串 ".swf
" 结尾的资源。
此步骤可能会结束,或上面的子步骤之一直接跳到下一步,而 resource type 仍然未知。在这两种情况下,下一步将触发后备。
处理程序:根据以下第一个匹配的情况处理内容:
image/
" 开头如果 object
元素的 内容可导航 为 null,则 为元素创建一个新的子可导航内容。
如果 response 的 URL 不 匹配
about:blank
,则使用元素的 节点文档,导航 元素的 内容可导航
到 response 的 URL,历史处理
设置为 "替换
"。
image/
" 开头,并且未禁用图像支持销毁一个子可导航内容
给定 object
元素。
应用 图像嗅探规则 以确定图像的类型。
如果图像无法渲染,例如因为它格式错误或格式不受支持,跳转到下面标记为 后备 的步骤。
给定的 resource type 不受支持。跳转到下面标记为 后备 的步骤。
如果上一步结束时 resource type 仍然未知,这就是触发的情况。
元素的内容不是 object
元素表示的一部分。
如果 object
元素不表示其 内容可导航,则在资源完全加载后,排队一个元素任务 在给定 object
元素的 DOM
操作任务源 上,触发一个事件 名为 load
在元素上。
返回。
后备:object
元素 表示 元素的子元素。这是元素的 后备内容。销毁一个子可导航内容 给定元素。
由于上述算法,object
元素的内容充当 后备内容,仅在引用的资源无法显示时使用(例如返回 404
错误)。这允许多个 object
元素嵌套在一起,针对具有不同能力的多个用户代理,用户代理选择它支持的第一个。
form
属性用于显式关联 object
元素与其 表单所有者。
所有当前引擎均支持。
所有当前引擎均支持。
所有当前引擎均支持。
IDL 属性 data
、type
和 name
各自必须 反映
同名的相应内容属性。
HTMLObjectElement/contentDocument
所有当前引擎均支持。
contentDocument
getter 步骤是返回 this 的 内容文档。
HTMLObjectElement/contentWindow
所有当前引擎均支持。
contentWindow
getter 步骤是返回 this 的 内容窗口。
willValidate
、validity
和
validationMessage
属性,以及 checkValidity()
、reportValidity()
和 setCustomValidity()
方法,是 约束验证 API
的一部分。form
IDL
属性是元素的表单
API 的一部分。
在此示例中,使用 object
元素将 HTML 页面嵌入到另一个页面中。
< figure >
< object data = "clock.html" ></ object >
< figcaption > My HTML Clock</ figcaption >
</ figure >
video
元素所有当前引擎均支持。
所有当前引擎均支持。
controls
属性:Interactive
content.src
属性:零个或多个
track
元素,然后是透明内容,但不能有媒体元素后代。
src
属性:零个或多个
source
元素,然后是零个或多个 track
元素,然后是透明内容,但不能有媒体元素后代。
src
—
资源地址crossorigin
— 处理跨域请求的方式poster
—
视频播放前显示的海报帧preload
— 提示需要缓冲多少媒体资源autoplay
— 页面加载时自动开始播放媒体资源plays inline
— 鼓励用户代理在元素的播放区域内显示视频内容loop
—
是否循环播放媒体资源muted
— 默认是否静音媒体资源controls
— 显示用户代理控件width
—
水平尺寸height
— 垂直尺寸[Exposed =Window ]
interface HTMLVideoElement : HTMLMediaElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute unsigned long width ;
[CEReactions ] attribute unsigned long height ;
readonly attribute unsigned long videoWidth ;
readonly attribute unsigned long videoHeight ;
[CEReactions ] attribute USVString poster ;
[CEReactions ] attribute boolean playsInline ;
};
A video
元素用于播放视频或电影,以及带有字幕的音频文件。
可以在 video
元素内提供内容。用户代理不应向用户显示此内容;它是为不支持 video
的旧版网页浏览器准备的,以便向这些旧浏览器的用户显示文本,告知他们如何访问视频内容。
特别地,此内容并不是为了应对可访问性问题。为了使视频内容对部分视力障碍者、盲人、听力障碍者、聋人以及其他有身体或认知障碍的人可访问,有多种功能可用。可以提供嵌入视频流中的字幕或使用 track
元素作为外部文件的字幕。手语轨道可以嵌入视频流中。音频描述可以嵌入视频流中或以文本形式使用 WebVTT 文件
引用,并由用户代理合成成语音。WebVTT
还可以用于提供章节标题。对于不愿意使用媒体元素的用户,可以通过简单地在 video
元素附近的文本中链接到转录本或其他文本替代品来提供这些内容。[WEBVTT]
The video
元素是一个 媒体元素,其 媒体数据 显然是视频数据,可能还包括相关的音频数据。
src
,crossorigin
,preload
,autoplay
,loop
,muted
,和
controls
属性是所有媒体元素的共同属性。
poster
属性提供一个图像文件的
URL,用户代理可以在没有视频数据时显示该图像。如果存在此属性,则必须包含一个 有效的非空 URL,可能被空格包围。
如果指定的资源要被使用,那么,当元素被创建或 poster
属性被设置、更改或移除时,用户代理必须运行以下步骤来确定元素的 海报帧(无论元素的 显示海报标志 的值如何):
如果 url 失败,则返回。没有 海报帧。
让 request 成为一个新 请求,其 URL 是 url,客户端 是元素的 节点文档 的 相关设置对象,目标 是
"image
",启动者类型 是
"video
",凭证模式 是 "include
",并且 使用 URL 凭证标志 被设置。
poster
属性提供的图像,即 海报帧,旨在作为视频的代表帧(通常是第一个非空白帧),以便让用户了解视频的内容。
playsinline
属性是一个布尔属性。如果存在,它作为用户代理的提示,视频应该默认在文档中“内联”显示,受限于元素的播放区域,而不是全屏显示或在一个独立的可调整大小的窗口中显示。
缺少 playsinline
属性并不意味着视频将默认全屏显示。事实上,大多数用户代理已经选择默认内联播放所有视频,并且在这些用户代理中,playsinline
属性没有效果。
A video
元素表示以下列表中第一个匹配条件的内容:
readyState
属性为 HAVE_NOTHING
,或
HAVE_METADATA
但尚未获得任何视频数据,或元素的 readyState
属性为任何后续值,但 媒体资源
没有视频通道)
video
元素 表示其 海报帧(如果有),否则表示 透明黑,没有自然尺寸。
video
元素 暂停时,当前播放位置 是视频的第一帧,并且元素的 显示海报标志 被设置video
元素 表示其 海报帧(如果有),否则表示视频的第一帧。video
元素 暂停,且与 当前播放位置
对应的视频帧不可用时(例如因为视频正在查找或缓冲)video
元素既不 可能播放,也不
暂停 时(例如在查找或停滞时)
video
元素 表示视频的最后一帧。video
元素 暂停 时video
元素 表示与 当前播放位置 对应的视频帧。video
元素有一个视频通道并且 可能播放)video
元素 表示与不断增加的 “当前”位置 对应的视频帧。当 当前播放位置 变化,使得最后渲染的帧不再是视频中与 当前播放位置 对应的帧时,必须渲染新帧。
视频帧必须从在 事件循环最后到达 步骤 1 时所选择的视频轨道中获取。
视频流中与特定播放位置对应的帧由视频流的格式定义。
video
元素还 表示任何 文本轨迹提示,其 文本轨迹提示活动标志 被设置且 文本轨迹 处于 显示 模式,并且任何 媒体资源 中的音频,在 当前播放位置。
任何与 媒体资源 相关的音频必须(如果播放)与 当前播放位置 同步播放,在元素的 有效媒体音量 下播放。用户代理必须播放在 事件循环最后到达步骤 1 时启用的音频轨道。
此外,用户代理可以通过在视频或元素的播放区域的其他区域上覆盖文本或图标,或以其他适当方式,向用户提供消息(如“缓冲中”、“没有视频加载”、“错误”或更详细的信息)。
无法渲染视频的用户代理可以使元素 表示一个链接到外部视频播放工具或视频数据本身。
当 video
元素的 媒体资源
有一个视频通道时,元素提供一个
绘制源,其宽度是 媒体资源 的 自然宽度,其高度是 媒体资源 的 自然高度,其外观是与 当前播放位置
对应的视频帧,如果那是可用的,否则(例如当视频正在查找或缓冲时)其以前的外观,如果有的话,否则(例如因为视频仍在加载第一帧)为
黑色。
video.videoWidth
所有当前引擎均支持。
video.videoHeight
所有当前引擎均支持。
这些属性返回视频的自然尺寸,如果尺寸未知则返回0。
自然宽度 和 自然高度 是 媒体资源 在考虑了资源的尺寸、纵横比、净有效区、分辨率等之后的尺寸,如资源使用的格式定义的那样。如果一种非方格式没有定义如何将纵横比应用于视频数据的尺寸以获得“正确”的尺寸,那么用户代理必须通过增加一个尺寸并保持另一个不变来应用比率。
videoWidth
IDL 属性必须返回 自然宽度 的视频以 CSS 像素
为单位。videoHeight
IDL 属性必须返回视频的 自然高度,以 CSS 像素
为单位。如果元素的 readyState
属性为 HAVE_NOTHING
,则这些属性必须返回
0。
每当 自然宽度 或 自然高度 变化时(例如,因为选择了不同的视频轨道),如果元素的 readyState
属性不是 HAVE_NOTHING
,用户代理必须
排队一个媒体元素任务 给 媒体元素,以 触发一个名为 resize
的事件。
在没有相反的样式规则的情况下,视频 内容应在元素的播放区域内居中显示,以最大可能的尺寸完全适应播放区域,同时保持视频内容的纵横比。因此,如果播放区域的纵横比与视频的纵横比不匹配,视频将显示为信箱模式或柱箱模式。播放区域中不包含视频的区域不表示任何内容。
在实现 CSS 的用户代理中,上述要求可以通过使用 渲染部分建议的样式规则 来实现。
自然宽度 是 video
元素播放区域的 自然宽度,如果有并且元素当前表示其海报帧;否则,它是视频资源的 自然宽度,如果可用;否则自然宽度丢失。
自然高度 是 video
元素播放区域的 自然高度,如果有并且元素当前表示其海报帧;否则它是视频资源的 自然高度,如果可用;否则自然高度丢失。
默认对象大小 是宽度为 300 CSS 像素 和高度为 150 CSS 像素。[CSSIMAGES]
用户代理应提供控件以启用或禁用显示闭合字幕、音频描述轨道和与视频流相关的其他附加数据,但这些功能不应干扰页面的正常渲染。
用户代理可以允许用户以更适合用户的方式查看视频内容,例如全屏或在独立的可调整大小的窗口中。用户代理甚至可以在播放视频时默认触发这种查看模式,尽管它们在指定了 playsinline
属性时不应这样做。与其他用户界面功能一样,启用此功能的控件不应干扰页面的正常渲染,除非用户代理正在 向用户展示用户界面。然而,在这种独立的查看模式中,用户代理可以使完整的用户界面可见,即使
controls
属性不存在。
用户代理可以允许视频播放影响可能干扰用户体验的系统功能;例如,用户代理可以在视频播放期间禁用屏幕保护程序。
poster
IDL
属性必须 反映 poster
内容属性。
playsInline
IDL 属性必须 反映 playsinline
内容属性。
此示例展示了如何检测视频播放失败的情况:
< script >
function failed( e) {
// video playback failed - show a message saying why
switch ( e. target. error. code) {
case e. target. error. MEDIA_ERR_ABORTED:
alert( 'You aborted the video playback.' );
break ;
case e. target. error. MEDIA_ERR_NETWORK:
alert( 'A network error caused the video download to fail part-way.' );
break ;
case e. target. error. MEDIA_ERR_DECODE:
alert( 'The video playback was aborted due to a corruption problem or because the video used features your browser did not support.' );
break ;
case e. target. error. MEDIA_ERR_SRC_NOT_SUPPORTED:
alert( 'The video could not be loaded, either because the server or network failed or because the format is not supported.' );
break ;
default :
alert( 'An unknown error occurred.' );
break ;
}
}
</ script >
< p >< video src = "tgif.vid" autoplay controls onerror = "failed(event)" ></ video ></ p >
< p >< a href = "tgif.vid" > Download the video file</ a > .</ p >
audio
元素支持所有当前引擎。
支持所有当前引擎。
controls
属性:交互内容。
controls
属性:可感知内容。src
属性:零个或多个track
元素,然后透明,但没有媒体元素后代。src
属性:零个或多个source
元素,然后零个或多个track
元素,然后透明,但没有媒体元素后代。src
—
资源地址crossorigin
— 元素如何处理跨域请求preload
— 提示媒体资源可能需要多少缓冲autoplay
— 提示媒体资源可以在页面加载时自动启动loop
—
是否循环媒体资源muted
— 是否默认静音媒体资源controls
— 显示用户代理控件[Exposed =Window ,
LegacyFactoryFunction =Audio (optional DOMString src )]
interface HTMLAudioElement : HTMLMediaElement {
[HTMLConstructor ] constructor ();
};
audio
元素表示声音或音频流。
内容可以放在audio
元素中。用户代理不应向用户显示这些内容;它们是为不支持audio
的旧版网页浏览器准备的,以便向这些旧版浏览器的用户显示如何访问音频内容的文本。
特别地,这些内容不是为了解决可访问性问题。为了使音频内容对聋人或有其他身体或认知障碍的人可访问,有多种功能可用。如果有字幕或手语视频,可以使用video
元素代替audio
元素播放音频,允许用户启用视觉替代。可以使用track
元素和WebVTT 文件提供章节标题以帮助导航。自然,也可以通过简单地在audio
元素附近的正文中链接到它们来提供转录或其他文本替代。[WEBVTT]
src
、crossorigin
、preload
、autoplay
、loop
、muted
和
controls
属性是所有媒体元素共有的属性。
audio = new Audio([ url ])
支持所有当前引擎。
返回一个新的audio
元素,src
属性设置为传递的参数值(如果适用)。
为创建HTMLAudioElement
对象提供了一个传统的工厂函数(除了
DOM 的工厂方法如createElement()
外):Audio(src)
。调用传统工厂函数时,必须执行以下步骤:
令document为当前全局对象的关联Document
。
如果src被给定,则设置audio的一个属性值,使用“src
”和src。(这将导致用户代理在返回之前调用对象的资源选择算法。)
返回audio。
track
元素支持所有当前引擎。
支持所有当前引擎。
kind
—
文本轨道的类型src
—
资源的地址srclang
— 文本轨道的语言label
— 用户可见标签default
— 如果没有其他 文本轨道 更合适,则启用该轨道[Exposed =Window ]
interface HTMLTrackElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString kind ;
[CEReactions ] attribute USVString src ;
[CEReactions ] attribute DOMString srclang ;
[CEReactions ] attribute DOMString label ;
[CEReactions ] attribute boolean default ;
const unsigned short NONE = 0;
const unsigned short LOADING = 1;
const unsigned short LOADED = 2;
const unsigned short ERROR = 3;
readonly attribute unsigned short readyState ;
readonly attribute TextTrack track ;
};
track
元素允许作者为 媒体元素 指定显式的外部定时
文本轨道。它本身不 代表任何东西。
kind
属性是一个 枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
subtitles |
字幕 | 对话的转录或翻译,适用于声音可用但听不懂的情况(例如用户不理解 媒体资源音轨的语言)。覆盖在视频上。 |
captions |
字幕 | 对话、音效、相关音乐提示和其他相关音频信息的转录或翻译,适用于声音不可用或不清晰的情况(例如由于静音、被环境噪声淹没或用户是聋人)。覆盖在视频上;标记为适合听力障碍者。 |
descriptions |
描述 | 对 媒体资源视频组件的文本描述,旨在视觉组件被遮挡、不可用或无法使用时进行音频合成(例如用户在驾驶时无需屏幕与应用程序互动,或用户是盲人)。合成为音频。 |
chapters |
章节元数据 | 供脚本使用的轨道。用户代理不显示。 |
metadata |
元数据 |
属性的缺失值默认值为 字幕状态,无效值默认值为 元数据状态。
src
属性提供文本轨道数据的 URL。值必须是 有效的非空 URL,可能被空格包围。此属性必须存在。
元素有一个相关的 轨道 URL(一个字符串),初始为空字符串。
当元素的 src
属性被设置时,执行以下步骤:
令 trackURL 失败。
令 value 为元素的 src
属性值。
如果 value 不是空字符串,则将 trackURL 设置为 编码、解析和序列化 URL 的结果,给定 value,相对于元素的 节点文档。
如果 trackURL 不是失败,则将元素的 轨道 URL 设置为 trackURL;否则设为空字符串。
如果元素的 轨道 URL 指定了 WebVTT
资源,并且元素的
kind
属性不在
章节元数据
或 元数据
状态中,则 WebVTT 文件必须是 使用提示文本的 WebVTT 文件。[WEBVTT]
srclang
属性提供文本轨道数据的语言。值必须是有效的 BCP 47 语言标签。如果元素的 kind
属性处于
字幕
状态,则必须存在此属性。[BCP47]
如果元素有一个 srclang
属性且其值不是空字符串,则元素的 轨道语言 为属性的值。否则,元素没有 轨道语言。
label
属性提供用户可读的轨道标题。用户代理在列出 字幕、字幕 和
音频描述 轨道时使用此标题。
如果存在 label
属性,其值不得为空字符串。此外,不得有两个相同 媒体元素的 track
子元素,其 kind
属性处于相同状态,其 srclang
属性都缺失或有相同语言的值,并且其 label
属性都缺失或有相同值。
如果元素有一个 label
属性且其值不是空字符串,则元素的 轨道标签 为属性的值。否则,元素的 轨道标签 为空字符串。
default
属性是一个
布尔属性,如果指定,表示如果用户的偏好不表明另一个轨道更合适,则启用该轨道。
每个 媒体元素 不能有超过一个 track
子元素,其 kind
属性处于
字幕
或 字幕
状态,且 default
属性已指定。
每个 媒体元素 不能有超过一个 track
子元素,其 kind
属性处于
描述 状态,且 default
属性已指定。
每个 媒体元素 不能有超过一个 track
子元素,其 kind
属性处于
章节元数据
状态,且 default
属性已指定。
对于 track
元素,其 kind
属性处于 元数据 状态且 default
属性已指定的数量没有限制。
track.readyState
返回 文本轨道就绪状态,用以下列表中的数字表示:
track.track
readyState
属性必须返回对应于 文本轨道就绪状态的数值,如以下列表所定义:
NONE
(数值 0)
LOADING
(数值
1)LOADED
(数值
2)
ERROR
(数值 3)
track
IDL
属性必须在获取时返回 文本轨道的相应 TextTrack
对象。
支持所有当前引擎。
src
,srclang
,label
和 default
IDL
属性必须反映同名的相应内容属性。kind
IDL 属性必须反映同名内容属性,仅限于已知值。
此视频包含多种语言的字幕:
< video src = "brave.webm" >
< track kind = subtitles src = brave.en.vtt srclang = en label = "English" >
< track kind = captions src = brave.en.hoh.vtt srclang = en label = "English for the Hard of Hearing" >
< track kind = subtitles src = brave.fr.vtt srclang = fr lang = fr label = "Français" >
< track kind = subtitles src = brave.de.vtt srclang = de lang = de label = "Deutsch" >
</ video >
(最后两个 lang
属性描述的是
label
属性的语言,而不是字幕本身的语言。字幕的语言由 srclang
属性指定。)
HTMLMediaElement对象(在本规范中audio
和video
)被简单地称为媒体元素。
支持所有当前引擎。
enum CanPlayTypeResult { "" /* empty string */, " maybe " , " probably " };
typedef (MediaStream or MediaSource or Blob ) MediaProvider ;
[Exposed =Window ]
interface HTMLMediaElement : HTMLElement {
// error state
readonly attribute MediaError ? error ;
// network state
[CEReactions ] attribute USVString src ;
attribute MediaProvider ? srcObject ;
readonly attribute USVString currentSrc ;
[CEReactions ] attribute DOMString ? crossOrigin ;
const unsigned short NETWORK_EMPTY = 0;
const unsigned short NETWORK_IDLE = 1;
const unsigned short NETWORK_LOADING = 2;
const unsigned short NETWORK_NO_SOURCE = 3;
readonly attribute unsigned short networkState ;
[CEReactions ] attribute DOMString preload ;
readonly attribute TimeRanges buffered ;
undefined load ();
CanPlayTypeResult canPlayType (DOMString type );
// ready state
const unsigned short HAVE_NOTHING = 0;
const unsigned short HAVE_METADATA = 1;
const unsigned short HAVE_CURRENT_DATA = 2;
const unsigned short HAVE_FUTURE_DATA = 3;
const unsigned short HAVE_ENOUGH_DATA = 4;
readonly attribute unsigned short readyState ;
readonly attribute boolean seeking ;
// playback state
attribute double currentTime ;
undefined fastSeek (double time );
readonly attribute unrestricted double duration ;
object getStartDate ();
readonly attribute boolean paused ;
attribute double defaultPlaybackRate ;
attribute double playbackRate ;
attribute boolean preservesPitch ;
readonly attribute TimeRanges played ;
readonly attribute TimeRanges seekable ;
readonly attribute boolean ended ;
[CEReactions ] attribute boolean autoplay ;
[CEReactions ] attribute boolean loop ;
Promise <undefined > play ();
undefined pause ();
// controls
[CEReactions ] attribute boolean controls ;
attribute double volume ;
attribute boolean muted ;
[CEReactions ] attribute boolean defaultMuted ;
// tracks
[SameObject ] readonly attribute AudioTrackList audioTracks ;
[SameObject ] readonly attribute VideoTrackList videoTracks ;
[SameObject ] readonly attribute TextTrackList textTracks ;
TextTrack addTextTrack (TextTrackKind kind , optional DOMString label = "", optional DOMString language = "");
};
媒体元素属性,src
,crossorigin
,preload
,autoplay
,loop
,muted
和controls
适用于所有媒体元素。它们在本节中定义。
媒体元素用于向用户展示音频数据,或视频和音频数据。在本节中,这被称为媒体数据,因为本节同样适用于音频或视频的媒体元素。
术语媒体资源用于指代完整的媒体数据集,例如完整的视频文件或完整的音频文件。
媒体资源有一个关联的来源,可以是"none
"、"multiple
"、"rewritten
"或一个来源。最初设定为"none
"。
媒体资源可以有多个音频和视频轨道。对于媒体元素,媒体资源的视频数据仅为元素的videoTracks
属性中当前选定的轨道(如果有)在事件循环最后一次到达步骤1时的数据,而媒体资源的音频数据则是元素的audioTracks
属性中当前启用的所有轨道(如果有)在事件循环最后一次到达步骤1时混合后的结果。
audio
和
video
元素都可以用于音频和视频。两者之间的主要区别是audio
元素没有用于显示视觉内容(如视频或字幕)的播放区域,而video
元素有。
每个媒体元素都有一个唯一的媒体元素事件任务源。
要排队媒体元素任务与一个媒体元素element和一系列步骤steps,请根据element和steps在媒体元素的媒体元素事件任务源上排队一个元素任务。
支持所有当前的引擎。
media.error
支持所有当前的引擎。
返回一个MediaError
对象,表示元素当前的错误状态。
如果没有错误,则返回 null。
所有媒体元素都有一个关联的错误状态,它记录了自资源选择算法最后一次调用以来元素遇到的最后一个错误。error
属性,在获取时,必须返回为此最后一个错误创建的MediaError
对象,如果没有错误,则返回 null。
[Exposed =Window ]
interface MediaError {
const unsigned short MEDIA_ERR_ABORTED = 1;
const unsigned short MEDIA_ERR_NETWORK = 2;
const unsigned short MEDIA_ERR_DECODE = 3;
const unsigned short MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
readonly attribute unsigned short code ;
readonly attribute DOMString message ;
};
media.error.code
支持所有当前的引擎。
返回当前错误的错误代码,见下表。
media.error.message
支持所有当前的引擎。
返回有关遇到的错误情况的具体诊断信息。消息和消息格式在不同的用户代理之间通常并不统一。如果没有这样的消息可用,则返回空字符串。
每个MediaError
对象都有一个消息,它是一个字符串,还有一个代码,它是以下之一:
MEDIA_ERR_ABORTED
(数值1)MEDIA_ERR_NETWORK
(数值2)MEDIA_ERR_DECODE
(数值3)MEDIA_ERR_SRC_NOT_SUPPORTED
(数值4)src
属性指示的媒体资源或分配的媒体提供对象不适用。要创建一个MediaError
,给定一个错误代码,它是上述值之一,返回一个新的MediaError
对象,其代码是给定的错误代码,其消息是包含用户代理能够提供的关于错误情况原因的任何详细信息的字符串,如果用户代理无法提供这些详细信息,则为空字符串。此消息字符串不得仅包含通过提供的错误代码已经可用的信息;例如,它不得只是将代码翻译为字符串格式。如果没有比错误代码提供的更多的附加信息,则消息必须设置为空字符串。
src
内容属性在媒体元素上给出了要显示的媒体资源(视频、音频)的URL。如果存在,该属性必须包含一个有效的非空URL,可能被空格包围。
如果在媒体元素上指定了itemprop
属性,则必须同时指定src
属性。
crossorigin
内容属性在媒体元素上是一个CORS设置属性。
如果创建一个带有src
属性的媒体元素,用户代理必须立即调用媒体元素的资源选择算法。
如果设置或更改媒体元素的src
属性,用户代理必须调用媒体元素的媒体元素加载算法。(移除src
属性不会这样做,即使存在source
元素。)
支持所有当前的引擎。
支持所有当前的引擎。
crossOrigin
IDL 属性必须反映crossorigin
内容属性,仅限于已知值。
媒体提供对象是一个可以表示媒体资源的对象,与URL分开。MediaStream
对象,MediaSource
对象和Blob
对象都是媒体提供对象。
每个媒体元素都可以有一个分配的媒体提供对象,它是一个媒体提供对象。当创建媒体元素时,它没有分配的媒体提供对象。
media.srcObject [ = source ]
仅在一个引擎中支持。
media.currentSrc
支持所有当前的引擎。
currentSrc
IDL 属性必须最初设置为空字符串。其值由下面定义的资源选择算法更改。
srcObject
IDL 属性,在获取时,必须返回元素的分配的媒体提供对象,如果有的话,否则返回null。在设置时,它必须将元素的分配的媒体提供对象设置为新值,然后调用元素的媒体元素加载算法。
有三种方法可以指定媒体资源:srcObject
IDL 属性、src
内容属性和source
元素。IDL
属性优先,其次是内容属性,最后是元素。
媒体资源可以通过其类型来描述,特别是 MIME
类型,在某些情况下还可以带有codecs
参数。(是否允许codecs
参数取决于 MIME 类型。)[RFC6381]
类型通常是有些不完整的描述;例如 "video/mpeg
" 除了说明容器类型外什么也没说,即使像
"video/mp4; codecs="avc1.42E01E, mp4a.40.2"
"
这样的类型也不包括实际比特率的信息(只包括最大比特率)。因此,给定一种类型,用户代理通常只能知道它可能能够播放该类型的媒体(置信度不同),或它绝对不能播放该类型的媒体。
用户代理知道无法渲染的类型是描述用户代理绝对不支持的资源的类型,例如因为它不识别容器类型,或者它不支持列出的编解码器。
MIME
类型"application/octet-stream
"没有参数时,永远不会是用户代理知道无法渲染的类型。用户代理在用来标记潜在的媒体资源时,必须将该类型视为等同于缺少任何显式的Content-Type 元数据。
只有MIME 类型"application/octet-stream
"没有参数在这里是特例;如果有任何参数出现,它将被视为与任何其他MIME
类型相同。这偏离了应该忽略未知MIME 类型参数的规则。
media.canPlayType(type)
支持所有当前引擎。
根据用户代理是否有信心播放给定类型的媒体资源,返回空字符串(否定回应)、"maybe"或"probably"。
canPlayType(type)
方法必须在type为用户代理知道无法渲染的类型或类型为"application/octet-stream
"时返回空字符串;如果用户代理有信心该类型表示的媒体资源可以在此音频
或视频
元素中渲染,则必须返回"probably
";否则,必须返回"maybe
"。建议实现者除非能确定该类型是否支持,否则返回"maybe
"。一般来说,如果允许codecs
参数且该参数不存在,用户代理不应为该类型返回"probably
"。
此脚本测试用户代理是否支持(虚构的)新格式,以动态决定是否使用视频
元素:
< section id = "video" >
< p >< a href = "playing-cats.nfv" > Download video</ a ></ p >
</ section >
< script >
const videoSection = document. getElementById( 'video' );
const videoElement = document. createElement( 'video' );
const support = videoElement. canPlayType( 'video/x-new-fictional-format;codecs="kittens,bunnies"' );
if ( support === "probably" ) {
videoElement. setAttribute( "src" , "playing-cats.nfv" );
videoSection. replaceChildren( videoElement);
}
</ script >
type
属性允许用户代理避免下载无法渲染格式的资源。 source
元素的
media.networkState
支持所有当前引擎。
返回元素的当前网络活动状态,以下列表中的代码之一。
当媒体元素与网络交互时,它们的当前网络活动由networkState
属性表示。获取时,它必须返回元素的当前网络状态,该状态必须是以下值之一:
NETWORK_EMPTY
(数值 0)NETWORK_IDLE
(数值 1)NETWORK_LOADING
(数值 2)NETWORK_NO_SOURCE
(数值 3)资源选择算法在下文定义,描述了networkState
属性何时更改值以及触发哪些事件以指示此状态的变化。
media.load()
在所有当前引擎中都支持。
导致元素重置并开始从头选择和加载新的 媒体资源 。
所有 媒体元素 都具有一个 可以自动播放标志,其初始状态必须为 true,以及一个 延迟加载事件标志,其初始状态必须为 false。 当 延迟加载事件标志 为 true 时,该元素必须 延迟其文档的加载事件。
当在 媒体元素 上调用 load()
方法时,用户代理必须执行
媒体元素加载算法。
媒体元素 具有一个关联的布尔值 当前是否暂停,初始值为 false。
媒体元素加载算法 包含以下步骤:
将此元素的 当前是否暂停 设置为 false。
中止此元素的任何已经运行的 资源选择算法 实例。
将 pending tasks 设为来自 媒体元素 的 媒体元素事件任务源 的所有 任务 的列表,存在于其中一个 任务队列 中。
对于 pending tasks 中的每个任务,若其会 解决待处理的播放承诺 或 拒绝待处理的播放承诺,立即按任务排队的顺序解决或拒绝这些承诺。
将 pending tasks 中的每个 任务 从其 任务队列 中移除。
基本上,当媒体元素开始加载新资源时,待处理的事件和回调会被丢弃,正在处理的承诺会被立即解决或拒绝。
如果media
element的networkState
被设置为NETWORK_LOADING
或NETWORK_IDLE
,queue a media
element task给定media
element去fire an
event命名为abort
在media
element上。
如果 媒体元素 的
networkState
没有设置为 NETWORK_EMPTY
,则:
排队一个媒体元素任务,给定媒体元素去触发一个事件,名为emptied
在媒体元素上。
如果 媒体元素 的获取过程正在进行,用户代理应停止该过程。
如果 媒体元素
的 指定的媒体提供者对象 是一个 MediaSource
对象,则 将其分离。
如果 readyState
没有设置为 HAVE_NOTHING
,则将其设置为该状态。
如果 paused
属性为 false,则:
将 paused
属性设置为 true。
处理待处理的播放承诺 和 拒绝待处理的播放承诺
,并以结果和一个 “AbortError
” DOMException
。
如果 seeking
为 true,则将其设置为 false。
将当前播放位置设置为0。
将官方播放位置设置为0。
如果这改变了官方播放位置,那么排队一个媒体元素任务,给定媒体元素去触发一个事件,名为timeupdate
在媒体元素上。
将 时间轴偏移 设置为 Not-a-Number (NaN)。
更新 duration
属性为 Not-a-Number (NaN)。
用户代理 不会 为此特定的持续时间变化触发 durationchange
事件。
将 playbackRate
属性设置为 defaultPlaybackRate
属性的值。
任何之前正在播放的 媒体资源 播放停止。
资源选择算法对于一个 媒体元素 如下所述。该算法始终作为 任务 的一部分调用,但算法的第一步之一是返回并继续运行剩余步骤 并行。此外,该算法与 事件循环 机制紧密交互;特别是,它有 同步部分(作为 事件循环 算法的一部分触发)。这些部分中的步骤标有 ⌛。
将元素的 networkState
属性设置为 NETWORK_NO_SOURCE
值。
将元素的 显示海报标志 设置为 true。
等待稳定状态,允许调用此算法的 任务 继续。同步部分 包含此算法的所有剩余步骤,直到算法指示 同步部分 已结束。(同步部分中的步骤标有 ⌛。)
⌛ 如果 媒体元素 的 阻塞解析器标志 为 false,则 填充待处理文本轨道列表。
⌛ 如果 媒体元素 有一个 指定的媒体提供者对象,则将 mode 设为 object。
⌛ 否则,如果 媒体元素 没有 指定的媒体提供者对象,但有 src
属性,则将 mode 设为 attribute。
⌛ 否则,如果 媒体元素 没有 指定的媒体提供者对象 且没有 src
属性,但有一个 source
元素子节点,则将 mode 设为 children,并将 candidate 设为第一个这样的 source
元素子节点,按 树顺序。
⌛ 否则,媒体元素
没有 指定的媒体提供者对象,也没有 src
属性,也没有 source
元素子节点:
⌛ 将 networkState
设置为 NETWORK_EMPTY
。
结束 同步部分 并返回。
⌛ 将 媒体元素 的
networkState
设置为 NETWORK_LOADING
。
⌛ 排队一个媒体元素任务,给定媒体元素去触发一个事件,名为loadstart
在媒体元素上。
运行以下列表中的适当步骤:
⌛ 将 currentSrc
属性设置为空字符串。
运行 资源获取算法,使用 指定的媒体提供者对象。如果该算法在不中止此算法的情况下返回,则加载失败。
媒体提供者加载失败:到达此步骤表示媒体资源加载失败。处理待处理的播放承诺并 排队一个媒体元素任务,让 媒体元素 使用结果运行 专用媒体源失败步骤。
等待前一步排队的 任务 执行完毕。
返回。在此算法再次触发之前,元素不会尝试加载另一个资源。
⌛ 将 urlRecord 设为 编码解析 URL 的结果,给定 src
属性的值,相对于 媒体元素 的 节点文档,当
src
属性最后一次更改时。
⌛ 如果 urlRecord 不是失败,则将 currentSrc
属性设置为应用 URL
序列化器 到 urlRecord 的结果。
如果 urlRecord 不是失败,则运行 资源获取算法,使用 urlRecord。如果该算法在不中止此算法的情况下返回,则加载失败。
属性加载失败:到达此步骤表示媒体资源加载失败或 urlRecord 失败。处理待处理的播放承诺 并 排队一个媒体元素任务,让 媒体元素 使用结果运行 专用媒体源失败步骤。
等待前一步排队的 任务 执行完毕。
返回。在此算法再次触发之前,元素不会尝试加载另一个资源。
⌛ 将 pointer 设为由 媒体元素 的子节点列表中的两个相邻节点定义的位置,视列表的开始(列表中第一个子节点之前,如果有的话)和列表的结束(列表中最后一个子节点之后,如果有的话)为节点本身。一个节点是 pointer 之前的节点,另一个节点是 pointer 之后的节点。初始情况下,将 pointer 设为 candidate 节点和下一个节点之间的位置,如果有的话,或列表的末尾,如果它是最后一个节点。
当节点被 插入 和 移除 到 媒体元素 中时,必须按以下方式更新 pointer:
其他变化不会影响 pointer。
⌛ 处理候选:如果 candidate 没有 src
属性,或其 src
属性的值为空字符串,则结束 同步部分,并跳到下面的 元素加载失败 步骤。
⌛ 如果 candidate 有 media
属性,其值不 匹配环境,则结束 同步部分,并跳到下面的 元素加载失败 步骤。
⌛ 将 urlRecord 设为 编码解析 URL 的结果,给定 candidate 的
src
属性的值,相对于 candidate 的 节点文档,当
src
属性最后一次更改时。
⌛ 如果 urlRecord 失败,则结束 同步部分,并跳到下面的 元素加载失败 步骤。
⌛ 如果 candidate 有 type
属性,当解析为 MIME 类型(包括任何由 codecs
参数描述的编解码器,对于定义该参数的类型),表示 用户代理知道它不能渲染的类型,则结束
同步部分,并跳到下面的
元素加载失败 步骤。
⌛ 将 currentSrc
属性设置为应用 URL
序列化器 到 urlRecord 的结果。
运行 资源获取算法,使用 urlRecord。如果该算法在不中止此算法的情况下返回,则加载失败。
元素失败:排队一个媒体元素任务,给定媒体元素去触发一个事件,名为error
在candidate上。
⌛ 找到下一个候选:将 candidate 设为 null。
⌛ 搜索循环:如果 pointer 之后的节点是列表的末尾,则跳到下面的 等待 步骤。
⌛ 如果 pointer 之后的节点是一个 source
元素,将 candidate 设为该元素。
⌛ 前移 pointer,使 pointer 之前的节点现在成为 pointer 之后的节点,并且 pointer 之后的节点成为 pointer 之后节点之后的节点(如果有)。
⌛ 如果 candidate 为 null,跳回 搜索循环 步骤。否则,跳回 处理候选 步骤。
⌛ 等待:将元素的 networkState
属性设置为 NETWORK_NO_SOURCE
值。
⌛ 将元素的 显示海报标志 设置为 true。
⌛ 排队一个媒体元素任务,让 媒体元素 设置元素的 延迟加载事件标志 为 false。这会停止 延迟加载事件。
等待直到 pointer 之后的节点是一个非列表末尾的节点。(此步骤可能永远等待。)
⌛ 将 networkState
设置回 NETWORK_LOADING
。
⌛ 跳回上面的 找到下一个候选 步骤。
专用媒体源失败步骤,带有一个承诺列表 promises 如下:
将 error
属性设置为 创建一个
MediaError
的结果,使用 MEDIA_ERR_SRC_NOT_SUPPORTED
。
将元素的 networkState
属性设置为 NETWORK_NO_SOURCE
值。
将元素的 show poster 标志 设置为 true。
拒绝待处理的播放承诺,使用 promises 和一个
“NotSupportedError
” DOMException
。
要 验证媒体响应,给定一个 响应
response、一个 媒体资源
resource,以及
"entire resource
" 或一个 (number, number 或 "until end
") 元组 byteRange:
如果 response 是一个 网络错误, 则返回 false。
如果 byteRange 是 "entire resource
",则返回
true。
让 internalResponse 为 response 的 不安全响应。
如果 internalResponse 的 状态 为 200,则返回 true。
如果 internalResponse 的 状态 不是 206,则返回 false。
如果从 internalResponse 中 提取内容范围值 的结果失败,则返回 false。
注意,提取的值不会被使用,特别是不会与 byteRange 进行比较。因此,这一步作为 `Content-Range
`
头部的语法验证,但如果响应中的 `Content-Range
`
值与请求中的 `Range
`
值不匹配,这不被视为失败。
让 origin 为 "rewritten
" 如果
internalResponse 的 URL 为
null;
否则
internalResponse 的 URL 的
origin。
让 previousOrigin 为 resource 的 origin。
如果以下任何条件为真:
previousOrigin 是 "none
";
origin 和 previousOrigin 是 "rewritten
";
或
origin 和 previousOrigin 是 origin,并且 origin 与 previousOrigin 是 相同来源,
则将 resource 的 origin 设置为 origin。
否则,如果 response 是 CORS 跨源,则返回 false。
否则,将 resource 的 origin 设置为
"multiple
"。
这确保了带有范围头的透明响应不会通过与来自不同来源的其他响应拼接在一起而泄露信息。
返回 true。
用于 媒体元素 和给定的 URL 记录 或 媒体提供者对象 的 资源获取算法 如下:
如果算法是通过 媒体提供者对象 或 URL 记录 被调用的,而该 blob URL 条目 是一个 blob URL 条目,其 对象 是一个 媒体提供者对象,则让 mode 为 local。否则,让 mode 为 remote。
如果 mode 为 remote,则让 current media resource 为传递给该算法的 URL 记录 所给出的资源;否则,让 current media resource 为 媒体提供者对象 所给出的资源。无论如何,current media resource 现在是元素的 媒体资源。
如果有的话,从 媒体元素 的 待处理文本轨道列表 中移除所有 媒体资源特定文本轨道。
执行以下步骤列表中的适当步骤:
可以选择执行以下子步骤。如果用户代理打算不尝试获取资源,直到用户明确请求它(例如,作为实现 preload
属性的 none
关键字的一种方式),这是预期的行为。
将 networkState
设置为 NETWORK_IDLE
。
排队一个媒体元素任务,给定 媒体元素,以 触发一个名为 suspend
的事件。
排队一个媒体元素任务,给定 媒体元素,以将元素的 delaying-the-load-event flag 设置为 false。这将停止 延迟加载事件。
等待任务执行。
等待一个 实现定义 的事件(例如,用户请求媒体元素开始播放)。
将元素的 delaying-the-load-event flag 重新设置为 true(这再次 延迟加载事件,以防它尚未触发)。
将 networkState
设置为 NETWORK_LOADING
。
让 request 成为 创建一个潜在的 CORS 请求 的结果,给定
current media resource 的 URL
记录、destination 和 媒体元素 的当前状态的 crossorigin
内容属性。
将 request 的 发起者类型 设置为 destination。
让 byteRange 为 "entire resource
" 或一个(number,number 或
"until end
")元组,表示满足 媒体数据 中缺失数据所需的字节范围。该值是 实现定义的,并可能依赖于编解码器、网络状况或其他启发式方法。用户代理可能决定完全获取资源,在这种情况下
byteRange 将为 "entire resource
",从字节偏移量到结束获取资源,在这种情况下 byteRange
将为(number,"until end
"),或在两个字节偏移量之间获取资源,在这种情况下 byteRange
将为表示两个偏移量的(number,number)元组。
如果 byteRange 不是 "entire resource
",则:
如果 byteRange[1] 是 "until end
",则 向 request 添加一个范围头,给定 byteRange[0]。
否则,向 request 添加一个范围头,给定 byteRange[0] 和 byteRange[1]。
获取 request,并设置 processResponse 为以下步骤,给定 response response:
让 updateMedia 是 排队一个媒体元素任务,给定 媒体元素 以运行以下 媒体数据处理步骤列表中的第一个适当步骤。(为此使用一个新任务,使以下描述的工作相对于适当的 媒体元素事件任务源 发生,而不是使用 网络任务源。)
让 processEndOfMedia 是以下步骤:如果获取过程在没有错误的情况下完成,包括解码媒体数据,并且所有数据都可供用户代理在不进行网络访问的情况下使用,那么,用户代理必须继续执行以下最后一步。这可能永远不会发生,例如在流式传输无限资源(如网络广播)时,或者资源长度超过用户代理的缓存数据能力。
如果给定 current media resource 和 byteRange 验证 response 的结果为 false,则中止这些步骤。
否则,增量读取 response 的 主体,给定 updateMedia、processEndOfMedia、一个空算法和 global。
使用以这种方式获取的 response 的 不安全响应 内容更新 媒体数据。response 可以是 CORS-same-origin 或
CORS-cross-origin;这会影响通过 API 公开的字幕,并且,对于
video
元素,当视频被绘制到画布上时,画布是否会被污染。
媒体元素停止超时 是一个 实现定义的 时间长度,应该约为三秒。当一个正在积极尝试获取 媒体数据 的 媒体元素 在等于 媒体元素停止超时 的时间内未能接收到任何数据时,用户代理必须 排队一个媒体元素任务,给定 媒体元素 来:
将元素的 is currently stalled 设置为 true。
用户代理可能允许用户选择性地阻止或减慢 媒体数据 下载。当 媒体元素 的下载被完全阻止时,用户代理必须像处理它停止了一样(而不是像连接关闭了一样)。下载速度也可能会被用户代理自动限制,例如平衡与共享同一带宽的其他连接的下载。
用户代理可以随时决定不下载更多内容,例如在缓冲一个小时媒体资源的五分钟后,等待用户决定是否播放资源,在交互式资源中等待用户输入,或者当用户导航离开页面时。当 媒体元素
的下载被暂停时,用户代理必须 排队一个媒体元素任务,给定 媒体元素,将 networkState
设置为 NETWORK_IDLE
并 触发一个名为
suspend
的事件。如果且当资源的下载恢复时,用户代理必须 排队一个媒体元素任务,给定 媒体元素,将 networkState
设置为 NETWORK_LOADING
。在这些任务排队之间,加载被暂停(因此如上所述,不会触发
progress
事件)。
preload
属性提供了一个提示,即使在没有 autoplay
属性的情况下,作者认为建议缓冲多少。
当用户代理决定完全暂停下载时,例如,如果它正在等待用户开始播放然后再下载任何进一步的内容,用户代理必须 排队一个媒体元素任务,给定 媒体元素,将元素的 delaying-the-load-event flag 设置为 false。这将停止 延迟加载事件。
尽管上述步骤给出了发出请求的算法,用户代理可能会使用其他方法,特别是在面对错误条件时。例如,用户代理可能会重新连接到服务器或切换到流协议。用户代理必须只在放弃尝试获取资源时才认为资源出错,并继续上述步骤的错误分支。
为了确定 媒体资源 的格式,用户代理必须使用 专门嗅探音频和视频的规则。
在加载未暂停的情况下(见下文),每 350 毫秒(±200 毫秒)或每接收一个字节,以频率更低者为准,排队一个媒体元素任务,给定 媒体元素 以:
将元素的 is currently stalled 设置为 false。
虽然用户代理可能仍然需要网络访问才能获取 媒体资源 的部分内容,用户代理必须停留在此步骤。
例如,如果用户代理已丢弃视频的前半部分,即使 播放已结束,用户代理仍将停留在此步骤,因为用户随时可能会回放到开始处。事实上,在这种情况下,一旦 播放已结束,用户代理最终将触发一个 suspend
事件,如前所述。
由 current media resource 描述的资源(如果有)包含 媒体数据。它是 CORS-same-origin。
如果 current media resource 是原始数据流(例如来自 File
对象),则为了确定 媒体资源 的格式,用户代理必须使用
专门嗅探音频和视频的规则。否则,如果数据流是预解码的,则格式是相关规范给出的格式。
每当新的 current media resource 数据可用时,排队一个媒体元素任务,给定 媒体元素 以运行以下 媒体数据处理步骤列表中的第一个适当步骤。
当 current media resource 永久耗尽时(例如,Blob
的所有字节已处理完),如果没有解码错误,则用户代理必须继续执行以下 最后一步。这可能永远不会发生,例如,如果 current media resource 是 MediaStream
。
媒体数据处理步骤列表 如下:
在用户代理确定 current media resource 是否可用之前发生的 DNS 错误、HTTP 4xx 和 5xx 错误(以及其他协议的等效错误)以及其他致命网络错误,以及文件使用不受支持的容器格式或所有数据使用不受支持 的编解码器,必须导致用户代理执行以下步骤:
用户代理应取消获取过程。
中止此子算法,返回到 资源选择算法。
创建一个 AudioTrack
对象以表示音轨。
使用新的 AudioTrack
对象更新 媒体元素 的 audioTracks
属性的 AudioTrackList
对象。
让 enable 为 unknown。
如果 媒体资源 或 current media resource 的 URL 表示启用特定的音轨集,或者如果用户代理有信息可以选择特定音轨以改善用户体验,那么:如果此音轨是要启用的音轨之一,则将 enable 设置为 true,否则将 enable 设置为 false。
这可能由 媒体片段语法 触发,但也可能由例如用户代理选择 5.1 环绕声音轨而不是立体声音轨触发。
如果 enable 仍为 unknown,则如果 媒体元素 还没有启用音轨,则将 enable 设置为 true,否则将 enable 设置为 false。
如果 enable 是 true,则启用此音轨,否则,不启用此音轨。
触发一个名为
addtrack
的事件,使用 TrackEvent
,其
track
属性初始化为新的 AudioTrack
对象。
创建一个 VideoTrack
对象以表示视频轨道。
使用新的 VideoTrack
对象更新 媒体元素 的 videoTracks
属性的 VideoTrackList
对象。
让 enable 为 unknown。
如果 媒体资源 或 current media resource 的 URL 表示启用特定的视频轨道集,或者如果用户代理有信息可以选择特定视频轨道以改善用户体验,那么:如果这是第一个这样的视频轨道,则将 enable 设置为 true,否则将 enable 设置为 false。
这可能再次由 媒体片段语法 触发。
如果 enable 仍为 unknown,则如果 媒体元素 还没有选中的视频轨道,则将 enable 设置为 true,否则将 enable 设置为 false。
如果 enable 是 true,则选择此轨道并取消选择任何先前选中的视频轨道,否则,不选择此视频轨道。如果其他轨道被取消选择,则 将触发 change
事件。
触发一个名为
addtrack
的事件,使用 TrackEvent
,其
track
属性初始化为新的 VideoTrack
对象。
这表明资源可用。用户代理必须遵循这些子步骤:
根据上一步建立的 媒体时间轴,将 时间轴偏移 更新为与零时间相对应的日期和时间。如果 媒体资源 没有明确给出时间和日期,则 时间轴偏移 必须设置为非数字(NaN)。
使用上面建立的 媒体时间轴
的最后一帧的时间(如果已知)更新 duration
属性。如果未知(例如,一个原则上无限的流),则将 duration
属性更新为正无穷大。
用户代理 将 排队一个媒体元素任务,给定 媒体元素
以 触发一个名为
durationchange
的事件。
对于 video
元素,设置 videoWidth
和 videoHeight
属性,并 排队一个媒体元素任务,给定 媒体元素
以 触发一个名为
resize
的事件。
如果尺寸随后发生变化,将触发进一步的 resize
事件。
将 readyState
属性设置为 HAVE_METADATA
。
作为将 readyState
属性设置为新值的一部分,将触发 loadedmetadata
DOM 事件。
让 jumped 为 false。
让 initial playback position 为零。
如果 媒体资源 或 current media resource 的 URL 表示特定的开始时间,则将 initial playback position 设置为该时间,并且如果 jumped 仍为 false,则 seek 到该时间。
如果没有 启用
的音轨,则启用一个音轨。这将 触发 change
事件。
如果没有 选中的 视频轨道,则选择一个视频轨道。这将 触发 change
事件。
一旦 readyState
属性达到 HAVE_CURRENT_DATA
,在触发 loadeddata
事件后,将元素的 delaying-the-load-event flag 设置为
false。这将停止 延迟加载事件。
一个尝试减少网络使用的用户代理,同时仍然获取每个 媒体资源 的元数据,也将在此时停止缓冲,按照 前面描述的规则,这包括 networkState
属性切换到 NETWORK_IDLE
值并触发 suspend
事件。
用户代理在播放之前必须确定 媒体资源 的持续时间并执行此步骤。
将 networkState
设置为 NETWORK_IDLE
并 触发一个名为
suspend
的事件,给定 媒体元素。
如果用户代理丢弃了任何 媒体数据,然后需要恢复网络活动以再次获取它,则用户代理必须 排队一个媒体元素任务,给定 媒体元素,将
networkState
设置为 NETWORK_LOADING
。
如果用户代理可以保持 媒体资源 已加载,则算法将继续执行其 最后一步,该步骤将中止算法。
在用户代理确定 current media resource 是否可用之后发生的致命网络错误(即一旦 媒体元素 的
readyState
属性不再是 HAVE_NOTHING
)必须导致用户代理执行以下步骤:
用户代理应取消获取过程。
将 error
属性设置为 创建一个
MediaError
的结果,并设置为
MEDIA_ERR_NETWORK
。
将元素的 networkState
属性设置为 NETWORK_IDLE
值。
将元素的 delaying-the-load-event flag 设置为 false。这将停止 延迟加载事件。
中止整体 资源选择算法。
在用户代理确定 current media resource 是否可用之后发生的致命解码错误(即一旦 媒体元素 的
readyState
属性不再是 HAVE_NOTHING
)必须导致用户代理执行以下步骤:
用户代理应取消获取过程。
将 error
属性设置为 创建一个
MediaError
的结果,并设置为
MEDIA_ERR_DECODE
。
将元素的 networkState
属性设置为 NETWORK_IDLE
值。
将元素的 delaying-the-load-event flag 设置为 false。这将停止 延迟加载事件。
中止整体 资源选择算法。
用户中止了获取过程,例如因为用户按下了“停止”按钮,则用户代理必须执行以下步骤。如果在执行这些步骤时调用了 load()
方法,则不执行这些步骤,因为上述步骤处理了那种特定类型的中止。
用户代理应取消获取过程。
将 error
属性设置为 创建一个
MediaError
的结果,并设置为
MEDIA_ERR_ABORTED
。
如果 媒体元素 的 readyState
属性值等于 HAVE_NOTHING
,则将元素的
networkState
属性设置为 NETWORK_EMPTY
值,将元素的 show poster
flag 设置为 true,并 触发一个名为
emptied
的事件。
否则,将元素的 networkState
属性设置为 NETWORK_IDLE
值。
将元素的 delaying-the-load-event flag 设置为 false。这将停止 延迟加载事件。
中止整体 资源选择算法。
服务器返回的数据 部分可用但无法最佳渲染,必须导致用户代理仅渲染它能处理的部分,忽略其余部分。
如果 媒体数据 是 CORS-same-origin,则使用相关数据运行 步骤以暴露媒体资源特定文本轨道。
跨源视频不暴露其字幕,因为这将允许攻击,例如恶意网站从用户内联网的机密视频中读取字幕。
最后一步:如果用户代理达到此步骤(这只有在整个资源加载并保持可用的情况下才会发生):中止整体 资源选择算法。
当一个媒体元素需要忘记媒体元素的媒体资源特定轨道时,用户代理必须从媒体元素的文本轨道列表中移除所有媒体资源特定文本轨道,然后清空媒体元素的audioTracks
属性的AudioTrackList
对象,然后清空媒体元素的videoTracks
属性的VideoTrackList
对象。作为这一过程的一部分不会触发任何事件(特别是不触发removetrack
事件);可以使用调用此算法的算法触发的error
和emptied
事件代替。
preload
属性是一个 枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
auto
|
自动 | 向用户代理暗示,用户代理可以优先考虑用户的需求而不会对服务器造成风险,包括乐观地下载整个资源。 |
(空字符串) | ||
none
|
无 | 向用户代理暗示,作者不期望用户需要媒体资源,或者服务器希望最小化不必要的流量。此状态不提供有关在缓冲开始后如何积极下载媒体资源的暗示(例如,一旦用户点击“播放”)。 |
metadata
|
元数据 | 向用户代理暗示,作者不期望用户需要媒体资源,但获取资源元数据(尺寸、轨道列表、持续时间等)甚至前几帧是合理的。如果用户代理精确地不超过元数据的获取,那么 媒体元素 最终会将其
readyState
属性设置为 HAVE_METADATA ;但通常会获取一些帧,它可能会是
HAVE_CURRENT_DATA
或 HAVE_FUTURE_DATA 。当媒体资源在播放时,暗示用户代理要考虑带宽稀缺,例如建议节流下载以最慢的速度获取媒体数据,同时保持连续播放。
|
该属性的 缺失值默认 和 无效值默认 都是 实现定义的,尽管建议将 元数据 状态作为在减少服务器负载和提供最佳用户体验之间的折衷。
即使在 媒体资源 正在缓冲或播放时也可以更改该属性;上表中的描述应考虑到这一点。
作者可能会在用户开始播放后,将属性从 "none
"
或 "metadata
"
动态切换为 "auto
"。例如,在有许多视频的页面上,这可能用于指示除非请求否则不下载许多视频,但一旦请求其中一个视频,则应积极下载。
preload
属性旨在向用户代理提供一个提示,关于作者认为什么会带来最佳用户体验。该属性可能会被完全忽略,例如基于用户的明确偏好或可用的连接情况。
preload
IDL 属性必须 反映 同名内容属性,仅限于已知值。
autoplay
属性可以覆盖 preload
属性(因为如果媒体播放,它自然首先要缓冲,不论 preload
属性给出的提示如何)。然而,同时包含这两个属性并不是错误。
media.buffered
所有当前引擎支持。
返回一个 TimeRanges
对象,该对象表示用户代理已缓冲的媒体资源的范围。
buffered
属性必须返回一个新的静态标准化
TimeRanges
对象,该对象表示用户代理在评估属性时已缓冲的媒体资源的范围(如果有)。用户代理必须准确确定可用的范围,即使对于只能通过繁琐检查确定的媒体流。
通常,这将是锚定在零点的单一范围,但如果例如用户代理在响应搜索时使用 HTTP 范围请求,则可能有多个范围。
用户代理可以丢弃先前缓冲的数据。
因此,一段时间内由 buffered
属性返回的对象范围内的时间位置,可能在稍后时间由相同属性返回的对象范围内不包括。
每次返回一个新对象是属性获取器的不良模式,仅在此固化是因为更改它的代价高昂。这不应复制到新的 API 中。
media.duration
所有当前引擎支持。
返回媒体资源的长度,单位为秒,假设媒体资源的起点为零。
如果持续时间不可用,则返回 NaN。
对于无限流,返回 Infinity。
media.currentTime [ = value ]
所有当前引擎支持。
返回官方播放位置,以秒为单位。
可以设置,以跳到指定时间。
媒体资源有一个媒体时间线,将时间(以秒为单位)映射到媒体资源中的位置。时间线的起点是其最早定义的位置。时间线的持续时间是其最后定义的位置。
建立媒体时间线:如果媒体资源以某种方式指定了起点不是负数的显式时间线(即为每帧指定了特定的时间偏移,并为第一帧指定了零或正偏移),则媒体时间线应为该时间线。(是否可以指定时间线取决于媒体资源的格式。)如果媒体资源指定了显式的开始时间和日期,则该时间和日期应被视为媒体时间线的零点;时间线偏移量将是时间和日期,通过getStartDate()
方法暴露。
如果媒体资源具有不连续的时间轴,用户代理必须在整个资源范围内扩展资源开始时使用的时间轴,以使媒体时间轴从最早可能的位置(如下所定义)线性增加,即使底层媒体数据具有无序甚至重叠的时间码。
例如,如果将两个片段连接到一个视频文件中,但视频格式暴露了两个片段的原始时间,则视频数据可能暴露一个时间线,例如 00:15..00:29 然后是 00:05..00:38。然而,用户代理不会暴露这些时间;相反,它会 将时间暴露为 00:15..00:29 和 00:29..01:02,作为一个单一视频。
在极少数情况下,如果媒体资源没有显式时间线,媒体时间线的零时间应对应于媒体资源的第一帧。在更罕见的情况下,如果媒体资源没有任何显式时间信息,甚至没有帧持续时间,用户代理必须以实现定义的方式自行确定每帧的时间。
没有显式时间线但有显式帧持续时间的文件格式的示例是动画 GIF 格式。没有任何显式时间的文件格式的示例是 JPEG 推送格式(multipart/x-mixed-replace
与
JPEG 帧,通常用作 MJPEG 流的格式)。
如果在没有时间信息的资源情况下,用户代理仍然能够跳到服务器最初提供的第一帧之前的较早位置,则零时间应对应于媒体资源的最早可寻位置;否则,它应对应于从服务器收到的第一帧(用户代理开始接收流的媒体资源中的位置)。
在撰写本文时,没有已知的格式缺少显式帧时间偏移但仍支持跳到服务器发送的第一帧之前的帧。
考虑一个电视广播的流,它在十月的一个阳光明媚的星期五下午开始流,并且始终向连接的用户代理发送相同媒体时间线上的媒体数据,其零时间设置为该流的开始时间。几个月后,连接到该流的用户代理会发现他们收到的第一帧时间有数百万秒。getStartDate()
方法将始终返回广播开始的日期;这将允许控制器在其进度条上显示实际时间(例如“下午
2:30”)而不是相对于广播开始的时间(“8 个月 4 小时 12 分钟 23 秒”)。
考虑一个包含多个连接片段的视频流,由不允许用户代理请求特定时间但只按预定顺序流式传输视频数据的服务器广播,始终将第一个传送的帧标识为时间零的帧。如果用户代理连接到此流并收到覆盖时间戳 2010-03-20 23:15:00
UTC 至 2010-03-21 00:05:00 UTC 和 2010-02-12 14:25:00 UTC 至 2010-02-12 14:35:00 UTC 的片段,它会以从 0 秒开始并延伸到 3600
秒(一小时)的媒体时间线暴露这些时间。假设流媒体服务器在第二个片段结束时断开连接,则duration
属性会返回
3600。getStartDate()
方法会返回一个Date
对象,时间对应于
2010-03-20 23:15:00 UTC。然而,如果另一个用户代理五分钟后连接,它会(大概)收到覆盖时间戳 2010-03-20 23:20:00 UTC 至 2010-03-21 00:05:00 UTC 和
2010-02-12 14:25:00 UTC 至 2010-02-12 14:35:00 UTC 的片段,并以从 0 秒开始并延伸到 3300 秒(五十五分钟)的媒体时间线暴露这些时间。在这种情况下,getStartDate()
方法会返回一个Date
对象,时间对应于
2010-03-20 23:20:00 UTC。
在这两个示例中,seekable
属性将给出控制器希望在其
UI 中实际显示的范围;通常,如果服务器不支持跳到任意时间,这将是从用户代理连接到流的时刻到用户代理已获取的最新帧的时间范围;然而,如果用户代理开始丢弃早期信息,实际范围可能会更短。
在任何情况下,用户代理都必须确保使用已建立的媒体时间线(如下所定义)时的最早可能位置大于或等于零。
媒体时间线还有一个关联的时钟。使用哪个时钟由用户代理定义,可能依赖于媒体资源,但它应近似用户的挂钟。
媒体元素有一个当前播放位置,其初始值(即在没有媒体数据的情况下)必须为零秒。当前播放位置是媒体时间线上的时间。
媒体元素也有一个官方播放位置,它最初必须设置为零秒。官方播放位置是当前播放位置的一个近似值,在脚本运行时保持稳定。
媒体元素还有一个默认播放起始位置,其初始值必须设置为零秒。此时间用于在媒体加载之前允许元素进行搜索。
每个媒体元素都有一个显示海报标志。创建媒体元素时,必须将此标志设置为 true。此标志用于控制何时为视频
元素显示海报帧,而不是显示视频内容。
currentTime
属性必须,在获取时,返回媒体元素的默认播放起始位置,除非该值为零,在这种情况下它必须返回元素的官方播放位置。返回值必须以秒为单位表示。在设置时,如果媒体元素的readyState
为HAVE_NOTHING
,则必须将媒体元素的默认播放起始位置设置为新值;否则,它必须将官方播放位置设置为新值,然后搜索到新值。新值必须以秒为单位解释。
如果媒体资源是流媒体资源,则用户代理可能无法在缓冲区过期后获取资源的某些部分。同样,某些媒体资源可能有一个不从零开始的媒体时间线。最早可能的位置是用户代理可以再次获得的流或资源中的最早位置。这也是媒体时间线上的一个时间。
最早可能的位置在API中没有明确暴露;它对应于seekable
属性的TimeRanges
对象中第一个范围的开始时间(如果有的话),否则对应于当前播放位置。
当最早可能的位置变化时,如果当前播放位置早于最早可能的位置,用户代理必须搜索到最早可能的位置;否则,如果用户代理在过去 15 到 250
毫秒内没有在元素上触发timeupdate
事件,并且还没有在运行该事件的事件处理程序,则用户代理必须排队媒体元素任务,将该媒体元素给定以触发一个名为timeupdate
的事件。
由于上述要求和资源获取算法中在获取媒体元数据时启动的要求,当前播放位置不能小于最早可能的位置。
如果用户代理在任何时候得知音轨或视频轨道已经结束,并且所有媒体数据都对应于媒体时间线中早于最早可能位置的部分,则用户代理可以排队一个媒体元素任务,将该媒体元素给定以运行这些步骤:
从audioTracks
属性的AudioTrackList
对象或videoTracks
属性的VideoTrackList
对象中移除该轨道(根据需要)。
触发一个名为removetrack
的事件,使用TrackEvent
,在上述媒体元素的AudioTrackList
或VideoTrackList
对象上,初始化track
属性为代表轨道的AudioTrack
或VideoTrack
对象。
duration
属性必须返回媒体资源在媒体时间线上的结束时间,以秒为单位。如果没有可用的媒体数据,则属性必须返回 NaN
值。如果媒体资源不被认为是有界的(例如流媒体广播或没有宣布结束时间的直播活动),则属性必须返回正无穷值。
用户代理必须在播放任何媒体数据之前,并且在将readyState
设置为大于或等于HAVE_METADATA
之前,确定媒体资源的持续时间,即使这样做需要获取资源的多个部分。
当媒体资源的长度变为已知值(例如从未知变为已知,或从先前确定的长度变为新长度)时,用户代理必须排队一个媒体元素任务,将该媒体元素给定以触发一个名为durationchange
的事件(加载新媒体资源时重置持续时间不会触发此事件)。如果持续时间发生变化,使当前播放位置大于媒体资源的结束时间,则用户代理还必须搜索到媒体资源的结束时间。
如果“无限”流出于某种原因结束,则持续时间将从正无穷大变为流中最后一帧或样本的时间,并触发durationchange
事件。同样,如果用户代理最初估计媒体资源的持续时间而不是精确定义它,并根据新信息稍后修正估计,则持续时间会发生变化并触发durationchange
事件。
某些视频文件还有一个与媒体时间线的零时间相对应的显式日期和时间,称为时间线偏移。初始时,时间线偏移必须设置为 NaN。
getStartDate()
方法必须返回一个新的Date
对象,表示当前的时间线偏移。
loop
属性是一个布尔属性,如果指定,表示媒体元素在到达媒体资源的末尾时应回到开始。
所有当前引擎支持。
loop
IDL
属性必须反映同名内容属性。
media.readyState
所有当前引擎支持。
返回一个值,该值表示元素当前相对于渲染当前播放位置的状态,从以下列表中的代码中选择。
媒体元素有一个就绪状态,描述了它在当前播放位置准备渲染的程度。可能的值如下;任何特定时间媒体元素的就绪状态是描述元素状态的最大值:
HAVE_NOTHING
(数值 0)没有可用的关于媒体资源的信息。没有关于当前播放位置的数据。媒体元素的networkState
属性设置为NETWORK_EMPTY
时,总是处于HAVE_NOTHING
状态。
HAVE_METADATA
(数值 1)已获取足够的资源,以便可以获得资源的持续时间。如果是视频
元素,也可以获得视频的尺寸。没有可用的关于媒体数据的当前播放位置的数据。
HAVE_CURRENT_DATA
(数值 2)有可用的关于当前播放位置的数据,但没有足够的数据让用户代理能够在不立即恢复到HAVE_METADATA
状态的情况下成功地在播放方向上推进当前播放位置,或者在播放方向上没有更多的数据可获取。例如,在视频中,这对应于用户代理拥有当前帧的数据,但没有下一帧的数据,当当前播放位置在当前帧的末尾时;以及当播放已结束时。
HAVE_FUTURE_DATA
(数值 3)有可用的关于当前播放位置的数据,以及足够的数据让用户代理能够在不立即恢复到HAVE_METADATA
状态的情况下至少在播放方向上推进当前播放位置,并且文本轨道已准备好。例如,在视频中,这对应于用户代理在当前播放位置位于两帧之间的瞬间时,拥有至少当前帧和下一帧的数据,或者当当前播放位置在帧中间时,拥有当前帧的视频数据和至少能继续播放一点的音频数据。如果播放已结束,用户代理不能处于此状态,因为在这种情况下当前播放位置永远不能前进。
HAVE_ENOUGH_DATA
(数值 4)满足HAVE_FUTURE_DATA
状态描述的所有条件,并且满足以下条件之一:
playbackRate
推进,在播放到达媒体资源末尾之前不会超过可用数据。实际上,HAVE_METADATA
和HAVE_CURRENT_DATA
之间的区别是微不足道的。真正唯一相关的区别是在将视频
元素绘制到画布
上时,它区分了会绘制某些内容的情况(HAVE_CURRENT_DATA
或更高)与不会绘制任何内容的情况(HAVE_METADATA
或更低)。同样,HAVE_CURRENT_DATA
(仅当前帧)和HAVE_FUTURE_DATA
(至少当前帧和下一帧)之间的区别可能是微不足道的(在极端情况下,仅一个帧)。这种区别真正重要的唯一时间是页面提供“逐帧”导航接口时。
当媒体元素的networkState
不为NETWORK_EMPTY
时,其就绪状态发生变化时,用户代理必须按照以下步骤操作:
从以下列表中应用第一个适用的子步骤集:
HAVE_NOTHING
,而新就绪状态是HAVE_METADATA
排队一个媒体元素任务,将该媒体元素给定以触发一个名为loadedmetadata
的事件。
HAVE_METADATA
,而新就绪状态是HAVE_CURRENT_DATA
或更高
如果这是自上次调用load()
算法以来首次发生这种情况,对于该媒体元素,用户代理必须排队一个媒体元素任务,给定媒体元素去触发一个名为loadeddata
的事件在该元素上。
如果新就绪状态是HAVE_FUTURE_DATA
或HAVE_ENOUGH_DATA
,则必须运行以下相关步骤。
HAVE_FUTURE_DATA
或更高,而新就绪状态是HAVE_CURRENT_DATA
或更低
如果媒体元素在readyState
属性降至HAVE_FUTURE_DATA
以下之前处于潜在播放状态,并且元素未结束播放,且播放未因错误停止、因用户互动暂停或因带内内容暂停,用户代理必须排队一个媒体元素任务,将该媒体元素给定以触发一个名为timeupdate
的事件,并排队一个媒体元素任务,将该媒体元素给定以触发一个名为waiting
的事件。
HAVE_CURRENT_DATA
或更低,而新就绪状态是HAVE_FUTURE_DATA
用户代理必须排队一个媒体元素任务,将该媒体元素给定以触发一个名为canplay
的事件。
HAVE_ENOUGH_DATA
如果之前的就绪状态是HAVE_CURRENT_DATA
或更低,用户代理必须排队一个媒体元素任务,将该媒体元素给定以触发一个名为canplay
的事件,并且,如果元素的paused
属性为
false,通知关于播放。
用户代理必须排队一个媒体元素任务,将该媒体元素给定以触发一个名为canplaythrough
的事件。
如果元素不符合自动播放条件,则用户代理必须中止这些子步骤。
用户代理可以运行以下子步骤:
paused
属性设置为
false。play
的事件。
或者,如果元素是视频
元素,用户代理可以开始观察元素是否与视口相交。当元素开始与视口相交时,如果元素仍然符合自动播放条件,运行上述子步骤。可选地,当元素停止与视口相交时,如果可自动播放标志仍然为真并且自动播放
属性仍然指定,运行以下子步骤:
pause
的事件。
随着元素开始或停止与视口相交,播放和暂停的子步骤可以多次运行,只要可自动播放标志为真。
用户代理不需要支持自动播放,建议用户代理尊重用户对该问题的偏好。建议作者使用自动播放
属性而不是使用脚本强制视频播放,以便允许用户在需要时覆盖行为。
媒体元素的就绪状态可能会不连续地在这些状态之间跳跃。例如,媒体元素的状态可以直接从HAVE_METADATA
跳到HAVE_ENOUGH_DATA
,而不经过HAVE_CURRENT_DATA
和HAVE_FUTURE_DATA
状态。
readyState
IDL 属性在获取时必须返回上述描述的值,表示媒体元素的当前就绪状态。
autoplay
属性是一个布尔属性。当存在时,用户代理(如本文中描述的算法所述)将自动开始播放媒体资源,只要它可以在不停止的情况下进行。
建议作者使用自动播放
属性,而不是使用脚本触发自动播放,因为这允许用户在不需要时覆盖自动播放,例如使用屏幕阅读器时。作者还被鼓励考虑完全不使用自动播放行为,而是让用户代理等待用户显式启动播放。
所有当前引擎支持。
autoplay
IDL 属性必须反映同名内容属性。
media.paused
在所有当前引擎中支持。
如果播放已暂停,则返回 true;否则返回 false。
media.ended
在所有当前引擎中支持。
如果播放已达到 媒体资源 的结束,则返回 true。
media.defaultPlaybackRate [ = value ]
HTMLMediaElement/defaultPlaybackRate
在所有当前引擎中支持。
返回默认的播放速率,用于用户未快进或倒退媒体时的播放。
可以设置此属性来更改默认的播放速率。
默认速率对播放没有直接影响,但如果用户切换到快进模式,当他们返回到正常播放模式时,预计播放速率将恢复为默认播放速率。
media.playbackRate [ = value ]
在所有当前引擎中支持。
返回当前的播放速率,其中 1.0 为正常速度。
可以设置此属性来改变播放速率。
media.preservesPitch
HTMLMediaElement/preservesPitch
如果使用了保持音调算法,当 playbackRate
不等于 1.0 时返回 true。默认值为 true。
可以设置为 false,使 媒体资源 的音频音调随 playbackRate
改变。这对审美和性能方面都有帮助。
media.played
返回一个 TimeRanges
对象,表示用户代理已播放的 媒体资源 的范围。
media.play()
所有当前引擎均支持。
将 paused
属性设置为 false,如果需要的话,加载
媒体资源
并开始播放。如果播放已经结束,将从头开始重新播放。
media.pause()
所有当前引擎均支持。
paused
属性表示 媒体元素
是否处于暂停状态。该属性初始值必须为 true。
如果 媒体元素 的 readyState
属性处于 HAVE_NOTHING
状态、HAVE_METADATA
状态,或 HAVE_CURRENT_DATA
状态,或者如果该元素已被 用户交互暂停 或 因带内内容暂停,则该媒体元素被称为 被阻塞的媒体元素。
当 媒体元素 的 paused
属性为 false,且元素没有 结束播放、播放没有 因错误停止,且元素不是 被阻塞的媒体元素 时,该媒体元素被称为 可能正在播放。
如果 waiting
DOM 事件 可能会触发,当一个
可能正在播放
的元素因其 readyState
属性的值变为低于 HAVE_FUTURE_DATA
时。
当以下所有条件都满足时,媒体元素 被认为是 符合自动播放条件:
如果用户代理和系统允许在当前上下文中播放媒体,则 媒体元素 被认为是 允许播放。
例如,用户代理可能只在 媒体元素 的
Window
对象具有
临时激活
时允许播放,但可以做出例外,允许在 静音 时播放。
当以下条件满足时,媒体元素 被认为是 播放结束:
元素的 readyState
属性为 HAVE_METADATA
或更高,并且
要么:
或者:
ended
属性必须返回 true,如果在 事件循环 到达
步骤 1 时,媒体元素 处于 播放结束 状态且播放方向为向前,否则返回 false。
当以下条件满足时,媒体元素 被认为是 由于错误停止:
元素的 readyState
属性为 HAVE_METADATA
或更高,并且用户代理在处理 媒体数据 时遇到 非致命错误,并且由于该错误,无法在 当前播放位置 播放内容。
当 媒体元素 的 paused
属性为 false,且 readyState
属性为 HAVE_FUTURE_DATA
或 HAVE_ENOUGH_DATA
时,并且用户代理已到达需要用户进行选择的 媒体资源
的一个点,以继续播放,则媒体元素被认为是 因用户交互暂停。
一个 媒体元素 可以同时具有 播放结束 和 因用户交互暂停 状态。
当一个 媒体元素 处于 可能播放
状态并且因 因用户交互暂停 而停止播放时,用户代理必须 排队一个媒体元素任务,以便 媒体元素 触发一个名为 timeupdate
的事件。
当 媒体元素 的 paused
属性为 false,且 readyState
属性为 HAVE_FUTURE_DATA
或 HAVE_ENOUGH_DATA
时,且用户代理已暂停 媒体资源
的播放,以播放时间上锚定到该资源且长度不为零的内容,或播放时间上锚定到该媒体资源的一段但长度大于该段的内容时,媒体元素被认为是 因带内内容暂停。
一个 媒体元素 被认为是 因带内内容暂停 的一个例子是当用户代理正在播放来自外部 WebVTT 文件的 音频描述 时,而为某个提示生成的合成语音的时间长于 文本轨道提示开始时间 和 文本轨道提示结束时间 之间的时间。
当 当前播放位置 达到 媒体资源 的末尾时,且 播放方向 为前向,用户代理必须遵循以下步骤:
排队一个媒体元素任务,给定 媒体元素 和以下步骤:
当 当前播放位置 达到 最早可能的位置 的 媒体资源 时,如果 播放方向 为后向,则用户代理仅需 排队一个媒体元素任务,给定
媒体元素,以 触发一个事件,事件名为 timeupdate
。
这里的“达到”并不意味着 当前播放位置 必须在正常播放过程中发生变化;它也可以通过 跳转 进行变化。
defaultPlaybackRate
属性给出 媒体资源
播放的期望速度,作为其固有速度的倍数。该属性是可变的:在获取时必须返回最后设置的值,如果尚未设置则返回 1.0;在设置时,属性必须设置为新值。
用户代理在 向用户暴露用户界面 时使用 defaultPlaybackRate
。
playbackRate
属性给出有效的播放速率,即 媒体资源
播放的速度,作为其固有速度的倍数。如果它不等于 defaultPlaybackRate
,则意味着用户正在使用诸如快进或慢动作播放等功能。该属性是可变的:在获取时必须返回最后设置的值,如果尚未设置则返回
1.0;在设置时,用户代理必须遵循以下步骤:
如果给定值不被用户代理支持,则抛出 “NotSupportedError
” DOMException
。
将 playbackRate
设置为新值,如果元素处于 可能正在播放
状态,则更改播放速度。
当 defaultPlaybackRate
或 playbackRate
属性值发生变化(无论是由脚本设置还是由用户代理直接更改,例如响应用户控制时),用户代理必须 排队一个媒体元素任务,给定 媒体元素,以 触发一个事件,事件名为 ratechange
,在
媒体元素
上。用户代理必须平滑地处理属性更改,不能引入任何可感知的间隙或静音。
preservesPitch
的获取步骤是,如果在播放期间应用了保持音高的算法,则返回
true。设置步骤是相应地开启或关闭保持音高的算法,而不引入任何可感知的间隙或静音。默认情况下,必须启用这种保持音高的算法(即,获取器将初始返回 true)。
played
属性必须返回一个新的静态 规范化的 TimeRanges
对象,该对象表示通过通常的单调递增的
当前播放位置
在正常播放期间到达的 媒体时间轴
上的范围,如果有的话,在属性被评估时。
每次返回一个新对象是一种不良的属性获取器模式,仅在这里被保留,因为改变它会很麻烦。这不应被复制到新的 API 中。
每个 媒体元素 都有一个 待处理播放承诺的列表,该列表最初必须是空的。
要 获取待处理播放承诺 对于一个 媒体元素,用户代理必须执行以下步骤:
让 promises 成为一个空的承诺列表。
将 媒体元素 的 待处理播放承诺的列表 复制到 promises。
清空 媒体元素 的 待处理播放承诺的列表。
要 解决待处理播放承诺 对于一个 媒体元素 和一个承诺列表 promises,用户代理必须用未定义值解决 promises 中的每个承诺。
要 拒绝待处理播放承诺 对于一个 媒体元素 和一个承诺列表 promises 及一个异常名称 error,用户代理必须用 error 拒绝 promises 中的每个承诺。
要 通知播放状态 对于一个 媒体元素,用户代理必须执行以下步骤:
获取待处理播放承诺 并将结果赋值给 promises。
排队一个媒体元素任务 给定该元素和以下步骤:
当对一个 媒体元素 调用
play()
方法时,用户代理必须执行以下步骤。
如果 媒体元素 不被
允许播放,则返回 一个被拒绝的承诺,拒绝原因是 "NotAllowedError
" DOMException
。
如果 媒体元素 的
error
属性不为 null 并且其 code 为 MEDIA_ERR_SRC_NOT_SUPPORTED
,则返回
一个被拒绝的承诺,拒绝原因是 "NotSupportedError
" DOMException
。
让 promise 成为一个新的承诺,并将 promise 添加到 待处理播放承诺的列表。
返回 promise。
对于一个 媒体元素 的 内部播放步骤 如下:
如果 媒体元素 的
networkState
属性的值为 NETWORK_EMPTY
,则调用
媒体元素 的 资源选择算法。
如果 播放已结束 且 播放方向 为前向,跳转到 媒体资源的最早可能位置。
这将导致用户代理 排队一个媒体元素任务 给定该 媒体元素,以 触发一个事件 名为 timeupdate
在该 媒体元素 上。
将 paused
的值更改为假。
排队一个媒体元素任务,给定媒体元素去触发一个事件,名为play
在该元素上。
如果 媒体元素
的 readyState
属性的值为 HAVE_NOTHING
、HAVE_METADATA
或 HAVE_CURRENT_DATA
,则
排队一个媒体元素任务 给定该 媒体元素,以 触发一个事件 名为
waiting
在该元素上。
否则,媒体元素
的 readyState
属性的值为 HAVE_FUTURE_DATA
或 HAVE_ENOUGH_DATA
:通知播放情况。
否则,如果 媒体元素
的 readyState
属性的值为 HAVE_FUTURE_DATA
或 HAVE_ENOUGH_DATA
,处理待处理的播放承诺
并且 排队一个媒体元素任务 给定该 媒体元素 以 解决待处理的播放承诺。
媒体元素已经在播放。然而,promise 可能会在排队任务执行之前被 拒绝。
当调用 pause()
方法时,并且当用户代理需要暂停 媒体元素,
用户代理必须执行以下步骤:
如果 媒体元素 的
networkState
属性的值为 NETWORK_EMPTY
,
调用 媒体元素 的
资源选择算法。
一个 媒体元素 的 内部暂停步骤 如下:
如果 媒体元素 的
paused
属性为假,则执行以下步骤:
将 paused
的值更改为真。
处理待处理的播放承诺 并让 promises 为结果。
排队一个媒体元素任务 给定该 媒体元素 和以下步骤:
触发一个事件
名为 timeupdate
在该元素上。
拒绝待处理的播放承诺 使用 promises
和一个 "AbortError
" DOMException
。
如果元素的 playbackRate
是正值或零,
那么 播放方向 为前进。否则,为后退。
当一个 媒体元素 处于 可能正在播放 状态并且
其 文档
是
一个
完全活动的
文档
,
其 当前播放位置
必须按照元素的 playbackRate
媒体时间单位每单位时间在 媒体时间轴
的时钟上单调增加。(该规范总是将其称为 增加,但这种增加实际上可能是
减少,如果元素的 playbackRate
是负数的话。)
元素的 playbackRate
可以是 0.0,在这种情况下,当前播放位置 不会移动,
尽管播放没有被暂停(paused
不会变为真,并且 pause
事件不会触发)。
该规范没有定义用户代理如何实现适当的播放速率——根据协议和可用媒体的不同,用户代理可能会与服务器协商,让服务器以适当的速率提供媒体数据,以便(除非在速率更改与服务器更新流的播放速率之间的时间段)客户端实际上不需要丢弃或插值任何帧。
每当用户代理 提供稳定状态 时, 官方播放位置 必须设置为 当前播放位置。
当 播放方向 为后退时,
任何相应的音频必须是
静音。当元素的 playbackRate
低到用户代理无法有效播放音频的程度时,相应的音频也必须被 静音。
如果元素的 playbackRate
不为 1.0 并且 preservesPitch
为真,则用户代理必须应用音调调整以保持音频的原始音调。否则,用户代理必须加快或减慢音频播放而不进行音调调整。
当一个 媒体元素 处于 可能正在播放 状态时,其播放的音频数据必须与 当前播放位置 同步,并且使用元素的 有效媒体音量 播放。用户代理必须播放在 事件循环 上次达到 步骤 1 时已启用的音轨数据。
当一个 媒体元素 不处于 可能正在播放 状态时,该元素的音频不得播放。
媒体元素 在未 可能正在播放 且不在 文档中 时,不得播放任何视频,但应播放任何音频组件。媒体元素不得仅仅因为所有对它的引用已被移除而停止播放;只有当媒体元素处于一种状态,无法再播放任何音频时,该元素才能被垃圾回收。
即使对一个没有明确引用的元素,仍有可能播放音频,即使该元素不再积极播放:例如,它可能已被解除暂停但仍在等待内容缓冲,或者仍在缓冲中,但有一个 suspend
事件监听器开始播放。即使是一个 媒体资源
没有音轨的媒体元素,如果它有一个更改 媒体资源
的事件监听器,也可能会再次播放音频。
每个 媒体元素 有一个 新引入提示的列表,该列表初始为空。每当一个 文本轨道提示 被添加到 提示列表 中的 文本轨道,该 提示 必须被添加到 媒体元素 的 新引入提示的列表 中。每当一个 文本轨道 被添加到 文本轨道列表 中的 媒体元素,该 文本轨道 中的所有 提示 必须被添加到 媒体元素 的 新引入提示的列表 中。当 媒体元素 的 新引入提示的列表 中有新提示被添加,而该 媒体元素 的 显示海报标志 未被设置时,用户代理必须执行 时间继续前进 步骤。
当一个 文本轨道提示 从一个在 文本轨道列表 中的 文本轨道 中被移除时,以及每当一个 文本轨道 从 文本轨道列表 中的 媒体元素 中被移除时,如果 媒体元素 的 显示海报标志 未被设置时,用户代理必须执行 时间继续前进 步骤。
当媒体元素的当前播放位置发生变化时(例如由于播放或搜索),用户代理必须运行时间向前推进步骤。为了支持依赖提示事件触发时间精度的用例,例如将字幕与视频中的镜头变化同步,用户代理应尽可能接近媒体时间轴上的位置触发提示事件,理想情况下在20毫秒内。如果在步骤运行时当前播放位置发生变化,则用户代理必须等待步骤完成,然后必须立即重新运行这些步骤。因此,这些步骤尽可能或按需运行。
如果一个迭代耗时较长,这可能会导致短时长的 提示 被跳过,因为用户代理急于 "赶上",因此这些提示不会出现在 activeCues
列表中。
“时间流逝”的步骤如下:
让 current cues 成为一个提示的列表,初始化时包含所有 提示,这些提示来自所有 或 显示 的 文本轨道 的 媒体元素(不是 禁用的),其 开始时间 小于或等于 当前播放位置,其 结束时间 大于 当前播放位置。
让 other cues 成为一个提示的列表,初始化时包含所有 提示,这些提示来自 和 显示 的 文本轨道 的 媒体元素,这些提示不在 current cues 中。
让 last time 成为在此算法最后一次运行时的 当前播放位置,如果这不是第一次运行。
如果 当前播放位置 自上次运行此算法以来,仅通过正常播放中的单调增加发生变化,则让 missed cues 成为在 other cues 中的 提示 列表,其 开始时间 大于或等于 last time,其 结束时间 小于或等于 当前播放位置。否则,让 missed cues 成为空列表。
移除 missed cues 中的所有 提示,这些提示也在 媒体元素 的 新引入提示列表 中,然后清空该元素的 新引入提示列表。
如果时间是通过 当前播放位置
在正常播放期间的单调增加达到的,并且用户代理在过去的15到250毫秒内没有在元素上触发过 timeupdate
事件,并且仍未处理此事件的事件处理程序,则用户代理必须 排队一个媒体元素任务,要求 媒体元素
在元素上触发一个名为 timeupdate
的事件。(在其他情况下,如显式跳转,相关事件会在改变 当前播放位置 的整个过程中触发。)
因此,事件不会触发得比约66Hz快,或者比4Hz慢(假设事件处理程序的运行时间不超过250毫秒)。鼓励用户代理根据系统负载和每次处理事件的平均成本来调整事件的频率,以便UI更新的频率不会超过用户代理在解码视频时可以舒适处理的程度。
如果 current cues 中的所有 提示 都已设置其 文本轨道提示激活标志,且 other cues 中没有 提示 设置其 文本轨道提示激活标志,并且 missed cues 为空,则返回。
如果时间是通过 当前播放位置 在正常播放期间的单调增加达到的,并且 other cues 中有 提示,这些提示设置了 文本轨道提示退出时暂停标志,并且这些提示要么设置了 文本轨道提示激活标志,要么也在 missed cues 中,则 立即 暂停 媒体元素。
在其他情况下,例如显式跳转,即使该 提示 设置了 文本轨道提示退出时暂停标志,播放也不会因为超出提示的结束时间而暂停。
让 events 成为一个初始为空的 任务 列表。此列表中的每个 任务 将与一个 文本轨道、一个 文本轨道提示 和一个时间相关联,这些信息用于在任务排队之前对列表进行排序。
让 affected tracks 成为一个初始为空的 文本轨道 列表。
当步骤下列指示为具有时间 time 的 文本轨道提示 target 准备一个名为 event 的事件时,用户代理必须执行以下步骤:
对于missed cues中的每个文本轨道提示,准备一个事件,名为enter
,为TextTrackCue
对象设置文本轨道提示开始时间。
对于每个other cues中已设置其文本轨道提示活动标志或在missed cues中的文本轨道提示,准备一个事件,名为exit
,为TextTrackCue
对象设置文本轨道提示结束时间和文本轨道提示开始时间中较晚的时间。
对于每个current cues中未设置其文本轨道提示活动标志的文本轨道提示,准备一个事件,名为enter
,为TextTrackCue
对象设置文本轨道提示开始时间。
按升序对 events 中的 任务 进行排序(较早时间的任务在前)。
进一步对 events 中具有相同时间的 任务 按这些 文本轨道提示 关联的 文本轨道提示顺序 进行排序。
最后,对 events 中具有相同时间和相同 文本轨道提示顺序 的 任务 进行排序,将触发
enter
事件的任务放在触发 exit
事件的任务之前。
排队一个媒体元素任务,要求 媒体元素 对 events 中的每个 任务,按列表顺序。
按 文本轨道 在 媒体元素 的 文本轨道列表 中出现的相同顺序对 affected tracks 进行排序,并移除重复项。
对于 affected tracks 中的每个 文本轨道,按列表顺序,排队一个媒体元素任务,要求 媒体元素 触发一个名为
cuechange
的事件,事件对象为 TextTrack
对象。如果 文本轨道 有一个对应的
track
元素,则同样触发一个名为 cuechange
的事件,事件对象为 track
元素。
将 current cues 中所有 提示 的 文本轨道提示激活标志 设置为激活状态,并将 other cues 中所有 提示 的 文本轨道提示激活标志 取消设置。
按照 更新文本轨道渲染的规则 对 affected tracks 中所有 文本轨道 进行处理,这些文本轨道处于 显示 状态,并提供 文本轨道 的 文本轨道语言 作为备用语言(如果该语言不为空)。例如,对于基于 WebVTT 的 文本轨道,使用 WebVTT 文本轨道显示更新规则。[WEBVTT]
对于上述算法的目的,只有当 文本轨道提示 列在 文本轨道提示列表 中时,才被认为是属于 文本轨道,而不仅仅是与 文本轨道 相关联。
如果 媒体元素 的 节点文档 不再是 完全活动 文档,则播放将 停止,直到文档再次变为活动状态。
当 媒体元素 被 从
Document
中移除 时,用户代理必须执行以下步骤:
media.seeking
如果用户代理当前正在寻找,则返回 true。
media.seekable
所有当前引擎均支持。
返回一个 TimeRanges
对象,表示用户代理能够寻找到的 媒体资源 的范围。
media.fastSeek(time)
尽可能快速地寻找到接近给定 time 的位置,以速度换取精度。(要精确寻找到一个时间,请使用 currentTime
属性。)
如果媒体资源尚未加载,则不执行任何操作。
seeking
属性初始值必须为 false。
fastSeek(time)
方法必须 寻找到由 time 给定的时间,
并设置 approximate-for-speed 标志。
当用户代理需要 寻找到 媒体资源中的特定 new playback position 时, 可选择设置 approximate-for-speed 标志,这意味着用户代理必须执行以下步骤。该算法与 事件循环 机制紧密交互;特别是,它具有 一个 同步部分(作为 事件循环 算法的一部分触发)。该部分的步骤用 ⌛ 标记。
如果媒体元素的readyState
为HAVE_NOTHING
,则返回。
如果元素的seeking
IDL属性为true,则表示此算法的另一个实例正在运行。终止该算法的另一个实例,而无需等待其运行的步骤完成。
将seeking
IDL属性设置为true。
如果搜索是响应DOM方法调用或设置IDL属性,则继续脚本。其余步骤必须并行运行。除了标有⌛的步骤外,这些步骤随时可能被另一个实例调用而中止。
如果new playback position小于最早可能的位置,则将其设为该位置。
如果(可能现在已更改的)new playback position不在seekable
属性提供的范围之一内,则将其设为seekable
属性提供的最接近new playback
position的范围中的位置。如果两个位置都满足该约束(即new playback position正好位于seekable
属性中的两个范围之间),则使用最接近当前播放位置的位置。如果seekable
属性中没有给定范围,则将seeking
IDL属性设置为false并返回。
如果设置了approximate-for-speed标志,则调整new playback position以允许快速恢复播放。如果此步骤之前的new playback position在当前播放位置之前,则调整后的new playback position也必须在当前播放位置之前。同样,如果此步骤之前的new playback position在当前播放位置之后,则调整后的new playback position也必须在当前播放位置之后。
例如,用户代理可以捕捉到附近的关键帧,以便在恢复播放之前不必花时间解码然后丢弃中间帧。
排队一个媒体元素任务,给定媒体元素去触发一个事件,名为seeking
在该元素上。
将当前播放位置设置为new playback position。
如果媒体元素在开始搜索之前是潜在播放状态,但搜索导致其readyState
属性变为低于HAVE_FUTURE_DATA
的值,则将在该元素上触发一个waiting
事件。
此步骤设置当前播放位置,因此可以立即触发其他条件,例如播放何时达到媒体资源的末尾的规则(处理循环的一部分逻辑),即使在用户代理实际上能够渲染该位置的媒体数据之前(如下一步所确定)。
currentTime
属性返回官方播放位置,而不是当前播放位置,因此在脚本执行之前独立于此算法进行更新。
等待用户代理确定new playback position的媒体数据是否可用,并且,如果可用,则等待它解码足够的数据以播放该位置。
⌛ 将seeking
IDL属性设置为false。
⌛ 运行时间向前推进步骤。
⌛ 排队一个媒体元素任务,给定媒体元素去触发一个事件,名为timeupdate
在该元素上。
⌛ 排队一个媒体元素任务,给定媒体元素去触发一个事件,名为seeked
在该元素上。
seekable
属性必须返回一个新的静态 标准化的
TimeRanges
对象,表示用户代理能够寻找到的 媒体资源
的范围(如果有的话),在评估该属性时返回。
如果用户代理可以在 媒体资源
中的任意位置进行寻找到,例如,因为这是一个简单的电影文件且用户代理和服务器支持 HTTP Range 请求,那么属性将返回一个具有一个范围的对象,该范围的开始是第一个帧的时间(最早可能的位置,通常为零),结束时间是第一个帧的时间加上
duration
属性的值(这将等于最后一个帧的时间,可能为正无穷)。
该范围可能会不断变化,例如,如果用户代理在无限流上缓存滑动窗口。这在 DVR 观看直播电视时会看到。
每次返回一个新对象是属性获取器的一个糟糕模式,只在此处被铭记,因为改变它的成本很高。这不应被复制到新的 API 中。
用户代理应采取非常宽松和乐观的寻找到视图。用户代理还应在可能的情况下缓冲最近的内容,以使寻找到过程更快。
例如,考虑一个在没有 HTTP Range 请求支持的 HTTP 服务器上提供的大型视频文件。一个浏览器 可以 实现为只缓冲当前帧和获取后续帧的数据,从不允许寻找到,除了通过重启播放来寻找到开始。但是,这将是一个不好的实现。高质量的实现将缓冲最近几分钟的内容(或更多,如果有足够的存储空间),允许用户快速跳回并重新观看令人惊讶的内容而没有任何延迟,并且如果必要的话,还会允许通过从头开始重新加载文件来进行任意寻找到,这会更慢但仍然比仅仅重启视频并全部观看一遍来获取早期未缓冲的点更方便。
媒体资源 可能是内部脚本化的或交互式的。因此,一个 媒体元素 可能以非线性的方式播放。如果发生这种情况,用户代理必须在 寻找到 算法被使用时表现得好像当前播放位置 变化 是不连续的(以便相关事件被触发)。
一个 媒体资源 可以包含多个嵌入的音频和视频轨道。例如,除了主要的视频和音频轨道外,一个 媒体资源 还可以包含外语配音、导演评论、音频描述、备用角度或手语覆盖层。
media.audioTracks
所有当前引擎均支持。
返回一个 AudioTrackList
对象,表示在 媒体资源
中可用的音频轨道。
media.videoTracks
所有当前引擎均支持。
返回一个 VideoTrackList
对象,表示在 媒体资源
中可用的视频轨道。
媒体元素 的 audioTracks
属性必须返回一个 live
AudioTrackList
对象,表示在 媒体元素 的 媒体资源 中可用的音频轨道。
媒体元素 的 videoTracks
属性必须返回一个 live
VideoTrackList
对象,表示在 媒体元素 的 媒体资源 中可用的视频轨道。
每个 媒体元素
只有一个 AudioTrackList
对象和一个
VideoTrackList
对象,即使另一个 媒体资源
被加载到元素中:这些对象会被重用。(不过,AudioTrack
和 VideoTrack
对象则不会。)
AudioTrackList
和 VideoTrackList
对象支持所有当前的引擎。
支持所有当前的引擎。
支持所有当前的引擎。
AudioTrackList
和 VideoTrackList
接口由前面章节中定义的属性使用。
支持所有当前的引擎。
支持所有当前的引擎。
[Exposed =Window ]
interface AudioTrackList : EventTarget {
readonly attribute unsigned long length ;
getter AudioTrack (unsigned long index );
AudioTrack ? getTrackById (DOMString id );
attribute EventHandler onchange ;
attribute EventHandler onaddtrack ;
attribute EventHandler onremovetrack ;
};
[Exposed =Window ]
interface AudioTrack {
readonly attribute DOMString id ;
readonly attribute DOMString kind ;
readonly attribute DOMString label ;
readonly attribute DOMString language ;
attribute boolean enabled ;
};
[Exposed =Window ]
interface VideoTrackList : EventTarget {
readonly attribute unsigned long length ;
getter VideoTrack (unsigned long index );
VideoTrack ? getTrackById (DOMString id );
readonly attribute long selectedIndex ;
attribute EventHandler onchange ;
attribute EventHandler onaddtrack ;
attribute EventHandler onremovetrack ;
};
[Exposed =Window ]
interface VideoTrack {
readonly attribute DOMString id ;
readonly attribute DOMString kind ;
readonly attribute DOMString label ;
readonly attribute DOMString language ;
attribute boolean selected ;
};
media.audioTracks.length
支持所有当前引擎。
media.videoTracks.length
支持所有当前引擎。
返回列表中的轨道数量。
audioTrack = media.audioTracks[index]
videoTrack = media.videoTracks[index]
返回指定的 AudioTrack
或 VideoTrack
对象。
audioTrack = media.audioTracks.getTrackById(id)
支持所有当前引擎。
videoTrack = media.videoTracks.getTrackById(id)
支持所有当前引擎。
返回具有给定标识符的 AudioTrack
或 VideoTrack
对象,如果没有具有该标识符的轨道,则返回 null。
audioTrack.id
支持所有当前引擎。
videoTrack.id
支持所有当前引擎。
返回给定轨道的 ID。如果格式支持 片段,并且可以与 getTrackById()
方法一起使用,则这是可使用的 ID。
audioTrack.kind
支持所有当前引擎。
videoTrack.kind
支持所有当前引擎。
返回给定轨道所属的类别。下面给出了可能的轨道类别。
audioTrack.label
支持所有当前引擎。
videoTrack.label
支持所有当前引擎。
返回给定轨道的标签(如果已知),否则返回空字符串。
audioTrack.language
支持所有当前引擎。
videoTrack.language
支持所有当前引擎。
返回给定轨道的语言(如果已知),否则返回空字符串。
audioTrack.enabled [ = value ]
支持所有当前引擎。
如果给定轨道处于活动状态,则返回 true,否则返回 false。
可以设置,以更改轨道是否已启用。如果同时启用多个音轨,则它们会混合。
media.videoTracks.selectedIndex
支持所有当前引擎。
返回当前选定轨道的索引(如果有),否则返回 −1。
videoTrack.selected [ = value ]
支持所有当前引擎。
如果给定轨道处于活动状态,则返回 true,否则返回 false。
可以设置,以更改轨道是否已选择。可以选择零个或一个视频轨道;在选择新轨道时,取消选择先前的轨道。
一个 AudioTrackList
对象表示一个动态列表,包含零个或多个音轨,其中零个或多个可以同时启用。每个音轨由一个
AudioTrack
对象表示。
一个 VideoTrackList
对象表示一个动态列表,包含零个或多个视频轨道,其中每次只能选择零个或一个。每个视频轨道由一个
VideoTrack
对象表示。
AudioTrackList
和 VideoTrackList
对象中的轨道必须保持一致的顺序。如果 媒体资源的格式定义了顺序,则必须使用该顺序;否则,顺序必须是轨道在媒体资源中声明的相对顺序。使用的顺序称为列表的自然顺序。
因此,这些对象中的每个轨道都有一个索引;第一个索引为 0,每个后续轨道的编号比前一个高一。 如果 媒体资源动态添加或删除音轨或视频轨道,则轨道的索引将动态更改。如果媒体资源完全更改,则所有先前的轨道将被删除并替换为新轨道。
AudioTrackList
length
和 VideoTrackList
length
属性的获取器必须返回其对象在获取时表示的轨道数量。
支持的属性索引 AudioTrackList
和
VideoTrackList
对象在任何时刻的支持的属性索引是从零到各自对象表示的轨道数量减一的数字(如果表示任何轨道)。如果一个
AudioTrackList
或 VideoTrackList
对象不表示任何轨道,则它没有
支持的属性索引。
对于给定索引 index 在 AudioTrackList
或 VideoTrackList
对象 list 中 确定索引属性的值,用户代理必须返回表示list
中第index个轨道的 AudioTrack
或
VideoTrack
对象。
AudioTrackList
getTrackById(id)
和
VideoTrackList
getTrackById(id)
方法必须
返回在
AudioTrackList
或 VideoTrackList
对象(分别)中的第一个 AudioTrack
或 VideoTrack
对象(分别),其标识符等于 id 参数的值(如上定义的列表的自然顺序)。当没有轨道与给定参数匹配时,方法必须返回 null。
AudioTrack
和 VideoTrack
对象表示
媒体资源的特定轨道。每个轨道可以有一个标识符、类别、标签和语言。
这些轨道的各个方面在轨道的生命周期内是永久的;即使从 媒体资源的 AudioTrackList
或 VideoTrackList
对象中移除这些轨道,这些方面也不会改变。
此外, AudioTrack
对象可以启用或禁用;这是音轨的启用状态。创建 AudioTrack
时,其启用状态
必须设置为 false(禁用)。 资源获取算法可以覆盖此设置。
类似地,每个 VideoTrack
对象的 VideoTrackList
对象
中可以选择一个,这就是视频轨道的选择状态。创建 VideoTrack
时,其选择状态必须设置为 false(未选择)。 资源获取算法可以覆盖此设置。
AudioTrack
id
和 VideoTrack
id
属性
必须返回轨道的标识符(如果有),否则返回空字符串。如果 媒体资源的格式支持媒体片段语法,则返回的特定轨道的标识符必须与使用该标识符作为该轨道在轨道维度中的名称时相同,从而启用该轨道片段。 [INBAND]
例如,在 Ogg 文件中,这将是轨道的 Name 头字段。 [OGGSKELETONHEADERS]
AudioTrack
kind
和
VideoTrack
kind
属性
必须返回轨道的类别(如果有),否则返回空字符串。
轨道的类别是下表第一列中根据第二列和第三列中的定义最适合该轨道的字符串,如由媒体资源中的元数据确定。表中某一行第三列中的单元格说明了该行第一列中给定类别适用的对象;某个类别仅在适用于音轨时才适用于音轨,仅在适用于视频轨道时才适用于视频轨道。类别必须仅返回
AudioTrack
对象,如果它们适用于音频,并且必须仅返回 VideoTrack
对象,如果它们适用于视频。
对于 Ogg 文件,轨道的 Role 头字段提供了相关元数据。对于 DASH 媒体资源, Role
元素传达了信息。对于 WebM,目前只有 FlagDefault
元素映射到一个值。从媒体容器到 HTML 的带内媒体资源轨道的来源有更多细节。 [OGGSKELETONHEADERS] [DASH] [WEBMCG] [INBAND]
类别 | 定义 | 适用于... | 示例 |
---|---|---|---|
"alternative "
|
主轨道的可能替代,例如歌曲的不同版本(音频),或不同的视角(视频)。 | 音频和视频。 | Ogg: "audio/alternate" 或 "video/alternate"; DASH: "alternate" 没有 "main" 和 "commentary" 角色,并且音频没有 "dub" 角色(忽略其他角色)。 |
"captions "
|
带有字幕的主视频轨道版本。(用于遗留内容;新内容将使用文本轨道。) | 仅视频。 | DASH: "caption" 和 "main" 角色一起(忽略其他角色)。 |
"descriptions "
|
视频轨道的音频描述。 | 仅音频。 | Ogg: "audio/audiodesc". |
"main "
|
主要音轨或视频轨道。 | 音频和视频。 | Ogg: "audio/main" 或 "video/main"; WebM: 设置了 "FlagDefault" 元素; DASH: "main" 角色没有 "caption"、"subtitle" 和 "dub" 角色(忽略其他角色)。 |
"main-desc "
|
混合了音频描述的主要音轨。 | 仅音频。 | MPEG-2 TS 中的 AC3 音频: bsmod=2 和 full_svc=1。 |
"sign "
|
音轨的手语翻译。 | 仅视频。 | Ogg: "video/sign". |
"subtitles "
|
带有字幕的主视频轨道版本。(用于遗留内容;新内容将使用文本轨道。) | 仅视频。 | DASH: "subtitle" 和 "main" 角色一起(忽略其他角色)。 |
"translation "
|
主要音轨的翻译版本。 | 仅音频。 | Ogg: "audio/dub". DASH: "dub" 和 "main" 角色一起(忽略其他角色)。 |
"commentary "
|
对主要音轨或视频轨道的评论,例如导演评论。 | 音频和视频。 | DASH: "commentary" 角色没有 "main" 角色(忽略其他角色)。 |
" "(空字符串)
|
没有明确的类别,或轨道元数据中给出的类别未被用户代理识别。 | 音频和视频。 |
AudioTrack
label
和
VideoTrack
label
属性必须返回轨道的标签(如果有),否则返回空字符串。 [INBAND]
AudioTrack
language
和 VideoTrack
language
属性必须
返回轨道的 BCP 47 语言标签(如果有),否则返回空字符串。如果用户代理无法将该语言表示为 BCP 47 语言标签(例如,因为媒体资源格式中的语言信息是没有定义解释的自由格式字符串),那么该方法必须返回空字符串,就像轨道没有语言一样。
[INBAND]
AudioTrack
enabled
属性,在获取时,必须返回 true 如果轨道当前已启用,否则返回 false。在设置时,如果新值为 true,则必须启用轨道,否则禁用轨道。(如果轨道不再在一个 AudioTrackList
对象中,则轨道的启用或
禁用除了更改 AudioTrack
对象上的属性值外没有其他效果。)
每当 AudioTrackList
中已禁用的音轨被启用,以及启用的音轨被禁用时,用户代理必须
排队媒体元素任务给定媒体元素以触发一个名为
change
的事件在 AudioTrackList
对象上。
在 媒体时间轴上没有特定位置数据的音轨,或在该位置不存在的音轨,必须被解释为在该时间点上是静音的。
VideoTrackList
selectedIndex
属性必须返回
当前选择的轨道的索引(如果有)。如果 VideoTrackList
对象当前不表示任何轨道,或者如果没有选择任何轨道,则必须返回
−1。
VideoTrack
selected
属性,在获取时,必须返回 true 如果轨道当前已选择,否则返回 false。在设置时,如果新值为 true,则必须选择轨道,否则取消选择它。如果轨道在一个 VideoTrackList
中,则该列表中的所有其他
VideoTrack
对象必须取消选择。(如果轨道不再在一个 VideoTrackList
对象中,则轨道的选择或取消选择除了更改 VideoTrack
对象上的属性值外没有其他效果。)
每当 VideoTrackList
中先前未选择的轨道被选择,以及当 VideoTrackList
中已选择的轨道未选择且没有新轨道被选中代替时,用户代理必须 排队一个媒体元素任务给定 媒体元素以 触发一个名为 change
的事件在 VideoTrackList
对象上。该 任务必须在 排队一个元素任务之前排队
触发 resize
事件的任务(如果有)。
在 媒体时间轴上没有特定位置数据的视频轨道必须在该时间点上被解释为 透明黑色, 具有与该位置之前的最后一帧相同的尺寸,或者如果位置在该轨道的所有数据之前,则具有该轨道第一帧的尺寸。当前位置根本不存在的轨道必须被视为存在但没有数据。
例如,如果一个视频有一个在播放一个小时后才引入的轨道,并且用户选择该轨道然后返回到开始位置,则用户代理将表现得像该轨道从媒体资源的开始处开始,但只是在一小时内透明。
以下是 事件处理程序(及其对应的事件处理程序事件类型),这些处理程序必须由所有实现 AudioTrackList
和 VideoTrackList
接口的对象支持,作为 事件处理程序 IDL 属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onchange
支持所有当前引擎。 Firefox🔰
33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+ Edge (旧版)不支持Internet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? 支持所有当前引擎。 Firefox31+Safari7+Chrome33+
Opera?Edge79+ Edge (旧版)18Internet Explorer不支持 Firefox Android?Safari iOS?Chrome Android?WebView Android4.4+Samsung Internet?Opera Android? 支持所有当前引擎。 Firefox🔰
33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+ Edge (旧版)不支持Internet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
change
|
onaddtrack
支持所有当前引擎。 Firefox🔰
33+Safari
7+Chrome🔰
37+
Opera?Edge🔰 79+ Edge (旧版)不支持Internet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? 支持所有当前引擎。 Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer11 Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ 支持所有当前引擎。 Firefox🔰
33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+ Edge (旧版)不支持Internet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
addtrack
|
onremovetrack
AudioTrackList/removetrack_event 支持所有当前引擎。 Firefox🔰
33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+ Edge (旧版)不支持Internet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? TextTrackList/removetrack_event 支持所有当前引擎。 Firefox31+Safari7+Chrome33+
Opera20+Edge79+ Edge (旧版)18Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android4.4+Samsung Internet?Opera Android20+ VideoTrackList/removetrack_event 支持所有当前引擎。 Firefox🔰
33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+ Edge (旧版)不支持Internet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
removetrack
|
audioTracks
和 videoTracks
属性允许脚本选择应该播放的轨道,但也可以通过在片段中指定特定轨道,以声明方式选择特定轨道
,即通过指定URL的媒体资源。片段的格式取决于MIME类型。[RFC2046] [URL]
在这个例子中,一个使用支持媒体片段语法 的格式的视频被嵌入,以便启用标记为“Alternative”的替代角度,而不是默认的视频轨道。
< video src = "myvideo#track=Alternative" ></ video >
媒体元素可以有一组相关的文本轨迹,称为媒体元素的文本轨迹列表。文本轨迹按以下顺序排序:
使用addTextTrack()
方法添加的任何文本轨迹,按添加顺序排列,最早的在前。
任何特定于媒体资源的文本轨迹(文本轨迹对应于媒体资源中的数据),按媒体资源的格式规范中定义的顺序排列。
文本轨迹包括:
这决定了用户代理如何处理轨迹。类型由一个字符串表示。可能的字符串包括:
subtitles
captions
descriptions
chapters
metadata
这是一个人类可读的字符串,用于识别轨迹。
在对应于文本轨迹的track
元素的情况下,轨迹的标签可以动态更改。
当文本轨迹标签为空字符串时,用户代理应自动从文本轨迹的其他属性(例如文本轨迹的类型和语言)生成一个适当的标签,以在其用户界面中使用。此自动生成的标签不会在API中公开。
这是从媒体资源中提取的一个字符串,专门用于带内元数据轨迹,以便将这些轨迹分派给文档中的不同脚本。
例如,传统电视台的网络直播,配有网页特定的互动功能,可以包含带有广告定位、游戏节目期间的问答游戏数据、体育比赛中的玩家状态、烹饪节目的食谱信息等元数据的文本轨迹。随着每个节目开始和结束,新的轨迹可能会被添加或从流中移除,当每个轨迹被添加时,用户代理可以使用此属性的值将其绑定到专用的脚本模块。
除了带内元数据文本轨迹之外,带内元数据轨迹调度类型为空字符串。如何为不同媒体格式填充此值在暴露特定媒体资源文本轨迹的步骤中进行了描述。
这是一个表示文本轨迹提示语言的字符串(BCP 47语言标签)。[BCP47]
以下之一:
表示文本轨迹的提示尚未获取。
表示文本轨迹正在加载,目前尚未遇到致命错误。解析器可能仍会向轨迹添加更多提示。
表示文本轨迹已加载且没有致命错误。
表示文本轨迹已启用,但用户代理尝试获取它时失败(例如,URL无法解析,网络错误,未知的文本轨迹格式)。一些或所有提示可能丢失,且不会被获取。
文本轨迹的准备状态在轨迹获取过程中动态变化。
以下之一:
表示文本轨迹未激活。除了在DOM中暴露轨迹之外,用户代理将忽略文本轨迹。没有提示激活,没有事件触发,用户代理不会尝试获取轨迹的提示。
表示文本轨迹已激活,但用户代理未主动显示提示。如果尚未尝试获取轨迹的提示,用户代理将立即尝试。用户代理维护一个活跃提示的列表,并相应触发事件。
表示文本轨道是活跃的。如果尚未尝试获取轨道的提示,用户代理将立即进行此尝试。用户代理正在维护一个列表,记录哪些提示是活跃的,并相应地触发事件。此外,对于类型为字幕
或标题
的文本轨道,提示适当地叠加在视频上;对于类型为描述
的文本轨道,用户代理以非视觉方式向用户提供提示;对于类型为章节
的文本轨道,用户代理提供一种机制,使用户可以通过选择提示在媒体资源中的任何一点进行导航。
一个文本轨迹提示的列表,以及更新文本轨迹渲染的规则。例如,对于WebVTT,更新WebVTT文本轨迹显示的规则。[WEBVTT]
每个媒体元素都有一个待处理文本轨迹列表,该列表必须最初为空,还有一个被解析器阻塞标志,该标志必须最初为假,以及一个是否执行了自动轨迹选择标志,该标志也必须最初为假。
当用户代理需要填充待处理文本轨迹列表时,用户代理必须将元素的待处理文本轨迹列表中添加每个文本轨迹,这些文本轨迹在元素的文本轨迹列表中,其文本轨迹模式不是禁用的,并且其文本轨迹准备状态是加载中。
每当一个track
元素的父节点发生变化时,用户代理必须从它所在的任何待处理文本轨迹列表中移除相应的文本轨迹。
每当一个文本轨迹的文本轨迹准备状态变为已加载或加载失败时,用户代理必须从它所在的任何待处理文本轨迹列表中移除它。
当一个媒体元素由HTML 解析器或XML 解析器创建时,用户代理必须将该元素的被解析器阻塞标志设置为真。当一个媒体元素从打开元素栈中弹出时,用户代理必须尊重用户对自动文本轨迹选择的偏好,填充待处理文本轨迹列表,并将元素的被解析器阻塞标志设置为假。
当一个媒体元素的待处理文本轨迹列表为空且元素的被解析器阻塞标志为假时,该媒体元素的文本轨迹被认为是准备好的。
每个媒体元素都有一个待处理文本轨迹更改通知标志,该标志最初未设置。
每当一个文本轨迹,它在一个媒体元素的文本轨迹列表中,其文本轨迹模式发生变化时,用户代理必须对该媒体元素执行以下步骤:
如果媒体元素的待处理文本轨迹更改通知标志被设置,返回。
队列一个媒体元素任务,使该媒体元素执行以下步骤:
取消设置媒体元素的待处理文本轨迹更改通知标志。
触发一个事件,事件名称为change
,该事件发给媒体元素的textTracks
属性的TextTrackList
对象。
一个文本轨迹提示是文本轨迹中的时间敏感数据单元,例如对于字幕和标题,表示在特定时间出现并在另一个时间消失的文本。
每个文本轨迹提示包括:
一个任意字符串。
以秒和秒的分数表示的时间,描述提示适用的媒体数据范围的开始。
一个布尔值,指示在达到提示适用的范围结束时是否暂停播放媒体资源。
根据格式的需要,包含提示的实际数据的附加字段。例如,WebVTT 有一个文本轨迹提示书写方向等。[WEBVTT]
一个无限制文本轨迹提示是一个文本轨迹提示,其文本轨迹提示结束时间设置为正无穷大。一个活跃的无限制文本轨迹提示无法通过正常播放过程中当前播放位置的单调增加变为不活动(例如,在一个没有宣布结束时间的实时事件中的章节元数据提示)。
文本轨迹提示开始时间和文本轨迹提示结束时间可以为负值。(虽然当前播放位置永远不能为负值,因此完全在时间零之前的提示不能处于活动状态。)
每个文本轨迹提示都有一个对应的TextTrackCue
对象(更具体地说,是一个继承自TextTrackCue
的对象——例如,WebVTT提示使用VTTCue
接口)。一个文本轨迹提示的内存表示可以通过此TextTrackCue
API
动态更改。[WEBVTT]
一个文本轨迹提示与更新文本轨迹渲染的规则相关联,这些规则由特定类型的文本轨迹提示规范定义。这些规则在表示提示的对象通过TextTrack
对象的addCue()
方法添加到该对象时特别使用。
此外,每个文本轨迹提示有两项动态信息:
该标志必须最初未设置。此标志用于确保在提示变为活跃或不活跃时适当地触发事件,并确保正确的提示被渲染。
每当文本轨道提示从其文本轨道的文本轨道提示列表中移除时;每当文本轨道本身从其媒体元素的文本轨道列表中移除时,或其文本轨道模式更改为禁用时;以及每当媒体元素的readyState
更改回HAVE_NOTHING
时,用户代理必须同步取消设置此标志。当对于在相关事件发生前正在显示的文本轨道中的一个或多个提示以这种方式取消设置标志后,用户代理必须在为所有受影响的提示取消设置标志后,应用这些文本轨道的文本轨道渲染更新规则。例如,对于基于WebVTT的文本轨道,WebVTT文本轨道显示更新规则。[WEBVTT]
这作为渲染模型的一部分,用于保持提示的一致位置。它必须最初为空。每当文本轨迹提示活动标志被取消设置时,用户代理必须清空文本轨迹提示显示状态。
文本轨迹提示的排序在媒体元素的文本轨迹中相对彼此进行,这一排序方式如下确定:首先按照文本轨迹对提示进行分组,分组的顺序与其在媒体元素的文本轨迹列表中出现的顺序相同;然后,在每组内,提示必须按照其开始时间进行排序,最早的时间优先;接着,任何具有相同开始时间的提示必须按照其结束时间进行排序,最晚的时间优先;最后,任何具有相同结束时间的提示必须按照其最后添加到各自的文本轨迹提示列表的顺序进行排序,最旧的优先(例如,对于来自WebVTT文件的提示,这最初将是提示在文件中列出的顺序)。[WEBVTT]
媒体资源特定文本轨迹是一个文本轨迹,对应于在媒体资源中找到的数据。
处理和渲染此类数据的规则由相关规范定义,例如,如果媒体资源是视频,则由视频格式规范定义。一些遗留格式的详细信息可以在从媒体容器中获取嵌入式媒体资源轨迹到HTML中找到。[INBAND]
当媒体资源包含用户代理识别并支持作为文本轨迹的数据时,用户代理将执行暴露媒体资源特定文本轨迹的步骤,如下所示。
将相关数据与新的文本轨迹及其对应的新TextTrack
对象关联。该文本轨迹是媒体资源特定文本轨迹。
将文本轨迹提示列表与适用于该格式的文本轨迹渲染更新规则关联。
如果新的文本轨迹的类型是章节
或元数据
,则根据媒体资源的类型设置文本轨迹嵌入式元数据轨迹分派类型,如下:
CodecID
元素的值。[WEBMCG]stsd
盒子、位于第一个stbl
盒子、位于第一个minf
盒子、位于第一个mdia
盒子中的文本轨迹的trak
盒子为stsd盒子(如果存在)。
如果文件没有stsd盒子,或stsd盒子既没有mett
盒子也没有metx
盒子,则文本轨迹嵌入式元数据轨迹
分派类型必须设置为空字符串。
否则,如果stsd盒子有mett
盒子,则文本轨迹嵌入式元数据轨迹分派类型必须设置为字符串"mett
"、一个U+0020
SPACE字符和第一个mett
盒子的第一个mime_format
字段的值,如果该字段在该盒子中缺失,则为空字符串。
否则,如果stsd盒子没有mett
盒子但有metx
盒子,则文本轨迹嵌入式元数据轨迹分派类型必须设置为字符串"metx
"、一个U+0020
SPACE字符和第一个metx
盒子的第一个namespace
字段的值,如果该字段在该盒子中缺失,则为空字符串。将新的文本轨迹的模式设置为与用户的偏好和相关规范要求的数据一致的模式。
例如,如果没有其他激活的字幕,并且这是一个强制字幕轨迹(提供音频轨迹的主要语言的字幕,但仅限于实际使用另一种语言的音频),则可以在此处激活这些字幕。
触发事件,事件名称为addtrack
,在媒体元素的textTracks
属性的TextTrackList
对象上,使用TrackEvent
,其中track
属性初始化为文本轨迹的TextTrack
对象。
当创建一个track
元素时,它必须与一个新的文本轨迹(其值设置如下所定义)及其相应的新TextTrack
对象关联。
文本轨迹类型由元素的kind
属性的状态确定,依据下表;对于第一列中的状态,类型是第二列中给定的字符串:
状态 | 字符串 |
---|---|
Subtitles | subtitles
|
Captions | captions
|
Descriptions | descriptions
|
Chapters metadata | chapters
|
Metadata | metadata
|
文本轨迹语言是元素的轨迹语言(如果有的话),否则为空字符串。
随着kind
、label
和srclang
属性的设置、更改或删除,文本轨迹必须相应地更新,如上定义。
对轨迹URL的更改在下面的算法中处理。
文本轨迹提示列表最初为空。解析引用文件时会动态修改它。与列表关联的是适用于该格式的文本轨迹渲染更新规则;对于WebVTT,这是更新WebVTT文本轨迹显示的规则。[WEBVTT]
当track
元素的父元素发生变化并且新父元素是媒体元素时,用户代理必须将track
元素的相应文本轨迹添加到媒体元素的文本轨迹列表中,然后将媒体元素任务排入队列,给定媒体元素,触发一个事件,事件名为addtrack
,在媒体元素的textTracks
属性的TextTrackList
对象上,使用TrackEvent
,其中track
属性初始化为文本轨迹的TextTrack
对象。
当track
元素的父元素发生变化并且旧父元素是媒体元素时,用户代理必须将track
元素的相应文本轨迹从媒体元素的文本轨迹列表中移除,然后将媒体元素任务排入队列,给定媒体元素,触发一个事件,事件名为removetrack
,在媒体元素的textTracks
属性的TextTrackList
对象上,使用TrackEvent
,其中track
属性初始化为文本轨迹的TextTrack
对象。
当一个文本轨迹对应一个track
元素被添加到媒体元素的文本轨迹列表时,用户代理必须将媒体元素任务排入队列,给定媒体元素,按以下步骤运行媒体元素:
当用户代理需要为媒体元素尊重用户对自动文本轨迹选择的偏好时,用户代理必须运行以下步骤:
如果在媒体元素的文本轨迹列表中有任何文本轨迹,其文本轨迹类型是chapters
或metadata
,并且其对应的track
元素设置了default
属性,其文本轨迹模式设置为禁用,则将所有此类轨迹的文本轨迹模式设置为 。
将元素的已执行自动轨迹选择标志设置为真。
当上述步骤要求为一个或多个文本轨迹类型执行自动文本轨迹选择时,意味着运行以下步骤:
令candidates为媒体元素的文本轨迹列表中,文本轨迹的类型是传递给算法的类型之一(如果有),按文本轨迹列表中给定的顺序。
如果candidates为空,则返回。
如果用户根据其文本轨迹类型、文本轨迹语言和文本轨迹标签表达了希望启用candidates中的轨迹的意愿,则将其文本轨迹模式设置为显示。
例如,用户可以设置浏览器偏好,如“我希望在任何可能的情况下启用法语字幕”,或者“如果有标题中包含‘评论’的字幕轨迹,启用它”,或者“如果有音频描述轨迹可用,启用一个,最好是瑞士德语,但如果没有,则启用标准瑞士德语或标准德语”。
否则,如果candidates中有任何文本轨迹,其对应track
元素设置了default
属性,并且其文本轨迹模式设置为禁用,则将第一个这样的轨迹的文本轨迹模式设置为显示。
当一个文本轨迹对应一个track
元素经历以下任何情况时,用户代理必须启动track
处理模型,用于该文本轨迹及其track
元素:
当用户代理启动track
处理模型时,为文本轨迹及其track
元素,它必须运行以下算法。此算法与事件循环机制密切互动;特别是,它有一个同步部分(在事件循环算法的一部分触发)。该部分的步骤标有⌛。
在允许导致这些步骤运行的情况下,并行运行剩余步骤。
⌛如果track
元素的父元素是媒体元素,则令corsAttributeState为父媒体元素的crossorigin
内容属性的状态。否则,令corsAttributeState为无CORS。
如果URL不为空字符串,则:
令request为创建一个潜在的CORS请求的结果,给定URL、“track
”和corsAttributeState,并设置同源回退标志。
将request的启动器类型设置为“track
”。
获取request。
通过获取算法在网络任务源上排队处理数据时,任务必须确定资源的类型。如果资源的类型不是受支持的文本轨迹格式,加载将失败,如下所述。否则,资源的数据必须传递给适当的解析器(例如,WebVTT解析器),并在接收时传递给该解析器的输出使用的文本轨迹提示列表。[WEBVTT]
适当的解析器将在这些网络任务源任务期间逐步更新文本轨迹提示列表,因为每个任务会处理从网络接收的数据。
本规范目前没有说明是否或如何检查文本轨迹的MIME类型,或者是否或如何使用实际文件数据进行文件类型嗅探。实施者在这个问题上的意图有所不同,因此不清楚正确的解决方案是什么。在这里没有任何要求的情况下,HTTP规范严格要求遵循Content-Type头的规定(“Content-Type指定了底层数据的媒体类型。”...“只有在Content-Type字段未给出媒体类型的情况下,接收方可以尝试通过检查其内容 和/或标识资源的URI的名称扩展来猜测媒体类型。”)。
如果由于任何原因(网络错误、服务器返回错误代码、CORS失败等)导致获取失败,或者URL为空字符串,则在媒体元素上排队一个元素任务,首先将文本轨迹准备状态更改为加载失败,然后触发一个事件,事件名为error
,在track
元素上。
如果获取没有失败,但资源的类型不是受支持的文本轨迹格式,或者文件未成功处理(例如,该格式是XML格式,文件包含XML要求检测和报告给应用程序的良好格式错误),则在检测到上述问题的网络任务源上排队的任务,必须将文本轨迹准备状态更改为加载失败,并触发一个事件,事件名为error
,在track
元素上。
如果获取没有失败,并且文件已成功处理,则在解析数据后,通过网络任务源排队的最后一个任务,必须将文本轨迹准备状态更改为已加载,并触发一个事件,事件名为load
,在track
元素上。
如果在获取进行时:
...那么用户代理必须中止获取,丢弃该算法生成的任何待处理任务(特别是不在URL更改后的文本轨迹提示列表中添加任何提示),然后在track
元素上排队一个元素任务,首先将文本轨迹准备状态更改为加载失败,然后触发一个事件,事件名为error
,在track
元素上。
跳到标记为顶部的步骤。
每当track
元素的src
属性被设置、更改或删除时,用户代理必须立即清空该元素的文本轨迹的文本轨迹提示列表。(这也会导致上面的算法停止从以前给定的URL获取的资源中添加提示,如果有的话。)
特定格式的文本轨迹提示如何解释,以便由HTML用户代理进行处理,由该格式定义。在缺乏此类规范的情况下,本节提供了一些限制,以便实现可以尝试一致地暴露这些格式。
为了支持文本轨迹模型, 每个定时数据单元被转换为一个 文本轨迹提示。 当 格式的特性与文本轨迹提示的 方面在本规范中没有定义时,实现必须 确保映射与上述文本轨迹提示的 方面的定义一致,并符合以下限制:
如果格式没有明显的类似物,应设置为空字符串。
应设置为false。
在所有当前引擎中都支持。
[Exposed =Window ]
interface TextTrackList : EventTarget {
readonly attribute unsigned long length ;
getter TextTrack (unsigned long index );
TextTrack ? getTrackById (DOMString id );
attribute EventHandler onchange ;
attribute EventHandler onaddtrack ;
attribute EventHandler onremovetrack ;
};
media.textTracks.length
在所有当前引擎中都支持。
media.textTracks[ n ]
textTrack = media.textTracks.getTrackById(id)
在所有当前引擎中都支持。
返回具有给定标识符的 TextTrack
对象,如果没有该标识符的轨道,则返回 null。
TextTrackList
对象表示一个动态更新的 文本轨道 列表,按给定的顺序排列。
textTracks
属性的 媒体元素 必须
返回一个 TextTrackList
对象,表示
TextTrack
对象
作为 文本轨道 在
媒体元素 的 文本轨道列表 中,顺序与
文本轨道列表 中的顺序相同。
在所有当前引擎中都支持。
length
属性的 TextTrackList
对象必须返回列表中 文本轨道 的数量,该列表由 TextTrackList
对象表示。
一个 TextTrackList
对象在任何时刻的 支持的属性索引 是从零到
文本轨道 数量减一(如果有的话)的数字。如果列表中没有
文本轨道,则没有
支持的属性索引。
要确定一个索引属性的值
在给定索引 index 的情况下,用户代理必须返回在
TextTrackList
对象表示的列表中第 index 个 文本轨道。
getTrackById(id)
方法必须
返回 TextTrack
对象中第一个其 id
IDL 属性返回的值等于 id 参数值的轨道。当没有轨道与给定的参数匹配时,该方法必须返回 null。
在所有当前引擎中支持。
enum TextTrackMode { " disabled " , " hidden " , " showing " };
enum TextTrackKind { " subtitles " , " captions " , " descriptions " , " chapters " , " metadata " };
[Exposed =Window ]
interface TextTrack : EventTarget {
readonly attribute TextTrackKind kind ;
readonly attribute DOMString label ;
readonly attribute DOMString language ;
readonly attribute DOMString id ;
readonly attribute DOMString inBandMetadataTrackDispatchType ;
attribute TextTrackMode mode ;
readonly attribute TextTrackCueList ? cues ;
readonly attribute TextTrackCueList ? activeCues ;
undefined addCue (TextTrackCue cue );
undefined removeCue (TextTrackCue cue );
attribute EventHandler oncuechange ;
};
textTrack = media.addTextTrack(kind [, label [, language ] ])
textTrack.kind
在所有当前引擎中都支持。
返回 文本轨道类型 字符串。
textTrack.label
在所有当前引擎中都支持。
返回 文本轨道标签,如果存在,否则返回空字符串(表示可能需要从对象的其他属性生成自定义标签,如果对象暴露给用户)。
textTrack.language
在所有当前引擎中都支持。
返回 文本轨道语言 字符串。
textTrack.id
在所有当前引擎中都支持。
返回给定轨道的 ID。
对于带内轨道,这是可以与 片段 一起使用的 ID(如果格式支持 媒体片段语法),并且可以与 getTrackById()
方法一起使用。
textTrack.inBandMetadataTrackDispatchType
TextTrack/inBandMetadataTrackDispatchType
返回 文本轨道带内元数据调度类型 字符串。
textTrack.mode [ = value ]
在所有当前引擎中都支持。
返回 文本轨道模式,表示为以下列表中的一个字符串:
可以设置来更改模式。
textTrack.cues
在所有当前引擎中都支持。
返回 文本轨道提示列表,作为 TextTrackCueList
对象。
textTrack.activeCues
在所有当前引擎中都支持。
返回一个包含当前活动的 文本轨道提示 的 文本轨道提示列表 的 TextTrackCueList
对象。
textTrack.addCue(cue)
在所有当前引擎中都支持。
将给定提示添加到 textTrack 的 文本轨道提示列表 中。
textTrack.removeCue(cue)
在所有当前引擎中都支持。
从 textTrack 的 文本轨道提示列表 中删除给定提示。
当 媒体元素 的 addTextTrack(kind, label,
language)
方法被调用时,必须运行以下步骤:
创建一个新的 TextTrack
对象。
创建一个与新对象对应的新 文本轨道,并将其 文本轨道类型 设置为 kind,其 文本轨道标签 设置为 label,其 文本轨道语言 设置为 language,其 文本轨道就绪状态 设置为 文本轨道已加载 状态,其 文本轨道模式 设置为 模式,其 文本轨道提示列表 设置为空列表。
最初,文本轨道提示列表 与任何 更新文本轨道渲染的规则 无关。当向其中添加 文本轨道提示 时, 文本轨道提示列表 永久设置其规则。
排队一个媒体元素任务,给定 媒体元素 以 触发一个事件,该事件名为 addtrack
,并在
媒体元素 的 textTracks
属性的 TextTrackList
对象上,
使用 TrackEvent
,
其
track
属性初始化为新 文本轨道 的 TextTrack
对象。
返回新的 TextTrack
对象。
kind
属性必须返回 文本轨道类型,该 文本轨道
由 TextTrack
对象表示。
label
属性必须返回 文本轨道标签,该 文本轨道
由 TextTrack
对象表示。
language
属性必须返回 文本轨道语言,该
文本轨道
由 TextTrack
对象表示。
id
属性返回轨道的标识符(如果有的话),否则返回空字符串。对于与 track
元素对应的轨道,轨道的标识符是元素的 id
属性的值(如果有的话)。对于带内轨道,轨道的标识符由 媒体资源 指定。如果 媒体资源 是支持 媒体片段语法
的格式,返回的特定轨道的标识符必须与作为此类 片段 轨道维度的轨道名称时会启用该轨道的标识符相同。
inBandMetadataTrackDispatchType
属性必须返回 文本轨道带内元数据调度类型,该
文本轨道 由 TextTrack
对象表示。
mode
属性在获取时,必须返回与 文本轨道模式
相对应的字符串,该 文本轨道
由 TextTrack
对象表示,如下列表所定义:
disabled
"hidden
"showing
"在设置时,如果新值不等于属性当前返回的值,则必须按如下步骤处理新值:
disabled
"
showing
"
如果 文本轨道模式 是 文本轨道,由
TextTrack
对象表示,不是 文本轨道禁用 模式,则
cues
属性必须返回一个 实时的 TextTrackCueList
对象,该对象表示
文本轨道提示列表
的子集,列表中的 文本轨道 由
TextTrack
对象表示,其 结束时间
发生在脚本开始时的 最早可能位置 或之后,按 文本轨道提示顺序
排列。否则,必须返回 null。对于每个 TextTrack
对象,当返回一个对象时,每次都必须返回相同的 TextTrackCueList
对象。
脚本开始时的最早可能位置 是上次 事件循环 达到步骤 1 时的 最早可能位置。
如果 文本轨道模式 是 文本轨道,由
TextTrack
对象表示,不是 文本轨道禁用 模式,则
activeCues
属性必须返回一个 实时的 TextTrackCueList
对象,该对象表示
文本轨道提示列表
的子集,列表中的 文本轨道 由
TextTrack
对象表示,其 脚本开始时的活动标志已设置,按 文本轨道提示顺序
排列。否则,必须返回 null。对于每个 TextTrack
对象,当返回一个对象时,每次都必须返回相同的 TextTrackCueList
对象。
如果 文本轨道提示 的 脚本开始时活动标志已设置,则表示其 文本轨道提示活动标志 在上次 事件循环 达到 步骤 1 时已设置。
addCue(cue)
方法在 TextTrack
对象中被调用时,必须运行以下步骤:
如果 文本轨道提示列表 还没有任何关联的 更新文本轨道渲染的规则,则将 文本轨道提示列表 与适用于 cue 的 更新文本轨道渲染的规则 相关联。
如果 文本轨道提示列表 关联的 更新文本轨道渲染的规则 与适用于 cue 的 更新文本轨道渲染的规则 不相同,则抛出 "InvalidStateError
" DOMException
。
removeCue(cue)
方法在
TextTrack
对象中被调用时,必须运行以下步骤:
如果给定的 cue 不在 TextTrack
对象的 文本轨道 的 文本轨道提示列表 中,则抛出 "NotFoundError
" DOMException
。
在这个例子中,使用一个 audio
元素来播放包含多个音效的音频文件中的特定音效。使用提示暂停音频,以便音频在剪辑结束时正好结束,即使浏览器正在运行一些脚本。如果页面依赖于脚本来暂停音频,那么如果浏览器无法在指定的时间运行脚本,则可能会听到下一个剪辑的开始部分。
var sfx = new Audio( 'sfx.wav' );
var sounds = sfx. addTextTrack( 'metadata' );
// add sounds we care about
function addFX( start, end, name) {
var cue = new VTTCue( start, end, '' );
cue. id = name;
cue. pauseOnExit = true ;
sounds. addCue( cue);
}
addFX( 12.783 , 13.612 , 'dog bark' );
addFX( 13.612 , 15.091 , 'kitten mew' );
function playSound( id) {
sfx. currentTime = sounds. getCueById( id). startTime;
sfx. play();
}
// play a bark as soon as we can
sfx. oncanplaythrough = function () {
playSound( 'dog bark' );
}
// meow when the user tries to leave,
// and have the browser ask them to stay
window. onbeforeunload = function ( e) {
playSound( 'kitten mew' );
e. preventDefault();
}
Support in all current engines.
[Exposed =Window ]
interface TextTrackCueList {
readonly attribute unsigned long length ;
getter TextTrackCue (unsigned long index );
TextTrackCue ? getCueById (DOMString id );
};
cuelist.length
返回列表中 提示 的数量。
cuelist[index]
cuelist.getCueById(id)
如果没有提示具有给定的标识符或参数为空字符串,则返回null。
A TextTrackCueList
对象表示按给定顺序动态更新的 文本轨提示 列表。
所有当前引擎都支持。
The length
属性必须返回由 TextTrackCueList
对象表示的列表中的 提示 数量。
The supported property indices of a TextTrackCueList
object at any
instant are the numbers from zero to the number of 提示 in the
list represented by the TextTrackCueList
object minus one, if any. If there are no
提示 in the list,
there are no supported property
indices.
To determine the value of an indexed property
for
a
given index index, the user agent must return the indexth 文本轨提示 in the list
represented by the TextTrackCueList
object.
所有当前引擎都支持。
The getCueById(id)
方法,当
传入的参数不是空字符串时,必须返回列表中第一个标识符为 id 的 文本轨提示,如果有的话,否则返回 null。如果参数为空字符串,则该方法必须返回 null。
所有当前引擎都支持。
[Exposed =Window ]
interface TextTrackCue : EventTarget {
readonly attribute TextTrack ? track ;
attribute DOMString id ;
attribute double startTime ;
attribute unrestricted double endTime ;
attribute boolean pauseOnExit ;
attribute EventHandler onenter ;
attribute EventHandler onexit ;
};
cue.track
cue.id [ = value ]
返回文本轨道提示标识符。
可设置。
cue.startTime [ = value ]
返回文本轨道提示开始时间,单位为秒。
可设置。
cue.endTime [ = value ]
返回文本轨道提示结束时间,单位为秒。
对于无界文本轨道提示返回正无穷大。
可设置。
cue.pauseOnExit [ = value ]
如果文本轨道提示退出时暂停标志被设置,则返回true,否则返回false。
可设置。
所有当前引擎都支持。
获取时,track
属性必须返回TextTrack
对象,该对象表示TextTrackCue
对象表示的文本轨道提示在其提示列表中找到的文本轨道。如果没有,则返回null。
所有当前引擎都支持。
获取时,id
属性必须返回TextTrackCue
对象表示的文本轨道提示的文本轨道提示标识符。设置时,必须将文本轨道提示标识符设置为新值。
所有当前引擎都支持。
获取时,startTime
属性必须返回TextTrackCue
对象表示的文本轨道提示的文本轨道提示开始时间,单位为秒。设置时,必须将文本轨道提示开始时间设置为新值,解释为秒;然后,如果TextTrackCue
对象的文本轨道提示在其文本轨道的提示列表中,并且该文本轨道在媒体元素的文本轨道列表中,并且媒体元素的显示海报标志未设置,则为该媒体元素运行时间推进步骤。
所有当前引擎都支持。
获取时,endTime
属性必须返回TextTrackCue
对象表示的文本轨道提示的文本轨道提示结束时间,单位为秒或正无穷大。设置时,如果新值是负无穷大或NaN(非数值),则抛出TypeError异常。否则,必须将文本轨道提示结束时间设置为新值。然后,如果TextTrackCue
对象的文本轨道提示在其文本轨道的提示列表中,并且该文本轨道在媒体元素的文本轨道列表中,并且媒体元素的显示海报标志未设置,则为该媒体元素运行时间推进步骤。
所有当前引擎都支持。
获取时,pauseOnExit
属性必须返回true,如果TextTrackCue
对象表示的文本轨道提示的文本轨道提示退出时暂停标志已设置;否则返回false。设置时,如果新值为true,则必须设置文本轨道提示退出时暂停标志;否则必须取消设置。
以下是必须由所有实现TextTrackList
接口的对象支持的事件处理程序及其相应的事件处理程序事件类型,作为事件处理程序IDL属性支持:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onchange |
change
|
onaddtrack |
addtrack
|
onremovetrack |
removetrack
|
以下是必须由所有实现TextTrack
接口的对象支持的事件处理程序及其相应的事件处理程序事件类型,作为事件处理程序IDL属性支持:
事件处理程序 | 事件处理程序事件类型 |
---|---|
oncuechange
所有当前引擎都支持。 Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
cuechange
|
以下是必须由所有实现TextTrackCue
接口的对象支持的事件处理程序及其相应的事件处理程序事件类型,作为事件处理程序IDL属性支持:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onenter
所有当前引擎都支持。 Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
enter
|
onexit
所有当前引擎都支持。 Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
exit
|
本节为非规范性内容。
文本轨道可以用于存储与媒体数据相关的数据,用于交互或增强视图。
例如,显示体育直播的页面可以包含当前比分的信息。假设一个机器人比赛正在直播,图像可以覆盖分数,如下所示:
为了使得比分显示在用户任意快进视频时都能正确渲染,元数据文本轨道提示需要根据比分的适当长度设置。例如,在上面的框架中,可能会有一个持续整个比赛时间的提示,给出比赛编号,一个提示持续到蓝方联盟的分数变化,一个提示持续到红方联盟的分数变化。如果视频只是现场直播流,右下角的时间可能会根据当前视频时间自动派生,而不是基于提示。然而,如果视频只是精彩片段,那么这些时间也可能会在提示中给出。
以下显示了在WebVTT文件中可能会有的片段:
WEBVTT ... 05:10:00.000 --> 05:12:15.000 matchtype:qual matchnumber:37 ... 05:11:02.251 --> 05:11:17.198 red:78 05:11:03.672 --> 05:11:54.198 blue:66 05:11:17.198 --> 05:11:25.912 red:80 05:11:25.912 --> 05:11:26.522 red:83 05:11:26.522 --> 05:11:26.982 red:86 05:11:26.982 --> 05:11:27.499 red:89 ...
关键在于注意信息是在适用事件的时间长度内给出的提示中。如果比分是以零长度(或非常短的,几乎零长度)提示的方式给出的,例如在05:11:17.198说“red+2”,在05:11:25.912说“red+3”,等,则会出现问题:首先,寻求实现变得更加困难,因为脚本必须遍历整个提示列表以确保没有错过通知;此外,如果提示很短,脚本可能永远不会看到它们处于活动状态,除非它专门监听它们。
在这种方式使用提示时,鼓励作者使用cuechange
事件来更新当前注释。(特别是,使用timeupdate
事件会较不适当,因为它会在提示未更改时仍需工作,更重要的是,会在元数据提示变为活动状态和显示更新之间引入更高的延迟,因为timeupdate
事件是有速率限制的。)
需要使用URL来识别AudioTrack
或VideoTrack
的kind
或kind
IDL属性的其他规范或格式,或者识别文本轨道类型,必须使用about:html-kind
URL。
controls
属性是一个布尔属性。
如果存在,则表示作者没有提供脚本控制器,希望用户代理提供自己的一套控制。
如果存在该属性,或者该脚本已禁用的媒体元素,则用户代理应当向用户展示一个用户界面。这个用户界面应当包括开始播放、暂停播放、跳转到内容中任意位置(如果内容支持任意跳转)、更改音量、更改隐藏字幕或嵌入手语轨道的显示、选择不同音轨或打开音频描述、以及以更适合用户的方式显示媒体内容(例如全屏视频或在独立的可调整大小的窗口中)。其他控制也可以提供。
即使没有该属性,用户代理也可以提供控制来影响媒体资源的播放(例如播放、暂停、跳转、轨道选择和音量控制),但这些功能不应干扰页面的正常渲染。例如,这些功能可以在媒体元素的上下文菜单、平台媒体键或遥控器中提供。用户代理可以通过如上所述向用户展示一个用户界面来实现这一点(就像存在controls
属性一样)。
如果用户代理通过在媒体元素上显示控件来向用户展示用户界面,则用户代理应当在用户与此界面交互时抑制任何用户交互事件。(例如,如果用户点击视频的播放控件,不会同时向页面上的元素触发mousedown
事件等)。
如果可能(特别是用于开始、停止、暂停和继续播放、跳转、更改播放速率、快进或倒退、列出、启用和禁用文本轨道、以及静音或更改音量),用户代理暴露的用户界面功能必须根据上述DOM API实现,以确保例如所有相同的事件触发。
诸如快进或倒退的功能必须仅通过更改playbackRate
属性(而不是defaultPlaybackRate
属性)来实现。
跳转必须根据跳转到媒体元素的媒体时间轴中的请求位置来实现。对于跳转到任意位置会很慢的媒体资源,用户代理应当在响应用户操作近似位置界面(如跳转条)时使用approximate-for-speed标志。
所有当前引擎支持。
controls
IDL属性必须反映同名的内容属性。
media.volume [ = value ]
所有当前引擎支持。
返回当前播放音量,范围为0.0到1.0,其中0.0是最安静的,1.0是最响亮的。
可以设置以更改音量。
如果新值不在0.0到1.0的范围内,则抛出"IndexSizeError
"DOMException
。
media.muted [ = value ]
所有当前引擎支持。
如果音频被静音,返回true,覆盖volume
属性;如果volume
属性被尊重,返回false。
可以设置,以更改音频是否被静音。
媒体元素具有一个播放音量,范围为0.0(静音)到1.0(最响亮)。最初,音量应为1.0,但用户代理可以在每个站点或其他情况下记住上次设置的值,因此音量可能从其他值开始。
volume
IDL属性必须返回播放音量的任何音频部分的媒体元素。在设置时,如果新值在0.0到1.0范围内(包括),则媒体元素的播放音量必须设置为新值。如果新值不在0.0到1.0范围内(包括),则在设置时,必须抛出"IndexSizeError
"DOMException
。
媒体元素也可以静音。如果有任何东西将元素静音,则它是静音的。(例如,当播放方向是向后时,元素被静音。)
muted
IDL属性必须返回最后设置的值。当创建媒体元素时,如果元素指定了一个muted
内容属性,则muted
IDL属性应设置为true;否则,用户代理可以将值设置为用户的首选值(例如记住上次设置的值)。当muted
IDL属性设置为true时,媒体元素必须静音。
每当volume
和muted
IDL属性返回的值之一发生变化时,用户代理必须队列一个媒体元素任务给定媒体元素以触发一个事件,命名为volumechange
在媒体元素上。然后,如果媒体元素不允许播放,用户代理必须为媒体元素运行内部暂停步骤。
用户代理有一个关联的音量锁定(布尔值)。其值是实现定义的,决定是否播放音量生效。
元素的有效媒体音量确定如下:
如果用户已指示用户代理覆盖元素的音量,则返回用户所需的音量。
如果用户代理的音量锁定为true,则返回系统音量。
如果元素的音频输出被静音,则返回零。
返回volume,相对于0.0到1.0的范围解释,0.0为静音,1.0为最响亮的设置,中间的值增加响度。范围不必是线性的。最响亮的设置可以低于系统的最大可能设置;例如用户可以设置最大音量。
muted
内容属性在媒体元素上是一个布尔属性,控制媒体资源的音频输出的默认状态,可能会覆盖用户偏好。
所有当前引擎支持。
defaultMuted
IDL属性必须反映muted
内容属性。
此属性没有动态效果(它只控制元素的默认状态)。
这个视频(广告)会自动播放,但为了避免打扰用户,它在没有声音的情况下播放,并允许用户打开声音。如果没有用户交互,用户代理可以暂停视频。
< video src = "adverts.cgi?kind=video" controls autoplay loop muted ></ video >
所有当前引擎支持。
实现TimeRanges
接口的对象表示一系列时间范围(期间)。
[Exposed =Window ]
interface TimeRanges {
readonly attribute unsigned long length ;
double start (unsigned long index );
double end (unsigned long index );
};
media.length
所有当前引擎支持。
返回对象中的范围数。
time = media.start(index)
所有当前引擎支持。
返回给定索引的范围的开始时间。
如果索引超出范围,则抛出"IndexSizeError
" DOMException
。
time = media.end(index)
所有当前引擎支持。
返回给定索引的范围的结束时间。
如果索引超出范围,则抛出"IndexSizeError
" DOMException
。
length
IDL属性必须返回对象所表示的范围数。
start(index)
方法必须返回对象所表示的第index个范围的开始位置,以该对象覆盖的时间轴开始测量的秒数。
end(index)
方法必须返回对象所表示的第index个范围的结束位置,以该对象覆盖的时间轴开始测量的秒数。
如果以大于或等于对象表示的范围数的index参数调用这些方法,则必须抛出"IndexSizeError
" DOMException
。
当一个TimeRanges
对象被称为标准化TimeRanges
对象时,它所表示的范围必须遵守以下标准:
换句话说,此类对象中的范围是有序的,不重叠且不接触(相邻范围折叠成一个更大的范围)。范围可以是空的(仅引用时间上的一个时刻),例如,在用户代理丢弃整个媒体资源的情况下,指示当前仅缓冲一个帧,当媒体元素暂停时。
一个TimeRanges
对象中的范围必须是包含的。
因此,一个范围的结束等于后续相邻(接触但不重叠)范围的开始。同样,覆盖整个以零为锚点的时间轴的范围的开始将等于零,结束将等于时间轴的持续时间。
由媒体元素的buffered
,
seekable
和
played
IDL属性返回的对象使用的时间轴必须是该元素的媒体时间轴。
TrackEvent
接口所有当前引擎支持。
[Exposed =Window ]
interface TrackEvent : Event {
constructor (DOMString type , optional TrackEventInit eventInitDict = {});
readonly attribute (VideoTrack or AudioTrack or TextTrack )? track ;
};
dictionary TrackEventInit : EventInit {
(VideoTrack or AudioTrack or TextTrack )? track = null ;
};
event.track
所有当前引擎支持。
返回事件相关的轨道对象(TextTrack
,
AudioTrack
,
或
VideoTrack
)。
track
属性必须返回它初始化时的值。它代表事件的上下文信息。
本节为非规范性内容。
在媒体元素上触发以下事件,作为上述处理模型的一部分:
事件名称 | 接口 | 触发时机... | 前提条件 |
---|---|---|---|
loadstart
HTMLMediaElement/loadstart_event 所有当前引擎支持。 Firefox6+Safari4+Chrome3+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
Event
|
用户代理开始查找媒体数据,作为资源选择算法的一部分。 | networkState 等于NETWORK_LOADING
|
progress
HTMLMediaElement/progress_event 所有当前引擎支持。 Firefox6+Safari3.1+Chrome3+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
Event
|
用户代理正在获取媒体数据。 | networkState 等于NETWORK_LOADING
|
suspend
HTMLMediaElement/suspend_event 所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
用户代理有意暂停当前获取媒体数据。 | networkState 等于NETWORK_IDLE
|
abort
所有当前引擎支持。 Firefox9+Safari3.1+Chrome3+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
Event
|
用户代理在媒体数据完全下载之前停止获取,但不是由于错误。 | error 是一个代码为MEDIA_ERR_ABORTED 的对象。networkState 等于NETWORK_EMPTY 或NETWORK_IDLE ,取决于何时中止下载。
|
error
所有当前引擎支持。 Firefox6+Safari3.1+Chrome3+
Opera11.6+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
Event
|
在获取媒体数据时发生错误或资源类型不支持媒体格式。 | error 是一个代码为MEDIA_ERR_NETWORK 或更高的对象。networkState 等于NETWORK_EMPTY 或NETWORK_IDLE ,取决于何时中止下载。
|
emptied
HTMLMediaElement/emptied_event 所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
网络状态先前不为NETWORK_EMPTY 的媒体元素刚刚切换到该状态(要么是加载期间发生了致命错误即将报告,要么是在资源选择算法已在运行时调用了load() 方法)。 |
networkState 为NETWORK_EMPTY ;所有IDL属性都在其初始状态。
|
stalled
HTMLMediaElement/stalled_event 所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
用户代理尝试获取媒体数据,但数据意外未到达。 | networkState 为NETWORK_LOADING 。
|
loadedmetadata
HTMLMediaElement/loadedmetadata_event 所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
用户代理刚刚确定了媒体资源的持续时间和维度,并且文本轨道已准备好。 | readyState 首次等于或大于HAVE_METADATA 。
|
loadeddata
HTMLMediaElement/loadeddata_event 所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
用户代理可以在当前播放位置首次渲染媒体数据。 | readyState 首次增加到HAVE_CURRENT_DATA 或更高。
|
canplay
HTMLMediaElement/canplay_event 所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
用户代理可以恢复播放媒体数据,但估计如果现在开始播放,则无法在不需进一步缓冲内容的情况下以当前播放速率渲染媒体资源直至结束。 | readyState 新增加到HAVE_FUTURE_DATA 或更高。
|
canplaythrough
HTMLMediaElement/canplaythrough_event 所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
用户代理估计如果现在开始播放,媒体资源可以以当前播放速率渲染到结束而不需进一步缓冲。 | readyState 新等于HAVE_ENOUGH_DATA 。
|
playing
HTMLMediaElement/playing_event 所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
播放准备开始,在暂停或因缺少媒体数据而延迟后。 | readyState 新大于或等于HAVE_FUTURE_DATA ,且paused 为false,或paused 新为false且readyState 大于或等于HAVE_FUTURE_DATA 。即使此事件触发,元素也可能仍未可能正在播放,例如,如果元素是因用户互动暂停或因带内内容暂停。 |
waiting
HTMLMediaElement/waiting_event 所有当前引擎支持。 Firefox6+Safari3.1+Chrome3+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+ |
Event
|
播放已停止,因为下一帧不可用,但用户代理预期该帧将适时可用。 | readyState 小于或等于HAVE_CURRENT_DATA ,且paused 为false。seeking 为true,或当前播放位置不包含在buffered 中的任何范围内。播放可能由于其他原因停止而paused 不为false,但这些原因不会触发此事件(当这些情况解决时,也不会触发单独的playing 事件):例如,播放已结束,或播放因错误停止,或元素已因用户互动暂停或因带内内容暂停。 |
seeking
HTMLMediaElement/seeking_event 所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android? Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
seeking IDL属性已更改为true,且用户代理已开始寻找新位置。
|
|
seeked
所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
seeking IDL属性已更改为false,当前播放位置已更改。
|
|
ended
所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
播放已停止,因为到达媒体资源的末端。 | currentTime 等于媒体资源的末端;ended 为true。
|
durationchange
HTMLMediaElement/durationchange_event 所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
duration 属性刚刚更新。
|
|
timeupdate
HTMLMediaElement/timeupdate_event 所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
当前播放位置在正常播放过程中或以特别有趣的方式(例如不连续地)发生了变化。 | |
play
所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
元素不再暂停。在play() 方法返回后或autoplay 属性导致播放开始时触发。
|
paused 新为false。
|
pause
所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
元素已暂停。在pause() 方法返回后触发。
|
paused 新为true。
|
ratechange
HTMLMediaElement/ratechange_event 所有当前引擎支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
Event
|
defaultPlaybackRate 或playbackRate 属性刚刚更新。
|
|
resize
|
Event
|
videoWidth 和videoHeight 属性之一或两者刚刚更新。
|
媒体元素是video 元素;readyState 不为HAVE_NOTHING
|
volumechange
HTMLMediaElement/volumechange_event 所有当前引擎支持。 Firefox6+Safari3.1+Chrome3+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+ |
Event
|
volume 属性或muted 属性已更改。在相关属性的setter返回后触发。
|
以下事件会在source
元素上触发:
事件名称 | 接口 | 触发时机 |
---|---|---|
error
|
Event
|
在获取媒体数据时发生错误或资源类型不是支持的媒体格式。 |
以下事件会在AudioTrackList
、VideoTrackList
和TextTrackList
对象上触发:
事件名称 | 接口 | 触发时机 |
---|---|---|
change
所有当前引擎支持。 Firefox🔰
33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+ Edge (旧版)NoInternet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? 所有当前引擎支持。 Firefox31+Safari7+Chrome33+
Opera?Edge79+ Edge (旧版)18Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android4.4+Samsung Internet?Opera Android? 所有当前引擎支持。 Firefox🔰
33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+ Edge (旧版)NoInternet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
Event
|
一个或多个轨道在轨道列表中已启用或禁用。 |
addtrack
所有当前引擎支持。 Firefox🔰
33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+ Edge (旧版)NoInternet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? 所有当前引擎支持。 Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer11 Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android? 所有当前引擎支持。 Firefox🔰
33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+ Edge (旧版)NoInternet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
TrackEvent |
轨道已添加到轨道列表中。 |
removetrack
AudioTrackList/removetrack_event 所有当前引擎支持。 Firefox🔰
33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+ Edge (旧版)NoInternet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? TextTrackList/removetrack_event 所有当前引擎支持。 Firefox31+Safari7+Chrome33+
Opera20+Edge79+ Edge (旧版)18Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android4.4+Samsung Internet?Opera Android? VideoTrackList/removetrack_event 所有当前引擎支持。 Firefox🔰
33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+ Edge (旧版)NoInternet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
TrackEvent |
轨道已从轨道列表中移除。 |
事件名称 | 接口 | 触发时机 |
---|---|---|
cuechange
HTMLTrackElement/cuechange_event 所有当前引擎支持。 Firefox68+Safari10+Chrome32+
Opera19+Edge79+ Edge (旧版)14+Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android4.4.3+Samsung Internet?Opera Android19+ 所有当前引擎支持。 Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
Event
|
轨道中的一个或多个提示已变为活动或停止活动。 |
以下事件在track
元素上触发:
事件名称 | 接口 | 触发时机 |
---|---|---|
error
|
Event
|
获取轨道数据时发生错误或资源类型不是受支持的文本轨道格式。 |
load
|
Event
|
轨道数据已被获取并成功处理。 |
以下事件在TextTrackCue
对象上触发:
事件名称 | 接口 | 触发时机 |
---|---|---|
enter
所有当前引擎支持。 Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
Event
|
提示已变为活动。 |
exit
所有当前引擎支持。 Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
Event
|
提示已停止活动。 |
video
和audio
元素的主要安全和隐私影响来自跨源嵌入媒体的能力。威胁可以从两个方向流动:从恶意内容到受害页面,以及从恶意页面到受害内容。
如果受害页面嵌入恶意内容,威胁在于内容可能包含脚本代码,试图与嵌入内容的Document
交互。为避免这种情况,用户代理必须确保内容无法访问嵌入页面。在使用DOM概念的媒体内容的情况下,嵌入的内容必须被视为在其自己无关的顶级可遍历中。
例如,如果在video
元素中嵌入一个SVG动画,用户代理不会给予它访问外部页面DOM的权限。从SVG资源中的脚本视角来看,SVG文件将显得处于一个没有父级的单独顶级可遍历中。
如果恶意页面嵌入受害内容,威胁在于嵌入页面可能会从内容中获取其本不会访问的信息。API确实暴露了一些信息:媒体的存在、其类型、其持续时间、其大小及其主机的性能特征。这些信息已经可能带来问题,但实际上可以通过img
元素获取到差不多的信息,因此被认为是可以接受的。
然而,如果用户代理进一步暴露内容中的元数据,如字幕,则可能获得显著更敏感的信息。因此,只有在视频资源使用CORS时才暴露这些信息。crossorigin
属性允许作者启用CORS。[FETCH]
没有这个限制,攻击者可能会欺骗在企业网络内运行的用户访问一个试图从企业内联网泄露位置加载视频的网站。如果这样的影片包含新产品的机密计划,那么能够读取字幕将造成严重的机密泄露。
本节为非规范性内容。
在小型设备(如机顶盒或手机)上播放音视频资源通常受到设备硬件资源有限的限制。例如,一个设备可能只支持同时播放三个视频。因此,当媒体元素media
elements播放完毕时,通过非常谨慎地移除对该元素的所有引用并允许其被垃圾回收,或者更好的方法是将元素的src
属性设置为空字符串,来释放资源。如果设置了srcObject
,则将srcObject
设置为null。
同样地,当播放速率不完全是1.0时,硬件、软件或格式限制可能会导致视频帧丢失和音频断断续续或静音。
本节为非规范性内容。
实现media element API的各个方面的准确程度被认为是实现质量问题。
例如,在实现buffered
属性时,报告已缓冲范围的精确程度取决于用户代理检查数据的仔细程度。由于API以时间报告范围,但数据是以字节流获取的,因此接收可变比特率流的用户代理可能只能通过实际解码所有数据来确定精确时间。然而,用户代理不需要这样做;他们可以返回估计值(例如基于到目前为止看到的平均比特率),这些估计值会随着更多信息的出现而进行修正。
作为一般规则,用户代理应保守而非乐观。例如,报告所有内容都已缓冲但实际上并没有缓冲完全是有害的。
另一个实现质量问题是当编解码器仅设计用于前向播放(例如关键帧很少且间隔很远,并且中间帧仅具有前一帧的增量)时,反向播放视频。用户代理可能会表现不佳,例如只显示关键帧;然而,更好的实现会做更多的工作,从而表现得更好,例如实际前向解码视频部分,存储完整帧,然后反向播放这些帧。
同样,实现可以随时丢弃缓冲数据(没有要求用户代理在媒体元素的生命周期内保留所有获取的媒体数据),这也是实现质量问题:有足够资源的用户代理被鼓励保留所有数据,因为这可以提供更好的用户体验。例如,如果用户在观看直播,用户代理可以只允许用户观看直播视频;然而,更好的用户代理会缓冲所有内容,并允许用户浏览早期材料,暂停,前后播放等。
当一个media element暂停时被从文档中移除并且在事件循环到达步骤1之前未重新插入,实现资源受限的用户代理被鼓励利用这个机会释放所有由media element使用的硬件资源(如视频平面、网络资源和数据缓冲区)。(用户代理仍需跟踪播放位置等,以防以后重新开始播放。)
map
元素所有当前引擎都支持。
所有当前引擎都支持。
name
— 用于从
usemap
属性引用图像地图的名称
[Exposed =Window ]
interface HTMLMapElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString name ;
[SameObject ] readonly attribute HTMLCollection areas ;
};
map
元素,与
img
元素和任何
area
元素后代一起使用,定义一个 图像地图。该元素表示其子元素。
name
属性为地图提供了一个名称,以便可以引用。该属性必须存在,并且必须具有一个没有 ASCII 空白字符的非空值。name
属性的值不得等于同一树中的其他 map
元素的 name
属性的值。如果还指定了
id
属性,则两个属性的值必须相
同。
map.areas
返回一个根植于 map
元素的
HTMLCollection
,其过滤器仅匹配
area
元素。
areas
属性必须返回一个根植于 map
元素的 HTMLCollection
,其过滤器仅匹配
area
元素。
IDL 属性 name
必须反映同名的内容属性。
图像地图可以与页面上的其他内容一起定义,以简化维护。这个示例是一个页面,在页面顶部有一个图像地图,在底部有一组对应的文本链接。
<!DOCTYPE HTML>
< HTML LANG = "EN" >
< TITLE > Babies™: Toys</ TITLE >
< HEADER >
< H1 > Toys</ H1 >
< IMG SRC = "/images/menu.gif"
ALT = "Babies™ navigation menu. Select a department to go to its page."
USEMAP = "#NAV" >
</ HEADER >
...
< FOOTER >
< MAP NAME = "NAV" >
< P >
< A HREF = "/clothes/" > Clothes</ A >
< AREA ALT = "Clothes" COORDS = "0,0,100,50" HREF = "/clothes/" > |
< A HREF = "/toys/" > Toys</ A >
< AREA ALT = "Toys" COORDS = "100,0,200,50" HREF = "/toys/" > |
< A HREF = "/food/" > Food</ A >
< AREA ALT = "Food" COORDS = "200,0,300,50" HREF = "/food/" > |
< A HREF = "/books/" > Books</ A >
< AREA ALT = "Books" COORDS = "300,0,400,50" HREF = "/books/" >
</ P >
</ MAP >
</ FOOTER >
area
元素所有当前引擎都支持。
所有当前引擎都支持。
map
元素祖先时。
alt
—
当图像不可用时使用的替代文本coords
— 在图像地图中创建形状的坐标shape
—
在图像地图中创建形状的类型href
—
超链接的地址target
— 用于导航超链接的可导航目标download
— 是否下载资源而不是导航到它,如果是,则为其文件名ping
— 要 ping 的 URLrel
—
文档中包含超链接的位置与目标资源之间的关系referrerpolicy
— 元素发起的获取的引用策略href
属性:作者参考;实现者参考。[Exposed =Window ]
interface HTMLAreaElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString alt ;
[CEReactions ] attribute DOMString coords ;
[CEReactions ] attribute DOMString shape ;
[CEReactions ] attribute DOMString target ;
[CEReactions ] attribute DOMString download ;
[CEReactions ] attribute USVString ping ;
[CEReactions ] attribute DOMString rel ;
[SameObject , PutForwards =value ] readonly attribute DOMTokenList relList ;
[CEReactions ] attribute DOMString referrerPolicy ;
// also has obsolete members
};
HTMLAreaElement includes HTMLHyperlinkElementUtils ;
area
元素
表示在图像地图上的超链接和相应的区域,或者是图像地图上的一个无效区域。
如果 area
元素具有 href
属性,那么 area
元素表示一个
超链接。在这种情况下,alt
属性必须存在。它指定超链接的文本。其值必须是这样的文本:当与图像地图的其他超链接文本以及图像的替代文本一起呈现时,但没有图像本身时,向用户提供与超链接使用其形状应用于图像时相同类型的选择。如果同一 图像地图 中有另一个 area
元素指向相同的资源,并且其 alt
属性不为空,则该属性可以留空。
如果 area
元素没有 href
属性,则该元素表示的区域不可选择,并且必须省略 alt
属性。
在这两种情况下,shape
和 coords
属性指定该区域。
shape
属性是一个具有以下关键字和状态的枚举属性:
关键字 | 符合 | 状态 | 简要描述 |
---|---|---|---|
circle |
圆形状态 | 表示一个圆形,使用 coords
属性中的三个整数。 |
|
circ |
否 | ||
default |
默认状态 | 该区域是整个图像。(不使用 coords
属性。) |
|
poly |
多边形状态 | 表示一个多边形,使用 coords
属性中的至少六个整数。 |
|
polygon |
否 | ||
rect |
矩形状态 | 表示一个矩形,使用 coords
属性中的四个整数。 |
|
rectangle |
否 |
coords
属性必须包含一个 有效的浮点数列表,如果指定的话。该属性提供了由 shape
属性描述的形状的坐标。此属性的处理在 图像地图处理模型中描述。
在 圆形状态中,area
元素必须具有
coords
属性,该属性包含三个整数,最后一个必须为非负数。第一个整数必须是从图像左边缘到圆心的距离,第二个整数必须是从图像上边缘到圆心的距离,第三个整数必须是圆的半径,均以 CSS 像素为单位。
在 默认状态中,area
元素不能有
coords
属性。(该区域是整个图像。)
在 多边形状态中,area
元素必须具有
coords
属性,至少包含六个整数,并且整数的数量必须是偶数。每对整数必须表示从图像左侧和顶部的距离,均以 CSS 像素 为单位,并且所有坐标一起表示多边形的点,按顺序排列。
在 矩形状态中,area
元素必须具有
coords
属性,其中包含四个整数,第一个必须小于第三个,第二个必须小于第四个。这四个点分别表示从图像左边缘到矩形左侧的距离、从顶部边缘到顶部的距离、从左侧到右侧的距离和从顶部到底部的距离,均以 CSS 像素为单位。
当用户代理允许用户 跟随超链接或 下载超链接 时,area
元素的
href
、target
、download
和 ping
属性决定了链接的跟随方式。rel
属性可用于向用户指示在用户跟随链接之前目标资源的可能性质。
target
、download
、ping
、rel
和
referrerpolicy
属性必须省略,如果没有 href
属性。
如果 itemprop
属性在 area
元素上指定,则还必须指定 href
属性。
所有当前引擎都支持。
ID属性 alt
、coords
、shape
、target
、download
、ping
和 rel
,必须 反映同名的相应内容属性。
所有当前引擎都支持。
HTMLAreaElement/referrerPolicy
所有当前引擎都支持。
ID属性 referrerPolicy
必须 反映 referrerpolicy
内容属性,仅限于已知值。
图像映射允许将图像上的几何区域与超链接关联起来。
图像(以img
元素的形式)可以通过在img
元素上指定usemap
属性来关联到图像映射(以map
元素的形式)。如果指定了usemap
属性,它必须是指向map
元素的有效的哈希名称引用。
考虑如下所示的图像:
如果我们只想让有颜色的区域可以点击,我们可以这样做:
< p >
Please select a shape:
< img src = "shapes.png" usemap = "#shapes"
alt = "Four shapes are available: a red hollow box, a green circle, a blue triangle, and a yellow four-pointed star." >
< map name = "shapes" >
< area shape = rect coords = "50,50,100,100" > <!-- the hole in the red box -->
< area shape = rect coords = "25,25,125,125" href = "red.html" alt = "Red box." >
< area shape = circle coords = "200,75,50" href = "green.html" alt = "Green circle." >
< area shape = poly coords = "325,25,262,125,388,125" href = "blue.html" alt = "Blue triangle." >
< area shape = poly coords = "450,25,435,60,400,75,435,90,450,125,465,90,500,75,465,60"
href = "yellow.html" alt = "Yellow star." >
</ map >
</ p >
如果img
元素有指定usemap
属性,用户代理必须按如下方式处理:
使用解析哈希名称引用的规则解析该属性的值为指向map
元素,并以该元素为上下文节点。这将返回一个元素(map)或null。
如果返回null,则返回。该图像并未关联到图像映射。
否则,用户代理必须收集所有作为map后代的area
元素。将这些元素称为areas。
获取形成图像映射的area
元素列表(areas)后,交互式用户代理必须以两种方式之一处理该列表。
如果用户代理打算显示img
元素表示的文本,则必须使用以下步骤。
删除areas中所有没有alt
属性或alt
属性值为空字符串的area
元素,如果在areas中有另一个具有相同href
属性值且具有非空alt
属性的area
元素。
每个剩余的areas中的area
元素都代表一个超链接。这些超链接应以与img
的文本相关的方式提供给用户。
在这种情况下,用户代理可以以area
和img
元素没有指定alt
属性或其alt
属性为空字符串或其他不可见文本的方式表示这些元素,使用一种实现定义的方式来指示缺少适当的作者提供的文本。
如果用户代理打算显示图像并允许与图像进行交互以选择超链接,则图像必须与一组从areas中的area
元素中获取的层叠形状关联,以相反的树顺序(即map中最后指定的area
元素是最底层的形状,map中的第一个元素,在树顺序中,是最顶层的形状)。
每个areas中的area
元素必须按如下方式处理以获得叠加在图像上的形状:
找到该元素的shape
属性所代表的状态。
使用解析浮点数列表的规则解析该元素的coords
属性(如果存在),并将结果设为coords列表。如果属性不存在,则将coords列表设为空列表。
如果coords列表中的项目数少于当前状态下area
元素的最小数量,则形状为空;返回。
状态 | 最小项目数 |
---|---|
圆形状态 | 3 |
默认状态 | 0 |
多边形状态 | 6 |
矩形状态 | 4 |
根据以下列表中与shape
属性的状态相对应的条目,检查coords列表中的多余项目:
现在,由元素表示的形状是下面列表中与shape
属性状态对应的条目所描述的形状:
令x为coords列表中的第一个数字,y为第二个数字,r为第三个数字。
形状是一个完全覆盖整个图像的矩形。
令xi为coords中的第2i个条目,yi为coords中的第2i+1个条目(coords中的第一个条目索引为0)。
令coordinates为(xi, yi),以CSS像素为单位,从图像左上角开始测量,对于所有i的整数值,从0到N/2-1,其中N是coords中的条目数。
该形状是一个多边形,其顶点由coordinates给出,其内部通过奇偶规则确定。[GRAPHICS]
令x1为coords中的第一个数字,y1为第二个数字,x2为第三个数字,y2为第四个数字。
该形状是一个矩形,其左上角由坐标(x1, y1)给出,右下角由坐标(x2, y2)给出,这些坐标以CSS像素为单位,从图像的左上角测量。
由于历史原因,坐标必须相对于显示后的图像解释,即CSS 'width'和'height'属性(或者,对于非CSS浏览器,图像元素的width
和height
属性——CSS浏览器将这些属性映射到上述CSS属性)。
浏览器缩放功能和使用CSS或SVG应用的变换不会影响坐标。
根据上述算法与一组层叠形状关联的图像的指针设备交互,必须首先将相关的用户交互事件发送到指针设备指示的点覆盖的最顶层形状(如果有),或者发送到图像元素本身(如果没有形状覆盖该点)。用户代理还可以允许选择和激活代表超链接的单个area
元素(例如使用键盘)。
由于map
元素(及其area
元素)可以与多个img
元素关联,因此area
元素可能对应于文档的多个可聚焦区域。
图像映射是实时的;如果DOM发生变化,用户代理必须像重新运行图像映射算法一样处理 。
HTML/HTML5/HTML5_Parser#Inline_SVG_and_MathML_support
支持所有当前引擎。
MathML math
元素属于 嵌入内容,
短语内容, 流内容, 和 可感知内容
类别,用于本规范中的内容模型。
当 MathML annotation-xml
元素包含来自
HTML 命名空间的元素时,这些元素都必须是 流内容。
当 MathML 令牌元素 (mi
,
mo
,
mn
,
ms
,
和 mtext
)
是 HTML 元素的后代时,它们可以包含来自 HTML
命名空间的
短语内容元素。
用户代理必须通过假装在 MathML 元素中发现的内容模型不允许直接文本的情况下将文本实际包装在 MathML
mtext
元素中来处理文本,而非 元素间空白。 (但这种文本并不符合规范。)
用户代理必须假装任何 MathML 元素的内容不符合元素的内容模型时,其内容被一个包含适当错误信息的 MathML
merror
元素替换,以用于 MathML 布局和渲染。
MathML 元素的语义由 MathML 和 其他适用的规范定义。 [MATHML]
这是在 HTML 文档中使用 MathML 的一个示例:
<!DOCTYPE html>
< html lang = "en" >
< head >
< title > The quadratic formula</ title >
</ head >
< body >
< h1 > The quadratic formula</ h1 >
< p >
< math >
< mi > x</ mi >
< mo > =</ mo >
< mfrac >
< mrow >
< mo form = "prefix" > −</ mo > < mi > b</ mi >
< mo > ±</ mo >
< msqrt >
< msup > < mi > b</ mi > < mn > 2</ mn > </ msup >
< mo > −</ mo >
< mn > 4</ mn > < mo > </ mo > < mi > a</ mi > < mo > </ mo > < mi > c</ mi >
</ msqrt >
</ mrow >
< mrow >
< mn > 2</ mn > < mo > </ mo > < mi > a</ mi >
</ mrow >
</ mfrac >
</ math >
</ p >
</ body >
</ html >
HTML/HTML5/HTML5_Parser#Inline_SVG_and_MathML_support
支持所有当前引擎。
SVG
svg
元素属于 嵌入内容,
短语内容, 流内容, 和 可感知内容
类别,用于本规范中的内容模型。
当 SVG foreignObject
元素包含来自
HTML 命名空间的元素时,这些元素都必须是 流内容。
在 HTML
文档中的 SVG title
元素的内容模型是 短语内容。 (这进一步限制了SVG
2中的要求。)
SVG 元素的语义由 SVG 2 和 其他适用的规范定义。 [SVG]
doc = iframe.getSVGDocument()
doc = embed.getSVGDocument()
doc = object.getSVGDocument()
getSVGDocument()
方法的步骤如下:
如果 document 非空,并且因为 页面加载处理模型针对 XML
文件部分创建了它,因为在 资源的计算类型在 导航算法中是
image/svg+xml
,那么返回
document。
返回 null。
作者要求:在 img
、
iframe
、
embed
、
object
、
video
、
source
元素上,
当其父元素是 picture
元素时,
以及当其 type
属性处于 图片按钮状态时,
input
元素,
可以指定 width
和
height
属性,
以给出元素视觉内容的尺寸(分别是宽度和高度,相对于输出媒介的标称方向),单位为 CSS 像素。如果指定了这些属性,它们的值必须是有效的非负整数。
给定的指定尺寸可能与资源本身指定的尺寸不同,因为资源的分辨率可能与 CSS 像素分辨率不同。(在屏幕上,CSS 像素 的分辨率是 96ppi,但一般来说,CSS 像素分辨率取决于阅读距离。)如果同时指定了两个属性,则必须满足以下陈述之一:
target ratio 是资源的 自然宽度 与
自然高度 的比率。specified width 和 specified height 分别是
width
和 height
属性的值。
如果相关资源没有 自然宽度 和 自然高度,则必须省略这两个属性。
如果两个属性都为0,这表示该元素不打算用于用户(例如,它可能是一个用于计数页面浏览量的服务的一部分)。
尺寸属性不应用于拉伸图像。
用户代理要求:用户代理应使用这些属性 作为渲染的提示。
支持所有当前引擎。
支持所有当前引擎。
width
和 height
IDL 属性在 iframe
、
embed
、
object
、
source
和
video
元素上
必须 反映相应的内容属性。
对于 iframe
、
embed
和
object
,
IDL 属性是 DOMString
;
对于 video
和
source
,
IDL 属性是
unsigned long
。
对于 img
和
input
元素,
相应的 IDL 属性在这些各自元素的部分中定义,因为它们更具体地与这些元素的其他行为相关。
table
元素支持所有当前引擎。
支持所有当前引擎。
caption
元素,随后零个或多个colgroup
元素,随后可选的thead
元素,随后零个或多个tbody
元素或一个或多个tr
元素,随后可选的tfoot
元素,可选地夹杂一个或多个脚本支持元素。[Exposed =Window ]
interface HTMLTableElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute HTMLTableCaptionElement ? caption ;
HTMLTableCaptionElement createCaption ();
[CEReactions ] undefined deleteCaption ();
[CEReactions ] attribute HTMLTableSectionElement ? tHead ;
HTMLTableSectionElement createTHead ();
[CEReactions ] undefined deleteTHead ();
[CEReactions ] attribute HTMLTableSectionElement ? tFoot ;
HTMLTableSectionElement createTFoot ();
[CEReactions ] undefined deleteTFoot ();
[SameObject ] readonly attribute HTMLCollection tBodies ;
HTMLTableSectionElement createTBody ();
[SameObject ] readonly attribute HTMLCollection rows ;
HTMLTableRowElement insertRow (optional long index = -1);
[CEReactions ] undefined deleteRow (long index );
// also has obsolete members
};
table
元素 表示具有多于一个维度的数据,以表格的形式。
table
元素参与 表格模型。表格具有由其后代给出的行、列和单元格。这些行和列形成一个网格;表格的单元格必须完全覆盖该网格而不重叠。
判断此一致性要求是否满足的具体规则在 表格模型的描述中。
鼓励作者提供描述如何解释复杂表格的信息。关于如何 提供此类信息的指导在下方。
表格不得用作布局辅助工具。历史上,一些网页作者错误地使用 HTML 表格来控制其页面布局。这种用法是不符合规范的,因为尝试从此类文档中提取表格数据的工具会得到非常混乱的结果。特别是,使用屏幕阅读器等辅助工具的用户可能会发现很难导航使用表格进行布局的页面。
有多种替代方案可用于布局,而不是使用 HTML 表格,例如 CSS 网格布局、CSS 弹性盒布局(“flexbox”)、CSS 多列布局、CSS 定位和 CSS 表格模型。[CSS]
表格可能很复杂,难以理解和导航。为了帮助用户,用户代理应清晰地将表格中的单元格彼此区分开来,除非用户代理已将表格分类为(不符合规范的)布局表格。
鼓励作者和实现者考虑使用一些在下方描述的 表格设计技巧 以使表格更易于用户导航。
用户代理,特别是那些对任意内容进行表格分析的用户代理,鼓励找到确定哪些表格实际包含数据而哪些仅用于布局的启发式方法。本规范未定义精确的启发式方法,但以下建议作为可能的指标:
特征 | 指示 |
---|---|
使用 role 属性,值为
presentation
|
可能是布局表格 |
使用不符合规范的 border
属性,值为 0 |
可能是布局表格 |
使用不符合规范的 cellspacing
和 cellpadding
属性,值为 0 |
可能是布局表格 |
使用 caption 、thead
或 th 元素
|
可能是非布局表格 |
使用 headers
和 scope
属性 |
可能是非布局表格 |
使用不符合规范的 border
属性,值为非0 |
可能是非布局表格 |
使用 CSS 设置的显式可见边框 | 可能是非布局表格 |
使用 summary
属性 |
不是一个好的指标(历史上,布局表格和非布局表格都设置了这个属性) |
以上建议很可能是错误的。强烈建议实现者提供反馈,详细说明他们尝试创建布局表格检测启发式方法的经验。
如果一个 table
元素有一个(不符合规范的)summary
属性,并且用户代理未将其分类为布局表格,则用户代理可以向用户报告该属性的内容。
table.caption [ = value ]
支持所有当前引擎。
返回表格的 caption
元素。
可设置,以替换 caption
元素。
caption = table.createCaption()
HTMLTableElement/createCaption
支持所有当前引擎。
确保表格有一个 caption
元素,并返回它。
table.deleteCaption()
HTMLTableElement/deleteCaption
支持所有当前引擎。
确保表格没有 caption
元素。
table.tHead [ = value ]
支持所有当前引擎。
返回表格的 thead
元素。
可设置,以替换 thead
元素。如果新值不是 thead
元素,则抛出 "HierarchyRequestError
" DOMException
。
thead = table.createTHead()
支持所有当前引擎。
确保表格有一个 thead
元素,并返回它。
table.deleteTHead()
支持所有当前引擎。
确保表格没有 thead
元素。
table.tFoot [ = value ]
支持所有当前引擎。
返回表格的 tfoot
元素。
可设置,以替换 tfoot
元素。如果新值不是 tfoot
元素,则抛出 "HierarchyRequestError
" DOMException
。
tfoot = table.createTFoot()
支持所有当前引擎。
确保表格有一个 tfoot
元素,并返回它。
table.deleteTFoot()
支持所有当前引擎。
确保表格没有 tfoot
元素。
table.tBodies
支持所有当前引擎。
返回一个 HTMLCollection
,包含表格的
tbody
元素。
tbody = table.createTBody()
支持所有当前引擎。
创建一个 tbody
元素,将其插入表格中,并返回它。
table.rows
支持所有当前引擎。
返回一个 HTMLCollection
,包含表格的
tr
元素。
tr = table.insertRow([ index ])
支持所有当前引擎。
创建一个 tr
元素,必要时同时创建 tbody
,按给定的位置将其插入表格中,并返回
tr
。
位置相对于表中的行。默认省略参数时,索引 -1 相当于插入到表格末尾。
如果给定位置小于 -1 或大于行数,则抛出 "IndexSizeError
" DOMException
。
table.deleteRow(index)
支持所有当前引擎。
移除表中给定位置的 tr
元素。
位置相对于表中的行。索引 -1 相当于删除表格的最后一行。
如果给定位置小于 -1 或大于最后一行的索引,或没有行,则抛出 "IndexSizeError
" DOMException
。
在以下所有属性和方法定义中,当一个元素需要 表格创建时,意味着根据 table
元素的
节点文档、给定的本地名称和 HTML 命名空间 创建一个元素。
当获取 caption
IDL 属性时,必须返回 caption
元素,若无则返回 null。设置时,必须移除 caption
元素子节点(如果有),并插入新值(若不为 null)。
当调用 createCaption()
方法时,必须返回 caption
元素,若无则创建并插入新 caption
元素,并返回。
当调用 deleteCaption()
方法时,必须移除 caption
元素(如果有)。
当获取 tHead
IDL 属性时,必须返回 thead
元素,若无则返回 null。设置时,如果新值为 null 或 thead
元素,必须移除第一个 thead
元素,并插入新值(若不为 null)。如果新值既不是 null 也不是 thead
元素,则抛出 "HierarchyRequestError
" DOMException
。
当调用 createTHead()
方法时,必须返回 thead
元素,若无则创建并插入新 thead
元素,并返回。
当调用 deleteTHead()
方法时,必须移除 thead
元素(如果有)。
当获取 tFoot
IDL 属性时,必须返回 tfoot
元素,若无则返回 null。设置时,如果新值为 null 或 tfoot
元素,必须移除第一个 tfoot
元素,并插入新值(若不为 null)。如果新值既不是 null 也不是 tfoot
元素,则抛出 "HierarchyRequestError
" DOMException
。
当调用 createTFoot()
方法时,必须返回 tfoot
元素,若无则创建并插入新 tfoot
元素,并返回。
当调用 deleteTFoot()
方法时,必须移除 tfoot
元素(如果有)。
当获取 tBodies
属性时,必须返回一个 HTMLCollection
,其过滤器仅匹配
tbody
元素。
当调用 createTBody()
方法时,必须 表格创建 一个新的 tbody
元素,将其插入到 table
元素的最后一个 tbody
元素之后(如果有),并返回新元素。
当获取 rows
属性时,必须返回一个 HTMLCollection
,其过滤器仅匹配
tr
元素。
调用 insertRow(index)
方法时,根据表格状态执行以下操作:
rows
集合中的元素数量:IndexSizeError
" DOMException
。
rows
集合中没有元素,且 table
中没有 tbody
元素:tbody
元素,然后 表格创建 一个 tr
元素,然后将
tr
元素追加到
tbody
元素中,然后将 tbody
元素追加到 table
元素中,最后返回 tr
元素。
rows
集合中没有元素:tr
元素,将其追加到表格中的最后一个 tbody
元素中,并返回 tr
元素。rows
集合中的项目数量:tr
元素,并将其追加到
rows
集合中的最后一个 tr
元素的父节点。然后,必须返回新创建的 tr
元素。
tr
元素,将其插入到
rows
集合中的第 index 个 tr
元素之前,并返回新创建的 tr
元素。
当调用 deleteRow(index)
方法时,用户代理必须执行以下步骤:
如果 index 小于 -1 或大于等于 rows
集合中的元素数量,则抛出 "IndexSizeError
" DOMException
。
这是一个将表格用于标记数独谜题的示例。请注意,缺少标题,这在这样的表格中是没有必要的。
< style >
# sudoku { border-collapse : collapse ; border : solid thick ; }
# sudoku colgroup , table # sudoku tbody { border : solid medium ; }
# sudoku td { border : solid thin ; height : 1.4 em ; width : 1.4 em ; text-align : center ; padding : 0 ; }
</ style >
< h1 > Today's Sudoku</ h1 >
< table id = "sudoku" >
< colgroup >< col >< col >< col >
< colgroup >< col >< col >< col >
< colgroup >< col >< col >< col >
< tbody >
< tr > < td > 1 < td > < td > 3 < td > 6 < td > < td > 4 < td > 7 < td > < td > 9
< tr > < td > < td > 2 < td > < td > < td > 9 < td > < td > < td > 1 < td >
< tr > < td > 7 < td > < td > < td > < td > < td > < td > < td > < td > 6
< tbody >
< tr > < td > 2 < td > < td > 4 < td > < td > 3 < td > < td > 9 < td > < td > 8
< tr > < td > < td > < td > < td > < td > < td > < td > < td > < td >
< tr > < td > 5 < td > < td > < td > 9 < td > < td > 7 < td > < td > < td > 1
< tbody >
< tr > < td > 6 < td > < td > < td > < td > 5 < td > < td > < td > < td > 2
< tr > < td > < td > < td > < td > < td > 7 < td > < td > < td > < td >
< tr > < td > 9 < td > < td > < td > 8 < td > < td > 2 < td > < td > < td > 5
</ table >
对于不仅仅由第一行和第一列包含标题的单元格网格组成的表格,以及任何读者可能难以理解内容的表格,作者应包括介绍表格的解释信息。这些信息对所有用户都有用,但对无法看到表格的用户尤其有用,例如屏幕阅读器用户。
这样的解释信息应介绍表格的目的,概述其基本单元格结构,突出任何趋势或模式,并一般性地教用户如何使用表格。
例如,以下表格:
负面 | 特征 | 正面 |
---|---|---|
悲伤 | 心情 | 快乐 |
失败 | 成绩 | 通过 |
...可能需要描述说明表格的布局方式,比如“特征在第二列给出,负面在左列,正面在右列”。
有多种方法可以包含这些信息,例如:
< p > In the following table, characteristics are given in the second
column, with the negative side in the left column and the positive
side in the right column.</ p >
< table >
< caption > Characteristics with positive and negative sides</ caption >
< thead >
< tr >
< th id = "n" > Negative
< th > Characteristic
< th > Positive
< tbody >
< tr >
< td headers = "n r1" > Sad
< th id = "r1" > Mood
< td > Happy
< tr >
< td headers = "n r2" > Failing
< th id = "r2" > Grade
< td > Passing
</ table >
caption
中
< table >
< caption >
< strong > Characteristics with positive and negative sides.</ strong >
< p > Characteristics are given in the second column, with the
negative side in the left column and the positive side in the right
column.</ p >
</ caption >
< thead >
< tr >
< th id = "n" > Negative
< th > Characteristic
< th > Positive
< tbody >
< tr >
< td headers = "n r1" > Sad
< th id = "r1" > Mood
< td > Happy
< tr >
< td headers = "n r2" > Failing
< th id = "r2" > Grade
< td > Passing
</ table >
caption
中,使用details
元素
< table >
< caption >
< strong > Characteristics with positive and negative sides.</ strong >
< details >
< summary > Help</ summary >
< p > Characteristics are given in the second column, with the
negative side in the left column and the positive side in the right
column.</ p >
</ details >
</ caption >
< thead >
< tr >
< th id = "n" > Negative
< th > Characteristic
< th > Positive
< tbody >
< tr >
< td headers = "n r1" > Sad
< th id = "r1" > Mood
< td > Happy
< tr >
< td headers = "n r2" > Failing
< th id = "r2" > Grade
< td > Passing
</ table >
figure
中
< figure >
< figcaption > Characteristics with positive and negative sides</ figcaption >
< p > Characteristics are given in the second column, with the
negative side in the left column and the positive side in the right
column.</ p >
< table >
< thead >
< tr >
< th id = "n" > Negative
< th > Characteristic
< th > Positive
< tbody >
< tr >
< td headers = "n r1" > Sad
< th id = "r1" > Mood
< td > Happy
< tr >
< td headers = "n r2" > Failing
< th id = "r2" > Grade
< td > Passing
</ table >
</ figure >
figure
的figcaption
中
< figure >
< figcaption >
< strong > Characteristics with positive and negative sides</ strong >
< p > Characteristics are given in the second column, with the
negative side in the left column and the positive side in the right
column.</ p >
</ figcaption >
< table >
< thead >
< tr >
< th id = "n" > Negative
< th > Characteristic
< th > Positive
< tbody >
< tr >
< td headers = "n r1" > Sad
< th id = "r1" > Mood
< td > Happy
< tr >
< td headers = "n r2" > Failing
< th id = "r2" > Grade
< td > Passing
</ table >
</ figure >
作者还可以使用其他技术,或组合以上技术,视情况而定。
当然,最好的选择不是写一段描述解释表格的布局方式,而是调整表格,使其不需要任何解释。
对于上面示例中使用的表格,只需简单地重新排列表格,使标题在顶部和左侧,即可消除解释的需要,同时也不需要使用headers
属性:
< table >
< caption > Characteristics with positive and negative sides</ caption >
< thead >
< tr >
< th > Characteristic
< th > Negative
< th > Positive
< tbody >
< tr >
< th > Mood
< td > Sad
< td > Happy
< tr >
< th > Grade
< td > Failing
< td > Passing
</ table >
良好的表格设计是使表格更具可读性和可用性的关键。
在视觉媒体中,提供列和行边框以及交替的行背景可以非常有效地使复杂表格更具可读性。
对于包含大量数字内容的表格,使用等宽字体可以帮助用户看到模式,特别是在用户代理不渲染边框的情况下。(不幸的是,由于历史原因,不渲染表格边框是一种常见的默认设置。)
在语音媒体中,可以通过在读取单元格内容之前报告相应的标题,以及允许用户以网格方式导航表格,而不是按源顺序串行化整个表格的内容,来区分表格单元格。
鼓励作者使用CSS来实现这些效果。
用户代理在页面未使用CSS且表格未被分类为布局表格时,建议使用这些技术渲染表格。
caption
元素Support in all current engines.
Support in all current engines.
table
元素的第一个子元素。
table
元素的后代。
caption
元素后面没有紧接着ASCII空白
或注释
,则可以省略caption
元素的结束标签
。[Exposed =Window ]
interface HTMLTableCaptionElement : HTMLElement {
[HTMLConstructor ] constructor ();
// also has obsolete members
};
caption
元素代表
其父元素(如果有父元素且该父元素是table
元素)的table
元素的标题。
当table
元素是figure
元素中除了figcaption
之外的唯一内容时,应该省略caption
元素,而使用figcaption
。
标题可以为表格提供上下文,使其更容易理解。
考虑以下表格:
1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
2 | 3 | 4 | 5 | 6 | 7 | 8 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
4 | 5 | 6 | 7 | 8 | 9 | 10 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
6 | 7 | 8 | 9 | 10 | 11 | 12 |
从抽象角度看,这个表格不清楚。然而,带有编号(用于在主文中引用
)并解释其用途的标题,使其更加清晰:
< caption >
< p > Table 1.
< p > This table shows the total score obtained from rolling two
six-sided dice. The first row represents the value of the first die,
the first column the value of the second die. The total is given in
the cell that corresponds to the values of the two dice.
</ caption >
这为用户提供了更多上下文:
1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
2 | 3 | 4 | 5 | 6 | 7 | 8 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
4 | 5 | 6 | 7 | 8 | 9 | 10 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
6 | 7 | 8 | 9 | 10 | 11 | 12 |
colgroup
元素支持所有当前引擎。
支持所有当前引擎。
table
元素的子元素,在任何 caption
元素之后,并且在任何 thead
、tbody
、tfoot
和 tr
元素之前。
span
属性存在:无内容。span
属性不存在:零个或多个 col
和
template
元素。
colgroup
元素内的第一个元素是 col
元素,并且该元素之前没有紧跟另一个 colgroup
元素(其结束标签已省略),则可以省略 开始标签。(如果元素为空,则不能省略)。
colgroup
元素后没有紧跟 ASCII 空白字符 或 注释,则可以省略 结束标签。
span
— 元素跨越的列数[Exposed =Window ]
interface HTMLTableColElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute unsigned long span ;
// also has obsolete members
};
colgroup
元素 表示 在其父 table
元素中(一组或多组)列。
如果 colgroup
元素不包含 col
元素,那么该元素可以指定一个 span
内容属性,其值必须是一个 有效的非负整数,大于零且小于等于 1000。
span
IDL 属性必须 反映 相同名称的内容属性。它的值 被限制在 [1,
1000] 范围内,其 默认值 是 1。
col
元素支持所有当前引擎。
colgroup
元素的子元素,该元素没有 span
属性。span
—
元素跨越的列数HTMLTableColElement
,如在
colgroup
元素中定义的那样。
如果 col
元素有一个父元素,而该父元素是一个 colgroup
元素,该元素本身有一个父元素是一个 table
元素,则该
col
元素 表示 该 colgroup
中的一列或多列。
该元素可以指定一个 span
内容属性,其值必须是一个 有效的非负整数,大于零且小于或等于 1000。
tbody
元素在所有当前引擎中支持。
在所有当前引擎中支持。
table
元素的子元素,在任何 caption
、colgroup
和 thead
元素之后,但前提是没有 tr
元素是 table
元素的子元素。tr
和 支持脚本 元素。tbody
元素中的第一个元素是 tr
元素,并且该元素前面没有省略了结束标签的 tbody
、thead
或
tfoot
元素,则可以省略 开始标签。(如果元素是空的,则不能省略。)
tbody
元素后面紧跟着一个 tbody
或
tfoot
元素,或者父元素中没有更多内容,则可以省略 结束标签。
[Exposed =Window ]
interface HTMLTableSectionElement : HTMLElement {
[HTMLConstructor ] constructor ();
[SameObject ] readonly attribute HTMLCollection rows ;
HTMLTableRowElement insertRow (optional long index = -1);
[CEReactions ] undefined deleteRow (long index );
// also has obsolete members
};
HTMLTableSectionElement
接口也用于 thead
和 tfoot
元素。
tbody
元素
表示一个 块的 行,它由父 table
元素的数据主体组成,如果 tbody
元素有一个父元素并且它是一个 table
。
tbody.rows
返回一个 HTMLCollection
,其中包含表节的
tr
元素。
tr = tbody.insertRow([ index ])
创建一个 tr
元素,将其插入到给定位置的表节中,并返回 tr
。
位置相对于表节中的行。省略参数时,默认值 -1 等同于插入到表节的末尾。
如果给定的位置小于 -1 或大于行数,则抛出 "IndexSizeError
" DOMException
。
tbody.deleteRow(index)
移除表节中给定位置的 tr
元素。
位置相对于表节中的行。索引 -1 等同于删除表节的最后一行。
如果给定的位置小于 -1 或大于最后一行的索引,或者如果没有行,则抛出 "IndexSizeError
" DOMException
。
rows
属性必须返回一个根植于该元素的 HTMLCollection
,其过滤器仅匹配作为该元素子元素的
tr
元素。
insertRow(index)
方法必须按如下方式操作:
如果 index 小于 -1 或大于 rows
集合中的元素数量,则抛出 "IndexSizeError
" DOMException
。
返回 table row。
deleteRow(index)
方法在调用时必须按如下操作:
如果 index 小于 -1 或大于等于 rows
集合中的元素数量,则抛出 "IndexSizeError
" DOMException
。
如果 index 为 -1,则从此元素中 移除 rows
集合中的最后一个元素,或者如果 rows
集合为空,则不执行任何操作。
thead
元素在所有当前引擎中支持。
table
元素的子元素,在任何 caption
和 colgroup
元素之后,在任何 tbody
、tfoot
和
tr
元素之前,但前提是没有其他 thead
元素是
table
元素的子元素。
tr
和 支持脚本 元素。thead
元素后面紧跟着一个 tbody
或
tfoot
元素,则可以省略 结束标签。
HTMLTableSectionElement
,如
tbody
元素中定义的。
thead
元素
表示由列标签(表头)和任何辅助非表头单元格组成的 块的 行,前提是 thead
元素有一个父元素并且它是一个 table
。
这个例子展示了 thead
元素的使用。注意在 thead
元素中同时使用了 th
和 td
元素:第一行是表头,第二行是如何填写表格的说明。
< table >
< caption > School auction sign-up sheet </ caption >
< thead >
< tr >
< th >< label for = e1 > Name</ label >
< th >< label for = e2 > Product</ label >
< th >< label for = e3 > Picture</ label >
< th >< label for = e4 > Price</ label >
< tr >
< td > Your name here
< td > What are you selling?
< td > Link to a picture
< td > Your reserve price
< tbody >
< tr >
< td > Ms Danus
< td > Doughnuts
< td >< img src = "https://example.com/mydoughnuts.png" title = "Doughnuts from Ms Danus" >
< td > $45
< tr >
< td >< input id = e1 type = text name = who required form = f >
< td >< input id = e2 type = text name = what required form = f >
< td >< input id = e3 type = url name = pic form = f >
< td >< input id = e4 type = number step = 0.01 min = 0 value = 0 required form = f >
</ table >
< form id = f action = "/auction.cgi" >
< input type = button name = add value = "Submit" >
</ form >
tfoot
元素在所有当前引擎中支持。
table
元素的子元素,在任何 caption
、colgroup
、thead
、tbody
和
tr
元素之后,但前提是没有其他 tfoot
元素是
table
元素的子元素。
tr
和 支持脚本 元素。tfoot
元素的 结束标签。HTMLTableSectionElement
,如
tbody
元素中定义的。
tfoot
元素
表示由列摘要(表尾)组成的 块的 行,前提是 tfoot
元素有一个父元素并且它是一个 table
。
tr
元素在所有当前引擎中支持。
在所有当前引擎中支持。
thead
元素的子元素。tbody
元素的子元素。tfoot
元素的子元素。table
元素的子元素,在任何 caption
、colgroup
和 thead
元素之后,但前提是没有 tbody
元素是
table
元素的子元素。
td
、th
和 支持脚本 元素。tr
元素后面紧跟着另一个 tr
元素,或者父元素中没有更多内容,则可以省略 结束标签。
[Exposed =Window ]
interface HTMLTableRowElement : HTMLElement {
[HTMLConstructor ] constructor ();
readonly attribute long rowIndex ;
readonly attribute long sectionRowIndex ;
[SameObject ] readonly attribute HTMLCollection cells ;
HTMLTableCellElement insertCell (optional long index = -1);
[CEReactions ] undefined deleteCell (long index );
// also has obsolete members
};
tr
元素 表示表格中的一个 行,该行由表格中的
单元格 组成。
tr.rowIndex
在所有当前引擎中支持。
返回该行在表格 rows
列表中的位置。
如果该元素不在表格中,则返回 −1。
tr.sectionRowIndex
返回该行在表格节的 rows
列表中的位置。
如果该元素不在表格节中,则返回 −1。
tr.cells
返回一个 HTMLCollection
,其中包含该行的
td
和 th
元素。
cell = tr.insertCell([ index ])
HTMLTableRowElement/insertCell
在所有当前引擎中支持。
创建一个 td
元素,将其插入到表格行中的给定位置,并返回 td
。
位置相对于行中的单元格。如果省略参数,默认值 -1 等同于插入到行的末尾。
如果给定的位置小于 -1 或大于单元格数量,则抛出 "IndexSizeError
" DOMException
。
tr.deleteCell(index)
位置相对于行中的单元格。索引 -1 等同于删除行的最后一个单元格。
如果给定的位置小于 -1 或大于最后一个单元格的索引,或者如果没有单元格,则抛出 "IndexSizeError
" DOMException
。
rowIndex
属性必须,如果该元素有一个父 table
元素,或者一个父 tbody
、thead
或
tfoot
元素和一个 祖父 table
元素,返回该
tr
元素在该 table
元素的
rows
集合中的索引。如果没有这样的 table
元素,则属性必须返回 -1。
sectionRowIndex
属性必须,如果该元素有一个父 table
、tbody
、thead
或
tfoot
元素,返回该 tr
元素在父元素的 rows
集合中的索引(对于表格,这是 HTMLTableElement
的 rows
集合;对于表格节,这是 HTMLTableSectionElement
的 rows
集合)。如果没有这样的父元素,则属性必须返回 -1。
cells
属性必须返回一个根植于该 tr
元素的 HTMLCollection
,其过滤器仅匹配作为该元素子元素的
td
和 th
元素。
insertCell(index)
方法必须按如下方式操作:
如果 index 小于 -1 或大于 cells
集合中的元素数量,则抛出
"IndexSizeError
" DOMException
。
如果 index 等于 -1 或等于 cells
集合中的项目
数量,则将 table cell 附加 到该 tr
元素。
否则,将 table cell 插入 作为该 tr
元素的子元素,紧挨着
td
或 th
元素在 cells
集合中的第
index 个元素之前。
返回 table cell。
deleteCell(index)
方法必须按如下方式操作:
如果 index 小于 -1 或大于等于 cells
集合中的元素数量,则抛出
"IndexSizeError
" DOMException
。
如果 index 为 -1,则从其父元素中 移除 cells
集合中的最后一个元素,或者如果 cells
集合为空,则不执行任何操作。
td
元素在所有当前引擎中支持。
在所有当前引擎中支持。
tr
元素的子元素。td
元素后面紧跟着另一个 td
或 th
元素,或者父元素中没有更多内容,则可以省略 结束标签。
colspan
—
单元格跨越的列数rowspan
—
单元格跨越的行数headers
—
该单元格的表头单元格[Exposed =Window ]
interface HTMLTableCellElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute unsigned long colSpan ;
[CEReactions ] attribute unsigned long rowSpan ;
[CEReactions ] attribute DOMString headers ;
readonly attribute long cellIndex ;
[CEReactions ] attribute DOMString scope ; // only conforming for th elements
[CEReactions ] attribute DOMString abbr ; // only conforming for th elements
// also has obsolete members
};
HTMLTableCellElement
接口也用于 th
元素。
td
元素及其 colspan
、rowspan
和
headers
属性参与 表模型。
用户代理,尤其是在非视觉环境中或在显示表格为二维网格不切实际的情况下,可能会在渲染单元格内容时为用户提供单元格的上下文;例如,给出其在 表模型 中的位置,或列出单元格的表头单元格(由 分配表头单元格的算法 确定)。当列出单元格的表头单元格时,用户代理可以使用这些表头单元格上的 abbr
属性值(如果有),而不是表头单元格的内容。
在这个例子中,我们看到一个由可编辑单元格组成的网格(本质上是一个简单的电子表格)的网页应用片段。一个单元格被配置为显示其上方单元格的总和。三个单元格被标记为表头,使用 th
元素而不是 td
元素。一个脚本会附加事件处理程序到这些元素上以维护总数。
< table >
< tr >
< th >< input value = "Name" >
< th >< input value = "Paid ($)" >
< tr >
< td >< input value = "Jeff" >
< td >< input value = "14" >
< tr >
< td >< input value = "Britta" >
< td >< input value = "9" >
< tr >
< td >< input value = "Abed" >
< td >< input value = "25" >
< tr >
< td >< input value = "Shirley" >
< td >< input value = "2" >
< tr >
< td >< input value = "Annie" >
< td >< input value = "5" >
< tr >
< td >< input value = "Troy" >
< td >< input value = "5" >
< tr >
< td >< input value = "Pierce" >
< td >< input value = "1000" >
< tr >
< th >< input value = "Total" >
< td >< output value = "1060" >
</ table >
th
元素在所有当前引擎中支持。
tr
元素的子元素。header
,footer
,分节内容或标题内容的后代元素。th
元素后面紧跟着一个 td
或
th
元素,或父元素中没有更多内容,则可以省略 结束标签。
colspan
—
单元格跨越的列数rowspan
—
单元格跨越的行数headers
—
该单元格的表头单元格scope
—
指定表头单元格应用于哪些单元格abbr
—
在其他上下文中引用该单元格时使用的替代标签HTMLTableCellElement
,如
td
元素所定义。
th
元素可以指定一个
scope
内容属性。
关键字 | 状态 | 简短描述 |
---|---|---|
row |
row | 表头单元格适用于同一行中的一些后续单元格。 |
col |
column | 表头单元格适用于同一列中的一些后续单元格。 |
rowgroup |
row group | 表头单元格适用于行组中的所有剩余单元格。 |
colgroup |
column group | 表头单元格适用于列组中的所有剩余单元格。 |
属性的 缺失值默认 和 无效值默认 都是 自动 状态。(在此状态下,表头单元格适用于基于上下文选择的一组单元格。)
如果元素未锚定在 行组 中,则 th
元素的 scope
属性不得处于 行组
状态;如果元素未锚定在 列组
中,则不得处于 列组 状态。
th
元素可以指定一个
abbr
内容属性。其值必须是表头单元格的替代标签,用于在其他上下文中引用该单元格(例如在描述适用于数据单元格的表头单元格时)。它通常是完整表头单元格的缩写形式,但也可以是扩展形式,或只是不同的措辞。
th
元素及其 colspan
,rowspan
,headers
和
scope
属性参与 表模型。
以下示例展示了 scope
属性的 rowgroup
值如何影响表头单元格适用的数据单元格。
这是一个显示表格的标记片段:
< table >
< thead >
< tr > < th > ID < th > Measurement < th > Average < th > Maximum
< tbody >
< tr > < td > < th scope = rowgroup > Cats < td > < td >
< tr > < td > 93 < th > Legs < td > 3.5 < td > 4
< tr > < td > 10 < th > Tails < td > 1 < td > 1
< tbody >
< tr > < td > < th scope = rowgroup > English speakers < td > < td >
< tr > < td > 32 < th > Legs < td > 2.67 < td > 4
< tr > < td > 35 < th > Tails < td > 0.33 < td > 1
</ table >
这将生成如下表格:
ID | Measurement | Average | Maximum |
---|---|---|---|
Cats | |||
93 | Legs | 3.5 | 4 |
10 | Tails | 1 | 1 |
English speakers | |||
32 | Legs | 2.67 | 4 |
35 | Tails | 0.33 | 1 |
第一行的表头直接适用于其列中的行。
具有 scope
属性且值为 rowgroup
的表头适用于其行组中的所有单元格,除了第一列中的单元格。
剩余的表头仅适用于它们右侧的单元格。
td
和th
元素的共有属性td
和th
元素可以有一个colspan
内容属性,该属性的值必须是大于零且小于或等于1000的有效非负整数。
td
和th
元素还可以有一个rowspan
内容属性,该属性的值必须是小于或等于65534的有效非负整数。对于该属性,值为零表示单元格将跨越行组中的所有剩余行。
这些属性分别给出了单元格要跨越的列数和行数。如表模型描述的那样,这些属性不得用于重叠单元格。
td
和th
元素可以有一个headers
内容属性。如果指定了headers
属性,其值必须包含一个字符串,该字符串由唯一的空格分隔的标记组成,这些标记的值必须是与td
或th
元素(如表模型所定义)在同一表中的th
元素的ID。
具有ID id的th
元素被认为是同一表中所有具有headers
属性且其值包含该ID的td
和th
元素直接目标。如果存在一个元素C,它本身被元素B作为目标,而A被C直接作为目标,则元素A被认为是被元素B作为目标。
th
元素不得自目标自身。
colspan
、rowspan
和headers
属性参与表模型。
cell.cellIndex
返回单元格在行的cells
列表中的位置。这不一定对应单元格在表中的x位置,因为前面的单元格可能覆盖了多个行或列。
如果元素不在行中,则返回-1。
colSpan
IDL属性必须反映内容属性colspan
。它被限制在范围[1,
1000],其默认值为1。
rowSpan
IDL属性必须反映内容属性rowspan
。它被限制在范围[0,
65534],其默认值为1。
headers
IDL属性必须反映相同名称的内容属性。
cellIndex
IDL属性必须在该元素有一个父tr
元素时,返回该单元格元素在父元素的cells
集合中的索引。如果没有这样的父元素,则该属性必须返回-1。
scope
IDL属性必须反映相同名称的内容属性,仅限于已知值。
abbr
IDL属性必须反映相同名称的内容属性。
各种表格元素及其内容属性共同定义了表模型。
一个表格由在二维网格槽上的对齐单元格组成,具有坐标(x,
y)。网格是有限的,并且是空的或有一个或多个槽。如果网格有一个或多个槽,则x坐标始终在范围0 ≤ x
< xwidth
,y坐标始终在范围0 ≤ y
< yheight
内。如果xwidth和yheight之一或两者为零,则该表为空(没有槽)。表对应于table
元素。
一个单元格是锚定在槽(cellx,
celly)上的一组槽,并具有特定的width和height,使单元格覆盖所有具有坐标(x,
y)的槽,其中cellx ≤ x
< cellx+width
和celly ≤ y
< celly+height。单元格可以是数据单元格或标题单元格。数据单元格对应于td
元素,标题单元格对应于th
元素。两种类型的单元格都可以有零个或多个关联的标题单元格。
在某些错误情况下,可能会出现两个单元格占据同一个槽的情况。
一个行是从x=0到x=xwidth-1的完整槽集,对于特定的y值。行通常对应于tr
元素,尽管在某些涉及跨越多行的单元格情况下,行组的末尾可能有一些隐含的行。
一个列是从y=0到y=yheight-1的完整槽集,对于特定的x值。列可以对应于col
元素。如果没有col
元素,则列是隐含的。
行组是一组锚定在位置 (0, groupy) 具有特定 height 的行,使得行组覆盖所有坐标
(x, y) 的槽,其中
0 ≤ x < xwidth 和
groupy ≤ y < groupy+height。行组对应于
tbody
、thead
和 tfoot
元素。并非每一行都必须在一个行组中。
列组是一组锚定在位置 (groupx, 0) 具有特定 width 的列,使得列组覆盖所有坐标
(x, y) 的槽,其中
groupx ≤ x < groupx+width
和 0 ≤ y < yheight。列组对应于 colgroup
元素。并非每一列都必须在一个列组中。
一个单元格不能覆盖两个或多个行组的槽。然而,一个单元格可以位于多个列组中。一个单元格的所有槽要么是零个,要么是一个行组的一部分,并且是零个或多个列组的一部分。
除了单元格、列、行、行组和列组,表格可以有一个caption
元素与之关联。这为表格提供了标题或说明。
表模型错误是指由table
元素及其后代表示的数据错误。文档中不应有表模型错误。
为了确定哪些元素对应于与table
元素关联的表格中的哪些槽,确定表格的尺寸(xwidth和yheight),以及确定是否存在表模型错误,用户代理必须使用以下算法:
令xwidth为零。
令yheight为零。
令the table为由table
元素表示的表格。xwidth和yheight变量给出了the
table的尺寸。the table最初是空的。
如果table
元素没有子元素,则返回the
table(它将是空的)。
令current element为table
元素的第一个子元素。
如果算法中的某个步骤需要将current element 推进到table
的下一个子元素,而没有这样的下一个子元素,那么用户代理必须跳到算法结尾附近标记为end的步骤。
如果current element是colgroup
,请按照以下子步骤进行:
列组:根据下面的适当情况处理current element:
col
元素子元素
按照以下步骤进行:
令xstart的值为xwidth。
列:如果current column col
元素具有span
属性,则使用解析非负整数的规则解析其值。
如果解析结果不是错误或零,则令span为该值。
否则,如果col
元素没有span
属性,或者尝试解析属性的值导致错误或零,则令span为1。
如果span大于1000,则令其为1000。
将xwidth增加span。
让the table中的最后span列对应于current column col
元素。
如果current column不是colgroup
元素的最后一个col
元素子元素,则令current
column为colgroup
元素的下一个col
元素子元素,并返回到标记为列的步骤。
让所有从 x=xstart 到 x=xwidth-1
的最后 列 在
the table 中形成一个新的 列组,锚定在位置 (xstart, 0),宽度为
xwidth-xstart,对应于 colgroup
元素。
col
元素子元素
如果current element是colgroup
元素,跳到上面标记为列组的步骤。
令ycurrent为零。
令list of downward-growing cells为空列表。
行:当current element不是以下元素之一时,将current element 推进到table
的下一个子元素:
如果current element是tr
,则运行行处理算法,将current element 推进到table
的下一个子元素,并返回到标记为行的步骤。
运行行组结束算法。
如果current element是tfoot
,则将该元素添加到pending
tfoot
元素列表中,将current
element 推进到table
的下一个子元素,并返回到标记为行的步骤。
当前元素current element是thead
或tbody
。
运行行组处理算法。
返回到标记为行的步骤。
返回the table。
上面的步骤集中调用的行组处理算法是:
令ystart的值为yheight。
如果 yheight > ystart,那么让所有从 y=ystart 到 y=yheight-1 的最后 行 在 the table 中形成一个新的 行组,锚定在坐标 (0, ystart) 的位置,高度为 yheight-ystart,对应于正在处理的元素。
运行行组结束算法。
当上述算法要求用户代理运行行组结束算法时,用户代理必须遵循以下步骤:
当ycurrent小于yheight时,执行以下步骤:
运行向下生长的单元算法。
将ycurrent增加1。
清空list of downward-growing cells。
上述算法调用的行处理算法是:
如果yheight等于ycurrent,则将yheight增加1。(ycurrent从不大于yheight。)
令xcurrent为0。
运行向下生长的单元算法。
单元格:当xcurrent小于xwidth且坐标为(xcurrent, ycurrent)的槽已经有单元格分配给它时,将xcurrent增加1。
如果xcurrent等于xwidth,则将xwidth增加1。(xcurrent从不大于xwidth。)
如果current cell有colspan
属性,则解析该属性的值,并令colspan为结果。
如果解析该值失败或返回零,或者该属性不存在,则令colspan为1。
如果colspan大于1000,则令其为1000。
如果current cell有rowspan
属性,则解析该属性的值,并令rowspan为结果。
如果解析该值失败或该属性不存在,则令rowspan为1。
如果rowspan大于65534,则令其为65534。
如果rowspan为零且table
元素的节点文档未设置为怪癖模式,则令cell
grows downward为真,并将rowspan设置为1。否则,令cell grows downward为假。
如果xwidth < xcurrent+colspan,则令xwidth为xcurrent+colspan。
如果yheight < ycurrent+rowspan,则令yheight为ycurrent+rowspan。
让坐标为(x, y)的槽覆盖由新单元c覆盖,其锚点为(xcurrent, ycurrent),宽度为colspan,高度为rowspan,对应于current cell元素。
如果current cell元素是th
元素,则让这个新单元c为一个标题单元格;否则,让它为一个数据单元格。
要确定哪些标题单元格适用于current cell元素,请使用下一节中描述的分配标题单元格的算法。
如果cell grows downward为真,则将元组{c, xcurrent, colspan}添加到list of downward-growing cells。
将xcurrent增加colspan。
如果current cell是正在处理的tr
元素中的最后一个td
或th
元素子元素,则将ycurrent增加1,中止此步骤集,并返回到上面的算法。
返回到标记为单元格的步骤。
当上述算法要求用户代理运行向下生长的单元算法时,用户代理必须对list of downward-growing cells中的每个{cell, cellx, width}元组,如果有,将单元cell扩展,以便它还覆盖坐标为(x, ycurrent)的槽,其中cellx ≤ x < cellx+width。
每个单元格可以分配零个或多个标题单元格。将标题单元格分配算法分配给单元格principal cell的过程如下。
令header list为空单元格列表。
令(principalx, principaly)为principal cell锚定的槽的坐标。
headers
属性
取principal cell的headers
属性值并按ASCII空白字符分割,得到id list。
对于id list中的每个令牌,如果文档
中第一个ID等于该令牌的元素是同一表格中的单元格,并且该单元格不是principal
cell,则将该单元格添加到header
list。
headers
属性
令principalwidth为principal cell的宽度。
令principalheight为principal cell的高度。
对于从principaly到principaly+principalheight-1的每个y值,运行扫描和分配标题单元格的内部算法,使用principal cell、header list、初始坐标(principalx, y)和增量Δx=−1和Δy=0。
对于从principalx到principalx+principalwidth-1的每个x值,运行扫描和分配标题单元格的内部算法,使用principal cell、header list、初始坐标(x, principaly)和增量Δx=0和Δy=−1。
如果principal cell锚定在一个行组中,则将所有在同一行组中锚定并且x坐标小于或等于principalx+principalwidth-1且y坐标小于或等于principaly+principalheight-1的行组标题单元格添加到header list中。
如果principal cell锚定在一个列组中,则将所有在同一列组中锚定并且x坐标小于或等于principalx+principalwidth-1且y坐标小于或等于principaly+principalheight-1的列组标题单元格添加到header list中。
从header list中移除所有空单元格。
从header list中移除所有重复项。
如果principal cell在header list中,则将其移除。
将header list中的标题分配给principal cell。
扫描和分配标题单元格的内部算法,给定一个principal cell、一个header list、初始坐标(initialx, initialy)和Δx和Δy增量,过程如下:
令x等于initialx。
令y等于initialy。
令opaque headers为空单元格列表。
令in header block为true,并令headers from current header block为包含principal cell的单元格列表。
令in header block为false,并令headers from current header block为空单元格列表。
循环:将x增加Δx;将y增加Δy。
对于此算法的每次调用,Δx和Δy中的一个将为-1,另一个将为0。
如果x或y小于0,则中止此内部算法。
如果没有单元格覆盖槽(x, y),或者有多个单元格覆盖槽(x, y),则返回到标记为循环的子步骤。
令current cell为覆盖槽(x, y)的单元格。
设置in header block为true。
将current cell添加到headers from current header block中。
令blocked为false。
如果blocked为false,则将current cell添加到header list中。
设置in header block为false。将headers from current header block中的所有单元格添加到opaque headers列表中,并清空headers from current header block列表。
返回到标记为循环的步骤。
锚定在坐标(x, y)、宽度为width、高度为height的槽上的标题单元格,如果符合以下任一条件,则称为列标题:
锚定在坐标(x, y)、宽度为width、高度为height的槽上的标题单元格,如果符合以下任一条件,则称为行标题:
如果其scope
属性处于列组状态,则该标题单元格称为列组标题。
如果其scope
属性处于行组状态,则该标题单元格称为行组标题。
如果单元格不包含任何元素,并且其子文本内容(如果有的话)仅由ASCII空白字符组成,则称为空单元格。
本节为非规范性内容。
以下显示了如何标记《史密森物理表,第71卷》表45的底部部分:
< table >
< caption > Specification values: < b > Steel</ b > , < b > Castings</ b > ,
Ann. A.S.T.M. A27-16, Class B;* P max. 0.06; S max. 0.05.</ caption >
< thead >
< tr >
< th rowspan = 2 > Grade.</ th >
< th rowspan = 2 > Yield Point.</ th >
< th colspan = 2 > Ultimate tensile strength</ th >
< th rowspan = 2 > Per cent elong. 50.8 mm or 2 in.</ th >
< th rowspan = 2 > Per cent reduct. area.</ th >
</ tr >
< tr >
< th > kg/mm< sup > 2</ sup ></ th >
< th > lb/in< sup > 2</ sup ></ th >
</ tr >
</ thead >
< tbody >
< tr >
< td > Hard</ td >
< td > 0.45 ultimate</ td >
< td > 56.2</ td >
< td > 80,000</ td >
< td > 15</ td >
< td > 20</ td >
</ tr >
< tr >
< td > Medium</ td >
< td > 0.45 ultimate</ td >
< td > 49.2</ td >
< td > 70,000</ td >
< td > 18</ td >
< td > 25</ td >
</ tr >
< tr >
< td > Soft</ td >
< td > 0.45 ultimate</ td >
< td > 42.2</ td >
< td > 60,000</ td >
< td > 22</ td >
< td > 30</ td >
</ tr >
</ tbody >
</ table >
该表可能如下所示:
等级。 | 屈服点。 | 极限抗拉强度 | 延伸率。50.8 mm或 2 英寸。 | 截面收缩率。 | |
---|---|---|---|---|---|
kg/mm2 | lb/in2 | ||||
硬 | 0.45 极限 | 56.2 | 80,000 | 15 | 20 |
中 | 0.45 极限 | 49.2 | 70,000 | 18 | 25 |
软 | 0.45 极限 | 42.2 | 60,000 | 22 | 30 |
以下显示了如何标记Apple, Inc. 2008财年10-K文件第46页上的毛利表:
< table >
< thead >
< tr >
< th >
< th > 2008
< th > 2007
< th > 2006
< tbody >
< tr >
< th > Net sales
< td > $ 32,479
< td > $ 24,006
< td > $ 19,315
< tr >
< th > Cost of sales
< td > 21,334
< td > 15,852
< td > 13,717
< tbody >
< tr >
< th > Gross margin
< td > $ 11,145
< td > $ 8,154
< td > $ 5,598
< tfoot >
< tr >
< th > Gross margin percentage
< td > 34.3%
< td > 34.0%
< td > 29.0%
</ table >
该表可能如下所示:
2008 | 2007 | 2006 | |
---|---|---|---|
净销售额 | $ 32,479 | $ 24,006 | $ 19,315 |
销售成本 | 21,334 | 15,852 | 13,717 |
毛利 | $ 11,145 | $ 8,154 | $ 5,598 |
毛利率 | 34.3% | 34.0% | 29.0% |
以下显示了如何标记同一文件页下方的运营费用表:
< table >
< colgroup > < col >
< colgroup > < col > < col > < col >
< thead >
< tr > < th > < th > 2008 < th > 2007 < th > 2006
< tbody >
< tr > < th scope = rowgroup > Research and development
< td > $ 1,109 < td > $ 782 < td > $ 712
< tr > < th scope = row > Percentage of net sales
< td > 3.4% < td > 3.3% < td > 3.7%
< tbody >
< tr > < th scope = rowgroup > Selling, general, and administrative
< td > $ 3,761 < td > $ 2,963 < td > $ 2,433
< tr > < th scope = row > Percentage of net sales
< td > 11.6% < td > 12.3% < td > 12.6%
</ table >
该表可能如下所示:
2008 | 2007 | 2006 | |
---|---|---|---|
研发 | $ 1,109 | $ 782 | $ 712 |
净销售额百分比 | 3.4% | 3.3% | 3.7% |
销售、一般和行政 | $ 3,761 | $ 2,963 | $ 2,433 |
净销售额百分比 | 11.6% | 12.3% | 12.6% |
所有当前引擎均支持。
本节为非规范性内容。
表单是网页的一个组件,包含表单控件,如文本框、按钮、复选框、范围选择器或颜色选择器控件。用户可以与这些表单进行交互,提供数据,然后可以将这些数据发送到服务器进行进一步处理(例如返回搜索或计算的结果)。在许多情况下,不需要客户端脚本,尽管提供了一个API,以便脚本可以增强用户体验或将表单用于提交数据到服务器以外的目的。
编写表单包括几个步骤,这些步骤可以按任何顺序执行:编写用户界面、实现服务器端处理以及配置用户界面与服务器通信。
本节为非规范性内容。
为了简单介绍,我们将创建一个披萨订购表单。
任何表单都从一个form
元素开始,控件放在其中。大多数控件由input
元素表示,该元素默认提供文本控件。要为控件添加标签,使用label
元素;标签文本和控件本身放在label
元素内。表单的每个部分都被视为一个段落,通常使用p
元素与其他部分分隔。结合这些元素,下面是如何询问客户姓名的示例:
< form >
< p >< label > Customer name: < input ></ label ></ p >
</ form >
为了让用户选择披萨的大小,我们可以使用一组单选按钮。单选按钮也使用input
元素,这次带有值为type
属性为radio
。为了使单选按钮作为一组工作,它们使用name
属性赋予一个共同的名称。为了将一批控件组合在一起,例如在这种情况下的单选按钮,可以使用fieldset
元素。这样一组控件的标题由fieldset
中的第一个元素给出,该元素必须是legend
元素。
< form >
< p >< label > Customer name: < input ></ label ></ p >
< fieldset >
< legend > Pizza Size </ legend >
< p >< label > < input type = radio name = size > Small </ label ></ p >
< p >< label > < input type = radio name = size > Medium </ label ></ p >
< p >< label > < input type = radio name = size > Large </ label ></ p >
</ fieldset >
</ form >
从上一步的变化已突出显示。
为了选择配料,我们可以使用复选框。这些使用input
元素,其type
属性值为checkbox
:
< form >
< p >< label > Customer name: < input ></ label ></ p >
< fieldset >
< legend > Pizza Size </ legend >
< p >< label > < input type = radio name = size > Small </ label ></ p >
< p >< label > < input type = radio name = size > Medium </ label ></ p >
< p >< label > < input type = radio name = size > Large </ label ></ p >
</ fieldset >
< fieldset >
< legend > Pizza Toppings </ legend >
< p >< label > < input type = checkbox > Bacon </ label ></ p >
< p >< label > < input type = checkbox > Extra Cheese </ label ></ p >
< p >< label > < input type = checkbox > Onion </ label ></ p >
< p >< label > < input type = checkbox > Mushroom </ label ></ p >
</ fieldset >
</ form >
这个披萨店总是出错,所以需要一种方法联系客户。为此,我们可以使用专门用于电话号码的表单控件(input
元素,其type
属性设置为tel
)和电子邮件地址(input
元素,其type
属性设置为email
):
< form >
< p >< label > Customer name: < input ></ label ></ p >
< p >< label > Telephone: < input type = tel ></ label ></ p >
< p >< label > Email address: < input type = email ></ label ></ p >
< fieldset >
< legend > Pizza Size </ legend >
< p >< label > < input type = radio name = size > Small </ label ></ p >
< p >< label > < input type = radio name = size > Medium </ label ></ p >
< p >< label > < input type = radio name = size > Large </ label ></ p >
</ fieldset >
< fieldset >
< legend > Pizza Toppings </ legend >
< p >< label > < input type = checkbox > Bacon </ label ></ p >
< p >< label > < input type = checkbox > Extra Cheese </ label ></ p >
< p >< label > < input type = checkbox > Onion </ label ></ p >
< p >< label > < input type = checkbox > Mushroom </ label ></ p >
</ fieldset >
</ form >
我们可以使用input
元素,其type
属性设置为time
来询问送货时间。许多这些表单控件都有属性来精确控制可以指定的值;在这种情况下,特别感兴趣的三个属性是min
,max
和step
。这些设置了最小时间、最大时间和允许值之间的间隔(以秒为单位)。这家披萨店只在上午11点到晚上9点之间送货,不承诺超过15分钟的增量,可以如下标记:
< form >
< p >< label > Customer name: < input ></ label ></ p >
< p >< label > Telephone: < input type = tel ></ label ></ p >
< p >< label > Email address: < input type = email ></ label ></ p >
< fieldset >
< legend > Pizza Size </ legend >
< p >< label > < input type = radio name = size > Small </ label ></ p >
< p >< label > < input type = radio name = size > Medium </ label ></ p >
< p >< label > < input type = radio name = size > Large </ label ></ p >
</ fieldset >
< fieldset >
< legend > Pizza Toppings </ legend >
< p >< label > < input type = checkbox > Bacon </ label ></ p >
< p >< label > < input type = checkbox > Extra Cheese </ label ></ p >
< p >< label > < input type = checkbox > Onion </ label ></ p >
< p >< label > < input type = checkbox > Mushroom </ label ></ p >
</ fieldset >
< p >< label > Preferred delivery time: < input type = time min = "11:00" max = "21:00" step = "900" ></ label ></ p >
</ form >
textarea
元素可用于提供多行文本控件。在这种情况下,我们将使用它为客户提供一个填写送货说明的空间:
< form >
< p >< label > Customer name: < input ></ label ></ p >
< p >< label > Telephone: < input type = tel ></ label ></ p >
< p >< label > Email address: < input type = email ></ label ></ p >
< fieldset >
< legend > Pizza Size </ legend >
< p >< label > < input type = radio name = size > Small </ label ></ p >
< p >< label > < input type = radio name = size > Medium </ label ></ p >
< p >< label > < input type = radio name = size > Large </ label ></ p >
</ fieldset >
< fieldset >
< legend > Pizza Toppings </ legend >
< p >< label > < input type = checkbox > Bacon </ label ></ p >
< p >< label > < input type = checkbox > Extra Cheese </ label ></ p >
< p >< label > < input type = checkbox > Onion </ label ></ p >
< p >< label > < input type = checkbox > Mushroom </ label ></ p >
</ fieldset >
< p >< label > Preferred delivery time: < input type = time min = "11:00" max = "21:00" step = "900" ></ label ></ p >
< p >< label > Delivery instructions: < textarea ></ textarea ></ label ></ p >
</ form >
最后,为了使表单可提交,我们使用button
元素:
< form >
< p >< label > Customer name: < input ></ label ></ p >
< p >< label > Telephone: < input type = tel ></ label ></ p >
< p >< label > Email address: < input type = email ></ label ></ p >
< fieldset >
< legend > Pizza Size </ legend >
< p >< label > < input type = radio name = size > Small </ label ></ p >
< p >< label > < input type = radio name = size > Medium </ label ></ p >
< p >< label > < input type = radio name = size > Large </ label ></ p >
</ fieldset >
< fieldset >
< legend > Pizza Toppings </ legend >
< p >< label > < input type = checkbox > Bacon </ label ></ p >
< p >< label > < input type = checkbox > Extra Cheese </ label ></ p >
< p >< label > < input type = checkbox > Onion </ label ></ p >
< p >< label > < input type = checkbox > Mushroom </ label ></ p >
</ fieldset >
< p >< label > Preferred delivery time: < input type = time min = "11:00" max = "21:00" step = "900" ></ label ></ p >
< p >< label > Delivery instructions: < textarea ></ textarea ></ label ></ p >
< p >< button > Submit order</ button ></ p >
</ form >
本节为非规范性内容。
编写服务器端处理器的具体细节不在本规范范围内。为了介绍的目的,我们假设https://pizza.example.com/order.cgi
上的脚本配置为接受使用application/x-www-form-urlencoded
格式的提交,期望在HTTP
POST主体中发送以下参数:
custname
custtel
custemail
size
small
,medium
或large
topping
bacon
,cheese
,onion
和mushroom
delivery
comments
本节为非规范性内容。
表单提交通过多种方式暴露给服务器,最常见的是HTTP GET或POST请求。为了指定使用的具体方法,在method
属性中进行指定。这并不指定表单数据的编码方式;要指定这个,需要使用enctype
属性。还必须使用action
属性指定将处理提交数据的服务的URL。
对于每个要提交的表单控件,必须给出一个名称,以便在提交中引用该数据。我们已经为一组单选按钮指定了名称;同样的属性(name
)也指定了提交名称。通过为单选按钮提供不同的值(使用value
属性),可以在提交中将它们区分开。
多个控件可以具有相同的名称;例如,这里我们给所有复选框相同的名称,服务器通过查看以该名称提交的值来区分哪个复选框被选中——就像单选按钮一样,它们也使用value
属性给出了唯一的值。
根据上一节中的设置,这些都变成:
< form method = "post"
enctype = "application/x-www-form-urlencoded"
action = "https://pizza.example.com/order.cgi" >
< p >< label > Customer name: < input name = "custname" ></ label ></ p >
< p >< label > Telephone: < input type = tel name = "custtel" ></ label ></ p >
< p >< label > Email address: < input type = email name = "custemail" ></ label ></ p >
< fieldset >
< legend > Pizza Size </ legend >
< p >< label > < input type = radio name = size value = "small" > Small </ label ></ p >
< p >< label > < input type = radio name = size value = "medium" > Medium </ label ></ p >
< p >< label > < input type = radio name = size value = "large" > Large </ label ></ p >
</ fieldset >
< fieldset >
< legend > Pizza Toppings </ legend >
< p >< label > < input type = checkbox name = "topping" value = "bacon" > Bacon </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "cheese" > Extra Cheese </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "onion" > Onion </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "mushroom" > Mushroom </ label ></ p >
</ fieldset >
< p >< label > Preferred delivery time: < input type = time min = "11:00" max = "21:00" step = "900" name = "delivery" ></ label ></ p >
< p >< label > Delivery instructions: < textarea name = "comments" ></ textarea ></ label ></ p >
< p >< button > Submit order</ button ></ p >
</ form >
某些属性的值带引号而其他的不带引号,并没有特别的意义。HTML语法允许多种同样有效的方式来指定属性,如语法部分讨论的那样。
例如,如果顾客输入“Denise Lawrence”作为姓名,“555-321-8642”作为电话号码,没有指定电子邮件地址,选择了中号披萨,选择了额外的奶酪和蘑菇配料,输入了晚上7点的送货时间,并且将送货说明文本控件留空,用户代理将向在线网络服务提交以下内容:
custname=Denise+Lawrence&custtel=555-321-8642&custemail=&size=medium&topping=cheese&topping=mushroom&delivery=19%3A00&comments=
Support in all current engines.
本节为非规范性内容。
表单可以进行注释,以便用户代理在表单提交之前检查用户的输入。服务器仍然需要验证输入是否有效(因为恶意用户可以轻松绕过表单验证),但这允许用户避免仅由服务器检查用户输入所带来的等待。
最简单的注释是required
属性,可以在input
元素上指定,以表明在给出值之前不提交表单。通过将此属性添加到客户姓名、披萨大小和送货时间字段,当用户在未填写这些字段的情况下提交表单时,用户代理会通知用户:
< form method = "post"
enctype = "application/x-www-form-urlencoded"
action = "https://pizza.example.com/order.cgi" >
< p >< label > Customer name: < input name = "custname" required ></ label ></ p >
< p >< label > Telephone: < input type = tel name = "custtel" ></ label ></ p >
< p >< label > Email address: < input type = email name = "custemail" ></ label ></ p >
< fieldset >
< legend > Pizza Size </ legend >
< p >< label > < input type = radio name = size required value = "small" > Small </ label ></ p >
< p >< label > < input type = radio name = size required value = "medium" > Medium </ label ></ p >
< p >< label > < input type = radio name = size required value = "large" > Large </ label ></ p >
</ fieldset >
< fieldset >
< legend > Pizza Toppings </ legend >
< p >< label > < input type = checkbox name = "topping" value = "bacon" > Bacon </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "cheese" > Extra Cheese </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "onion" > Onion </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "mushroom" > Mushroom </ label ></ p >
</ fieldset >
< p >< label > Preferred delivery time: < input type = time min = "11:00" max = "21:00" step = "900" name = "delivery" required ></ label ></ p >
< p >< label > Delivery instructions: < textarea name = "comments" ></ textarea ></ label ></ p >
< p >< button > Submit order</ button ></ p >
</ form >
还可以使用maxlength
属性来限制输入的长度。通过将此属性添加到textarea
元素,我们可以将用户限制为1000个字符,防止他们写出大量的文章而不是简明扼要的送货说明:
< form method = "post"
enctype = "application/x-www-form-urlencoded"
action = "https://pizza.example.com/order.cgi" >
< p >< label > Customer name: < input name = "custname" required ></ label ></ p >
< p >< label > Telephone: < input type = tel name = "custtel" ></ label ></ p >
< p >< label > Email address: < input type = email name = "custemail" ></ label ></ p >
< fieldset >
< legend > Pizza Size </ legend >
< p >< label > < input type = radio name = size required value = "small" > Small </ label ></ p >
< p >< label > < input type = radio name = size required value = "medium" > Medium </ label ></ p >
< p >< label > < input type = radio name = size required value = "large" > Large </ label ></ p >
</ fieldset >
< fieldset >
< legend > Pizza Toppings </ legend >
< p >< label > < input type = checkbox name = "topping" value = "bacon" > Bacon </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "cheese" > Extra Cheese </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "onion" > Onion </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "mushroom" > Mushroom </ label ></ p >
</ fieldset >
< p >< label > Preferred delivery time: < input type = time min = "11:00" max = "21:00" step = "900" name = "delivery" required ></ label ></ p >
< p >< label > Delivery instructions: < textarea name = "comments" maxlength = 1000 ></ textarea ></ label ></ p >
< p >< button > Submit order</ button ></ p >
</ form >
当表单提交时,会在每个无效的表单控件上触发invalid
事件。这对于显示表单问题的摘要很有用,因为通常浏览器本身只会一次报告一个问题。
本节为非规范性内容。
一些浏览器尝试通过自动填充表单控件来帮助用户,而不是每次都让用户重新输入他们的信息。例如,一个请求用户电话号码的字段可以自动填充用户的电话号码。
为了帮助用户代理实现这一点,可以使用autocomplete
属性来描述字段的用途。在此表单的情况下,有三个字段可以这样注释:关于披萨的收件人信息。添加这些信息如下所示:
< form method = "post"
enctype = "application/x-www-form-urlencoded"
action = "https://pizza.example.com/order.cgi" >
< p >< label > Customer name: < input name = "custname" required autocomplete = "shipping name" ></ label ></ p >
< p >< label > Telephone: < input type = tel name = "custtel" autocomplete = "shipping tel" ></ label ></ p >
< p >< label > Email address: < input type = email name = "custemail" autocomplete = "shipping email" ></ label ></ p >
< fieldset >
< legend > Pizza Size </ legend >
< p >< label > < input type = radio name = size required value = "small" > Small </ label ></ p >
< p >< label > < input type = radio name = size required value = "medium" > Medium </ label ></ p >
< p >< label > < input type = radio name = size required value = "large" > Large </ label ></ p >
</ fieldset >
< fieldset >
< legend > Pizza Toppings </ legend >
< p >< label > < input type = checkbox name = "topping" value = "bacon" > Bacon </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "cheese" > Extra Cheese </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "onion" > Onion </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "mushroom" > Mushroom </ label ></ p >
</ fieldset >
< p >< label > Preferred delivery time: < input type = time min = "11:00" max = "21:00" step = "900" name = "delivery" required ></ label ></ p >
< p >< label > Delivery instructions: < textarea name = "comments" maxlength = 1000 ></ textarea ></ label ></ p >
< p >< button > Submit order</ button ></ p >
</ form >
本节为非规范性内容。
某些设备,特别是那些带有虚拟键盘的设备,可以为用户提供多种输入模式。例如,当输入信用卡号码时,用户可能只希望看到数字键(0-9),而在输入他们的名字时,他们可能希望看到默认情况下每个单词首字母大写的表单字段。
使用inputmode
属性,我们可以选择合适的输入模式:
< form method = "post"
enctype = "application/x-www-form-urlencoded"
action = "https://pizza.example.com/order.cgi" >
< p >< label > Customer name: < input name = "custname" required autocomplete = "shipping name" ></ label ></ p >
< p >< label > Telephone: < input type = tel name = "custtel" autocomplete = "shipping tel" ></ label ></ p >
< p >< label > Buzzer code: < input name = "custbuzz" inputmode = "numeric" ></ label ></ p >
< p >< label > Email address: < input type = email name = "custemail" autocomplete = "shipping email" ></ label ></ p >
< fieldset >
< legend > Pizza Size </ legend >
< p >< label > < input type = radio name = size required value = "small" > Small </ label ></ p >
< p >< label > < input type = radio name = size required value = "medium" > Medium </ label ></ p >
< p >< label > < input type = radio name = size required value = "large" > Large </ label ></ p >
</ fieldset >
< fieldset >
< legend > Pizza Toppings </ legend >
< p >< label > < input type = checkbox name = "topping" value = "bacon" > Bacon </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "cheese" > Extra Cheese </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "onion" > Onion </ label ></ p >
< p >< label > < input type = checkbox name = "topping" value = "mushroom" > Mushroom </ label ></ p >
</ fieldset >
< p >< label > Preferred delivery time: < input type = time min = "11:00" max = "21:00" step = "900" name = "delivery" required ></ label ></ p >
< p >< label > Delivery instructions: < textarea name = "comments" maxlength = 1000 ></ textarea ></ label ></ p >
< p >< button > Submit order</ button ></ p >
</ form >
本节为非规范性内容。
type
、autocomplete
和inputmode
属性看起来似乎很相似。例如,在这三种情况下,字符串“email
”都是有效的值。本节试图说明这三个属性之间的区别,并提供如何使用它们的建议。
type
属性在input
元素上决定了用户代理将使用哪种控件来显示该字段。在选择该属性的不同值时,就像在选择是使用input
元素、textarea
元素、select
元素等。
相反,autocomplete
属性描述了用户将输入的值实际代表什么。在选择该属性的不同值时,就像在选择元素的标签是什么。
首先,考虑电话号码。如果一个页面要求用户提供电话号码,那么应该使用的表单控件是<input type=tel>
。但是,使用哪个autocomplete
值取决于页面要求的电话号码是哪种,是国际格式的电话号码还是本地格式的电话号码,等等。
例如,一个电商网站的结账过程中要求用户提供买家的电话号码(以防付款问题)和朋友的电话号码(以防配送问题)。如果网站期望国际电话号码(带国家代码前缀),那么可能如下所示:
< p >< label > Your phone number: < input type = tel name = custtel autocomplete = "billing tel" ></ label >
< p >< label > Recipient's phone number: < input type = tel name = shiptel autocomplete = "shipping tel" ></ label >
< p > Please enter complete phone numbers including the country code prefix, as in "+1 555 123 4567".
但是,如果网站仅支持英国客户和收件人,则可能如下所示(注意使用了tel-national
而不是tel
):
< p >< label > Your phone number: < input type = tel name = custtel autocomplete = "billing tel-national" ></ label >
< p >< label > Recipient's phone number: < input type = tel name = shiptel autocomplete = "shipping tel-national" ></ label >
< p > Please enter complete UK phone numbers, as in "(01632) 960 123".
现在,考虑一个人的首选语言。正确的autocomplete
值是language
。然而,可能有许多不同的表单控件可以用于此目的:文本控件(<input type=text>
),下拉列表(<select>
),单选按钮(<input type=radio>
),等等。这仅取决于所需的界面类型。
最后,考虑名字。如果页面只想从用户那里获取一个名字,那么相关的控件是<input type=text>
。如果页面要求用户的全名,那么相关的autocomplete
值是name
。
< p >< label > Japanese name: < input name = "j" type = "text" autocomplete = "section-jp name" ></ label >
< label > Romanized name: < input name = "e" type = "text" autocomplete = "section-en name" ></ label >
在这个例子中,section-*
关键字在autocomplete
属性的值中告诉用户代理,这两个字段期望不同的名称。如果没有这些关键字,当用户在第一个字段中输入值时,用户代理可能会自动将第一个字段的值填入第二个字段中。
关键词中的"-jp
"和"-en
"部分对用户代理是透明的;用户代理无法从这些部分猜测出两个名字分别应为日语和英语。
除了关于type
和autocomplete
的选择外,inputmode
属性决定了在控件是文本控件时使用何种输入模式(例如,虚拟键盘)。
考虑信用卡号码。适当的输入类型不是<input type=number>
,而是<input type=text>
。为了鼓励用户代理仍然使用数字输入模式(例如,只显示数字的虚拟键盘),页面可以使用
< p >< label > Credit card number:
< input name = "cc" type = "text" inputmode = "numeric" pattern = "[0-9]{8,19}" autocomplete = "cc-number" >
</ label ></ p >
本节是非规范性的。
在这个披萨配送的例子中,时间的格式是“HH:MM”:两个数字表示小时(24小时制),两个数字表示分钟。(秒数也可以指定,但在这个例子中没有必要。)
然而,在某些地区,时间呈现给用户时的格式可能不同。例如,在美国,仍然常用12小时制并带有上午/下午指示,如“2pm”。在法国,常用“h”字符分隔小时和分钟,如“14h00”。
日期也存在类似的问题,此外,日期组件的顺序并不总是一致的——例如,在塞浦路斯,2003年2月1日通常写作“1/2/03”,而在日本,同一日期通常写作“2003年02月01日”——即使是数字,在不同地区使用的标点符号也可能不同,例如作为小数点和千位分隔符的标点符号。
因此,有必要区分HTML和表单提交中使用的时间、日期和数字格式(这些格式始终是本规范中定义的格式,并基于广泛使用的ISO 8601标准,用于计算机可读的日期和时间格式),与浏览器向用户呈现的时间、日期和数字格式以及用户输入的格式。
“在线传输”的格式,即HTML标记和表单提交中的格式,旨在使计算机可读且与用户的区域设置无关。例如,日期总是以“YYYY-MM-DD”的格式书写,如“2003-02-01”。虽然有些用户可能会看到这种格式,但其他人可能会看到“01.02.2003”或“2003年2月1日”。
页面中给出的“在线传输”格式时间、日期或数字在显示给用户之前,会转换为用户的首选呈现方式(基于用户偏好或页面本身的区域设置)。同样,在用户使用其首选格式输入时间、日期或数字之后,用户代理会在将其放入DOM或提交之前将其转换回“在线传输”格式。
这样,页面和服务器上的脚本可以以一致的方式处理时间、日期和数字,而不需要支持几十种不同的格式,同时仍能满足用户的需求。
另请参见有关表单控件本地化的实现说明。
主要是由于历史原因,本节中的元素除了通常的类别,如流内容、 短语内容和交互内容外,还属于几个重叠(但稍有不同)的类别。
许多元素是表单关联元素,这意味着它们可以有一个表单所有者。
表单关联元素分为几个子类别:
表示在 form.elements
和
fieldset.elements
API 中列出的元素。这些元素还具有一个 form
内容属性,以及相应的 form
IDL 属性,允许作者指定明确的
表单所有者。
某些可提交的元素,取决于其属性,可能是按钮。下面的内容定义了元素何时为按钮。有些按钮是特定的提交按钮。
表示从其表单所有者继承autocapitalize
和autocorrect
属性的元素。
一些元素,并非所有元素都是表单关联元素,被归类为可标记元素。这些是可以与label
元素关联的元素。
form
元素Support in all current engines.
Support in all current engines.
form
元素的后代.
accept-charset
— 用于 表单提交的字符编码action
—
用于 URL 表单提交autocomplete
— 表单控件自动填充功能的默认设置enctype
— 用于条目列表编码类型 表单提交method
—
用于 表单提交 的变体name
—
在document.forms
API中的表单名称
novalidate
— 绕过表单控件验证 表单提交
target
—
导航 表单提交
rel
[Exposed =Window ,
LegacyOverrideBuiltIns ,
LegacyUnenumerableNamedProperties ]
interface HTMLFormElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString acceptCharset ;
[CEReactions ] attribute USVString action ;
[CEReactions ] attribute DOMString autocomplete ;
[CEReactions ] attribute DOMString enctype ;
[CEReactions ] attribute DOMString encoding ;
[CEReactions ] attribute DOMString method ;
[CEReactions ] attribute DOMString name ;
[CEReactions ] attribute boolean noValidate ;
[CEReactions ] attribute DOMString target ;
[CEReactions ] attribute DOMString rel ;
[SameObject , PutForwards =value ] readonly attribute DOMTokenList relList ;
[SameObject ] readonly attribute HTMLFormControlsCollection elements ;
readonly attribute unsigned long length ;
getter Element (unsigned long index );
getter (RadioNodeList or Element ) (DOMString name );
undefined submit ();
undefined requestSubmit (optional HTMLElement ? submitter = null );
[CEReactions ] undefined reset ();
boolean checkValidity ();
boolean reportValidity ();
};
form
元素表示一个可以通过一组表单关联元素进行操作的超链接,其中一些可以代表可提交到服务器进行处理的可编辑值。
accept-charset
属性给出用于提交的字符编码。如果指定,该值必须是UTF-8
的ASCII大小写不敏感匹配。[ENCODING]
name
属性表示form
在forms
集合中的名称。该值不能是空字符串,并且该值在其所在的form
元素集合中必须是唯一的。
autocomplete
属性是一个枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
on
|
on | 表单控件将默认其自动填充字段名称设置为"on "。
|
off
|
off | 表单控件将默认其自动填充字段名称设置为"off "。
|
action
,enctype
,method
,novalidate
,以及target
属性是表单提交属性。
rel
属性在form
元素上控制元素创建的链接类型。属性的值必须是无序的唯一空格分隔的标记集合。允许的关键字及其含义定义在前面的章节中。
rel
的支持的标记是HTML链接类型中定义的关键字,这些关键字允许在form
元素上使用,影响处理模型,并且由用户代理支持。可能的支持的标记是noreferrer
,noopener
,以及opener
。rel
的支持的标记只能包括用户代理实现处理模型的列表中的标记。
form.elements
Support in all current engines.
返回表单中的<form>元素控件(出于历史原因,不包括图像按钮)的HTMLFormControlsCollection。
form.length
Support in all current engines.
返回表单中表单控件的数量(出于历史原因,不包括图像按钮)。
form[index]
返回表单中的第index个元素(出于历史原因,不包括图像按钮)。
form[name]
返回具有给定ID或name
的表单控件(如果有多个,则返回表单控件的RadioNodeList
);如果没有,则返回具有给定ID的img
元素。
一旦使用特定名称引用了某个元素,即使元素的实际ID或name
发生变化,只要元素仍在树中,该名称仍可用于引用该元素。
如果有多个匹配项,则返回包含所有这些元素的RadioNodeList
对象。
form.submit()
Support in all current engines.
form.requestSubmit([ submitter ])
Support in all current engines.
请求提交表单。与submit()
不同,此方法包括交互约束验证和触发submit
事件,这两者都可以取消提交。
可以使用submitter参数指向特定的提交按钮,其formaction
,formenctype
,formmethod
,formnovalidate
,以及formtarget
属性可以影响提交。此外,在构建提交的条目列表时将包括提交者;通常按钮会被排除。
form.reset()
Support in all current engines.
重置表单。
form.checkValidity()
如果表单的控件全部有效,则返回true;否则返回false。
form.reportValidity()
如果表单的控件全部有效,则返回true;否则返回false,并通知用户。
autocomplete
IDL属性必须反映同名内容属性,仅限于已知值。
Support in all current engines.
name
和rel
IDL属性必须反映同名内容属性。
Support in all current engines.
acceptCharset
IDL属性必须反映accept-charset
内容属性。
elements
IDL属性必须返回一个以HTMLFormControlsCollection为根的form
元素的根,其过滤器匹配其表单所有者为form
元素的列出元素,但出于历史原因,必须从此特定集合中排除input
元素,其type
属性处于图像按钮状态。
length
IDL属性必须返回elements
集合所代表的节点数量。
在任何时刻支持的属性索引是由elements
属性返回的对象在该时刻支持的索引。
要确定索引属性的值对于form
元素,用户代理必须返回item
方法在elements
集合上返回的值,当使用给定的索引作为其参数调用时。
每个form
元素都有一个称为过去名称映射的名称到元素的映射。它用于在控件更改名称时持久化其名称。
支持的属性名称由以下算法获得的名称组成,按照从该算法获得的顺序:
令sourced names为一个最初为空的有序元组列表,由字符串、元素、来源组成,其中来源可以是id,name,或past,如果来源是past,则还有一个年龄。
对于其表单所有者是form
元素的每个列出元素
candidate,但出于历史原因,排除input
元素,其type
属性处于图像按钮状态:
对于过去名称映射中的每个条目past entry,将一个条目添加到sourced names,其中past entry的名称作为字符串,past entry的元素作为元素,将past作为来源,并且past entry在过去名称映射中存在的时间长度作为年龄。
按每个元组的元素条目的树顺序排序sourced names,将相同元素的条目排序为先按id,然后按name,最后按past,并按相同元素和来源的条目按其年龄排序,最老的排在前面。
删除sourced names中名称为空字符串的条目。
删除sourced names中与前面条目名称相同的条目。
按相对顺序返回sourced names中的名称列表。
要确定命名属性的值name对于form
元素,用户代理必须运行以下步骤:
让candidates成为一个实时RadioNodeList
对象,包含所有列出元素,其表单所有者是form
元素,并且具有等于name的id
属性或name
属性,但出于历史原因,排除其type
属性处于图像按钮状态的input
元素,按树顺序排序。
如果candidates为空,让candidates成为一个实时RadioNodeList
对象,包含所有img
元素,其表单所有者是form
元素,并且具有等于name的id
属性或name
属性,按树顺序排序。
如果candidates为空,并且name是form
元素的过去名称映射中的一个条目的名称:返回与该名称相关联的对象在该映射中。
如果candidates包含多个节点,则返回candidates。
否则,candidates只包含一个节点。在form
元素的过去名称映射中添加一个从name到candidates中的节点的映射,替换具有相同名称的先前条目(如果有)。
返回candidates中的节点。
如果在form
元素的过去名称映射中列出的元素更改了表单所有者,则必须从该映射中删除其条目。
submit()
方法步骤是从submit()方法设置为true的状态下提交this。
requestSubmit(submitter)
方法在调用时,必须执行以下步骤:
如果submitter不为null,则:
如果submitter的表单所有者不是该form
元素,则抛出"NotFoundError"DOMException
。
否则,将submitter设置为该form
元素。
reset()
方法在调用时,必须执行以下步骤:
如果调用了checkValidity()
方法,用户代理必须静态验证form
元素的约束,如果约束验证返回正面结果,则返回true,如果返回负面结果,则返回false。
如果调用了reportValidity()
方法,用户代理必须交互验证form
元素的约束,如果约束验证返回正面结果,则返回true,如果返回负面结果,则返回false,并通知用户。
此示例显示了两个搜索表单:
< form action = "https://www.google.com/search" method = "get" >
< label > Google: < input type = "search" name = "q" ></ label > < input type = "submit" value = "Search..." >
</ form >
< form action = "https://www.bing.com/search" method = "get" >
< label > Bing: < input type = "search" name = "q" ></ label > < input type = "submit" value = "Search..." >
</ form >
label
元素支持所有当前的引擎。
支持所有当前的引擎。
label
元素。
for
—
将标签与表单控件关联[Exposed =Window ]
interface HTMLLabelElement : HTMLElement {
[HTMLConstructor ] constructor ();
readonly attribute HTMLFormElement ? form ;
[CEReactions ] attribute DOMString htmlFor ;
readonly attribute HTMLElement ? control ;
};
label
元素
表示用户界面中的一个标题。标题可以与特定的表单控件关联,称为
label
元素的 标记控件,可以使用 for
属性,或通过将表单控件放在 label
元素内来实现。
支持所有当前的引擎。
for
属性可以被指定,以指示要关联的表单控件。如果指定了该属性,其值必须是与 label
元素在同一 树中的
可标记元素 的 ID。如果指定了该属性并且树中有一个元素的 ID 等于 for
属性的值,并且树序中第一个这样的元素是一个 可标记元素,那么该元素就是 label
元素的
标记控件。
如果未指定 for
属性,但 label
元素有一个 可标记元素
后代,那么树序中的第一个这样的后代是 label
元素的
标记控件。
label
元素的确切默认呈现和行为,尤其是其 激活行为,如果有的话,应与平台的标签行为相匹配。针对事件目标为 label
元素的交互内容后代及这些交互内容后代的任何后代的 交互内容 的
激活行为 必须什么都不做。
表单关联的自定义元素 是 可标记元素,因此对于那些 label
元素的 激活行为 影响到 标记控件 的用户代理,无论是内置元素还是自定义元素都会受到影响。
例如,在点击标签激活表单控件的平台上,点击以下代码中的 label
可能会触发用户代理对 input
元素触发 点击事件,就像用户直接触发了该元素一样:
< label >< input type = checkbox name = lost > Lost</ label >
类似地,假设 my-checkbox
被声明为一个 表单关联的自定义元素(如这个例子),那么以下代码
< label >< my-checkbox name = lost ></ my-checkbox > Lost</ label >
也会有相同的行为,对
my-checkbox
元素触发点击事件。
在其他平台上,这两种情况下的行为可能只是聚焦控件,或什么都不做。
以下示例显示了三个每个都有标签的表单控件,其中两个标签显示了用户使用的正确格式。
< p >< label > 全名: < input name = fn ></ input ></ label ></ p >
< p >< label > 年龄: < input name = age type = number min = 0 ></ label ></ p >
< p >< label > 邮政编码: < input name = pc ></ input ></ label ></ p >
label.control
支持所有当前的引擎。
返回与此元素关联的表单控件。
label.form
支持所有当前的引擎。
返回与此元素关联的表单控件的 表单所有者。
如果没有则返回 null。
支持所有当前的引擎。
control
IDL 属性必须返回 label
元素的 标记控件,如果有的话,否则返回
null。
form
IDL
属性必须执行以下步骤:
form
IDL 属性与
label
元素上的 form
IDL
属性不同,label
元素没有 form
内容属性。
control.labels
支持所有当前的引擎。
支持所有当前的引擎。
支持所有当前的引擎。
支持所有当前的引擎。
支持所有当前的引擎。
支持所有当前的引擎。
支持所有当前的引擎。
返回与表单控件关联的所有 NodeList
。
可标记元素 和所有 input
元素都有一个 live NodeList
对象,表示按 树序排列的 label
元素列表,其 标记控件 是相应的元素。不是
表单关联的自定义元素的 可标记元素的 labels
IDL 属性和 labels
IDL
属性,在获取时,必须返回该 NodeList
对象,并且必须始终返回相同的值,除非此元素是 input
元素,其 type
属性处于 状态,则它必须返回 null。
支持所有当前的引擎。
表单关联的自定义元素 没有
labels
IDL
属性。相反,它们的 ElementInternals
对象有一个 labels
IDL 属性。在获取时,如果 目标元素 不是 表单关联的自定义元素,则它必须抛出一个 "NotSupportedError
" DOMException
。否则,它必须返回该
NodeList
对象,并且始终返回相同的值。
此(不合规)示例显示了当 NodeList
发生变化时以及 labels
返回什么内容时,input
元素的 type
属性发生变化。
<!doctype html>
< p >< label >< input ></ label ></ p >
< script >
const input = document. querySelector( 'input' );
const labels = input. labels;
console. assert( labels. length === 1 );
input. type = 'hidden' ;
console. assert( labels. length === 0 ); // the input is no longer the label's labeled control
console. assert( input. labels === null );
input. type = 'checkbox' ;
console. assert( labels. length === 1 ); // the input is once again the label's labeled control
console. assert( input. labels === labels); // same value as returned originally
</ script >
input
元素所有当前引擎都支持。
所有当前引擎都支持。
type
属性 不是 隐藏 状态:
交互内容.
type
属性不是 隐藏状态:列出的、可标记的、可提交的、可重置的,以及自动大写和自动更正继承的 与表单关联的元素。
type
属性是隐藏状态:列出的、可提交的、可重置的,以及自动大写和自动更正继承的 与表单关联的元素。
type
属性 不是 隐藏
状态: 显著内容.accept
— 在 文件上传控件
中提示期望的文件类型
alt
—
在图像不可用时使用的替代文本
autocomplete
— 表单自动填充功能的提示
checked
— 控件是否被选中
dirname
— 用于发送元素的 方向性
的表单控件名称,在 表单提交 中
disabled
— 表单控件是否禁用
form
— 将元素与 表单
元素关联
formaction
— 用于 表单提交 的 URL
formenctype
— 用于 表单提交 的 条目列表 编码类型
formmethod
— 用于 表单提交 的变体
formnovalidate
— 在 表单提交
时绕过表单控件验证
formtarget
— 导航 用于 表单提交
height
— 垂直尺寸
list
—
自动完成选项列表
max
—
最大值
maxlength
— 值的最大 长度
min
—
最小值
minlength
— 值的最小 长度
multiple
— 是否允许多个值
name
—
用于 表单提交 和 form.elements
API 中使用的元素名称
pattern
— 表单控件值应匹配的模式
placeholder
— 用户可见的标签,放置在表单控件内
popovertarget
— 目标为显示、隐藏或切换的弹出元素
popovertargetaction
— 指示目标弹出元素是显示、隐藏还是切换
readonly
— 是否允许用户编辑值
required
— 控件是否在 表单提交 时必需
size
—
控件大小
src
—
资源地址
step
—
表单控件值应匹配的粒度
type
— 表单控件类型
value
— 表单控件的值
width
—
水平尺寸
title
属性在此元素上具有特殊语义:模式的描述(与 pattern
属性一起使用时)
type
属性在 隐藏 状态: 供作者使用; 供实现者使用.type
属性在 文本 状态: 供作者使用; 供实现者使用.type
属性在 搜索 状态: 供作者使用; 供实现者使用.type
属性在 电话 状态: 供作者使用; 供实现者使用.type
属性在 URL 状态:
供作者使用; 供实现者使用.
type
属性在 电子邮件 状态: 供作者使用; 供实现者使用.type
属性在 密码 状态: 供作者使用; 供实现者使用.type
属性在 日期
状态: 供作者使用; 供实现者使用.type
属性在 月份 状态: 供作者使用; 供实现者
使用.type
属性在 周
状态: 供作者使用; 供实现者使用.type
属性在 时间
状态: 供作者使用; 供实现者使用.type
属性在 本地日期和时间 状态: 供作者使用; 供实现者使用.type
属性在 数字 状态: 供作者使用; 供实现者使用.type
属性在 范围 状态: 供作者使用; 供实现者使用.type
属性在 颜色 状态: 供作者使用; 供实现者使用.type
属性在 复选框 状态: 供作者使用; 供实现者使用.type
属性在 单选按钮 状态:
供作者使用; 供实现者使用.
type
属性在 文件上传 状态:
供作者使用; 供实现者使用.
type
属性在 提交按钮
状态: 供作者使用; 供实现者使用.type
属性在 图像按钮 状态:
供作者使用; 供实现者使用.
type
属性在 重置按钮 状态:
供作者使用; 供实现者使用.
type
属性在 按钮 状态: 供作者使用; 供实现者使用.[Exposed =Window ]
interface HTMLInputElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString accept ;
[CEReactions ] attribute DOMString alt ;
[CEReactions ] attribute DOMString autocomplete ;
[CEReactions ] attribute boolean defaultChecked ;
attribute boolean checked ;
[CEReactions ] attribute DOMString dirName ;
[CEReactions ] attribute boolean disabled ;
readonly attribute HTMLFormElement ? form ;
attribute FileList ? files ;
[CEReactions ] attribute USVString formAction ;
[CEReactions ] attribute DOMString formEnctype ;
[CEReactions ] attribute DOMString formMethod ;
[CEReactions ] attribute boolean formNoValidate ;
[CEReactions ] attribute DOMString formTarget ;
[CEReactions ] attribute unsigned long height ;
attribute boolean indeterminate ;
readonly attribute HTMLDataListElement ? list ;
[CEReactions ] attribute DOMString max ;
[CEReactions ] attribute long maxLength ;
[CEReactions ] attribute DOMString min ;
[CEReactions ] attribute long minLength ;
[CEReactions ] attribute boolean multiple ;
[CEReactions ] attribute DOMString name ;
[CEReactions ] attribute DOMString pattern ;
[CEReactions ] attribute DOMString placeholder ;
[CEReactions ] attribute boolean readOnly ;
[CEReactions ] attribute boolean required ;
[CEReactions ] attribute unsigned long size ;
[CEReactions ] attribute USVString src ;
[CEReactions ] attribute DOMString step ;
[CEReactions ] attribute DOMString type ;
[CEReactions ] attribute DOMString defaultValue ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString value ;
attribute object ? valueAsDate ;
attribute unrestricted double valueAsNumber ;
[CEReactions ] attribute unsigned long width ;
undefined stepUp (optional long n = 1);
undefined stepDown (optional long n = 1);
readonly attribute boolean willValidate ;
readonly attribute ValidityState validity ;
readonly attribute DOMString validationMessage ;
boolean checkValidity ();
boolean reportValidity ();
undefined setCustomValidity (DOMString error );
readonly attribute NodeList ? labels ;
undefined select ();
attribute unsigned long ? selectionStart ;
attribute unsigned long ? selectionEnd ;
attribute DOMString ? selectionDirection ;
undefined setRangeText (DOMString replacement );
undefined setRangeText (DOMString replacement , unsigned long start , unsigned long end , optional SelectionMode selectionMode = "preserve");
undefined setSelectionRange (unsigned long start , unsigned long end , optional DOMString direction );
undefined showPicker ();
// also has obsolete members
};
HTMLInputElement includes PopoverInvokerElement ;
input
元素 表示
一个类型化的数据字段,通常带有一个表单控件,允许用户编辑数据。
type
属性控制元素的数据类型(及相关控件)。它是一个 枚举属性,具有以下关键字和状态:
关键字 | 状态 | 数据类型 | 控件类型 |
---|---|---|---|
hidden
|
任意字符串 | 不适用 | |
text
|
文本 | 无换行符的文本 | 文本控件 |
search
|
搜索 | 无换行符的文本 | 搜索控件 |
tel
|
电话 | 无换行符的文本 | 文本控件 |
url
|
URL | 绝对 URL | 文本控件 |
email
|
电子邮件 | 一个或多个电子邮件地址 | 文本控件 |
password
|
密码 | 无换行符的文本(敏感信息) | 隐藏数据输入的文本控件 |
date
|
日期 | 不带时区的日期(年、月、日) | 日期控件 |
month
|
月份 | 不带时区的日期(年和月) | 月份控件 |
week
|
周 | 不带时区的日期(周年号和周号) | 周控件 |
time
|
时间 | 不带时区的时间(小时、分钟、秒、分秒) | 时间控件 |
datetime-local
|
本地日期和时间 | 不带时区的日期和时间(年、月、日、小时、分钟、秒、分秒) | 日期和时间控件 |
number
|
数字 | 数值 | 文本控件或微调控件 |
range
|
范围 | 数值,但具有额外的语义,即确切值并不重要 | 滑块控件或类似控件 |
color
|
颜色 | 具有 8 位红、绿、蓝组件的 sRGB 颜色 | 颜色选择器 |
checkbox
|
复选框 | 从预定义列表中选择零个或多个值 | 复选框 |
radio
|
单选按钮 | 枚举值 | 单选按钮 |
file
|
文件上传 | 零个或多个文件,每个文件都有一个 MIME 类型 和(可选的)文件名 | 标签和按钮 |
submit
|
提交按钮 | 枚举值,具有额外的语义,即它必须是最后选择的值,并启动表单提交 | 按钮 |
image
|
图像按钮 | 相对于特定图像大小的坐标,具有额外的语义,即它必须是最后选择的值,并启动表单提交 | 可点击的图像或按钮 |
reset
|
重置按钮 | 不适用 | 按钮 |
button
|
按钮 | 不适用 | 按钮 |
哪些
accept
,
alt
,
autocomplete
,
checked
,
dirname
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
list
,
max
,
maxlength
,
min
,
minlength
,
multiple
,
pattern
,
placeholder
,
readonly
,
required
,
size
,
src
,
step
,
和
width
内容属性,
checked
,
files
,
valueAsDate
,
valueAsNumber
,
和
list
IDL 属性,
select()
方法,
selectionStart
,
selectionEnd
,
和
selectionDirection
,
IDL 属性,
setRangeText()
和
setSelectionRange()
方法,
stepUp()
和
stepDown()
方法,以及
input
和
change
事件 适用 于
input
元素取决于其
type
属性的状态。
定义每种类型的子部分也在规范的“簿记”部分中明确规定了这些功能中的哪些适用,哪些不适用于每种类型。这些功能的行为取决于它们是否适用,如各自部分中定义的(例如 内容属性,API,事件)。
下表是非规范性的,概述了哪些内容属性、IDL 属性、方法和事件适用于每种状态:
文本, 搜索 | 电话, URL | 电子邮件 | 密码 | 日期, 月份, 周, 时间 | 本地日期和时间 | 数字 | 范围 | 颜色 | 复选框, 单选按钮 | 文件上传 | 提交按钮 | 图片按钮 | 重置按钮, 按钮 | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
内容属性 | |||||||||||||||
accept
|
· | · | · | · | · | · | · | · | · | · | · | 是 | · | · | · |
alt
|
· | · | · | · | · | · | · | · | · | · | · | · | · | 是 | · |
autocomplete
|
是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | · | · | · | · | · |
checked
|
· | · | · | · | · | · | · | · | · | · | 是 | · | · | · | · |
dirname
|
是 | 是 | 是 | 是 | 是 | · | · | · | · | · | · | · | 是 | · | · |
formaction
|
· | · | · | · | · | · | · | · | · | · | · | · | 是 | 是 | · |
formenctype
|
· | · | · | · | · | · | · | · | · | · | · | · | 是 | 是 | · |
formmethod
|
· | · | · | · | · | · | · | · | · | · | · | · | 是 | 是 | · |
formnovalidate
|
· | · | · | · | · | · | · | · | · | · | · | · | 是 | 是 | · |
formtarget
|
· | · | · | · | · | · | · | · | · | · | · | · | 是 | 是 | · |
height
|
· | · | · | · | · | · | · | · | · | · | · | · | · | 是 | · |
list
|
· | 是 | 是 | 是 | · | 是 | 是 | 是 | 是 | 是 | · | · | · | · | · |
max
|
· | · | · | · | · | 是 | 是 | 是 | 是 | · | · | · | · | · | · |
maxlength
|
· | 是 | 是 | 是 | 是 | · | · | · | · | · | · | · | · | · | · |
min
|
· | · | · | · | · | 是 | 是 | 是 | 是 | · | · | · | · | · | · |
minlength
|
· | 是 | 是 | 是 | 是 | · | · | · | · | · | · | · | · | · | · |
multiple
|
· | · | · | 是 | · | · | · | · | · | · | · | 是 | · | · | · |
pattern
|
· | 是 | 是 | 是 | 是 | · | · | · | · | · | · | · | · | · | · |
placeholder
|
· | 是 | 是 | 是 | 是 | · | · | 是 | · | · | · | · | · | · | · |
popovertarget
|
· | · | · | · | · | · | · | · | · | · | · | · | 是 | 是 | 是 |
popovertargetaction
|
· | · | · | · | · | · | · | · | · | · | · | · | 是 | 是 | 是 |
readonly
|
· | 是 | 是 | 是 | 是 | 是 | 是 | 是 | · | · | · | · | · | · | · |
required
|
· | 是 | 是 | 是 | 是 | 是 | 是 | 是 | · | · | 是 | 是 | · | · | · |
size
|
· | 是 | 是 | 是 | 是 | · | · | · | · | · | · | · | · | · | · |
src
|
· | · | · | · | · | · | · | · | · | · | · | · | · | 是 | · |
step
|
· | · | · | · | · | 是 | 是 | 是 | 是 | · | · | · | · | · | · |
width
|
· | · | · | · | · | · | · | · | · | · | · | · | · | 是 | · |
IDL 属性和方法 | |||||||||||||||
checked
|
· | · | · | · | · | · | · | · | · | · | 是 | · | · | · | · |
files
|
· | · | · | · | · | · | · | · | · | · | · | 是 | · | · | · |
value
|
default | value | value | value | value | value | value | value | value | value | default/on | filename | default | default | default |
valueAsDate
|
· | · | · | · | · | 是 | · | · | · | · | · | · | · | · | · |
valueAsNumber
|
· | · | · | · | · | 是 | 是 | 是 | 是 | · | · | · | · | · | · |
list
|
· | 是 | 是 | 是 | · | 是 | 是 | 是 | 是 | 是 | · | · | · | · | · |
select()
|
· | 是 | 是 | 是† | 是 | 是† | 是† | 是† | · | 是† | · | 是† | · | · | · |
selectionStart
|
· | 是 | 是 | · | 是 | · | · | · | · | · | · | · | · | · | · |
selectionEnd
|
· | 是 | 是 | · | 是 | · | · | · | · | · | · | · | · | · | · |
selectionDirection
|
· | 是 | 是 | · | 是 | · | · | · | · | · | · | · | · | · | · |
setRangeText()
|
· | 是 | 是 | · | 是 | · | · | · | · | · | · | · | · | · | · |
setSelectionRange()
|
· | 是 | 是 | · | 是 | · | · | · | · | · | · | · | · | · | · |
stepDown()
|
· | · | · | · | · | 是 | 是 | 是 | 是 | · | · | · | · | · | · |
stepUp()
|
· | · | · | · | · | 是 | 是 | 是 | 是 | · | · | · | · | · | · |
事件 | |||||||||||||||
input
事件
|
· | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | · | · | · |
change
事件
|
· | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | · | · | · |
† 如果控件没有可选择的文本,select()
方法将无操作,不会出现"InvalidStateError
" DOMException
。
某些 type
属性的状态定义了 值清理算法。
每个 input
元素都有一个 value,它通过 value
IDL
属性暴露出来。某些状态定义了将字符串转换为数字的 算法,将数字转换为字符串的 算法,将字符串转换为 Date
对象的 算法,以及将 Date
对象转换为字符串的 算法,这些算法被 max
,min
,step
,valueAsDate
,valueAsNumber
,以及
stepUp()
使用。
当用户以更改 value
的方式与控件交互时,input
元素的
dirty value flag 必须设置为
true。(当值以编程方式更改时,它也会设置为 true,如 value
IDL
属性的定义中所述。)
value
内容属性给出了 input
元素的默认 value。当 value
内容属性被添加、设置或移除时,如果控件的 dirty value flag 为
false,用户代理必须将元素的 value 设置为该 value
内容属性的值(如果有),否则为空字符串,然后运行当前的 值清理算法(如果有定义)。
每个 input
元素都有一个 checkedness,它通过 checked
IDL 属性暴露出来。
每个 input
元素都有一个布尔 dirty checkedness flag。当它为 true 时,元素被认为有 dirty checkedness。dirty checkedness flag 必须在元素创建时初始化为 false,并且在用户以更改 checkedness
的方式与控件交互时必须设置为 true。
所有当前浏览器均支持。
checked
内容属性是一个 布尔属性,用于指定 checkedness(选中状态)为 input
元素的默认值。当添加 checked
内容属性时,如果控件没有 脏选中状态,用户代理必须将该元素的 checkedness 设置为
true;当移除 checked
内容属性时,如果控件没有 脏选中状态,用户代理必须将该元素的 checkedness 设置为
false。
重置算法 适用于 input
元素,需将其 用户有效性、脏值标志 和 脏选中状态标志 恢复为 false,将元素的 值 设置为 value
内容属性的值(如果存在),否则为空字符串,将元素的 checkedness
设置为 true(如果元素具有 checked
内容属性)或 false(如果没有),清空 选定的文件 列表,然后调用 值清理算法,如果 type
属性的当前状态定义了一个。
每个 input
元素可以是 可变的。除非另有说明,input
元素始终是 可变的。同样,除非另有说明,用户代理不应允许用户修改元素的 值 或 选中状态。
readonly
属性在某些情况下(例如,Date 状态,但不是 Checkbox
状态)也可以阻止 input
元素变为 可变的。
对于 input
元素,克隆步骤 必须将节点被克隆的 值、脏值标志、选中状态 和 脏选中状态标志 从被克隆的节点传播到副本。
对于 input
元素,给定 event,激活行为 包括以下步骤:
运行 element 的 input 激活行为(如果有),否则不做任何操作。
在 element 上运行 弹出目标属性激活行为。
请记住,元素的 激活行为 适用于用户发起的激活以及合成激活(例如,通过
el.click()
)。用户代理也可能对给定控件有特定的行为——这些行为在此未指定——这些行为仅由真正的用户发起的激活触发。一个常见的选择是 在适用的情况下显示选择器。与此相对,input
激活行为 仅在特殊的历史情况下(例如 文件上传 和 颜色
状态)显示选择器。
如果该元素的 type
属性在
Checkbox
状态 中,则将该元素的 选中状态
设置为相反的值(即如果为 false 则设置为 true,如果为 true 则设置为 false),并将该元素的 indeterminate
IDL 属性设置为 false。
如果该元素的 type
属性在
Radio Button
状态 中,则获取该元素所在的 单选按钮组 中选中状态为
true 的元素的引用(如果有),然后将该元素的 选中状态 设置为
true。
如果该元素的 type
属性在
Checkbox
状态 中,则将该元素的 选中状态 和该元素的
indeterminate
IDL 属性恢复到在 传统预激活行为 运行之前的值。
如果该元素的 type
属性在
Radio Button
状态 中,则如果在 传统预激活行为 中获取的引用元素仍在当前元素的 单选按钮组
中(如果有),则将该元素的 选中状态 设置为
true;否则,如果没有这样的元素,或该元素不再在当前元素的 单选按钮组
中,或者当前元素不再有 单选按钮组,则将该元素的 选中状态 设置为
false。
当 input
元素首次创建时,该元素的渲染和行为必须设置为定义的 type
属性状态的渲染和行为,并且如果有定义,则必须调用 值清理算法。
当 input
元素的 type
属性状态发生变化时,用户代理必须执行以下步骤:
如果元素的 type
属性的先前状态将 value
IDL 属性设置为 value
模式,并且元素的 值 不是空字符串,且元素的
type
属性的新状态将 value
IDL 属性设置为 default 模式或 default/on
模式,则将元素的 value
内容属性设置为元素的 值。
否则,如果元素的 type
属性的先前状态将 value
IDL 属性设置为 value
模式以外的任何模式,且元素的 type
属性的新状态将 value
IDL 属性设置为 value
模式,则将元素的 值 设置为 value
内容属性的值(如果有),否则为空字符串,然后将控件的 脏值标志 设置为
false。
否则,如果元素的 type
属性的先前状态将 value
IDL 属性设置为 filename 模式以外的任何模式,且元素的 type
属性的新状态将 value
IDL 属性设置为 filename 模式,则将元素的 值 设置为空字符串。
更新元素的渲染和行为为新状态的渲染和行为。
发出类型变化信号。特别是,Radio Button 状态使用此信号。
如果 setRangeText()
之前对元素应用了 应用,则让
previouslySelectable 为 true,否则为 false。
如果 setRangeText()
现在对元素 应用,则让
nowSelectable 为 true,否则为 false。
如果 previouslySelectable 为 false 且 nowSelectable 为 true,则将元素的 文本输入光标位置
设置为文本控件的开始位置,并将其选择方向 设置 为 "none
"。
name
属性表示元素的名称。
dirname
属性控制元素的 方向性
的提交方式。
disabled
属性用于使控件不可交互,并防止其值被提交。
form
属性用于显式地将
input
元素与其 表单拥有者 关联。
autocomplete
属性控制用户代理如何提供自动填充行为。
HTMLInputElement#indeterminate
所有当前引擎的支持情况。
indeterminate
IDL 属性必须最初设置为 false。获取时,必须返回最后设置的值。设置时,必须设置为新值。除了改变 复选框
控件的外观外,没有其他效果。
所有当前引擎的支持情况。
accept
、alt
、max
、min
、multiple
、pattern
、placeholder
、required
、size
、src
和 step
IDL
属性必须 反映 同名的内容属性。dirName
IDL
属性必须 反映 dirname
内容属性。readOnly
IDL 属性必须 反映 readonly
内容
属性。defaultChecked
IDL 属性必须 反映 checked
内容属性。defaultValue
IDL 属性必须 反映 value
内容属性。
type
IDL 属性必须
反映 同名的内容属性,仅限于已知值。maxLength
IDL 属性必须 反映 maxlength
内容属性,仅限于非负数。minLength
IDL 属性必须 反映 minlength
内容属性,仅限于非负数。
IDL 属性 width
和 height
必须返回图像的渲染宽度和
高度,单位为 CSS 像素,如果图像 正在渲染;否则返回图像的 自然宽度和高度,单位为 CSS 像素,如果图像 可用 但未 渲染;否则返回 0,
如果图像不可 可用。当 input
元素的 type
属性不在 图像按钮
状态时,则没有图像 可用。[CSS]
设置时,它们必须表现得好像它们 反映 同名的内容属性。
willValidate
,
validity
,
和 validationMessage
IDL 属性,以及 checkValidity()
,
reportValidity()
,
和 setCustomValidity()
方法,都是 约束验证 API
的一部分。labels
IDL 属性提供元素的 label
列表。
select()
,
selectionStart
,
selectionEnd
,
selectionDirection
,
setRangeText()
,
和 setSelectionRange()
方法和 IDL 属性公开元素的文本选择。disabled
,
form
,
和 name
IDL 属性是元素表单 API 的一部分。
type
属性的状态type=hidden
)支持所有当前的浏览器引擎。
当一个
元素的 属性处于 状态时,本节中的规则适用。该
元素 一个不打算由用户检查或操作的值。约束验证:如果一个
元素的 属性处于 状态时,它被 。如果
属性存在且其值是与 " " 进行 匹配的,那么元素的 属性必须被省略。和 内容属性 该元素。
IDL 属性 该元素,并且处于 模式。
以下内容属性不得被指定,并且
该元素: , , , , , , , , , , , , , , , , , , , , , , , , 和 。以下 IDL 属性和方法
于该元素: , , , , , , , 和 IDL 属性; , , , , 和 方法。以下事件
和 。type=text
) 状态和 搜索 状态 (type=search
)
在所有当前引擎中支持。
在所有当前引擎中支持。
当 input
元素的 type
属性为
文本
状态或 搜索
状态时,本节中的规则适用。
input
元素 表示 一个单行纯文本编辑控件
用于该元素的 值。
文本状态和搜索状态的主要区别在于样式:在那些将搜索控件与普通文本控件区分开来的平台上,搜索状态可能会使控件的外观与平台的搜索控件一致,而不是像普通文本控件那样呈现。
如果元素是 可变的,其 值 应该可以被用户编辑。用户代理不能允许 用户在元素的 值 中插入 U+000A 换行符 (LF) 或 U+000D 回车符 (CR) 字符。
如果元素是 可变的,用户代理应允许用户更改元素的书写方向,将其设置为从左到右的书写 方向或从右到左的书写方向。如果用户这样做,用户代理必须运行以下步骤:
如果用户选择了从左到右的书写方向,则将元素的 dir
属性设置为 "ltr
"
;如果用户选择了从右到左的书写方向,则设置为 "rtl
"。
在用户交互任务源
中排队一个元素任务,给定
元素以 触发名为 input
的事件,并将 bubbles
和 composed
属性初始化为 true。
如果指定了 value
属性,则其值中不得包含 U+000A 换行符 (LF) 或 U+000D 回车符 (CR) 字符。
以下常见的 input
元素内容
属性、IDL 属性和方法 适用于 该元素:
autocomplete
,
dirname
,
list
,
maxlength
,
minlength
,
pattern
,
placeholder
,
readonly
,
required
,
和
size
内容属性;
list
、
selectionStart
、
selectionEnd
、
selectionDirection
、
和
value
IDL 属性;
select()
、
setRangeText()
、
和
setSelectionRange()
方法。
以下内容属性不得指定且 不适用 于元素:
accept
、
alt
、
checked
、
formaction
、
formenctype
、
formmethod
、
formnovalidate
、
formtarget
、
height
、
max
、
min
、
multiple
、
popovertarget
、
popovertargetaction
、
src
、
step
、
和
width
。
以下 IDL 属性和方法 不适用 于元素:
checked
、
files
、
valueAsDate
、
和
valueAsNumber
IDL 属性;
stepDown()
和
stepUp()
方法。
type=tel
)Support in all current engines.
当 input
元素的 type
属性处于 Telephone
状态时,本节规则适用。
input
元素 代表
一个用于编辑电话号码的控件,该电话号码在元素的 value 中给出。
如果该元素是 可变的,其 value 应该是用户可编辑的。用户代理可以更改用户输入的 值 的间距,并在谨慎情况下更改标点符号。用户代理不得允许用户在元素的 value 中插入 U+000A 换行符 (LF) 或 U+000D 回车符 (CR) 字符。
value
属性(如果指定)必须具有不包含 U+000A 换行符 (LF) 或 U+000D 回车符 (CR) 字符的值。
与 URL 和 Email 类型不同,Telephone
类型不强制执行特定的语法。这是有意为之;实际上,电话号码字段往往是自由格式的字段,因为存在多种有效的电话号码。需要强制执行特定格式的系统建议使用 pattern
属性或 setCustomValidity()
方法来挂钩客户端验证机制。
以下常见的 input
元素内容
属性、IDL 属性和方法 适用于 该元素:
autocomplete
,
dirname
,
list
,
maxlength
,
minlength
,
pattern
,
placeholder
,
readonly
,
required
,
和
size
内容属性;
list
,
selectionStart
,
selectionEnd
,
selectionDirection
,
和
value
IDL 属性;
select()
,
setRangeText()
,
和
setSelectionRange()
方法。
以下内容属性不得指定并且 不适用
于该元素:
accept
,
alt
,
checked
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
max
,
min
,
multiple
,
popovertarget
,
popovertargetaction
,
src
,
step
,
和
width
。
以下 IDL 属性和方法 不适用于 该元素:
checked
,
files
,
valueAsDate
,
和
valueAsNumber
IDL 属性;
stepDown()
和
stepUp()
方法。
type=url
)Support in all current engines.
当 input
元素的 type
属性处于 URL
状态时,本节规则适用。
input
元素 代表 一个用于编辑单个 绝对 URL 的控件,该 URL 在元素的 value 中给出。
如果该元素是 可变的,用户代理应允许用户更改其 value 所代表的 URL。用户代理可以允许用户将 value 设置为一个不是 有效的 绝对 URL 的字符串,但也可以或替代地自动转义用户输入的字符,使得 value 始终是一个 有效的 绝对 URL(即使这不是用户在界面中看到和编辑的实际值)。用户代理应允许用户将 value 设置为空字符串。用户代理不得允许用户在 value 中插入 U+000A 换行符 (LF) 或 U+000D 回车符 (CR) 字符。
value
属性(如果指定且不为空)必须具有一个 有效的可能被空格包围的 URL,且该 URL 也是一个 绝对 URL。
值清理算法 如下:从值中去除换行符,然后从值中去除前导和尾随的 ASCII 空白。
约束验证:当元素的 value 既不是空字符串也不是 有效的 绝对 URL 时,元素 存在类型不匹配。
以下常见的 input
元素内容属性、IDL 属性和方法 适用于 该元素:
autocomplete
,
dirname
,
list
,
maxlength
,
minlength
,
pattern
,
placeholder
,
readonly
,
required
,
和
size
内容属性;
list
,
selectionStart
,
selectionEnd
,
selectionDirection
,
和
value
IDL 属性;
select()
,
setRangeText()
,
和
setSelectionRange()
方法。
以下内容属性不得指定并且 不适用 于该元素:
accept
,
alt
,
checked
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
max
,
min
,
multiple
,
popovertarget
,
popovertargetaction
,
src
,
step
,
和
width
。
以下 IDL 属性和方法 不适用于 该元素:
checked
,
files
,
valueAsDate
,
和
valueAsNumber
IDL 属性;
stepDown()
和
stepUp()
方法。
如果文档包含以下标记:
< input type = "url" name = "location" list = "urls" >
< datalist id = "urls" >
< option label = "MIME: Format of Internet Message Bodies" value = "https://www.rfc-editor.org/rfc/rfc2045" >
< option label = "HTML" value = "https://html.spec.whatwg.org/" >
< option label = "DOM" value = "https://dom.spec.whatwg.org/" >
< option label = "Fullscreen" value = "https://fullscreen.spec.whatwg.org/" >
< option label = "Media Session" value = "https://mediasession.spec.whatwg.org/" >
< option label = "The Single UNIX Specification, Version 3" value = "http://www.unix.org/version3/" >
</ datalist >
...用户输入了"spec.w",而用户代理还发现用户最近访问过https://url.spec.whatwg.org/#url-parsing
和https://streams.spec.whatwg.org/
,那么渲染结果可能如下所示:
此示例中的前四个URL由与用户输入文本匹配的作者指定列表中的四个URL组成,并以某种实现定义的方式排序(可能根据用户引用这些URL的频率)。请注意,UA利用了这些值是URL的知识,使用户可以省略方案部分并对域名进行智能匹配。
最后两个URL(以及可能更多的URL,根据滚动条指示有更多值可用)是用户代理的会话历史数据中的匹配项。这些数据不会提供给页面DOM。在这种特殊情况下,UA没有提供这些值的标题。
type=email
)所有当前引擎支持。
当 input
元素的 type
属性处于 电子邮件
状态时,本节的规则适用。
电子邮件
状态的操作方式取决于是否指定了 multiple
属性。
multiple
属性时 input
元素 表示 用于编辑元素的 value
中给定的电子邮件地址的控件。
如果元素是 可变的,用户代理应允许用户更改其 value 表示的电子邮件地址。用户代理可以允许用户将 value 设置为不是 有效电子邮件地址 的字符串。用户代理应以与期望用户提供单个电子邮件地址一致的方式行事。用户代理应允许用户将 value 设置为空字符串。用户代理不得允许用户在 value 中插入 U+000A 换行符 (LF) 或 U+000D 回车符 (CR) 字符。用户代理可以转换 value 以进行显示和编辑;特别是,用户代理应将 value 中域标签的 punycode 转换为显示中的 IDN,反之亦然。
约束验证:当用户界面表示用户代理无法转换为 punycode 的输入时,控件 遭受错误输入。
value
属性(如果指定且不为空)必须具有单个 有效电子邮件地址 的值。
值清理算法 如下:从值中去除换行符,然后从值中去除前导和尾随的 ASCII 空白。
multiple
属性时 input
元素 表示 用于添加、删除和编辑元素的
值
中给定的电子邮件地址的控件。
如果元素是 可变的,用户代理应允许用户添加、删除和编辑其 值 表示的电子邮件地址。用户代理可以允许用户将 值 列表中的任何单个值设置为不是 有效电子邮件地址 的字符串,但不得允许用户将任何单个值设置为包含 U+002C 逗号(,)、U+000A 换行符(LF)或 U+000D 回车符(CR)字符的字符串。用户代理应允许用户删除元素的 值 中的所有地址。用户代理可以转换 值 以进行显示和编辑;特别是,用户代理应将 值 中域标签的 punycode 转换为显示中的 IDN,反之亦然。
约束验证:当用户界面描述的情况是某个单独的值包含 U+002C 逗号(,)或表示用户代理无法转换为 punycode 的输入时,控件 遭受错误输入。
每当用户更改元素的 值 时,用户代理必须运行以下步骤:
让 latest values 成为元素的 值 的副本。
从 latest values 中的每个值中 删除前导和尾随的 ASCII 空白字符。
将元素的 值 设置为 latest values 中所有值的连接结果,每个值之间用单个 U+002C 逗号字符(,)分隔,保持列表的顺序。
value
属性(如果指定)必须具有 有效电子邮件地址列表 的值。
值清理算法 如下:
按逗号拆分 元素的值,从每个结果的令牌中去除前导和尾随的 ASCII 空白(如果有的话),并使元素的值成为(可能为空的)结果令牌列表,保持原始顺序。
约束验证:当元素的 值 不是 有效电子邮件地址列表 时,元素 遭受类型不匹配。
当 multiple
属性被设置或移除时,用户代理必须运行 值清理算法。
有效电子邮件地址 是符合以下 ABNF 的 email
生成规则的字符串,其字符集为 Unicode。该 ABNF 实现了
RFC 1123 中描述的扩展。[ABNF] [RFC5322] [RFC1034]
[RFC1123]
email = 1* ( atext / "." ) "@" label * ( "." label )
label = let-dig [ [ ldh-str ] let-dig ] ; limited to a length of 63 characters by RFC 1034 section 3.5
atext = < as defined in RFC 5322 section 3 .2 .3 >
let-dig = < as defined in RFC 1034 section 3 .5 >
ldh-str = < as defined in RFC 1034 section 3 .5 >
此要求是对 RFC 5322 的 故意违反,RFC 5322 定义了一个电子邮件地址语法,在 "@" 字符之前过于严格,"@" 字符之后过于模糊,并且过于宽松(允许大多数用户不熟悉的方式包含注释、空白字符和引号字符串),在这里不实用。
以下兼容 JavaScript 和 Perl 的正则表达式是上述定义的实现。
/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
有效电子邮件地址列表 是一组 逗号分隔的标记集,其中每个标记本身都是一个 有效电子邮件地址。要从 有效电子邮件地址列表 中获取标记列表,实施必须 将字符串按逗号分割。
以下常见的 input
元素内容属性、IDL 属性和方法 适用于 该元素:
autocomplete
,
dirname
,
list
,
maxlength
,
minlength
,
multiple
,
pattern
,
placeholder
,
readonly
,
required
,
和
size
内容属性;
list
,
和
value
IDL 属性;
select()
方法。
以下内容属性不得指定并且 不适用于
该元素:
accept
,
alt
,
checked
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
max
,
min
,
popovertarget
,
popovertargetaction
,
src
,
step
,
和
width
。
以下 IDL 属性和方法 不适用于
该元素:
checked
,
files
,
selectionStart
,
selectionEnd
,
selectionDirection
,
valueAsDate
,
和
valueAsNumber
IDL 属性;
setRangeText()
,
setSelectionRange()
,
stepDown()
,
和
stepUp()
方法。
type=password
)支持所有当前引擎。
当 input
元素的 type
属性处于
密码
状态时,本节的规则适用。
该 input
元素 表示
一个用于编辑
元素的 value
的单行纯文本编辑控件。用户代理应遮蔽该值以防止其他人看到。
如果元素是 可变的,其 value 应可由用户编辑。用户代理不得允许 用户在 value 中插入 U+000A 换行符(LF)或 U+000D 回车符(CR)。
如果指定了 value
属性,则其值不得包含 U+000A 换行符(LF)或 U+000D 回车符(CR)。
以下常见的 input
元素内容
属性、IDL 属性和方法 适用于 该元素:
autocomplete
,
dirname
,
maxlength
,
minlength
,
pattern
,
placeholder
,
readonly
,
required
,
和
size
内容属性;
selectionStart
,
selectionEnd
,
selectionDirection
,
和
value
IDL 属性;
select()
,
setRangeText()
,
和
setSelectionRange()
方法。
以下内容属性不得指定,且 不适用于 该元素:
accept
,
alt
,
checked
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
list
,
max
,
min
,
multiple
,
popovertarget
,
popovertargetaction
,
src
,
step
,
和
width
。
以下 IDL 属性和方法 不适用于 该元素:
checked
,
files
,
list
,
valueAsDate
,
和
valueAsNumber
IDL 属性;
stepDown()
,
和
stepUp()
方法。
type=date
)支持所有当前引擎。
当 input
元素的 type
属性处于
日期
状态时,本节的规则适用。
该 input
元素 表示 一个
控件,用于设置元素的
value 为表示特定
日期 的字符串。
如果元素是 可变的,用户代理应允许 用户更改其 日期 由其 value 表示,正如通过解析日期字符串 获得的那样。用户代理不得允许用户将 value 设置为非空字符串且该字符串不是 有效日期字符串。如果用户代理提供用于选择 日期 的用户界面,那么 value 必须设置为表示用户选择的 有效日期字符串。用户代理应允许用户将 value 设置为空字符串。
约束验证:当用户界面描述的输入用户代理无法转换为 有效日期字符串 时,控件 存在错误输入。
请参阅引言部分,讨论日期、时间和数字表单控件的输入格式和提交格式之间的区别,以及 实现注释, 了解表单控件的本地化。
如果指定且不为空,value
属性必须具有
有效日期字符串 的值。
值清理算法 如下:如果元素的 value 不是 有效日期字符串,则将其设置为空字符串。
如果指定,min
属性必须具有
有效日期字符串
的值。max
属性如果指定,则必须具有
有效日期字符串 的值。
step
属性以天数表示。步长比例因子 为
86,400,000
(将天数转换为毫秒,如其他算法中使用)。默认步长 为 1 天。
当元素存在步长不匹配时,用户代理可以将元素的 value 四舍五入到最近的日期,对于该日期元素不会 存在步长不匹配。
将字符串转换为数字的算法 如下:给定字符串
input,如果从 input 中
解析日期
结果出错,则返回错误;否则,返回从 1970-01-01
上午零时(由值 "1970-01-01T00:00:00.0Z
" 表示的时间)到解析的 日期(忽略闰秒)所经过的毫秒数。
将数字转换为字符串的算法 如下:给定数字
input,返回表示 UTC 时间从 1970-01-01
上午零时(由值 "1970-01-01T00:00:00.0Z
" 表示的时间)到当前 input 毫秒后的 有效日期字符串。
将字符串转换为 Date
对象的算法
如下:给定字符串 input,如果从
input 中解析日期
结果出错,则返回错误;否则,返回一个新的Date
对象,表示解析的 日期 的 UTC 时间的午夜。
将
Date
对象转换为字符串的算法,给定 Date
对象 input,如下:返回表示 input 所在时间的 UTC 时区当前时间的
有效日期字符串。
日期 状态(以及后续章节中描述的其他与日期和时间相关的状态)不适用于无法相对于当代日历确定精确日期和时间的值的输入。例如,它不适用于输入像“宇宙大爆炸后一毫秒”、“侏罗纪早期”或“公元前 250 年的某个冬天”这样的时间。
对于在引入公历之前的日期输入,建议作者不要使用日期
状态(以及后续章节中描述的其他与日期和时间相关的状态),因为用户代理不需要支持将早期时期的日期和时间转换为公历,要求用户手动完成会给用户带来不必要的负担。(这还由于公历是分阶段引入的,这在不同国家发生的时间不同,从 16
世纪中期到 20 世纪初不等。)相反,建议作者使用
选择
元素和 输入
元素与 数字
状态提供细粒度的输入控件。
以下常见的 input
元素内容属性、IDL 属性和方法 适用于该元素:
autocomplete
,
list
,
max
,
min
,
readonly
,
required
,
和
step
内容属性;
list
,
value
,
valueAsDate
,
和
valueAsNumber
IDL 属性;
select()
,
step Down()
,
和
stepUp()
方法。
以下内容属性不得指定且不适用于该元素:
accept
,
alt
,
checked
,
dirname
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
maxlength
,
minlength
,
multiple
,
pattern
,
placeholder
,
popovertarget
,
popovertargetaction
,
src
,
和
width
。
以下 IDL 属性和方法 不适用于
该元素:
checked
,
selectionStart
,
selectionEnd
,
和
selectionDirection
IDL 属性;
setRangeText()
,
和
setSelectionRange()
方法。
type=month
)在所有当前引擎中都支持。
当一个 input
元素的 type
属性处于
月份 状态时,本节中的规则适用。
该 input
元素 表示 一个
控件,用于将元素的
值 设置为
代表特定 月份 的字符串。
如果元素是 可变,用户代理应允许用户更改 其 月份,根据 解析月份 从中获得。用户代理不得允许用户将 值 设置为非空且不是 有效月份字符串 的字符串。如果用户代理提供用于选择 月份 的用户界面,则 值 必须设置为表示用户选择的 有效月份字符串。用户代理应允许用户将 值 设置为空字符串。
约束验证:当用户界面描述的输入用户代理无法转换为 有效月份字符串 时,控件 受到错误输入的影响。
请参阅 引言部分 讨论日期、时间和数字表单控件的输入格式与提交格式之间的差异,以及 实现说明 关于表单控件本地化的内容。
value
属性(如果指定且不为空)必须具有 有效月份字符串 的值。
值清理算法 如下:如果该 值 不是 有效月份字符串,则将其设置为空字符串。
min
属性(如果指定)必须具有 有效月份字符串 的值。max
属性(如果指定)必须具有 有效月份字符串 的值。
step
属性以月份为单位。步长比例因子 为
1(算法使用月份,因此无需转换)。默认步长 为 1 个月。
当元素 步长不匹配 时,用户代理可以将元素的 值 四舍五入到最近的 月份,使元素不再 步长不匹配。
将字符串转换为数字的算法,给定字符串 input,如下:如果从 input 解析月份 结果为错误,则返回错误;否则,返回 1970 年 1 月和解析的 月份 之间的月份数。
将数字转换为字符串的算法,给定数字 input,如下:返回表示 有效月份字符串 的字符串,表示距离 1970 年 1 月 input 个月的 月份。
将字符串转换为 Date
对象的算法,给定字符串
input,如下:
如果从 input 解析月份
结果为错误,则返回错误;否则,返回 一个新的
Date
对象,表示解析的 月份
第一日的午夜 UTC。
将
Date
对象转换为字符串的算法,给定 Date
对象 input,如下:返回一个 有效月份字符串,表示 input 在 UTC 时区表示的当前时间的 月份。
以下通用 input
元素内容
属性、IDL 属性和方法 适用于 该元素:
autocomplete
,
list
,
max
,
min
,
readonly
,
required
,
和
step
内容属性;
list
,
value
,
valueAsDate
,
和
valueAsNumber
IDL 属性;
select()
,
stepDown()
,
和
stepUp()
方法。
以下内容属性不得指定,并且 不适用
于该元素:
accept
,
alt
,
checked
,
dirname
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
maxlength
,
minlength
,
multiple
,
pattern
,
placeholder
,
popovertarget
,
popovertargetaction
,
size
,
src
,
和
width
。
以下 IDL 属性和方法 不适用
于该元素:
checked
,
files
,
selectionStart
,
selectionEnd
,
和
selectionDirection
IDL 属性;
setRangeText()
,
和
setSelectionRange()
方法。
type=week
)当 input
元素的 type
属性为
周
状态时,本节中的规则适用。
该 input
元素 表示 用于设置元素的 值 为表示特定 周 的字符串的控件。
如果元素是 可变的,用户代理应允许用户更改其 值 所表示的 周,通过 解析一个周字符串 获得。用户代理不得允许用户将 值 设置为非空的、非 有效周字符串 的字符串。如果用户代理提供了用于选择 周 的用户界面,那么 值 必须设置为表示用户选择的 有效周字符串。用户代理应允许用户将 值 设置为空字符串。
约束验证:当用户界面描述的输入无法转换为 有效周字符串 时,控件 存在错误输入。
请参阅 介绍部分,讨论日期、时间和数字表单控件的输入格式和提交格式之间的差异,以及有关表单控件本地化的 实现说明。
如果指定且不为空,value
属性的值必须是 有效周字符串。
值清理算法 如下:如果元素的 值 不是 有效周字符串,则将其设置为空字符串。
如果指定,min
属性的值必须是
有效周字符串。如果指定,max
属性的值必须是
有效周字符串。
step
属性以周为单位表示。步长比例因子 为
604,800,000(将周转换为毫秒,与其他算法中使用的单位一致)。默认步长 为 1 周。默认步长基准 为 −259,200,000(1970-W01 周的起始时间)。
当元素 存在步长不匹配 时,用户代理可以将元素的 值 四舍五入到最近的 周,以使元素不会 存在步长不匹配。
将字符串转换为数字的算法 如下:如果 解析一个周字符串
结果出错,则返回错误;否则,返回从 1970-01-01 午夜 UTC(由值 "1970-01-01T00:00:00.0Z
" 表示的时间)到解析出的 周 的星期一凌晨 UTC 的毫秒数,不考虑闰秒。
将数字转换为字符串的算法 如下:返回一个 有效周字符串,表示在 UTC
时间下,从 1970-01-01 午夜 UTC(由值 "1970-01-01T00:00:00.0Z
" 表示的时间)开始 input 毫秒后的 周。
将字符串转换为 Date
对象的算法 如下:如果
解析一个周字符串
结果出错,则返回错误;否则,返回 一个新的
Date
对象,表示解析出的 周 的星期一凌晨
UTC。
将
Date
对象转换为字符串的算法 如下:返回一个
有效周字符串,表示在
UTC 时区中 input 所代表的时间的当前 周。
以下通用 input
元素内容属性、IDL 属性和方法 适用于 该元素:
autocomplete
、
list
、
max
、
min
、
readonly
、
required
和
step
内容属性;
list
、
value
、
valueAsDate
和
valueAsNumber
IDL 属性;
select()
、
stepDown()
和
stepUp()
方法。
以下内容属性不得指定且 不适用于 该元素:
accept
、
alt
、
checked
、
dirname
、
formaction
、
formenctype
、
formmethod
、
formnovalidate
、
formtarget
、
height
、
maxlength
、
minlength
、
multiple
、
pattern
、
placeholder
、
popovertarget
、
popovertargetaction
、
size
、
src
和
width
。
以下 IDL 属性和方法 不适用于
该元素:
checked
、
files
、
selectionStart
、
selectionEnd
和
selectionDirection
IDL 属性;
setRangeText()
和
setSelectionRange()
方法。
type=time
)支持所有当前引擎。
当 input
元素的 type
属性处于
时间
状态时,本节中的规则适用。
该 input
元素 表示 一个控件,用于将元素的 值 设置为表示特定 时间 的字符串。
如果该元素是 可变的,用户代理应允许用户更改其 时间,如通过从中 解析时间 获得的 值。用户代理不得允许用户将 值 设置为非空字符串,除非该字符串是 有效时间字符串。如果用户代理提供用户界面以选择 时间,则 值 必须设置为表示用户选择的 有效时间字符串。用户代理应允许用户将 值 设置为空字符串。
约束验证:当用户界面描述的输入无法由用户代理转换为 有效时间字符串 时,该控件 存在错误输入。
请参阅 介绍部分,讨论日期、时间和数字表单控件的输入格式与提交格式的区别,以及有关表单控件本地化的 实现注意事项。
如果指定并且不为空,value
属性必须具有 有效时间字符串 的值。
值净化算法 如下:如果元素的 值 不是 有效时间字符串,则将其设置为空字符串。
表单控件 具有周期性领域。
如果指定,min
属性必须具有
有效时间字符串
的值。max
属性如果指定,必须具有 有效时间字符串 的值。
step
属性以秒为单位表示。步长比例因子 是
1000(将秒转换为毫秒,正如其他算法中所使用的那样)。默认步长 为 60 秒。
当元素 存在步长不匹配 时,用户代理可以将元素的 值 四舍五入到最接近的 时间,使该元素不会 存在步长不匹配。
将字符串转换为数字的算法 如下:如果 解析 字符串 input 的时间出现错误,则返回错误;否则,返回从午夜到解析出的 时间 的毫秒数。
将数字转换为字符串的算法 如下:返回一个 有效时间字符串,表示从午夜开始后 input 毫秒的 时间。
将字符串转换为 Date
对象的算法 如下:如果
解析 字符串
input 的时间出现错误,则返回错误;否则,返回一个 新的 Date
对象,表示 UTC 时间 1970-01-01 的解析 时间。
将
Date
对象转换为字符串的算法 如下:返回一个
有效时间字符串,表示由
input 表示的 UTC 时间组件。
以下常见 input
元素内容属性、IDL 属性和方法 适用于 该元素:
autocomplete
、
list
、
max
、
min
、
readonly
、
required
和
step
内容属性;
list
、
value
、
valueAsDate
和
valueAsNumber
IDL 属性;
select()
、
stepDown()
和
stepUp()
方法。
以下内容属性不得指定并且 不适用 于该元素:
accept
、
alt
、
checked
、
dirname
、
formaction
、
formenctype
、
formmethod
、
formnovalidate
、
formtarget
、
height
、
maxlength
、
minlength
、
multiple
、
pattern
、
placeholder
、
popovertarget
、
popovertargetaction
、
size
、
src
和
width
。
以下 IDL 属性和方法 不适用
于该元素:
checked
、
files
、
selectionStart
、
selectionEnd
和
selectionDirection
IDL 属性;
setRangeText()
和
setSelectionRange()
方法。
type=datetime-local
)
所有当前引擎均支持。
当 input
元素的 type
属性处于 本地日期和时间
状态时,本节中的规则适用。
input
元素 表示 用于将元素的 值 设置为表示 本地日期和时间 的字符串的控件,没有时区偏移信息。
如果元素是 可变的,用户代理应允许用户更改其 日期和时间,如从中 值 解析出。用户代理不得允许用户将 值 设置为非空字符串,该字符串不是 有效的规范化本地日期和时间字符串。如果用户代理提供选择 本地日期和时间 的用户界面,则 值 必须设置为表示用户选择的 有效的规范化本地日期和时间字符串。用户代理应允许用户将 值 设置为空字符串。
约束验证:当用户界面描述的输入无法转换为 有效的规范化本地日期和时间字符串 时,控件 遇到错误输入。
请参阅 引言部分 讨论日期、时间和数字表单控件的输入格式和提交格式之间的差异,以及 实现说明 以了解表单控件的本地化。
如果指定且非空,value
属性必须具有 有效的本地日期和时间字符串 值。
值清理算法 如下:如果元素的 值 是 有效的本地日期和时间字符串,则将其设置为表示相同日期和时间的 有效的规范化本地日期和时间字符串;否则,将其设置为空字符串。
如果指定,min
属性必须具有 有效的本地日期和时间字符串 值。max
属性如果指定,必须具有 有效的本地日期和时间字符串 值。
step
属性以秒为单位表示。步长比例因子 为 1000(将秒转换为算法中使用的毫秒)。默认步长 为 60 秒。
当元素 遇到步长不匹配 时,用户代理可以将元素的 值 舍入到最近的 本地日期和时间,该日期和时间不导致元素 遇到步长不匹配。
将字符串转换为数字的算法,给定一个字符串 input,如下:如果 从 input 解析日期和时间 结果出错,则返回错误;否则,返回从 1970-01-01 凌晨到解析出的 本地日期和时间 的毫秒数,忽略闰秒。
将数字转换为字符串的算法,给定一个数字 input,如下:返回表示从 1970-01-01 凌晨 input 毫秒后的日期和时间的 有效规范化本地日期和时间字符串。
以下常见 input
元素内容属性、IDL 属性和方法适用于该元素:
autocomplete
、
list
、
max
、
min
、
readonly
、
required
和
step
内容属性;
list
、
value
和
valueAsNumber
IDL 属性;
select()
、
stepDown()
和
stepUp()
方法。
以下内容属性不得指定且 不适用
于元素:
accept
、
alt
、
checked
、
dirname
、
formaction
、
formenctype
、
formmethod
、
formnovalidate
、
formtarget
、
height
、
maxlength
、
minlength
、
multiple
、
pattern
、
placeholder
、
popovertarget
、
popovertargetaction
、
size
、
src
和
width
。
以下 IDL 属性和方法 不适用于
元素:
checked
、
files
、
selectionStart
、
selectionEnd
、
selectionDirection
和
valueAsDate
IDL 属性;
setRangeText()
和
setSelectionRange()
方法。
以下示例展示了一个航班预订应用程序的一部分。该应用程序使用 input
元素,其 type
属性设置为
datetime-local
,
并在所选机场的时区中解释给定的日期和时间。
< fieldset >
< legend > Destination</ legend >
< p >< label > Airport: < input type = text name = to list = airports ></ label ></ p >
< p >< label > Departure time: < input type = datetime-local name = totime step = 3600 ></ label ></ p >
</ fieldset >
< datalist id = airports >
< option value = ATL label = "Atlanta" >
< option value = MEM label = "Memphis" >
< option value = LHR label = "London Heathrow" >
< option value = LAX label = "Los Angeles" >
< option value = FRA label = "Frankfurt" >
</ datalist >
type=number
)在所有当前引擎中均支持。
当 input
元素的 type
属性处于
数字 状态时,本节的规则适用。
input
元素 表示
一个用于将元素的 值
设置为表示数字的字符串的控件。
如果该元素是 可变的,用户代理应允许用户更改其 值 所代表的数字,依据的是应用 解析浮点数值的规则。用户代理不得允许用户将 值 设置为非空但不是 有效浮点数 的字符串。如果用户代理提供了选择数字的用户界面,则 值 必须设置为表示用户选择的数字的 最佳表示。用户代理应允许用户将 值 设置为空字符串。
约束验证:当用户界面描述的输入无法转换为 有效浮点数 时,控件 遇到错误输入。
本规范未定义用户代理应使用的用户界面;建议用户代理供应商考虑什么最能满足其用户的需求。例如,在波斯或阿拉伯市场中的用户代理可能支持波斯和阿拉伯数字输入(将其转换为上述描述的提交格式)。同样,为罗马市场设计的用户代理可能会以罗马数字而不是十进制显示值;或者(更现实地)为法国市场设计的用户代理可能会在千位之间显示撇号,在小数点前显示逗号,并允许用户以这种方式输入值,内部将其转换为上述描述的提交格式。
值清理算法 如下:如果元素的 值 不是 有效浮点数,则将其设置为空字符串。
如果指定,min
属性必须具有 有效浮点数 值。max
属性如果指定,必须具有 有效浮点数 值。
步长比例因子 为 1。默认步长 为 1(仅允许用户选择整数,除非 步长基数 具有非整数值)。
当元素 遇到步长不匹配 时,用户代理可以将元素的 值 四舍五入到最接近的不会 步长不匹配 的数。如果有两个这样的数字,建议用户代理选择最接近正无穷的那个。
将字符串转换为数字的算法 如下:如果将 input 应用于 解析浮点数值的规则 结果出错,则返回错误;否则,返回结果数值。
将数字转换为字符串的算法 如下:返回一个表示 input 的 有效浮点数。
以下通用 input
元素内容属性、IDL 属性和方法 适用于 该元素:
autocomplete
、
list
、
max
、
min
、
placeholder
、
readonly
、
required
和
step
内容属性;
list
、
value
和
valueAsNumber
IDL 属性;
select()
、
stepDown()
和
stepUp()
方法。
以下内容属性不得指定且 不适用
于该元素:
accept
、
alt
、
checked
、
dirname
、
formaction
、
formenctype
、
formmethod
、
formnovalidate
、
formtarget
、
height
、
maxlength
、
minlength
、
multiple
、
pattern
、
popovertarget
、
popovertargetaction
、
size
、
src
和
width
。
以下 IDL 属性和方法 不适用
于该元素:
checked
、
files
、
selectionStart
、
selectionEnd
、
selectionDirection
和
valueAsDate
IDL 属性;
setRangeText()
和
setSelectionRange()
方法。
以下是使用数字输入控件的示例:
< label > 你想收取多少?$< input type = number min = 0 step = 0.01 name = price ></ label >
如上所述,用户代理可能支持用户本地格式的数字输入,并将其转换为上述所需的提交格式。这可能包括处理分组分隔符(如“872,000,000,000”)和各种小数分隔符(如“3,99”与“3.99”),或使用本地数字(如阿拉伯、天城文、波斯和泰文数字)。
当输入内容仅由数字组成但严格来说不是数字时,type=number
状态是不合适的。例如,它不适用于信用卡号或美国邮政编码。判断是否使用 type=number
的一个简单方法是考虑输入控件是否适合具有旋转框界面(例如带有“上”和“下”箭头)。在信用卡号最后一位错了 1
并不是一个小错误,它和所有数字都错了没有区别。因此,不适合用户使用“上”和“下”按钮选择信用卡号。当旋转框界面不合适时,type=text
可能是正确的选择(可能带有 inputmode
或 pattern
属性)。
type=range
)Support in all current engines.
当input
元素的type
属性处于范围状态时,本节的规则适用。
该input
元素表示一个用于设置元素的
值
为一个表示数字的字符串的控件,但前提是精确值并不重要,从而使得用户代理可以提供比
数字状态更简单的界面。
如果元素是可变的,用户代理应允许用户更改其 值,如通过将 解析浮点数值的规则 应用于其获取。用户代理不得允许用户将值设置为非 有效浮点数的字符串。如果用户代理提供了用于选择数字的用户界面,则值必须设置为表示用户选择的 最佳浮点数表示的值。用户代理不得允许用户将值设置为空字符串。
约束验证:当用户界面描述的输入用户代理无法转换为 有效浮点数时,控件 存在错误输入。
值净化算法如下:如果元素的 值不是 有效浮点数,则将其设置为 最佳浮点数表示的 默认值。
默认值是最小值 加上最小值和最大值之间差的一半,除非最大值小于最小值,此时默认值为最小值。
当元素存在下溢时,用户代理必须将元素的 值设置为最小值的 最佳浮点数表示。
当元素存在上溢时,如果最大值不小于最小值,用户代理必须将元素的 值 设置为表示最大值的 有效浮点数。
当元素存在步长不匹配时,用户代理必须将元素的 值舍入到满足以下条件的最接近的数字,该数字不会使元素 存在步长不匹配,且大于或等于最小值,并且如果最大值不小于最小值,则该值小于或等于最大值。如果有两个符合这些条件的数字,则用户代理必须使用最接近正无穷的那个数字。
例如,标记
<input type="range" min=0 max=100 step=20 value=50>
的结果是初始值为 60 的范围控件。
以下是使用自动完成功能列表和list
属性的范围控件示例。这在全范围控件中某些值特别重要时会很有用,例如在作为速度控制器使用的范围控件中预配置的亮度或典型速度限制。以下标记片段:
< input type = "range" min = "-100" max = "100" value = "0" step = "10" name = "power" list = "powers" >
< datalist id = "powers" >
< option value = "0" >
< option value = "-30" >
< option value = "30" >
< option value = "++50" >
</ datalist >
...应用以下样式表:
input { writing-mode : vertical-lr; height : 75 px ; width : 49 px ; background : #D5CCBB; color : black; }
...可能渲染为:
请注意用户代理如何根据样式表指定的高度和宽度属性的比例确定控件的方向。颜色同样从样式表中得出。然而,刻度标记是从标记中派生的。特别是,step
属性未影响刻度标记的位置,用户代理决定只使用作者指定的完成值,然后在极端位置添加更长的刻度标记。
还请注意无效值++50
被忽略了。
另一个示例,请考虑以下标记片段:
< input name = x type = range min = 100 max = 700 step = 9.09090909 value = 509.090909 >
用户代理可以以多种方式显示,例如:
或者,或者:
用户代理可以根据样式表中给定的尺寸选择显示哪一个。这将允许它在保持刻度标记相同分辨率的同时显示不同的宽度。
最后,这里是带有两个标记值的范围控件示例:
< input type = "range" name = "a" list = "a-values" >
< datalist id = "a-values" >
< option value = "10" label = "Low" >
< option value = "90" label = "High" >
</ datalist >
使用使控件垂直绘制的样式,它可能如下所示:
在这种状态下,即使在用户输入期间,范围和步长约束也会被强制执行,并且无法将值设置为空字符串。
如果指定了min
属性,则其值必须是有效浮点数。默认最小值为0。如果指定了max
属性,则其值必须是有效浮点数。默认最大值为100。
步长比例因子为1。默认步长为1(仅允许整数,除非min
属性具有非整数值)。
将字符串转换为数字的算法如下:如果将 解析浮点数值的规则 应用于输入结果出现错误,则返回错误;否则,返回结果数字。
将数字转换为字符串的算法如下:返回表示输入的 最佳浮点数表示 的字符串。
以下常见input
元素内容属性、IDL属性和方法适用于该元素:
autocomplete
,
list
,
max
,
min
,
和
step
内容属性;
list
,
value
,
和
valueAsNumber
IDL属性;
stepDown()
和
stepUp()
方法。
以下内容属性不得指定且不适用该元素:
accept
,
alt
,
checked
,
dirname
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
maxlength
,
minlength
,
multiple
,
pattern
,
popovertarget
,
popovertargetaction
,
readonly
,
required
,
size
,
src
,
和
width
。
以下IDL属性和方法不适用该元素:
checked
,
files
,
selectionStart
,
selectionEnd
,
selectionDirection
,
和
valueAsDate
IDL属性;
select()
,
setRangeText()
,
和
setSelectionRange()
方法。
type=color
)在所有当前引擎中支持。
当input
元素的type
属性为
颜色状态时,本节的规则适用。
input
元素表示表示一个颜色井控件,用于设置元素的值
为表示简单颜色的字符串。
在这种状态下,总是有一个选定的颜色,无法将值设置为空字符串。
如果该元素是可变的,用户代理应允许用户更改其值所表示的颜色,如通过将解析简单颜色值的规则应用于其值来获得的颜色。用户代理不得允许用户将值设置为不符合有效的小写简单颜色的字符串。如果用户代理提供了用于选择颜色的用户界面,则值必须设置为用户选择的颜色,使用序列化简单颜色值的规则的结果。用户代理不得允许用户将值设置为空字符串。
对于这样的元素element的输入激活行为 是显示选择器(如果适用)。
约束验证:当用户界面描述了用户代理无法转换为有效的小写简单颜色的输入时,该控件 遇到了错误输入。
如果指定且不为空,value
属性必须具有有效的简单颜色值。
值清理算法如下:如果元素的值是一个有效的简单颜色,
则将其设置为元素的值转换为ASCII小写后的值;
否则,将其设置为字符串"#000000
"。
以下常见input
元素内容属性和IDL属性适用于该元素:
autocomplete
和
list
内容属性;
list
和
value
IDL属性;
select()
方法。
以下内容属性不得指定并且不适用该元素:
accept
,
alt
,
checked
,
dirname
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
max
,
maxlength
,
min
,
minlength
,
multiple
,
pattern
,
placeholder
,
popovertarget
,
popovertargetaction
,
readonly
,
required
,
size
,
src
,
step
,
和
width
。
以下IDL属性和方法不适用该元素:
checked
,
files
,
selectionStart
,
selectionEnd
,
selectionDirection
,
valueAsDate
,
和
valueAsNumber
IDL属性;
setRangeText()
,
setSelectionRange()
,
stepDown()
,
和
stepUp()
方法。
type=checkbox
)支持所有当前引擎。
当input
元素的type
属性为复选框状态时,本节的规则适用。
input
元素表示一个双状态控件,代表元素的选中状态。如果元素的选中状态为真,则控件表示一个正向选择;如果为假,则表示一个负向选择。如果元素的不确定
IDL属性设置为真,则控件的选择应被遮蔽,仿佛控件处于第三种不确定状态。
即使元素的不确定
IDL属性设置为真,控件也从来不是一个真正的三态控件。不确定
IDL属性仅提供第三种状态的外观。
输入激活行为如下:
如果该元素未连接,则返回。
约束验证:如果该元素是必填的,并且其选中状态为假,则该元素缺失。
input.indeterminate [ = value ]
设置时,覆盖复选框 控件的渲染,使当前值不可见。
以下常见input
元素内容属性和IDL属性适用该元素:
checked
,
和
required
内容属性;
checked
和
value
IDL属性。
以下内容属性不得指定并且不适用该元素:
accept
,
alt
,
autocomplete
,
dirname
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
list
,
max
,
maxlength
,
min
,
minlength
,
multiple
,
pattern
,
placeholder
,
popovertarget
,
popovertargetaction
,
readonly
,
size
,
src
,
step
,
和
width
。
以下IDL属性和方法不适用该元素:
files
,
list
,
selectionStart
,
selectionEnd
,
selectionDirection
,
valueAsDate
,
和
valueAsNumber
IDL属性;
select()
,
setRangeText()
,
setSelectionRange()
,
stepDown()
,
和
stepUp()
方法。
type=radio
)在所有当前引擎中支持。
当 input
元素的 type
属性为 单选按钮状态时,本节中的规则适用。
input
元素表示
一个控件,当与其他 input
元素结合使用时,形成一个单选按钮组,其中只有一个控件可以将其选中状态设置为 true。如果元素的选中状态为 true,则控件表示组中的选定控件;如果为 false,则表示组中未选定的控件。
包含 input
元素a的 单选按钮组 还包含所有其他满足以下条件的 input
元素 b:
input
元素 b 的 type
属性处于单选按钮状态。name
属性,它们的 name
属性不为空,并且 a 的 name
属性的值等于 b 的 name
属性的值。一个 树中不能包含一个 input
元素,其 单选按钮组
中仅包含该元素。
当发生以下任何现象时,如果元素的 选中状态在发生后为 true,则同一 单选按钮组 中所有其他元素的 选中状态必须设置为 false:
name
属性被设置、更改或删除。输入激活行为是执行以下步骤:
如果元素未连接,则返回。
约束验证:如果单选按钮组中的元素必需,并且input中 选中状态为 false 的所有元素,则该元素存在缺失问题。
以下示例由于某些原因指定 puppers 同时 必需 和 禁用:
< form >
< p >< label >< input type = "radio" name = "dog-type" value = "pupper" required disabled > Pupper</ label >
< p >< label >< input type = "radio" name = "dog-type" value = "doggo" > Doggo</ label >
< p >< button > Make your choice</ button >
</ form >
如果用户在未先选择 "Doggo" 的情况下尝试提交此表单,则这两个
input
元素将存在缺失问题,因为单选按钮组中的一个元素是必需的(即第一个元素),并且单选按钮组中的两个元素都具有 false 的选中状态。
另一方面,如果用户选择 "Doggo" 然后提交表单,则这两个
input
元素将不会存在缺失问题,因为虽然其中一个是必需的,但并非所有元素都具有
false 的选中状态。
如果 单选按钮组 中没有任何单 选按钮被选中,则它们在界面中将初始为未选中状态,直到其中一个被选中(由用户或脚本)。
以下常见 input
元素内容属性和 IDL 属性 适用于该元素:
checked
和
required
内容属性;
checked
和
value
IDL 属性。
value
IDL 属性处于模式 default/on。
以下内容属性不得指定,并且不适用于该元素:
accept
,
alt
,
autocomplete
,
dirname
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
list
,
max
,
maxlength
,
min
,
minlength
,
multiple
,
pattern
,
placeholder
,
popovertarget
,
popovertargetaction
,
readonly
,
size
,
src
,
step
,
和
width
。
以下 IDL 属性和方法不适用于该元素:
files
,
list
,
selectionStart
,
selectionEnd
,
selectionDirection
,
valueAsDate
,
和
valueAsNumber
IDL 属性;
select()
,
setRangeText()
,
setSelectionRange()
,
stepDown()
,
和
stepUp()
方法。
type=file
)所有当前引擎支持。
当 input
元素的 type
属性处于 文件上传 状态时,本节中的规则适用。
input
元素 表示
一个已选择的文件列表,每个文件包括一个文件名、一个文件类型和一个文件主体(文件内容)。
文件名不得包含 路径组件,即使用户选择了整个目录层次结构或来自不同目录的多个同名文件也是如此。路径组件,对于 文件上传 状态而言,是指由 U+005C 反斜杠字符(\)分隔的文件名部分。
除非设置了 multiple
属性,否则所选文件列表中不得超过一个文件。
对于这样的元素 element,输入激活行为 是为 element 显示选择器(如果适用)。
如果元素是 可变 的,用户代理应该允许用户通过其他方式更改文件列表,例如,通过拖放添加或删除文件。当用户这样做时,用户代理必须 更新元素的文件选择。
如果元素不是 可变 的,用户代理不得允许用户更改元素的选择。
要 更新元素的文件选择,请执行以下步骤:
在给定 element 的用户交互任务源上排队一个元素任务,并执行以下步骤:
约 束验证:如果元素是 必需 的,并且已选择文件列表为空,则该元素 缺少。
所有当前引擎支持。
所有当前引擎支持。
accept
属性可用于向用户代理提供接受文件类型的提示。
如果指定,该属性必须由一组逗号分隔的标记组成,每个标记必须是以下之一的 ASCII 不区分大小写 的匹配项:
audio/*
"video/*
"image/*
"标记不得是其他标记的 ASCII 不区分大小写 的匹配项(即不允许重复)。要从属性中获取标记列表,用户代理必须 按逗号拆分属性值。
用户代理可以使用此属性的值来显示更合适的用户界面,而不是通用的文件选择器。例如,给定值 image/*
,用户代理可以为用户提供使用本地摄像头或从照片集中选择照片的选项;给定值
audio/*
,用户代理可以为用户提供使用耳机麦克风录制片段的选项。
用户代理应防止用户选择不被这些标记之一(或多个)接受的文件。
鼓励作者在寻找特定格式的数据时,同时指定任何 MIME 类型和任何对应的扩展名。
例如,考虑一个将 Microsoft Word 文档转换为 Open Document Format 文件的应用程序。由于 Microsoft Word 文档描述为多种 MIME 类型和扩展名,站点可以列出几种,如下所示:
< input type = "file" accept = ".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document" >
在仅使用文件扩展名描述文件类型的平台上,这里列出的扩展名可用于筛选允许的文档,而 MIME 类型可用于系统的类型注册表(将 MIME 类型映射到系统使用的扩展名),以确定允许的其他扩展名。同样,在没有文件名或扩展名但内部用 MIME 类型标记文档的系统上,可以使用 MIME 类型选择允许的文件,而如果系统有一个将已知扩展名映射到系统使用的 MIME 类型的扩展名注册表,则可以使用扩展名。
扩展名往往模糊不清(例如,有许多格式使用 ".dat
" 扩展名,并且用户通常可以很容易地将文件重命名为 ".doc
" 扩展名,即使它们不是
Microsoft Word 文档),而 MIME 类型往往不可靠(例如,许多格式没有正式注册的类型,并且许多格式实际上使用多种不同的 MIME
类型标记)。提醒作者,像往常一样,从客户端接收的数据应谨慎处理,因为即使用户不是恶意的,并且用户代理完全遵守 accept
属性的要求,数据也可能不符合预期格式。
由于历史原因,value
IDL 属性会在文件名前加上字符串 "C:\fakepath\
"。某些遗留用户代理实际上包含完整路径(这是一个安全漏洞)。因此,以向后兼容的方式从 value
IDL 属性中获取文件名并不容易。以下函数以适当的兼容方式提取文件名:
function extractFilename( path) {
if ( path. substr( 0 , 12 ) == "C:\\fakepath\\" )
return path. substr( 12 ); // modern browser
var x;
x = path. lastIndexOf( '/' );
if ( x >= 0 ) // Unix-based path
return path. substr( x+ 1 );
x = path. lastIndexOf( '\\' );
if ( x >= 0 ) // Windows-based path
return path. substr( x+ 1 );
return path; // just the filename
}
可以如下使用:
< p >< input type = file name = image onchange = "updateFilename(this.value)" ></ p >
< p > The name of the file you picked is: < span id = "filename" > (none)</ span ></ p >
< script >
function updateFilename( path) {
var name = extractFilename( path);
document. getElementById( 'filename' ). textContent = name;
}
</ script >
以下常见 input
元素内容属性和 IDL 属性 适用于 该元素:
accept
,
multiple
,
和
required
内容属性;
files
和
value
IDL 属性;
select()
方法。
以下内容属性不得指定,并且 不适用于 该元素:
alt
,
autocomplete
,
checked
,
dirname
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
list
,
max
,
maxlength
,
min
,
minlength
,
pattern
,
popovertarget
,
popovertargetaction
,
placeholder
,
readonly
,
size
,
src
,
step
,
和
width
。
元素的 value
属性必须省略。
以下 IDL 属性和方法 不适用于 该元素:
checked
,
list
,
selectionStart
,
selectionEnd
,
selectionDirection
,
valueAsDate
,
和
valueAsNumber
IDL 属性;
setRangeText()
,
setSelectionRange()
,
stepDown()
,
和
stepUp()
方法。
type=submit
)所有当前引擎都支持。
当 input
元素的 type
属性处于
提交按钮 状态时,本节中的规则适用。
input
元素 表示
一个按钮,当激活时,提交表单。如果该元素有 value
属性,
按钮的标签必须是该属性的值;否则,必须是一个
实现定义
的字符串,意思是“提交”或类似的。
该
元素是一个 按钮,
具体来说是一个 提交按钮。
由于默认标签是 实现定义 的,并且按钮的宽度通常取决于按钮的标签,按钮的宽度可能会泄露一些指纹信息。这些信息很可能与用户代理的身份和用户的区域设置密切相关。
元素的 输入激活行为 给定 event 如下:
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
和 formtarget
属性是 表单提交的属性。
formnovalidate
属性可以用来制作不会触发约束验证的提交按钮。
以下常见的 input
元素内容属性和 IDL 属性 适用于
该元素:
dirname
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
popovertarget
,
和
popovertargetaction
内容
属性; value
IDL 属性。
以下内容属性不得指定并且 不适用于
元素:
accept
,
alt
,
autocomplete
,
checked
,
height
,
list
,
max
,
maxlength
,
min
,
minlength
,
multiple
,
pattern
,
placeholder
,
readonly
,
required
,
size
,
src
,
step
,
和
width
。
以下 IDL 属性和方法 不适用于 该元素:
checked
,
files
,
list
,
selectionStart
,
selectionEnd
,
selectionDirection
,
valueAsDate
,
和
valueAsNumber
IDL 属性;
select()
,
setRangeText()
,
setSelectionRange()
,
stepDown()
,
和
stepUp()
方法。
type=image
)所有当前引擎都支持。
当 input
元素的 type
属性处于
图像按钮 状态时,本节中的规则适用。
input
元素 表示
一个图像,用户可以从中选择一个坐标并提交表单,或者作为按钮提交表单。该元素是一个 按钮,具体来说是一个 提交按钮。
坐标通过发送两个元素条目到服务器来提交表单,这两个条目源自控件的名称,但名称末尾附加了 ".x
" 和 ".y
",分别对应坐标的 x
和 y 组件。
所有当前引擎都支持。
图像由 src
属性提供。src
属性必须存在,并且必须包含一个 有效的非空URL,可能被空格包围,引用一个非交互、可选动画、非分页或非脚本的图像资源。
当发生以下事件时
input
元素的 type
属性第一次设置为 图像按钮 状态(可能在元素首次创建时),并且 src
属性存在input
元素的 type
属性改回 图像按钮
状态,并且 src
属性存在,并且其值自上次 type
属性处于 图像按钮 状态以来已更改input
元素的 type
属性处于 图像按钮 状态,并且 src
属性已设置或更改除非用户代理不支持图像,或其图像支持已被禁用,或用户代理仅按需获取图像,或 src
属性的值为空字符串,否则请执行以下步骤:
如果 url 解析失败,则返回。
令 request 为一个新的 请求,其
URL 是
url,客户端
是元素的 节点文档 的
相关设置对象,目的地 为 "image
",发起类型 为 "input
",
凭据模式 为 "include
",并且其
使用URL凭据标志 被设置。
获取 request,设置 processResponseEndOfBody 为 以下步骤,给定 响应 response:
获取图像必须 延迟加载事件,直到资源被获取后由 网络任务源排队的 任务 已运行。
如果图像成功获取,没有网络错误,并且图像的类型是支持的图像类型,并且该类型的图像是有效的,则该图像被认为是 可用的。如果在图像完全下载之前这是真的,那么在图像获取期间由 任务 队列的每个任务必须适当更新图像的呈现。
用户代理应应用 图像嗅探规则 来确定图像的类型,图像的 相关的内容类型标头 给出官方类型。如果不应用这些规则,则图像的类型必须是由图像的 相关内容类型标头 给出的类型。
用户代理不得支持非图像资源作为 input
元素。用户代理不得运行嵌入在图像资源中的可执行代码。用户代理只能显示多页资源的第一页。用户代理不得允许资源以交互方式运行,但应尊重资源中的任何动画。
所有当前引擎都支持。
alt
属性为无法使用图像的用户和用户代理提供按钮的文本标签。alt
属性必须存在,并且必须包含一个非空字符串,给出在图像不可用时适合的等效按钮标签。
如果 src
属性已设置,并且图像 可用
且用户代理配置为显示该图像,
则元素 表示 一个从由 src
属性指定的图像中选择一个 坐标 的控件。在这种情况下,如果该元素是 可变的,则用户代理应允许用户选择此 坐标。
否则,元素 表示
一个提交按钮,其标签由 alt
属性的值给出。
元素的 输入激活行为 给定 event 如下:
如果元素没有 表单所有者,则返回。
如果用户在显式选择坐标时激活控件,则将元素的 选定坐标 设置为该坐标。
这只有在上述条件下才可能,当元素 表示 一个用于选择此类坐标的控件。即便如此,用户可能在未显式选择坐标的情况下激活控件。
元素的 选定坐标 由 x 组件和 y 组件组成。它最初为 (0, 0)。这些坐标表示相对于元素图像边缘的位置,坐标空间具有向右的正 x 方向和向下的正 y 方向。
x 组件必须是一个 有效的整数,表示范围内的数 −(borderleft+paddingleft) ≤ x ≤ width+borderright+paddingright,其中 width 是图像的渲染宽度,borderleft 是图像左侧的边框宽度,paddingleft 是图像左侧的填充宽度,borderright 是图像右侧的边框宽度,paddingright 是图像右侧的填充宽度,所有尺寸均以 CSS 像素 为单位。
y 组件必须是一个 有效的整数,表示范围内的数 −(bordertop+paddingtop) ≤ y ≤ height+borderbottom+paddingbottom,其中 height 是图像的渲染高度,bordertop 是图像上方的边框宽度,paddingtop 是图像上方的填充宽度,borderbottom 是图像下方的边框宽度,paddingbottom 是图像下方的填充宽度,所有尺寸均以 CSS 像素 为单位。
缺少边框或填充时,其宽度为零 CSS 像素。
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
和 formtarget
属性是 表单提交的属性。
image.width [ = value ]
image.height [ = value ]
这些属性返回图像的实际渲染尺寸,如果尺寸未知,则返回 0。
它们可以设置,以更改相应的内容属性。
以下常见的 input
元素内容属性和 IDL 属性 适用于
该元素:
alt
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
popovertarget
,
popovertargetaction
,
src
,
和
width
内容属性;
value
IDL 属性。
以下内容属性不得指定并且 不适用于
元素:
accept
,
autocomplete
,
checked
,
dirname
,
list
,
max
,
maxlength
,
min
,
minlength
,
multiple
,
pattern
,
placeholder
,
readonly
,
required
,
size
,
和
step
。
元素的 value
属性必须省略。
以下 IDL 属性和方法 不适用于 该元素:
checked
,
files
,
list
,
selectionStart
,
selectionEnd
,
selectionDirection
,
valueAsDate
,
和
valueAsNumber
IDL 属性;
select()
,
setRangeText()
,
setSelectionRange()
,
stepDown()
,
和
stepUp()
方法。
此状态的许多行为与 img
元素的行为类似。建议读者阅读该部分,其中更详细地描述了许多相同的要求。
以下是一个表单示例:
< form action = "process.cgi" >
< input type = image src = map.png name = where alt = "Show location list" >
</ form >
如果用户点击图像的坐标 (127,40),用于提交表单的 URL
将为 "process.cgi?where.x=127&where.y=40
"。
(在此示例中,假设对于看不到地图的用户,他们只会看到一个标有“显示位置列表”的按钮,点击该按钮将导致服务器显示一个位置列表以供选择,而不是地图。)
type=reset
)所有当前引擎都支持。
当 input
元素的 type
属性处于 重置按钮 状态时,本节中的规则适用。
input
元素 表示
一个按钮,当激活时,重置表单。如果元素有 value
属性,按钮的标签必须是该属性的值;否则,必须是一个实现定义的字符串,表示“重置”或类似的意思。该元素是一个 按钮。
由于默认标签是实现定义的,并且按钮的宽度通常取决于按钮的标签,按钮的宽度可能会泄露一些可用于指纹识别的信息。这些信息很可能与用户代理的身份和用户的区域设置密切相关。
元素的 输入激活行为 如下:
约束验证:该元素 不受约束验证 影响。
value
IDL 属性 适用于 该元素,并且处于 默认 模式。
以下常见的 input
元素内容属性 适用于 该元素:
popovertarget
和
popovertargetaction
。
以下内容属性不得指定,并且 不适用于 该元素:
accept
,
alt
,
autocomplete
,
checked
,
dirname
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
list
,
max
,
maxlength
,
min
,
minlength
,
multiple
,
pattern
,
placeholder
,
readonly
,
required
,
size
,
src
,
step
,
和
width
。
以下 IDL 属性和方法 不适用于 该元素:
checked
,
files
,
list
,
selectionStart
,
selectionEnd
,
selectionDirection
,
valueAsDate
,
和
valueAsNumber
IDL 属性;
select()
,
setRangeText()
,
setSelectionRange()
,
stepDown()
,
和
stepUp()
方法。
type=button
)所有当前引擎都支持。
当 input
元素的 type
属性处于 按钮
状态时,本节中的规则适用。
input
元素 表示
一个没有默认行为的按钮。必须在 value
属性中提供按钮的标签,尽管它可以是空字符串。如果元素具有 value
属性,按钮的标签必须是该属性的值;否则,必须是空字符串。该元素是一个 按钮。
该元素没有 输入激活行为。
约束验证:该元素 不受约束验证 影响。
value
IDL 属性 适用于 该元素,并且处于 默认 模式。
以下常见的 input
元素内容属性 适用于 该元素:
popovertarget
和
popovertargetaction
。
以下内容属性不得指定,并且 不适用于
该元素:
accept
,
alt
,
autocomplete
,
checked
,
dirname
,
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
formtarget
,
height
,
list
,
max
,
maxlength
,
min
,
minlength
,
multiple
,
pattern
,
placeholder
,
readonly
,
required
,
size
,
src
,
step
,
和
width
。
以下 IDL 属性和方法 不适用于 该元素:
checked
,
files
,
list
,
selectionStart
,
selectionEnd
,
selectionDirection
,
valueAsDate
,
和
valueAsNumber
IDL 属性;
select()
,
setRangeText()
,
setSelectionRange()
,
stepDown()
,
和
stepUp()
方法。
本节是非规范性的。
在日期、时间和数字控件中显示给用户的格式与用于表单提交的格式无关。
鼓励浏览器使用用户界面,按照input
元素的
语言
或用户首选语言的习惯显示日期、时间和数字。使用页面的语言将确保与页面提供的数据保持一致。
例如,如果一个美国英语页面声称 Cirque De Soleil 演出将在 02/03 上演,但用户的浏览器配置为使用英国英语区域,票务购买日期选择器中只显示 03/02 的日期,这对用户来说会非常困惑。使用页面的语言至少可以确保日期在所有地方都以相同的格式显示。(当然,仍然存在用户可能迟到一个月的风险,但对于这种文化差异,我们能做的也只有这么多了……)
input
元素属性
这些属性仅当 input
元素的 type
属性处于其定义声明该属性
适用
的状态时才适用。当一个属性不适用于 input
元素时,用户代理必须忽略该属性,不论以下的要求和定义如何。
maxlength
和 minlength
属性支持所有当前引擎。
支持所有当前引擎。
支持所有当前引擎。
maxlength
属性当 适用 时,是一个
表单控件的
maxlength
属性。
支持所有当前引擎。
minlength
属性当 适用 时,是一个
表单控件的
minlength
属性。
如果 input
元素具有 最大允许值长度,
那么该元素的 value
属性的值的 长度必须小于或等于该元素的 最大允许值长度。
以下示例显示了如何将消息客户端的文本输入限制为固定数量的字符,从而强制通过此媒介进行的任何对话简短,并阻止智能对话。
< label > What are you doing? < input name = status maxlength = 140 ></ label >
这里,密码设置了最小长度:
< p >< label > Username: < input name = u required ></ label >
< p >< label > Password: < input name = p required minlength = 12 ></ label >
size
属性size
属性
指定在视觉呈现中,用户代理在用户编辑元素的value时允许用户看到的字符数量。
size
属性(如果指定)必须具有一个值,
该值是一个大于零的有效的非负整数。
如果存在该属性,则必须使用解析非负整数的规则解析其值,如果结果是一个大于零的数字,则用户代理 应确保至少有这么多字符可见。
size
IDL
属性仅限于大于零的正数,并且具有默认值为20。
readonly
属性支持所有当前引擎。
支持所有当前引擎。
支持所有当前引擎。
readonly
属性是一个布尔属性,它控制用户是否可以编辑
表单控件。一旦指定,该元素就不可变。
约束验证:如果readonly
属性在input
元素上指定,则该元素将被排除在约束验证之外。
disabled
和 readonly
之间的区别在于只读控件仍然可以
使用,而禁用的控件在启用之前通常不能作为控件使用。这在本规范的其他地方有更详细的说明,带有规范要求引用了disabled概念(例如,元素的激活行为,它是否是一个可聚焦区域,或者
构造表单数据集时)。与禁用控件的用户交互相关的任何其他行为,例如是否可以选择或复制文本,不在本标准中定义。
只有文本控
件可以设置为只读,因为对于其他控件(例如复选框和按钮)来说,只读和禁用之间没有有用的区别,因此readonly
属性不适用。
在以下示例中,现有的产品标识符不能被修改,但它们仍然显示为表单的一部分,以便与表示新产品的行保持一致(新产品的标识符尚未填写)。
< form action = "products.cgi" method = "post" enctype = "multipart/form-data" >
< table >
< tr > < th > Product ID < th > Product name < th > Price < th > Action
< tr >
< td > < input readonly = "readonly" name = "1.pid" value = "H412" >
< td > < input required = "required" name = "1.pname" value = "Floor lamp Ulke" >
< td > $< input required = "required" type = "number" min = "0" step = "0.01" name = "1.pprice" value = "49.99" >
< td > < button formnovalidate = "formnovalidate" name = "action" value = "delete:1" > Delete</ button >
< tr >
< td > < input readonly = "readonly" name = "2.pid" value = "FG28" >
< td > < input required = "required" name = "2.pname" value = "Table lamp Ulke" >
< td > $< input required = "required" type = "number" min = "0" step = "0.01" name = "2.pprice" value = "24.99" >
< td > < button formnovalidate = "formnovalidate" name = "action" value = "delete:2" > Delete</ button >
< tr >
< td > < input required = "required" name = "3.pid" value = "" pattern = "[A-Z0-9]+" >
< td > < input required = "required" name = "3.pname" value = "" >
< td > $< input required = "required" type = "number" min = "0" step = "0.01" name = "3.pprice" value = "" >
< td > < button formnovalidate = "formnovalidate" name = "action" value = "delete:3" > Delete</ button >
</ table >
< p > < button formnovalidate = "formnovalidate" name = "action" value = "add" > Add</ button > </ p >
< p > < button name = "action" value = "update" > Save</ button > </ p >
</ form >
required
属性required
属性是一个布尔属性。一旦指定,该元素就必须填充。
约束验证:如果元素是必须的,并且其value
IDL属性适用并处于value模式,
并且该元素是可变的,并且元素的value为空字符串,
那么该元素就缺失。
以下表单有两个必填字段,一个是邮箱地址,一个是密码。它还有第三个字段,只有当用户在密码字段和这个第三个字段中输入相同的密码时才被认为是有效的。
< h1 > Create new account</ h1 >
< form action = "/newaccount" method = post
oninput = "up2.setCustomValidity(up2.value != up.value ? 'Passwords do not match.' : '')" >
< p >
< label for = "username" > Email address:</ label >
< input id = "username" type = email required name = un >
< p >
< label for = "password1" > Password:</ label >
< input id = "password1" type = password required name = up >
< p >
< label for = "password2" > Confirm password:</ label >
< input id = "password2" type = password name = up2 >
< p >
< input type = submit value = "Create account" >
</ form >
对于单选按钮,如果单选按钮组中的任何一个按钮被选中,则满足required
属性。因此,在以下示例中,任何一个单选按钮都可以被选中,而不仅仅是标记为必需的那个:
< fieldset >
< legend > Did the movie pass the Bechdel test?</ legend >
< p >< label >< input type = "radio" name = "bechdel" value = "no-characters" > No, there are not even two female characters in the movie. </ label >
< p >< label >< input type = "radio" name = "bechdel" value = "no-names" > No, the female characters never talk to each other. </ label >
< p >< label >< input type = "radio" name = "bechdel" value = "no-topic" > No, when female characters talk to each other it's always about a male character. </ label >
< p >< label >< input type = "radio" name = "bechdel" value = "yes" required > Yes. </ label >
< p >< label >< input type = "radio" name = "bechdel" value = "unknown" > I don't know. </ label >
</ fieldset >
为了避免是否需要单选按钮组的混淆,建议作者在组中的所有单选按钮上指定属性。事实上,一般来说,建议作者避免在一开始没有任何初始选中控件的单选按钮组,因为用户无法返回到这种状态,因此通常被认为是较差的用户界面。
multiple
属性所有当前引擎均支持。
所有当前引擎均支持。
multiple
属性是一个布尔属性,表示是否允许用户指定多个值。
以下示例展示了电子邮件客户端的“收件人”字段如何接受多个电子邮件地址。
< label > 收件人: < input type = email multiple name = to ></ label >
如果用户在联系人数据库中有两个朋友“蜘蛛侠”(地址为 "spider@parker.example.net")和“猩红女巫”(地址为 "scarlet@avengers.example.net"),那么当用户输入 "s" 时,用户代理可能会向用户建议这两个电子邮件地址。
该页面还可以从网站链接到用户的联系人数据库:
< label > To: < input type = email multiple name = to list = contacts ></ label >
...
< datalist id = "contacts" >
< option value = "hedral@damowmow.com" >
< option value = "pillar@example.com" >
< option value = "astrophy@cute.example" >
< option value = "astronomy@science.example.org" >
</ datalist >
假设用户在此文本控件中输入了“bob@example.net”,然后开始输入以“s”开头的第二个电子邮件地址。用户代理可能会显示之前提到的两个朋友的电子邮件地址,以及 datalist
元素中给出的 "astrophy" 和
"astronomy" 值。
以下示例展示了电子邮件客户端的“附件”字段如何接受多个文件上传。
< label > 附件: < input type = file multiple name = att ></ label >
pattern
属性所有当前引擎均支持。
所有当前引擎均支持。
pattern
属性指定了表单控件的 值 或者当
multiple
属性 适用
且已设置时,控件的 值
应该匹配的正则表达式。
如果指定,该属性的值必须符合JavaScript Pattern[+UnicodeSetsMode, +N]
生成。
如果<input>元素存在,input
元素的
已编译的模式正则表达式 是一个JavaScript RegExp
对象。其确定方式如下:
如果元素没有指定pattern
属性,则返回空。元素没有已编译的模式正则表达式。
让pattern成为元素的pattern
属性的值。
让regexpCompletion成为 RegExpCreate(pattern, "v
")。
如果 regexpCompletion 是 异常完成,则返回空。元素没有 已编译的模式正则表达式。
建议用户代理在开发者控制台记录此错误,以帮助调试。
让anchoredPattern成为字符串 "^(?:
",后接pattern,后接")$
"。
返回!RegExpCreate(anchoredPattern, "v
")。
这些步骤的原因,而不是直接使用 pattern
属性的值,有两个。
首先,我们要确保当与字符串匹配时,正则表达式的开始锚定在字符串的开始,结束锚定在字符串的结束。其次,我们要确保正则表达式在独立形式中是有效的,而不仅仅是在被"^(?:
"和")$
"锚定包围后才变得有效。
一个RegExp
对象regexp如果input非空,RegExpBuiltinExec(regexp, input)不为空,则匹配字符串input。
约束验证:如果元素的值不是空字符串,并且元素的multiple
属性未指定或input
元素在其type
属性的当前状态下不适用,且元素有已编译的模式正则表达式但该正则表达式不匹配元素的值,则该元素模式不匹配。
约束验证:如果元素的值不是空字符串,并且元素的multiple
属性被指定并适用于input
元素,且元素有已编译的模式正则表达式但该正则表达式不匹配每个元素的值,则该元素模式不匹配。
当 input
元素指定了 pattern
属性时,作者应包含一个 title
属性来描述该模式。用户代理可以在通知用户模式不匹配时,或在其他任何合适的时间(例如作为工具提示或由辅助技术在控件 获得焦点 时读取)使用此属性的内容(如果存在)。
例如,以下代码片段:
< label > Part number:
< input pattern = "[0-9][A-Z]{3}" name = "part"
title = "A part number is a digit followed by three uppercase letters." />
</ label >
...可能会导致用户代理显示如下警告:
零件编号是一个数字,后跟三个大写字母。 您不能在字段不正确时提交此表单。
当控件有pattern
属性时,title
属性(如果使用)必须描述该模式。可以包括其他信息,只要它有助于用户填写控件。否则,辅助技术将受到影响。
例如,如果title属性包含控件的标题,辅助技术可能会最终说出类似于您输入的文本不符合要求的模式。生日,这没有用。
用户代理仍可以在非错误情况下显示title
(例如,作为悬停在控件上时的工具提示),因此作者应注意不要将title
措辞为错误已必然发生。
min
和
max
属性
所有当前引擎均支持。
所有当前引擎均支持。
某些表单控件可以应用明确的约束,限制用户可提供的值的范围。通常,这样的范围是线性且连续的。然而,表单控件可以具有周期性域,在这种情况下,表单控件的最大可能范围是有限的,作者可以在此范围内指定跨越边界的明确范围。
具体来说,type=time
控件的最大范围是午夜到午夜(24小时),作者可以设置连续线性范围(例如从晚上9点到晚上11点)和跨越午夜的不连续范围(例如从晚上11点到凌晨1点)。
min
和 max
属性表示元素的允许值范围。
它们的语法由定义type
属性当前状态的部分定义。
如果元素具有min
属性,并且将min
属性的值应用于将字符串转换为数字的算法的结果是一个数字,那么该数字就是元素的最小值;否则,如果type
属性的当前状态定义了默认最小值,那么这就是最小值
;否则,元素没有最小值
。
如果元素具有max
属性,并且将max
属性的值应用于将字符串转换为数字的算法的结果是一个数字,那么该数字就是元素的最大值;否则,如果type
属性的当前状态定义了默认最大值,那么这就是最大值
;
否则,元素没有最大值
。
如果元素没有周期性域,则max
属性的值(最大值)不得小于min
属性的值(其最小值)。
如果一个元素没有周期性域,且其最大值小于其最小值,那么只要该元素有值,它将要么下溢要么上溢。
如果一个元素具有周期性域,且其最大值小于其最小值,则该元素范围倒置。
约束验证:当元素有最小值且没有范围倒置,并且将元素的值应用于将字符串转换为数字的算法的结果是一个数字,并且从该算法获得的数字小于最小值时,元素下溢。
约束验证:当元素有最大值且没有范围倒置,并且将元素的值应用于将字符串转换为数字的算法的结果是一个数字,并且从该算法获得的数字大于最大值时,元素上溢。
约束验证:当元素范围倒置,并且将元素的值应用于将字符串转换为数字的算法的结果是一个数字,并且从该算法获得的数字大于最大值且小于最小值时,元素同时下溢和上溢。
以下日期控件将输入限制为1980年代之前的日期:
< input name = bday type = date max = "1979-12-31" >
以下数字控件将输入限制为大于零的整数:
< input name = quantity required = "" type = "number" min = "1" value = "1" >
以下时间控件将输入限制为晚上9点到早上6点之间的分钟,默认为午夜:
< input name = "sleepStart" type = time min = "21:00" max = "06:00" step = "60" value = "00:00" >
step
属性所有当前引擎均支持。
step
属性通过限制允许值来指示预期(并要求)的值或值的粒度。定义type
属性当前状态的部分还定义了默认步进、步进比例因子,在某些情况下还定义了默认步进基准,这些在处理属性时如下所述。
如果指定,step
属性必须具有有效的浮点数值,该值解析为大于零的数字,或必须具有与字符串"any
"的ASCII大小写不敏感匹配的值。
该属性为元素提供了允许值步进,如下所示:
否则,如果属性值与字符串"any
"的ASCII大小写不敏感匹配,则没有允许值步进。
步进基准是以下算法返回的值:
如果元素具有min
内容属性,并且将min
内容属性的值应用于将字符串转换为数字的算法的结果不是错误,则返回该结果。
如果元素具有value
内容属性,并且将value
内容属性的值应用于将字符串转换为数字的算法的结果不是错误,则返回该结果。
返回零。
约束验证:当元素具有允许值步进,并且将元素的值应用于将字符串转换为数字的算法的结果是一个数字,并且该数字减去步进基准不是允许值步进的整数倍时,元素步进不匹配。
以下范围控件仅接受0到1范围内的值,并允许该范围内的256步:
< input name = opacity type = range min = 0 max = 1 step = 0.00392156863 >
以下控件允许选择一天中的任何时间,精度可以达到任意程度(例如千分之一秒或更高):
< input name = favtime type = time step = any >
通常,时间控件的精度限制为一分钟。
list
属性所有当前引擎均支持。
list
属性用于标识列出建议用户的预定义选项的元素。
建议来源元素是树中第一个具有与list
属性值相等的ID的元素,如果该元素是datalist
元素。如果没有list
属性,或者没有具有该ID的元素,或者第一个具有该ID的元素不是datalist
元素,则没有建议来源元素。
如果有建议来源元素,则当用户代理允许用户编辑input
元素的值时,用户代理应以适合所用控件类型的方式向用户提供由建议来源元素表示的建议。如果适用,用户代理应使用建议的标签和值来向用户标识建议。
当建议数量较多时,鼓励用户代理过滤由建议来源元素表示的建议,只包含最相关的建议(例如基于用户迄今为止的输入)。没有定义精确的阈值,但将列表限制在四到七个值是合理的。如果基于用户的输入进行过滤,用户代理应在建议的标签和值中进行匹配。用户代理应考虑输入变化如何影响匹配过程。应应用Unicode规范化,以便不同的Unicode代码点序列不会干扰匹配过程。应忽略大小写变化,这可能需要特定语言的大小写映射。有关这些的示例,请参见Character Model for the World Wide Web: String Matching。用户代理还可以提供其他匹配功能,例如匹配不同形式的假名到彼此(或到汉字),忽略重音,或应用拼写校正。[CHARMODNORM]
此文本字段允许您选择一种JavaScript函数类型。
< input type = "text" list = "function-types" >
< datalist id = "function-types" >
< option value = "function" > function</ option >
< option value = "async function" > async function</ option >
< option value = "function*" > generator function</ option >
< option value = "=>" > arrow function</ option >
< option value = "async =>" > async arrow function</ option >
< option value = "async function*" > async generator function</ option >
</ datalist >
然后,输入"arrow"或"=>"会将列表过滤到标签为"arrow function"和"async arrow function"的条目。输入"generator"或"*"会将列表过滤到标签为"generator function"和"async generator function"的条目。
一如既往,用户代理可以根据其特定需求和用户的特定情况做出适当的用户界面决策。然而,这一直是实现者、Web开发人员和用户的困惑领域,因此我们在上面给出了一些“应该”的建议。
如何处理用户对建议的选择取决于元素是仅接受单个值的控件,还是接受多个值:
multiple
属性,或者multiple
属性不适用type
属性处于Email状态,并且元素指定了multiple
属性
当用户选择一个建议时,用户代理必须向input
元素的值添加一个新条目,该条目的值是所选建议的值,或者将现有条目更改为所选建议的值,就像用户自己添加或编辑了一个条目一样。具体的行为取决于用户界面的实现定义方式。
此URL字段提供一些建议。
< label > Homepage: < input name = hp type = url list = hpurls ></ label >
< datalist id = hpurls >
< option value = "https://www.google.com/" label = "Google" >
< option value = "https://www.reddit.com/" label = "Reddit" >
</ datalist >
用户历史记录中的其他URL也可能显示;这取决于用户代理。
此示例演示了如何设计一个使用自动完成列表功能的表单,同时在旧版用户代理中仍有用。
如果自动完成列表只是一个辅助,并且对内容不重要,那么只需使用具有子option
元素的datalist
元素即可。为了防止值在旧版用户代理中呈现,需要将它们放在value
属性中,而不是内联。
< p >
< label >
Enter a breed:
< input type = "text" name = "breed" list = "breeds" >
< datalist id = "breeds" >
< option value = "Abyssinian" >
< option value = "Alpaca" >
<!-- ... -->
</ datalist >
</ label >
</ p >
但是,如果需要在旧版用户代理中显示这些值,则可以将回退内容放在datalist
元素中,如下所示:
< p >
< label >
Enter a breed:
< input type = "text" name = "breed" list = "breeds" >
</ label >
< datalist id = "breeds" >
< label >
or select one from the list:
< select name = "breed" >
< option value = "" > (none selected)
< option > Abyssinian
< option > Alpaca
<!-- ... -->
</ select >
</ label >
</ datalist >
</ p >
回退内容将仅在不支持datalist
的用户代理中显示。另一方面,选项将被所有用户代理检测到,即使它们不是datalist
元素的子元素。
请注意,如果在datalist
中使用的option
元素被selected
,则它将在默认情况下由旧版用户代理选择(因为它会影响select
元素),但它不会对支持datalist
的用户代理中的input
元素产生任何影响。
placeholder
属性所有当前引擎均支持。
Element/input#attr-placeholder
所有当前引擎均支持。
placeholder
属性表示一个简短的提示(一个词或短语),旨在在控件没有值时帮助用户输入数据。提示可以是示例值或预期格式的简要描述。如果指定了该属性,其值不能包含U+000A换行符(LF)或U+000D回车符(CR)字符。
placeholder
属性不应作为label
的替代品使用。对于较长的提示或其他建议性文本,title
属性更为合适。
这些机制非常相似但有细微差别:控件的label
提供的提示始终显示;placeholder
属性提供的简短提示在用户输入值之前显示;而title
属性中的提示在用户请求进一步帮助时显示。
用户代理应在控件的value为空字符串时向用户展示这个提示,尤其是在控件未聚焦的情况下,展示前应移除提示中的换行符。
如果用户代理通常在控件聚焦时不显示这个提示,那么如果控件因autofocus
属性而聚焦,用户代理仍应显示提示,因为在这种情况下用户在控件聚焦前没有机会查看它。
下面是一个使用placeholder
属性的邮件配置用户界面的示例:
< fieldset >
< legend > Mail Account</ legend >
< p >< label > Name: < input type = "text" name = "fullname" placeholder = "John Ratzenberger" ></ label ></ p >
< p >< label > Address: < input type = "email" name = "address" placeholder = "john@example.net" ></ label ></ p >
< p >< label > Password: < input type = "password" name = "password" ></ label ></ p >
< p >< label > Description: < input type = "text" name = "desc" placeholder = "My Email Account" ></ label ></ p >
</ fieldset >
在控件内容有一种方向性而占位符需要有不同方向性的情况下,可以在属性值中使用Unicode的双向算法格式字符:
< input name = t1 type = tel placeholder = " ‫ رقم الهاتف 1 ‮ " >
< input name = t2 type = tel placeholder = " ‫ رقم الهاتف 2 ‮ " >
为了稍微更清楚一点,下面是使用数字字符引用而不是内联阿拉伯语的相同示例:
< input name = t1 type = tel placeholder = " ‫ رقم الهاتف 1 ‮ " >
< input name = t2 type = tel placeholder = " ‫ رقم الهاتف 2 ‮ " >
input
元素 APIinput.value [ = value ]
返回表单控件的当前值。
可以设置以更改值。
如果控件是文件上传控件且设置为非空字符串,则抛出"InvalidStateError
" DOMException
。
input.checked [ = value ]
返回表单控件的当前checkedness。
可以设置以更改checkedness。
input.files [ = files ]
Support in all current engines.
Support in all current engines.
返回一个列出表单控件所选文件的FileList
对象。
如果控件不是文件控件,则返回null。
input.valueAsDate [ = value ]
返回一个表示表单控件的值的Date
对象(如果适用);否则返回null。
可以设置以更改值。
如果控件不是基于日期或时间的,则抛出"InvalidStateError
" DOMException
。
input.valueAsNumber [ = value ]
返回一个表示表单控件的值的数字(如果适用);否则返回NaN。
可以设置以更改值。将其设置为NaN将把基础值设置为空字符串。
如果控件既不是基于日期或时间的也不是数字的,则抛出"InvalidStateError
" DOMException
。
input.stepUp([ n ])
input.stepDown([ n ])
更改表单控件的值,以step属性中的值乘以n。n的默认值为1。
如果控件既不是基于日期或时间的也不是数字的,或step
属性的值为"any
",则抛出"InvalidStateError
" DOMException
。
input.list
input.showPicker()
显示适用于input的任何适用的选择器UI,以便用户可以选择一个值。(如果没有为给定控件实现选择器UI,则此方法不执行任何操作。)
如果input不是可变的,则抛出"InvalidStateError
" DOMException
。
如果在没有临时用户激活的情况下调用,则抛出"NotAllowedError
" DOMException
。
如果input位于跨域iframe
内,则抛出"SecurityError
" DOMException
,除非input处于文件上传或颜色状态。
value
IDL属性允许脚本操作值的input
元素。该属性处于以下模式之一,定义其行为:
在获取时,返回元素的当前值。
在设置时:
在获取时,如果元素有value
内容属性,则返回该属性的值;否则返回空字符串。
在设置时,将元素的value
内容属性的值设置为新值。
在获取时,如果元素有value
内容属性,则返回该属性的值;否则返回字符串"on
"。
在设置时,将元素的value
内容属性的值设置为新值。
在获取时,返回字符串"C:\fakepath\
",后跟所选文件列表中第一个文件的名称(如果有);如果列表为空,则返回空字符串。
在设置时,如果新值为空字符串,则清空所选文件列表;否则抛出"InvalidStateError
" DOMException
。
这个“假路径”要求是历史上的一个遗憾事故。有关更多信息,请参见文件上传状态部分的示例。
由于文件列表中的文件名中不允许有路径组件,因此"\fakepath\"不能被误认为是路径组件。
checked
IDL属性允许脚本操作input
元素的checkedness。在获取时,它必须返回元素的当前
checkedness;在设置时,它必须将元素的checkedness设置为新值,并将元素的脏checkedness标志设置为true。
files
IDL属性允许脚本访问元素的选定文件。
在获取时,如果IDL属性适用,则必须返回一个表示当前选定文件的FileList
对象。必须返回相同的对象,直到选定文件列表发生变化。
如果IDL属性不适用,则必须返回null。[FILEAPI]
在设置时,必须运行这些步骤:
valueAsDate
IDL属性表示元素的值,解释为日期。
在获取时,如果valueAsDate
属性不适用,如input
元素的type
属性的当前状态定义的那样,则返回null。否则,运行定义该状态的将字符串转换为Date
对象的算法以获取元素的值;如果算法返回了Date
对象,则返回它,否则返回null。
在设置时,如果valueAsDate
属性不适用,如input
元素的type
属性的当前状态定义的那样,则抛出"InvalidStateError
" DOMException
;否则,如果新值不是null也不是Date
对象,则抛出TypeError
异常;
否则,如果新值为null或表示NaN时间值的Date
对象,则将元素的值设置为空字符串;否则,运行定义该状态的将Date
对象转换为字符串的算法以获取新值,并将元素的值设置为生成的字符串。
valueAsNumber
IDL属性表示元素的值,解释为数字。
在获取时,如果valueAsNumber
属性不适用,如input
元素的type
属性的当前状态定义的那样,则返回非数字值(NaN)。
否则,运行定义该状态的将字符串转换为数字的算法以获取元素的值;
如果算法返回一个数字,则返回它,
否则,返回非数字值(NaN)。
在设置时,如果新值是无限的,则抛出TypeError
异常。
否则,如果valueAsNumber
属性不适用,如input
元素的type
属性的当前状态定义的那样,则抛出"InvalidStateError
" DOMException
。
否则,如果新值是非数字值(NaN),则将元素的值设置为空字符串。否则,运行定义该状态的将数字转换为字符串的算法,
以获取新值,并将元素的值设置为生成的字符串。
stepDown(n)
和stepUp(n)
方法,
在调用时,必须运行以下算法:
如果stepDown()
和stepUp()
方法不适用,如input
元素的type
属性的当前状态定义的那样,则抛出"InvalidStateError
" DOMException
。
如果元素没有允许的值步长,则抛出"InvalidStateError
" DOMException
。
如果元素有一个最小值和一个最大值,并且没有大于或等于 元素的最小值且小于或等于元素的最大值的值,在从步长基数中减去时,是允许的值步长的整数倍,则返回。
如果将字符串转换为数字的算法应用于由元素的值给出的字符串时没有产生错误,则令 value为该算法的结果。否则,令value为零。
令valueBeforeStepping为value。
如果从步长基数中减去value不是允许的值步长的整数倍,则将value设置为最近的值,在从步长基数中减去时,是允许的值步长的整数倍,且小于
value,如果调用的方法是stepDown()
方法,且大于value,否则。
否则(从步长基数中减去value是允许的值步长的整数倍):
令n为参数。
令delta为允许的值步长乘以n。
如果调用的方法是stepDown()
方法,则取delta的相反数。
令value 为将delta加到value的结果。
如果元素有一个最小值,且value小于该最小值,则将 value设置为从步长基数中减去时,是允许的值步长的整数倍的最小值,且大于或等于 minimum。
如果元素有一个最大值,且value大于该最大值,则 将value设置为从步长基数中减去时,是允许的值步长的整数倍的最大值,且小于或等于 maximum。
如果调用的方法是stepDown()
方法且value大于valueBeforeStepping,或调用的方法是stepUp()
方法且value小于valueBeforeStepping,则返回。
令value as string为运行定义该状态的将数字转换为字符串的算法,以获取value的结果。
将元素的值设置为value as string。
list
IDL属性必须返回当前的建议源元素(如果有),否则返回null。
Support in all current engines.
HTMLInputElement
showPicker()
和HTMLSelectElement
showPicker()
方法步骤如下:
如果this不是可变的,则抛出
"InvalidStateError
" DOMException
。
如果this的相关设置对象的来源与
this的
相关设置对象的顶级来源不是同一来源,且
this是select
元素,或者
this的type
属性不在文件上传状态或颜色状态,则抛出
"SecurityError
" DOMException
。
如果this的相关全局对象没有临时激活,则抛出"NotAllowedError
"
DOMException
。
如果this是select
元素,且this未
渲染,则抛出"NotSupportedError
"
DOMException
。
显示选择器,如果适用,用于this。
要为input
或select
元素element显示选择器,如果适用,请执行以下步骤:
如果 element 不是 可变的,则返回。
如果element是input
元素,并且element的type
属性处于文件上传状态,则并行运行这些步骤:
可选地,等待直到此算法的任何先前执行终止。
向用户显示一个提示,要求用户指定一些文件。如果multiple
属性未设置在element上,则不能选择多个文件;否则,可以选择任意数量的文件。文件可以来自文件系统或动态创建,例如,从连接到用户设备的相机拍摄的照片。
等待用户做出选择。
如果用户在未更改选择的情况下关闭了提示,则在用户交互任务源上排队一个元素任务,给定element去触发一个事件,名为cancel
在element上,bubbles
属性初始化为true。
否则,更新文件选择给element。
与所有用户界面规范一样,用户代理在解释这些要求时有很大的自由度。上述文本意味着用户要么取消提示,要么更改选择;其中一个肯定会成立。但是,标准并未强制将这些可能性映射到具体的用户界面元素。例如,用户代理可能将点击“取消”按钮时的操作解释为选择零文件,从而触发input
和change
事件。或者,它可能将此类点击解释为未更改选择的取消,从而触发cancel
事件。同样,重新选择之前选择的相同文件是否计为取消或更改选择取决于用户代理的解释。
否则,用户代理应显示任何相关的用户界面,用于选择element的值,就像用户与控件交互时通常会显示一样。(如果element没有应用此类用户界面,则此步骤不执行任何操作。)
如果显示了此类用户界面,则它必须尊重规范中关于element行为的相关部分的要求,给定其type
属性状态。(例如,各种部分描述了对生成的值字符串的限制。)
此步骤可以有副作用,例如关闭以前由此算法显示的其他选择器。(如果这关闭了文件选择器,则根据上述内容,这将导致触发input
和change
事件,或cancel
事件。)
当input
和change
事件适用时(这适用于所有input
控件,除了按钮和那些type
属性处于 状态的控件),会触发这些事件以指示用户已与控件进行交互。每当用户修改控件的数据时,input
事件就会触发。当值被提交时,change
事件会触发,如果控件失去焦点时也是如此。在所有情况下,input
事件会先于对应的change
事件(如果有的话)触发。
当input
元素有定义的输入激活行为时,如果这些事件适用,则触发这些事件的规则在上方定义type
属性状态的部分中给出。(这适用于所有input
控件,其type
属性处于复选框状态、单选按钮状态或文件上传状态。)
对于没有定义输入激活行为但这些事件适用的input
元素,如果用户界面涉及交互操作和明确的提交操作,当用户更改元素的值时,用户代理必须在input
元素上排队一个元素任务,在input
元素上触发一个名为input
的事件,bubbles
和composed
属性初始化为true;每当用户提交更改时,用户代理必须在input
元素上排队一个元素任务,将其用户有效性设置为true,并在input
元素上触发一个名为change
的事件,bubbles
属性初始化为true。
一个涉及交互操作和提交操作的用户界面的例子是使用滑块的范围控件。当用户使用指点设备拖动控件的旋钮时,每当位置变化时会触发input
事件,而只有当用户松开旋钮提交到特定值时才会触发change
事件。
对于没有定义输入激活行为但这些事件适用的input
元素,如果用户界面涉及明确的提交操作但没有中间操作,每当用户提交对元素值的更
改时,用户代理必须在input
元素上首先触发一个名为input
的事件,bubbles
和composed
属性初始化为true,然后在input
元素上触发一个名为change
的事件,bubbles
属性初始化为true。
一个有提交操作的用户界面的例子是由单个按钮组成的颜色控件,该按钮弹出一个颜色轮:如果只有在对话框关闭时值才会改变,则这就是明确的提交操作。另一方面,如果操作控件时颜色会交互地改变,则可能没有提交操作。
另一个有提交操作的用户界面的例子是允许用户输入文本和从下拉日历中选择日期的日期控件:虽然文本输入可能没有明确的提交步骤,但从下拉日历中选择日期然后关闭下拉框则是提交操作。
对于没有定义输入激活行为但这些事件适用的input
元素,每当用户在没有明确提交操作的情况下导致元素的值变化时,用户代理必须在input
元素上排队一个元素任务,触发一个名为input
的事件,bubbles
和composed
属性初始化为true。相应的change
事件(如果有)将在控件失去焦点时触发。
用户更改元素值的例子包括用户在文本控件中输入、粘贴新值或撤销编辑。某些用户交互不会导致值更改,例如在空文本控件中按“删除”键,或用与剪贴板中完全相同的文本替换控件中的某些文本。
用户用键盘操作并聚焦的范围控件(滑块)是用户更改元素值而无需提交步骤的另一个例子。
对于仅触发input
事件的任务,用户代理可能会等待用户交互的适当间隙再排队这些任务;例如,用户代理可以等待用户在100毫秒内未按键,以便在用户暂停时而不是每次按键时触发事件。
当用户代理要代表用户更改input
元素的值时(例如作为表单预填充功能的一部分),用户代理必须在input
元素上排队一个元素任务,首先相应地更新值,然后在input
元素上触发一个名为input
的事件,bubbles
和composed
属性初始化为true,然后在input
元素上触发一个名为change
的事件,bubbles
属性初始化为true。
这些事件不会响应脚本对表单控件值的更改而触发。(这是为了更容易地响应用户操作控件来更新表单控件的值,而不必过滤脚本自身的更改以避免无限循环。)
当浏览器在导航期间作为状态恢复的一部分更改表 单控件的值时,这些事件也不会触发。
button
元素Support in all current engines.
Support in all current engines.
tabindex
属性的后代。
disabled
—
表单控件是否禁用form
—
将元素与表单元素关联formaction
— 用于表单提交的URLformenctype
— 用于表单提交的条目列表编码类型formmethod
— 用于表单提交的变体
formnovalidate
— 跳过表单提交的表单控件验证
formtarget
— 用于表单提交的导航对象name
— 用于表单提交和form.elements
API中的元素名称popovertarget
— 目标弹出元素的切换、显示或隐藏popovertargetaction
— 指示目标弹出元素是切换、显示还是隐藏type
— 按钮类型value
—
用于表单提交的值[Exposed =Window ]
interface HTMLButtonElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute boolean disabled ;
readonly attribute HTMLFormElement ? form ;
[CEReactions ] attribute USVString formAction ;
[CEReactions ] attribute DOMString formEnctype ;
[CEReactions ] attribute DOMString formMethod ;
[CEReactions ] attribute boolean formNoValidate ;
[CEReactions ] attribute DOMString formTarget ;
[CEReactions ] attribute DOMString name ;
[CEReactions ] attribute DOMString type ;
[CEReactions ] attribute DOMString value ;
readonly attribute boolean willValidate ;
readonly attribute ValidityState validity ;
readonly attribute DOMString validationMessage ;
boolean checkValidity ();
boolean reportValidity ();
undefined setCustomValidity (DOMString error );
readonly attribute NodeList labels ;
};
HTMLButtonElement includes PopoverInvokerElement ;
该元素是一个按钮。
type
属性控制按钮激活时的行为。它是一个枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
submit |
提交按钮 | 提交表单。 |
reset |
重置按钮 | 重置表单。 |
button |
按钮 | 无操作。 |
如果type
属性为提交按钮状态,则该元素是一个特定的提交按钮。
约束验证: 如果type
属性为重置按钮状态或按钮状态,则该元素不参与约束验证。
button
元素 element
的 激活行为给定event如下:
如果element是禁用的,则返回。
运行弹出目标属性激活行为给定element。
form
属性用于显式关联button
元素与其表单所有者。name
属性表示元素的名称。disabled
属性用于使控件不可交互并防止其值被提交。formaction
,
formenctype
,
formmethod
,
formnovalidate
,
和 formtarget
是表单提交的属性。
formnovalidate
属性可用于制作不触发约束验证的提交按钮。
formaction
,
formenctype
,
formmethod
,
formnovalidate
,
和 formtarget
如果元素的type
属性不处于提交按钮状态,则不得指定。
value
属性为表单提交目的提供元素的值。元素的值是其value
属性的值(如果有),否则为空字符串。
按钮(及其值)仅在按钮本身用于启动表单提交时才包含在表单提交中。
value
IDL属性必须反映同名内容属性。
willValidate
,
validity
,
和 validationMessage
IDL属性,以及 checkValidity()
,
reportValidity()
,
和 setCustomValidity()
方法是约束验证 API的一部分。labels
IDL属性提供了元素的标签列表。disabled
,
form
, 和name
IDL属性是元素的表单
API的一部分。
以下按钮标记为“Show hint”,激活时会弹出一个对话框:
< button type = button
onclick = "alert('This 15-20 minute piece was composed by George Gershwin.')" >
Show hint
</ button >
select
元素所有当前引擎支持。
所有当前引擎支持。
option
,
optgroup
,
hr
, 和脚本支持元素。
autocomplete
— 表单自动填充功能的提示disabled
—
表单控件是否禁用form
—
将元素与form
元素关联
multiple
— 是否允许多个值name
— 用于表单提交的元素名称,并在form.elements
API中使用required
— 控件是否必需用于表单提交
size
— 控件的大小multiple
属性或size
属性且值大于1:
作者; 实现者。
[Exposed =Window ]
interface HTMLSelectElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString autocomplete ;
[CEReactions ] attribute boolean disabled ;
readonly attribute HTMLFormElement ? form ;
[CEReactions ] attribute boolean multiple ;
[CEReactions ] attribute DOMString name ;
[CEReactions ] attribute boolean required ;
[CEReactions ] attribute unsigned long size ;
readonly attribute DOMString type ;
[SameObject ] readonly attribute HTMLOptionsCollection options ;
[CEReactions ] attribute unsigned long length ;
getter HTMLOptionElement ? item (unsigned long index );
HTMLOptionElement ? namedItem (DOMString name );
[CEReactions ] undefined add ((HTMLOptionElement or HTMLOptGroupElement ) element , optional (HTMLElement or long )? before = null );
[CEReactions ] undefined remove (); // ChildNode overload
[CEReactions ] undefined remove (long index );
[CEReactions ] setter undefined (unsigned long index , HTMLOptionElement ? option );
[SameObject ] readonly attribute HTMLCollection selectedOptions ;
attribute long selectedIndex ;
attribute DOMString value ;
readonly attribute boolean willValidate ;
readonly attribute ValidityState validity ;
readonly attribute DOMString validationMessage ;
boolean checkValidity ();
boolean reportValidity ();
undefined setCustomValidity (DOMString error );
undefined showPicker ();
readonly attribute NodeList labels ;
};
select
元素表示一个用于从一组选项中选择的控件。
所有当前引擎支持。
multiple
属性是一个 布尔属性。如果存在该属性,则 select
元素表示一个从 选项列表中选择零个或多个选项的控件。如果该属性不存在,则 select
元素表示一个从 选项列表中选择一个选项的控件。
所有当前引擎支持。
size
属性表示要显示给用户的选项数量。size
属性(如果指定)必须具有一个大于零的 有效非负整数 值。
display size
是应用 解析非负整数的规则 的结果,如果该值成功解析。如果解析失败或者 size
属性不存在,那么元素的显示大小为 4(如果存在 multiple
内容属性),否则为 1。
list of options
由所有的 option
元素组成,这些元素是 select
元素的子元素,或者是 optgroup
元素的子元素,并按 树形顺序排列。
所有当前引擎支持。
required
属性是一个 布尔属性。当指定时,用户在提交表单之前必须选择一个值。
如果一个 select
元素指定了 required
属性,没有指定 multiple
属性,并且 显示大小 为
1;如果第一个 option
元素的 值
为空字符串,并且该 option
元素的父节点是 select
元素(而不是 optgroup
元素),那么该 option
是 select
元素的 占位符标签选项。
如果一个 select
元素指定了 required
属性,没有指定 multiple
属性,并且 显示大小 为
1,那么该 select
元素必须有一个 占位符标签选项。
实际上,上述段落中所述的要求只能在 select
元素没有 size
属性或其值大于1时才适用。
约束验证: 如果元素指定了 required
属性,并且 option
元素的 selectedness 为
true,或者唯一一个 option
元素的 selectedness 为
true 是 占位符标签选项,那么该元素 缺失。
如果 multiple
属性不存在,并且该元素未被 禁用,则用户代理应允许用户选择 选项列表 中未被 禁用 的
option
元素。在此 option
元素被 选中(通过点击、失焦后更改值、菜单命令或其他机制),并在相关用户交互事件排队之前(例如在 click
事件之前),用户代理必须将所选 选中状态 设为 true,将其 脏状态 设为
true,然后 发送
select
更新通知。
如果 multiple
属性不存在,每当 option
元素在 select
元素的 选项列表 中的 选中状态 设为 true,并且每当
option
元素的 选中状态 设为 true
时,必须将其他所有 option
元素的 选中状态 设为 false。
如果 multiple
属性不存在并且元素的 显示大小 大于
1,则用户代理还应允许用户请求取消选中 option
元素的 选中状态。在此请求传达给用户代理之前,并在相关用户交互事件排队之前(例如在 click
事件之前),用户代理必须将所选 选中状态 设为 false,将其 脏状态
设为 true,然后 发送
select
更新通知。
选中状态设置算法,给定一个 select
元素 element,是运行以下步骤:
如果 element 的 multiple
属性不存在,并且 element 的 显示大小 为 1,并且 element 的 选项列表 中没有 option
元素的 选中状态 设为
true,则将 选中状态
设为第一个 树形顺序 中的 option
元素(如果有)为 true,然后返回。
如果 element 的 multiple
属性不存在,并且 element 的 选项列表中的两个或多个 option
元素的 选中状态设置为
true,则将树顺序中除最后一个 选项列表中 选中状态设置为 true 的所有 option
元素的 选中状态设置为
false。
option
HTML 元素插入步骤,给定
insertedNode,如下:
如果 insertedNode 的父节点是 select
元素,或者 insertedNode 的父节点是一个 optgroup
元素,其父节点是 select
元素,则运行该 select
元素的 选中状态设置算法。
option
HTML 元素移除步骤,给定
removedNode 和
oldParent,如下:
optgroup
HTML 元素移除步骤,给定
removedNode 和
oldParent,如下:
如果 option
元素在 选项列表 中 请求重置,则运行该 select
元素的 选中状态设置算法。
如果 multiple
属性存在,并且该元素未被 禁用,则用户代理应允许用户 切换 选中状态 的 option
元素在其 选项列表
中的状态,这些元素本身未被 禁用。在此元素被 切换(通过点击、菜单命令或其他机制)之前,并在相关用户交互事件排队之前(例如在相关 click
事件之前),用户代理必须更改 选中状态(从 true 到 false 或从 false 到 true),将该元素的 脏状态
设为 true,并且用户代理必须 发送 select
更新通知。
当用户代理要发送select
更新通知时,在用户交互任务源上排队一个元素任务,给定select
元素以运行这些步骤:
重置算法 对于 select
元素 selectElement 如下:
form
属性用于显式关联 select
元素与其 表单所有者。name
属性表示元素的名称。disabled
属性用于使控件不可交互并防止其值被提交。autocomplete
属性控制用户代理如何提供自动填充行为。
select.type
Support in all current engines.
返回 "select-multiple
" 如果该元素有 multiple
属性,否则返回 "select-one
"。
select.options
Support in all current engines.
返回 HTMLOptionsCollection
的 选项列表。
select.length [ = value ]
返回 选项列表 中的元素数。
element = select.item(index)
Support in all current engines.
select[index]
element = select.namedItem(name)
Support in all current engines.
返回 ID 或 name
为
name 的第一个项目从 选项列表。
如果找不到具有该 ID 的元素,则返回 null。
select.add(element [, before ])
Support in all current engines.
在由 before 指定的节点之前插入 element。
before 参数可以是一个数字,在这种情况下 element 被插入到该数字的项目之前,或者 选项列表 中的一个元素,在这种情况下 element 被插入到该元素之前。
如果省略 before,为 null,或超出范围的数字,则 element 将被添加到列表的末尾。
如果 element 是要插入的元素的祖先,此方法将抛出 "HierarchyRequestError
" DOMException
。
select.selectedOptions
HTMLSelectElement/selectedOptions
Support in all current engines.
返回 HTMLCollection
选项的 选项列表。
select.selectedIndex [ = value ]
HTMLSelectElement/selectedIndex
Support in all current engines.
返回第一个选中项的索引,如果有的话,否则为 -1。
可以设置,以更改选择。
select.value [ = value ]
返回第一个选中项的 值,如果有的话,否则为空字符串。
可以设置,以更改选择。
select.showPicker()
显示适用的选择 UI,使用户可以选择一个值。
如果 select 不是 可变的,则抛出
"InvalidStateError
" DOMException
。
如果在没有 瞬时用户激活 的情况下调用,则抛出 "NotAllowedError
" DOMException
。
如果 select 在跨域 iframe
中,则抛出 "SecurityError
" DOMException
。
如果 select 没有 被渲染,则抛出 "NotSupportedError
" DOMException
。
获取时,type
IDL 属性必须返回字符串 "select-one
" 如果 multiple
属性不存在,并返回字符串 "select-multiple
" 如果 multiple
属性存在。
options
IDL 属性必须返回一个 HTMLOptionsCollection
根植于 select
节点,其过滤器匹配 选项列表 中的元素。
options
集合也会在 HTMLSelectElement
对象上镜像。任一时刻的 支持的属性索引 是当时由 options
属性返回的对象支持的索引。
获取时,length
IDL 属性必须返回由 options
集合 表示
的节点数量。设置时,它必须像 options
集合上的同名属性一样。
item(index)
方法必须返回 同名方法 在 options
集合上调用时返回的值。
namedItem(name)
方法必须返回 同名方法 在
options
集合上调用时返回的值。
当用户代理要 设置新的索引属性的值 或 设置现有索引属性的值 时,它必须改为在 select
元素的 options
集合上运行 相应的算法。
同样,add(element, before)
方法必须像其在 options
集合上的同名方法一样。
Support in all current engines.
remove()
方法必须像其在 options
集合上的同名方法一样(有参数时),并且像其祖先接口 HTMLSelectElement
实现的 ChildNode
接口上的同名方法一样(没有参数时)。
selectedOptions
IDL 属性必须返回一个 HTMLCollection
根植于 select
节点,其过滤器匹配
选项列表 中其 选择状态 设置为 true 的元素。
获取时,selectedIndex
IDL 属性必须返回 索引,第一个 option
元素在 选项列表 中,其 选择状态 设置为 true
的元素(如果有的话)。如果没有,则必须返回 -1。
设置时,selectedIndex
属性必须将 选择状态 设置为
false 的所有 option
元素在 选项列表
中,然后将给定新值(如果有的话)的 索引 对应的 option
元素的 选择状态 设置为 true
并将其 脏状态
设置为 true。
这可能导致没有元素的 选择状态 设置为 true,即使在 select
元素没有 multiple
属性并且 显示大小 为 1
的情况下也是如此。
获取时,value
IDL 属性必须返回第一个 option
元素在 选项列表 中其 选择状态 设置为 true 的元素的
值(如果有的话)。如果没有,则必须返回空字符串。
设置时,value
属性必须将 选择状态 设置为
false 的所有 option
元素在 选项列表 中,然后将第一个
option
元素在 选项列表 中,其 值
等于给定新值(如果有的话),其 选择状态 设置为 true 并将其 脏状态
设置为 true。
这可能导致没有元素的 选择状态 设置为 true,即使在 select
元素没有 multiple
属性并且 显示大小 为 1
的情况下也是如此。
multiple
、required
和 size
IDL 属性必须
反映同名的内容属性。size
IDL 属性的
默认值 为 0。
出于历史原因,size
IDL
属性的默认值不会返回实际使用的大小,在没有 size
内容属性的情况下,实际大小取决于 multiple
属性的存在情况,要么是 1 要么是 4。
willValidate
、validity
和
validationMessage
IDL 属性,以及 checkValidity()
、reportValidity()
和 setCustomValidity()
方法是 约束验证 API
的一部分。labels
IDL
属性提供了元素的 label
列表。disabled
、form
和 name
IDL 属性是元素表单 API
的一部分。
以下示例展示了如何使用 select
元素为用户提供一组选项,用户可以从中选择一个选项。默认选项已预选。
< p >
< label for = "unittype" > Select unit type:</ label >
< select id = "unittype" name = "unittype" >
< option value = "1" > Miner </ option >
< option value = "2" > Puffer </ option >
< option value = "3" selected > Snipey </ option >
< option value = "4" > Max </ option >
< option value = "5" > Firebot </ option >
</ select >
</ p >
当没有默认选项时,可以使用占位符:
< select name = "unittype" required >
< option value = "" > Select unit type </ option >
< option value = "1" > Miner </ option >
< option value = "2" > Puffer </ option >
< option value = "3" > Snipey </ option >
< option value = "4" > Max </ option >
< option value = "5" > Firebot </ option >
</ select >
在这里,用户可以从一组选项中选择任意数量。默认情况下,所有五个选项都被选中。
< p >
< label for = "allowedunits" > Select unit types to enable on this map:</ label >
< select id = "allowedunits" name = "allowedunits" multiple >
< option value = "1" selected > Miner </ option >
< option value = "2" selected > Puffer </ option >
< option value = "3" selected > Snipey </ option >
< option value = "4" selected > Max </ option >
< option value = "5" selected > Firebot </ option >
</ select >
</ p >
有时候,用户需要选择一个或多个项目。这个示例展示了这样的界面。
< label >
Select the songs from that you would like on your Act II Mix Tape:
< select multiple required name = "act2" >
< option value = "s1" > It Sucks to Be Me (Reprise)
< option value = "s2" > There is Life Outside Your Apartment
< option value = "s3" > The More You Ruv Someone
< option value = "s4" > Schadenfreude
< option value = "s5" > I Wish I Could Go Back to College
< option value = "s6" > The Money Song
< option value = "s7" > School for Monsters
< option value = "s8" > The Money Song (Reprise)
< option value = "s9" > There's a Fine, Fine Line (Reprise)
< option value = "s10" > What Do You Do With a B.A. in English? (Reprise)
< option value = "s11" > For Now
</ select >
</ label >
有时,添加一个分隔符是有用的:
< label >
Select the song to play next:
< select required name = "next" >
< option value = "sr" > Random
< hr >
< option value = "s1" > It Sucks to Be Me (Reprise)
< option value = "s2" > There is Life Outside Your Apartment
…
datalist
元素Support in all current engines.
option
和脚本支持元素。
[Exposed =Window ]
interface HTMLDataListElement : HTMLElement {
[HTMLConstructor ] constructor ();
[SameObject ] readonly attribute HTMLCollection options ;
};
datalist
元素表示一组 option
元素,这些元素表示其他控件的预定义选项。在呈现中,datalist
元素不表示任何内容,它及其子元素应被隐藏。
datalist
元素可以通过两种方式使用。最简单的情况是,datalist
元素只有 option
元素子元素。
< label >
Animal:
< input name = animal list = animals >
< datalist id = animals >
< option value = "Cat" >
< option value = "Dog" >
</ datalist >
</ label >
在更复杂的情况下,datalist
元素可以包含要显示给不支持 datalist
的旧版客户端的内容。在这种情况下,option
元素放在 select
元素中,位于 datalist
元素内。
< label >
Animal:
< input name = animal list = animals >
</ label >
< datalist id = animals >
< label >
or select from the list:
< select name = animal >
< option value = "" >
< option > Cat
< option > Dog
</ select >
</ label >
</ datalist >
datalist
元素通过 list
属性与
input
元素连接。
每个作为 datalist
元素后代的 option
元素,如果不是 禁用的,且其 值 是非空字符串,则表示一个建议。每个建议都有一个 值 和一个 标签。
datalist.options
返回 HTMLCollection
,包含
option
元素。
datalist
元素的 options
IDL 属性必须返回一个
HTMLCollection
,以
datalist
节点为根,其过滤条件为 option
元素。
约束验证:如果一个元素有 datalist
元素祖先,则该元素被禁止约束验证。
optgroup
元素
支持所有当前的引擎。
支持所有当前的引擎。
select
元素的子元素。option
和 脚本支持的 元素。
optgroup
元素的 结束标签 可省略,
如果 optgroup
元素紧跟另一个 optgroup
元素、紧跟一个
hr
元素,或父元素中没有更多内容时。
disabled
— 是否禁用表单控件
label
— 用户可见的标签
[Exposed =Window ]
interface HTMLOptGroupElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute boolean disabled ;
[CEReactions ] attribute DOMString label ;
};
The optgroup
元素表示具有相同标签的一组
option
元素。
该元素的 option
元素组由 optgroup
元素的子元素组成。
在 select
元素中显示 option
元素时,用户代理应将这些组的 option
元素视为彼此相关,并与其他
option
元素分开。
支持所有当前引擎。
disabled
属性是一个 布尔属性,可用于 禁用一组
option
元素。
label
属性必须指定。其值给出了该组的名称,用于用户界面。用户代理应在为 option
元素组在 select
元素中进行标记时使用此属性的值。
disabled
和 label
属性必须
反映各自的内容属性。
没有办法选择 optgroup
元素。只能选择 option
元素。optgroup
元素只是为一组
option
元素提供标签。
以下代码片段显示如何在 select
下拉控件中提供三个课程中的一组课程:
< form action = "courseselector.dll" method = "get" >
< p > 您今天想观看哪门课程?
< p >< label > 课程:
< select name = "c" >
< optgroup label = "8.01 物理学 I:经典力学" >
< option value = "8.01.1" > 讲座 01:十的幂
< option value = "8.01.2" > 讲座 02:一维运动学
< option value = "8.01.3" > 讲座 03:向量
< optgroup label = "8.02 电磁学" >
< option value = "8.02.1" > 讲座 01:是什么维持了我们的世界?
< option value = "8.02.2" > 讲座 02:电场
< option value = "8.02.3" > 讲座 03:电通量
< optgroup label = "8.03 物理学 III:振动与波动" >
< option value = "8.03.1" > 讲座 01:周期现象
< option value = "8.03.2" > 讲座 02:拍频
< option value = "8.03.3" > 讲座 03:带阻尼的受迫振动
</ select >
</ label >
< p >< input type = submit value = "▶ 播放" >
</ form >
option
元素在所有当前引擎中都支持。
在所有当前引擎中都支持。
select
元素的子元素。datalist
元素的子元素。optgroup
元素的子元素。label
属性和 value
属性: 无内容。label
属性但没有 value
属性: 文本。
label
属性并且不是
datalist
元素的子元素: 文本,但不包括
元素间的空白。
label
属性并且是
datalist
元素的子元素: 文本。
option
元素紧跟在另一个 option
元素之后,或紧跟在一个 optgroup
元素之后,或紧跟在一个 hr
元素之后,或者父元素中没有更多内容,则可以省略 option
元素的 结束标签。disabled
— 表单控件是否被禁用
label
— 用户可见的标签
selected
— 该选项是否默认被选中
value
— 用于 表单提交的值
[Exposed =Window ,
LegacyFactoryFunction =Option (optional DOMString text = "", optional DOMString value , optional boolean defaultSelected = false , optional boolean selected = false )]
interface HTMLOptionElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute boolean disabled ;
readonly attribute HTMLFormElement ? form ;
[CEReactions ] attribute DOMString label ;
[CEReactions ] attribute boolean defaultSelected ;
attribute boolean selected ;
[CEReactions ] attribute DOMString value ;
[CEReactions ] attribute DOMString text ;
readonly attribute long index ;
};
option
元素 表示
select
元素中的一个选项或 datalist
元素中的建议列表的一部分。
在某些情况下,如 select
元素的定义中所述,一个
option
元素可以是 select
元素的 占位
符标签选项。一个 占位符标签选项并不表示一个实际的选项,而是表示
select
控件的标签。
在所有当前引擎中都支持。
disabled
属性是一个 布尔属性。当 option
元素的 disabled
属性存在时,或者它是 optgroup
元素的子元素并且该 disabled
属性存在,则 禁用。
被禁用的option
元素必须防止任何排队的 点击
事件
从 用户交互任务源派发到该元素上。
label
属性为元素提供一个标签。option
元素的标签是 label
内容属性的值(如果存在且值不为空字符串),否则为元素的 text
IDL 属性的值。
label
内容属性(如果指定)必须不为空。
value
属性为元素提供一个值。option
元素的 值是 value
内容属性的值(如果存在),否则为元素的 text
IDL 属性的值。
selected
属性是一个 布尔属性。它表示元素的默认 选中状态。
脏状态 是 option
元素的一个布尔状态,初始为 false。它控制是否添加或移除 selected
内容属性会产生影响。
选中状态 是 option
元素的一个布尔状态,初始为 false。除非另有规定,当元素被创建时,如果元素有 selected
属性,则其 选中状态必须设置为
true。每当
option
元素的 selected
属性被添加时,如果其 脏状态为 false,则其 选中状态必须设置为 true。每当
option
元素的 selected
属性被
移除时,如果其 脏状态为
false,则其
选中状态必须设置为 false。
Option()
构造函数在传递三个或更少参数时,即使第三个参数为 true(暗示设置 selected
属性),也会覆盖 选中状态的初始状态,始终为 false。第四个参数可用于显式设置构造函数中使用的初始 选中状态。
未指定 select
属性的 multiple
元素不得有多个子 option
元素设有
selected
属性。
option
元素的索引是同一个 选项列表 中位于它之前的
option
元素的数量(按 树顺序)。如果
option
元素不在 选项列表中,则
option
元素的索引为零。
option.selected
如果元素被选中,返回 true,否则返回 false。
可以设置以覆盖元素的当前状态。
option.index
option.form
返回元素的 form
元素(如果有),否则返回 null。
option.text
与 textContent
相同,
只是空格会被折叠且 script
元素会被跳过。
option = new Option([ text [, value [, defaultSelected [, selected ] ] ] ])
在所有当前引擎中都支持。
返回一个
新的 option
元素。
text 参数设置元素的内容。
value 参数设置 value
属性。
defaultSelected 参数设置 selected
属性。
selected 参数设置元素是否被选中。如果省略该参数,即使 defaultSelected 参数为 true,元素也不会被选中。
disabled
IDL 属性必须 反映
同名内容属性。defaultSelected
IDL 属性必须
反映 selected
内容属性。
label
IDL 属性在获取时,如果有 label
内容属性,必须返回该属性的值;否则,必须返回元素的 标签。
在设置时,元素的 label
内容属性必须设置为新值。
value
IDL 属性在获取时,必须返回元素的 值。在设置时,元素的 value
内容属性必须设置为新值。
selected
IDL 属性在获取时,如果元素的 选中状态为 true,必须返回 true,否则返回 false。在设置时,必须将元素的 选中状态设置为新值,将其 脏状态设置为 true,然后使元素 请求重置。
index
IDL 属性必须返回元素的 索引。
text
IDL
属性在获取时,必须返回从所有 文本
节点后代的数据中剥离和折叠 ASCII 空白的结果,这些节点是
option
元素的后代,按 树顺序,排除任何是其自身的 script
或
SVG script
元素的后代。
text
属性的设置器必须 在此元素内使用给定值进行字符串替换所有。
form
IDL
属性的行为取决于 option
元素是否在
select
元素中。如果 option
有一个 select
元素作为其父元素,或有一个 optgroup
元素作为其父元素并且该
optgroup
元素有一个 select
元素作为其父元素,则 form
IDL 属性必须返回与该 select
元素上的 form
IDL
属性相同的值。否则,必须返回 null。
提供了一个
用于创建 HTMLOptionElement
对象的传统工厂函数(除了 DOM 的工厂方法如 createElement()
):
Option(text, value,
defaultSelected, selected)
。调用传统工厂函数时,必须执行以下步骤:
令 document 为 当前全局对象的 关联
Document
。
如果 text 不为空字符串,则向 option 追加一个新的
文本
节点,其数据为 text。
如果 defaultSelected 为 true,则为 option 设置一个属性值,使用 "selected
"
和空字符串。
如果 selected 为 true,则将 option 的 选中状态设置为 true;否则,将其 选中状态设置为 false(即使 defaultSelected 为 true)。
返回 option。
textarea
元素支持所有当前引擎。
支持所有当前引擎。
autocomplete
— 表单自动填充特性的提示
cols
— 每行的最大字符数
dirname
—
用于发送元素的方向性的表单控件名称在表单提交中
disabled
— 表单控件是否禁用
form
—
将元素与 表单
元素关联
maxlength
— 值的最大 长度
minlength
— 值的最小 长度
name
— 用于
表单提交 和 form.elements
API 中使用的元素名称
placeholder
— 要放置在表单控件中的用户可见标签
readonly
— 是否允许用户编辑值
required
— 控件是否为 表单提交
所必需
rows
— 要显示的行数
wrap
— 表单控件的值在 表单提交时如何换行
[Exposed =Window ]
interface HTMLTextAreaElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString autocomplete ;
[CEReactions ] attribute unsigned long cols ;
[CEReactions ] attribute DOMString dirName ;
[CEReactions ] attribute boolean disabled ;
readonly attribute HTMLFormElement ? form ;
[CEReactions ] attribute long maxLength ;
[CEReactions ] attribute long minLength ;
[CEReactions ] attribute DOMString name ;
[CEReactions ] attribute DOMString placeholder ;
[CEReactions ] attribute boolean readOnly ;
[CEReactions ] attribute boolean required ;
[CEReactions ] attribute unsigned long rows ;
[CEReactions ] attribute DOMString wrap ;
readonly attribute DOMString type ;
[CEReactions ] attribute DOMString defaultValue ;
attribute [LegacyNullToEmptyString ] DOMString value ;
readonly attribute unsigned long textLength ;
readonly attribute boolean willValidate ;
readonly attribute ValidityState validity ;
readonly attribute DOMString validationMessage ;
boolean checkValidity ();
boolean reportValidity ();
undefined setCustomValidity (DOMString error );
readonly attribute NodeList labels ;
undefined select ();
attribute unsigned long selectionStart ;
attribute unsigned long selectionEnd ;
attribute DOMString selectionDirection ;
undefined setRangeText (DOMString replacement );
undefined setRangeText (DOMString replacement , unsigned long start , unsigned long end , optional SelectionMode selectionMode = "preserve");
undefined setSelectionRange (unsigned long start , unsigned long end , optional DOMString direction );
};
textarea
元素 表示
一个多行纯文本编辑控件,用于元素的原始值。控件的内容表示控件的默认值。
textarea 控件的原始值最初必须为空字符串。
此元素 有涉及双向算法的渲染要求.
readonly
属性是一个 布尔属性,用于控制文本是否可以由用户编辑。
在这个例子中,一个文本控件被标记为只读,因为它代表一个只读文件:
Filename: < code > /etc/bash.bashrc</ code >
< textarea name = "buffer" readonly >
# System-wide .bashrc file for interactive bash(1) shells.
# To enable the settings / commands in this file for login shells as well,
# this file has to be sourced in /etc/profile.
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
...</ textarea >
约束验证: 如果 readonly
属性在 textarea
元素上指定,则该元素 被禁止约束验证.
textarea
元素是 可变的 如果它既不是
禁用的 也没有指定
readonly
属性。
当 textarea
是可变的时,其原始值应该可供用户编辑:用户代理应允许用户编辑、插入和删除文本,以及以U+000A LINE FEED
(LF)字符的形式插入和删除换行符。任何时候用户导致元素的原始值发生变化,用户代理必须在用户交互任务源上排队一个给定
textarea
元素的元素任务以触发一个名为
input
的事件,事件发生在 textarea
元素,bubbles
和 composed
属性初始化为 true。用户代理可以在用户交互中找到合适的休息时间再排队该任务;例如,用户代理可以等待用户在100毫秒内未按下任何键,以便仅在用户暂停时触发事件,而不是每次按键时连续触发事件。
textarea
元素的 脏值标志
必须在用户与控件交互以更改 原始值
时设为 true。
克隆步骤 对于 textarea
元素必须传播被克隆节点的 原始值 和
脏值标志 到副本。
重置算法 对于 textarea
元素是将 用户有效性 设置为 false,将 脏值标志 重置为
false,并将元素的 原始值
设置为其 子文本内容。
当 textarea
元素从 开放元素堆栈 中弹出时用户代理必须调用元素的 重置算法。
如果元素是 可变的, 用户代理应该允许用户改变元素的书写方向,将其设置为从左到右或从右到左。如果用户这样做,用户代理必须执行以下步骤:
将元素的 dir
属性设置为
"ltr
"
如果用户选择从左到右的书写方向,并且 "rtl
"
如果用户选择从右到左的书写方向。
排队一个元素任务在用户交互任务源上,给定textarea
元素去触发一个事件,名为input
在textarea
元素上,bubbles
和composed
属性初始化为true。
cols
属性指定每行的预期最大字符数。如果 cols
属性已指定,其值必须是大于零的有效非负整数。如果将 解析非负整数的规则 应用于属性的值结果为一个大于零的数字,则元素的字符宽度即为该值;否则,其值为20。
用户代理可以使用 textarea
元素的 字符宽度
作为对用户的提示,例如让控件的宽度为该字符数。在视觉渲染中,用户代理应该在渲染时将用户的输入换行,使每行的宽度不超过这个字符数。
rows
属性指定要显示的行数。如果 rows
属性已指定,其值必须是大于零的 有效非负整数。如果将 解析非负整数的规则 应用于属性的值结果为一个大于零的数字,则元素的 字符高度即为该值;否则,其值为2。
视觉用户代理应将控件的高度设置为 字符高度 所指定的行数。
wrap
属性是一个 枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
soft
|
软 | 文本在提交时不换行(虽然仍然可以在渲染中换行)。 |
hard
|
硬 | 用户代理应插入换行符以确保文本在提交时换行。 |
如果元素的 wrap
属性处于 硬 状态,则必须指定
cols
属性。
由于历史原因,元素的值在三种不同用途上以三种不同方式进行规范化。原始值 是最初设置的值。它不进行规范化。API 值 是在
value
IDL 属性中使用的值,在 textLength
IDL 属性中使用的值,以及由 maxlength
和 minlength
内容属性使用的值。它被规范化为换行符使用 U+000A 换行符 (LF) 字符。最后,有 值,在此规范中的表单提交和其他处理模型中使用。它被规范化为 API
值,并且如果根据元素的 wrap
属性需要,还会插入额外的换行符以在给定宽度处换行文本。
获取元素 API 值 的算法是返回元素的 原始值,并 规范化换行符。
元素的 值 被定义为元素的 API 值 应用 textarea 换行转换 的结果。textarea 换行转换 是以下算法,对字符串应用:
如果元素的 wrap
属性处于 硬
状态,则使用 实现定义
算法在字符串中插入 U+000A 换行符 (LF) 字符,以确保每行不超过 字符宽度。对于此要求的目的,行由字符串的开头、字符串的结尾和 U+000A 换行符 (LF) 字符分隔。
maxlength
属性是 表单控件的
maxlength
属性。
如果 textarea
元素有一个 最大允许值长度,那么元素的子元素必须使其值的 长度(包括所有子元素的文本内容,且换行符已规范化)小于或等于元素的 最大允许值长度。
minlength
属性是 表单控件的
minlength
属性。
required
属性是 布尔属性。当指定时,用户在提交表单之前必须输入一个值。
约束验证: 如果元素指定了 required
属性,并且元素是 可变的,并且元素的 值 为空字符串,则该元素 存在丢失。
placeholder
属性表示一个 简短
的提示(一个词或短语),旨在帮助用户在控件没有值时进行数据输入。提示可以是一个示例值或预期格式的简短描述。
placeholder
属性不应作为 标签
的替代。对于较长的提示或其他建议文本,title
属性更为合适。
这些机制非常相似但略有不同:控件的 标签
提供的提示始终显示;在用户输入值之前显示 placeholder
属性中的短提示;当用户请求更多帮助时显示 title
属性中的提示。
用户代理在控件的 值 为空字符串且控件未 聚焦 时应向用户显示此提示(例如,在空白未聚焦控件内部显示)。提示中的所有 U+000D 回车符 U+000A 换行符字符对 (CRLF),以及提示中的所有其他 U+000D 回车符 (CR) 和 U+000A 换行符 (LF) 字符,在渲染提示时必须视为换行。
如果用户代理通常在控件 聚焦 时不向用户显示此提示,则在控件由于
autofocus
属性聚焦时,用户代理仍应向用户显示此提示,因为在这种情况下,用户在控件聚焦前没有机会查看控件。
name
属性表示元素的名称。dirname
属性控制元素的 方向性
如何提交。disabled
属性用于使控件不可交互,并防止其值被提交。form
属性用于显式将
textarea
元素与其 表单所有者 关联。autocomplete
属性控制用户代理如何提供自动填充行为。
textarea.type
返回字符串 "textarea
"。
textarea.value
返回元素的当前值。
可以设置以更改值。
cols
,
placeholder
, required
, rows
, 和
wrap
IDL
属性必须 反映相同名称的相应内容属性。cols
和
rows
属性 仅限于正数且有回退值。cols
IDL 属性的 默认值 是 20。rows
IDL 属性的 默认值 是 2。dirName
IDL 属性必须 反映 dirname
内容属性。maxLength
IDL 属性必须 反映 maxlength
内容属性,仅限于非负数。minLength
IDL 属性必须 反映 minlength
内容属性,仅限于非负数。readOnly
IDL 属性必须 反映 readonly
内容属性。
type
IDL 属性必须返回值 "textarea
"。
defaultValue
属性的 getter 必须返回元素的 子文本内容。
defaultValue
属性的 setter 必须在该元素中使用给定值进行 字符串替换。
value
IDL 属性在获取时必须返回元素的 API
值。在设置时,必须执行以下步骤:
让 oldAPIValue 是此元素的 API 值。
将此元素的 原始值 设置为新值。
将此元素的 脏值标志 设为 true。
如果新的 API
值 与 oldAPIValue 不同,则将 文本输入光标位置 移动到文本控件的末尾,取消选择任何选定的文本,并 重置选择方向 为
"none
"。
textLength
IDL 属性必须返回元素的 长度。
willValidate
,
validity
,
和 validationMessage
IDL 属性,以及 checkValidity()
,
reportValidity()
,
和 setCustomValidity()
方法,是 约束验证 API
的一部分。labels
IDL
属性提供了元素的 标签
列表。select()
,
selectionStart
,
selectionEnd
,
selectionDirection
,
setRangeText()
,
和 setSelectionRange()
方法和 IDL 属性公开了元素的文本选择。disabled
,
form
, 和
name
IDL
属性是元素的表单 API 的一部分。
这是一个 textarea
元素在表单中用于不受限制的自由文本输入的示例:
< p > 如果你有任何评论,请告诉我们:< textarea cols = 80 name = comments ></ textarea ></ p >
要为评论指定一个最大长度,可以使用 maxlength
属性:
< p > 如果你有任何短评,请告诉我们:< textarea cols = 80 name = comments maxlength = 200 ></ textarea ></ p >
要给出默认值,可以在元素内部包含文本:
< p > 如果你有任何评论,请告诉我们:< textarea cols = 80 name = comments > 你真棒!</ textarea ></ p >
你也可以指定最小长度。这里需要用户填写一封信;提供了一个模板(比最小长度短),但不足以提交表单:
< textarea required minlength = "500" > 尊敬的议长女士,
关于你们的来信...
...
此致,
...
</ textarea >
还可以提供一个占位符,以向用户建议基本形式,而不提供显式模板:
< textarea placeholder = "亲爱的弗朗辛,
他们这周关闭了公园,所以我们不能在那里见面了。我们要不要去吃晚饭?
爱你的,
爸爸" ></ textarea >
要让浏览器提交元素的 方向性 及其值,可以指定 dirname
属性:
< p > If you have any comments, please let us know (you may use either English or Hebrew for your comments):
< textarea cols = 80 name = comments dirname = comments.dir ></ textarea ></ p >
output
元素所有当前引擎均支持。
所有当前引擎均支持。
for
—
指定计算结果的控制项form
—
将元素与form
元素关联
name
—
在form.elements
API 中使用的元素名称。[Exposed =Window ]
interface HTMLOutputElement : HTMLElement {
[HTMLConstructor ] constructor ();
[SameObject , PutForwards =value ] readonly attribute DOMTokenList htmlFor ;
readonly attribute HTMLFormElement ? form ;
[CEReactions ] attribute DOMString name ;
readonly attribute DOMString type ;
[CEReactions ] attribute DOMString defaultValue ;
[CEReactions ] attribute DOMString value ;
readonly attribute boolean willValidate ;
readonly attribute ValidityState validity ;
readonly attribute DOMString validationMessage ;
boolean checkValidity ();
boolean reportValidity ();
undefined setCustomValidity (DOMString error );
readonly attribute NodeList labels ;
};
output
元素表示应用程序执行的计算结果或用户操作的结果。
此元素可与samp
元素对比,后者适用于引用先前运行的其他程序的输出。
所有当前引擎均支持。
for
内容属性允许在计算结果和表示计算输入值的元素之间建立明确关系。for
属性(如果指定)必须包含一个无序的唯一空格分隔标记集,其中每个标记都必须具有同一树中某个元素的ID值。
form
属性用于显式地将output
元素与其表单所有者关联。name
属性表示元素的名称。output
元素与表单关联,以便可以从表单控件的事件处理程序中轻松引用;表单提交时元素的值本身不会提交。
元素有一个默认值覆盖(null或字符串)。最初它必须为null。
元素的默认值由以下步骤确定:
output.value [ = value ]
返回元素的当前值。
可以设置以更改值。
output.defaultValue [ = value ]
返回元素的当前默认值。
可以设置以更改默认值。
output.type
返回字符串"output
"。
value
setter步骤是:
用给定的值字符串替换在此元素内。
defaultValue
getter步骤是运行此元素的默认值。
defaultValue
setter步骤是:
type
getter步骤是返回"output
"。
willValidate
,
validity
,
和validationMessage
IDL属性,以及checkValidity()
,
reportValidity()
,
和setCustomValidity()
方法是约束验证API的一部分。labels
IDL属性提供了元素的label
列表。form
和name
IDL属性是元素表单API的一部分。
一个简单的计算器可以使用output
来显示计算结果:
< form onsubmit = "return false" oninput = "o.value = a.valueAsNumber + b.valueAsNumber" >
< input id = a type = number step = any > +
< input id = b type = number step = any > =
< output id = o for = "a b" ></ output >
</ form >
在这个例子中,使用output
元素来报告由远程服务器执行的计算结果,当它们到达时:
< output id = "result" ></ output >
< script >
var primeSource = new WebSocket( 'ws://primes.example.net/' );
primeSource. onmessage = function ( event) {
document. getElementById( 'result' ). value = event. data;
}
</ script >
progress
元素支持所有当前引擎。
支持所有当前引擎。
progress
元素的后代。
value
— 元素的当前值
max
—
范围的上限
[Exposed =Window ]
interface HTMLProgressElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute double value ;
[CEReactions ] attribute double max ;
readonly attribute double position ;
readonly attribute NodeList labels ;
};
progress
元素 表示 任务的完成进度。
进度要么是不确定的,表示正在取得进展但不清楚任务完成前还需做多少工作(例如,因为任务在等待远程主机响应),要么是一个在零到最大值范围内的数字,表示已完成的工作比例。
支持所有当前引擎。
有两个属性决定了元素所表示的当前任务完成情况。value
属性指定任务已完成的部分,max
属性指定任务总共需要的工作量。单位是任意的,没有规定。
要制作一个确定的进度条,请添加一个带有当前进度的 value
属性(可以是 0.0 到 1.0 之间的数字,或者,如果指定了 max
属性,则是从 0 到 max
属性的值的数字)。要制作一个不确定的进度条,请删除 value
属性。
鼓励作者还在元素内以文本形式包括当前值和最大值,以便进度对于旧版用户代理的用户可用。
以下是一个显示某些自动任务进度的 Web 应用程序片段:
< section >
< h2 > Task Progress</ h2 >
< p > Progress: < progress id = p max = 100 >< span > 0</ span > %</ progress ></ p >
< script >
var progressBar = document. getElementById( 'p' );
function updateProgress( newValue) {
progressBar. value = newValue;
progressBar. getElementsByTagName( 'span' )[ 0 ]. textContent = newValue;
}
</ script >
</ section >
(这个示例中的 updateProgress()
方法将由页面上的其他代码调用,以在任务进展时更新实际进度条。)
value
和 max
属性存在时,其值必须是 有效的浮点数。value
属性(如果存在)必须有一个大于或等于零且小于或等于 max
属性值(如果存在)或 1.0(否则)的值。max
属性(如果存在)必须有一个大于零的值。
progress
元素不适合用于仅仅作为仪表的情况,而不是任务进度。例如,使用 progress
来指示磁盘空间使用情况是不合适的。相反,可以使用 meter
元素用于此类用例。
用户代理要求: 如果省略了
value
属性,则进度条是不确定的进度条。否则,它是确定的进度条。
如果进度条是确定的进度条且元素有一个 max
属性,用户代理必须根据 解析浮点数值规则 解析 max
属性的值。如果这不会导致错误,并且解析值大于零,则进度条的 最大值 是该值。否则,如果元素没有 max
属性,或有但解析它导致错误,或解析值小于或等于零,则进度条的 最大值 为 1.0。
如果进度条是确定的进度条,用户代理必须根据 解析浮点数值规则 解析 value
属性的值。如果这不会导致错误,并且解析值大于零,则进度条的 值 是该解析值。否则,如果解析 value
属性的值导致错误或数字小于或等于零,则进度条的 值 为零。
如果进度条是确定的进度条,则 当前值 是 最大值,如果 值 大于 最大值,否则为 值。
展示进度条的 UA 要求: 在向用户表示 progress
元素时,UA 应该指示它是确定的还是不确定的进度条,在前一种情况下,应该指示 当前值 相对于 最大值 的相对位置。
progress.position
对于确定的进度条(具有已知的当前值和最大值),返回当前值除以最大值的结果。
对于不确定的进度条,返回 -1。
如果进度条是不确定的进度条,则 position
IDL 属性必须返回 -1。否则,它必须返回 当前值 除以 最大值 的结果。
如果进度条是不确定的进度条,则 value
IDL 属性,在获取时,必须返回 0。否则,它必须返回 当前值。在设置时,必须将给定值转换为 数字的最佳浮点表示,然后将 value
内容属性设置为该字符串。
将 value
IDL 属性设置为其自身,而相应的内容属性不存在时,会将进度条从不确定进度条更改为没有进度的确定进度条。
max
IDL
属性必须 反映 同名的内容属性,仅限于正数。max
的默认值 为 1.0。
meter
元素支持所有当前引擎。
支持所有当前引擎。
meter
元素的后代。
value
— 元素的当前值min
—
范围的下限max
—
范围的上限low
—
低范围的高限high
—
高范围的低限optimum
— 仪表的最佳值[Exposed =Window ]
interface HTMLMeterElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute double value ;
[CEReactions ] attribute double min ;
[CEReactions ] attribute double max ;
[CEReactions ] attribute double low ;
[CEReactions ] attribute double high ;
[CEReactions ] attribute double optimum ;
readonly attribute NodeList labels ;
};
meter
元素
表示在已知范围内的标量测量值或分数值;例如磁盘使用情况、查询结果的相关性或某个候选人选票比例。
这也称为仪表。
meter
元素不应用于指示进度(如进度条)。为此,HTML 提供了单独的 progress
元素。
meter
元素也不表示任意范围内的标量值——例如,用它来报告重量或高度是错误的,除非有已知的最大值。
有六个属性决定了元素表示的仪表的语义。
支持所有当前引擎。
支持所有当前引擎。
min
属性指定范围的下限,max
属性指定范围的上限。value
属性指定仪表指示的“测量”值。
其他三个属性可用于将仪表的范围分段为“低”、“中”和“高”部分,并指示哪部分是“最佳”部分。low
属性指定被认为是“低”部分的范围,high
属性指定被认为是“高”部分的范围。optimum
属性给出了“最佳”的位置;如果它高于“高”值,则表示值越高越好;如果它低于“低”值,则表示值越低越好,自然地,如果它介于两者之间,则表示高值和低值都不是好的。
作者要求: 必须指定 value
属性。value
、min
、low
、high
、max
和 optimum
属性在存在时,必须具有 有效的浮点数 值。
此外,这些属性的值还有进一步的约束:
设 value 为 value
属性的数值。
如果指定了 min
属性,则 minimum 为该属性的值;否则,设为零。
如果指定了 max
属性,则 maximum 为该属性的值;否则,设为 1.0。
以下不等式必须成立,如适用:
minimum ≤ value ≤ maximum
如果未指定最小值或最大值,则假定范围为 0..1,因此值必须在该范围内。
鼓励作者在元素内容中包含仪表状态的文本表示,以供不支持 meter
元素的用户代理使用。
与 微数据 一起使用时,meter
元素的
value
属性提供了元素的机器可读值。
以下示例显示了三个仪表,它们都将填充四分之三:
Storage space usage: < meter value = 6 max = 8 > 6 blocks used (out of 8 total)</ meter >
Voter turnout: < meter value = 0.75 >< img alt = "75%" src = "graph75.png" ></ meter >
Tickets sold: < meter min = "0" max = "100" value = "75" ></ meter >
以下示例是元素的不正确用法,因为它没有给出范围(并且由于默认最大值为 1,这 两个仪表看起来都会达到最大值):
< p > The grapefruit pie had a radius of < meter value = 12 > 12cm</ meter >
and a height of < meter value = 2 > 2cm</ meter > .</ p > <!-- BAD! -->
相反,可以不包括 meter 元素,或者使用带有定义范围的 meter 元素,以给出与其他派相比的尺寸上下文:
< p > The grapefruit pie had a radius of 12cm and a height of
2cm.</ p >
< dl >
< dt > Radius: < dd > < meter min = 0 max = 20 value = 12 > 12cm</ meter >
< dt > Height: < dd > < meter min = 0 max = 10 value = 2 > 2cm</ meter >
</ dl >
在 meter
元素中没有明确的方法指定单位,但可以在 title
属性中以自由格式文本指定单位。
上述示例可以扩展为提及单位:
< dl >
< dt > Radius: < dd > < meter min = 0 max = 20 value = 12 title = "centimeters" > 12cm</ meter >
< dt > Height: < dd > < meter min = 0 max = 10 value = 2 title = "centimeters" > 2cm</ meter >
</ dl >
用户代理要求: 用户代理必须解析 min
、max
、value
、low
、high
和 optimum
属性,使用 解析浮点数值的规则。
然后,用户代理必须使用所有这些数字来获得仪表上的六个点的值,如下所示。(这些值的计算顺序很重要,因为某些值引用了较早的值。)
minimum value
如果指定了 min
属性并且可以解析出一个值,那么最小值就是该值。否则,最小值为零。
maximum value
如果指定了 max
属性并且可以解析出一个值,那么候选最大值就是该值。否则,候选最大值为 1.0。
如果候选最大值大于或等于最小值,则最大值为候选最大值。否则,最大值与最小值相同。
actual value
如果指定了 value
属性并且可以解析出一个值,那么候选实际值就是该值。否则,候选实际值为零。
如果候选实际值小于最小值,则实际值为最小值。
否则,如果候选实际值大于最大值,则实际值为最大值。
否则,实际值就是候选实际值。
low boundary
如果指定了 low
属性并且可以解析出一个值,那么候选低边界就是该值。否则,候选低边界与最小值相同。
如果候选低边界小于最小值,则低边界为最小值。
否则,如果候选低边界大于最大值,则低边界为最大值。
否则,低边界就是候选低边界。
high boundary
如果指定了 high
属性并且可以解析出一个值,那么候选高边界就是该值。否则,候选高边界与最大值相同。
如果候选高边界小于低边界,则高边界为低边界。
否则,如果候选高边界大于最大值,则高边界为最大值。
否则,高边界就是候选高边界。
optimum point
如果指定了 optimum
属性并且可以解析出一个值,那么候选最佳点就是该值。否则,候选最佳点是最小值和最大值之间的中点。
如果候选最佳点小于最小值,则最佳点为最小值。
否则,如果候选最佳点大于最大值,则最佳点为最大值。
否则,最佳点就是候选最佳点。
所有这些将导致以下不等式都成立:
最小值 ≤ 实际值 ≤ 最大值
最小值 ≤ 低边界 ≤ 高边界 ≤ 最大值
最小值 ≤ 最佳点 ≤ 最大值
仪表区域的用户代理要求: 如果最佳点等于低边界或高边界,或介于两者之间,则仪表的低边界和高边界之间的区域必须被视为最佳区域,低边界和高边界部分(如果有)必须视为次优部分。否则,如果最佳点小于低边界,则最小值和低边界之间的区域必须被视为最佳区域,低边界到高边界之间的区域必须视为次优区域,剩余区域必须视为更差的区域。最后,如果最佳点高于高边界,则情况相反;高边界和最大值之间的区域必须视为最佳区域,高边界到低边界之间的区域必须视为次优区域,剩余区域必须视为更差的区域。
显示仪表的用户代理要求: 在向用户表示 meter
元素时,用户代理应指示实际值相对于最小值和最大值的相对位置,以及实际值与仪表的三个区域之间的关系。
以下标记:
< h3 > Suggested groups</ h3 >
< menu >
< li >< a href = "?cmd=hsg" onclick = "hideSuggestedGroups()" > Hide suggested groups</ a ></ li >
</ menu >
< ul >
< li >
< p >< a href = "/group/comp.infosystems.www.authoring.stylesheets/view" > comp.infosystems.www.authoring.stylesheets</ a > -
< a href = "/group/comp.infosystems.www.authoring.stylesheets/subscribe" > join</ a ></ p >
< p > Group description: < strong > Layout/presentation on the WWW.</ strong ></ p >
< p > < meter value = "0.5" > Moderate activity,</ meter > Usenet, 618 subscribers</ p >
</ li >
< li >
< p >< a href = "/group/netscape.public.mozilla.xpinstall/view" > netscape.public.mozilla.xpinstall</ a > -
< a href = "/group/netscape.public.mozilla.xpinstall/subscribe" > join</ a ></ p >
< p > Group description: < strong > Mozilla XPInstall discussion.</ strong ></ p >
< p > < meter value = "0.25" > Low activity,</ meter > Usenet, 22 subscribers</ p >
</ li >
< li >
< p >< a href = "/group/mozilla.dev.general/view" > mozilla.dev.general</ a > -
< a href = "/group/mozilla.dev.general/subscribe" > join</ a ></ p >
< p > < meter value = "0.25" > Low activity,</ meter > Usenet, 66 subscribers</ p >
</ li >
</ ul >
可能呈现如下:
用户代理可以结合 title
属性的值和其他属性,提供上下文敏感的帮助或内联文本,详细说明实际值。
例如,以下代码片段:
< meter min = 0 max = 60 value = 23.2 title = "秒" ></ meter >
...可能会导致用户代理显示一个仪表,上面有一个工具提示显示“值:23.2(共 60)。”一行和“秒”第二行。
value
IDL 属性在获取时,必须返回 实际值。在设置时,给定的值必须转换为数字的最佳浮点表示,然后 value
内容属性必须设置为该字符串。
min
IDL 属性在获取时,必须返回 最小值。在设置时,给定的值必须转换为数字的最佳浮点表示,然后 min
内容属性必须设置为该字符串。
max
IDL 属性在获取时,必须返回 最大值。在设置时,给定的值必须转换为数字的最佳浮点表示,然后 max
内容属性必须设置为该字符串。
low
IDL 属性
在获取时,必须返回 低边界。在设置时,给定的值必须转换为数字的最佳浮点表示,然后 low
内容属性必须设置为该字符串。
high
IDL 属性在获取时,必须返回 高边界。在设置时,给定的值必须转换为数字的最佳浮点表示,然后 high
内容属性必须设置为该字符串。
optimum
IDL 属性在获取时,必须返回
最佳值。在设置时,给定的值必须转换为数字的最佳浮点表示,然后 optimum
内容属性必须设置为该字符串。
以下示例显示了仪表如何回退到本地化或漂亮的文本。
< p > Disk usage: < meter min = 0 value = 170261928 max = 233257824 > 170 261 928 bytes used
out of 233 257 824 bytes available</ meter ></ p >
fieldset
元素支持所有当前引擎。
支持所有当前引擎。
legend
元素,后跟流内容。disabled
— 是否禁用后代表单控件,除了任何在legend
内部的控件
form
—
将该元素与form
元素关联
name
—
用于form.elements
API 中使用的元素名称。[Exposed =Window ]
interface HTMLFieldSetElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute boolean disabled ;
readonly attribute HTMLFormElement ? form ;
[CEReactions ] attribute DOMString name ;
readonly attribute DOMString type ;
[SameObject ] readonly attribute HTMLCollection elements ;
readonly attribute boolean willValidate ;
[SameObject ] readonly attribute ValidityState validity ;
readonly attribute DOMString validationMessage ;
boolean checkValidity ();
boolean reportValidity ();
undefined setCustomValidity (DOMString error );
};
fieldset
元素表示一组表单控件(或其他内容),这些控件可以分组在一起,并且可以选择性地带有一个标题。标题由第一个legend
元素提供,该元素是fieldset
元素的子元素(如果有的话)。其余的后代构成了该组。
Element/fieldset#attr-disabled
支持所有当前引擎。
disabled
属性,当被指定时,会使fieldset
元素的所有表单控件后代(不包括fieldset
元素的第一个legend
元素子代,如果有的话)禁用。
如果满足以下任何条件,fieldset
元素就是禁用字段集:
form
属性用于显式地将fieldset
元素与其表单所有者关联。name
属性表示元素的名称。
fieldset.type
返回字符串 "fieldset"。
fieldset.elements
返回元素中的表单控件的HTMLCollection
。
disabled
IDL属性必须反映同名的内容属性。
type
IDL属性必须返回字符串"fieldset
"。
elements
IDL属性必须返回一个HTMLCollection
,它以fieldset
元素为根,其过滤器匹配列出的元素。
willValidate
,validity
,和validationMessage
属性,以及checkValidity()
,reportValidity()
,和setCustomValidity()
方法,都是约束验证API的一部分。form
和name
IDL属性是元素的表单API的一部分。
此示例显示了使用fieldset
元素来分组一组相关控件:
< fieldset >
< legend > Display</ legend >
< p >< label >< input type = radio name = c value = 0 checked > Black on White</ label >
< p >< label >< input type = radio name = c value = 1 > White on Black</ label >
< p >< label >< input type = checkbox name = g > Use grayscale</ label >
< p >< label > Enhance contrast < input type = range name = e list = contrast min = 0 max = 100 value = 0 step = 1 ></ label >
< datalist id = contrast >
< option label = Normal value = 0 >
< option label = Maximum value = 100 >
</ datalist >
</ fieldset >
以下代码片段显示了一个字段集,其中 legend 中的复选框控制字段集是否启用。字段集的内容包括两个必填文本控件和一个可选的年/月控件。
< fieldset name = "clubfields" disabled >
< legend > < label >
< input type = checkbox name = club onchange = "form.clubfields.disabled = !checked" >
Use Club Card
</ label > </ legend >
< p >< label > Name on card: < input name = clubname required ></ label ></ p >
< p >< label > Card number: < input name = clubnum required pattern = "[-0-9]+" ></ label ></ p >
< p >< label > Expiry date: < input name = clubexp type = month ></ label ></ p >
</ fieldset >
您还可以嵌套fieldset
元素。以下是一个扩展上一个示例的示例:
< fieldset name = "clubfields" disabled >
< legend > < label >
< input type = checkbox name = club onchange = "form.clubfields.disabled = !checked" >
Use Club Card
</ label > </ legend >
< p >< label > Name on card: < input name = clubname required ></ label ></ p >
< fieldset name = "numfields" >
< legend > < label >
< input type = radio checked name = clubtype onchange = "form.numfields.disabled = !checked" >
My card has numbers on it
</ label > </ legend >
< p >< label > Card number: < input name = clubnum required pattern = "[-0-9]+" ></ label ></ p >
</ fieldset >
< fieldset name = "letfields" disabled >
< legend > < label >
< input type = radio name = clubtype onchange = "form.letfields.disabled = !checked" >
My card has letters on it
</ label > </ legend >
< p >< label > Card code: < input name = clublet required pattern = "[A-Za-z]+" ></ label ></ p >
</ fieldset >
</ fieldset >
在此示例中,如果外部的“使用俱乐部卡”复选框未选中,则包括两个嵌套的fieldset
的
legend 中的两个单选按钮在内的外部fieldset
中的所有内容都将被禁用。然而,如果复选框被选中,则两个单选按钮都将被启用,并让您选择要启用的两个内部fieldset
之一。
此示例显示了一个控件组,其中legend
元素既标记了该组,又在文档大纲中显示了嵌套的标题元素:
< fieldset >
< legend > < h2 >
How can we best reach you?
</ h2 > </ legend >
< p > < label >
< input type = radio checked name = contact_pref >
Phone
</ label > </ p >
< p > < label >
< input type = radio name = contact_pref >
Text
</ label > </ p >
< p > < label >
< input type = radio name = contact_pref >
Email
</ label > </ p >
</ fieldset >
legend
元素所有当前引擎支持。
所有当前引擎支持。
fieldset
元素的第一个子元素。
[Exposed =Window ]
interface HTMLLegendElement : HTMLElement {
[HTMLConstructor ] constructor ();
readonly attribute HTMLFormElement ? form ;
// also has obsolete members
};
legend
元素表示其父fieldset
元素内容的标题。
legend.form
返回元素的form
元素,如果有的话,否则返回null。
form
IDL属性的行为取决于legend
元素是否在fieldset
元素中。如果legend
的父元素是fieldset
,那么form
IDL属性必须返回与该fieldset
元素上的form
IDL属性相同的值。否则,必须返回null。
大多数表单控件都有一个值和一个选中状态。(后者仅用于input
元素。)这些用于描述用户如何与控件进行交互。
控件的值是其内部状态。因此,它可能与用户的当前输入不匹配。
例如,如果用户在一个预期为数字的数字字段中输入单词“three”,用户的输入将是字符串“three”,但控件的值将保持不变。或者,如果用户在电子邮件字段中输入电子邮件地址“ awesome@example.com”(前导空格),用户的输入将是字符串“ awesome@example.com”,但浏览器的电子邮件字段UI可能会将其转换为没有前导空格的值“awesome@example.com
”。
input
和textarea
元素有一个脏值标志。 这用于跟踪值和默认值之间的交互。如果为false,值镜像默认值。如果为true,则忽略默认值。
input
、
textarea
和select
元素有一个
用户有效性布尔值。它最初设置为false。
为了定义约束验证在input
元素的multiple
属性中的行为,input
元素
也可以有单独定义的值s。
为了定义maxlength
和minlength
属性的行为,以及其他特定于
textarea
元素的API,所有具有值的表单控件也有一个获取API值的算法。默认情况下,此算法只是简单地返回控件的值。
select
元素没有值;
使用的是其option
元素的选中状态。
表单控件可以被指定为可变的。
这决定了(通过本规范中依赖于元素是否被指定为可变的定义和要求)用户是否可以修改表单控件的值或选中状态,或者控件是否可以自动预填充。
与表单关联的元素可以与form
元素有关系,这称为元素的表单所有者。如果与表单关联的元素未与form
元素关联,则其表单所有者为null。
与表单关联的元素有一个关联的解析器插入标志。
Support in all current engines.
Support in all current engines.
与表单关联的元素默认与其最近的祖先form
元素相关联(如下所述),但是,如果它是列表,则可以指定一个form
属性来覆盖此关联。
此功能允许作者解决嵌套form
元素的支持缺乏问题。
如果列出的与表单关联的元素指定了form
属性,则该属性的值必须是该元素树中某个form
元素的ID。
本节中的规则因以下事实而变得复杂:尽管符合规范的文档或树永远不会包含嵌套的form
元素,但完全有可能(例如,使用执行DOM操作的脚本)生成具有此类嵌套元素的树。这些规则还因HTML解析器中的规则而复杂化,这些规则由于历史原因,可能导致与表单关联的元素与不是其祖先的form
元素相关联。
当创建与表单关联的元素时,其表单所有者必须初始化为null(无所有者)。
当与表单关联的元素要与表单关联时,其表单所有者必须设置为该表单。
当列出的与表单关联的元素的form
属性被设置、更改或删除时,用户代理必须重置该元素的表单所有者。
当一个列表的表单关联元素有一个form
属性,并且树中任何元素的ID发生变化时,用户代理必须重置该表单关联元素的表单所有者。
当一个列表的表单关联元素有一个form
属性,并且具有ID的元素被插入或移出文档
时,用户代理必须重置该表单关联元素的表单所有者。
要重置表单所有者,请执行以下步骤:与表单关联的元素element:
在以下不合格的代码片段中
...
< form id = "a" >
< div id = "b" ></ div >
</ form >
< script >
document. getElementById( 'b' ). innerHTML =
'<table><tr><td></form><form id="c"><input id="d"></table>' +
'<input id="e">' ;
</ script >
...
"d"的表单所有者将是内部嵌套表单"c",而"e"的表单所有者将是外部表单"a"。
这是这样发生的:首先,"e"节点在HTML解析器中与"c"相关联。然后,innerHTML
算法将节点从临时文档移动到"b"元素。在这一点上,节点看到它们的祖先链发生变化,因此解析器所做的所有“魔术”关联都会重置为正常的祖先关联。
element.form
Support in all current engines.
Support in all current engines.
返回元素的表单所有者。
如果没有,则返回null。
列出的与表单关联的元素(除了与表单关联的自定义元素)有一个form
IDL属性,获取时必须返回元素的表单所有者,如果没有则返回null。
Support in all current engines.
与表单关联的自定义元素没有form
IDL属性。相反,它们的ElementInternals
对象有一个form
IDL属性。获取时,如果目标元素不是与表单关联的自定义元素,则必须抛出DOMException
的“"NotSupportedError
"”。否则,必须返回元素的表单所有者,如果没有则返回null。
name
属性Support in all current engines.
name
内容属性给出了表单控件的名称,用于表单提交和form
元素的elements
对象。如果指定了该属性,则其值不能是空字符串或isindex
。
许多用户代理在历史上对名称为isindex
的表单中第一个文本控件实现了特殊支持,本规范先前也定义了相关的用户代理要求。然而,一些用户代理随后删除了该特殊支持,并且相关要求已从本规范中删除。因此,为了避免在遗留用户代理中的问题性重新解释,不再允许使用isindex
名称。
除isindex
外,name
的任何非空值都是允许的。对名称_charset_
的ASCII不区分大小写匹配是特殊的:如果用作没有value
属性的 控件的名称,则在提交期间,value
属性会自动获得一个值,该值包含提交字符编码。
DOM篡改是安全问题的常见原因。避免在name
内容属性中使用内置表单属性的名称。
let form = document. createElement( "form" );
let input = document. createElement( "input" );
form. appendChild( input);
form. method; // => "get"
input. name = "method" ; // DOM clobbering occurs here
form. method === input; // => true
由于输入名称优先于内置表单属性,JavaScript引用form.method
将指向名为“method”的input
元素,而不是内置的method
属性。
dirname
属性
Support in all current engines.
dirname
属性在表单控件元素上启用了元素的方向性的提交,并给出了在表单提交期间包含此值的控件的名称。如果指定了此类属性,其值不能是空字符串。
在此示例中,一个表单包含一个文本控件和一个提交按钮:
< form action = "addcomment.cgi" method = post >
< p >< label > Comment: < input type = text name = "comment" dirname = "comment.dir" required ></ label ></ p >
< p >< button name = "mode" type = submit value = "add" > Post Comment</ button ></ p >
</ form >
当用户提交表单时,用户代理会包含三个字段,一个名为"comment",一个名为"comment.dir",一个名为"mode";因此,如果用户输入"Hello",提交的内容可能是这样的:
comment=Hello&comment.dir=ltr&mode=add
如果用户手动切换到从右到左的书写方向并输入"مرحبا",提交的内容可能是这样的:
comment=%D9%85%D8%B1%D8%AD%D8%A8%D8%A7&comment.dir=rtl&mode=add
maxlength
属性表单控件
maxlength
属性,由 dirty value flag
控制,声明了用户可以输入的字符数限制。字符数使用 长度 测量,并且在 textarea
元素的情况下,所有换行符被规范化为一个字符(与 CRLF 对不同)。
如果一个元素指定了其 表单控件 maxlength
属性,该属性的值必须是一个 有效的非负整数。如果指定了该属性并将其值应用于 解析非负整数的规则
得到了一个数字,那么该数字就是元素的 最大允许值长度。如果省略了该属性或解析其值时出现错误,那么就没有 最大允许值长度。
约束验证:如果一个元素有 最大允许值长度,其 dirty value flag 为 true,其 值 最近一次由用户编辑更改(而不是脚本更改),并且该元素的 长度 大于元素的 最大允许值长度,那么该元素 过长。
用户代理可以防止用户使元素的 API 值 设置为一个长度大于该元素的 最大允许值长度 的值。
在 textarea
元素的情况下,API 值 和 值
是不同的。特别是,在检查 换行规范化 之前会应用 最大允许值长度(而不会应用 textarea 包装转换)。
minlength
属性表单控件
minlength
属性,由 dirty value flag
控制,声明了用户可以输入的字符数下限。"字符数" 使用 长度 测量,并且在 textarea
元素的情况下,所有换行符被规范化为一个字符(与 CRLF 对不同)。
minlength
属性不暗示 required
属性。如果表单控件没有 required
属性,则仍可以省略该值;minlength
属性仅在用户输入任何值时生效。如果不允许空字符串,则还需要设置 required
属性。
如果一个元素指定了其 表单控件
minlength
属性,该属性的值必须是一个 有效的非负整数。如果指定了该属性并将其值应用于
解析非负整数的规则
得到了一个数字,那么该数字就是元素的 最小允许值长度。如果省略了该属性或解析其值时出现错误,那么就没有 最小允许值长度。
如果一个元素同时有 最大允许值长度 和 最小允许值长度,则 最小允许值长度 必须小于或等于 最大允许值长度。
约束验证:如果一个元素有 最小允许值长度,其 dirty value flag 为 true,其 值 最近一次由用户编辑更改(而不是脚本更改),其 值 不是空字符串,并且该元素的 长度 小于该元素的 最小允许值长度,那么该元素 过短。
在此示例中,有四个文本控件。第一个是必填项,长度必须至少为 5 个字符。其他三个是可选的,但如果用户填写其中一个,用户必须输入至少 10 个字符。
< form action = "/events/menu.cgi" method = "post" >
< p >< label > Name of Event: < input required minlength = 5 maxlength = 50 name = event ></ label ></ p >
< p >< label > Describe what you would like for breakfast, if anything:
< textarea name = "breakfast" minlength = "10" ></ textarea ></ label ></ p >
< p >< label > Describe what you would like for lunch, if anything:
< textarea name = "lunch" minlength = "10" ></ textarea ></ label ></ p >
< p >< label > Describe what you would like for dinner, if anything:
< textarea name = "dinner" minlength = "10" ></ textarea ></ label ></ p >
< p >< input type = submit value = "Submit Request" ></ p >
</ form >
disabled
属性支持所有当前的引擎。
支持所有当前的引擎。
支持所有当前的引擎。
支持所有当前的引擎。
disabled
内容属性是一个布尔属性。
disabled
属性用于option
元素和 disabled
属性用于 optgroup
元素是分别定义的。
如果以下任何一种情况为真,则表单控件是禁用的:
该元素是 button
、input
、select
、textarea
或表单关联自定义元素,且该元素上指定了
disabled
属性(无论其值如何);或者
该元素是 fieldset
元素的后代元素,并且 disabled
属性在该 fieldset
元素的第一个 legend
元素子代(如果有的话)的后代中未指定。
如果表单控件被禁用,则必须防止在用户交互任务源上排队的任何
click
事件被分派到该元素上。
支持所有当前的引擎。
支持所有当前的引擎。
disabled
IDL 属性必须反映disabled
内容属性。
Element/form#Attributes_for_form_submission
支持所有当前的引擎。
表单提交属性 可以在 form
元素和 提交按钮(表示提交表单的按钮的元素,例如其
input
元素的 type
属性处于 提交按钮 状态)上指定。
可在 form
元素上指定的 表单提交属性 是 action
、enctype
、method
、novalidate
和 target
。
可在 提交按钮上指定的相应 表单提交属性
是 formaction
、formenctype
、formmethod
、formnovalidate
和 formtarget
。当省略时,它们默认为
form
元素上指定的相应属性的值。
支持所有当前的引擎。
action
和 formaction
内容属性(如果指定)必须具有 有效的非空URL(可能被空格包围) 值。
元素的 action 是该元素的 formaction
属性的值(如果该元素是 提交按钮
并且具有此属性),或其 表单所有者 的 action
属性的值(如果有),否则为空字符串。
支持所有当前的引擎。
method
和 formmethod
内容属性是 枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
get
|
GET | 表示 form
将使用 HTTP GET 方法。
|
post
|
POST | 表示 form
将使用 HTTP POST 方法。
|
dialog
|
Dialog | 表示 form
旨在关闭包含该表单的 对话框 (如果有),否则不提交。
|
method
属性的 缺失值默认值 和 无效值默认值 均为 GET 状态。
formmethod
属性没有 缺失值默认值,其 无效值默认值 为 GET 状态。
元素的 method 是这些状态之一。如果元素是 提交按钮 并具有 formmethod
属性,则该元素的 method 是该属性的状态;否则,它是其 表单所有者 的 method
属性的状态。
在此示例中,使用 method
属性显式指定默认值 "get
",以便在
URL 中提交搜索查询:
< form method = "get" action = "/search.cgi" >
< p >< label > Search terms: < input type = search name = q ></ label ></ p >
< p >< input type = submit ></ p >
</ form >
另一方面,在此示例中,使用 method
属性指定值 "post
",以便用户的消息在
HTTP 请求的主体中提交:
< form method = "post" action = "/post-message.cgi" >
< p >< label > Message: < input type = text name = m ></ label ></ p >
< p >< input type = submit value = "Submit message" ></ p >
</ form >
在此示例中,form
与 对话框
一起使用。使用 method
属性的 "dialog
"
关键字使对话框在提交表单时自动关闭。
< dialog id = "ship" >
< form method = dialog >
< p > A ship has arrived in the harbour.</ p >
< button type = submit value = "board" > Board the ship</ button >
< button type = submit value = "call" > Call to the captain</ button >
</ form >
</ dialog >
< script >
var ship = document. getElementById( 'ship' );
ship. showModal();
ship. onclose = function ( event) {
if ( ship. returnValue == 'board' ) {
// ...
} else {
// ...
}
};
</ script >
支持所有当前引擎。
enctype
和 formenctype
内容属性是 枚举属性,具有以下关键字和状态:
application/x-www-form-urlencoded
”关键字及相应状态。multipart/form-data
”关键字及相应状态。text/plain
”关键字及相应状态。该属性的 缺失值默认值 和
无效值默认值 均为 application/x-www-form-urlencoded
状态。
formenctype
属性没有 缺失值默认值,其 无效值默认值 为 application/x-www-form-urlencoded
状态。
元素的 enctype 是这三种状态之一。如果元素是 提交按钮 并具有 formenctype
属性,则该元素的 enctype 是该属性的状态;否则,它是其
表单所有者 的 enctype
属性的状态。
支持所有当前的引擎。
target
和 formtarget
内容属性(如果指定)必须具有 有效的可导航目标名称或关键字 值。
支持所有当前的引擎。
novalidate
和 formnovalidate
内容属性是 布尔属性。如果存在,它们表示表单在提交时不进行验证。
元素的 no-validate 状态 为 true 如果该元素是 提交按钮 并且该元素的 formnovalidate
属性存在,或者其 表单所有者 的 novalidate
属性存在,否则为 false。
该属性用于在具有验证约束的表单中包含“保存”按钮,以允许用户保存进度,即使他们尚未完全输入表单中的数据。以下示例显示了一个简单的表单,该表单有两个必填字段。有三个按钮:一个提交表单,要求填写所有字段;一个保存表单,以便用户可以稍后回来填写;一个取消整个表单。
< form action = "editor.cgi" method = "post" >
< p >< label > Name: < input required name = fn ></ label ></ p >
< p >< label > Essay: < textarea required name = essay ></ textarea ></ label ></ p >
< p >< input type = submit name = submit value = "Submit essay" ></ p >
< p >< input type = submit formnovalidate name = save value = "Save essay" ></ p >
< p >< input type = submit formnovalidate name = cancel value = "Cancel" ></ p >
</ form >
支持所有当前的引擎。
支持所有当前的引擎。
支持所有当前的引擎。
支持所有当前的引擎。
支持所有当前的引擎。
action
IDL 属性必须
反映
同名内容属性,除非获取时内容属性缺失或其值为空字符串,则必须返回元素的 节点文档 的 URL。target
IDL 属性必须 反映 同名内容属性。method
和 enctype
IDL 属性必须 反映 同名内容属性,限于仅已知值。encoding
IDL 属性必须 反映 enctype
内容属性,限于仅已知值。noValidate
IDL 属性必须 反映 novalidate
内容属性。formAction
IDL 属性必须 反映 formaction
内容属性,除非获取时内容属性缺失或其值为空字符串,则必须返回元素的 节点文档 的 URL。formEnctype
IDL 属性必须 反映 formenctype
内容属性,限于仅已知值。formMethod
IDL 属性必须 反映 formmethod
内容属性,限于仅已知值。formNoValidate
IDL 属性必须 反映 formnovalidate
内容属性。formTarget
IDL 属性必须 反映 formtarget
内容属性。
autocomplete
属性
支持所有当前的引擎。
用户代理有时具有帮助用户填写表单的功能,例如根据之前的用户输入预填用户的地址。autocomplete
内容属性可用于提示用户代理如何或是否提供此类功能。
此属性有两种使用方式。当处于自动填充期望模式时,
autocomplete
属性描述用户期望输入的内容。当处于自动填充锚模式时,
autocomplete
属性描述给定值的意义。
在 input
元素上,其 type
属性为 状态时,
autocomplete
属性处于自动填充锚模式。
在其他情况下,它处于自动填充期望模式。
当处于自动填充期望模式时,
autocomplete
属性(如指定)必须具有一个值,该值是由空格分隔的标记集合,其组成如下:
要么是单个标记,与字符串"off
"进行ASCII不区分大小写匹配;
要么是单个标记,与字符串"on
"进行ASCII不区分大小写匹配;
或者是自动填充详细标记。
当处于自动填充锚模式时,
autocomplete
属性(如指定)必须具有一个值,该值是由空格分隔的标记集合组成,只包含自动填充详细标记
(即不允许使用"on
"和"off
"关键字)。
自动填充详细标记如下所示,按给定顺序排列:
可选标记,其前八个字符与字符串"section-
"进行ASCII不区分大小写匹配,表示字段属于命名组。
例如,如果表单中有两个送货地址,则可以将它们标记为:
< fieldset >
< legend > Ship the blue gift to...</ legend >
< p > < label > Address: < textarea name = ba autocomplete = "section-blue shipping street-address" ></ textarea > </ label >
< p > < label > City: < input name = bc autocomplete = "section-blue shipping address-level2" > </ label >
< p > < label > Postal Code: < input name = bp autocomplete = "section-blue shipping postal-code" > </ label >
</ fieldset >
< fieldset >
< legend > Ship the red gift to...</ legend >
< p > < label > Address: < textarea name = ra autocomplete = "section-red shipping street-address" ></ textarea > </ label >
< p > < label > City: < input name = rc autocomplete = "section-red shipping address-level2" > </ label >
< p > < label > Postal Code: < input name = rp autocomplete = "section-red shipping postal-code" > </ label >
</ fieldset >
可选标记,与以下字符串之一进行ASCII不区分大小写匹配:
shipping
",表示字段是送货地址或联系信息的一部分
billing
",表示字段是账单地址或联系信息的一部分
以下两种选择之一:
与以下自动填充字段名称之一进行ASCII不区分大小写匹配的标记,不包括那些对控件不合适的字段:
name
"
honorific-prefix
"
given-name
"
additional-name
"
family-name
"
honorific-suffix
"
nickname
"
username
"
new-password
"
current-password
"
one-time-code
"
organization-title
"
organization
"
street-address
"
address-line1
"
address-line2
"
address-line3
"
address-level4
"
address-level3
"
address-level2
"
address-level1
"
country
"
country-name
"
postal-code
"
cc-name
"
cc-given-name
"
cc-additional-name
"
cc-family-name
"
cc-number
"
cc-exp
"
cc-exp-month
"
cc-exp-year
"
cc-csc
"
cc-type
"
transaction-currency
"
transaction-amount
"
language
"
bday
"
bday-day
"
bday-month
"
bday-year
"
sex
"
url
"
photo
"
(请参见下表中这些值的描述。)
以下顺序:
可选标记,与以下字符串之一进行ASCII不区分大小写匹配:
home
",表示该字段用于联系某人的住处
work
",表示该字段用于联系某人的工作地点
mobile
",表示该字段用于无论位置如何都可以联系某人
fax
",表示该字段描述传真机的联系信息
pager
",表示该字段描述寻呼机或传呼机的联系信息
一个与以下之一进行ASCII不区分大小写匹配的自动填充字段名称的标记,排除那些不适合该控件的名称:
tel
"
tel-country-code
"
tel-national
"
tel-area-code
"
tel-local
"
tel-local-prefix
"
tel-local-suffix
"
tel-extension
"
email
"
impp
"
(请参见下表中这些值的描述。)
可选标记,与字符串"webauthn
"进行ASCII不区分大小写匹配,表示用户代理应在用户与表单控件交互时显示通过条件
中介可用的公共密钥凭证。webauthn
仅对input
和textarea
元素有效。
如前所述,属性和其关键字的含义取决于该属性所佩戴的斗篷。
"off
"关键字表示控件的输入数据特别敏感(例如核武器的激活代码);或它是一个永不重用的值(例如银行登录的一次性密钥),因此用户必须每次显式输入数据,而不是依赖用户代理预填充值;或文档提供了自己的自动填充机制,并且不希望用户代理提供自动填充值。
"on
"关键字表示用户代理可以向用户提供自动填充值,但不提供有关用户可能输入数据类型的进一步信息。用户代理将不得不使用启发式方法来决定建议哪些自动填充值。
上述自动填充字段表明用户代理可以向用户提供自动填充值,并指定预期值的类型。每个关键字的含义在下表中描述。
如果省略autocomplete
属性,则使用元素的表单所有者的autocomplete
属性对应的默认值("on
"或"off
")。如果没有表单所有者,则使用值"on
"。
上述自动填充字段表明特定类型值提供的值是为此元素提供的值。每个关键字的含义在下表中描述。
在此示例中,页面已明确指定了交易的货币和金额。表单要求提供信用卡和其他账单详细信息。用户代理可以使用此信息来建议其已知具有足够余额并支持相关货币的信用卡。
< form method = post action = "step2.cgi" >
< input type = hidden autocomplete = transaction-currency value = "CHF" >
< input type = hidden autocomplete = transaction-amount value = "15.00" >
< p >< label > Credit card number: < input type = text inputmode = numeric autocomplete = cc-number ></ label >
< p >< label > Expiry Date: < input type = month autocomplete = cc-exp ></ label >
< p >< input type = submit value = "Continue..." >
</ form >
自动填充字段关键字之间的关系如下面的表格所述。每个表格中的字段名对应的行在“含义”列中描述了该行的含义。一些字段对应于其他字段的子部分;例如,信用卡到期日期可以表示为一个字段,给出到期的月份和年份("cc-exp
"),或者表示为两个字段,一个给出月份("cc-exp-month
"),另一个给出年份("cc-exp-year
")。在这种情况下,更广泛的字段名称涵盖多个行,其中定义了更狭窄的字段。
一般来说,鼓励作者使用更广泛的字段而不是更狭窄的字段,因为更狭窄的字段往往暴露出西方偏见。例如,虽然在一些西方文化中,常见的是有一个名字和一个姓氏,并以这个顺序排列(因此通常称为名和姓),但许多文化将姓氏放在前,名字放在后,还有许多文化仅有一个名字(单名)。因此,使用单个字段更为灵活。
某些字段仅适用于特定的表单控件。一个自动填充字段名称对控件不适用,如果该控件不属于描述该字段的第一行的第五列中列出的组。每个组包含的控件在表格下方描述。
字段名称 | 含义 | 规范格式 | 规范格式示例 | 控件组 | |||
---|---|---|---|---|---|---|---|
"name "
|
全名 | 自由格式文本,无换行符 | Sir Timothy John Berners-Lee, OM, KBE, FRS, FREng, FRSA | 文本 | |||
"honorific-prefix "
|
前缀或头衔(例如“Mr.”,“Ms.”,“Dr.”,“Mlle”) | 自由格式文本,无换行符 | Sir | 文本 | |||
"given-name "
|
名字(在一些西方文化中,也称为first name) | 自由格式文本,无换行符 | Timothy | 文本 | |||
"additional-name "
|
其他名字(在一些西方文化中,也称为middle names,除了名字以外的名字) | 自由格式文本,无换行符 | John | 文本 | |||
"family-name "
|
姓氏(在一些西方文化中,也称为last name或surname) | 自由格式文本,无换行符 | Berners-Lee | 文本 | |||
"honorific-suffix "
|
后缀(例如“Jr.”,“B.Sc.”,“MBASW”,“II”) | 自由格式文本,无换行符 | OM, KBE, FRS, FREng, FRSA | 文本 | |||
"nickname "
|
昵称、屏幕名称、句柄:通常用作全名的简短名称 | 自由格式文本,无换行符 | Tim | 文本 | |||
"organization-title "
|
职位名称(例如“Software Engineer”,“Senior Vice President”,“Deputy Managing Director”) | 自由格式文本,无换行符 | Professor | 文本 | |||
"username "
|
用户名 | 自由格式文本,无换行符 | timbl | 用户名 | |||
"new-password "
|
新密码(例如创建账户或更改密码时) | 自由格式文本,无换行符 | GUMFXbadyrS3 | 密码 | |||
"current-password "
|
由username 字段标识的账户的当前密码(例如登录时)
|
自由格式文本,无换行符 | qwerty | 密码 | |||
"one-time-code "
|
用于验证用户身份的一次性代码 | 自由格式文本,无换行符 | 123456 | 密码 | |||
"organization "
|
与该字段关联的其他字段中的人、地址或联系信息对应的公司名称 | 自由格式文本,无换行符 | World Wide Web Consortium | 文本 | |||
"street-address "
|
街道地址(多行,保留换行符) | 自由格式文本 | 32 Vassar Street MIT Room 32-G524 |
多行 | |||
"address-line1 "
|
街道地址(每个字段一行) | 自由格式文本,无换行符 | 32 Vassar Street | 文本 | |||
"address-line2 "
|
自由格式文本,无换行符 | MIT Room 32-G524 | 文本 | ||||
"address-line3 "
|
自由格式文本,无换行符 | 文本 | |||||
"address-level4 "
|
地址中的最细粒度行政级别,适用于有四个行政级别的地址 | 自由格式文本,无换行符 | 文本 | ||||
"address-level3 "
|
第三行政级别,适用于有三个或更多行政级别的地址 | 自由格式文本,无换行符 | 文本 | ||||
"address-level2 "
|
第二行政级别,适用于有两个或更多行政级别的地址;在有两个行政级别的国家,这通常是找到相关街道地址的城市、乡镇、村庄或其他地方 | 自由格式文本,无换行符 | Cambridge | 文本 | |||
"address-level1 "
|
地址中的最广泛行政级别,即找到相关街道地址的省份;例如在美国,这将是州;在瑞士是州;在英国是邮政城镇 | 自由格式文本,无换行符 | MA | 文本 | |||
"country "
|
国家代码 | 有效的ISO 3166-1-alpha-2国家代码 [ISO3166] | US | 文本 | |||
"country-name "
|
国家名称 | 自由格式文本,无换行符;某些情况下从country 派生
|
US | 文本 | |||
"postal-code "
|
邮政编码、邮政编码、邮政编码、CEDEX代码(如果是CEDEX,请在address-level2 字段中附加“CEDEX”及相关的arrondissement)
|
自由格式文本,无换行符 | 02139 | 文本 | |||
"cc-name "
|
支付工具上显示的全名 | 自由格式文本,无换行符 | Tim Berners-Lee | 文本 | |||
"cc-given-name "
|
支付工具上显示的名字(在一些西方文化中,也称为first name) | 自由格式文本,无换行符 | Tim | 文本 | |||
"cc-additional-name "
|
支付工具上显示的其他名字(在一些西方文化中,也称为middle names,除了名字以外的名字) | 自由格式文本,无换行符 | 文本 | ||||
"cc-family-name "
|
支付工具上显示的姓氏(在一些西方文化中,也称为last name或surname) | 自由格式文本,无换行符 | Berners-Lee | 文本 | |||
"cc-number "
|
标识支付工具的代码(例如信用卡号码) | ASCII数字 | 4114360123456785 | 文本 | |||
"cc-exp "
|
支付工具的到期日期 | 有效的月份字符串 | 2014-12 | 月份 | |||
"cc-exp-month "
|
支付工具的到期日期的月份部分 | 有效整数,范围为1..12 | 12 | 数字 | |||
"cc-exp-year "
|
支付工具的到期日期的年份部分 | 有效整数,大于零 | 2014 | 数字 | |||
"cc-csc "
|
支付工具的安全码(也称为卡安全码(CSC),卡验证码(CVC),卡验证值(CVV),签名面板代码(SPC),信用卡ID(CCID)等) | ASCII数字 | 419 | 文本 | |||
"cc-type "
|
支付工具的类型 | 自由格式文本,无换行符 | Visa | 文本 | |||
"transaction-currency "
|
用户希望交易使用的货币 | ISO 4217货币代码[ISO4217] | GBP | 文本 | |||
"transaction-amount "
|
用户希望进行的交易金额(例如输入出价或售价时) | 有效的浮点数 | 401.00 | 数字 | |||
"language "
|
首选语言 | 有效的BCP 47语言标签[BCP47] | en | 文本 | |||
"bday "
|
生日 | 有效的日期字符串 | 1955-06-08 | 日期 | |||
"bday-day "
|
生日的日期部分 | 有效整数,范围为1..31 | 8 | 数字 | |||
"bday-month "
|
生日的月份部分 | 有效整数,范围为1..12 | 6 | 数字 | |||
"bday-year "
|
生日的年份部分 | 有效整数,大于零 | 1955 | 数字 | |||
"sex "
|
性别认同(例如女性,Fa'afafine) | 自由格式文本,无换行符 | Male | 文本 | |||
"url "
|
主页或与该字段关联的其他字段中的公司、个人、地址或联系信息对应的其他网页 | 有效的URL字符串 | https://www.w3.org/People/Berners-Lee/ | URL | |||
"photo "
|
与该字段关联的其他字段中的公司、个人、地址或联系信息对应的照片、图标或其他图像 | 有效的URL字符串 | https://www.w3.org/Press/Stock/Berners-Lee/2001-europaeum-eighth.jpg | URL | |||
"tel "
|
完整电话号码,包括国家代码 | ASCII数字和U+0020空格字符,以U+002B加号字符(+)为前缀 | +1 617 253 5702 | 电话 | |||
"tel-country-code "
|
电话号码的国家代码部分 | ASCII数字,以U+002B加号字符(+)为前缀 | +1 | 文本 | |||
"tel-national "
|
没有国家代码部分的电话号码,如果适用,应用国家内部前缀 | ASCII数字和U+0020空格字符 | 617 253 5702 | 文本 | |||
"tel-area-code "
|
电话号码的区号部分,如果适用,应用国家内部前缀 | ASCII数字 | 617 | 文本 | |||
"tel-local "
|
没有国家代码和区号部分的电话号码 | ASCII数字 | 2535702 | 文本 | |||
"tel-local-prefix "
|
在该组件分为两个组件时,区号后面组件的第一部分 | ASCII数字 | 253 | 文本 | |||
"tel-local-suffix "
|
在该组件分为两个组件时,区号后面组件的第二部分 | ASCII数字 | 5702 | 文本 | |||
"tel-extension "
|
电话号码的内部分机号 | ASCII数字 | 1000 | 文本 | |||
"email "
|
电子邮件地址 | 有效的电子邮件地址 | timbl@w3.org | 用户名 | |||
"impp "
|
表示即时消息协议终端的URL(例如,"aim:goim?screenname=example "或"xmpp:fred@example.net ")
|
有效的URL字符串 | irc://example.org/timbl,isuser | URL |
这些组对应的控件如下:
input
元素,其 type
属性在 Hidden 状态input
元素,其 type
属性在 Text
状态input
元素,其 type
属性在 Search
状态textarea
元素select
元素input
元素,其 type
属性在 Hidden 状态textarea
元素select
元素input
元素,其 type
属性在 Hidden 状态input
元素,其 type
属性在 Text
状态input
元素,其 type
属性在 Search
状态input
元素,其 type
属性在 Password 状态textarea
元素select
元素input
元素,其 type
属性在 Hidden 状态input
元素,其 type
属性在 Text
状态input
元素,其 type
属性在 Search
状态input
元素,其 type
属性在 URL 状态textarea
元素select
元素input
元素,其 type
属性在 Hidden 状态input
元素,其 type
属性在 Text
状态input
元素,其 type
属性在 Search
状态input
元素,其 type
属性在 Email 状态textarea
元素select
元素input
元素,其 type
属性在 Hidden 状态input
元素,其 type
属性在 Text
状态input
元素,其 type
属性在 Search
状态input
元素,其 type
属性在 Telephone 状态textarea
元素select
元素input
元素,其 type
属性在 Hidden 状态input
元素,其 type
属性在 Text
状态input
元素,其 type
属性在 Search
状态input
元素,其 type
属性在 Number 状态textarea
元素select
元素input
元素,其 type
属性在 Hidden 状态input
元素,其 type
属性在 Text
状态input
元素,其 type
属性在 Search
状态input
元素,其 type
属性在 Month 状态textarea
元素select
元素input
元素,其 type
属性在 Hidden 状态input
元素,其 type
属性在 Text
状态input
元素,其 type
属性在 Search
状态input
元素,其 type
属性在 Date 状态textarea
元素select
元素地址级别: "address-level1
"
– "address-level4
"
字段用于描述街道地址的地方。不同地区有不同数量的级别。例如,美国使用两个级别(州和城镇),英国使用一个或两个级别(邮镇,有时还包括地方),而中国可以使用三个级别(省、市、区)。"address-level1
"
字段代表最宽泛的行政区划。不同地区的字段顺序不同;例如,在美国,城镇(第2级)在州(第1级)之前;而在日本,县(第1级)在城市(第2级)之前,城市在区(第3级)之前。建议作者提供
符合国家惯例的表单(根据用户更改国家来隐藏、显示和重新排列字段)。
每个具有input
元素的autocomplete
属性适用,每个select
元素和每个textarea
元素都有一个自动填充提示集、一个自动填充范围、一个自动填充字段名、一个非自动填充凭证类型和一个IDL暴露的自动填充值。
自动填充字段名指定字段中预期的数据类型,例如,"street-address
"或"cc-exp
"。
自动填充提示集标识用户代理要查找的地址或联系信息类型,例如,"shipping
fax
"或"billing
"。
非自动填充凭证类型标识用户代理在用户与字段交互时可能提供的凭证类型,并与其他自动填充字段值一起提供。如果此值为"webauthn
"而不是null,则选择这种类型的凭证将解决一个挂起的条件
中介navigator.credentials.get()
请求,而不是自动填充字段。
例如,一个登录页面可以指示用户代理自动填充已保存的密码,或者显示一个公钥凭证,它将解决一个挂起的navigator.credentials.get()
请求。用户可以选择任意一种方式登录。
< input name = password type = password autocomplete = "current-password webauthn" >
自动填充范围标识信息涉及同一主题的字段组,由自动填充提示集组成,如果适用,还包括"section-*
"前缀,例如,"billing
"、"section-parent shipping
"或"section-child shipping home
"。
这些值是通过运行以下算法定义的:
如果元素没有autocomplete
属性,则跳到标有默认的步骤。
令tokens为将属性的值按ASCII空格分割的结果分割字符串上的空格。
如果tokens为空,则跳到标有默认的步骤。
令index为tokens中最后一个标记的索引。
令field为tokens中的第index个标记。
将category和maximum tokens对设置为根据field确定字段类别的结果确定字段类别。
如果category为null,则跳到标有默认的步骤。
如果tokens中的标记数大于maximum tokens,则跳到标有默认的步骤。
如果category为Off或Automatic,但元素的autocomplete
属性穿着自动填充锚披风,则跳到标有默认的步骤。
如果category为Off,则令元素的自动填充字段名为字符串"off
",令其自动填充提示集为空,并令其IDL暴露的自动填充值为字符串"off
"。然后,返回。
如果category为Automatic,则令元素的自动填充字段名为字符串"on
",令其自动填充提示集为空,并令其IDL暴露的自动填充值为字符串"on
"。然后,返回。
令scope tokens为空列表。
令hint tokens为空集。
令credential type为null。
令IDL value的值与field相同。
如果category为Credential,并且tokens中的第index个标记是"webauthn
"的ASCII大小写不敏感匹配ASCII大小写不敏感,则运行以下子步骤:
将credential type设置为"webauthn
"。
如果tokens中的第index个标记是第一个条目,则跳到标有完成的步骤。
将index减一。
根据tokens中的第index个标记,将category和maximum tokens对设置为确定字段类别的结果确定字段类别。
如果category不是Normal且category不是Contact,则跳到标有默认的步骤。
如果index大于maximum tokens减一(即,如果剩余标记的数量大于maximum tokens),则跳到标有默认的步骤。
将IDL value设置为tokens中的第index个标记、一个U+0020空格字符和之前IDL value值的串联。
如果tokens中的第index个标记是第一个条目,则跳到标有完成的步骤。
将index减一。
如果category为Contact,并且tokens中的第index个标记是以下列表中的字符串之一的ASCII大小写不敏感匹配ASCII大小写不敏感,则运行以下子步骤:
子步骤如下:
令contact为上面列表中的匹配字符串。
将contact插入到scope tokens的开头。
将contact添加到hint tokens中。
令IDL value为contact、一个U+0020空格字符和之前IDL value值的串联。
如果tokens中的第index个条目是第一个条目,则跳到标有完成的步骤。
将index减一。
如果tokens中的第index个标记是以下列表中的字符串之一的ASCII大小写不敏感匹配ASCII大小写不敏感,则运行以下子步骤:
子步骤如下:
令mode为上面列表中的匹配字符串。
将mode插入到scope tokens的开头。
将mode添加到hint tokens中。
令IDL value为mode、一个U+0020空格字符和之前IDL value值的串联。
如果tokens中的第index个条目是第一个条目,则跳到标有完成的步骤。
将index减一。
如果tokens中的第index个条目不是第一个条目,则跳到标有默认的步骤。
如果tokens中的第index个标记的前八个字符不是section-
字符串的ASCII大小写不敏感匹配ASCII大小写不敏感,则跳到标有默认的步骤。
令section为tokens中的第index个标记,转换为ASCII小写。
将section插入到scope tokens的开头。
令IDL value为section、一个U+0020空格字符和之前IDL value值的串联。
完成:令元素的自动填充提示集为hint tokens。
令元素的非自动填充凭证类型为credential type。
令元素的自动填充范围为scope tokens。
令元素的自动填充字段名为field。
令元素的IDL暴露的自动填充值为IDL value。
返回。
默认:令元素的IDL暴露的自动填充值为空字符串,其自动填充提示集和自动填充范围为空。
如果元素的autocomplete
属性穿着自动填充锚披风,则令元素的自动填充字段名为空字符串并返回。
令form为元素的表单拥有者,如果有的话,否则为null。
如果form不为null且form的autocomplete
属性处于off状态,则令元素的自动填充字段名为"off
"。
要确定字段的类别,给定field:
如果field不是ASCII大小写不敏感匹配下表第一列中的某个标记,则返回(null, null)。
标记 | 最大标记数 | 类别 |
---|---|---|
"off "
|
1 | Off |
"on "
|
1 | Automatic |
"name "
|
3 | Normal |
"honorific-prefix "
|
3 | Normal |
"given-name "
|
3 | Normal |
"additional-name "
|
3 | Normal |
"family-name "
|
3 | Normal |
"honorific-suffix "
|
3 | Normal |
"nickname "
|
3 | Normal |
"organization-title "
|
3 | Normal |
"username "
|
3 | Normal |
"new-password "
|
3 | Normal |
"current-password "
|
3 | Normal |
"one-time-code "
|
3 | Normal |
"organization "
|
3 | Normal |
"street-address "
|
3 | Normal |
"address-line1 "
|
3 | Normal |
"address-line2 "
|
3 | Normal |
"address-line3 "
|
3 | Normal |
"address-level4 "
|
3 | Normal |
"address-level3 "
|
3 | Normal |
"address-level2 "
|
3 | Normal |
"address-level1 "
|
3 | Normal |
"country "
|
3 | Normal |
"country-name "
|
3 | Normal |
"postal-code "
|
3 | Normal |
"cc-name "
|
3 | Normal |
"cc-given-name "
|
3 | Normal |
"cc-additional-name "
|
3 | Normal |
"cc-family-name "
|
3 | Normal |
"cc-number "
|
3 | Normal |
"cc-exp "
|
3 | Normal |
"cc-exp-month "
|
3 | Normal |
"cc-exp-year "
|
3 | Normal |
"cc-csc "
|
3 | Normal |
"cc-type "
|
3 | Normal |
"transaction-currency "
|
3 | Normal |
"transaction-amount "
|
3 | Normal |
"language "
|
3 | Normal |
"bday "
|
3 | Normal |
"bday-day "
|
3 | Normal |
"bday-month "
|
3 | Normal |
"bday-year "
|
3 | Normal |
"sex "
|
3 | Normal |
"url "
|
3 | Normal |
"photo "
|
3 | Normal |
"tel "
|
4 | Contact |
"tel-country-code "
|
4 | Contact |
"tel-national "
|
4 | Contact |
"tel-area-code "
|
4 | Contact |
"tel-local "
|
4 | Contact |
"tel-local-prefix "
|
4 | Contact |
"tel-local-suffix "
|
4 | Contact |
"tel-extension "
|
4 | Contact |
"email "
|
4 | Contact |
"impp "
|
4 | Contact |
"webauthn "
|
5 | Credential |
否则,将maximum tokens和category设为该行第二列和第三列中的值。
返回category和maximum tokens这对值。
对于自动填充的目的,控件的数据取决于控件的种类:
input
元素,其type
属性处于Email状态且指定了multiple
属性
input
元素
textarea
元素
select
元素,且其multiple
属性被指定
select
元素的选项列表中,其option
元素的选中状态设为true。
select
元素
select
元素的选项列表中,其option
元素的选中状态设为true。
如何处理自动填充提示集、自动填充范围和自动填充字段名称取决于autocomplete
属性的状态。
当一个元素的自动填充字段名称为"off
"时,用户代理不应记住该控件的数据,并且不应向用户提供过去的值。
此外,当一个元素的自动填充字段名称为"off
"时,在重新激活文档时值会被重置。
例如,银行经常不希望用户代理预填登录信息:
< p >< label > Account: < input type = "text" name = "ac" autocomplete = "off" ></ label ></ p >
< p >< label > PIN: < input type = "password" name = "pin" autocomplete = "off" ></ label ></ p >
当一个元素的自动填充字段名称不是"off
"时,用户代理可以存储该控件的数据,并可以向用户提供之前存储的值。
例如,假设用户访问了一个包含以下控件的页面:
< select name = "country" >
< option > Afghanistan
< option > Albania
< option > Algeria
< option > Andorra
< option > Angola
< option > Antigua and Barbuda
< option > Argentina
< option > Armenia
<!-- ... -->
< option > Yemen
< option > Zambia
< option > Zimbabwe
</ select >
可能呈现如下:
假设用户在第一次访问该页面时选择了"Zambia"。在第二次访问时,用户代理可以将Zambia的条目复制到列表顶部,使界面看起来如下:
当自动填充字段名称为"on
"时,用户代理应尝试使用启发式方法确定最适合提供给用户的值,例如基于元素的name
值、元素在其树中的位置、表单中存在的其他字段等。
当自动填充字段名称是上述表格中描述的自动填充字段名称之一时,用户代理应提供与字段名称含义匹配的建议,如本节前面表格中所述。自动填充提示集应用于从多个可能的建议中进行选择。
例如,如果用户曾经在使用"shipping
"关键字的字段中输入一个地址,而在使用"billing
"关键字的字段中输入另一个地址,则在随后的表单中,只有第一个地址会被建议用于自动填充提示集包含"shipping
"关键字的表单控件。然而,对于自动填充提示集不包含任何一个关键字的地址相关表单控件,可能会建议这两个地址。
当自动填充字段名称不是空字符串时,用户代理必须如同用户指定了给定的控件数据一样行事,结合自动填充提示集、自动填充范围和自动填充字段名称。
当用户代理自动填充表单控件时,具有相同表单所有者和相同自动填充范围的元素必须使用相同的个人、地址、支付工具和联系信息数据。当用户代理自动填充具有相同表单所有者和自动填充范围的"国家
"和"国家名称
"字段时,如果用户代理有国家
字段的值,则必须使用相同国家的人类可读名称填充"国家名称
"字段。当用户代理一次填充多个字段时,所有具有相同自动填充字段名称、表单所有者和自动填充范围的字段必须填充相同的值。
假设用户代理知道两个电话号码,+1 555 123 1234和+1 555 666
7777。用户代理不能将"autocomplete="shipping tel-local-prefix"
"字段预填为"123",而在同一表单中的另一个字段中预填"autocomplete="shipping tel-local-suffix"
"字段的值为"7777"。给定上述信息,唯一有效的预填值分别是"123"和"1234",或"666"和"7777"。
同样地,如果一个表单包含"cc-exp
"字段和"cc-exp-month
"字段,且用户代理预填了该表单,则前者的月份组件必须与后者匹配。
这一要求也与自动填充锚定状态相关。考虑以下标记片段:
< form >
< input type = hidden autocomplete = "nickname" value = "TreePlate" >
< input type = text autocomplete = "nickname" >
</ form >
唯一一个合规的用户代理可以在文本控件中建议的值是隐藏的input
元素给出的"TreePlate"值。
"section-*
"标记在自动填充范围中是不可解释的;用户代理不得试图从这些标记的精确值中推导出含义。
例如,如果用户代理决定它应为"section-child
"提供它所知道的用户女儿的地址,而为"section-spouse
"提供它所知道的用户配偶的地址,则这将不符合要求。
自动填充机制必须由用户代理执行,仿佛用户修改了控件的数据,并且必须在元素可变时进行(例如,在元素刚插入文档后,或在用户代理停止解析时)。用户代理必须仅使用用户可能输入的值预填控件。
例如,如果select
元素只有option
元素的值为"Steve"、"Rebecca"、"Jay"和"Bob",并且具有自动填充字段名称"given-name
",但用户代理唯一想要预填的值是"Evan",则用户代理不能预填该字段。将select
元素的值设置为"Evan"将不符合要求,因为用户无法自己完成此操作。
用户代理预填表单控件时不得区分在文档树中和已连接的表单控件;即,不合规的行为是根据元素的根是阴影根还是文档
来决定是否自动填充。
用户代理预填表单控件的值时,不得导致该控件类型不匹配、过长、过短、下溢、上溢或步长不匹配。用户代理预填表单控件的值时,也不得导致该控件模式不匹配。在给定控件约束条件的情况下,用户代理必须使用上述表格中给出的规范格式。若无法使用规范格式,用户代理应使用启发式方法尝试转换值以便使用。
例如,如果用户代理知道用户的中间名是"Ines",并尝试预填一个类似于此的表单控件:
< input name = middle-initial maxlength
= 1 autocomplete = "additional-name" >
...则用户代理可以将"Ines"转换为"I"并以这种方式预填。
一个更复杂的例子是月份值。如果用户代理知道用户的生日是2012年7月27日,则可能会尝试以稍微不同的值预填以下控件,这些值都源自该信息:
|
2012-07 | 月份状态只接受月份/年份组合,丢弃了日期。(注意此示例不合规,因为bday 自动填充字段名称不允许使用月份状态。)
|
|
July | 用户代理从列表选项中选择月份,或通过注意到有十二个选项并选择第七个,或通过识别某个字符串(如"Jul"三个字符后跟换行符和空格)与月份名称(July)在用户代理支持的某种语言中的名称接近,或通过其他类似机制。 |
|
7 | 用户代理将"July"转换为范围1..12内的月份数字,如字段。 |
|
6 | 用户代理将"July"转换为范围0..11内的月份数字,如字段。 |
|
用户代理不填充该字段,因为无法很好地猜测表单期望的内容。 |
用户代理可以允许用户覆盖元素的自动填充字段名称,例如将其从"off
"改为"on
",以允许记住和预填值,尽管页面作者反对,或始终为"off
",永远不记住值。
更具体地说,用户代理可能特别考虑替换与下表第一列中描述的表单控件匹配的元素的自动填充字段名称,当其自动填充字段名称为"on
"或"off
"时,用该行第二个单元格中给出的值进行替换。如果使用此表格,则替换必须按树顺序进行,因为除了第一行之外,所有行都引用前面元素的自动填充字段名称。当描述提到表单控件被其他控件前后相随时,意味着在共享相同表单所有者的列出元素列表中。
表单控件 | 新的自动填充字段名称 |
---|---|
一个input 元素,其type 属性处于文本状态,后面跟随一个input 元素,其type 属性处于密码状态 |
"username "
|
一个input 元素,其type 属性处于密码状态,前面跟随一个input 元素,其自动填充字段名称为"username "
|
"current-password "
|
一个input 元素,其type 属性处于密码状态,前面跟随一个input 元素,其自动填充字段名称为"current-password "
|
"new-password "
|
一个input 元素,其type 属性处于密码状态,前面跟随一个input 元素,其自动填充字段名称为"new-password "
|
"new-password "
|
当获取autocomplete
IDL属性时,必须返回元素的IDL暴露的自动填充值,并在设置时,必须反映
同名内容属性。
input
和 textarea
元素定义了处理其选择的若干属性和方法。它们的共享算法在此定义。
element.select()
选择文本控件中的所有内容。
element.selectionStart [ = value ]
返回选择的起始偏移。
可以设置,以改变选择的起始位置。
element.selectionEnd [ = value ]
返回选择的结束偏移。
可以设置,以改变选择的结束位置。
element.selectionDirection [ = value ]
返回选择的当前方向。
可以设置,以改变选择的方向。
可能的值是 "forward
", "backward
" 和 "none
"。
element.setSelectionRange(start, end [, direction])
HTMLInputElement/setSelectionRange
支持所有当前引擎。
更改选择以覆盖给定方向的子字符串。如果省略方向,将重置为平台默认值(none 或 forward)。
element.setRangeText(replacement [, start, end [, selectionMode ] ])
支持所有当前引擎。
用新文本替换一段文本。如果没有提供 start 和 end 参数,则假定范围为选择内容。
最后一个参数确定替换文本后如何设置选择。可能的值是:
select
"
start
"
end
"
preserve
"
所有 input
元素和
所有 textarea
元素,无论是否 被渲染,始终具有 选择 或 文本输入光标位置,以控件的 相关值 的偏移量来衡量。初始状态必须由控件开头的 文本输入光标 组成。
对于 input
元素,这些 API 必须对元素的 值
进行操作。对于 textarea
元素,这些 API 必须对元素的 API 值
进行操作。在下面的算法中,我们将操作的值字符串称为 相关值。
< textarea id = "demo" ></ textarea >
< script >
demo. value = "A\r\nB" ;
demo. setRangeText( "replaced" , 0 , 2 );
assert( demo. value === "replacedB" );
</ script >
如果我们对 "A\r\nB
" 的 原始值 进行操作,我们会替换 "A\r
" 字符,结果变成
"replaced\nB
"。但由于我们使用了 "A\nB
" 的 API 值,我们替换了 "A\n
" 字符,得到
"replacedB
"。
无可见渲染的字符(如 U+200D ZERO WIDTH JOINER)仍然算作字符。因此,例如,选择可以仅包含一个不可见字符,文本插入光标可以放置在该字符的任一侧。
每当这些 API 适用的元素的 相关值 发生变化时,运行以下步骤:
如果元素有 选择:
在某些情况下,当 相关值 发生变化时,规范的其他部分也会修改 文本输入光标位置,不仅仅是上述的夹紧步骤。例如,参见 value
设置器 textarea
。
尽可能使用 设置选择范围 算法来实现 input
和
textarea
元素中更改 文本选择
的用户界面功能,以便所有相同的事件都能触发。
input
和
textarea
元素的 选择 具有
选择方向,即
"forward
", "backward
" 或 "none
"。选择方向的确切含义取决于平台。此方向在用户操作选择时设置。初始 选择方向 必须是
"none
"(如果平台支持该方向),否则为 "forward
"。
要将元素的选择方向设置为给定方向,请更新元素的 选择方向
为给定方向;如果方向是 "none
" 且平台不支持该方向,则将元素的 选择方向 更新为
"forward
"。
在 Windows 上,方向表示插入点相对于选择的位置:"forward
" 选择在选择末尾有插入点,而 "backward
" 选择在选择开始处有插入点。Windows 没有
"none
" 方向。
在 Mac 上,方向表示在用户使用 Shift
修饰键调整选择大小时,选择的哪一端受到影响:“forward
”方向表示选择的末端被修改,而“backward
”方向表示选择的起始端被修改。"none
"
方向是 Mac 的默认方向,它表示尚未选择特定方向。用户在首次调整选择时,基于使用的方向键隐式地设置方向。
支持所有当前引擎。
select()
方法调用时,必须执行以下步骤:
如果此元素是 input
元素,并且 select()
不适用
于此元素,或对应的控件没有可选择的文本,则返回。
例如,在某些用户代理中,<input type=color>
作为颜色选择器而不是接受十六进制颜色代码的文本控件呈现时,将没有可选择的文本,因此忽略对方法的调用。
设置选择范围 为 0 和无限大。
selectionStart
属性的 getter 必须执行以下步骤:
如果此元素是 input
元素,并且 selectionStart
不适用 于此元素,则返回 null。
selectionStart
属性的 setter 必须执行以下步骤:
如果此元素是 input
元素,并且 selectionStart
不适用 于此元素,则抛出 "InvalidStateError
" DOMException
。
让 end 为此元素的 selectionEnd
属性的值。
如果 end 小于给定值,则将 end 设置为给定值。
设置选择范围
为给定值、end 和此元素的 selectionDirection
属性的值。
selectionEnd
属性的 getter 必须执行以下步骤:
如果此元素是 input
元素,并且 selectionEnd
不适用 于此元素,则返回 null。
selectionEnd
属性的 setter 必须执行以下步骤:
如果此元素是 input
元素,并且 selectionEnd
不适用 于此元素,则抛出 "InvalidStateError
" DOMException
。
设置选择范围 为此元素的 selectionStart
属性的值、给定值和此元素的 selectionDirection
属性的值。
selectionDirection
属性的 getter 必须执行以下步骤:
如果此元素是 input
元素,并且 selectionDirection
不适用 于此元素,则返回 null。
返回此元素的 选择方向。
selectionDirection
属性的 setter 必须执行以下步骤:
如果此元素是 input
元素,并且 selectionDirection
不适用 于此元素,则抛出 "InvalidStateError
" DOMException
。
设置选择范围 为此元素的 selectionStart
属性的值、此元素的 selectionEnd
属性的值和给定值。
setSelectionRange(start, end, direction)
方法调用时,必须执行以下步骤:
如果此元素是 input
元素,并且 setSelectionRange()
不适用 于此元素,则抛出 "InvalidStateError
" DOMException
。
设置选择范围 为 start、end 和 direction。
要用整数或 null start、整数或 null 或特殊值 infinity end 和可选字符串 direction 设置选择范围,运行以下步骤:
如果 start 为 null,则将 start 设为 0。
如果 end 为 null,则将 end 设为 0。
将文本控件的 选择 设置为 代码单元 序列,开始于 start 位置的代码单元,并结束于 (end-1) 位置的代码单元。大于文本控件 长度 的参数(包括特殊值 infinity)必须视为指向文本控件的末尾。如果 end 小于或等于 start,则选择的开始和结束都必须放置在 end 偏移字符之前。在没有空选择概念的用户代理中,这必须将光标设置在 end 偏移字符之前。
如果 direction 不 相同 于
"backward
" 或 "forward
",或如果没有给出 direction 参数,则将 direction 设为
"none
"。
设置文本控件的选择方向 为 direction。
如果前面的步骤导致修改了文本控件的 选择(无论是范围还是 方向),则 队列元素任务
给定元素,触发名为 select
的事件,并将
bubbles
属性初始化为 true。
setRangeText(replacement, start, end, selectMode)
方法调用时,必须执行以下步骤:
如果此元素是 input
元素,并且 setRangeText()
不适用 于此元素,则抛出 "InvalidStateError
" DOMException
。
将此元素的 脏值标志 设置为 true。
如果方法只有一个参数,则让 start 和 end 具有 selectionStart
属性和 selectionEnd
属性的值。
否则,让 start 和 end 具有第二个和第三个参数的值。
如果 start 大于 end,则抛出 "IndexSizeError
" DOMException
。
让 selection start 为 selectionStart
属性的当前值。
让 selection end 为 selectionEnd
属性的当前值。
如果 start 小于 end,则删除元素 代码单元 的序列,从 start 位置开始,到 (end-1) 位置结束。
让 new length 为第一个参数值的 长度。
让 new end 为 start 和 new length 的和。
运行以下步骤列表中的适当子步骤:
select
"让 selection start 为 start。
让 selection end 为 new end。
start
"让 selection start 和 selection end 为 start。
end
"让 selection start 和 selection end 为 new end。
preserve
"让 old length 为 end 减去 start。
让 delta 为 new length 减去 old length。
如果 selection start 大于 end,则将其增加 delta。 (如果 delta 为负,即新文本比旧文本短,则这将 减少 selection start 的值。)
否则:如果 selection start 大于 start,则将其设置为 start。 (如果选择的开始在替换的文本中间,则将选择的开始对齐到新文本的开始。)
如果 selection end 大于 end,则以同样的方式增加 delta。
否则:如果 selection end 大于 start,则将其设置为 new end。 (如果选择的结束在替换的文本中间,则将选择的结束对齐到新文本的结束。)
设置选择范围 为 selection start 和 selection end。
setRangeText()
方法使用以下枚举:
enum SelectionMode {
" select " ,
" start " ,
" end " ,
" preserve " // default
};
要获取当前选定的文本,只需以下 JavaScript 代码:
var selectionText = control. value. substring( control. selectionStart, control. selectionEnd);
要在文本控件的开头添加一些文本,同时保持文本选择,必须保留这三个属性:
var oldStart = control. selectionStart;
var oldEnd = control. selectionEnd;
var oldDirection = control. selectionDirection;
var prefix = "http://" ;
control. value = prefix + control. value;
control. setSelectionRange( oldStart + prefix. length, oldEnd + prefix. length, oldDirection);
可提交元素 是 约束验证候选者,除非某个条件将其 排除在约束验证之外。(例如,如果某个元素具有 datalist
元素祖先,则该元素 被排除在约束验证之外。)
元素可以定义 自定义有效性错误消息。最初,元素的 自定义有效性错误消息 必须设置为空字符串。当其值不是空字符串时,元素 存在自定义错误。可以使用 setCustomValidity()
方法设置,除了 表单关联自定义元素。表单关联自定义元素 可以通过其 ElementInternals
对象的 setValidity()
方法设置 自定义有效性错误消息。当向用户提示控件问题时,用户代理应使用 自定义有效性错误消息。
元素可以有各种约束方式。以下是表单控件可能处于的 有效性状态 列表,使控件在约束验证中无效。(以下定义是非规范性的;本规范的其他部分更精确地定义了每个状态适用或不适用的情况。)
当控件没有 值 但具有
required
属性时(input
required
,textarea
required
);或
select
元素和 单选按钮组
控件的更复杂规则,如其部分中所述。
当 setValidity()
方法将 valueMissing
标志设置为 true 用于 表单关联自定义元素 时。
当允许任意用户输入的控件的 值 语法不正确时(电子邮件,URL)。
当 setValidity()
方法将 typeMismatch
标志设置为 true 用于 表单关联自定义元素 时。
当 setValidity()
方法将 patternMismatch
标志设置为 true 用于 表单关联自定义元素 时。
当控件的 值 对于 表单控件 maxlength
属性 来说太长时(input
maxlength
,textarea
maxlength
)。
当 setValidity()
方法将 tooLong
标志设置为 true 用于 表单关联自定义元素 时。
当控件的 值 对于 表单控件 minlength
属性 来说太短时(input
minlength
,textarea
minlength
)。
当 setValidity()
方法将 tooShort
标志设置为 true 用于 表单关联自定义元素 时。
当 setValidity()
方法将 rangeUnderflow
标志设置为 true 用于 表单关联自定义元素 时。
当 setValidity()
方法将 rangeOverflow
标志设置为 true 用于 表单关联自定义元素 时。
当setValidity()
方法为表单关联的自定义元素设置stepMismatch
标志为true时。
当控件输入不完整且用户代理认为用户不应在当前状态下提交表单时。
当 setValidity()
方法将 badInput
标志设置为 true 用于 表单关联自定义元素 时。
当控件的 自定义有效性错误消息(由元素的 setCustomValidity()
方法或 ElementInternals
的 setValidity()
方法设置)不是空字符串时。
即使元素 禁用,元素仍可能存在这些状态;因此,即使在提交期间验证表单时不会向用户显示问题,这些状态也可以在 DOM 中表示。
如果元素不存在上述任何 有效性状态,则元素 满足其约束条件。
当用户代理需要对
静态验证约束
进行
form
元素 form 时,
必须执行以下步骤,这些步骤将返回
肯定 结果(表单中的所有控件都有效)或 否定
结果(存在无效控件),以及一个(可能为空的)无效元素列表,并且这些元素没有脚本声明其责任:
让invalid controls成为一个初始为空的元素列表。
对controls中的每个元素field,按树顺序:
如果 invalid controls 为空,则返回 肯定 结果。
让unhandled invalid controls成为一个初始为空的元素列表。
对invalid controls中的每个元素field,按树顺序:
让notCanceled成为在field上触发一个事件(名为invalid
),cancelable
属性初始化为true。
如果notCanceled为true,则将field添加到unhandled invalid controls。
返回 否定 结果,并附带 unhandled invalid controls 列表中的元素。
如果用户代理要交互验证表单
元素form的约束,则用户代理必须运行以下步骤:
静态验证form的约束,如果结果为负面,则让unhandled invalid controls成为返回的元素列表。
如果结果为正面,则返回该结果。
向用户报告unhandled invalid controls中至少一个元素的约束问题。
返回负面结果。
element.willValidate
HTMLObjectElement/willValidate
在所有当前引擎中都受支持。
如果元素在表单提交时会被验证,则返回 true;否则返回 false。
element.setCustomValidity(message)
HTMLObjectElement/setCustomValidity
在所有当前引擎中都受支持。
HTMLSelectElement/setCustomValidity
在所有当前引擎中都受支持。
设置一个自定义错误,使元素无法通过验证。给定的消息是报告问题时显示给用户的消息。
如果参数是空字符串,则清除自定义错误。
element.validity.valueMissing
在所有当前引擎中都受支持。
如果元素没有值但这是一个必需字段,则返回 true;否则返回 false。
element.validity.typeMismatch
如果元素的值不符合正确的语法,则返回 true;否则返回 false。
element.validity.patternMismatch
如果元素的值不匹配提供的模式,则返回 true;否则返回 false。
element.validity.tooLong
在所有当前引擎中都受支持。
如果元素的值超过了提供的最大长度,则返回 true;否则返回 false。
element.validity.tooShort
在所有当前引擎中都受支持。
如果元素的值(如果不是空字符串)短于提供的最小长度,则返回 true;否则返回 false。
element.validity.rangeUnderflow
如果元素的值低于提供的最小值,则返回 true;否则返回 false。
element.validity.rangeOverflow
如果元素的值高于提供的最大值,则返回 true;否则返回 false。
element.validity.stepMismatch
如果元素的值不符合 step
属性规定的规则,则返回 true;否则返回 false。
element.validity.badInput
所有当前引擎均支持。
如果用户在用户界面中提供的输入,用户代理无法转换为值,则返回 true;否则返回 false。
element.validity.customError
如果元素有自定义错误,则返回 true;否则返回 false。
element.validity.valid
如果元素的值没有有效性问题,则返回 true;否则返回 false。
valid = element.checkValidity()
HTMLInputElement/checkValidity
所有当前引擎均支持。
HTMLObjectElement/checkValidity
所有当前引擎均支持。
HTMLSelectElement/checkValidity
所有当前引擎均支持。
如果元素的值没有有效性问题,则返回 true;否则返回 false。在后一种情况下,会在元素上触发一个 invalid
事件。
valid = element.reportValidity()
HTMLFormElement/reportValidity
所有当前引擎均支持。
HTMLInputElement/reportValidity
所有当前引擎均支持。
如果元素的值没有有效性问题,则返回 true;否则返回 false,触发一个 invalid
事件,并且(如果事件没有被取消)将问题报告给用户。
element.validationMessage
HTMLObjectElement/validationMessage
所有当前引擎均支持。
返回如果检查元素的有效性时显示给用户的错误消息。
willValidate
属性的 getter 必须在以下情况下返回 true:如果该元素是一个 约束验证的候选,否则返回 false(即,如果有任何条件 阻止它进行约束验证)。
所有当前引擎均支持。
willValidate
属性在 ElementInternals
接口上获取时,如果 目标元素 不是一个 与表单关联的自定义元素,则必须抛出一个 "NotSupportedError
" DOMException
。否则,如果
目标元素 是一个
约束验证的候选,则必须返回 true,否则返回 false。
HTMLInputElement/setCustomValidity
所有当前引擎均支持。
setCustomValidity(error)
方法的步骤是:
将 error 设置为对 规范化换行符 后的 error 结果。
将 自定义有效性错误消息 设置为 error。
在以下示例中,每次编辑表单控件的值时,脚本都会检查该值,并在值无效时使用 setCustomValidity()
方法设置适当的消息。
< label > Feeling: < input name = f type = "text" oninput = "check(this)" ></ label >
< script >
function check( input) {
if ( input. value == "good" ||
input. value == "fine" ||
input. value == "tired" ) {
input. setCustomValidity( '"' + input. value + '" is not a feeling.' );
} else {
// input is fine -- reset the error message
input. setCustomValidity( '' );
}
}
</ script >
所有当前引擎均支持。
validity
属性的 getter 必须返回一个
ValidityState
对象,表示此元素的 有效性状态。该对象是 实时 的。
所有当前引擎均支持。
validity
属性的
ElementInternals
接口,在获取时,如果 目标元素 不是 与表单关联的自定义元素,必须抛出
"NotSupportedError
" DOMException
。否则,它必须返回一个
ValidityState
对象,表示 有效性状态。该对象是 实时 的。
[Exposed =Window ]
interface ValidityState {
readonly attribute boolean valueMissing ;
readonly attribute boolean typeMismatch ;
readonly attribute boolean patternMismatch ;
readonly attribute boolean tooLong ;
readonly attribute boolean tooShort ;
readonly attribute boolean rangeUnderflow ;
readonly attribute boolean rangeOverflow ;
readonly attribute boolean stepMismatch ;
readonly attribute boolean badInput ;
readonly attribute boolean customError ;
readonly attribute boolean valid ;
};
ValidityState
对象具有以下属性。获取时,如果下列条件对应的条件为真,则返回 true,否则返回 false。
valueMissing
控件 处于缺失状态。
typeMismatch
所有当前引擎均支持。
控制项 存在类型不匹配。
patternMismatch
所有当前引擎均支持。
控制项 存在模式不匹配。
tooLong
控制项 存在过长的问题。
tooShort
控制项 存在过短的问题。
rangeUnderflow
所有当前引擎均支持。
控制项 存在下溢的问题。
rangeOverflow
所有当前引擎均支持。
控制项 存在上溢的问题。
stepMismatch
所有当前引擎均支持。
控制项 存在步长不匹配的问题。
badInput
控制项 存在错误输入的问题。
customError
控制项 存在自定义错误。
valid
其他条件均不成立。
检查有效性步骤 对于元素 element 的步骤如下:
如果 element 是 约束验证候选 且不满足 其约束,则:
触发一个事件 名为
invalid
在 element 上,带有 cancelable
属性初始化为 true(尽管取消没有效果)。
返回 false。
返回 true。
checkValidity()
方法在调用时,必须在该元素上运行 检查有效性步骤。
ElementInternals/checkValidity
所有当前引擎均支持。
checkValidity()
方法必须运行以下步骤:
让 element 成为此 ElementInternals
的 目标元素。
如果 element 不是 与表单关联的自定义元素,则抛出 "NotSupportedError
" DOMException
。
在 element 上运行 检查有效性步骤。
报告有效性步骤 对于元素 element 的步骤如下:
如果 element 是 约束验证候选 且不满足 其约束,则:
让 report 成为 触发一个事件
的结果,事件名称为 invalid
在 element 上,带有 cancelable
属性初始化为 true。
如果 report 为 true,则将此元素的约束问题报告给用户。在将约束问题报告给用户时,用户代理可以为 element 运行聚焦步骤,并且可以更改文档的滚动位置,或执行其他操作以引起用户对 element 的注意。如果 element 同时存在多个问题,用户代理可以报告多个约束违规。
返回 false。
返回 true。
reportValidity()
方法在调用时,必须在该元素上运行
报告有效性步骤。
ElementInternals/reportValidity
所有当前引擎均支持。
reportValidity()
方法必须运行以下步骤:
让 element 成为此 ElementInternals
的 目标元素。
如果 element 不是 与表单关联的自定义元素,则抛出 "NotSupportedError
" DOMException
。
在 element 上运行 报告有效性步骤。
validationMessage
属性的 getter 必须运行以下步骤:
返回一个合适的本地化消息,该消息会在此是唯一具有有效性约束问题的表单控件时显示给用户。如果在这种情况下用户代理实际上不会显示文本消息(例如,它会显示图形提示),则返回一个合适的本地化消息,表达控件未满足的有效性约束。如果该元素是 约束验证候选 并且 存在自定义错误,则返回值中应包含 自定义有效性错误消息。
服务器不应依赖客户端验证。恶意用户可以有意绕过客户端验证,使用旧版用户代理或不实现这些功能的自动化工具的用户也可能无意中绕过客户端验证。约束验证功能仅旨在改善用户体验,而不是提供任何形式的安全机制。
本节非规范性。
当表单提交时,表单中的数据会转换为 enctype 指定的结构,然后使用给定的 方法 发送到 action 指定的目标。
例如,以下表单:
< form action = "/find.cgi" method = get >
< input type = text name = t >
< input type = search name = q >
< input type = submit >
</ form >
如果用户在第一个字段中输入 "cats",在第二个字段中输入 "fur",然后点击提交按钮,用户代理将加载 /find.cgi?t=cats&q=fur
。
另一方面,考虑这个表单:
< form action = "/find.cgi" method = post enctype = "multipart/form-data" >
< input type = text name = t >
< input type = search name = q >
< input type = submit >
</ form >
给出相同的用户输入,提交时的结果会大不相同:用户代理会对给定的 URL 执行 HTTP POST,其实体主体内容类似如下文本:
------kYFrd4jNJEgCervE Content-Disposition: form-data; name="t" cats ------kYFrd4jNJEgCervE Content-Disposition: form-data; name="q" fur ------kYFrd4jNJEgCervE--
form
元素的 默认按钮 是在 提交按钮 中第一个按 树顺序 排列,其 表单所有者 是该 form
元素。
如果用户代理支持让用户隐式提交表单(例如,在某些平台上,当文本控件 聚焦
时按下 "Enter" 键隐式提交表单),则对于具有 默认按钮 且该按钮具有 激活行为 且未 禁用 的表单,必须导致用户代理在该 默认按钮 上 触发一个 click
事件。
网页上有些页面只有在存在隐式提交表单的方法时才可用,因此强烈建议用户代理支持这一功能。
如果表单没有 提交按钮,则隐式提交机制必须执行以下步骤:
如果表单有多个 阻止隐式提交的字段,则返回。
从 form
元素本身提交 form
元素,userInvolvement 设置为 "activation
"。
为了前段的目的,如果一个元素是一个 阻止隐式提交的字段,那么该元素是一个 form
元素的
input
元素,并且它的 表单拥有者 是该 form
元素,并且其 type
属性处于以下状态之一:
文本,
搜索,
电话,
URL,
电子邮件,
密码,
日期,
月份,
周,
时间,
本地日期和时间,
数字
每个 form
元素有一个 构建条目列表 布尔值,初始为 false。
每个 form
元素有一个 触发提交事件 布尔值,初始为 false。
要从元素 submitter(通常是按钮)提交 form
元素 form,给定一个可选的布尔值 submitted from submit()
method(默认为 false)和一个可选的 用户导航参与度 userInvolvement(默认为 "none
"):
如果 form 不能导航,则返回。
如果 form 的 构建条目列表 为 true,则返回。
让 form document 成为 form 的 节点文档。
如果 form document 的 活动沙箱标志集 设置了其 沙箱表单浏览上下文标志,则返回。
如果 submitted from submit()
方法 为 false,则:
如果 form 的 触发提交事件 为 true,则返回。
将 form 的 触发提交事件 设置为 true。
对于 form 中的每个元素 field,如果该元素是 可提交元素,其 表单所有者 是 form,则将 field 的 用户有效性 设置为 true。
如果 submitter 元素的 无效验证状态 为 false,则 交互式验证约束 form 并检查结果。如果结果是否定的(即约束验证得出有无效字段并且可能通知了用户),则:
将 form 的 触发提交事件 设置为 false。
返回。
如果 submitter 是 form,则将 submitterButton 设为 null。否则,将 submitterButton 设为 submitter。
让 shouldContinue 成为 触发事件 结果,事件名为
submit
在 form 上,使用 SubmitEvent
,submitter
属性初始化为 submitterButton,bubbles
属性初始化为 true,cancelable
属性初始化为 true。
将 form 的 触发提交事件 设置为 false。
如果 shouldContinue 为 false,则返回。
如果 form 不能导航,则返回。
让 encoding 成为 为表单选择编码 的结果。
让 entry list 成为 构建条目列表 的结果,使用 form、submitter 和 encoding。
断言:entry list 不为 null。
如果 form 不能导航,则返回。
让 method 成为 submitter 元素的 方法。
如果 method 是 对话框,则:
让 action 成为 submitter 元素的 动作。
如果 action 是空字符串,则让 action 成为 URL 的 form document。
让 parsed action 成为 编码解析 URL 的结果,给定 action,相对于 submitter 的 节点文档。
如果 parsed action 失败,则返回。
让 scheme 成为 方案 的 parsed action。
让 enctype 成为 submitter 元素的 enctype。
让 formTarget 为 null。
如果 submitter 元素是 提交按钮 且其具有 formtarget
属性,则将 formTarget 设置为 formtarget
属性值。
让 noopener 成为 获取元素的 noopener 的结果,给定 form 和 target。
让 target Navigable 成为应用 选择导航的规则 的第一个返回值,给定 target、form 的 节点导航 和 noopener。
如果 targetNavigable 为 null,则返回。
让 historyHandling 为 "auto
"。
如果 form document 等于 targetNavigable 的 活动文档,且 form document 还没有 完全加载,则将
historyHandling 设置为 "replace
"。
根据 scheme 在下表中选择适当的行。然后根据 method 在该行的第一列中给出的适当单元格选择。然后跳转到该单元格中命名的步骤,并在表下定义。
GET | POST | |
---|---|---|
http |
变更动作 URL | 提交为实体正文 |
https |
变更动作 URL | 提交为实体正文 |
ftp |
获取动作 URL | 获取动作 URL |
javascript |
获取动作 URL | 获取动作 URL |
data |
变更动作 URL | 获取动作 URL |
mailto |
通过邮件发送头部 | 通过邮件发送正文 |
如果 scheme 不在此表中列出,则此规范未定义行为。在没有其他规范定义的情况下,用户代理应模仿此规范为类似方案定义的行为。
每个 form
元素有一个 计划的导航,其值为 null 或 任务;当 form
首次创建时,其 计划的导航 必须设置为
null。在下述行为中,当用户代理需要 计划导航 到 URL url 时,给定一个可选的 POST 资源 或 null
postResource(默认为 null),它必须运行以下步骤:
让 referrerPolicy 为空字符串。
如果 form
元素的 链接类型 包含 noreferrer
关键字,则将 referrerPolicy 设置为 "no-referrer
"。
行为如下:
让 pairs 成为 转换为名称值对列表 的结果,使用 entry list。
让 query 成为运行 application/x-www-form-urlencoded
序列化程序 的结果,使用 pairs 和 encoding。
将 parsed action 的 查询 组件设置为 query。
计划导航 到 parsed action。
根据 enctype 切换:
application/x-www-form-urlencoded
让 pairs 成为 转换为名称值对列表 的结果,使用 entry list。
让 body 成为运行 application/x-www-form-urlencoded
序列化程序 的结果,使用 pairs 和 encoding。
将 body 设置为 编码 body 的结果。
让 mimeType 为 `application/x-www-form-urlencoded
`。
multipart/form-data
让 body 成为运行 multipart/form-data
编码算法 的结果,使用 entry list 和 encoding。
让 mimeType 为 同构编码,其连接了
"multipart/form-data; boundary=
" 和 multipart/form-data
边界字符串,由 multipart/form-data
编码算法 生成。
text/plain
让 pairs 成为 转换为名称值对列表 的结果,使用 entry list。
让 body 成为运行 text/plain
编码算法 的结果,使用
pairs。
将 body 设置为 编码 body 使用 encoding 的结果。
让 mimeType 为 `text/plain
`。
计划导航 到 parsed action,给定 POST 资源,其 请求正文 为 body,请求内容类型 为 mimeType。
计划导航 到 parsed action。
entry list 被丢弃。
让 pairs 成为 转换为名称值对列表 的结果,使用 entry list。
让 headers 成为运行 application/x-www-form-urlencoded
序列化程序 的结果,使用 pairs 和 encoding。
将 headers 中的 U+002B 加号字符(+)替换为字符串 "%20
"。
将 parsed action 的 查询 设置为 headers。
计划导航 到 parsed action。
让 pairs 成为 转换为名称值对列表 的结果,使用 entry list。
根据 enctype 切换:
text/plain
让 body 成为运行 text/plain
编码算法 的结果,使用
pairs。
将 body 设置为运行 UTF-8 百分比编码 的结果,使用 body 和 默认编码集。[URL]
让 body 成为运行 application/x-www-form-urlencoded
序列化程序 的结果,使用 pairs 和 encoding。
如果 parsed action 的 查询 为空,则将其设置为空字符串。
如果 parsed action 的 查询 不是空字符串,则在其后追加一个 U+0026 AMPERSAND 字符(&)。
在 parsed action 的 查询 中追加
"body=
"。
在 parsed action 的 查询 中追加 body。
计划导航 到 parsed action。
一个 条目列表 是一个 列表,通常代表表单的内容。一个 条目 是一个包含一个 名称(一个 标量值字符串)和一个
值(可以是一个 标量值字符串 或一个 文件
对象)的元组。
为了 创建一个条目,给定一个字符串
name,一个字符串或 Blob
对象 value,以及一个可选的 标量值字符串
filename:
将 name 转换为 标量值字符串。
如果 value 是一个字符串,则将 value 转换为 标量值字符串。
否则:
如果 value 不是一个 文件
对象,则将 value 设置为一个新的 文件
对象,代表相同的字节,其 name
属性值为 "blob
"。
如果提供了 filename,则将 value 设置为一个新的 文件
对象,代表相同的字节,其 name
属性为 filename。
这些操作将在提供 filename 或传递的 Blob
不是 文件
对象的情况下创建一个新的 文件
对象。在这些情况下,传递的 Blob
对象的身份不会保留。
为了 构建条目列表,给定一个 form,一个可选的 submitter(默认为 null),和一个可选的 encoding(默认为 UTF-8):
如果 form 的 构建条目列表 为 true,则返回 null。
将 form 的 构建条目列表 设置为 true。
让 entry list 成为一个新的空 条目列表。
对于 controls 中的每个元素 field,按 树顺序:
如果以下任何一项为真:
那么 继续。
如果 field 是一个 表单关联自定义元素,则对 field 和 entry list 执行 条目构建算法,然后 继续。
将 name 设为 field 元素的 name
属性的值。
如果 field 元素是一个 select
元素,则对 field 的每个 option
元素,在 select
元素的 选项列表 中,其 选中状态 为
true 且不是 禁用的,创建一个条目,名称为 name,值为该 option
元素的 值,并将其 追加到 entry list。
否则,如果 field 元素是一个 input
元素,其 type
属性在
状态中,并且 name 是 ASCII 不区分大小写 匹配 "_charset_
":
如果该元素有 dirname
属性,该属性的值不是空字符串,并且该元素是 自动方向表单关联元素:
将 form data 设为一个新的 FormData
对象,关联 entry list。
触发一个名为 formdata
的事件在 form 上,使用 FormDataEvent
,其
formData
属性初始化为 form data,其 bubbles
属性初始化为 true。
将 form 的 构建条目列表 设置为 false。
返回 条目列表 的克隆。
如果用户代理需要为表单选择编码,则必须运行以下步骤:
将 encoding 设置为文档的字符编码。
如果表单
元素有一个accept-charset
属性,则将
encoding 设置为运行以下子步骤的返回值:
将 input 设置为表单
元素的accept-charset
属性的值。
将 candidate encoding labels 设置为按 ASCII 空白字符分割 input 的结果。
将 candidate encodings 设置为空的字符编码列表。
对于 candidate encoding labels 中的每个 token,按顺序获取编码,如果没有失败,则将编码追加到 candidate encodings。
如果 candidate encodings 为空,返回 UTF-8。
返回 candidate encodings 中的第一个编码。
返回获取输出编码从 encoding 的结果。
application/x-www-form-urlencoded
和text/plain
编码算法需要一个名称-值对列表,其中的值必须是字符串,而不是值可以是文件
的条目列表。以下算法执行转换。
要将条目列表转换为名称-值对列表,请运行以下步骤:
将list设置为空的名称-值对列表。
对每个entry的entry list:
返回list。
关于application/x-www-form-urlencoded
的详细信息,请参见URL。[URL]
multipart/form-data
编码算法,给定一个entry list entry list和一个encoding
encoding,如下:
对于每个 entry 在entry list中:
返回使用RFC 7578描述的规则编码entry list得到的字节序列,条件如下:[RFC7578]
部分的顺序必须与entry list中的字段顺序相同。具有相同名称的多个entry必须视为不同的字段。
生成的multipart/form-data
资源中的字段名称、非文件字段的字段值以及文件字段的文件名必须设置为使用encoding编码相应entry的名称或值的结果,转换为字节序列。
对于字段名称和文件字段的文件名,前一个步骤中编码的结果必须通过将任何0x0A (LF)字节替换为字节序列%0A
,0x0D (CR)替换为%0D
,以及0x22
(")替换为%22
来进行转义。用户代理不得执行任何其他转义。
对应非文件字段的生成的multipart/form-data
资源的部分不得指定Content-Type
头。
用户代理在生成此算法的返回值时使用的边界是multipart/form-data
边界字符串。(此值用于生成此算法生成的表单提交有效负载的MIME类型。)
有关如何解释multipart/form-data
有效负载的详细信息,请参见RFC
7578。[RFC7578]
text/plain
编码算法,给定一个名称-值对列表pairs,如下:
令result为空字符串。
对于pairs中的每个pair:
将pair的名称追加到result。
将一个U+003D等号字符(=)追加到result。
将pair的值追加到result。
将一个U+000D回车(CR)和U+000A换行(LF)字符对追加到result。
返回result。
使用text/plain
格式的有效负载旨在易于人类阅读。它们无法可靠地被计算机解释,因为格式存在歧义(例如,没有办法区分值中的换行符与值末尾的换行符)。
SubmitEvent
接口支持所有当前引擎。
支持所有当前引擎。
[Exposed =Window ]
interface SubmitEvent : Event {
constructor (DOMString type , optional SubmitEventInit eventInitDict = {});
readonly attribute HTMLElement ? submitter ;
};
dictionary SubmitEventInit : EventInit {
HTMLElement ? submitter = null ;
};
submitter
属性必须返回它被初始化的值。
FormDataEvent
接口支持所有当前引擎。
支持所有当前引擎。
[Exposed =Window ]
interface FormDataEvent : Event {
constructor (DOMString type , FormDataEventInit eventInitDict );
readonly attribute FormData formData ;
};
dictionary FormDataEventInit : EventInit {
required FormData formData ;
};
formData
属性必须返回它被初始化的值。它表示一个与提交 表单
时 构建 的
条目列表 相关联的 FormData
对象。
当 表单
元素
form 被 重置时,执行以下步骤:
让 reset 成为 触发名为 reset
的事件的结果,在
form 上,bubbles
和 cancelable
属性初始化为 true。
每个 可重置元素 都定义其自己的 重置算法。作为这些算法的一部分对表单控件所做的更改不计为用户所做的更改(例如,不会触发 input
事件)。
details
元素所有当前引擎支持。
所有当前引擎支持。
summary
元素,后跟流内容。name
— 互斥的details
元素组的名称
open
— 详情是否可见
[Exposed =Window ]
interface HTMLDetailsElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString name ;
[CEReactions ] attribute boolean open ;
};
details
元素表示一个披露小部件,用户可以从中获取额外的信息或控件。
与所有 HTML 元素一样,当尝试表示另一种控件时,使用details
元素是不符合规范的。例如,选项卡小部件和菜单小部件不是披露小部件,因此滥用details
元素来实现这些模式是不正确的。
details
元素不适合用于脚注。请参阅脚注部分以了解如何标记脚注。
元素的第一个summary
元素子元素(如果有的话)表示详细信息的摘要或说明。如果没有子summary
元素,用户代理应提供自己的说明(例如“详情”)。
元素其余的内容表示附加信息或控件。
name
内容属性给出了该元素所属的相关details
元素组的名称。打开此组的一个成员会导致其他成员关闭。如果指定了该属性,其值不得为空字符串。
在使用此功能之前,作者应考虑将相关details
元素分组为一个独占手风琴对用户是有帮助还是有害的。虽然使用独占手风琴可以减少一组内容占用的最大空间,但也可能会让用户感到沮丧,因为他们必须打开许多项才能找到自己想要的内容,或者用户希望同时查看多个项的内容。
文档中不得包含多个details
元素在同一个details name
group中具有open
属性。作者不得使用脚本向文档中添加details
元素,以导致details name
group中有多个details
元素具有open
属性。
由公共name
属性创建的元素组是排他的,意味着最多只能有一个details
元素可以打开。虽然这种排他性由用户代理强制执行,但结果立即更改标记中的open
属性。对作者的这种要求禁止了这种误导性的标记。
文档中不得包含details
元素,该元素是同一details name
group中另一个details
元素的后代。
使用name
属性将多个相关details
元素分组的文档应将这些相关元素放在一个包含元素(如section
元素或article
元素)中。当使用标题介绍该组时,作者应将该标题放在包含元素的开头的heading元素中。
将相关元素在视觉上和编程上分组在一起对于可访问的用户体验可能非常重要。这可以帮助用户理解这些元素之间的关系。当相关元素位于网页的不同部分而不是分组时,这些元素之间的关系可能不太容易发现或理解。
open
内容属性是一个布尔属性。如果存在,则表示摘要和附加信息都要显示给用户。如果属性不存在,则只显示摘要。
当创建元素时,如果属性不存在,则附加信息应隐藏;如果属性存在,则信息应显示。随后,如果删除属性,则信息应隐藏;如果添加属性,则信息应显示。
用户代理应允许用户请求显示或隐藏附加信息。为了响应请求显示详细信息,用户代理必须将open
属性设置为空字符串。为了响应请求隐藏信息,用户代理必须从元素中移除open
属性。
请求显示或隐藏附加信息的能力可能只是适当的summary
元素的激活行为,但如果没有这样的元素,用户代理仍可以通过其他用户界面方式提供此能力。
details name group包含一个details
元素a,还包含所有其他details
元素b,它们满足以下所有条件:
每个details
元素都有一个details toggle task tracker,它是一个toggle task
tracker或 null,初始值为 null。
以下属性更改步骤,给定element、localName、oldValue、value和namespace,适用于所有details
元素:
details
HTML元素插入步骤,给定insertedNode,是:
给定insertedNode确保详细信息的排他性。
需要明确的是,这些属性更改和插入步骤也会在通过解析器插入属性或元素时运行。
为了给定一个details
元素element、一个字符串oldState和一个字符串newState排队一个详细信息切换事件任务:
如果element的详细信息切换任务跟踪器不为 null,则:
将oldState设置为element的详细信息切换任务跟踪器的旧状态。
从其任务队列中移除element的详细信息切换任务跟踪器的任务。
将element的详细信息切换任务跟踪器设置为 null。
给定 DOM 操作任务源和element排队一个元素任务以运行以下步骤:
在element上触发一个名为toggle
的事件,使用ToggleEvent
,oldState
属性初始化为oldState,newState
属性初始化为newState。
将element的详细信息切换任务跟踪器设置为 null。
将element的详细信息切换任务跟踪器设置为包含刚排队任务的结构,旧状态设置为oldState。
为了给定一个details
元素element确保详细信息的排他性:
设 groupMembers 为元素列表,包含 element 的详情名称组中的所有元素,除了 element 本身,按照树顺序排列。
对于 groupMembers 中的每个元素 otherElement:
为了确保详情的排他性,必要时通过关闭给定元素来实现,给定一个
details
元素
element:
如果 element 没有 open
属性,则返回。
设 groupMembers 为元素列表,包含 element 的详情名称组中的所有元素,除了 element 本身,按照树顺序排列。
对于 groupMembers 中的每个元素 otherElement:
所有当前引擎支持。
name
和open
IDL属性必须反映相应的同名内容属性。
祖先详细信息揭示算法是对currentNode运行以下步骤:
当currentNode在平坦树中有父节点时:
以下示例展示了details
元素用于在进度报告中隐藏技术细节。
< section class = "progress window" >
< h1 > Copying "Really Achieving Your Childhood Dreams"</ h1 >
< details >
< summary > Copying... < progress max = "375505392" value = "97543282" ></ progress > 25%</ summary >
< dl >
< dt > Transfer rate:</ dt > < dd > 452KB/s</ dd >
< dt > Local filename:</ dt > < dd > /home/rpausch/raycd.m4v</ dd >
< dt > Remote filename:</ dt > < dd > /var/www/lectures/raycd.m4v</ dd >
< dt > Duration:</ dt > < dd > 01:16:27</ dd >
< dt > Color profile:</ dt > < dd > SD (6-1-6)</ dd >
< dt > Dimensions:</ dt > < dd > 320×240</ dd >
</ dl >
</ details >
</ section >
以下示例展示了details
元素如何用于默认隐藏一些控件:
< details >
< summary >< label for = fn > Name & Extension:</ label ></ summary >
< p >< input type = text id = fn name = fn value = "Pillar Magazine.pdf" >
< p >< label >< input type = checkbox name = ext checked > Hide extension</ label >
</ details >
可以将此与列表中的其他details
一起使用,允许用户将一组字段折叠成一小组标题,并有能力打开每个字段。
在这些示例中,摘要实际上只是总结了控件可以更改的内容,而不是实际的值,这不是很理想。
以下示例展示了name
属性用于创建一个独占手风琴,即一组details
元素,其中用户操作打开一个details
元素会导致任何打开的details
元素关闭。
< section class = "characteristics" >
< details name = "frame-characteristics" >
< summary > Material</ summary >
The picture frame is made of solid oak wood.
</ details >
< details name = "frame-characteristics" >
< summary > Size</ summary >
The picture frame fits a photo 40cm tall and 30cm wide.
The frame is 45cm tall, 35cm wide, and 2cm thick.
</ details >
< details name = "frame-characteristics" >
< summary > Color</ summary >
The picture frame is available in its natural wood
color, or with black stain.
</ details >
</ section >
以下示例展示了当对使用name
属性创建独占手风琴的details
元素设置open
属性时会发生什么。
给定初始标记:
< section class = "characteristics" >
< details name = "frame-characteristics" id = "d1" open > ...</ details >
< details name = "frame-characteristics" id = "d2" > ...</ details >
< details name = "frame-characteristics" id = "d3" > ...</ details >
</ section >
和脚本:
document. getElementById( "d2" ). setAttribute( "open" , "" );
然后脚本执行后的结果树将等效于标记:
< section class = "characteristics" >
< details name = "frame-characteristics" id = "d1" > ...</ details >
< details name = "frame-characteristics" id = "d2" open > ...</ details >
< details name = "frame-characteristics" id = "d3" > ...</ details >
</ section >
因为在d2
上设置open
属性会从d1
中移除它。
当用户激活summary
元素内的d2
时,也会发生相同的情况。
由于open
属性在
用户与控件交互时自动添加和删除,因此可以在 CSS 中使用它根据元素的状态以不同的方式对其进行样式设置。此处,样式表用于在打开或关闭元素时动画显示摘要的颜色:
< style >
details > summary { transition : color 1 s ; color : black ; }
details [ open ] > summary { color : red ; }
</ style >
< details >
< summary > Automated Status: Operational</ summary >
< p > Velocity: 12m/s</ p >
< p > Direction: North</ p >
</ details >
summary
元素所有当前引擎支持。
details
元素的第一个子元素。HTMLElement
。summary
元素表示其父details
元素的内容的摘要、标题或说明(如果有的话)。
如果以下算法返回 true,则summary
元素是其父详细信息的摘要:
如果这个summary
元素不是其父详细信息的摘要,则返回。
令parent为这个summary
元素的父元素。
如果parent上存在open
属性,则将其移除。否则,将parent的open
属性设置为空字符串。
这将运行详细信息通知任务步骤。
命令是菜单项、按钮和链接背后的抽象概念。一旦命令被定义,界面的其他部分可以引用相同的命令,从而允许多个访问点共享例如禁用状态等 Facets。
命令被定义为具有以下Facets:
用户代理可以公开符合以下条件的命令:
鼓励用户代理特别为具有访问键的命令执行此操作,作为向用户宣传这些键的一种方式。
例如,这些命令可以在用户代理的菜单栏中列出。
a
元素定义命令如果元素具有
属性,则命令的 为 true(隐藏),否则为 false。如果元素或其某个祖先是惰性的,则命令的禁用状态为 true,否则为 false。
命令的动作是触发一个 click
事件。
button
元素定义命令
命令的标签、访问键、 和动作 Facets
是按照定义 a
元素的方式确定的(见上一节)。
如果元素或其某个祖先是惰性的,或者元素的禁用状态已设置,则命令的禁用状态为 true,否则为 false。
input
元素定义命令
当 input
元素的 type
属性为 提交按钮、重置按钮、图像按钮、按钮、单选按钮或 复选框 状态时,定义了一个命令。
命令的标签按如下方式确定:
如果 type
属性为 提交按钮、重置按钮、图像按钮或 按钮 状态,则 标签是由
value
属性给出的字符串(如果有),如果该属性不存在,则由用户代理用于标记按钮本身的依赖于用户代理和区域设置的值。
否则,如果元素是一个标记控件,那么 标签是 第一个在树顺序中的 label
元素的后代文本内容。(在
JavaScript 术语中,这是由
element.labels[0].textContent
给出的。)
否则,标签为空字符串。
如果元素具有
属性,则命令的 为 true(隐藏),否则为 false。如果元素或其某个祖先是惰性的,或者元素的禁用状态已设置,则命令的禁用状态为 true,否则为 false。
命令的动作是触发一个
click
事件。
option
元素定义命令
具有祖先 select
元素且没有 value
属性或具有非空 value
属性的 option
元素定义了一个命令。
命令的标签是
option
元素的 label
属性的值(如果有),否则是 option
元素的后代文本内容,其中ASCII 空白字符被剥离和折叠。
如果元素具有
属性,则命令的 为 true(隐藏),否则为 false。如果元素被禁用,或者其最近的祖先 select
元素被禁用,或者它或其某个祖先是惰性的,则命令的禁用状态为 true,否则为 false。
如果 option
的最近的祖先 select
元素具有 multiple
属性,则命令的动作是切换 option
元素。否则,命令的动作是选择 option
元素。
accesskey
属性在 legend
元素上定义命令
如果满足以下所有条件,则 legend
元素定义了一个命令:
它具有一个分配的访问键。
它是 fieldset
元素的子元素。
它的父元素有一个后代,该后代定义了一个命令,该命令既不是 label
元素也不是 legend
元素。如果此元素存在,则它是 legend
元素的
accesskey
受托者。
命令的禁用状态和动作特性与 legend
元素的 accesskey
受托者 的相应特性相同。
在此示例中,legend
元素指定了一个 accesskey
,当激活时,将委托给
input
元素。
< fieldset >
< legend accesskey = p >
< label > I want < input name = pizza type = number step = 1 value = 1 min = 0 >
pizza(s) with these toppings</ label >
</ legend >
< label >< input name = pizza-cheese type = checkbox checked > Cheese</ label >
< label >< input name = pizza-ham type = checkbox checked > Ham</ label >
< label >< input name = pizza-pineapple type = checkbox > Pineapple</ label >
</ fieldset >
accesskey
属性在其他元素上定义命令
如果前面定义了定义命令的元素的章节之一定义了此元素定义了一个命令,那么该章节适用于此元素,而本章节不适用。否则,本章节适用于该元素。
命令的标签取决于元素。如果该元素是带标签的控件,则第一个 label
元素的后代文本内容 是该命令的标签(在 JavaScript 中,这由
element.labels[0].textContent
给出)。否则,该标签是元素的后代文本内容。
命令的
为 true(隐藏)如果元素具有 属性,否则为 false。命令的禁用状态为 true 如果元素或其祖先之一为惰性,否则为 false。
命令的动作是运行以下步骤:
click
事件。dialog
元素Support in all current engines.
Support in all current engines.
open
— 对话框是否显示[Exposed =Window ]
interface HTMLDialogElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute boolean open ;
attribute DOMString returnValue ;
[CEReactions ] undefined show ();
[CEReactions ] undefined showModal ();
[CEReactions ] undefined close (optional DOMString returnValue );
};
dialog
元素表示应用程序的临时部分,形式为用户与之交互以执行任务或收集信息的小窗口(“对话框”)。用户完成后,对话框可以由应用程序自动关闭,或由用户手动关闭。
特别是对于模态对话框,这是所有类型应用程序中的常见模式,作者应确保其Web应用程序中的对话框行为与非Web应用程序中的用户习惯相一致。
与所有HTML元素一样,当尝试表示另一种控件时,使用 dialog
元素是不符合规范的。例如,上下文菜单、工具提示和弹出列表框不是对话框,因此使用 dialog
元素来实现这些模式是错误的。
用户面对的对话框行为的一个重要部分是初始焦点的放置。对话框聚焦步骤尝试在对话框显示时为初始焦点选择一个好的候选项,但可能无法替代作者仔细思考正确选择以匹配用户对特定对话框的期望。因此,作者应在对话框的子孙元素上使用
autofocus
属性,以便在对话框打开后用户期望立即与之交互。如果没有这样的元素,则作者应在 autofocus
属性使用在 dialog
元素本身。
在下面的示例中,对话框用于编辑库存管理Web应用程序中产品的详细信息。
< dialog >
< label > Product Number < input type = "text" readonly ></ label >
< label > Product Name < input type = "text" autofocus ></ label >
</ dialog >
如果没有 autofocus
属性,产品编号字段将被对话框聚焦步骤聚焦。尽管这是合理的行为,但作者认为更相关的字段是产品名称字段,因为产品编号字段是只读的,不需要用户输入。因此,作者使用autofocus覆盖了默认设置。
即使作者希望默认情况下聚焦产品编号字段,他们最好明确指定该字段,通过在该 input
元素上使用autofocus。这使意图对未来的代码读者显而易见,并确保代码在未来更新的情况下保持稳健。(例如,如果另一位开发者添加了一个关闭按钮,并将其放置在产品编号字段之前的节点树中)。
用户行为的另一个重要方面是对话框是否可滚动。在某些情况下,溢出(因此可滚动)是不可避免的,例如当用户的高文本缩放设置导致时。但通常情况下,用户不期望可滚动的对话框。将大型文本节点直接添加到对话框元素中尤其不好,因为这可能会导致对话框元素本身溢出。作者最好避免这种情况。
以下服务条款对话框遵循上述建议。
< dialog style = "height: 80vh;" >
< div style = "overflow: auto; height: 60vh;" autofocus >
< p > By placing an order via this Web site on the first day of the fourth month of the year
2010 Anno Domini, you agree to grant Us a non-transferable option to claim, for now and for
ever more, your immortal soul.</ p >
< p > Should We wish to exercise this option, you agree to surrender your immortal soul,
and any claim you may have on it, within 5 (five) working days of receiving written
notification from this site or one of its duly authorized minions.</ p >
<!-- ... etc., with many more <p> elements ... -->
</ div >
< form method = "dialog" >
< button type = "submit" value = "agree" > Agree</ button >
< button type = "submit" value = "disagree" > Disagree</ button >
</ form >
</ dialog >
注意 对话框聚焦步骤 默认会选择可滚动的 div
元素,但与前一个示例类似,我们在 autofocus
上放置 div
以使其更加明确并对未来的更改更加稳健。
相反,如果没有这样的包装器 div
元素,那么
dialog
本身将变得可滚动,违反上述建议。此外,在没有任何 autofocus
属性的情况下,这样的标记模式将违反上述建议,并触发 对话框聚焦步骤 的默认行为,并导致焦点跳转到同意 button
,这是不良的用户体验。
open
属性是一个 布尔属性。指定时,它表示 dialog
元素是活动的,用户可以与之交互。
没有指定 dialog
元素的 open
属性不应向用户显示。此要求可以通过样式层间接实现。例如,支持建议的默认渲染的用户代理使用 渲染部分中描述的CSS规则实现此要求。
删除 open
属性通常会隐藏对话框。但是,这样做会带来一些奇怪的附加后果:
dialog.show()
Support in all current engines.
显示 dialog
元素。
dialog.showModal()
Support in all current engines.
显示 dialog
元素并使其成为最上层的模态对话框。
此方法遵循 autofocus
属性。
dialog.close([ result ])
Support in all current engines.
关闭 dialog
元素。
参数(如果提供)将提供返回值。
dialog.returnValue [ = result ]
Support in all current engines.
返回 dialog
的返回值。
可以设置,以更新返回值。
show()
方法步骤如下:
如果 this 具有 open
属性,则抛出 "InvalidStateError
" DOMException
。
将 this 的 previously focused element 设置为 focused 元素。
让 hideUntil 成为运行 topmost popover ancestor 给定 this、null 和 false 的结果。
运行 hide all popovers until 给定 hideUntil、false 和 true。
运行 dialog focusing steps 给定 this。
showModal()
方法步骤如下:
如果 this 具有 open
属性,则抛出 "InvalidStateError
" DOMException
。
如果 this 未 连接,则抛出 "InvalidStateError
" DOMException
。
如果 this 处于 popover 显示状态,则抛出 "InvalidStateError
" DOMException
。
这将导致 文档的聚焦区域 变为 惰性(除非当前聚焦区域是 影子包含的后代)。在这种情况下,我们将尝试找到一个更好的候选项来聚焦。
将 this 的 关闭观察者 设置为 建立关闭观察者 结果,给定 this 的 相关全局对象,包括:
cancelAction 给定
canPreventClose 返回结果 触发事件 名为 cancel
在
this 上,带有 cancelable
属性初始化为 canPreventClose。
closeAction 关闭对话框,给定 this 和 null。
将 this 的 previously focused element 设置为 focused 元素。
让 hideUntil 成为运行 topmost popover ancestor 给定 this、null 和 false 的结果。
运行 hide all popovers until 给定 hideUntil、false 和 true。
运行 dialog focusing steps 给定 this。
对话框聚焦步骤,给定一个 dialog
元素 subject,如下:
让 control 为 null。
如果 subject 具有 autofocus
属性,则将 control 设置为 subject。
如果 control 为 null,则将 control 设置为 subject 的 focus delegate。
如果 control 为 null,则将 control 设置为 subject。
运行 focusing steps 给定 control。
如果 control 不 focusable,则不会执行任何操作。这只会发生在 subject 没有 focus delegate 的情况下,并且用户代理决定
dialog
元素通常不可聚焦。在这种情况下,任何 早期修改 到 文档的聚焦区域 将适用。
让 topDocument 成为 control 的 node navigable 的 顶层可遍历 的 活动文档。
设置 topDocument 的 自动聚焦处理标志 为 true。
dialog
HTML 元素删除步骤,给定
removedNode 和
oldParent,如下:
如果 removedNode 的 关闭观察者 不为 null,则:
如果 removedNode 的 节点文档 的 顶层 包含 removedNode,则 立即从顶层删除元素 给定 removedNode。
设置 removedNode 的 is modal 标志为 false。
close(returnValue)
方法步骤如下:
当一个 dialog
元素 subject 要 关闭 时,带有 null 或字符串 result,按以下步骤运行:
如果 subject 没有 open
属性,则返回。
删除 subject 的 open
属性。
让 wasModal 成为 subject 的 is modal 标志的值。
将 subject 的 is modal 标志设置为 false。
如果 result 不为 null,则将 returnValue
属性设置为 result。
如果 subject 的 previously focused element 不为 null,则:
让 element 成为 subject 的 previously focused element。
将 subject 的 previously focused element 设置为 null。
如果 subject 的 节点文档 的 文档的聚焦区域 的 DOM 锚点 是 影子包含的后代 element,或者 wasModal 为 true,则运行 focusing steps 给定 element;执行此步骤时不应滚动视口。
在用户交互任务源上队列一个元素任务,给定
subject 元素 触发一个事件 名为 close
在
subject 上。
如果 subject 的 关闭观察者 不为 null,则:
returnValue
IDL 属性,在获取时,必须返回上次设置的值。在设置时,必须设置为新值。当元素被创建时,必须设置为空字符串。
我们使用 show/close 作为 dialog
元素的动词,而不是更常见的反义词动词对,如 show/hide 或 open/close,原因如下:
隐藏对话框与关闭对话框不同。关闭对话框会为其提供返回值,触发事件,解锁页面以显示其他对话框,等等。而隐藏对话框只是一个纯粹的视觉属性,可以通过 open
属性来完成。(另请参阅关于删除 open
属性的 上面注释,以及以这种方式隐藏对话框通常是不理想的。)
显示对话框与打开对话框不同。打开对话框包括创建和显示该对话框(类似于 window.open()
既创建又显示新窗口)。而显示对话框是将已经在DOM中的 dialog
元素展示给用户并使其交互和可见的过程。
如果我们有一个 dialog.open()
方法,尽管有上述区别,它仍会与 dialog.open
属性冲突。
此外,一项调查 表明,许多其他与
dialog
元素设计同时期的 UI 框架表明,show/close 动词对是相当常见的。
总之,事实证明某些动词的含义及其在技术环境中的使用方式意味着,显示和关闭对话框等配对操作并不总是可以用反义词表达。
每个 dialog
元素都有一个 关闭观察者,它是一个 关闭观察者 或 null,最初为 null。
每个 dialog
元素都有一个 is modal 标志。当创建一个 dialog
元素时,此标志必须设置为 false。
每个 HTML 元素 都有一个 previously focused element,它为 null 或一个元素,最初为 null。当调用 showModal()
和 show()
时,此元素设置为当前 聚焦 元素。在运行 对话框聚焦步骤
之前。带有 popover
属性的元素在 显示弹出窗口算法 中设置为当前 聚焦 元素。
Support in all current engines.
此对话框包含一些小字。使用 strong
元素以引起用户注意更重要的部分。
< dialog >
< h1 > Add to Wallet</ h1 >
< p >< strong >< label for = amt > How many gold coins do you want to add to your wallet?</ label ></ strong ></ p >
< p >< input id = amt name = amt type = number min = 0 step = 0.01 value = 100 ></ p >
< p >< small > You add coins at your own risk.</ small ></ p >
< p >< label >< input name = round type = checkbox > Only add perfectly round coins</ label ></ p >
< p >< input type = button onclick = "submit()" value = "Add Coins" ></ p >
</ dialog >
脚本允许作者为其文档添加交互性。
鼓励作者尽可能使用声明性替代脚本,因为声明性机制通常更易于维护,且许多用户禁用脚本。
例如,作者可以使用details
元素来显示或隐藏部分详细信息,而不是使用脚本。
还鼓励作者使其应用程序在缺乏脚本支持的情况下也能优雅降级。
例如,如果作者在表头提供了一个链接来动态排序表格,该链接也可以在没有脚本的情况下通过向服务器请求排序后的表格来工作。
script
元素在所有当前引擎中都得到支持。
在所有当前引擎中都得到支持。
src
属性,则取决于
type
属性的值,但必须符合 脚本内容限制。
src
属性,则元素必须为空或仅包含 脚本文档,且符合 脚本内容限制。src
— 资源的地址type
—
脚本类型nomodule
— 防止在支持 模块脚本 的用户代理中执行
async
—
在获取时执行脚本,不阻塞defer
—
延迟脚本执行crossorigin
— 元素如何处理跨源请求integrity
— 用于 子资源完整性 检查的完整性元数据 [SRI]referrerpolicy
— 元素发起的 引用政策 用于 抓取blocking
— 元素是否 可能会阻塞渲染fetchpriority
— 设置元素发起的 请求优先级[Exposed =Window ]
interface HTMLScriptElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute USVString src ;
[CEReactions ] attribute DOMString type ;
[CEReactions ] attribute boolean noModule ;
[CEReactions ] attribute boolean async ;
[CEReactions ] attribute boolean defer ;
[CEReactions ] attribute DOMString ? crossOrigin ;
[CEReactions ] attribute DOMString text ;
[CEReactions ] attribute DOMString integrity ;
[CEReactions ] attribute DOMString referrerPolicy ;
[SameObject , PutForwards =value ] readonly attribute DOMTokenList blocking ;
[CEReactions ] attribute DOMString fetchPriority ;
static boolean supports (DOMString type );
// also has obsolete members
};
script
元素允许作者在文档中包含动态脚本和数据块。该元素不 表示
用户内容。
在所有当前引擎中都得到支持。
type
属性允许自定义表示的脚本类型:
省略该属性、将其设置为空字符串,或将其设置为
JavaScript MIME 类型本质匹配,意味着
脚本是一个 经典脚本,
按照 JavaScript Script 顶级
生产进行解释。经典脚本受
async
和 defer
属性的影响,但仅在 src
属性被设置时。作者应省略 type
属性,而不是冗余地设置它。
将属性设置为 ASCII
不区分大小写 的 "module
" 匹配意味着脚本是一个 JavaScript 模块脚本,按照 JavaScript Module 顶级
生产进行解释。模块脚本不受 defer
属性的影响,但受 async
属性的影响(无论 src
属性的状态如何)。
将属性设置为 ASCII
不区分大小写 的 "importmap
" 匹配意味着脚本是一个 导入映射,包含
将用于控制 模块说明符解析 行为的
JSON。导入映射只能
是内联的,即 src
属性和大多数其他属性是无效的,不应与它们一起使用。
将属性设置为任何其他值意味着脚本是一个 数据块,不被处理。没有
script
属性(除了 type
本身)对数据块没有任何影响。作者必须使用
有效 MIME 类型字符串,而不是 JavaScript MIME 类型本质匹配 来表示数据块。
要求 数据块
必须使用 有效 MIME 类型字符串
来表示,以避免未来潜在的冲突。如果本规范未来添加额外类型的
脚本,它们将通过将
type
属性设置为非 MIME 类型的值(类似于 "module
" 值表示 模块脚本)来触发。通过现在使用有效 MIME 类型字符串,您可以确保您的数据块不会
被重新解释为不同的脚本类型,即使在未来的用户代理中也是如此。
经典脚本
和 JavaScript 模块脚本
可以内联嵌入,或者通过 src
属性从外部文件导入,如果指定则给出 URL
外部脚本资源的使用。如果 src
被指定,
它必须是一个 有效的非空 URL 可能被空格包围。
内联 script
元素的内容或外部脚本资源必须符合 JavaScript 规范的 Script 或 Module 生产规则,分别用于 经典脚本
和 JavaScript 模块脚本。 [JAVASCRIPT]
外部脚本资源的内容对于 CSS 模块脚本 必须符合 CSS 规范的要求。 [CSS]
外部脚本资源的内容对于 JSON 模块脚本 必须符合 JSON 规范的要求。 [JSON]
用于 导入映射 的内联 script
元素的内容必须符合 导入映射编写要求。
对于 导入映射 script
元素,src
、
async
、
nomodule
、
defer
、
crossorigin
、
integrity
,
和 referrerpolicy
属性不得指定。
当用于包含 数据块 时,数据必须
内联嵌入,数据的格式必须通过 type
属性给出,并且 script
元素的内容必须符合所使用格式的要求。src
、
async
、
nomodule
、
defer
、
crossorigin
、
integrity
、
referrerpolicy
和 fetchpriority
属性不得指定。
nomodule
属性是一个 布尔属性,
它防止脚本在支持 模块脚本 的用户代理中执行。
这允许在现代用户代理中选择性地执行 模块脚本
和在较旧用户代理中执行 经典脚本,
如下面所示。nomodule
属性不得在 模块脚本
上指定(如果指定则会被忽略)。
在所有当前引擎中都支持。
在所有当前引擎中都支持。
async
和
defer
属性是 布尔属性,
表示脚本的评估方式。经典脚本 可以指定
defer
或 async
,
但如果没有指定 src
属性,则不能指定这两个属性中的任何一个。模块脚本
可以指定 async
属性,但不能指定 defer
属性。
可以使用这些属性选择几种不同的模式,具体取决于脚本的类型。
对于 经典脚本,
如果指定了 async
属性,则经典脚本将会 与解析并行 获取,
并在脚本可用时立即评估(可能在解析完成之前)。如果没有指定 async
属性,但指定了 defer
属性,则经典脚本将会 与解析并行 获取,
并在页面完成解析时进行评估。如果没有指定这两个属性,则脚本将立即获取并评估,阻止解析直到两者都完成。
对于 模块脚本,
如果指定了 async
属性,则模块脚本及其所有依赖项将 与解析并行 获取,
并在模块脚本可用时立即进行评估(可能在解析完成之前)。否则,模块脚本及其依赖项将 与解析并行
获取,并在页面完成解析时进行评估。(defer
属性对模块脚本没有影响。)
以下是对这些内容的总结示意图:
这些属性的具体处理细节因为主要是历史原因,涉及到许多HTML的方面,因此有些复杂。实现要求因此必须分散在规范的各个部分。下面的算法(在本节中)描述了处理的核心,但这些算法引用并被引用于HTML中
script
开始 和 结束 标签,外部内容,
和 XML,document.write()
方法的规则,脚本处理等。
使用 document.write()
方法插入的 script
元素 通常 执行(通常会阻止进一步的脚本执行或HTML解析)。使用 innerHTML
和 outerHTML
属性插入的脚本则不会执行。
defer
属性即使在指定了 async
属性的情况下也可以指定,以使仅支持 defer
(而不支持 async
)的旧版
网络浏览器回退到 defer
行为,而不是默认的阻塞行为。
crossorigin
属性是一个 CORS
设置属性。对于 经典脚本,它控制是否会暴露错误信息,当脚本来自其他 来源 时。对于 模块脚本,它控制用于跨源请求的 凭证模式。
与 经典脚本 不同,模块脚本 需要使用 CORS 协议 进行跨源获取。
integrity
属性表示该元素负责的请求的 完整性元数据。其值为文本。只有在指定了 src
属性时,才可以指定 integrity
属性。[SRI]
referrerpolicy
属性是一个 referer
策略属性。它的目的是设置在 获取
脚本时使用的 referer 策略,以及从脚本中导入的任何
脚本。
[REFERRERPOLICY]
一个示例,展示了 script
元素在获取导入的脚本时使用的 referer 策略,但不适用于其他子资源:
< script referrerpolicy = "origin" >
fetch( '/api/data' ); // not fetched with <script>'s referrer policy
import ( './utils.mjs' ); // is fetched with <script>'s referrer policy ("origin" in this case)
</ script >
blocking
属性是一个 阻塞属性。
fetchpriority
属性是一个
获取优先级属性。它的作用是设置在 获取 脚本时使用的 优先级。
动态改变 src
、type
、nomodule
、async
、defer
、crossorigin
、integrity
、referrerpolicy
和 fetchpriority
属性没有直接效果;这些属性只在下面描述的特定时间使用。
IDL 属性 src
、type
、defer
、integrity
和 blocking
,
必须分别 反映 同名的内容属性。
HTMLScriptElement/referrerPolicy
在所有当前引擎中支持。
referrerPolicy
IDL 属性必须
反映 referrerpolicy
内容属性,限制为仅已知值。
fetchPriority
IDL 属性必须
反映 fetchpriority
内容属性,限制为仅已知值。
crossOrigin
IDL 属性必须 反映
crossorigin
内容属性,限制为仅已知值。
noModule
IDL 属性必须 反映
nomodule
内容属性。
async
获取器步骤如下:
async
设置器步骤如下:
script.text [ = value ]
返回元素的 子文本内容。
可以被设置,以用给定的值替换元素的子节点。
HTMLScriptElement
.supports(type)
如果给定的 type 是用户代理支持的脚本类型,则返回 true。本规范中的可能脚本类型为 "classic
"、"module
" 和
"importmap
",但将来可能会添加其他类型。
text
属性的获取器必须返回此 script
元素的 子文本内容。
text
属性的设置器必须 字符串替换
所有 用给定值替换此 script
元素的内容。
HTMLScriptElement/supports_static
支持所有当前引擎。
supports(type)
方法的步骤是:
如果 type 是 "classic
",则返回
true。
如果 type 是 "module
",则返回
true。
如果 type 是 "importmap
",则返回
true。
返回 false。
type 参数必须与这些值完全匹配;我们不会执行 ASCII
不区分大小写 匹配。这与 type
内容属性值的处理方式以及 DOMTokenList
的 supports()
方法的工作方式不同,但与 WorkerType
枚举在 Worker()
构造函数中使用的方式一致。
在这个例子中,使用了两个 script
元素。一个嵌入了一个外部 经典脚本,另一个包含了一些数据作为 数据块。
< script src = "game-engine.js" ></ script >
< script type = "text/x-game-map" >
........ U......... e
o............ A.... e
..... A..... AAA.... e
. A.. AAA... AAAAA... e
</ script >
在这种情况下,数据可能会被脚本用来生成视频游戏的地图。不过,数据不必以这种方式使用;也许地图数据实际上嵌入在页面的其他部分的标记中,而这里的数据块只是被网站的搜索引擎用来帮助用户寻找游戏地图中的特定功能。
以下示例展示了如何使用一个 script
元素来定义一个函数,然后在文档的其他部分使用这个函数,作为 经典脚本
的一部分。它还展示了如何使用一个 script
元素在文档解析时调用脚本,在这种情况下,用于初始化表单的输出。
< script >
function calculate( form) {
var price = 52000 ;
if ( form. elements. brakes. checked)
price += 1000 ;
if ( form. elements. radio. checked)
price += 2500 ;
if ( form. elements. turbo. checked)
price += 5000 ;
if ( form. elements. sticker. checked)
price += 250 ;
form. elements. result. value = price;
}
</ script >
< form name = "pricecalc" onsubmit = "return false" onchange = "calculate(this)" >
< fieldset >
< legend > Work out the price of your car</ legend >
< p > Base cost: £52000.</ p >
< p > Select additional options:</ p >
< ul >
< li >< label >< input type = checkbox name = brakes > Ceramic brakes (£1000)</ label ></ li >
< li >< label >< input type = checkbox name = radio > Satellite radio (£2500)</ label ></ li >
< li >< label >< input type = checkbox name = turbo > Turbo charger (£5000)</ label ></ li >
< li >< label >< input type = checkbox name = sticker > "XZ" sticker (£250)</ label ></ li >
</ ul >
< p > Total: £< output name = result ></ output ></ p >
</ fieldset >
< script >
calculate( document. forms. pricecalc);
</ script >
</ form >
以下示例展示了如何使用一个 script
元素来包含一个外部的 JavaScript
模块脚本。
< script type = "module" src = "app.mjs" ></ script >
这个模块及其所有依赖项(通过 JavaScript import
语句在源文件中表示)将被获取。一旦整个结果模块图被导入,并且文档解析完成,app.mjs
的内容将被评估。
此外,如果同一个 script
元素中的另一段代码在同一个 Window
中从
app.mjs
导入模块(例如,通过 import "./app.mjs";
),那么前一个 script
元素创建的相同 JavaScript 模块脚本
将会被导入。
这个例子展示了如何为现代用户代理包含一个 JavaScript 模块脚本,以及为旧版用户代理包含一个 经典脚本:
< script type = "module" src = "app.mjs" ></ script >
< script nomodule defer src = "classic-app-bundle.js" ></ script >
在支持 JavaScript 模块脚本
的现代用户代理中,具有 nomodule
属性的 script
元素将被忽略,而具有 type
为
"module
" 的 script
元素将被提取并执行(作为 JavaScript
模块脚本)。相反,旧版用户代理将忽略具有 type
为
"module
" 的 script
元素,因为这是它们未知的脚本类型——但它们将毫无问题地提取和执行其他 script
元素(作为 经典脚本),因为它们不实现
nomodule
属性。
以下示例展示了如何使用 script
元素编写一个内联的 JavaScript
模块脚本,该脚本对文档的文本进行多个替换,以提供更有趣的阅读体验(例如,在新闻网站上):[XKCD1288]
< script type = "module" >
import { walkAllTextNodeDescendants } from "./dom-utils.mjs" ;
const substitutions = new Map([
[ "witnesses" , "these dudes I know" ]
[ "allegedly" , "kinda probably" ]
[ "new study" , "Tumblr post" ]
[ "rebuild" , "avenge" ]
[ "space" , "spaaace" ]
[ "Google glass" , "Virtual Boy" ]
[ "smartphone" , "Pokédex" ]
[ "electric" , "atomic" ]
[ "Senator" , "Elf-Lord" ]
[ "car" , "cat" ]
[ "election" , "eating contest" ]
[ "Congressional leaders" , "river spirits" ]
[ "homeland security" , "Homestar Runner" ]
[ "could not be reached for comment" , "is guilty and everyone knows it" ]
]);
function substitute( textNode) {
for ( const [ before, after] of substitutions. entries()) {
textNode. data = textNode. data. replace( new RegExp( `\\b ${ before} \\b` , "ig" ), after);
}
}
walkAllTextNodeDescendants( document. body, substitute);
</ script >
使用 JavaScript 模块脚本带来的一些显著功能包括能够从其他 JavaScript 模块中导入函数、默认启用严格模式,以及顶级声明不会在 全局对象 上引入新属性。还需注意的是,无论此
script
元素在文档中出现在哪里,它都不会在文档解析完成和其依赖项(dom-utils.mjs
)被获取并评估之前被执行。
以下示例展示了如何从一个 JavaScript 模块脚本 中导入一个 JSON 模块脚本:
< script type = "module" >
import peopleInSpace from "http://api.open-notify.org/astros.json" with { type: "json" };
const list = document. querySelector( "#people-in-space" );
for ( const { craft, name } of peopleInSpace. people) {
const li = document. createElement( "li" );
li. textContent = ` ${ name} / ${ craft} ` ;
list. append( li);
}
</ script >
模块脚本的 MIME 类型检查是严格的。为了成功获取 JSON
模块脚本,HTTP 响应必须具有 JSON MIME 类型,例如
Content-Type: text/json
。另一方面,如果省略了 with { type: "json" }
部分,则假定意图是导入 JavaScript 模块脚本,如果 HTTP
响应的 MIME 类型不是 JavaScript
MIME 类型,则获取将失败。
一个script
元素有多个关联的状态。
一个script
元素有一个解析器文档,它要么是null,要么是一个
Document
,
初始值为null。它由
HTML解析器和
XML解析器在script
元素插入时设置,并影响这些元素的处理。具有非null
解析器文档的script
元素称为解析器插入。
一个script
元素有一个准备时间文档,它要么是null
要么是Document
,
初始值为null。它用于防止脚本在
准备期间在文档之间移动时
执行。
一个script
元素有一个强制异步布尔值,初始值为true。它由
HTML解析器和
XML解析器在script
元素插入时设置,并在元素添加async
内容属性时设置为false。
一个script
元素有一个来自外部文件布尔值,初始值为false。它在脚本
准备时确定,基于该时刻的元素的src
属性。
一个script
元素有一个准备好被解析器执行布尔值,初始值为false。这仅用于
解析器插入的元素,让解析器知道何时执行脚本。
一个script
元素有一个已开始布尔值,初始值为false。
一个script
元素有一个延迟加载事件布尔值,初始值为false。
一个script
元素有一个类型,它要么是null,要么是"classic
"、"module
"或"importmap
",初始值为null。它在元素
准备时确定,基于该时刻的元素的type
属性。
一个script
元素有一个结果,它要么是"uninitialized
",要么是null(表示错误),要么是一个脚本,要么是一个import
map解析结果。它的初始值为"uninitialized
"。
一个script
元素有结果准备好时要运行的步骤,它们是一系列步骤或null,初始值为null。要标记为准备好一个
script
元素el,给定一个脚本、import map解析结果,或null
result:
将el的结果设置为 result。
如果el的结果准备好时要运行的步骤 不为null,那么 运行它们。
将el的结果准备好时要运行的步骤 设置为null。
将el的延迟加载事件设置为false。
一个script
元素el是隐式潜在渲染阻塞的,如果el的类型是
"classic
",el是解析器插入的,并且
el没有async
或defer
属性。
克隆步骤为一个script
元素el克隆到副本copy的步骤是将copy的
已开始设置为el的已开始。
当一个async
属性被添加到一个
script
元素el时,用户代理必须将el的
强制异步设置为false。
每当一个 script
元素 el 的 delaying the load event 为真时,用户代理必须
delay
the load event 的 el 的 preparation-time document。
给定insertedNode,script
的HTML
元素后连接步骤是:
如果insertedNode未连接,则返回。
这种情况可能发生在一个较早插入的script
移除了一个较晚插入的script
时。例如:
< script >
const script1 = document. createElement( 'script' );
script1. innerText = `
document.querySelector('#script2').remove();
` ;
const script2 = document. createElement( 'script' );
script2. id = 'script2' ;
script2. textContent = `console.log('script#2 running')` ;
document. body. append( script1, script2);
</ script >
在此示例中,未向控制台打印任何内容。当第一次运行HTML 元素连接后的步骤时,原子插入的第一个script
可以观察到第二个
append()
已经与 DOM 连接。它会移除第二个
script
,以确保当HTML 元素连接后的步骤运行时,第二个script
已经不再连接,因此不会被准备。
如果insertedNode是解析器插入
,则返回。
给定insertedNode,准备 script 元素
。
给定script
元素,运行HTML 元素后连接步骤
。
这对script
元素和任何新插入的子script
元素的执行顺序有一个有趣的影响。请考虑以下代码片段:
< script id = outer-script ></ script >
< script >
const outerScript = document. querySelector( '#outer-script' );
const start = new Text( 'console.log(1);' );
const innerScript = document. createElement( 'script' );
innerScript. textContent = `console.log('inner script executing')` ;
const end = new Text( 'console.log(2);' );
outerScript. append( start, innerScript, end);
// 输出:
// 1
// 2
// 内部脚本执行
</ script >
当第二个脚本块执行时,outer-script
已经被准备
,但因为它是空的,没有执行,所以没有标记为已启动
。原子插入Text
节点和嵌套的script
元素产生了以下效果:
以下属性更改步骤,给定element,localName,oldValue,value和namespace,适用于所有script
元素:
如果namespace不为null,则返回。
如果localName是src
,则运行script
的HTML
元素后连接步骤,给定element。
要准备脚本元素,给定一个script
元素el:
如果el的已开始为true,那么返回。
让parser document成为el的解析器文档。
将el的解析器 文档设置为null。
这样做是为了当解析器插入的script
元素在解析器尝试运行它们时未能运行,例如因为它们是空的或指定了不支持的脚本语言,另一个脚本可以稍后改变它们并导致它们再次运行。
如果parser document不是null,并且el没有async
属性,那么将el的强制异步设置为true。
这样做是为了当解析器插入的script
元素在解析器尝试运行它时未能运行,但稍后在一个脚本动态更新它后被执行时,它将以异步方式执行,即使没有设置async
属性。
让source text成为el的子文本内容。
如果el没有src
属性,并且source text是空字符串,
那么返回。
如果el不是连接,那么返回。
如果以下任何一项为true:
那么让the script block's type string为这个script
元素
是"text/javascript
"。
否则,如果el有一个type
属性,那么
让the script block's type string是该属性的值,去除前导和尾随ASCII空白。
否则,el有一个非空的language
属性;让the script block's type string是"text/
"和
el的language
属性值的连接。
如果the script block's type string是一个JavaScript MIME类型本质匹配,
那么将el的类型设置为"classic
"。
否则,如果the script block's type string是一个ASCII不区分大小写匹配字符串"module
",那么将
el的类型设置为"module
"。
否则,如果the script block's type string是一个ASCII不区分大小写匹配字符串"importmap
",那么将
el的类型设置为"importmap
"。
否则,返回。(没有脚本被执行,并且el的类型保持为null。)
如果parser document不是null,那么将el的解析器文档设置回parser document并将el的强制异步设置为false。
将el的已开始设置为 true。
如果parser document不是null,并且parser document不等于 el的准备时间文档,那么返回。
如果脚本禁用对于el,那么返回。
脚本禁用的定义意味着,包括但不限于以下脚本将不会执行:XMLHttpRequest
中的脚本,
responseXML
文档中的脚本,DOMParser
创建的文档中的脚本,由
XSLTProcessor
的
transformToDocument
功能创建的文档中的脚本,以及由脚本首先插入到使用
Document
API创建的文档中的脚本。
[XHR]
[DOMPARSING] [XSLTP] [DOM]
如果el没有src
内容属性,并且元素的内联行为应被内容安全策略阻止吗?算法在给定
el、"script
"和
source text时返回"Blocked
",那么返回。[CSP]
如果el有一个event
属性和一个for
属性,并且el的类型是"classic
",那么:
让for成为el的for
属性的值。
让event成为el的event
属性的值。
去除前导和尾随的ASCII空白从event和 for中。
如果for不是一个ASCII不区分大小写匹配字符串
"window
",那么返回。
如果event不是一个ASCII不区分大小写匹配字符串"onload
"或字符串"onload()
",那么
返回。
如果el有一个charset
属性,那么让
encoding成为获取编码的结果从
charset
属性的值。
如果el没有charset
属性,或如果获取编码失败,那么让encoding成为
el的节点文档的
编码。
如果el的类型是"module
",那么这个编码将被忽略。
让classic script CORS setting成为el的当前状态的crossorigin
内容属性。
让module script credentials mode成为CORS设置属性凭证模式对于el的crossorigin
内容属性。
让cryptographic nonce成为el的[[CryptographicNonce]] 内部槽的值。
如果el有一个integrity
属性,
那么让integrity metadata成为该属性的值。
否则,让integrity metadata为空字符串。
让referrer policy成为el的当前状态的referrerpolicy
内容属性。
让fetch priority成为el的当前状态的fetchpriority
内容属性。
让parser metadata为"parser-inserted
",如果
el是解析器插入的,并且为"not-parser-inserted
",如果
否则。
让options成为一个脚本获取选项,其加密nonce是cryptographic nonce,完整性元数据是integrity metadata,解析器 元数据是parser metadata,凭证模式是module script credentials mode,引用 策略是referrer policy,以及获取优先级是fetch priority。
如果el有一个src
内容属性,那么:
如果el的类型是"importmap
",那么将一个元素任务排队在DOM
操作任务源上给定el来触发
一个事件命名为error
在el上,然后返回。
外部import map脚本当前不支持。请参阅WICG/import-maps issue #235关于添加支持的讨论。
让src成为el的src
属性的值。
如果src为空字符串,那么将一个元素任务排队在
DOM操作任务源上给定
el来触发一个事件
命名为error
在el上,然后返回。
将el的来自外部文件 设置为true。
如果url是失败,那么将一个元素任务排队在DOM
操作任务源上给定el来触发
一个事件命名为error
在el上,然后
返回。
将el的延迟加载 事件设置为true。
让onComplete给定result是以下步骤:
标记为 准备好 el给定result。
切换el的类型:
classic
"获取一个经典脚本给定url, settings object, options,classic script CORS setting,encoding,和 onComplete。
module
"如果el没有integrity
属性,那么将options的完整性元数据设置为
结果的
解析模块完整性
元数据给定url和
settings object。
获取一个外部模块脚本图 给定url,settings object,options,和onComplete。
出于性能原因,用户代理可能会尽快开始获取经典脚本或模块图
(如上所述),一旦src
属性被设置,
而不是,期望el将变得连接(并且crossorigin
属性不会改变值在此期间)。无论如何,一旦el变得连接,加载必须
按照此步骤描述开始。如果UA执行了这样的预取,但el
从未变得连接,或者src
属性被
动态更改,或者crossorigin
属性被动态更改,那么
用户代理将不会执行获取到的脚本,获取过程将
被有效浪费。
如果el没有src
内容
属性:
切换el的类型:
classic
"module
"importmap
"如果el的类型是"classic
"并且el有一个
src
属性,或者el的类型是"module
":
否则,如果el不是 解析器插入:
让script成为el的准备时间文档的 将按顺序尽快执行的脚本列表。
附加el到script。
将el的当结果准备好时要运行的步骤设置为 以下:
否则,如果el有一个
defer
属性或el的类型是"module
":
附加el到其解析器 文档的文档解析完成后将执行的脚本列表。
将el的当结果准备好时要运行的步骤设置为 以下:设置el的准备好被解析器执行为true。(解析器 将处理执行脚本。)
否则:
阻止渲染 在 el 上。
将 el 的 result 准备就绪时要运行的步骤 设置为以下内容:将 el 的 ready to be parser-executed 设置为 true。(解析器将处理脚本的执行。)
否则:
每个Document
有一个
待解析阻塞脚本,这是一个
script
元素或null,最初为null。
每个Document
有一个
将尽快执行的脚本集,这是一个集合的script
元素,最初为空。
每个Document
有一个
将按顺序尽快执行的脚本列表,这是一个列表的script
元素,最初
为空。
每个Document
有一个
文档解析完成后将执行的脚本列表,这是一个列表的script
元素,最初
为空。
如果一个script
元素阻塞一个解析器被移动到另一个
Document
在它通常会停止阻塞解析器之前,它仍然会
继续阻塞解析器,直到导致它阻塞解析器的条件不再适用(例如,如果脚本是一个待解析阻塞脚本,因为
原来的Document
有一个样式表在阻塞
脚本当它被
解析,但随后脚本被移动到另一个Document
在阻塞样式
表加载之前,脚本仍然会阻塞解析器,直到样式表全部加载完成,到
那时脚本执行并且解析器被解锁)。
为了执行脚本元素给定一个
script
元素el:
让document成为el的节点文档。
如果el的准备时间文档不等于 document,那么返回。
解除阻塞渲染在el上。
如果el的来自外部文件为
true,或el的
类型是"module
",那么增加
document的忽略破坏性写入计数器。
切换el的类型:
classic
"让oldCurrentScript成为document的currentScript
对象最近设置的值。
如果el的根不是
一个影子根,那么
将document的currentScript
属性设置为el。否则,将其设置为null。
这不使用在文档树中检查,
因为el可能在执行之前已从文档中移除,在这种情况下currentScript
仍然需要
指向它。
将document的currentScript
属性设置为
oldCurrentScript。
module
"断言:document的currentScript
属性为null。
importmap
"减少document的忽略破坏性写入计数器, 如果 它在前面的步骤中增加。
用户代理不要求支持JavaScript。如果有一种语言出现并在网页浏览器中获得类似的广泛采用,则需要更新本标准。直到那时,实现其他语言将与本标准冲突,因为为script
元素定义的处理模型。
服务器应使用text/javascript
用于JavaScript资源,根据更新ECMAScript媒体类型。服务器不应使用其他
JavaScript MIME类型用于JavaScript资源,并且
必须不使用非JavaScript MIME类型。
[RFC9239]
对于外部JavaScript资源,`Content-Type
`头中的MIME类型参数通常被忽略。(在某些情况下,`charset
`参数有影响。)但是,对于script
元素的type
属性,它们是重要的;它使用JavaScript MIME类型精髓匹配概念。
例如,设置了其type
属性为"text/javascript; charset=utf-8
"的脚本将不会被评估,尽管这在解析时是一个有效的JavaScript MIME类型。
此外,对于外部JavaScript资源,在`Content-Type
`头处理周围有特殊考虑,如准备脚本元素算法和Fetch中详细描述的那样。[FETCH]
script
元素内容的限制
避免本节所述的相当奇怪的限制的最简单和最安全的方法是在脚本的字面量中(例如在字符串、正则表达式或注释中)出现"<!--
"时将其转义为"\x3C!--
","<script
"转义为"\x3Cscript
","</script
"转义为"\x3C/script
",并避免在表达式中编写使用此类构造的代码。这样做可以避免本节中的限制容易触发的陷阱:即由于历史原因,HTML中script
块的解析是一种奇怪且复杂的做法,在这些序列面前表现得不直观。
script
元素的后代文本内容必须符合以下ABNF中的script
生成规则,其字符集为Unicode。[ABNF]
script = outer * ( comment-open inner comment-close outer )
outer = < 任何 字符串 不包含 子字符串 匹配 not-in-outer >
not-in-outer = comment-open
inner = < 任何 字符串 不包含 子字符串 匹配 not-in-inner >
not-in-inner = comment-close / script-open
comment-open = "<!--"
comment-close = "-->"
script-open = "<" s c r i p t tag-end
s = %x0053 ; U+0053 拉丁大写字母 S
s =/ %x0073 ; U+0073 拉丁小写字母 s
c = %x0043 ; U+0043 拉丁大写字母 C
c =/ %x0063 ; U+0063 拉丁小写字母 c
r = %x0052 ; U+0052 拉丁大写字母 R
r =/ %x0072 ; U+0072 拉丁小写字母 r
i = %x0049 ; U+0049 拉丁大写字母 I
i =/ %x0069 ; U+0069 拉丁小写字母 i
p = %x0050 ; U+0050 拉丁大写字母 P
p =/ %x0070 ; U+0070 拉丁小写字母 p
t = %x0054 ; U+0054 拉丁大写字母 T
t =/ %x0074 ; U+0074 拉丁小写字母 t
tag-end = %x0009 ; U+0009 字符制表符 (tab)
tag-end =/ %x000A ; U+000A 换行符 (LF)
tag-end =/ %x000C ; U+000C 换页符 (FF)
tag-end =/ %x0020 ; U+0020 空格
tag-end =/ %x002F ; U+002F 斜杠 (/)
tag-end =/ %x003E ; U+003E 大于号 (>)
当script
元素包含脚本文档时,有进一步的限制,如下节所述。
以下脚本说明了这个问题。假设你有一个包含字符串的脚本,如下所示:
const example = 'Consider this string: <!-- <script>' ;
console. log( example);
如果将这个字符串直接放在script
块中,它将违反上述限制:
< script >
const example = 'Consider this string: <!-- <script>' ;
console. log( example);
</ script >
更大的问题是,脚本将被奇怪地解析:上面的脚本块未终止。也就是说,在这个片段中看起来像"</script>
"的结束标签实际上仍然是script
块的一部分。脚本不会执行(因为它未终止);如果它以某种方式执行,如下面的标记所示,它将失败,因为脚本(此处高亮部分)不是有效的JavaScript:
< script >
const example = 'Consider this string: <!-- <script>' ;
console. log( example);
</ script >
<!-- despite appearances, this is actually part of the script still! -->
< script >
... // this is the same script block still...
</ script >
这里发生的事情是由于遗留原因,HTML中<!--
和<script
字符串在script
元素中需要平衡,以便解析器考虑关闭该块。
通过如本节顶部所述转义问题字符串,可以完全避免这个问题:
< script >
// Note: `\x3C` is an escape sequence for `<`.
const example = 'Consider this string: \x3C!-- \x3Cscript>' ;
console. log( example);
</ script >
<!-- this is just a comment between script blocks -->
< script >
... // this is a new script block
</ script >
这些序列可能自然出现在脚本表达式中,如以下示例所示:
if ( x<!-- y) { ... }
if ( player< script ) { ... }
在这种情况下,字符不能转义,但表达式可以重写,使序列不出现,如下所示:
if ( x < !-- y) { ... }
if ( !-- y > x) { ... }
if ( ! ( -- y) > x) { ... }
if ( player < script) { ... }
if ( script > player) { ... }
这样做还可以避免另一个陷阱:由于相关的历史原因,经典脚本中的字符串"<!--"实际上被视为行注释开始,就像"//"一样。
如果script
元素的src
属性被指定,那么script
元素的内容(如果有的话)必须符合以下ABNF中的documentation
生成规则,字符集为Unicode。[ABNF]
documentation = * ( * ( space / tab / comment ) [ line-comment ] newline )
comment = slash star * ( not-star / star not-slash ) 1* star slash
line-comment = slash slash * not-newline
; characters
tab = %x0009 ; U+0009 CHARACTER TABULATION (tab)
newline = %x000A ; U+000A LINE FEED (LF)
space = %x0020 ; U+0020 SPACE
star = %x002A ; U+002A ASTERISK (*)
slash = %x002F ; U+002F SOLIDUS (/)
not-newline = %x0000-0009 / %x000B-10FFFF
; a scalar value other than U+000A LINE FEED (LF)
not-star = %x0000-0029 / %x002B-10FFFF
; a scalar value other than U+002A ASTERISK (*)
not-slash = %x0000-002E / %x0030-10FFFF
; a scalar value other than U+002F SOLIDUS (/)
这相当于将元素的内容放在JavaScript注释中。
这一要求是对script
元素内容语法的早期限制的补充。
这允许作者在其文档中包含文档信息,例如许可信息或API信息,同时仍然引用外部脚本文件。语法受到限制,以免作者在提供src
属性时,意外包含看似有效的脚本。
< script src = "cool-effects.js" >
// create new instances using:
// var e = new Effect();
// start the effect using .play, stop using .stop:
// e.play();
// e.stop();
</ script >
script
元素和XSLT的交互本节为非规范性内容。
本规范未定义XSLT与script
元素的交互方式。然而,在没有其他规范实际定义的情况下,以下是基于现有实现的实现指南:
当<?xml-stylesheet?>
处理指令触发XSLT转换程序且浏览器实现直接到DOM的转换时,由XSLT处理器创建的script
元素需要正确设置其解析器文档,并按照文档顺序(除标记为defer
或async
的脚本外)立即运行,因为转换正在进行中。
XSLTProcessor
的transformToDocument()
方法将元素添加到具有空浏览上下文的Document
对象中,因此它们创建的任何script
元素需要在准备脚本元素算法中将其已启动设置为true,并且永远不会被执行(脚本被禁用)。不过,这些script
元素仍需要设置其解析器文档,以使其async
IDL属性在没有async
内容属性的情况下返回false。
XSLTProcessor
的transformToFragment()
方法需要创建一个等同于通过document.createElementNS()
手动创建元素而生成的片段。例如,它需要创建具有空解析器文档且其已启动设置为false的script
元素,以便在将片段插入文档时执行。
前两种情况与最后一种情况的主要区别在于,前两种情况操作的是Document
,而最后一种情况操作的是片段。
noscript
元素Support in all current engines.
head
元素中的HTML文档中,如果没有祖先noscript
元素。noscript
元素。head
元素中:按任何顺序,零个或多个link
元素,零个或多个style
元素,和零个或多个meta
元素。head
元素中:透明,但不能有noscript
元素的后代。HTMLElement
。如果启用了脚本,则noscript
元素不表示任何内容;如果禁用了脚本,则表示其子元素。它用于向支持脚本和不支持脚本的用户代理呈现不同的标记,从而影响文档的解析方式。
在HTML文档中使用时,允许的内容模型如下:
head
元素中,如果脚本被
禁用适用于noscript
元素
head
元素中,如果启用了脚本适用于noscript
元素
noscript
元素必须只包含文本,但调用HTML片段解析算法,将noscript
元素作为上下文元素,将文本内容作为input,必须生成一个仅包含link
、style
和meta
元素的节点列表,这些元素如果是noscript
元素的子元素则是符合规范的,并且没有解析错误。
head
元素之外,如果脚本被禁用适用于noscript
元素
noscript
元素的内容模型是透明的,但有一个额外的限制,即noscript
元素不能有noscript
元素的祖先(即noscript
不能嵌套)。
head
元素之外,如果启用了脚本适用于noscript
元素
noscript
元素必须只包含文本,但文本必须是运行以下算法生成的文档符合规范,没有noscript
元素和
元素,且算法的任何步骤都不会抛出异常或导致HTML解析器标记解析错误:
script
所有这些转变都是必要的,因为出于历史原因,noscript
元素的处理方式会根据解析器调用时是否启用了脚本而不同。
noscript
元素仅在HTML语法中有效,在XML语法中无效。这是因为它的工作原理是通过本质上“关闭”解析器来使脚本启用时将元素内容视为纯文本,而不是实际元素。XML没有定义这种机制。
noscript
元素没有其他要求。特别是,即使noscript
元素的子元素在元素启用了脚本时,它们也不豁免于表单提交、脚本等要求。
在下面的示例中,noscript
元素用于为脚本提供后备内容。
< form action = "calcSquare.php" >
< p >
< label for = x > Number</ label > :
< input id = "x" name = "x" type = "number" >
</ p >
< script >
var x = document. getElementById( 'x' );
var output = document. createElement( 'p' );
output. textContent = 'Type a number; it will be squared right then!' ;
x. form. appendChild( output);
x. form. onsubmit = function () { return false ; }
x. oninput = function () {
var v = x. valueAsNumber;
output. textContent = v + ' squared is ' + v * v;
};
</ script >
< noscript >
< input type = submit value = "Calculate Square" >
</ noscript >
</ form >
当脚本被禁用时,会出现一个按钮来在服务器端进行计算。当脚本被启用时,值会被即时计算。
noscript
元素是一种笨拙的工具。有时,脚本可能被启用,但由于某种原因页面的脚本可能会失败。因此,通常最好避免使用noscript
,而是设计脚本使其能够即时将页面从无脚本页面转换为有脚本页面,如下一个示例所示:
< form action = "calcSquare.php" >
< p >
< label for = x > Number</ label > :
< input id = "x" name = "x" type = "number" >
</ p >
< input id = "submit" type = submit value = "Calculate Square" >
< script >
var x = document. getElementById( 'x' );
var output = document. createElement( 'p' );
output. textContent = 'Type a number; it will be squared right then!' ;
x. form. appendChild( output);
x. form. onsubmit = function () { return false ; }
x. oninput = function () {
var v = x. valueAsNumber;
output. textContent = v + ' squared is ' + v * v;
};
var submit = document. getElementById( 'submit' );
submit. parentNode. removeChild( submit);
</ script >
</ form >
template
元素支持所有当前引擎。
支持所有当前引擎。
shadowrootmode
— 启用流式声明阴影根shadowrootdelegatesfocus
— 在声明阴影根上设置委派焦点shadowrootclonable
— 在声明阴影根上设置可克隆shadowrootserializable
— 在声明阴影根上设置可序列化[Exposed =Window ]
interface HTMLTemplateElement : HTMLElement {
[HTMLConstructor ] constructor ();
readonly attribute DocumentFragment content ;
[CEReactions ] attribute DOMString shadowRootMode ;
[CEReactions ] attribute boolean shadowRootDelegatesFocus ;
[CEReactions ] attribute boolean shadowRootClonable ;
[CEReactions ] attribute boolean shadowRootSerializable ;
};
template
元素用于声明可以通过脚本克隆和插入到文档中的HTML片段。
shadowrootmode
内容属性是枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
open |
open | template元素表示一个开放的声明性阴影根。 |
closed |
closed | template元素表示一个封闭的声明性阴影根。 |
shadowrootmode
属性的无效值默认和缺失值默认状态均为none状态。
shadowrootdelegatesfocus
内容属性是布尔属性。
shadowrootclonable
内容属性是布尔属性。
shadowrootserializable
内容属性是布尔属性。
template内容并不是template
元素的子节点。
由于DOM操作的结果,template
元素也可能包含文本
节点和元素节点;然而,拥有任何这些节点都违反了template
元素的内容模型,因为其内容模型定义为无。
例如,考虑以下文档:
<!doctype html>
< html lang = "en" >
< head >
< title > Homework</ title >
< body >
< template id = "template" >< p > Smile!</ p ></ template >
< script >
let num = 3 ;
const fragment = document. getElementById( 'template' ). content. cloneNode( true );
while ( num-- > 1 ) {
fragment. firstChild. before( fragment. firstChild. cloneNode( true ));
fragment. firstChild. textContent += fragment. lastChild. textContent;
}
document. body. appendChild( fragment);
</ script >
</ html >
template
元素中的 p
元素在
DOM 中 不是 template
的子元素;它是由 template
元素的 content
IDL 属性返回的 DocumentFragment
的子元素。
如果脚本调用 appendChild()
在 template
元素上,这会给 template
元素添加一个子元素(就像对任何其他元素一样);然而,这样做是违反 template
元素的内容模型的。
template.content
支持所有当前引擎。
返回模板内容(一个DocumentFragment
)。
每个template
元素都有一个关联的DocumentFragment
对象,这是它的模板内容。模板内容没有任何符合性要求。当创建一个template
元素时,用户代理必须运行以下步骤以建立模板内容:
让doc成为template
元素的节点文档的适当模板内容拥有文档。
创建一个DocumentFragment
对象,其节点文档是doc,并且宿主是template
元素。
将template
元素的模板内容设置为新创建的DocumentFragment
对象。
一个Document
doc的适当模板内容拥有文档是通过以下算法返回的Document
:
如果doc不是由该算法创建的Document
,则:
如果doc尚未有一个关联的惰性模板文档,则:
将doc设置为doc的关联的惰性模板文档。
因此,每个不是由该算法创建的Document
将获得一个单独的Document
作为其代理,用于拥有其所有template
元素的模板内容,以便它们不在浏览上下文中,从而保持惰性(例如脚本不会运行)。与此同时,位于由该算法创建的Document
对象内的template
元素将重用相同的Document
所有者用于其内容。
返回doc。
对于template
元素,采纳步骤(以node和oldDocument为参数)如下:
让doc成为node的节点文档的适当模板内容拥有文档。
采纳 node的模板内容(一个DocumentFragment
对象)到doc中。
content
getter步骤是返回template
的模板内容,如果模板内容不是一个ShadowRoot
节点;否则为null。
shadowRootMode
IDL属性必须反映shadowrootmode
内容属性,仅限于已知值。
shadowRootDelegatesFocus
IDL属性必须反映shadowrootdelegatesfocus
内容属性。
shadowRootClonable
IDL属性必须反映shadowrootclonable
内容属性。
shadowRootSerializable
IDL属性必须反映shadowrootserializable
内容属性。
对于正在克隆到副本copy的template
元素node,克隆步骤必须运行以下步骤:
如果在调用克隆算法中未设置clone children flag,则返回。
让copied contents成为node的模板内容的所有子节点的克隆结果,document设置为copy的模板内容的节点文档,并且设置clone children flag。
将copied contents附加到copy的模板内容。
在这个例子中,一个脚本使用一个template
来提供元素结构,而不是手动从标记中生成结构,从数据结构中填充一个四列表格的数据。
<!DOCTYPE html>
< html lang = 'en' >
< title > Cat data</ title >
< script >
// Data is hard-coded here, but could come from the server
var data = [
{ name: 'Pillar' , color: 'Ticked Tabby' , sex: 'Female (neutered)' , legs: 3 },
{ name: 'Hedral' , color: 'Tuxedo' , sex: 'Male (neutered)' , legs: 4 },
];
</ script >
< table >
< thead >
< tr >
< th > Name < th > Color < th > Sex < th > Legs
< tbody >
< template id = "row" >
< tr >< td >< td >< td >< td >
</ template >
</ table >
< script >
var template = document. querySelector( '#row' );
for ( var i = 0 ; i < data. length; i += 1 ) {
var cat = data[ i];
var clone = template. content. cloneNode( true );
var cells = clone. querySelectorAll( 'td' );
cells[ 0 ]. textContent = cat. name;
cells[ 1 ]. textContent = cat. color;
cells[ 2 ]. textContent = cat. sex;
cells[ 3 ]. textContent = cat. legs;
template. parentNode. appendChild( clone);
}
</ script >
This example uses cloneNode()
on the
template
's
contents; it could equivalently have used document.importNode()
,
which does the same thing. The
only difference between these two APIs is when the node document
is
updated: with
cloneNode()
it is updated when the nodes are appended
with appendChild()
,
with document.importNode()
it is updated when the nodes are
cloned.
template
元素与XSLT和XPath的交互本节非规范性。
本规范未定义XSLT和XPath与template
元素的交互方式。但是,在没有其他规范实际定义此内容的情况下,以下是一些针对实现者的指南,旨在与本规范中描述的其他处理方式保持一致:
基于XML解析器的XSLT处理器,如本规范所述,需要在转换过程中,template
元素内包含其template内容作为其后代元素。
输出DOM的XSLT处理器需要确保将本应放入template
元素中的节点放置到该元素的template内容中。
当使用XPath DOM API对使用本规范描述的HTML解析器或XML解析器解析的Document
进行XPath评估时,需要忽略template内容。
slot
元素Support in all current engines.
Support in all current engines.
name
—
shadow tree slot的名称[Exposed =Window ]
interface HTMLSlotElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString name ;
sequence <Node > assignedNodes (optional AssignedNodesOptions options = {});
sequence <Element > assignedElements (optional AssignedNodesOptions options = {});
undefined assign ((Element or Text )... nodes );
};
dictionary AssignedNodesOptions {
boolean flatten = false ;
};
slot
元素定义了一个slot。它通常用于shadow tree中。slot
元素表示其已分配的节点(如果有),否则表示其内容。
name
内容属性可以包含任何字符串值。它表示一个slot的name。
name
属性用于分配slot给其他元素:一个带有
slot
元素和一个name
属性的元素创建一个命名的slot,任何具有slot
属性且其值与name
属性值匹配的元素会被分配到该slot中,并且slot
元素是shadow
tree的子元素,该shadow tree的根的宿主具有相应的slot
属性值。
slot.name
Support in all current engines.
slot.assignedNodes()
Support in all current engines.
slot.assignedNodes({ flatten: true })
slot
元素进行递归处理,直到没有slot
元素为止。
slot.assignedElements()
HTMLSlotElement/assignedElements
Support in all current engines.
slot.assignedElements({ flatten: true })
assignedNodes({ flatten: true })
相同的结果,仅限于元素。
slot.assign(...nodes)
将slot的手动分配的节点设置为给定的nodes。
name
IDL属性必须反映相同名称的内容属性。
slot
元素有手动分配的节点,这是一个由assign()
设置的有序集合。该集合初始为空。
手动分配的节点集合可以使用对slottables的弱引用来实现,因为该集合不能直接从脚本访问。
assignedNodes(options)
方法步骤如下:
返回使用this进行查找扁平化的slottables的结果。
assignedElements(options)
方法步骤如下:
Support in all current engines.
assign(...nodes)
方法步骤如下:
将nodesSet设置为新的有序集合。
对每个 nodes的node:
为this的根运行为树分配slotables。
canvas
元素支持所有当前引擎。
支持所有当前引擎。
width
—
水平方向尺寸height
— 垂直方向尺寸typedef (CanvasRenderingContext2D or ImageBitmapRenderingContext or WebGLRenderingContext or WebGL2RenderingContext or GPUCanvasContext ) RenderingContext ;
[Exposed =Window ]
interface HTMLCanvasElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute unsigned long width ;
[CEReactions ] attribute unsigned long height ;
RenderingContext ? getContext (DOMString contextId , optional any options = null );
USVString toDataURL (optional DOMString type = "image/png", optional any quality );
undefined toBlob (BlobCallback _callback , optional DOMString type = "image/png", optional any quality );
OffscreenCanvas transferControlToOffscreen ();
};
callback BlobCallback = undefined (Blob ? blob );
canvas
元素为脚本提供了一个分辨率相关的位图画布,可用于动态渲染图表、游戏图形、艺术或其他视觉图像。
作者不应在有更合适的元素可用时在文档中使用canvas
元素。例如,用canvas
元素来渲染页面标题是不合适的:如果标题的预期呈现是图形密集型的,则应使用适当的元素(通常是h1
)进行标记,然后使用CSS和支持技术(如shadow树)进行样式化。
当作者使用canvas
元素时,他们还必须提供在呈现给用户时具有与canvas
的位图基本相同的功能或目的的内容。这些内容可以放置在canvas
元素的内容中。canvas
元素的内容(如果有)是元素的后备内容。
在交互式视觉媒体中,如果canvas
元素启用了脚本,并且启用了对canvas
元素的支持,那么canvas
元素表示由动态创建的图像组成的嵌入内容,即元素的位图。
在非交互式静态视觉媒体中,如果canvas
元素以前与渲染上下文相关联(例如,如果页面在交互式视觉媒体中查看,现在正在打印,或者在页面布局过程中运行的某些脚本在元素上绘制了内容),则canvas
元素表示其当前位图和大小的嵌入内容。否则,元素表示其后备内容。
在非视觉媒体中,以及在视觉媒体中,如果canvas
元素禁用了脚本或禁用了对canvas
元素的支持,则canvas
元素表示其后备内容。
当canvas
元素表示嵌入内容时,用户仍然可以聚焦canvas
元素的后代(在后备内容中)。当元素被聚焦时,它是键盘交互事件的目标(即使元素本身不可见)。这允许作者使交互式画布具有键盘无障碍性:作者应在后备内容中有一对一的映射到交互区域到可聚焦区域。(聚焦对鼠标交互事件没有影响。)[UIEVENTS]
元素的最近的canvas
元素祖先正在被渲染,并且表示嵌入内容的元素是一个被用作相关画布后备内容的元素。
canvas
元素有两个属性来控制元素位图的大小:width
和height
。这些属性在指定时必须具有有效的非负整数值。必须使用解析非负整数的规则来获得其数值。如果属性丢失,或解析其值返回错误,则必须使用默认值。width
属性默认为300,height
属性默认为150。
当设置width
或height
属性的值时,如果canvas
元素的上下文模式设置为占位符,用户代理必须抛出DOMException
并保留属性值不变。
当canvas
元素表示嵌入内容时,其自然尺寸等于元素位图的尺寸。
用户代理必须使用由每个坐标空间单位对应一个图像数据像素组成的方形像素密度来处理canvas
的位图及其渲染上下文。
canvas
元素可以通过样式表任意调整大小,其位图随后将受'object-fit' CSS属性的影响。
canvas
元素的位图、ImageBitmap
对象的位图,以及渲染上下文的某些位图(如下面关于CanvasRenderingContext2D
和ImageBitmapRenderingContext
对象的部分所述),具有可以设置为true或false的origin-clean标志。最初,当创建canvas
元素或ImageBitmap
对象时,其位图的origin-clean标志必须设置为true。
canvas
元素可以绑定渲染上下文。最初,它没有绑定的渲染上下文。为了跟踪是否具有渲染上下文以及是什么类型的渲染上下文,canvas
还具有一个画布上下文模式,最初为none,但可以通过本规范中定义的算法更改为占位符、2d、bitmaprenderer、webgl、webgl2或webgpu。
当其画布上下文模式为none时,canvas
元素没有渲染上下文,其位图必须是透明黑色,自然宽度等于元素的数值,即元素的width
属性和自然高度等于元素的height
属性的数值,这些值在设置、更改或删除属性时以CSS像素为单位解释并更新。
当其画布上下文模式为占位符时,canvas
元素没有渲染上下文。它作为OffscreenCanvas对象的占位符,并且canvas
元素的内容由OffscreenCanvas
对象的渲染上下文更新。
当canvas
元素表示嵌入内容时,它提供了一个绘画源,其宽度是元素的自然宽度,其高度是元素的自然高度,其外观是元素的位图。
每当width
和height
内容属性被设置、移除、改变或冗余设置为它们已经有的值时,用户代理必须执行以下表中对应于canvas
元素的上下文模式的操作。
操作 |
|
---|---|
按照WebGL规范中定义的行为进行。[WEBGL] |
|
按照WebGPU中定义的行为进行。[WEBGPU] |
|
如果上下文的位图模式设置为空白,运行步骤设置 |
|
什么也不做。 |
|
什么也不做。 |
支持所有当前引擎。
支持所有当前引擎。
width
和height
IDL属性必须反映同名的相应内容属性,并具有相同的默认值。
context = canvas.getContext(contextId [, options ])
Support in all current engines.
返回一个在画布上绘图的API对象。contextId指定所需的API:“2d
”,
“bitmaprenderer
”,
“webgl
”,
“webgl2
”,
或“webgpu
”。
options由该API处理。
本规范定义了“2d
”
和“bitmaprenderer
”
上下文。WebGL规范定义了“webgl
”
和“webgl2
”
上下文。WebGPU定义了“webgpu
”
上下文。[WEBGL] [WEBGPU]
如果contextId不支持,或者如果画布已经初始化了其他类型的上下文(例如,在获取“2d
”
上下文后尝试获取“webgl
”
上下文),则返回null。
getContext(contextId, options)
是canvas
元素的方法,当调用时,必须执行以下步骤:
如果options不是对象,则将options设置为null。
将options设置为转换 options为JavaScript值的结果。
运行下表中列标题与此canvas
元素的画布上下文模式匹配且行标题与contextId匹配的单元格中的步骤:
无 | 2d | bitmaprenderer | webgl或webgl2 | webgpu | 占位符 | |
---|---|---|---|---|---|---|
"2d "
|
返回上次用相同的第一个参数调用此方法时返回的相同对象。 | 返回null。 | 返回null。 | 返回null。 |
抛出一个“InvalidStateError ” DOMException 。
|
|
"bitmaprenderer "
|
|
返回null。 | 返回上次用相同的第一个参数调用此方法时返回的相同对象。 | 返回null。 | 返回null。 |
抛出一个“InvalidStateError ” DOMException 。
|
"webgl " 或 "webgl2 ",如果用户代理在其当前配置中支持WebGL功能
|
返回null。 | 返回null。 | 返回上次用相同的第一个参数调用此方法时返回的相同对象。 | 返回null。 |
抛出一个“InvalidStateError ” DOMException 。
|
|
"webgpu ",如果用户
代理在其当前配置中支持WebGPU功能
|
返回null。 | 返回null。 | 返回null。 | 返回上次用相同的第一个参数调用此方法时返回的相同对象。 |
抛出一个“InvalidStateError ” DOMException 。
|
|
不支持的值* | 返回null。 | 返回null。 | 返回null。 | 返回null。 | 返回null。 |
抛出一个“InvalidStateError ” DOMException 。
|
url = canvas.toDataURL([ type [, quality ] ])
Support in all current engines.
返回画布中的图像的data:
URL。
第一个参数(如果提供)控制要返回的图像类型(例如PNG或JPEG)。默认值为"image/png
";
如果给定的类型不受支持,也会使用该类型。第二个参数适用于支持可变质量的图像格式(例如"image/jpeg
"),
是一个范围在0.0到1.0之间的数字,表示所需的图像质量级别。
当尝试使用"image/png
"以外的类型时,
作者可以通过检查返回的字符串是否以"data:image/png,
"或"data:image/png;
"之一开头来检查图像是否真的是以请求的格式返回的。如果是,
则图像是PNG,因此请求的类型不受支持。(唯一的例外是如果画布的高度或宽度为零,则结果可能只是"data:,
"。)
canvas.toBlob(callback [, type [, quality ] ])
Support in all current engines.
创建一个表示画布中图像的Blob
对象,
并使用该对象的句柄调用回调。
第二个参数(如果提供)控制要返回的图像类型(例如PNG或JPEG)。默认值为"image/png
";
如果给定的类型不受支持,也会使用该类型。第三个参数适用于支持可变质量的图像格式(例如"image/jpeg
"),
是一个范围在0.0到1.0之间的数字,表示所需的图像质量级别。
canvas.transferControlToOffscreen()
HTMLCanvasElement/transferControlToOffscreen
Support in all current engines.
返回一个新创建的OffscreenCanvas
对象,该对象使用
canvas
元素作为占位符。一旦canvas
元素变成
OffscreenCanvas
对象的占位符,它的自然大小就不能再改变,并且不能有渲染上下文。占位符画布的内容在
OffscreenCanvas
的
相关代理的事件循环的更新渲染
步骤中更新。
toDataURL(type, quality)
方法,
调用时,必须运行以下步骤:
如果这个canvas
元素的位图的origin-clean标志被设置为false,则抛出
“SecurityError
” DOMException
。
如果这个canvas
元素的位图没有像素(即它的水平尺寸或垂直尺寸为零),则返回字符串"data:,
"。(这是最短的
data:
URL;它表示一个text/plain
资源中的空字符串。)
让file成为该canvas
元素位图作为文件的序列化,
如果给定,则传递type和quality。
如果file为null,则返回"data:,
"。
toBlob(callback, type,
quality)
方法,调用时,必须运行以下步骤:
如果这个canvas
元素的位图的origin-clean标志被设置为false,则抛出
“SecurityError
” DOMException
。
让result为null。
如果这个canvas
元素的位图有像素(即,它的水平尺寸和垂直尺寸都不是零),则将result设置为这个
canvas
元素位图的副本。
并行运行这些步骤:
如果result非null,则将result设置为将result序列化为文件, 并给出type和quality(如果提供)。
在
画布blob序列化任务源上队列一个元素任务,给定canvas
元素,运行这些步骤:
transferControlToOffscreen()
方法,调用时,必须运行以下步骤:
如果这个canvas
元素的context
mode未设置为none,则抛出
“InvalidStateError
” DOMException
。
让offscreenCanvas成为一个新的OffscreenCanvas
对象,
它的宽度和高度等于这个width
和height
内容属性的值
canvas
元素。
将这个offscreenCanvas的占位符canvas
元素设置为对这个canvas
元素的弱引用。
将这个canvas
元素的context
mode设置为placeholder。
返回offscreenCanvas。
所有当前引擎均支持。
所有当前引擎均支持。
所有当前引擎均支持。
所有当前引擎均支持。
所有当前引擎均支持。
typedef (HTMLImageElement or
SVGImageElement ) HTMLOrSVGImageElement ;
typedef (HTMLOrSVGImageElement or
HTMLVideoElement or
HTMLCanvasElement or
ImageBitmap or
OffscreenCanvas or
VideoFrame ) CanvasImageSource ;
enum PredefinedColorSpace { " srgb " , " display-p3 " };
enum CanvasFillRule { " nonzero " , " evenodd " };
dictionary CanvasRenderingContext2DSettings {
boolean alpha = true ;
boolean desynchronized = false ;
PredefinedColorSpace colorSpace = "srgb";
boolean willReadFrequently = false ;
};
enum ImageSmoothingQuality { " low " , " medium " , " high " };
[Exposed =Window ]
interface CanvasRenderingContext2D {
// back-reference to the canvas
readonly attribute HTMLCanvasElement canvas ;
CanvasRenderingContext2DSettings getContextAttributes ();
};
CanvasRenderingContext2D includes CanvasState ;
CanvasRenderingContext2D includes CanvasTransform ;
CanvasRenderingContext2D includes CanvasCompositing ;
CanvasRenderingContext2D includes CanvasImageSmoothing ;
CanvasRenderingContext2D includes CanvasFillStrokeStyles ;
CanvasRenderingContext2D includes CanvasShadowStyles ;
CanvasRenderingContext2D includes CanvasFilters ;
CanvasRenderingContext2D includes CanvasRect ;
CanvasRenderingContext2D includes CanvasDrawPath ;
CanvasRenderingContext2D includes CanvasUserInterface ;
CanvasRenderingContext2D includes CanvasText ;
CanvasRenderingContext2D includes CanvasDrawImage ;
CanvasRenderingContext2D includes CanvasImageData ;
CanvasRenderingContext2D includes CanvasPathDrawingStyles ;
CanvasRenderingContext2D includes CanvasTextDrawingStyles ;
CanvasRenderingContext2D includes CanvasPath ;
interface mixin CanvasState {
// state
undefined save (); // push state on state stack
undefined restore (); // pop state stack and restore state
undefined reset (); // reset the rendering context to its default state
boolean isContextLost (); // return whether context is lost
};
interface mixin CanvasTransform {
// transformations (default transform is the identity matrix)
undefined scale (unrestricted double x , unrestricted double y );
undefined rotate (unrestricted double angle );
undefined translate (unrestricted double x , unrestricted double y );
undefined transform (unrestricted double a , unrestricted double b , unrestricted double c , unrestricted double d , unrestricted double e , unrestricted double f );
[NewObject ] DOMMatrix getTransform ();
undefined setTransform (unrestricted double a , unrestricted double b , unrestricted double c , unrestricted double d , unrestricted double e , unrestricted double f );
undefined setTransform (optional DOMMatrix2DInit transform = {});
undefined resetTransform ();
};
interface mixin CanvasCompositing {
// compositing
attribute unrestricted double globalAlpha ; // (default 1.0)
attribute DOMString globalCompositeOperation ; // (default "source-over")
};
interface mixin CanvasImageSmoothing {
// image smoothing
attribute boolean imageSmoothingEnabled ; // (default true)
attribute ImageSmoothingQuality imageSmoothingQuality ; // (default low)
};
interface mixin CanvasFillStrokeStyles {
// colors and styles (see also the CanvasPathDrawingStyles and CanvasTextDrawingStyles interfaces)
attribute (DOMString or CanvasGradient or CanvasPattern ) strokeStyle ; // (default black)
attribute (DOMString or CanvasGradient or CanvasPattern ) fillStyle ; // (default black)
CanvasGradient createLinearGradient (double x0 , double y0 , double x1 , double y1 );
CanvasGradient createRadialGradient (double x0 , double y0 , double r0 , double x1 , double y1 , double r1 );
CanvasGradient createConicGradient (double startAngle , double x , double y );
CanvasPattern ? createPattern (CanvasImageSource image , [LegacyNullToEmptyString ] DOMString repetition );
};
interface mixin CanvasShadowStyles {
// shadows
attribute unrestricted double shadowOffsetX ; // (default 0)
attribute unrestricted double shadowOffsetY ; // (default 0)
attribute unrestricted double shadowBlur ; // (default 0)
attribute DOMString shadowColor ; // (default transparent black)
};
interface mixin CanvasFilters {
// filters
attribute DOMString filter ; // (default "none")
};
interface mixin CanvasRect {
// rects
undefined clearRect (unrestricted double x , unrestricted double y , unrestricted double w , unrestricted double h );
undefined fillRect (unrestricted double x , unrestricted double y , unrestricted double w , unrestricted double h );
undefined strokeRect (unrestricted double x , unrestricted double y , unrestricted double w , unrestricted double h );
};
interface mixin CanvasDrawPath {
// path API (see also CanvasPath)
undefined beginPath ();
undefined fill (optional CanvasFillRule fillRule = "nonzero");
undefined fill (Path2D path , optional CanvasFillRule fillRule = "nonzero");
undefined stroke ();
undefined stroke (Path2D path );
undefined clip (optional CanvasFillRule fillRule = "nonzero");
undefined clip (Path2D path , optional CanvasFillRule fillRule = "nonzero");
boolean isPointInPath (unrestricted double x , unrestricted double y , optional CanvasFillRule fillRule = "nonzero");
boolean isPointInPath (Path2D path , unrestricted double x , unrestricted double y , optional CanvasFillRule fillRule = "nonzero");
boolean isPointInStroke (unrestricted double x , unrestricted double y );
boolean isPointInStroke (Path2D path , unrestricted double x , unrestricted double y );
};
interface mixin CanvasUserInterface {
undefined drawFocusIfNeeded (Element element );
undefined drawFocusIfNeeded (Path2D path , Element element );
};
interface mixin CanvasText {
// text (see also the CanvasPathDrawingStyles and CanvasTextDrawingStyles interfaces)
undefined fillText (DOMString text , unrestricted double x , unrestricted double y , optional unrestricted double maxWidth );
undefined strokeText (DOMString text , unrestricted double x , unrestricted double y , optional unrestricted double maxWidth );
TextMetrics measureText (DOMString text );
};
interface mixin CanvasDrawImage {
// drawing images
undefined drawImage (CanvasImageSource image , unrestricted double dx , unrestricted double dy );
undefined drawImage (CanvasImageSource image , unrestricted double dx , unrestricted double dy , unrestricted double dw , unrestricted double dh );
undefined drawImage (CanvasImageSource image , unrestricted double sx , unrestricted double sy , unrestricted double sw , unrestricted double sh , unrestricted double dx , unrestricted double dy , unrestricted double dw , unrestricted double dh );
};
interface mixin CanvasImageData {
// pixel manipulation
ImageData createImageData ([EnforceRange ] long sw , [EnforceRange ] long sh , optional ImageDataSettings settings = {});
ImageData createImageData (ImageData imagedata );
ImageData getImageData ([EnforceRange ] long sx , [EnforceRange ] long sy , [EnforceRange ] long sw , [EnforceRange ] long sh , optional ImageDataSettings settings = {});
undefined putImageData (ImageData imagedata , [EnforceRange ] long dx , [EnforceRange ] long dy );
undefined putImageData (ImageData imagedata , [EnforceRange ] long dx , [EnforceRange ] long dy , [EnforceRange ] long dirtyX , [EnforceRange ] long dirtyY , [EnforceRange ] long dirtyWidth , [EnforceRange ] long dirtyHeight );
};
enum CanvasLineCap { "butt" , "round" , "square" };
enum CanvasLineJoin { "round" , "bevel" , "miter" };
enum CanvasTextAlign { " start " , " end " , " left " , " right " , " center " };
enum CanvasTextBaseline { " top " , " hanging " , " middle " , " alphabetic " , " ideographic " , " bottom " };
enum CanvasDirection { " ltr " , " rtl " , " inherit " };
enum CanvasFontKerning { " auto " , " normal " , " none " };
enum CanvasFontStretch { " ultra-condensed " , " extra-condensed " , " condensed " , " semi-condensed " , " normal " , " semi-expanded " , " expanded " , " extra-expanded " , " ultra-expanded " };
enum CanvasFontVariantCaps { " normal " , " small-caps " , " all-small-caps " , " petite-caps " , " all-petite-caps " , " unicase " , " titling-caps " };
enum CanvasTextRendering { " auto " , " optimizeSpeed " , " optimizeLegibility " , " geometricPrecision " };
interface mixin CanvasPathDrawingStyles {
// line caps/joins
attribute unrestricted double lineWidth ; // (default 1)
attribute CanvasLineCap lineCap ; // (default "butt")
attribute CanvasLineJoin lineJoin ; // (default "miter")
attribute unrestricted double miterLimit ; // (default 10)
// dashed lines
undefined setLineDash (sequence <unrestricted double > segments ); // default empty
sequence <unrestricted double > getLineDash ();
attribute unrestricted double lineDashOffset ;
};
interface mixin CanvasTextDrawingStyles {
// text
attribute DOMString font ; // (default 10px sans-serif)
attribute CanvasTextAlign textAlign ; // (default: "start")
attribute CanvasTextBaseline textBaseline ; // (default: "alphabetic")
attribute CanvasDirection direction ; // (default: "inherit")
attribute DOMString letterSpacing ; // (default: "0px")
attribute CanvasFontKerning fontKerning ; // (default: "auto")
attribute CanvasFontStretch fontStretch ; // (default: "normal")
attribute CanvasFontVariantCaps fontVariantCaps ; // (default: "normal")
attribute CanvasTextRendering textRendering ; // (default: "auto")
attribute DOMString wordSpacing ; // (default: "0px")
};
interface mixin CanvasPath {
// shared path API methods
undefined closePath ();
undefined moveTo (unrestricted double x , unrestricted double y );
undefined lineTo (unrestricted double x , unrestricted double y );
undefined quadraticCurveTo (unrestricted double cpx , unrestricted double cpy , unrestricted double x , unrestricted double y );
undefined bezierCurveTo (unrestricted double cp1x , unrestricted double cp1y , unrestricted double cp2x , unrestricted double cp2y , unrestricted double x , unrestricted double y );
undefined arcTo (unrestricted double x1 , unrestricted double y1 , unrestricted double x2 , unrestricted double y2 , unrestricted double radius );
undefined rect (unrestricted double x , unrestricted double y , unrestricted double w , unrestricted double h );
undefined roundRect (unrestricted double x , unrestricted double y , unrestricted double w , unrestricted double h , optional (unrestricted double or DOMPointInit or sequence <(unrestricted double or DOMPointInit )>) radii = 0);
undefined arc (unrestricted double x , unrestricted double y , unrestricted double radius , unrestricted double startAngle , unrestricted double endAngle , optional boolean counterclockwise = false );
undefined ellipse (unrestricted double x , unrestricted double y , unrestricted double radiusX , unrestricted double radiusY , unrestricted double rotation , unrestricted double startAngle , unrestricted double endAngle , optional boolean counterclockwise = false );
};
[Exposed =(Window ,Worker )]
interface CanvasGradient {
// opaque object
undefined addColorStop (double offset , DOMString color );
};
[Exposed =(Window ,Worker )]
interface CanvasPattern {
// opaque object
undefined setTransform (optional DOMMatrix2DInit transform = {});
};
[Exposed =(Window ,Worker )]
interface TextMetrics {
// x-direction
readonly attribute double width ; // advance width
readonly attribute double actualBoundingBoxLeft ;
readonly attribute double actualBoundingBoxRight ;
// y-direction
readonly attribute double fontBoundingBoxAscent ;
readonly attribute double fontBoundingBoxDescent ;
readonly attribute double actualBoundingBoxAscent ;
readonly attribute double actualBoundingBoxDescent ;
readonly attribute double emHeightAscent ;
readonly attribute double emHeightDescent ;
readonly attribute double hangingBaseline ;
readonly attribute double alphabeticBaseline ;
readonly attribute double ideographicBaseline ;
};
dictionary ImageDataSettings {
PredefinedColorSpace colorSpace ;
};
[Exposed =(Window ,Worker ),
Serializable ]
interface ImageData {
constructor (unsigned long sw , unsigned long sh , optional ImageDataSettings settings = {});
constructor (Uint8ClampedArray data , unsigned long sw , optional unsigned long sh , optional ImageDataSettings settings = {});
readonly attribute unsigned long width ;
readonly attribute unsigned long height ;
readonly attribute Uint8ClampedArray data ;
readonly attribute PredefinedColorSpace colorSpace ;
};
[Exposed =(Window ,Worker )]
interface Path2D {
constructor (optional (Path2D or DOMString ) path );
undefined addPath (Path2D path , optional DOMMatrix2DInit transform = {});
};
Path2D includes CanvasPath ;
为了与现有的 Web 内容保持兼容,用户代理需要在CanvasUserInterface
定义的方法后立即在stroke()
方法之后枚举CanvasRenderingContext2D
对象的方法。
context = canvas.getContext('2d' [, { [ alpha: true ] [, desynchronized: false ] [, colorSpace: 'srgb'] [, willReadFrequently: false ]} ])
返回一个CanvasRenderingContext2D
对象,该对象永久绑定到特定的canvas
元素。
如果alpha
成员为false,则上下文将被强制始终不透明。
如果desynchronized
成员为true,则上下文可能是去同步的。
colorSpace
成员指定渲染上下文的色彩空间。
如果willReadFrequently
成员为true,则上下文将被标记为读取优化。
context.canvas
CanvasRenderingContext2D/canvas
所有当前引擎均支持。
返回canvas
元素。
attributes = context.getContextAttributes()
返回一个对象,其:
alpha
成员为true表示上下文具有alpha通道,为false表示强制其不透明。
desynchronized
成员为true表示上下文可以是去同步的。colorSpace
成员是一个字符串,表示上下文的色彩空间。willReadFrequently
成员为true表示上下文被标记为读取优化。
CanvasRenderingContext2D
对象具有在对象创建时初始化的输出位图。
输出位图具有一个可以设置为true或false的origin-clean标志。初始时,当创建这些位图之一时,其origin-clean标志必须设置为true。
CanvasRenderingContext2D
对象还具有一个alpha布尔值。当CanvasRenderingContext2D
对象的alpha为false时,其alpha通道必须为1.0(完全不透明),对任何像素alpha组件的更改尝试必须被静默忽略。
因此,这种上下文的位图从一开始就是不透明黑色,而不是透明黑色;clearRect()
总是产生不透明黑色像素,每四个字节中的一个从getImageData()
总是255,putImageData()
方法有效地忽略其输入中的每四个字节,等等。然而,绘制到画布上的样式和图像的alpha组件仍然会影响输出位图
的alpha通道;例如,在新创建的输出位图
上绘制一个50%透明的白色方块,其alpha设置为false将导致完全不透明的灰色方块。
CanvasRenderingContext2D
对象还具有一个去同步布尔值。当CanvasRenderingContext2D
对象的去同步为true时,用户代理可以优化画布的渲染,以减少从输入事件到光栅化的延迟,通过将画布绘制周期与事件循环去同步,绕过普通的用户代理渲染算法,或两者兼有。由于这种模式涉及绕过通常的绘制机制、光栅化或两者兼有,可能会引入可见的撕裂伪影。
用户代理通常在一个不显示的缓冲区上进行渲染,快速交换它和用于呈现的缓冲区;前者称为后缓冲区,后者称为前缓冲区。一种减少延迟的流行技术称为前缓冲渲染,也称为单缓冲渲染,其中渲染过程与扫描过程并行并具有竞争性。这种技术通过可能引入撕裂伪影来减少延迟,可以完全或部分实现去同步布尔值。[MULTIPLEBUFFERING]
去同步布尔值在实现某些类型的应用程序(如绘图应用程序)时很有用,其中输入和光栅化之间的延迟至关重要。
CanvasRenderingContext2D
对象还具有一个将频繁读取布尔值。当CanvasRenderingContext2D
对象的将频繁读取为true时,用户代理可以优化画布以进行读取操作。
在大多数设备上,用户代理需要决定是将画布的输出位图存储在GPU上(这也称为“硬件加速”),还是存储在CPU上(也称为“软件”)。大多数渲染操作对于加速画布更高效,主要例外是通过getImageData()
、toDataURL()
或toBlob()
进行读取操作。CanvasRenderingContext2D
对象的将频繁读取为true告知用户代理网页可能会执行许多读取操作,并且使用软件画布更有利。
CanvasRenderingContext2D
对象还具有类型为PredefinedColorSpace
的色彩空间设置。CanvasRenderingContext2D
对象的色彩空间表示输出位图的色彩空间。
getContextAttributes()
方法的步骤是返回«[ "alpha
"
→ this的alpha, "desynchronized
"
→ this的去同步, "colorSpace
"
→ this的色彩空间,
"willReadFrequently
"
→ this的将频繁读取 ]»。
CanvasRenderingContext2D
2D渲染上下文表示一个平面线性笛卡尔平面,其原点(0,0)位于左上角,坐标空间中x值向右增加,y值向下增加。右边缘的x坐标等于渲染上下文的输出位图的宽度,以CSS像素为单位;同样,底边缘的y坐标等于渲染上下文的输出位图的高度,以CSS像素为单位。
坐标空间的大小不一定表示用户代理在内部或渲染期间使用的实际位图的大小。例如,在高分辨率显示器上,用户代理可能在内部使用每个坐标空间单位四个设备像素的位图,以便在整个过程中保持高质量。同样,抗锯齿可以使用分辨率比最终显示图像更高的位图进行过采样来实现。
使用CSS像素描述渲染上下文的输出位图的大小并不意味着在渲染时画布将覆盖相当于CSS像素的区域。CSS像素的使用是为了方便与CSS功能(如文本布局)的集成。
换句话说,下面的canvas
元素的渲染上下文具有200x200的输出位图(内部使用CSS像素作为单位,以便于与CSS集成),并且以100x100CSS像素进行渲染:
< canvas width = 200 height = 200 style = width:100px;height:100px >
2D上下文创建算法,传递一个target(一个canvas
元素)和options,其步骤如下:
将settings设置为将options转换为字典类型CanvasRenderingContext2DSettings
的结果。(这可能会引发异常)。
将context设置为一个新的CanvasRenderingContext2D
对象。
初始化context的canvas
属性以指向target。
将context的输出位图设置为与target的位图相同(因此它们是共享的)。
将context的alpha设置为settings["alpha
"]。
将context的去同步设置为settings["desynchronized
"]。
将context的色彩空间设置为settings["colorSpace
"]。
将context的将频繁读取设置为settings["willReadFrequently
"]。
返回context。
当用户代理需要设置位图尺寸为width和height时,必须运行以下步骤:
将输出位图调整为新width和height。
如果canvas的width
内容属性的数字值与width不同,则将canvas的width
内容属性设置为表示width的最短可能字符串,作为有效非负整数。
如果canvas的height
内容属性的数字值与height不同,则将canvas的height
内容属性设置为表示height的最短可能字符串,作为有效非负整数。
在以下示例中,似乎只绘制了一个方块:
// canvas is a reference to a <canvas> element
var context = canvas. getContext( '2d' );
context. fillRect( 0 , 0 , 50 , 50 );
canvas. setAttribute( 'width' , '300' ); // clears the canvas
context. fillRect( 0 , 100 , 50 , 50 );
canvas. width = canvas. width; // clears the canvas
context. fillRect( 100 , 0 , 50 , 50 ); // only this square remains
canvas
属性必须返回对象创建时初始化的值。
"srgb
" 值表示 'srgb' 颜色空间。
"display-p3
" 值表示 'display-p3' 颜色空间。
转换颜色空间的算法可以在CSS Color的颜色转换部分找到。[CSSCOLOR]
CanvasFillRule
枚举用于选择填充规则算法,以确定一个点是在路径内部还是外部。
值 "nonzero
"
表示非零环绕规则,其中一个点被认为在形状外部,如果从该点绘制的一条半无限直线穿过形状路径的次数在一个方向上与在另一个方向上穿过路径的次数相等。
"evenodd
" 值表示奇偶规则,其中一个点被认为在形状外部,如果从该点绘制的一条半无限直线穿过形状路径的次数为偶数。
如果一个点不在形状外部,则它在形状内部。
ImageSmoothingQuality
枚举用于表达对平滑图像时使用的插值质量的偏好。
值 "low
" 表示对低水平图像插值质量的偏好。低质量图像插值可能比更高设置更有效。
值 "medium
" 表示对中等水平图像插值质量的偏好。
值 "high
" 表示对高水平图像插值质量的偏好。高质量图像插值可能比较低设置更耗费计算资源。
双线性缩放是一个相对较快的低质量图像平滑算法的例子。双三次或Lanczos缩放是生成高质量输出的图像平滑算法的例子。本规范并不强制要求使用特定的插值算法。
本节为非规范性内容。
输出位图,当它不是由用户代理直接显示时,实现可以不更新此位图,而只是记住已应用于它的绘图操作序列,直到需要位图的实际数据(例如因为调用了drawImage()
或createImageBitmap()
工厂方法)。在许多情况下,这将更具内存效率。
canvas
元素的位图是几乎总是会在实践中需要的位图。当渲染上下文有输出位图时,它总是只是一个canvas
元素位图的别名。
有时需要额外的位图,例如,当画布以不同于其自然尺寸的大小被绘制时,以启用快速绘图,或为了实现双重缓冲,以便在执行画布绘图命令时,图形更新(例如页面滚动)可以同时处理。
实现CanvasState
接口的对象维护一个绘图状态堆栈。绘图状态包括:
当前的变换矩阵。
当前的剪辑区域。
以下属性的当前值:lineWidth
,lineCap
,lineJoin
,miterLimit
,lineDashOffset
,shadowOffsetX
,shadowOffsetY
,shadowBlur
,font
,textAlign
,textBaseline
,direction
,fontKerning
,fontStretch
,fontVariantCaps
,textRendering
,imageSmoothingEnabled
,imageSmoothingQuality
。
当前的虚线列表。
渲染上下文的位图不是绘图状态的一部分,因为它们取决于渲染上下文是否以及如何绑定到canvas
元素。
实现CanvasState
混入的对象具有一个上下文丢失布尔值,该值在对象创建时初始化为false。上下文丢失值在上下文丢失步骤中更新。
context.save()
Support in all current engines.
将当前状态推送到堆栈。
context.restore()
CanvasRenderingContext2D/restore
Support in all current engines.
弹出堆栈顶部的状态,恢复上下文到该状态。
context.reset()
重置渲染上下文,包括后备缓冲区、绘图状态堆栈、路径和样式。
context.isContextLost()
如果渲染上下文丢失,则返回true。上下文丢失可能由于驱动程序崩溃、内存不足等原因发生。在这些情况下,画布会丢失其后备存储,并采取措施将渲染上下文重置为默认状态。
save()
方法步骤是将当前绘图状态的副本推送到绘图状态堆栈。
restore()
方法步骤是弹出绘图状态堆栈顶部的条目,并重置其描述的绘图状态。如果没有保存的状态,则该方法必须不执行任何操作。
CanvasRenderingContext2D/reset
OffscreenCanvasRenderingContext2D#canvasrenderingcontext2d.reset
reset()
方法步骤是将渲染上下文重置为默认状态。
要将渲染上下文重置为默认状态:
CanvasRenderingContext2D/isContextLost
Support in one engine only.
isContextLost()
方法步骤是返回this的上下文丢失。
context.lineWidth [ = value ]
CanvasRenderingContext2D/lineWidth
Support in all current engines.
styles.lineWidth [ = value ]
返回当前的线宽。
可以设置以改变线宽。非有限值大于零的值将被忽略。
context.lineCap [ = value ]
CanvasRenderingContext2D/lineCap
Support in all current engines.
styles.lineCap [ = value ]
返回当前的线端点样式。
可以设置以改变线端点样式。
可能的线端点样式有 "butt
","round
",和 "square
"。其他值将被忽略。
context.lineJoin [ = value ]
CanvasRenderingContext2D/lineJoin
Support in all current engines.
styles.lineJoin [ = value ]
返回当前的线连接样式。
可以设置以改变线连接样式。
可能的线
连接样式有 "bevel
","round
",和 "miter
"。其他值将被忽略。
context.miterLimit [ = value ]
CanvasRenderingContext2D/miterLimit
Support in all current engines.
styles.miterLimit [ = value ]
返回当前的斜接限制比率。
可以设置以改变斜接限制比率。非有限值大于零的值将被忽略。
context.setLineDash(segments)
CanvasRenderingContext2D/setLineDash
Support in all current engines.
styles.setLineDash(segments)
设置当前的线条虚线模式(用于描边)。参数是一个距离列表,表示线条开和关的交替长度。
segments = context.getLineDash()
CanvasRenderingContext2D/getLineDash
Support in all current engines.
segments = styles.getLineDash()
返回当前线条虚线模式的副本。返回的数组总是有偶数个条目(即模式被规范化)。
context.lineDashOffset
CanvasRenderingContext2D/lineDashOffset
Support in all current engines.
styles.lineDashOffset
返回相位偏移(与线条虚线模式的单位相同)。
可以设置以改变相位偏移。非有限值将被忽略。
实现 CanvasPathDrawingStyles
接口的对象有控制如何处理线条的属性和方法(在本节中定义)。
lineWidth
属性给出线条的宽度(以坐标空间单位表示)。获取时,必须返回当前值。设置时,零、负值、无穷大和 NaN
值必须被忽略,使值保持不变;其他值必须将当前值更改为新值。
创建实现 CanvasPathDrawingStyles
接口的对象时,lineWidth
属性最初的值必须为 1.0。
lineCap
属性定义用户代理在线条端点放置的结束样式。三个有效值为
"butt
","round
" 和 "square
"。
获取时,必须返回当前值。设置时,当前值必须更改为新值。
创建实现 CanvasPathDrawingStyles
接口的对象时,lineCap
属性最初的值必须为 "butt
"。
lineJoin
属性定义用户代理在线条交汇处放置的角落样式。三个有效值为
"bevel
","round
" 和 "miter
"。
获取时,必须返回当前值。设置时,当前值必须更改为新值。
创建实现 CanvasPathDrawingStyles
接口的对象时,lineJoin
属性最初的值必须为 "miter
"。
当 lineJoin
属性值为 "miter
" 时,描边使用斜接限制比率来决定如何渲染连接。斜接限制比率可以通过 miterLimit
属性明确设置。获取时,必须返回当前值。设置时,零、负值、无穷大和 NaN 值必须被忽略,使值保持不变;其他值必须将当前值更改为新值。
创建实现 CanvasPathDrawingStyles
接口的对象时,miterLimit
属性最初的值必须为 10.0。
每个 CanvasPathDrawingStyles
对象都有一个 虚线列表,该列表为空或包含偶数个非负数。最初,虚线列表
必须为空。
setLineDash(segments)
方法在调用时,必须执行以下步骤:
如果 segments 中的任何值不是有限的(例如,无穷大或 NaN 值),或者任何值为负(小于零),则返回(不抛出异常;用户代理可以在开发者控制台显示消息,因为这对调试有帮助)。
如果 segments 中的元素数目为奇数,则让 segments 为 segments 的两个副本的串联。
让对象的 虚线列表 为 segments。
当调用 getLineDash()
方法时,必须返回一个序列,其值为对象的 虚线列表 的值,顺序相同。
有时更改虚线图案的“相位”是有用的,例如实现“行军蚂蚁”效果。相位可以通过 lineDashOffset
属性设置。获取时,必须返回当前值。设置时,非有限值和 NaN 值必须被忽略,使值保持不变;其他值必须将当前值更改为新值。
创建实现 CanvasPathDrawingStyles
接口的对象时,lineDashOffset
属性最初的值必须为 0.0。
当用户代理 描摹路径 时,给定实现 CanvasPathDrawingStyles
接口的对象 style,必须运行以下算法。此算法返回一个新的 路径。
让 path 成为被描摹路径的副本。
从 path 修剪所有零长度的 线段。
从 path 移除任何包含无线条的子路径(即仅有一个点的子路径)。
将 path 中每个子路径的每个点替换为连接点(除了每个子路径的第一个点和最后一个点),这样子路径都由两个点组成(一个起点和一个终点),一条或多条线连接这些点和连接点。
为 path 中的每个闭合子路径添加一条直的封闭线,连接最后一个点和第一个点;将最后一个点更改为连接点(从之前的最后一条线到新添加的封闭线),并将第一个点更改为连接点(从新添加的封闭线到第一条线)。
如果 style 的 虚线列表 为空,则跳到标记为 convert 的步骤。
让 pattern width 为 style 的 虚线列表 所有条目的串联,以坐标空间单位表示。
对于 path 中的每个子路径 subpath,运行以下子步骤。这些子步骤在 path 中对子路径进行 活体内 突变。
让 subpath width 为 subpath 所有线条的长度,以坐标空间单位表示。
让 offset 为 style 的 lineDashOffset
的值,以坐标空间单位表示。
当 offset 大于 pattern width 时,将其减去 pattern width。
当 offset 小于零时,将其增加 pattern width。
定义 L 为沿 subpath 中所有线条定义的线性坐标线,使得子路径中第一条线的起点定义为坐标 0,子路径中最后一条线的终点定义为坐标 subpath width。
让 position 为零减去 offset。
让 index 为 0。
让 current state 为 关(其他状态为 开 和 零开)。
虚线开:让 segment length 为 style 的 虚线列表 的 index 条目值。
将 position 增加 segment length。
如果 position 大于 subpath width,则结束这些子步骤并开始下一个子路径的子步骤;如果没有更多的子路径,则跳到标记为 convert 的步骤。
如果 segment length 不为零,则让 current state 为 开。
将 index 增加 1。
虚线关:让 segment length 为 style 的 虚线列表 的 index 条目值。
让 start 为 L 上的 position 偏移。
将 position 增加 segment length。
如果 position 小于零,则跳到标记为 post-cut 的步骤。
如果 start 小于零,则让 start 为零。
如果 position 大于 subpath width,则让 end 为 L 上的 subpath width 偏移。否则,让 end 为 L 上的 position 偏移。
跳到第一个适当的步骤:
什么也不做,继续到下一个步骤。
在 end 位置的线条上剪断,并在该处放置一个点,将其切成两段子路径;移除 start 和 end 之间的所有线段、连接点、点和子路径;并最终在 start 处放置一个没有连接线的点。
对于绘制线帽的目的,这个点具有 方向性。方向性是原始线条在该点的方向(即当 L 在上面定义时)。
在 start 位置的线条上剪断并放置一个点,将其切成两段子路径,并类似地在 end 位置的线条上剪断并放置一个点,将其切成两段子路径,然后移除 start 和 end 之间的所有线段、连接点、点和子路径。
如果 start 和 end 是同一个点,则这将导致线条被切成两段并在该处插入两个点,除非该点上还有一个连接点,则必须移除该连接点。
Post-cut:如果 position 大于 subpath width,则跳到标记为 convert 的步骤。
如果 segment length 大于零,则让 positioned-at-on-dash 为假。
将 index 增加 1。如果它等于 style 的 虚线列表 中的条目数,则让 index 为 0。
返回到标记为 虚线开 的步骤。
转换:这是将路径转换为表示其描边的新路径的步骤。
创建一个新的 路径,描述如果长度等于
style 的 lineWidth
的直线沿每个子路径扫过的边缘,同时保持直线与被扫路径正交,替换每个点为满足 style 的 lineCap
属性所需的端点帽,如之前描述并详细说明的,并替换每个连接点为满足 style 的 lineJoin
类型所需的连接点,如下所定义。
帽:每个点有一个与出线方向垂直的平坦边缘。这然后根据 style 的 lineCap
值进行补充。"butt
" 值意味着不添加额外的线帽。"round
" 值意味着必须在每个点的出线处添加一个直径等于 style 的 lineWidth
宽度的半圆。"square
" 值意味着必须在每个点的出线处添加一个与点的出线方向垂直的矩形,其长度为 style 的 lineWidth
宽度的一半,宽度为 style 的 lineWidth
宽度。
没有出线的点必须放置两个背靠背的帽,就像它实际上是由一个方向性为该点方向的无限短直线连接的两个点。
连接:除了连接点本身,每个连接点还涉及两个额外的点,每条线各一个:在连接点半线宽远处的两个角之一,每条线垂直的方向,每个在线条最远的一侧。
必须在所有连接点处添加一个连接这两个相对角与连接点的三角形。在连接点渲染的其他内容由 lineJoin
属性控制。上述三个值有以下含义:
"bevel
" 值意味着在连接处仅渲染上述内容。
"round
" 值意味着必须在连接处添加一个连接上述角的弧,与上述三角形相接(而非重叠),直径等于线宽,起点为连接点。
"miter
" 值意味着在连接处必须(如果可能的话,给定斜接长度)添加第二个三角形,一条线是上述两个角之间的线,与第一个三角形相接,另一条线是连接线的外边缘的延伸,直到相交而不超过斜接长度。
斜接长度是从连接点到连接外边缘相交点的距离。斜接限制比率是斜接长度与线宽一半的最大允许比率。如果斜接长度导致斜接限制比率(由 style 的 miterLimit
属性设置)被超过,则不得添加第二个三角形。
新创建路径中的子路径必须以这样的方式排列,以便对于任何点,如果从该点绘制的半无限直线与子路径相交的次数是偶数,当且仅当从该点绘制的半无限直线与子路径相交的次数与子路径在另一个方向上的相交次数相等。
返回新创建的路径。
context.font [ = value ]
Support in all current engines.
styles.font [ = value ]
返回当前字体设置。
可以设置以更改字体。语法与 CSS 'font' 属性相同;无法解析为 CSS 字体值的值将被忽略。
相对关键字和长度是相对于 canvas
元素的字体计算的。
context.textAlign [ = value ]
CanvasRenderingContext2D/textAlign
Support in all current engines.
styles.textAlign [ = value ]
返回当前文本对齐设置。
可以设置以更改对齐方式。可能的值及其含义如下所示。其他值将被忽略。默认值是 "start
"。
context.textBaseline [ = value ]
CanvasRenderingContext2D/textBaseline
Support in all current engines.
styles.textBaseline [ = value ]
返回当前基线对齐设置。
可以设置以更改基线对齐。可能的值及其含义如下所示。其他值将被忽略。默认值是 "alphabetic
"。
context.direction [ = value ]
CanvasRenderingContext2D/direction
Support in all current engines.
styles.direction [ = value ]
返回当前方向性。
可以设置以更改方向性。可能的值及其含义如下所示。其他值将被忽略。默认值是 "inherit
"。
context.letterSpacing [ = value ]
styles.letterSpacing [ = value ]
返回当前文本中字符之间的间距。
可以设置以更改字符之间的间距。无法解析为 CSS <length> 的值将被忽略。默认值是 "0px
"。
context.fontKerning [ = value ]
styles.fontKerning [ = value ]
返回当前字体字距调整设置。
可以设置以更改字体字距调整。可能的值及其含义如下所示。其他值将被忽略。默认值是 "auto
"。
context.fontStretch [ = value ]
styles.fontStretch [ = value ]
返回当前字体拉伸设置。
可以设置以更改字体拉伸。可能的值及其含义如下所示。其他值将被忽略。默认值是 "normal
"。
context.fontVariantCaps [ = value ]
styles.fontVariantCaps [ = value ]
返回当前字体变体大写字母设置。
可以设置以更改字体变体大写字母。可能的值及其含义如下所示。其他值将被忽略。默认值是 "normal
"。
context.textRendering [ = value ]
styles.textRendering [ = value ]
返回当前文本渲染设置。
可以设置以更改文本渲染。可能的值及其含义如下所示。其他值将被忽略。默认值是 "auto
"。
context.wordSpacing [ = value ]
styles.wordSpacing [ = value ]
返回当前文本中词之间的间距。
可以设置以更改词之间的间距。无法解析为 CSS <length> 的值将被忽略。默认值是 "0px
"。
实现 CanvasTextDrawingStyles
接口的对象具有控制对象如何布局(光栅化或描边)文本的属性(在本节中定义)。这些对象还可以有一个 字体样式源对象。对于 CanvasRenderingContext2D
对象,这是上下文的 canvas
元素的值。对于 OffscreenCanvasRenderingContext2D
对象,这是 相关的
OffscreenCanvas
对象。
字体分辨率对于 字体样式源对象 需要一个 字体源。这是通过以下步骤为实现
CanvasTextDrawingStyles
的给定 object 确定的:[CSSFONTLOAD]
否则,object 的 字体样式源对象
是一个 OffscreenCanvas
对象:
让 global 成为 object 的 相关全局对象。
如果 global 是一个 Window
对象,则返回
global
的 关联的
Document
。
断言:global 实现了 WorkerGlobalScope
。
返回 global。
这是一个带有 ID 为 c1
的常规 canvas
元素的字体解析示例。
const font = new FontFace( "MyCanvasFont" , "url(mycanvasfont.ttf)" );
documents. fonts. add( font);
const context = document. getElementById( "c1" ). getContext( "2d" );
document. fonts. ready. then( function () {
context. font = "64px MyCanvasFont" ;
context. fillText( "hello" , 0 , 0 );
});
在此示例中,canvas 将使用 mycanvasfont.ttf
作为其字体来显示文本。
这是一个如何使用 OffscreenCanvas
进行字体解析的示例。假设有一个 ID 为 c2
的 canvas
元素,它被如下转移到一个 worker:
const offscreenCanvas = document. getElementById( "c2" ). transferControlToOffscreen();
worker. postMessage( offscreenCanvas, [ offscreenCanvas]);
Then, in the worker:
self. onmessage = function ( ev) {
const transferredCanvas = ev. data;
const context = transferredCanvas. getContext( "2d" );
const font = new FontFace( "MyFont" , "url(myfont.ttf)" );
self. fonts. add( font);
self. fonts. ready. then( function () {
context. font = "64px MyFont" ;
context. fillText( "hello" , 0 , 0 );
});
};
在此示例中,canvas 将使用 myfont.ttf
显示文本。注意,该字体仅在 worker 内加载,而不在文档上下文中加载。
font
IDL 属性,在设置时,必须按照 CSS <'font'> 值 进行解析(但不支持独立于属性的样式表语法,如
'inherit'),并将结果字体分配给上下文,将 'line-height' 组件强制为 'normal','font-size'
组件转换为 CSS 像素,并将系统字体计算为显式值。如果新值在语法上不正确(包括使用独立于属性的样式表语法如 'inherit' 或
'initial'),则必须忽略它,不分配新的字体值。[CSS]
字体族名称在使用字体时必须在 字体样式源对象
的上下文中解释;使用 @font-face
嵌入或使用 FontFace
对象加载的任何字体一旦加载完成,对 字体样式源对象
可见,则必须可用。(每个 字体样式源对象 有一个 字体源,它决定了哪些字体可用。)如果在字体完全加载之前使用字体,或者如果 字体样式源对象
在使用字体时不包含该字体,则必须将其视为未知字体,按照相关 CSS 规范的描述回退到另一个字体。[CSSFONTS] [CSSFONTLOAD]
在获取时,font
属性必须返回上下文当前字体的序列化形式(没有 'line-height' 组件)。[CSSOM]
例如,在以下语句之后:
context. font = 'italic 400 12px/2 Unknown Font, sans-serif' ;
……表达式 context.font
的结果将是字符串 "italic 12px "Unknown Font", sans-serif
"。"400"
字重没有显示,因为那是默认值。行高没有显示,因为它被强制为 "normal",这是默认值。
当实现 CanvasTextDrawingStyles
接口的对象被创建时,context 的字体必须被设置为 10px sans-serif。当 'font-size'
组件被设置为使用百分比、em
或
ex 单位,或
'larger'
或 'smaller' 关键词时,这些必须相对于 计算值来解释 'font-size' 属性的 font style source object 在属性设置时的值,如果它是一个元素。当 font-weight 组件被设置为相对值 'bolder' 和 'lighter' 时,这些必须相对于 计算值来解释 'font-weight'
属性的
font style
source object 在属性设置时的值,如果它是一个元素。如果对于特定情况(例如,因为 font style source object 不是元素或没有 正在渲染)未定义计算值,则必须相对于正常重量的 10px
sans-serif 默认值来解释相对关键词。
textAlign
IDL 属性,在获取时,必须返回当前值。在设置时,当前值必须更改为新值。当实现 CanvasTextDrawingStyles
接口的对象被创建时,textAlign
属性最初必须具有值 start
。
textBaseline
IDL 属性,在获取时,必须返回当前值。在设置时,当前值必须更改为新值。当实现 CanvasTextDrawingStyles
接口的对象被创建时,textBaseline
属性最初必须具有值 alphabetic
。
direction
IDL 属性,在获取时,必须返回当前值。在设置时,当前值必须更改为新值。当实现 CanvasTextDrawingStyles
接口的对象被创建时,direction
属性最初必须具有值 "inherit
"。
实现 CanvasTextDrawingStyles
接口的对象具有控制字母和单词间距的属性。这些对象具有相关联的 字母间距 和 单词间距 值,它们是 CSS <length> 值。最初,这两个值必须是将
"0px
" 作为 CSS <length> 解析的结果。
CanvasRenderingContext2D/letterSpacing
Support in one engine only.
letterSpacing
getter 步骤是返回 序列化形式 this's letter spacing。
letterSpacing
setter 步骤是:
如果 parsed 失败,则返回。
设置 this's letter spacing 为 parsed。
CanvasRenderingContext2D/wordSpacing
Support in one engine only.
wordSpacing
getter 步骤是返回 序列化形式 this's word spacing。
wordSpacing
setter 步骤是:
如果 parsed 失败,则返回。
设置 this's word spacing 为 parsed。
CanvasRenderingContext2D/fontKerning
fontKerning
IDL 属性,在获取时,必须返回当前值。在设置时,当前值必须更改为新值。当实现 CanvasTextDrawingStyles
接口的对象被创建时,fontKerning
属性最初必须具有值 "auto
"。
CanvasRenderingContext2D/fontStretch
Support in one engine only.
fontStretch
IDL 属性,在获取时,必须返回当前值。在设置时,当前值必须更改为新值。当实现 CanvasTextDrawingStyles
接口的对象被创建时,fontStretch
属性最初必须具有值 "normal
"。
CanvasRenderingContext2D/fontVariantCaps
Support in one engine only.
fontVariantCaps
IDL 属性,在获取时,必须返回当前值。在设置时,当前值必须更改为新值。当实现 CanvasTextDrawingStyles
接口的对象被创建时,fontVariantCaps
属性最初必须具有值 "normal
"。
CanvasRenderingContext2D/textRendering
Support in one engine only.
textRendering
IDL 属性,在获取时,必须返回当前值。在设置时,当前值必须更改为新值。当实现 CanvasTextDrawingStyles
接口的对象被创建时,textRendering
属性最初必须具有值 "auto
"。
textAlign
属性允许的关键词如下:
start
对齐到文本的起始边(从左到右文本的左侧,从右到左文本的右侧)。
end
对齐到文本的结束边(从左到右文本的右侧,从右到左文本的左侧)。
left
对齐到左侧。
right
对齐到右侧。
center
对齐到中心。
textBaseline
属性允许的关键词对应于字体中的对齐点:
关键词与这些对齐点的对应关系如下:
top
hanging
middle
alphabetic
ideographic
bottom
direction
属性允许的关键词如下:
fontKerning
属性允许的关键词如下:
auto
字距调整由用户代理决定。
normal
应用字距调整。
none
不应用字距调整。
fontStretch
属性允许的关键词如下:
ultra-condensed
与 CSS font-stretch 设置中的 ultra-condensed 设置相同。
extra-condensed
与 CSS font-stretch 设置中的 extra-condensed 设置相同。
condensed
与 CSS font-stretch 设置中的 condensed 设置相同。
semi-condensed
与 CSS font-stretch 设置中的 semi-condensed 设置相同。
normal
默认设置,字形宽度为 100%。
semi-expanded
与 CSS font-stretch 设置中的 semi-expanded 设置相同。
expanded
与 CSS font-stretch 设置中的 expanded 设置相同。
extra-expanded
与 CSS font-stretch 设置中的 extra-expanded 设置相同。
ultra-expanded
与 CSS font-stretch 设置中的 ultra-expanded 设置相同。
fontVariantCaps
属性允许的关键词如下:
normal
不启用以下列出的任何功能。
small-caps
与 CSS font-variant-caps 设置中的 small-caps 设置相同。
all-small-caps
与 CSS font-variant-caps 设置中的 all-small-caps 设置相同。
petite-caps
与 CSS font-variant-caps 设置中的 petite-caps 设置相同。
all-petite-caps
与 CSS font-variant-caps 设置中的 all-petite-caps 设置相同。
unicase
与 CSS font-variant-caps 设置中的 unicase 设置相同。
titling-caps
与 CSS font-variant-caps 设置中的 titling-caps 设置相同。
textRendering
属性允许的关键词如下:
auto
与 SVG text-rendering 属性中的 'auto' 设置相同。
optimizeSpeed
与 SVG text-rendering 属性中的 'optimizeSpeed' 设置相同。
optimizeLegibility
与 SVG text-rendering 属性中的 'optimizeLegibility' 设置相同。
geometricPrecision
与 SVG text-rendering 属性中的 'geometricPrecision' 设置相同。
text preparation algorithm 如下。它接受一个字符串 text,一个 CanvasTextDrawingStyles
对象 target,和一个可选的长度 maxWidth 作为输入。它返回一个字符形状数组,每个字符都在一个共同的坐标空间中定位,一个 physical
alignment 其值为 left, right, 或 center,以及一个 inline box。(大多数调用此算法的对象会忽略
physical alignment 和 inline box。)
如果提供了 maxWidth 但其小于或等于零或等于 NaN,则返回一个空数组。
将 text 中的所有 ASCII 空白字符 替换为 U+0020 空格字符。
令 font 为 target 的当前字体,由该对象的 font
属性给出。
应用以下列表中的适当步骤来确定 direction 的值:
direction
属性的值为 "ltr
"
direction
属性的值为 "rtl
"
Document
且具有非空 document element形成一个假设的无限宽 CSS line box 包含一个单独的 inline box 包含文本 text,其 CSS 属性设置如下:
属性 | 来源 |
---|---|
direction | direction |
font | font |
font-kerning | target's fontKerning
|
font-stretch | target's fontStretch
|
font-variant-caps | target's fontVariantCaps
|
letter-spacing | target's letter spacing |
SVG text-rendering | target's textRendering
|
white-space | pre |
word-spacing | target's word spacing |
并将所有其他属性设置为初始值。
如果提供了 maxWidth 并且假设的 inline box 在假设的 line box 中的宽度大于 maxWidth CSS 像素,则将 font 更改为具有更紧凑的字体(如果有可用的或通过对字体应用水平缩放因子可以合理地合成一个)或更小的字体,并返回到上一步。
anchor point 是 inline box 上的一个点,并且 physical alignment 是 left,
right, 和 center 之一。这些变量由 textAlign
和 textBaseline
的值确定如下:
水平位置:
textAlign
为 left
textAlign
为 start
并且 direction 为 ltrtextAlign
为 end
并且 direction 为 rtltextAlign
为 right
textAlign
为 end
并且 direction 为 ltrtextAlign
为 start
并且 direction 为 rtltextAlign
为 center
垂直位置:
textBaseline
为 top
textBaseline
为 hanging
textBaseline
为 middle
textBaseline
为 alphabetic
textBaseline
为 ideographic
textBaseline
为 bottom
令 result 为通过从左到右迭代 inline box 中的每个字符(如果有),并为每个字符添加其在 inline box 中的形状构造的数组,并在一个坐标空间中定位,使用 CSS 像素 其原点在 anchor point。
返回 result、physical alignment 和 inline box。
实现 CanvasPath
接口的对象有一个
路径。路径有一个或多个子路径的列表。每个子路径由一个或多个点组成,这些点由直线或曲线 线段连接,并有一个标志指示子路径是否关闭。关闭的子路径是指子路径的最后一个点通过一条直线连接到子路径的第一个点。只有一个点的子路径在绘制路径时会被忽略。
路径有一个 需要新子路径 标志。当此标志被设置时,某些 API 会创建一个新的子路径,而不是扩展前一个子路径。当 路径 被创建时,其 需要新子路径 标志必须被设置。
当创建实现 CanvasPath
接口的对象时,其 路径 必须初始化为零个子路径。
context.moveTo(x, y)
CanvasRenderingContext2D/moveTo
Support in all current engines.
path.moveTo(x, y)
创建一个包含给定点的新子路径。
context.closePath()
CanvasRenderingContext2D/closePath
Support in all current engines.
path.closePath()
将当前子路径标记为关闭,并以相同的起点和终点开始一个新子路径。
context.lineTo(x, y)
CanvasRenderingContext2D/lineTo
Support in all current engines.
path.lineTo(x, y)
将给定点添加到当前子路径,连接到先前的点通过一条直线。
context.quadraticCurveTo(cpx, cpy, x, y)
CanvasRenderingContext2D/quadraticCurveTo
Support in all current engines.
path.quadraticCurveTo(cpx, cpy, x, y)
将给定点添加到当前子路径,连接到先前的点通过一条二次贝塞尔曲线并带有给定的控制点。
context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
CanvasRenderingContext2D/bezierCurveTo
Support in all current engines.
path.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
将给定点添加到当前子路径,连接到先前的点通过一条三次贝塞尔曲线并带有给定的控制点。
context.arcTo(x1, y1, x2, y2, radius)
CanvasRenderingContext2D/arcTo
Support in all current engines.
path.arcTo(x1, y1, x2, y2, radius)
将给定的控制点和半径的弧添加到当前子路径,通过直线连接到先前的点。
如果给定的半径为负,则抛出 "IndexSizeError
" DOMException
。
context.arc(x, y, radius, startAngle, endAngle [, counterclockwise ])
Support in all current engines.
path.arc(x, y, radius, startAngle, endAngle [, counterclockwise ])
将点添加到子路径中,使由参数描述的圆的圆周的弧,从给定的起始角开始并在给定的终止角结束,按给定的方向(默认为顺时针)添加到路径中,通过直线连接到先前的点。
如果给定的半径为负,则抛出 "IndexSizeError
" DOMException
。
context.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle [, counterclockwise])
CanvasRenderingContext2D/ellipse
Support in all current engines.
path.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle [, counterclockwise])
将点添加到子路径中,使由参数描述的椭圆的圆周的弧,从给定的起始角开始并在给定的终止角结束,按给定的方向(默认为顺时针)添加到路径中,通过直线连接到先前的点。
如果给定的半径为负,则抛出 "IndexSizeError
" DOMException
。
context.rect(x, y, w, h)
Support in all current engines.
path.rect(x, y, w, h)
向路径添加一个新闭合子路径,表示给定的矩形。
context.roundRect(x, y, w, h, radii)
path.roundRect(x, y, w, h, radii)
向路径添加一个新闭合子路径,表示给定的圆角矩形。radii 是一个表示矩形角的半径的列表或单个半径,以像素为单位。如果提供列表,则这些半径的数量和顺序与 CSS 'border-radius' 属性相同。单个半径的行为与仅有一个元素的列表相同。
如果 w 和 h 都大于或等于 0,或者如果两者都小于 0,则路径按顺时针方向绘制。否则,按逆时针方向绘制。
当 w 为负时,圆角矩形水平翻转,这意味着通常适用于左角的半径值用于右角,反之亦然。同样,当 h 为负时,圆角矩形垂直翻转。
当 radii 中的值 r 为数字时,相应的角以半径 r 绘制为圆弧。
当 radii 中的值 r 为具有 { x, y }
属性的对象时,相应的角绘制为椭圆弧,其 x 和 y
半径分别等于 r.x 和 r.y。
当同一边缘的两个角的 radii 之和大于边缘长度时,所有圆角矩形的 radii 都按比例因子长度 / (r1 + r2) 缩放。如果多个边缘具有此属性,则使用比例因子最小的边缘的比例因子。这与 CSS 行为一致。
如果 radii 是大小不是一、二、三或四的列表,则抛出 RangeError
。
如果 radii 中的值为负数,或者是 { x, y }
对象,其 x
或 y
属性为负数,则抛出 RangeError
。
以下方法允许作者操作实现 路径 的对象,这些对象实现了
CanvasPath
接口。
对于实现 CanvasDrawPath
和
CanvasTransform
接口的对象,传递给方法的点,以及这些方法添加到 当前默认路径
的结果线,必须在添加到路径之前根据 当前变换矩阵 进行变换。
moveTo(x,
y)
方法在调用时,必须运行以下步骤:
如果任一参数为无限或 NaN,则返回。
创建一个以指定点为其第一个(也是唯一一个)点的新子路径。
当用户代理为 确保有一个子路径 为坐标 (x, y) 在 路径 上时,用户代理必须检查路径是否设置了其 需要新子路径
标志。如果设置了,则用户代理必须创建一个以点 (x, y) 为第一个(也是唯一一个)点的新子路径,就像调用了 moveTo()
方法一样,然后必须取消设置路径的 需要新子路径
标志。
closePath()
方法在调用时,如果对象的路径没有子路径,则不做任何操作。否则,它必须将最后一个子路径标记为关闭,创建一个新子路径,其第一个点与先前子路径的第一个点相同,最后将此新子路径添加到路径中。
如果最后一个子路径在其点列表中有多个点,则这相当于添加一条将最后一个点连接回最后一个子路径的第一个点的直线,从而“关闭”子路径。
使用以下描述的方法将新点和连接它们的线添加到子路径中。在所有情况下,这些方法只修改对象路径中的最后一个子路径。
lineTo(x,
y)
方法在调用时,必须运行以下步骤:
如果任一参数为无限或 NaN,则返回。
如果对象的路径没有子路径,则 确保有一个子路径 为 (x, y)。
否则,使用一条直线将子路径中的最后一个点连接到给定点 (x, y),然后将给定点 (x, y) 添加到子路径中。
quadraticCurveTo(cpx, cpy,
x, y)
方法在调用时,必须运行以下步骤:
如果任一参数为无限或 NaN,则返回。
确保有一个子路径 为 (cpx, cpy)。
使用控制点 (cpx, cpy) 将子路径中的最后一个点连接到给定点 (x, y),使用二次贝塞尔曲线。[BEZIER]
将给定点 (x, y) 添加到子路径中。
bezierCurveTo(cp1x, cp1y,
cp2x, cp2y, x, y)
方法在调用时,必须运行以下步骤:
如果任一参数为无限或 NaN,则返回。
确保有一个子路径 为 (cp1x, cp1y)。
使用控制点 (cp1x, cp1y) 和 (cp2x, cp2y) 将子路径中的最后一个点连接到给定点 (x, y),使用三次贝塞尔曲线。[BEZIER]
将点 (x, y) 添加到子路径中。
arcTo(x1,
y1, x2, y2, radius)
方法在调用时,必须运行以下步骤:
如果任一参数为无限或 NaN,则返回。
确保有一个子路径 为 (x1, y1)。
如果 radius 为负,则抛出 "IndexSizeError
"
DOMException
。
令点 (x0, y0) 为子路径中的最后一个点,通过 当前变换矩阵 的逆变换(以使其与传递给方法的点在同一坐标系中)。
如果点 (x0, y0) 等于点 (x1, y1),或者如果点 (x1, y1) 等于点 (x2, y2),或者如果 radius 为零,则将点 (x1, y1) 添加到子路径中,并通过直线将该点连接到前一个点 (x0, y0)。
否则,如果点 (x0, y0),(x1, y1) 和 (x2, y2) 全部在一条直线上,则将点 (x1, y1) 添加到子路径中,并通过直线将该点连接到前一个点 (x0, y0)。
否则,令 The Arc 为圆的周长所给出的最短弧,圆具有半径 radius,并且在点 (x0, y0) 和点 (x1, y1) 之间有一个点与该圆的半无限线相切,且在点 (x1, y1) 和点 (x2, y2) 之间有一个点与该圆的另一条半无限线相切。将点 (x0, y0) 连接到起始切点,通过一条直线添加起始切点到子路径中,然后将起始切点连接到终点切点,通过 The Arc 添加终点切点到子路径中。
arc(x,
y, radius, startAngle, endAngle,
counterclockwise)
方法在调用时,必须运行 椭圆方法步骤,并传递此参数、x、y、radius、radius、0、startAngle、endAngle
和 counterclockwise。
这使得它等效于 ellipse()
,但两个半径相等且
rotation 为 0。
ellipse(x,
y, radiusX, radiusY, rotation, startAngle,
endAngle, counterclockwise)
方法在调用时,必须运行 椭圆方法步骤,并传递此参数、x、y、radiusX、radiusY、rotation、startAngle、endAngle
和 counterclockwise。
确定椭圆上的点步骤,给定 ellipse 和 angle,如下:
令 eccentricCircle 为与 ellipse 共享其原点的圆,其半径等于 ellipse 的半长轴。
令 outerPoint 为在顺时针方向从 ellipse 的半长轴测量的 angle 角度的 eccentricCircle 的圆周上的点。
令 chord 为在该轴与 outerPoint 之间垂直于 ellipse 的长轴的线。
返回在 chord 上穿过 ellipse 的圆周的点。
椭圆方法步骤,给定 canvasPath、x、y、 radiusX、radiusY、rotation、startAngle、endAngle 和 counterclockwise,如下:
如果任一参数为无限或 NaN,则返回。
如果 radiusX 或 radiusY 为负,则抛出 "IndexSizeError
" DOMException
。
如果 canvasPath 的路径有任何子路径,则从子路径的最后一个点添加一条直线到弧的起点。
将弧的起点和终点添加到子路径中,并用一条弧连接它们。弧及其起点和终点定义如下:
考虑一个椭圆,其原点在 (x, y),其长轴半径为 radiusX,短轴半径为 radiusY,并且绕其原点顺时针旋转 rotation 弧度,使其半长轴与 x 轴成 rotation 角度。
如果 counterclockwise 为假且 endAngle − startAngle 大于或等于 2π,或者如果 counterclockwise 为真且 startAngle − endAngle 大于或等于 2π,则弧是此椭圆的整个圆周,并且起点和终点是运行 确定椭圆上的点步骤 所得的结果,此椭圆和 startAngle。
否则,起点是运行 确定椭圆上的点步骤 所得的结果,此椭圆和 startAngle,终点是运行 确定椭圆上的点步骤 所得的结果,此椭圆和 endAngle,弧是从起点到终点的椭圆圆周的路径,逆时针方向如果 counterclockwise 为真,否则顺时针方向。由于点位于椭圆上,而不是简单的角度从零开始,弧的角度永远不会超过 2π 弧度。
即使弧覆盖了椭圆的整个圆周且子路径中没有其他点,除非适当调用 closePath()
方法,否则路径不会闭合。
rect(x,
y, w, h)
方法在调用时,必须运行以下步骤:
如果任一参数为无限或 NaN,则返回。
创建一个仅包含四个点 (x, y), (x+w, y), (x+w, y+h), (x, y+h) 的新子路径,按该顺序,四个点通过直线连接。
将子路径标记为闭合。
创建一个以点 (x, y) 为唯一点的新子路径。
CanvasRenderingContext2D/roundRect
Support in all current engines.
roundRect(x, y, w,
h, radii)
方法步骤如下:
如果任一 x、y、w 或 h 为无限或 NaN,则返回。
如果 radii 是 unrestricted double
或 DOMPointInit
,则将
radii 设置为 « radii »。
如果 radii 不是大小为一、二、三或四的列表,则抛出 RangeError
。
令 normalizedRadii 为一个空列表。
对于 radii 中的每个 radius:
如果 radius 是 DOMPointInit
:
如果 radius["x
"]
或
radius["y
"]
为负数,则抛出 RangeError
。
否则,将 radius 附加到 normalizedRadii。
如果 radius 是 unrestricted double
:
如果 radius 为无限或 NaN,则返回。
如果 radius 为负数,则抛出 RangeError
。
令 upperLeft、upperRight、lowerRight 和 lowerLeft 为 null。
如果 normalizedRadii 的大小为 4,则将 upperLeft 设置为 normalizedRadii[0],将 upperRight 设置为 normalizedRadii[1],将 lowerRight 设置为 normalizedRadii[2],并将 lowerLeft 设置为 normalizedRadii[3]。
如果 normalizedRadii 的 大小为 3,则将 upperLeft 设置为 normalizedRadii[0],将 upperRight 和 lowerLeft 设置为 normalizedRadii[1],并将 lowerRight 设置为 normalizedRadii[2]。
如果 normalizedRadii 的大小为 2,则将 upperLeft 和 lowerRight 设置为 normalizedRadii[0],并将 upperRight 和 lowerLeft 设置为 normalizedRadii[1]。
如果 normalizedRadii 的大小为 1,则将 upperLeft、upperRight、lowerRight 和 lowerLeft 设置为 normalizedRadii[0]。
角曲线不能重叠。按比例缩放所有半径以防止这种情况:
创建一个新子路径:
移动到点 (x + upperLeft["x
"],
y)。
画一条直线到点 (x + w - upperRight["x
"],
y)。
画一条弧到点 (x + w,y + upperRight["y
"])。
画一条直线到点 (x + w,y + h - lowerRight["y
"])。
画一条弧到点 (x + w - lowerRight["x
"],
y + h)。
画一条直线到点 (x + lowerLeft["x
"],
y + h)。
画一条弧到点 (x, y + h - lowerLeft["y
"])。
画一条直线到点 (x, y + upperLeft["y
"])。
画一条弧到点 (x + upperLeft["x
"],
y)。
将子路径标记为闭合。
创建一个以点 (x, y) 为唯一点的新子路径。
这旨在与 CSS 'border-radius' 属性的行为类似。
Path2D
对象
所有当前引擎支持。
Path2D
对象可用于声明路径,然后在实现
CanvasDrawPath
接口的对象上使用。除了前面章节中描述的许多 API 之外,Path2D
对象还有方法来组合路径,并将文本添加到路径中。
path = new Path2D()
所有当前引擎支持。
创建一个新的空的 Path2D
对象。
path = new Path2D(path)
当 path 是 Path2D
对象时,返回一个副本。
当 path 是一个字符串时,创建由参数描述的路径,解释为 SVG 路径数据。[SVG]
path.addPath(path [, transform ])
所有当前引擎支持。
将参数给定的路径添加到路径中。
Path2D(path)
构造函数被调用时,必须执行以下步骤:
让 output 成为一个新的 Path2D
对象。
如果未给出 path,则返回 output。
如果 path 是 Path2D
对象,则将 path 的所有子路径添加到 output,并返回 output。(换句话说,它返回参数的副本。)
让 svgPath 成为根据 SVG 2 的路径数据规则解析和解释 path 的结果。[SVG]
生成的路径可能是空的。SVG 定义了解析和应用路径数据的错误处理规则。
让 (x, y) 成为 svgPath 中的最后一个点。
将 svgPath 中的所有子路径(如果有)添加到 output。
在 output 中创建一个新的子路径,其唯一点为 (x, y)。
返回 output。
addPath(path, transform)
方法在 Path2D
对象 a
上被调用时,必须执行以下步骤:
如果 Path2D
对象
path 没有子路径,则返回。
让 matrix 成为根据 2D 字典创建 DOMMatrix transform 的结果。
如果 matrix 的一个或多个m11 元素、m12 元素、m21 元素、m22 元素、m41 元素或m42 元素是无穷大或 NaN,则返回。
创建 path 中所有子路径的副本。称此副本为 c。
通过变换矩阵 matrix 变换 c 中的所有坐标和线。
让 (x, y) 成为 c 的最后一个子路径中的最后一个点。
将 c 中的所有子路径添加到 a。
在 a 中创建一个新的子路径,其唯一点为 (x, y)。
实现 CanvasTransform
接口的对象具有一个当前变换矩阵,以及操纵它的方法(在本节中描述)。当创建实现 CanvasTransform
接口的对象时,其变换矩阵必须初始化为单位矩阵。
当前变换矩阵在创建当前默认路径,以及在实现
CanvasTransform
接口的对象上绘制文本、形状和 Path2D
对象时应用于坐标。
变换必须以逆序执行。
例如,如果在画布上应用一个将宽度加倍的缩放变换,然后应用一个旋转变换使绘图操作旋转四分之一圈,然后在画布上绘制一个宽度是高度两倍的矩形,则实际结果将是一个正方形。
context.scale(x, y)
CanvasRenderingContext2D/scale
所有当前引擎支持。
更改 当前变换矩阵 以应用具有给定特征的缩放变换。
context.rotate(angle)
CanvasRenderingContext2D/rotate
所有当前引擎支持。
更改 当前变换矩阵 以应用具有给定特征的旋转变换。角度以弧度表示。
context.translate(x, y)
CanvasRenderingContext2D/translate
所有当前引擎支持。
更改 当前变换矩阵 以应用具有给定特征的平移变换。
context.transform(a, b, c, d, e, f)
CanvasRenderingContext2D/transform
所有当前引擎支持。
更改 当前变换矩阵 以应用如下所述的矩阵。
matrix = context.getTransform()
CanvasRenderingContext2D/getTransform
所有当前引擎支持。
context.setTransform(a, b, c, d, e, f)
CanvasRenderingContext2D/setTransform
所有当前引擎支持。
更改 当前变换矩阵 为下文描述的参数给出的矩阵。
context.setTransform(transform)
更改 当前变换矩阵
为传递的 DOMMatrix2DInit
字典表示的矩阵。
context.resetTransform()
CanvasRenderingContext2D/resetTransform
所有当前引擎支持。
将 当前变换矩阵 重置为单位矩阵。
scale(x, y)
方法在调用时,必须运行以下步骤:
如果任一参数为无限或 NaN,则返回。
将参数描述的缩放变换添加到 当前变换矩阵。x 参数表示水平方向的缩放因子,y 参数表示垂直方向的缩放因子。因子为倍数。
rotate(angle)
方法在调用时,必须运行以下步骤:
如果 angle 为无限或 NaN,则返回。
将参数描述的旋转变换添加到 当前变换矩阵。angle 参数表示顺时针旋转角度,以弧度表示。
translate(x, y)
方法在调用时,必须运行以下步骤:
如果任一参数为无限或 NaN,则返回。
将参数描述的平移变换添加到 当前变换矩阵。x 参数表示水平方向的平移距离,y 参数表示垂直方向的平移距离。参数以坐标空间单位表示。
transform(a, b, c, d, e, f)
方法在调用时,必须运行以下步骤:
如果任一参数为无限或 NaN,则返回。
将 当前变换矩阵 替换为与以下描述的矩阵相乘的结果:
a | c | e |
b | d | f |
0 | 0 | 1 |
参数 a, b, c, d, e 和 f 有时被称为 m11, m12, m21, m22, dx 和 dy 或 m11, m21, m12, m22, dx 和 dy。特别需要注意的是第二个和第三个参数(b 和 c)的顺序,因为它们在不同的 API 中顺序不同,并且 API 有时使用 m12/m21 的表示法,有时使用 m21/m12 的表示法。
getTransform()
方法在调用时,必须返回一个新创建的 DOMMatrix
对象,表示上下文的 当前变换矩阵
的副本。
此返回的对象不是实时的,因此更新它不会影响 当前变换矩阵,更新 当前变换矩阵 也不会影响已经返回的 DOMMatrix
。
setTransform(a, b, c, d, e, f)
方法在调用时,必须运行以下步骤:
如果任一参数为无限或 NaN,则返回。
将 当前变换矩阵 重置为如下描述的矩阵:
a | c | e |
b | d | f |
0 | 0 | 1 |
setTransform(transform)
方法在调用时,必须运行以下步骤:
让 matrix 成为 从 2D 字典创建 DOMMatrix 的结果 transform。
如果 matrix 的一个或多个m11 元素,m12 元素,m21 元素,m22 元素,m41 元素,或m42 元素是无限或 NaN,则返回。
将 当前变换矩阵 重置为 matrix。
resetTransform()
方法在调用时,必须将 当前变换矩阵 重置为单位矩阵。
给定由 transform()
和 setTransform()
方法创建的矩阵,即
a | c | e |
b | d | f |
0 | 0 | 1 |
在变换矩阵相乘后,结果变换后的坐标将是
xnew = a x + c y + e
ynew = b x + d y + f
在 CanvasDrawImage
和 CanvasFillStrokeStyles
接口上的某些方法将联合类型 CanvasImageSource
作为参数。
这种联合类型允许实现以下任一接口的对象用作图像源:
HTMLOrSVGImageElement
(img
或 SVG
image
元素)HTMLVideoElement
(video
元素)HTMLCanvasElement
(canvas
元素)OffscreenCanvas
ImageBitmap
VideoFrame
虽然未正式指定为这样,但 SVG
image
元素预计将几乎与 img
元素实现相同。也就是说,SVG
image
元素共享 img
元素的基本概念和功能。
ImageBitmap
接口可以从许多其他图像表示类型创建,包括 ImageData
。
要检查 image 参数的可用性,image 是 CanvasImageSource
对象,请执行以下步骤:
切换 image:
HTMLOrSVGImageElement
如果 image 的 当前请求 的 状态 是 损坏的,则抛出
"InvalidStateError
" DOMException
。
如果 image 不是 完全可解码的,则返回 bad。
HTMLVideoElement
如果 image 的 readyState
属性为 HAVE_NOTHING
或 HAVE_METADATA
,则返回
bad。
HTMLCanvasElement
OffscreenCanvas
如果 image 的水平尺寸或垂直尺寸等于零,则抛出 "InvalidStateError
" DOMException
。
ImageBitmap
VideoFrame
如果 image 的 [[Detached]] 内部槽值设置为 true,则抛出 "InvalidStateError
" DOMException
。
返回 good。
当 CanvasImageSource
对象表示 HTMLOrSVGImageElement
时,元素的图像必须用作源图像。
具体来说,当 CanvasImageSource
对象表示 HTMLOrSVGImageElement
中的动画图像时,用户代理必须使用动画的默认图像(格式定义的在不支持或禁用动画时使用的图像),或者,如果没有这样的图像,则使用动画的第一帧,当为 CanvasRenderingContext2D
API 渲染图像时。
当 CanvasImageSource
对象表示 HTMLVideoElement
时,调用方法时的 当前播放位置 的帧必须用作渲染 CanvasRenderingContext2D
API 时的源图像,源图像的尺寸必须是 自然宽度 和 自然高度 (即,应用任何纵横比校正后的尺寸) 的 媒体资源。
当 CanvasImageSource
对象表示 HTMLCanvasElement
时,元素的位图必须用作源图像。
当 CanvasImageSource
对象表示正在 渲染
的元素,并且该元素已调整大小时,必须使用源图像的原始图像数据,而不是渲染的图像(例如
宽度
和 高度
属性在为 CanvasRenderingContext2D
API 渲染图像时无效)。
当 CanvasImageSource
对象表示 ImageBitmap
时,对象的位图图像数据必须用作源图像。
当 CanvasImageSource
对象表示 OffscreenCanvas
时,对象的位图必须用作源图像。
当 CanvasImageSource
对象表示 VideoFrame
时,对象的像素数据必须用作源图像,源图像的尺寸必须是对象的 [[显示宽度]] 和 [[显示高度]]。
如果对象 image 不是 origin-clean,切换 image 的类型:
HTMLOrSVGImageElement
image 的 当前请求 的 图像数据 是 CORS-cross-origin。
HTMLVideoElement
image 的 媒体数据 是 CORS-cross-origin。
HTMLCanvasElement
ImageBitmap
OffscreenCanvas
image 的位图的 origin-clean 标志为 false。
context.fillStyle [ = value ]
CanvasRenderingContext2D/fillStyle
Support in all current engines.
返回用于填充形状的当前样式。
可以设置,以更改填充样式。
样式可以是包含 CSS 颜色的字符串,也可以是CanvasGradient
或CanvasPattern
对象。无效值会被忽略。
context.strokeStyle [ = value ]
CanvasRenderingContext2D/strokeStyle
Support in all current engines.
返回用于描边形状的当前样式。
可以设置,以更改描边样式。
样式可以是包含 CSS 颜色的字符串,也可以是CanvasGradient
或CanvasPattern
对象。无效值会被忽略。
实现CanvasFillStrokeStyles
接口的对象具有属性和方法(在本节定义),用于控制对象如何处理形状。
这些对象有相关的填充样式和描边样式值,这些值可以是 CSS 颜色、CanvasPattern
或CanvasGradient
。最初,这两个值都必须是解析字符串"#000000
"的结果。
当值是 CSS 颜色时,用于在位图上绘制时不得受变换矩阵的影响。
当设置为CanvasPattern
或CanvasGradient
对象时,赋值后的对象的更改会影响形状的后续描边或填充。
fillStyle
取值器步骤如下:
fillStyle
设值器步骤如下:
如果给定的值是字符串,则:
如果给定的值是标记为非来源干净的CanvasPattern
对象,则设置this的来源干净标志为 false。
strokeStyle
取值器步骤如下:
strokeStyle
设值器步骤如下:
如果给定的值是字符串,则:
如果给定的值是标记为非来源干净的CanvasPattern
对象,则设置this的来源干净标志为 false。
有三种类型的渐变,线性渐变、径向渐变和锥形渐变,由实现不透明CanvasGradient
接口的对象表示。
一旦创建了渐变(见下文),在渐变上放置停止点以定义颜色如何沿渐变分布。每个停止点的渐变颜色是为该停止点指定的颜色。在每个停止点之间,必须在线性插值的 RGBA 空间内找到用于该偏移量的颜色,而不预乘 alpha 值。在第一个停止点之前,颜色必须是第一个停止点的颜色。在最后一个停止点之后,颜色必须是最后一个停止点的颜色。当没有停止点时,渐变是透明黑色。
gradient.addColorStop(offset, color)
Support in all current engines.
在给定的偏移量处使用给定的颜色为渐变添加一个颜色停止点。0.0 是渐变一端的偏移量,1.0 是渐变另一端的偏移量。
如果偏移量超出范围,则抛出"IndexSizeError
"DOMException
。如果颜色无法解析,则抛出"SyntaxError
"DOMException
。
gradient = context.createLinearGradient(x0, y0, x1, y1)
CanvasRenderingContext2D/createLinearGradient
Support in all current engines.
返回表示沿由参数表示的坐标线绘制的线性渐变的CanvasGradient
对象。
gradient = context.createRadialGradient(x0, y0, r0, x1, y1, r1)
CanvasRenderingContext2D/createRadialGradient
Support in all current engines.
返回表示沿由参数表示的圆锥绘制的径向渐变的CanvasGradient
对象。
如果任一半径为负,则抛出"IndexSizeError
"DOMException
异常。
gradient = context.createConicGradient(startAngle, x, y)
CanvasRenderingContext2D/createConicGradient
Support in all current engines.
返回表示沿由参数表示的中心旋转顺时针绘制的锥形渐变的CanvasGradient
对象。
addColorStop(offset,
color)
方法在CanvasGradient
上调用时,必须运行以下步骤:
如果offset小于 0 或大于 1,则抛出"IndexSizeError
"DOMException
。
让parsed color为解析color的结果。
不传递元素给解析器,因为CanvasGradient
对象是canvas
中立的——一个CanvasGradient
对象由一个canvas
创建,可以被另一个使用,因此在指定颜色时无法知道哪个是“相关元素”。
如果parsed color失败,则抛出"SyntaxError
"DOMException
。
在渐变上添加一个新的停止点,偏移量为offset,颜色为parsed color。
如果在渐变的同一偏移量处添加多个停止点,则它们必须按添加顺序排列,第一个最接近渐变的起点,后续的每一个都在此步骤中相对于该点向终点方向无穷小地移动(实际上导致除第一个和最后一个停止点之外的所有停止点都被忽略)。
createLinearGradient(x0, y0, x1, y1)
方法接受四个参数,表示渐变的起点(x0、y0)和终点(x1、y1)。方法在调用时,必须返回一个用指定线初始化的线性CanvasGradient
。
线性渐变必须以这样的方式渲染:所有在穿过起点和终点的线垂直线上的点的颜色在这些两条线相交的点上具有该点的颜色(颜色来自于上述插值和外推)。在渲染时,线性渐变中的点必须按照当前变换矩阵描述的方式进行变换。
如果x0 = x1且y0 = y1,则线性渐变不绘制任何内容。
createRadialGradient(x0, y0, r0, x1, y1, r1)
方法接受六个参数,前三个表示起始圆的原点(x0、y0)和半径r0,后三个表示终止圆的原点(x1、y1)和半径r1。这些值以坐标空间单位表示。如果r0或r1为负,则必须抛出"IndexSizeError
"DOMException
。否则,方法在调用时,必须返回一个用指定圆初始化的径向CanvasGradient
。
径向渐变必须通过以下步骤渲染:
如果x0 = x1且y0 = y1且r0 = r1,则径向渐变不绘制任何内容。返回。
设x(ω) = (x1 - x0)ω + x0
设y(ω) = (y1 - y0)ω + y0
设r(ω) = (r1 - r0)ω + r0
设在ω处的颜色为该渐变上该位置的颜色(颜色来自于上述插值和外推)。
对于所有ω值,其中r(ω) > 0,从最接近正无穷的ω值开始,到最接近负无穷的ω值结束,绘制半径为r(ω)的圆的圆周,位置为(x(ω),y(ω)),颜色为ω处的颜色,但仅在之前步骤中此渐变渲染未绘制的位图部分上绘制。
这实际上创建了一个由定义渐变的两个圆接触的圆锥,圆锥前面的部分(0.0)使用第一个停止点的颜色,圆锥后面的部分(1.0)使用最后一个停止点的颜色,圆锥外部的区域未受渐变影响(透明黑色)。
然后在渲染时,必须按照当前变换矩阵描述的方式变换结果的径向渐变。
createConicGradient(startAngle,
x, y)
方法接受三个参数,第一个参数startAngle表示渐变开始的角度(以弧度表示),最后两个参数(x、y)表示CSS
像素中渐变的中心。方法在调用时,必须返回一个用指定中心和角度初始化的锥形CanvasGradient
。
它遵循与 CSS 'conic-gradient'相同的渲染规则,并且等同于 CSS 'conic-gradient(from adjustedStartAnglerad at xpx ypx, angularColorStopList)'。其中:
adjustedStartAngle由startAngle + π/2给出;
angularColorStopList由使用CanvasGradient
addColorStop()
添加的颜色停止点给出,颜色停止点偏移量解释为百分比。
渐变必须仅在相关描边或填充效果要求绘制它们的地方绘制。
图案由实现不透明CanvasPattern
接口的对象表示。
pattern = context.createPattern(image, repetition)
CanvasRenderingContext2D/createPattern
Support in all current engines.
返回一个使用给定图像并在由repetition参数给定的方向重复的CanvasPattern
对象。
repetition的允许值为repeat
(两个方向)、repeat-x
(仅水平)、repeat-y
(仅垂直)和no-repeat
(都不)。如果repetition参数为空,则使用值repeat
。
如果图像尚未完全解码,则不会绘制任何内容。如果图像是没有数据的画布,则抛出"InvalidStateError
"DOMException
。
pattern.setTransform(transform)
Support in all current engines.
设置在填充或描边绘制操作期间渲染图案时使用的变换矩阵。
createPattern(image,
repetition)
方法在调用时,必须运行以下步骤:
让usability为检查图像参数 的可用性image的结果。
如果usability为坏,则返回 null。
断言:usability为好。
如果repetition为空字符串,则将其设置为"repeat
"。
如果repetition不等同于之一"repeat
"、"repeat-x
"、"repeat-y
"或"no-repeat
",则抛出"SyntaxError
"DOMException
。
让pattern为一个新的CanvasPattern
对象,图像为image,重复行为由repetition给出。
如果image不是来源干净的,则将pattern标记为不是来源干净。
返回pattern。
在调用createPattern()
方法后,修改创建CanvasPattern
对象时使用的image不得影响CanvasPattern
对象呈现的图案。
图案具有变换矩阵,该矩阵控制在绘制图案时如何使用图案。最初,图案的变换矩阵必须是单位矩阵。
setTransform(transform)
方法在调用时,必须运行以下步骤:
让matrix为从 2D
字典创建DOMMatrix
transform的结果。
如果matrix的一个或多个m11 元素、m12 元素、m21 元素、m22 元素、m41 元素或m42 元素为无穷大或 NaN,则返回。
将图案的变换矩阵重置为matrix。
当在一个区域内渲染图案时,用户代理必须运行以下步骤来确定渲染内容:
创建一个无限的透明黑色位图。
在位图上放置图像的副本,锚定使其左上角位于坐标空间的原点,每个坐标空间单位对应图像的一个CSS
像素,然后如果重复行为为"repeat-x
",则在位图上水平放置重复图像,或者如果重复行为为"repeat-y
",则在位图上垂直放置重复图像,或者如果重复行为为"repeat
",则在位图的所有方向上放置重复图像。
如果原始图像数据是位图图像,则在重复区域的某一点上绘制的值是通过滤镜原始图像数据计算的。当放大时,如果imageSmoothingEnabled
属性设置为
false,则必须使用最近邻插值渲染图像。否则,用户代理可以使用任何滤镜算法(例如双线性插值或最近邻)。支持多种滤镜算法的用户代理可以使用imageSmoothingQuality
属性的值来指导选择滤镜算法。当这样的滤镜算法需要原始图像数据之外的像素值时,必须使用该像素的坐标相对于原始图像的尺寸进行包装的值。(即,滤镜使用“重复”行为,而不管图案的重复行为是什么。)
根据图案的变换矩阵变换生成的位图。
再次变换生成的位图,这次根据当前变换矩阵。
将图案渲染区域之外的图像部分替换为透明黑色。
生成的位图是要渲染的内容,具有相同的原点和相同的比例。
如果在变换矩阵为奇异时使用径向渐变或重复图案,则结果样式必须为透明黑色(否则渐变或图案将折叠为一个点或线,留下其他像素未定义)。线性渐变和实心颜色即使在变换矩阵为奇异时也总是定义所有点。
实现CanvasRect
接口的对象提供了以下方法,用于立即将矩形绘制到位图。这些方法每个都接受四个参数;前两个给出矩形左上角的x和y坐标,后两个分别给出矩形的宽度w和高度h。
当前变换矩阵必须应用到以下四个坐标,这些坐标形成必须关闭的路径以获得指定的矩形:(x, y),(x+w, y),(x+w, y+h),(x, y+h)。
形状在绘制时不会影响当前默认路径,并且受剪裁区域影响,除了clearRect()
,还会受到阴影效果、全局透明度以及当前的合成和混合操作符影响。
context.clearRect(x, y, w, h)
CanvasRenderingContext2D/clearRect
Support in all current engines.
将给定矩形内的所有像素清除为透明黑色。
context.fillRect(x, y, w, h)
CanvasRenderingContext2D/fillRect
Support in all current engines.
使用当前填充样式将给定矩形绘制到位图上。
context.strokeRect(x, y, w, h)
CanvasRenderingContext2D/strokeRect
Support in all current engines.
使用当前描边样式将给定矩形的外框绘制到位图上。
clearRect(x, y, w, h)
方法在调用时,必须执行以下步骤:
如果高度或宽度为零,此方法无效,因为像素集将为空。
fillRect(x, y, w, h)
方法在调用时,必须执行以下步骤:
strokeRect(x, y, w, h)
方法在调用时,必须执行以下步骤:
如果任何参数是无限或NaN,则返回。
采用描绘路径所描述路径的结果,使用CanvasPathDrawingStyles
接口的线样式填充它,并使用this的描边样式。
如果w和h均为零,则路径有一个子路径,只有一个点(x, y),没有线,此方法因此无效(在这种情况下,描绘路径算法返回一个空路径)。
如果w或h之一为零,则路径有一个由两个点组成的子路径,坐标为(x, y)和(x+w, y+h),按该顺序连接的一条直线。
否则,路径有一个由四个点组成的子路径,坐标为(x, y),(x+w, y),(x+w, y+h),和(x, y+h),按该顺序由直线连接。
支持所有当前的引擎。
context.fillText(text, x, y [, maxWidth ])
CanvasRenderingContext2D/fillText
支持所有当前的引擎。
context.strokeText(text, x, y [, maxWidth ])
CanvasRenderingContext2D/strokeText
支持所有当前的引擎。
分别填充或描边给定位置的文本。如果提供了最大宽度,文本将根据需要缩放以适应该宽度。
metrics = context.measureText(text)
CanvasRenderingContext2D/measureText
支持所有当前的引擎 。
返回一个TextMetrics
对象,包含给定文本在当前字体中的度量信息。
metrics.width
支持所有当前的引擎。
metrics.actualBoundingBoxLeft
TextMetrics/actualBoundingBoxLeft
支持所有当前的引擎。
metrics.actualBoundingBoxRight
TextMetrics/actualBoundingBoxRight
支持所有当前的引擎。
metrics.fontBoundingBoxAscent
TextMetrics/fontBoundingBoxAscent
支持所有当前的引擎。
metrics.fontBoundingBoxDescent
TextMetrics/fontBoundingBoxDescent
支持所有当前的引擎。
metrics.actualBoundingBoxAscent
TextMetrics/actualBoundingBoxAscent
支持所有当前的引擎。
metrics.actualBoundingBoxDescent
TextMetrics/actualBoundingBoxDescent
支持所有当前的引擎。
metrics.emHeightAscent
支持所有当前的引擎。
metrics.emHeightDescent
支持所有当前的引擎。
metrics.hangingBaseline
metrics.alphabeticBaseline
TextMetrics/alphabeticBaseline
metrics.ideographicBaseline
TextMetrics/ideographicBaseline
返回以下描述的度量值。
实现CanvasText
接口的对象提供以下方法来渲染文本。
fillText(text, x, y, maxWidth)
和 strokeText(text, x, y, maxWidth)
方法在指定的 (x, y) 坐标处渲染给定的 text,确保文本的宽度不会超过 maxWidth(如果指定),使用当前的font
、textAlign
和 textBaseline
值。具体来说,当调用这些方法时,用户代理必须执行以下步骤:
如果任何参数是无限或 NaN,则返回。
运行文本准备算法,传递给它text,实现CanvasText
接口的对象,以及(如果提供)maxWidth
参数。令glyphs为结果。
将glyphs中的形状按当前变换矩阵变换后的形状进行绘制,其中每个CSS 像素在glyphs的坐标空间单位上绘制。
对于fillText()
,应用this
的填充样式fill style到形状,并忽略this
的描边样式stroke style。对于strokeText()
,反之亦然:应用this
的描边样式stroke style到使用CanvasText
接口的对象的线条样式上进行路径追踪,并忽略this
的填充样式fill style。
measureText(text)
方法的步骤是运行文本准备算法,传递给它text和实现CanvasText
接口的对象,然后使用返回的内联框返回一个新的TextMetrics
对象,其成员行为如下所述:[CSS]
width
属性
actualBoundingBoxLeft
属性从textAlign
属性给定的对齐点到给定文本的边界矩形左侧的平行于基线的距离,以CSS 像素为单位;正数表示从给定对齐点向左的距离。
该值和下一个值(actualBoundingBoxRight
)的总和可能会超过内联框的宽度(width
),尤其是带有倾斜字体的字符可能会超过其前进宽度。
actualBoundingBoxRight
属性从textAlign
属性给定的对齐点到给定文本的边界矩形右侧的平行于基线的距离,以CSS 像素为单位;正数表示从给定对齐点向右的距离。
fontBoundingBoxAscent
属性从textBaseline
属性指示的水平线到第一个可用字体的上升度量的距离,以CSS 像素为单位;正数表示从给定基线向上的距离。
此值和下一个值在渲染背景时很有用,即使渲染的确切文本发生变化,高度也必须一致。actualBoundingBoxAscent
属性(及其对应的下降属性)在绘制特定文本的边界框时很有用。
fontBoundingBoxDescent
属性从textBaseline
属性指示的水平线到第一个可用字体的下降度量的距离,以CSS 像素为单位;正数表示
从给定基线向下的距离。
actualBoundingBoxAscent
属性从textBaseline
属性指示的水平线到给定文本的边界矩形顶部的距离,以CSS像素为单位;正数表示从给定基线向上的距离。
这个数字会根据输入文本的不同而有很大的变化,即使第一个指定的字体覆盖了输入中的所有字符。例如,一个小写字母“o”从字母基线的actualBoundingBoxAscent
将小于大写字母“F”的值。这个值很容易为负数;例如,当给定文本只是一个逗号“,
”时,从em框顶部(textBaseline
值“top
”)到边界矩形顶部的距离可能(除非字体非常不寻常)为负数。
actualBoundingBoxDescent
属性从textBaseline
属性指示的水平线到给定文本的边界矩形底部的距离,以CSS 像素为单位;正数表示从给定基线向下的距离。
emHeightAscent
属性从textBaseline
属性指示的水平线到内联框中
em 方块最高顶部的距离,以CSS 像素为单位;正数表示给定基线在 em
方块顶部下方(因此该值通常为正数)。如果给定基线是 em 方块顶部,则为零;如果给定基线是 em
方块的中间,则为字体大小的一半。
emHeightDescent
属性从textBaseline
属性指示的水平线到内联框中
em 方块最低底部的距离,以CSS 像素为单位;正数表示给定基线在 em
方块底部上方。(如果给定基线是 em 方块的底部,则为零。)
hangingBaseline
属性从textBaseline
属性指示的水平线到内联框的悬挂基线的距离,以CSS 像素为单位;正数表示给定基线在悬挂基线下方。(如果给定基线是悬挂基线,则为零。)
alphabeticBaseline
属性从textBaseline
属性指示的水平线到内联框的字母基线的距离,以CSS 像素为单位;正数表示给定基线在字母基线下方。(如果给定基线是字母基线,则为零。)
ideographicBaseline
属性从textBaseline
属性指示的水平线到内联框的表意文字基线的距离,以CSS 像素为单位;正数表示给定基线在表意文字基线下方。(如果给定基线是表意文字基线,则为零。)
使用fillText()
和strokeText()
绘制的字形可能会溢出由字体大小(em
方框大小)和measureText()
返回的宽度(文本宽度)给出的框。作者应使用上述边界框值以解决此问题。
未来版本的 2D 上下文 API 可能提供一种将使用 CSS 渲染的文档片段直接渲染到画布的方法。这将优先于提供多行布局的专用方法。
实现 CanvasDrawPath
接口的对象具有一个当前默认路径。只有一个当前默认路径,它不是绘图状态的一部分。当前默认路径是一个路径,如上所述。
context.beginPath()
CanvasRenderingContext2D/beginPath
支持所有当前引擎。
重置当前默认路径。
context.fill([ fillRule ])
支持所有当前引擎。
context.fill(path [, fillRule ])
使用当前填充样式根据给定的填充规则填充当前默认路径或给定路径的子路径。
context.stroke()
CanvasRenderingContext2D/stroke
支持所有当前引擎。
context.stroke(path)
使用当前描边样式对当前默认路径或给定路径的子路径进行描边。
context.clip([ fillRule ])
支持所有当前引擎。
context.clip(path [, fillRule ])
进一步使用给定填充规则约束裁剪区域到当前默认路径或给定路径。
context.isPointInPath(x, y [, fillRule ])
CanvasRenderingContext2D/isPointInPath
支持所有当前引擎。
context.isPointInPath(path, x, y [, fillRule ])
如果给定点位于当前默认路径或给定路径的区域内,则返回true,使用给定的填充规则来确定路径内的点。
context.isPointInStroke(x, y)
CanvasRenderingContext2D/isPointInStroke
支持所有当前引擎。
context.isPointInStroke(path, x, y)
如果给定点位于使用当前描边样式描边后的当前默认路径或给定路径的区域内,则返回true。
beginPath()
方法步骤是清空this的当前默认路径中的子路径列表,使其再次变为零子路径。
以下方法定义使用术语预期路径表示Path2D
-或-null
path,它的意思是path本身(如果它是Path2D
对象),或是当前默认路径。
当预期路径是Path2D
对象时,
它的子路径的坐标和线条必须根据对象上实现CanvasTransform
接口时使用的方法的当前变换矩阵进行变换(不影响Path2D
对象本身)。当预期路径是当前默认路径时,不受变换影响。(这是因为构建时变换已经影响了当前默认路径,所以在绘制时应用它会导致双重变换。)
fill(fillRule)
方法步骤是运行填充步骤,给定this、null和fillRule。
fill(path, fillRule)
方法步骤是运行填充步骤,给定this、path和fillRule。
填充步骤,给定CanvasDrawPath
context、Path2D
-或-null
path和填充规则
fillRule,是填充所有path的预期路径的子路径,使用context的填充样式,并使用fillRule指示的填充规则。在填充时必须隐式关闭开放的子路径(不影响实际子路径)。
stroke()
方法步骤是运行描边步骤,给定this和null。
stroke(path)
方法步骤是运行描边步骤,给定this和path。
描边步骤,给定CanvasDrawPath
context和Path2D
-或-null
path,是path的预期路径,使用context的线条样式,根据它的CanvasPathDrawingStyles
mixin进行描边,然后使用context的描边样式填充结果路径,使用非零缠绕规则。
由于定义了描路径的算法,一个描边操作中的路径重叠部分被视为其联合绘制的部分。
描边样式在绘制过程中受变换影响,即使使用当前默认路径。
路径在填充或描边时必须绘制而不影响当前默认路径或任何Path2D
对象,并且必须受阴影效果、全局透明度、裁剪区域和当前合成和混合操作的约束。(变换的影响如上所述,基于使用的路径而有所不同。)
clip(fillRule)
方法步骤是运行裁剪步骤,给定this、null和fillRule。
clip(path, fillRule)
方法步骤是运行裁剪步骤,给定this、path和fillRule。
裁剪步骤,给定CanvasDrawPath
context、Path2D
-或-null
path和填充规则
fillRule,是通过计算context的当前裁剪区域和path的预期路径描述的区域的交集来创建一个新的裁剪区域,使用fillRule指示的填充规则。计算裁剪区域时必须隐式关闭开放的子路径,不影响实际子路径。新裁剪区域替换当前裁剪区域。
当上下文初始化时,其当前裁剪区域必须设置为最大的无限表面(即默认情况下,不进行裁剪)。
isPointInPath(x, y,
fillRule)
方法步骤是返回运行点是否在路径中步骤的结果,给定this、null、x、y和
fillRule。
isPointInPath(path, x,
y, fillRule)
方法步骤是返回运行点是否在路径中步骤的结果,给定this、path、x、
y和fillRule。
点是否在路径中步骤,给定CanvasDrawPath
context、
Path2D
-或-null
path、两个数字x和y及填充规则
fillRule,是:
如果x或y 是无限或NaN,则返回false。
如果给定的x和y坐标作为画布坐标空间中的坐标,不受当前变换影响,则根据fillRule指示的填充规则,该点是否位于path的预期路径内,则返回true。计算路径内区域时必须隐式关闭开放的子路径,不影响实际子路径。路径本身的点必须被视为在路径内。
返回false。
isPointInStroke(x, y)
方法步骤是返回运行点是否在描边中步骤的结果,给定
this、null、x和y。
isPointInStroke(path, x,
y)
方法步骤是返回运行点是否在描边中步骤的结果,给定this、path、x和y。
点是否在描边中步骤,给定CanvasDrawPath
context、Path2D
-或-null
path和两个数字x
和y,是:
如果x或y是无限或NaN,则返回false。
如果给定的x和y坐标作为画布坐标空间中的坐标,不受当前变换影响,则根据描路径预期路径path,使用非零缠绕规则,并使用context的线条样式根据它的CanvasPathDrawingStyles
mixin,结果路径内的点必须被视为在路径内,则返回true。
返回false。
此画布
元素有几个复选框。与路径相关的命令被突出显示:
< canvas height = 400 width = 750 >
< label >< input type = checkbox id = showA > Show As</ label >
< label >< input type = checkbox id = showB > Show Bs</ label >
<!-- ... -->
</ canvas >
< script >
function drawCheckbox( context, element, x, y, paint) {
context. save();
context. font = '10px sans-serif' ;
context. textAlign = 'left' ;
context. textBaseline = 'middle' ;
var metrics = context. measureText( element. labels[ 0 ]. textContent);
if ( paint) {
context. beginPath();
context. strokeStyle = 'black' ;
context. rect( x- 5 , y- 5 , 10 , 10 );
context. stroke();
if ( element. checked) {
context. fillStyle = 'black' ;
context. fill();
}
context. fillText( element. labels[ 0 ]. textContent, x+ 5 , y);
}
context. beginPath();
context. rect( x- 7 , y- 7 , 12 + metrics. width+ 2 , 14 );
context. drawFocusIfNeeded( element);
context. restore();
}
function drawBase() { /* ... */ }
function drawAs() { /* ... */ }
function drawBs() { /* ... */ }
function redraw() {
var canvas = document. getElementsByTagName( 'canvas' )[ 0 ];
var context = canvas. getContext( '2d' );
context. clearRect( 0 , 0 , canvas. width, canvas. height);
drawCheckbox( context, document. getElementById( 'showA' ), 20 , 40 , true );
drawCheckbox( context, document. getElementById( 'showB' ), 20 , 60 , true );
drawBase();
if ( document. getElementById( 'showA' ). checked)
drawAs();
if ( document. getElementById( 'showB' ). checked)
drawBs();
}
function processClick( event) {
var canvas = document. getElementsByTagName( 'canvas' )[ 0 ];
var context = canvas. getContext( '2d' );
var x = event. clientX;
var y = event. clientY;
var node = event. target;
while ( node) {
x -= node. offsetLeft - node. scrollLeft;
y -= node. offsetTop - node. scrollTop;
node = node. offsetParent;
}
drawCheckbox( context, document. getElementById( 'showA' ), 20 , 40 , false );
if ( context. isPointInPath( x, y) )
document. getElementById( 'showA' ). checked = ! ( document. getElementById( 'showA' ). checked);
drawCheckbox( context, document. getElementById( 'showB' ), 20 , 60 , false );
if ( context. isPointInPath( x, y) )
document. getElementById( 'showB' ). checked = ! ( document. getElementById( 'showB' ). checked);
redraw();
}
document. getElementsByTagName( 'canvas' )[ 0 ]. addEventListener( 'focus' , redraw, true );
document. getElementsByTagName( 'canvas' )[ 0 ]. addEventListener( 'blur' , redraw, true );
document. getElementsByTagName( 'canvas' )[ 0 ]. addEventListener( 'change' , redraw, true );
document. getElementsByTagName( 'canvas' )[ 0 ]. addEventListener( 'click' , processClick, false );
redraw();
</ script >
context.drawFocusIfNeeded(element)
CanvasRenderingContext2D/drawFocusIfNeeded
支持所有当前引擎。
context.drawFocusIfNeeded(path, element)
如果element处于焦点状态,则在path周围绘制一个焦点环,遵循平台的焦点环惯例。
实现CanvasUserInterface
接口的对象提供以下方法来绘制焦点环。
drawFocusIfNeeded(element)
方法步骤是根据需要绘制焦点,给定this、element和this的当前默认路径。
drawFocusIfNeeded(path, element)
方法步骤是根据需要绘制焦点,给定this、element和path。
要根据需要绘制焦点,给定实现CanvasUserInterface
的context对象、元素element和路径path:
沿path绘制适当样式的焦点环,遵循平台惯例。
某些平台只会在从键盘聚焦的元素周围绘制焦点环,而不会在从鼠标聚焦的元素周围绘制焦点环。其他平台则只在启用相关辅助功能时才会在某些元素周围绘制焦点环。此API旨在遵循这些惯例。鼓励实现基于元素聚焦方式的区分的用户代理根据触发调用的用户交互事件(如果有)来分类focus()
方法驱动的焦点。
焦点环不应受到阴影效果、全局透明度、当前合成和混合操作、填充样式、描边样式或CanvasPathDrawingStyles
、CanvasTextDrawingStyles
接口中的任何成员的影响,但应受到裁剪区域的约束。(变换的影响如上所述,基于使用的路径而有所不同。)
在绘制焦点环时,用户代理不应隐式关闭预期路径中的开放子路径。
不过,这可能是一个无关紧要的问题。例如,如果焦点环被绘制为沿预期路径的点的轴对齐边界矩形,那么子路径是否关闭没有影响。本规范故意不具体规定如何绘制焦点环:用户代理应遵循其平台的本机惯例。
本节使用的“通知用户”并不意味着任何持久状态变化。例如,这可能意味着调用系统辅助功能API来通知放大工具等辅助技术,以便用户的放大镜移动到画布的给定区域。然而,它并不将路径与元素关联,或提供触觉反馈区域等。
实现CanvasDrawImage
接口的对象有drawImage()
方法来绘制图像。
此方法可以使用三种不同的参数集调用:
drawImage(image, dx, dy)
drawImage(image, dx, dy, dw, dh)
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
context.drawImage(image, dx, dy)
CanvasRenderingContext2D/drawImage
支持所有当前引擎。
context.drawImage(image, dx, dy, dw, dh)
context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
将给定图像绘制到画布上。参数解释如下:
如果图像尚未完全解码,则不会绘制任何内容。如果图像是没有数据的画布,则抛出DOMException
中的"InvalidStateError
"。
当调用drawImage()
方法时,用户代理必须执行以下步骤:
如果任何参数是无限或NaN,则返回。
让usability成为检查image可用性的结果。
如果usability是bad,则返回(不绘制任何内容)。
如下建立源矩形和目标矩形:
如果未指定,则dw和dh参数必须默认为sw和sh的值,解释为图像中的一个CSS像素被视为输出位图坐标空间中的一个单位。如果省略sx、sy、sw和sh参数,则它们必须默认为0、0、图像像素中的图像自然宽度和图像像素中的图像自然高度。如果图像没有自然尺寸,则必须使用具体对象尺寸,如使用CSS“具体对象尺寸解析”算法确定的,指定大小既没有确定的宽度也没有确定的高度,也没有任何附加约束,对象的自然属性是image参数的属性,默认对象尺寸是 输出位图的尺寸。[CSSIMAGES]
源矩形是四个点(sx,sy)、(sx+sw,sy)、(sx+sw,sy+sh)、(sx,sy+sh)的矩形。
目标矩形是四个点(dx,dy)、(dx+dw,dy)、(dx+dw,dy+dh)、(dx,dy+dh)的矩形。
当源矩形在源图像之外时,源矩形必须被裁剪到源图像,目标矩形必须按相同比例裁剪。
当目标矩形在目标图像之外时(输出位图),落在输出位图之外的像素将被丢弃,就像目标是一个无限画布,其渲染被裁剪到输出位图的尺寸一样。
如果sw或sh参数之一为零,则返回。不绘制任何内容。
在应用当前变换矩阵到目标矩形后,将由源矩形指定的image参数区域绘制在渲染上下文的输出位图的目标矩形区域上。
即使给定的尺寸为负,图像数据也必须按原始方向处理。
当放大时,如果imageSmoothingEnabled
属性设置为true,用户代理应尝试在图像缩放时应用平滑算法。支持多种过滤算法的用户代理可以使用imageSmoothingQuality
属性的值来指导过滤算法的选择,当imageSmoothingEnabled
属性设置为true时。否则,图像必须使用最邻近插值法进行渲染。
本规范没有定义缩小图像时的确切算法,或当imageSmoothingEnabled
属性设置为true时放大图像的确切算法。
当canvas
元素绘制到自身时,绘图模型要求在绘制图像之前复制源,因此可以将canvas
元素的部分复制到其自身的重叠部分。
如果原始图像数据是位图图像,则目标矩形某点的绘制值是通过过滤原始图像数据计算的。用户代理可以使用任何过滤算法(例如双线性插值或最邻近)。当过滤算法需要原始图像数据之外的像素值时,必须使用最近的边缘像素的值。(即,过滤器使用“夹边”行为。)当过滤算法需要源矩形之外但在原始图像数据之内的像素值时,必须使用原始图像数据的值。
因此,部分或整体缩放图像将产生相同的效果。这意味着当从单个精灵表中缩放精灵时,精灵表中的相邻图像可能会相互干扰。这可以通过确保精灵表中的每个精灵都被透明黑色边框包围来避免,或者将要缩放的精灵复制到临时canvas
元素中,并从那里绘制缩放后的精灵来避免。
如果image不是原点清洁的,则将CanvasRenderingContext2D
的origin-clean标志设置为false。
imagedata = new ImageData(sw, sh [, settings])
支持所有当前引擎。
返回具有给定尺寸和由settings指示的颜色空间的ImageData
对象。返回对象中的所有像素都是透明黑色。
如果宽度或高度参数为零,则抛出"IndexSizeError
" DOMException
。
imagedata = new ImageData(data, sw [, sh [, settings ] ])
使用Uint8ClampedArray
参数中提供的数据,并使用给定的尺寸和由settings指示的颜色空间,返回ImageData
对象。
由于数据中的每个像素由四个数字表示,因此数据的长度需要是给定宽度的四倍的倍数。如果同时提供了高度,那么长度需要正好是宽度乘以高度乘以4。
如果给定的数据和尺寸不能一致地解释,或者任一尺寸为零,则抛出"IndexSizeError
" DOMException
。
imagedata = context.createImageData(imagedata)
imagedata = context.createImageData(sw, sh [, settings])
CanvasRenderingContext2D/createImageData
支持所有当前引擎。
返回具有给定尺寸的ImageData
对象。返回对象的颜色空间是context的颜色空间,除非被settings覆盖。返回对象中的所有像素都是透明黑色。
如果宽度或高度参数为零,则抛出"IndexSizeError
" DOMException
。
imagedata = context.getImageData(sx, sy, sw, sh [, settings])
CanvasRenderingContext2D/getImageData
支持所有当前引擎。
返回包含给定矩形位图图像数据的ImageData
对象。返回对象的颜色空间是context的颜色空间,除非被settings覆盖。
如果宽度或高度参数为零,则抛出"IndexSizeError
" DOMException
。
imagedata.width
支持所有当前引擎。
imagedata.height
支持所有当前引擎。
返回ImageData
对象中的数据的实际尺寸,以像素为单位。
imagedata.data
支持所有当前引擎。
返回以RGBA顺序表示的、作为一维数组存储的数据,整数范围在0到255之间。
imagedata.colorSpace
返回像素的颜色空间。
context.putImageData(imagedata, dx, dy [, dirtyX, dirtyY, dirtyWidth, dirtyHeight ])
CanvasRenderingContext2D/putImageData
支持所有当前引擎。
将给定ImageData
对象中的数据绘制到位图上。如果提供了脏矩形,则只绘制该矩形中的像素。
对于此方法调用,globalAlpha
和globalCompositeOperation
属性,以及阴影属性,都将被忽略;画布中的像素将被整个替换,没有合成、alpha混合、阴影等。
如果imagedata对象的data
属性值的[[ViewedArrayBuffer]]内部插槽被分离,则抛出"InvalidStateError
" DOMException
。
实现CanvasImageData
接口的对象提供以下方法来读取和写入位图的像素数据。
new ImageData(sw, sh, settings)
构造函数步骤如下:
如果sw和sh中的一个或两个为零,则抛出"IndexSizeError
" DOMException
。
new ImageData(data, sw, sh, settings)
构造函数步骤如下:
让length为data中的字节数。
如果length不是四的非零整数倍,则抛出"InvalidStateError
" DOMException
。
将length除以四。
如果length不是sw的整数倍,则抛出"IndexSizeError
" DOMException
。
在此步骤中,长度保证大于零(否则第二步会中止步骤),所以如果sw为零,此步骤将抛出异常并返回。
将height设为length除以sw。
如果提供了sh且其值不等于height,则抛出"IndexSizeError
" DOMException
。
初始化this,给定sw、sh、settings设置为settings,以及source设置为data。
此步骤不会将this的数据设置为data的副本。它将其设置为传递为data的实际Uint8ClampedArray
对象。
createImageData(sw, sh, settings)
方法步骤如下:
如果sw和sh中的一个或两个为零,则抛出"IndexSizeError
" DOMException
。
初始化newImageData,给定sw的绝对值、sh的绝对值、settings设置为settings,以及defaultColorSpace设置为this的颜色空间。
将newImageData的图像数据初始化为透明黑色。
返回newImageData。
createImageData(imagedata)
方法步骤如下:
初始化newImageData,给定imagedata的width
属性值、imagedata的height
属性值,以及defaultColorSpace设置为imagedata的colorSpace
属性值。
将newImageData的图像数据初始化为透明黑色。
返回newImageData。
getImageData(sx, sy, sw, sh, settings)
方法步骤如下:
如果sw或sh参数为零,则抛出"IndexSizeError
" DOMException
。
如果CanvasRenderingContext2D
的origin-clean标志设置为false,则抛出"SecurityError
" DOMException
。
初始化imageData,给定sw、sh、settings设置为settings,以及defaultColorSpace设置为this的颜色空间。
设源矩形为由四个点(sx、sy)、(sx+sw、sy)、(sx+sw、sy+sh)、(sx、sy+sh)组成的矩形。
将imageData的像素值设置为this的输出位图中由位图坐标空间单位中源矩形指定的区域的像素,转换为imageData的颜色空间
,使用'相对色度'渲染意图。
返回imageData。
要初始化ImageData
对象imageData,给定正整数行数rows、每行像素数pixelsPerRow、可选ImageDataSettings
settings、可选Uint8ClampedArray
source和可选PredefinedColorSpace
defaultColorSpace:
如果提供了source,则将imageData的data
属性初始化为source。
否则(未提供source),将imageData的data
属性初始化为一个新的Uint8ClampedArray
对象。Uint8ClampedArray
对象必须使用新的画布像素ArrayBuffer
作为其存储,并且必须有零开始偏移量和长度等于其存储长度,以字节为单位。画布像素ArrayBuffer
必须具有正确的大小来存储rows
× pixelsPerRow像素。
如果画布像素ArrayBuffer
无法分配,则重新抛出JavaScript引发的RangeError
并返回。
将imageData的width
属性初始化为pixelsPerRow。
将imageData的height
属性初始化为rows。
如果提供了settings并且settings["colorSpace
"]存在,则将imageData的colorSpace
属性初始化为settings["colorSpace
"]。
否则,如果提供了defaultColorSpace,则将imageData的colorSpace
属性初始化为defaultColorSpace。
否则,将imageData的colorSpace
属性初始化为"srgb"。
ImageData
对象是可序列化对象。它们的序列化步骤,给定value和serialized,如下:
将serialized.[[Width]]设置为value的width
属性值。
将serialized.[[Height]]设置为value的height
属性值。
将serialized.[[ColorSpace]]设置为value的colorSpace
属性值。
它们的反序列化步骤,给定serialized、value 和targetRealm,如下:
将value的width
属性初始化为serialized.[[Width]]。
将value的height
属性初始化为serialized.[[Height]]。
将value的colorSpace
属性初始化为serialized.[[ColorSpace]]。
画布像素ArrayBuffer
是一个ArrayBuffer
,其数据从左到右表示,从上到下逐行排列,从左上角开始,每个像素的红色、绿色、蓝色和alpha分量按顺序给出。此数组中表示的每个像素的每个分量必须在0到255的范围内,表示该分量的8位值。分量必须从0开始为左上角像素的红色分量,连续分配索引。
putImageData()
方法将数据从ImageData
结构写回渲染上下文的输出位图。其参数为:imagedata、dx、dy、dirtyX、dirtyY、dirtyWidth和dirtyHeight。
当省略此方法的最后四个参数时,必须假定它们的值分别为0、0、imagedata结构的width
成员和imagedata结构的height
成员。
调用此方法时,必须按以下步骤操作:
设buffer为imagedata的data
属性值的[[ViewedArrayBuffer]]内部插槽。
如果IsDetachedBuffer(buffer)为true,则抛出"InvalidStateError
" DOMException
。
如果dirtyWidth为负,则设dirtyX为dirtyX+dirtyWidth,并将dirtyWidth设为dirtyWidth的绝对值。
如果dirtyHeight为负,则设dirtyY为dirtyY+dirtyHeight,并将dirtyHeight设为dirtyHeight的绝对值。
如果dirtyX为负,则将dirtyWidth设为dirtyWidth+dirtyX,并将dirtyX设为零。
如果dirtyY为负,则将dirtyHeight设为dirtyHeight+dirtyY,并将dirtyY设为零。
如果dirtyX+dirtyWidth大于imagedata参数的width
属性的值,则将dirtyWidth设为该width
属性的值减去dirtyX的值。
如果dirtyY+dirtyHeight大于imagedata参数的height
属性的值,则将dirtyHeight设为该height
属性的值减去dirtyY的值。
如果经过这些更改后,dirtyWidth或dirtyHeight为负或为零,则在不影响任何位图的情况下返回。
对于所有整数值的x和y,其中dirtyX ≤ x
< dirtyX+dirtyWidth
和dirtyY ≤ y
< dirtyY+dirtyHeight
,将imagedata数据结构的画布像素ArrayBuffer
中像素的四个通道复制到渲染上下文的输出位图中具有坐标(dx+x、dy+y)的像素。
由于在颜色空间之间转换和从预乘alpha颜色值转换的有损性质,刚刚使用putImageData()
设置的像素,如果不是完全不透明的,可能会以不同的值返回到等效的getImageData()
。
当前路径、变换矩阵、阴影属性、全局alpha、剪裁区域和当前合成和混合操作符不得影响本节中描述的方法。
在以下示例中,脚本生成一个ImageData
对象,以便可以在其上绘制。
// canvas is a reference to a <canvas> element
var context = canvas. getContext( '2d' );
// create a blank slate
var data = context. createImageData( canvas. width, canvas. height);
// create some plasma
FillPlasma( data, 'green' ); // green plasma
// add a cloud to the plasma
AddCloud( data, data. width/ 2 , data. height/ 2 ); // put a cloud in the middle
// paint the plasma+cloud on the canvas
context. putImageData( data, 0 , 0 );
// support methods
function FillPlasma( data, color) { ... }
function AddCloud( data, x, y) { ... }
这是一个使用getImageData()
和putImageData()
来实现边缘检测滤镜的示例。
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< title > Edge detection demo</ title >
< script >
var image = new Image();
function init() {
image. onload = demo;
image. src = "image.jpeg" ;
}
function demo() {
var canvas = document. getElementsByTagName( 'canvas' )[ 0 ];
var context = canvas. getContext( '2d' );
// draw the image onto the canvas
context. drawImage( image, 0 , 0 );
// get the image data to manipulate
var input = context. getImageData( 0 , 0 , canvas. width, canvas. height);
// get an empty slate to put the data into
var output = context. createImageData( canvas. width, canvas. height);
// alias some variables for convenience
// In this case input.width and input.height
// match canvas.width and canvas.height
// but we'll use the former to keep the code generic.
var w = input. width, h = input. height;
var inputData = input. data;
var outputData = output. data;
// edge detection
for ( var y = 1 ; y < h- 1 ; y += 1 ) {
for ( var x = 1 ; x < w- 1 ; x += 1 ) {
for ( var c = 0 ; c < 3 ; c += 1 ) {
var i = ( y* w + x) * 4 + c;
outputData[ i] = 127 + - inputData[ i - w* 4 - 4 ] - inputData[ i - w* 4 ] - inputData[ i - w* 4 + 4 ] +
- inputData[ i - 4 ] + 8 * inputData[ i] - inputData[ i + 4 ] +
- inputData[ i + w* 4 - 4 ] - inputData[ i + w* 4 ] - inputData[ i + w* 4 + 4 ];
}
outputData[( y* w + x) * 4 + 3 ] = 255 ; // alpha
}
}
// put the image data back after manipulation
context. putImageData( output, 0 , 0 );
}
</ script >
</ head >
< body onload = "init()" >
< canvas ></ canvas >
</ body >
</ html >
这是一个在绘制纯色并使用getImageData()
读取结果时应用颜色空间转换的示例。
<!DOCTYPE HTML>
< html lang = "en" >
< title > Color space image data demo</ title >
< canvas ></ canvas >
< script >
const canvas = document. querySelector( 'canvas' );
const context = canvas. getContext( '2d' , { colorSpace: 'display-p3' });
// Draw a red rectangle. Note that the hex color notation
// specifies sRGB colors.
context. fillStyle = "#FF0000" ;
context. fillRect( 0 , 0 , 64 , 64 );
// Get the image data.
const pixels = context. getImageData( 0 , 0 , 1 , 1 );
// This will print 'display-p3', reflecting the default behavior
// of returning image data in the canvas's color space.
console. log( pixels. colorSpace);
// This will print the values 234, 51, and 35, reflecting the
// red fill color, converted to 'display-p3'.
console. log( pixels. data[ 0 ]);
console. log( pixels. data[ 1 ]);
console. log( pixels. data[ 2 ]);
</ script >
context.globalAlpha [ = value ]
CanvasRenderingContext2D/globalAlpha
支持所有当前引擎。
返回当前应用于渲染操作的全局alpha值。
可以设置,以更改全局alpha值。超出0.0到1.0范围的值将被忽略。
context.globalCompositeOperation [ = value ]
CanvasRenderingContext2D/globalCompositeOperation
支持所有当前引擎。
返回当前的合成和混合操作符, 来自定义的值 在合成和混合中定义。[COMPOSITE]
可以设置,以更改当前的合成和混合操作符。 未知 值将被忽略。
实现CanvasCompositing
接口的对象有一个全局alpha值和一个当前的合成和混合操作符值,这两个值都会影响此对象上的所有绘图操作。
全局alpha值为在将形状和图像合成到输出位图之前应用的alpha值。 该值的范围是0.0(完全透明)到1.0(无额外透明度)。初始值必须为1.0。
globalAlpha
getter步骤是返回
this的全局alpha值。
globalAlpha
setter步骤是:
当前的合成和混合操作符值
控制在应用全局alpha和当前转换矩阵后,如何将形状和图像绘制到输出位图上。最初,它必须设置为"source-over
"。
globalCompositeOperation
getter
步骤是返回this的当前的合成和混合操作符。
globalCompositeOperation
setter步骤是:
如果给定值不等同于任何<blend-mode>或<composite-mode>属性定义的值,则返回。[COMPOSITE]
否则,将this的当前的合成和混合操作符 设置为给定值。
context.imageSmoothingEnabled [ = value ]
CanvasRenderingContext2D/imageSmoothingEnabled
支持所有当前引擎。
返回当前是否在放大图像时平滑图像的偏好设置,具体体现在图案填充和drawImage()
方法上,如果它们的像素与显示不完全对齐,则尝试平滑图像。
可以设置,以更改图像是否平滑(true)或不平滑(false)。
context.imageSmoothingQuality [ = value ]
CanvasRenderingContext2D/imageSmoothingQuality
返回当前的图像平滑质量偏好设置。
实现CanvasImageSmoothing
接口的对象有控制图像平滑如何执行的属性。
imageSmoothingEnabled
属性,在获取时,必须返回最后设置的值。在设置时,必须设置为新值。
当实现CanvasImageSmoothing
接口的对象被创建时,
属性必须设置为true。
imageSmoothingQuality
属性,在获取时,必须返回最后设置的值。在设置时,必须设置为新值。
当实现CanvasImageSmoothing
接口的对象被创建时,
属性必须设置为"低
"。
实现CanvasShadowStyles
接口的对象上的所有绘图操作都受到四个全局阴影属性的影响。
context.shadowColor [ = value ]
CanvasRenderingContext2D/shadowColor
支持所有当前引擎。
返回当前阴影颜色。
可以设置以更改阴影颜色。无法解析为CSS颜色的值将被忽略。
context.shadowOffsetX [ = value ]
CanvasRenderingContext2D/shadowOffsetX
支持所有当前引擎。
context.shadowOffsetY [ = value ]
CanvasRenderingContext2D/shadowOffsetY
支持所有当前引擎。
返回当前阴影偏移。
可以设置以更改阴影偏移。不是有限数的值将被忽略。
context.shadowBlur [ = value ]
CanvasRenderingContext2D/shadowBlur
支持所有当前引擎。
返回当前应用于阴影的模糊级别。
可以设置以更改模糊级别。不是有限数且大于或等于零的值将被忽略。
实现CanvasShadowStyles
接口的对象具有相关联的阴影颜色,这是一个CSS颜色。
最初,它必须是透明黑色。
shadowColor
的getter步骤是返回序列化this的阴影颜色,并请求HTML兼容的序列化。
shadowColor
setter步骤是:
让parsedValue成为使用context解析给定值的结果,如果不是null。
如果parsedValue失败,则返回。
shadowOffsetX
和shadowOffsetY
属性分别指定阴影在水平和垂直方向上的偏移距离。它们的值是坐标空间单位。它们不受当前转换矩阵的影响。
当上下文被创建时,阴影偏移属性最初必须具有值0。
在获取时,它们必须返回当前值。在设置时,正在设置的属性必须设置为新值,除非该值为无限或NaN,在这种情况下,必须忽略新值。
shadowBlur
属性指定模糊效果的级别。(单位不映射到坐标空间单位,并且不受当前转换矩阵的影响。)
当上下文被创建时,shadowBlur
属性最初必须具有值0。
在获取时,属性必须返回其当前值。在设置时,属性必须设置为新值,除非该值为负、无限或NaN,在这种情况下,必须忽略新值。
仅当阴影颜色的alpha分量的不透明度分量不为零且shadowBlur
不为零,或者shadowOffsetX
不为零,或者
shadowOffsetY
不为零时才绘制阴影。
绘制阴影时,必须按以下步骤渲染:
让A成为一个无限的透明黑色位图,其上已渲染了创建阴影的源图像。
让B成为一个无限的透明黑色位图,其坐标空间和原点与A相同。
将A的alpha通道复制到B,并在正x方向上偏移shadowOffsetX
,在正
y方向上偏移shadowOffsetY
。
如果shadowBlur
大于0:
让σ为shadowBlur
值的一半。
对B执行2D高斯模糊,使用σ作为标准偏差。
用户代理可以将σ的值限制为特定实现的最大值,以避免在高斯模糊操作期间超出硬件限制。
将B中每个像素的红色、绿色和蓝色分量设置为阴影颜色的红色、绿色和蓝色分量(分别)。
将B中每个像素的alpha分量乘以阴影颜色的alpha分量。
阴影在位图B中,并作为下面描述的绘图模型的一部分进行渲染。
如果当前的合成和混合操作符是"copy
",
那么阴影实际上不会渲染(因为形状会覆盖阴影)。
实现CanvasFilters
接口的对象上的所有绘图操作都受全局filter
属性的影响。
context.filter [ = value ]
CanvasRenderingContext2D/filter
返回当前滤镜。
可以设置以更改滤镜。值可以是字符串"none
"或可解析为<filter-value-list>的字符串。其他值将被忽略。
这些对象具有相关联的当前滤镜,这是一个字符串。最初,当前滤镜设置为字符串"none
"。
每当当前滤镜的值为字符串"none
"时,将禁用该上下文的滤镜。
filter
setter步骤是:
将parsedValue设为按照CSS语法解析给定值为<filter-value-list>的结果。如果存在任何独立于属性的样式表语法,如“inherit”或“initial”,则此解析必须返回失败。
如果parsedValue失败,则返回。
尽管
context.
将禁用该上下文的滤镜,
filter
= "none
"context.
、
filter
= ""context.
、
和
filter
= nullcontext.
都被视为无法解析的输入,并且当前滤镜的值保持不变。
filter
=
undefined
在当前滤镜值中使用的坐标被解释为一个像素等于一个SVG用户空间单位和一个画布坐标空间单位。滤镜坐标不受当前变换矩阵的影响。当前变换矩阵仅影响滤镜的输入。滤镜应用在 输出位图的坐标空间中。
当当前滤镜的值是可解析为定义了使用百分比或使用'em'或'ex'单位长度的<filter-value-list>的字符串时,这些长度必须相对于设置该属性时
计算值的'font-size'属性进行解释。如果计算值对于特定情况未定义(例如,因为字体样式源对象不是元素或没有被渲染),则相对关键字必须相对于
font
属性的默认值进行解释。不支持“larger”和“smaller”关键字。
如果当前滤镜的值是可解析为引用同一文档中的SVG滤镜的<filter-value-list>的字符串,并且该SVG滤镜发生变化,则在下一次绘图操作时使用更改后的滤镜。
如果当前滤镜的值是可解析为引用外部资源文档中的SVG滤镜的<filter-value-list>的字符串,并且在调用绘图操作时尚未加载该文档,则绘图操作必须在没有滤镜的情况下继续进行。
本节是非规范性的。
由于在外部定义的滤镜加载完成之前,绘图是使用滤镜值"none
"进行的,因此作者可能希望在进行绘图操作之前确定此类滤镜是否已加载完成。实现这一目标的一种方法是在同一页面内的某个其他元素中加载外部定义的滤镜,该元素会发送load
事件(例如,SVG
use
元素),并等待load
事件被触发。
当绘制形状或图像时,用户代理必须按照给定的顺序执行以下步骤(或表现得像这样做):
如前几节所述,将形状或图像渲染到一个无限的透明黑色位图上,创建图像A。对于形状,必须遵守当前的填充、描边和线条样式,并且描边本身也必须受到当前变换矩阵的影响。
当当前滤镜设置为"none
"以外的值且其引用的所有外部定义滤镜(如果有)都在当前已加载的文档中时,则使用图像A作为当前滤镜的输入,创建图像B。如果当前滤镜是可解析为<filter-value-list>的字符串,则以与SVG相同的方式使用当前滤镜进行绘制。
否则,让B为A的别名。
绘制阴影时,使用当前阴影样式从图像B渲染阴影,创建图像C。
绘制阴影时,使用当前的合成和混合操作符,在剪裁区域内将C复合到当前的输出位图上。
将B中每个像素的alpha分量乘以全局alpha
。
使用当前的合成和混合操作符,在剪裁区域内将B复合到当前的输出位图上。
当canvas是交互式时,作者应在元素的后备内容中包含可聚焦元素,对应canvas的每个可聚焦部分,如上面的示例。
在渲染聚焦环时,为确保聚焦环具有本地聚焦环的外观,作者应使用drawFocusIfNeeded()
方法,并传递要为其绘制环的元素。此方法仅在元素被聚焦时绘制聚焦环,因此可以在绘制元素时随时调用此方法,而无需先检查元素是否被聚焦。
作者应避免使用canvas
元素实现文本编辑控件。这样做有很多缺点:
这是一项巨大的工作,强烈建议作者通过使用input
元素、textarea
元素或contenteditable
属性来避免这些工作。
本节是非规范性的。
下面是一个使用canvas绘制漂亮的发光线条的脚本示例。
< canvas width = "800" height = "450" ></ canvas >
< script >
var context = document. getElementsByTagName( 'canvas' )[ 0 ]. getContext( '2d' );
var lastX = context. canvas. width * Math. random();
var lastY = context. canvas. height * Math. random();
var hue = 0 ;
function line() {
context. save();
context. translate( context. canvas. width/ 2 , context. canvas. height/ 2 );
context. scale( 0.9 , 0.9 );
context. translate( - context. canvas. width/ 2 , - context. canvas. height/ 2 );
context. beginPath();
context. lineWidth = 5 + Math. random() * 10 ;
context. moveTo( lastX, lastY);
lastX = context. canvas. width * Math. random();
lastY = context. canvas. height * Math. random();
context. bezierCurveTo( context. canvas. width * Math. random(),
context. canvas. height * Math. random(),
context. canvas. width * Math. random(),
context. canvas. height * Math. random(),
lastX, lastY);
hue = hue + 10 * Math. random();
context. strokeStyle = 'hsl(' + hue + ', 50%, 50%)' ;
context. shadowColor = 'white' ;
context. shadowBlur = 10 ;
context. stroke();
context. restore();
}
setInterval( line, 50 );
function blank() {
context. fillStyle = 'rgba(0,0,0,0.1)' ;
context. fillRect( 0 , 0 , context. canvas. width, context. canvas. height);
}
setInterval( blank, 40 );
</ script >
用于canvas
的2D渲染上下文常用于基于精灵的游戏。以下示例演示了这一点:
以下是此示例的源代码:
<!DOCTYPE HTML>
< html lang = "en" >
< meta charset = "utf-8" >
< title > Blue Robot Demo</ title >
< style >
html { overflow : hidden ; min-height : 200 px ; min-width : 380 px ; }
body { height : 200 px ; position : relative ; margin : 8 px ; }
. buttons { position : absolute ; bottom : 0 px ; left : 0 px ; margin : 4 px ; }
</ style >
< canvas width = "380" height = "200" ></ canvas >
< script >
var Landscape = function ( context, width, height) {
this . offset = 0 ;
this . width = width;
this . advance = function ( dx) {
this . offset += dx;
};
this . horizon = height * 0.7 ;
// This creates the sky gradient (from a darker blue to white at the bottom)
this . sky = context. createLinearGradient( 0 , 0 , 0 , this . horizon);
this . sky. addColorStop( 0.0 , 'rgb(55,121,179)' );
this . sky. addColorStop( 0.7 , 'rgb(121,194,245)' );
this . sky. addColorStop( 1.0 , 'rgb(164,200,214)' );
// this creates the grass gradient (from a darker green to a lighter green)
this . earth = context. createLinearGradient( 0 , this . horizon, 0 , height);
this . earth. addColorStop( 0.0 , 'rgb(81,140,20)' );
this . earth. addColorStop( 1.0 , 'rgb(123,177,57)' );
this . paintBackground = function ( context, width, height) {
// first, paint the sky and grass rectangles
context. fillStyle = this . sky;
context. fillRect( 0 , 0 , width, this . horizon);
context. fillStyle = this . earth;
context. fillRect( 0 , this . horizon, width, height- this . horizon);
// then, draw the cloudy banner
// we make it cloudy by having the draw text off the top of the
// canvas, and just having the blurred shadow shown on the canvas
context. save();
context. translate( width- (( this . offset+ ( this . width* 3.2 )) % ( this . width* 4.0 )) + 0 , 0 );
context. shadowColor = 'white' ;
context. shadowOffsetY = 30 + this . horizon/ 3 ; // offset down on canvas
context. shadowBlur = '5' ;
context. fillStyle = 'white' ;
context. textAlign = 'left' ;
context. textBaseline = 'top' ;
context. font = '20px sans-serif' ;
context. fillText( 'WHATWG ROCKS' , 10 , - 30 ); // text up above canvas
context. restore();
// then, draw the background tree
context. save();
context. translate( width- (( this . offset+ ( this . width* 0.2 )) % ( this . width* 1.5 )) + 30 , 0 );
context. beginPath();
context. fillStyle = 'rgb(143,89,2)' ;
context. lineStyle = 'rgb(10,10,10)' ;
context. lineWidth = 2 ;
context. rect( 0 , this . horizon+ 5 , 10 , - 50 ); // trunk
context. fill();
context. stroke();
context. beginPath();
context. fillStyle = 'rgb(78,154,6)' ;
context. arc( 5 , this . horizon- 60 , 30 , 0 , Math. PI* 2 ); // leaves
context. fill();
context. stroke();
context. restore();
};
this . paintForeground = function ( context, width, height) {
// draw the box that goes in front
context. save();
context. translate( width- (( this . offset+ ( this . width* 0.7 )) % ( this . width* 1.1 )) + 0 , 0 );
context. beginPath();
context. rect( 0 , this . horizon - 5 , 25 , 25 );
context. fillStyle = 'rgb(220,154,94)' ;
context. lineStyle = 'rgb(10,10,10)' ;
context. lineWidth = 2 ;
context. fill();
context. stroke();
context. restore();
};
};
</ script >
< script >
var BlueRobot = function () {
this . sprites = new Image();
this . sprites. src = 'blue-robot.png' ; // this sprite sheet has 8 cells
this . targetMode = 'idle' ;
this . walk = function () {
this . targetMode = 'walk' ;
};
this . stop = function () {
this . targetMode = 'idle' ;
};
this . frameIndex = {
'idle' : [ 0 ], // first cell is the idle frame
'walk' : [ 1 , 2 , 3 , 4 , 5 , 6 ], // the walking animation is cells 1-6
'stop' : [ 7 ], // last cell is the stopping animation
};
this . mode = 'idle' ;
this . frame = 0 ; // index into frameIndex
this . tick = function () {
// this advances the frame and the robot
// the return value is how many pixels the robot has moved
this . frame += 1 ;
if ( this . frame >= this . frameIndex[ this . mode]. length) {
// we've reached the end of this animation cycle
this . frame = 0 ;
if ( this . mode != this . targetMode) {
// switch to next cycle
if ( this . mode == 'walk' ) {
// we need to stop walking before we decide what to do next
this . mode = 'stop' ;
} else if ( this . mode == 'stop' ) {
if ( this . targetMode == 'walk' )
this . mode = 'walk' ;
else
this . mode = 'idle' ;
} else if ( this . mode == 'idle' ) {
if ( this . targetMode == 'walk' )
this . mode = 'walk' ;
}
}
}
if ( this . mode == 'walk' )
return 8 ;
return 0 ;
},
this . paint = function ( context, x, y) {
if ( ! this . sprites. complete) return ;
// draw the right frame out of the sprite sheet onto the canvas
// we assume each frame is as high as the sprite sheet
// the x,y coordinates give the position of the bottom center of the sprite
context. drawImage( this . sprites,
this . frameIndex[ this . mode][ this . frame] * this . sprites. height, 0 , this . sprites. height, this . sprites. height,
x- this . sprites. height/ 2 , y- this . sprites. height, this . sprites. height, this . sprites. height);
};
};
</ script >
< script >
var canvas = document. getElementsByTagName( 'canvas' )[ 0 ];
var context = canvas. getContext( '2d' );
var landscape = new Landscape( context, canvas. width, canvas. height);
var blueRobot = new BlueRobot();
// paint when the browser wants us to, using requestAnimationFrame()
function paint() {
context. clearRect( 0 , 0 , canvas. width, canvas. height);
landscape. paintBackground( context, canvas. width, canvas. height);
blueRobot. paint( context, canvas. width/ 2 , landscape. horizon* 1.1 );
landscape. paintForeground( context, canvas. width, canvas. height);
requestAnimationFrame( paint);
}
paint();
// but tick every 100ms, so that we don't slow down when we don't paint
setInterval( function () {
var dx = blueRobot. tick();
landscape. advance( dx);
}, 100 );
</ script >
< p class = "buttons" >
< input type = button value = "Walk" onclick = "blueRobot.walk()" >
< input type = button value = "Stop" onclick = "blueRobot.stop()" >
< footer >
< small > Blue Robot Player Sprite by < a href = "https://johncolburn.deviantart.com/" > JohnColburn</ a > .
Licensed under the terms of the Creative Commons Attribution Share-Alike 3.0 Unported license.</ small >
< small > This work is itself licensed under a < a rel = "license" href = "https://creativecommons.org/licenses/by-sa/3.0/" > Creative
Commons Attribution-ShareAlike 3.0 Unported License</ a > .</ small >
</ footer >
ImageBitmap
渲染上下文
ImageBitmapRenderingContext
是一个性能导向的接口,提供了一种低开销的方法来显示ImageBitmap
对象的内容。它使用传输语义来减少整体内存消耗。与drawImage()
方法不同,它通过避免中间合成来简化性能。
例如,使用img
元素作为获取图像资源到canvas中的中间体,会导致内存中同时存在两个解码图像的副本:img
元素的副本和canvas的后台存储中的副本。当处理非常大的图像时,这种内存开销可能是无法接受的。这可以通过使用ImageBitmapRenderingContext
来避免。
使用ImageBitmapRenderingContext
,以下是以节省内存和CPU的方式将图像转码为JPEG格式的方法:
createImageBitmap( inputImageBlob). then( image => {
const canvas = document. createElement( 'canvas' );
const context = canvas. getContext( 'bitmaprenderer' );
context. transferFromImageBitmap( image);
canvas. toBlob( outputJPEGBlob => {
// Do something with outputJPEGBlob.
}, 'image/jpeg' );
});
ImageBitmapRenderingContext
接口
所有当前引擎都支持。
[Exposed =(Window ,Worker )]
interface ImageBitmapRenderingContext {
readonly attribute (HTMLCanvasElement or OffscreenCanvas ) canvas ;
undefined transferFromImageBitmap (ImageBitmap ? bitmap );
};
dictionary ImageBitmapRenderingContextSettings {
boolean alpha = true ;
};
context = canvas.getContext('bitmaprenderer' [, { [ alpha: false ] } ])
返回一个ImageBitmapRenderingContext
对象,该对象永久绑定到特定的canvas
元素。
如果提供了alpha
设置并将其设置为false,则canvas将始终保持不透明。
context.canvas
返回canvas
元素,该元素与上下文绑定。
context.transferFromImageBitmap(imageBitmap)
ImageBitmapRenderingContext/transferFromImageBitmap
所有当前引擎都支持。
将底层位图数据
从imageBitmap传输到context,并且该位图成为canvas
元素的内容,该元素与context绑定。
context.transferFromImageBitmap(null)
将 context 所绑定的 canvas
元素的内容替换为一个 透明黑色
位图,其大小对应于 width
和 height
属性的内容。
canvas
属性必须返回对象创建时初始化的值。
ImageBitmapRenderingContext
对象有一个输出位图,它是对位图数据的引用。
一个 ImageBitmapRenderingContext
对象有一个 位图模式,它可以设置为 有效 或 空白。值为 有效 表示上下文的
输出位图
引用通过 transferFromImageBitmap()
获取的 位图数据。值为 空白 表示上下文的
输出位图
是默认的透明位图。
一个 ImageBitmapRenderingContext
对象也有一个 alpha 标志,它可以设置为 true 或 false。当一个 ImageBitmapRenderingContext
对象的 alpha 标志设置为 false
时,上下文所绑定的 canvas
元素的内容是通过将上下文的 输出位图
复合到同样大小的 不透明黑色 位图上,并使用 source-over
合成操作符获取的。如果 alpha 标志设置为
true,则
输出位图
用作上下文所绑定的 canvas
元素的内容。[COMPOSITE]
只要能通过其他手段更有效地获得等效结果,就应省略合成到不透明黑色位图的步骤。
当用户代理需要设置ImageBitmapRenderingContext
的输出位图时,使用context参数,该参数是ImageBitmapRenderingContext
对象,并且有一个可选参数bitmap,该参数指的是位图数据,则必须执行以下步骤:
如果未提供bitmap参数,则:
如果提供了bitmap参数,则:
ImageBitmapRenderingContext
创建算法,该算法传递target和options,包括以下步骤:
将options转换为字典类型ImageBitmapRenderingContextSettings
的结果,得到settings。
(这可能会抛出异常。)
让context成为一个新的ImageBitmapRenderingContext
对象。
初始化context的canvas
属性,使其指向target。
将context的输出位图设置为与target的位图相同(使它们共享)。
运行步骤以设置ImageBitmapRenderingContext
的输出位图,使用context。
初始化context的alpha标志为true。
处理settings的每个成员,如下所示:
alpha
返回context。
transferFromImageBitmap(bitmap)
方法,在调用时必须执行以下步骤:
让bitmapContext成为ImageBitmapRenderingContext
对象,
该对象上调用了transferFromImageBitmap()
方法。
如果bitmap为null,则运行步骤以设置ImageBitmapRenderingContext
的输出位图,
使用bitmapContext作为context参数且没有bitmap参数,然后返回。
如果bitmap的[[Detached]]内部槽的值设置为true,则抛出“InvalidStateError
”DOMException
。
运行步骤以设置ImageBitmapRenderingContext
的输出位图,
使用context参数等于bitmapContext,bitmap参数引用bitmap的底层位图数据。
将bitmap的[[Detached]]内部槽的值设置为true。
取消设置bitmap的位图数据。
OffscreenCanvas
接口所有当前引擎均支持。
typedef (OffscreenCanvasRenderingContext2D or ImageBitmapRenderingContext or WebGLRenderingContext or WebGL2RenderingContext or GPUCanvasContext ) OffscreenRenderingContext ;
dictionary ImageEncodeOptions {
DOMString type = "image/png";
unrestricted double quality ;
};
enum OffscreenRenderingContextId { " 2d " , " bitmaprenderer " , " webgl " , " webgl2 " , " webgpu " };
[Exposed =(Window ,Worker ), Transferable ]
interface OffscreenCanvas : EventTarget {
constructor ([EnforceRange ] unsigned long long width , [EnforceRange ] unsigned long long height );
attribute [EnforceRange ] unsigned long long width ;
attribute [EnforceRange ] unsigned long long height ;
OffscreenRenderingContext ? getContext (OffscreenRenderingContextId contextId , optional any options = null );
ImageBitmap transferToImageBitmap ();
Promise <Blob > convertToBlob (optional ImageEncodeOptions options = {});
attribute EventHandler oncontextlost ;
attribute EventHandler oncontextrestored ;
};
OffscreenCanvas
是一个 EventTarget
,
所以
OffscreenCanvasRenderingContext2D
和 WebGL 都可以向其触发事件。
OffscreenCanvasRenderingContext2D
可以触发 contextlost
和 contextrestored
,
而 WebGL 可以触发 webglcontextlost
和 webglcontextrestored
。
[WEBGL]
OffscreenCanvas
对象用于创建渲染上下文,类似于
HTMLCanvasElement
,
但与 DOM 无关。这使得在 workers 中使用 canvas 渲染上下文成为可能。
OffscreenCanvas
对象可能持有一个对 占位 canvas
元素 的弱引用,该元素通常位于 DOM 中,其嵌入内容由 OffscreenCanvas
对象提供。OffscreenCanvas
对象的位图被推送到 占位
canvas
元素,作为
OffscreenCanvas
的
相关代理的 事件循环的 更新渲染
步骤的一部分。
offscreenCanvas = new OffscreenCanvas(width,
height)
OffscreenCanvas/OffscreenCanvas
在所有当前引擎中支持。
返回一个新的 OffscreenCanvas
对象,该对象未链接到 占位 canvas
元素,
其位图的大小由 width 和 height 参数决定。
context = offscreenCanvas.getContext(contextId [,
options ])
在所有当前引擎中支持。
返回一个用于在 OffscreenCanvas
对象上绘制的 API 对象。
contextId 指定了所需的 API:"2d
"、
"bitmaprenderer
"、
"webgl
"、
"webgl2
",
或 "webgpu
"。
options 由该 API 处理。
本规范定义了如下 "2d
"
上下文,
它与从 canvas
元素创建的 "2d
"
上下文类似但有所不同。WebGL 规范定义了
"webgl
"
和 "webgl2
"
上下文。WebGPU 定义了
"webgpu
"
上下文。[WEBGL]
[WEBGPU]
如果画布已经使用另一种上下文类型初始化(例如,在获取
"2d
"
上下文后再获取
"webgl
"
上下文),则返回 null。
一个 OffscreenCanvas
对象内部有一个 位图,在对象创建时进行初始化。该位图的宽度和高度等于该 位图 的宽度和高度等于 width
和 height
属性的值。最初,所有位图的像素都是 透明黑色。
一个 OffscreenCanvas
对象可以绑定一个渲染上下文。最初,它没有绑定任何渲染上下文。为了跟踪它是否有渲染上下文以及渲染上下文的类型,OffscreenCanvas
对象还有一个 上下文模式,初始值为 无,但可以通过本规范定义的算法更改为 2d、bitmaprenderer、
webgl、webgl2、webgpu 或 分离。
构造函数 OffscreenCanvas(width,
height)
在调用时,必须创建一个新的 OffscreenCanvas
对象,并将其 位图
初始化为一个矩形数组,
其中包含由 width 和 height 指定尺寸的 透明黑色 像素;并将其
width
和 height
属性初始化为 width 和
height。
OffscreenCanvas
对象是 可转移的。它们的 转移步骤 给定
value 和
dataHolder,如下:
如果 value 的 上下文模式 不等于 无,则抛出一个 "InvalidStateError
" DOMException
。
将 width 和 height 设为 value 的 位图 的尺寸。
取消设置 value 的 位图。
将 dataHolder 的 [[Width]] 设置为 width,将 dataHolder 的 [[Height]] 设置为 height。
将 dataHolder 的 [[PlaceholderCanvas]] 设置为对 value 的 占位 canvas
元素 的弱引用,如果
value 有占位元素,则设置,否则为 null。
它们的 接收步骤,给定 dataHolder 和 value,如下:
将 value 的 位图 初始化为一个矩形数组, 其中包含 透明黑色 像素,其宽度由 dataHolder 的 [[Width]] 和高度由 dataHolder 的 [[Height]] 确定。
如果 dataHolder 的 [[PlaceholderCanvas]] 不为 null,则将 value 的 占位
canvas
元素 设置为
dataHolder 的 [[PlaceholderCanvas]](同时保持弱引用语义)。
当调用 OffscreenCanvas
对象的 getContext(contextId,
options)
方法时,必须运行以下步骤:
如果 options 不是 对象,则将 options 设置为 null。
将 options 设置为 转换 options 为 JavaScript 值的结果。
根据以下表格中与此 OffscreenCanvas
对象的 上下文模式 匹配的列标题和与 contextId
匹配的行标题,运行步骤:
无 | 2d | bitmaprenderer | webgl 或 webgl2 | webgpu | 分离 | |
---|---|---|---|---|---|---|
"2d "
|
|
返回上次使用相同第一个参数调用该方法时返回的相同对象。 | 返回 null。 | 返回 null。 | 返回 null。 |
抛出 "InvalidStateError " DOMException 。
|
"bitmaprenderer "
|
|
返回 null。 | 返回上次使用相同第一个参数调用该方法时返回的相同对象。 | 返回 null。 | 返回 null。 |
抛出 "InvalidStateError " DOMException 。
|
"webgl " 或 "webgl2 "
|
返回 null。 | 返回 null。 | 返回上次使用相同第一个参数调用该方法时返回的相同值。 | 返回 null。 |
抛出 "InvalidStateError " DOMException 。
|
|
"webgpu "
|
|
返回 null。 | 返回 null。 | 返回 null。 | 返回上次使用相同第一个参数调用该方法时返回的相同值。 |
抛出 "InvalidStateError " DOMException 。
|
offscreenCanvas.width [
= value ]
支持所有当前引擎。
offscreenCanvas.height [
= value ]
支持所有当前引擎。
这些属性返回 OffscreenCanvas
对象的 bitmap
的尺寸。
如果将 width
或 height
属性设置为新值或与之前相同的值,并且 OffscreenCanvas
对象的 上下文模式 为 2d,则将渲染上下文重置为默认状态并根据 width
和 height
的新值调整 OffscreenCanvas
对象的 bitmap 尺寸。
“webgl
”
和 “webgl2
”
上下文的调整行为由 WebGL 规范定义。[WEBGL]
“webgpu
”
上下文的调整行为由 WebGPU 规范定义。[WEBGPU]
如果更改了 OffscreenCanvas
对象的尺寸,并且该对象有一个 占位 canvas
元素,那么占位 canvas
元素 的 自然大小 仅会在
OffscreenCanvas
的 相关代理的 事件循环 的 渲染更新 步骤中进行更新。
promise = offscreenCanvas.convertToBlob([options])
支持所有当前引擎。
返回一个 promise,该 promise 将使用一个新的 Blob
对象,该对象表示包含 OffscreenCanvas
对象中图像的文件。
参数(如果提供)是一个控制要创建的图像文件的编码选项的字典。type
字段指定文件格式,默认值为 "image/png
";如果请求的类型不受支持,则也使用该类型。如果图像格式支持可变质量(例如
"image/jpeg
"),则
quality
字段是一个介于 0.0 到 1.0 之间的数字,表示所需的图像质量级别。
canvas.transferToImageBitmap()
OffscreenCanvas/transferToImageBitmap
支持所有当前引擎。
返回一个新创建的 ImageBitmap
对象,其中包含 OffscreenCanvas
对象中的图像。OffscreenCanvas
对象中的图像将被新空白图像替换。
convertToBlob(options)
方法,
在调用时,必须执行以下步骤:
如果此 OffscreenCanvas
对象的 [[Detached]]
内部槽设置为 true,那么返回 一个被拒绝的 promise,其中包含一个
"InvalidStateError
" DOMException
。
如果此 OffscreenCanvas
对象的 context mode 是 2d
且渲染上下文的 bitmap 的 origin-clean 标志设置为 false,那么返回
一个被拒绝的 promise,其中包含一个 "SecurityError
"
DOMException
。
如果此 OffscreenCanvas
对象的 bitmap
没有像素(即它的水平
维度或垂直维度为零),那么返回 一个被拒绝的 promise,其中包含一个
"IndexSizeError
" DOMException
。
让 bitmap 成为此 OffscreenCanvas
对象的 bitmap
的副本。
让 result 成为一个新的 promise 对象。
并行运行以下步骤:
让 file 成为 bitmap 的文件序列化,带有
options 的 type
和 quality
(如果存在)。
在元素任务队列中排队 在
画布 blob 序列化任务源 中,给 canvas
元素执行以下步骤:
如果 file 为 null,则使用
"EncodingError
" DOMException
拒绝 result。
否则,使用一个新的 Blob
对象解析 result,该对象在此 OffscreenCanvas
对象的 相关领域
中创建,表示 file。
[FILEAPI]
返回 result。
transferToImageBitmap()
方法,
在调用时,必须执行以下步骤:
如果此 OffscreenCanvas
对象的 [[Detached]]
内部槽设置为 true,那么抛出 "InvalidStateError
"
DOMException
。
如果此 OffscreenCanvas
对象的 context mode 设置为 none,那么抛出
"InvalidStateError
" DOMException
。
让 image 成为一个新创建的 ImageBitmap
对象,该对象引用与此 OffscreenCanvas
对象的 bitmap
相同的底层位图数据。
将此 OffscreenCanvas
对象的 bitmap
设置为引用一个新创建的 bitmap,其维度和颜色空间与之前的
bitmap 相同,并且其像素初始化为
透明黑,如果渲染上下文的 不透明黑,则初始化为不透明黑。
这意味着如果此 OffscreenCanvas
的渲染上下文是
WebGLRenderingContext
,
则 preserveDrawingBuffer
的值将无效。
[WEBGL]
返回 image。
以下是所有实现 OffscreenCanvas
接口的对象必须支持的 事件处理器(及其对应的 事件处理器事件类型),作为 事件处理器IDL属性:
事件处理器 | 事件处理器事件类型 |
---|---|
oncontextlost |
contextlost
|
oncontextrestored |
contextrestored
|
OffscreenCanvasRenderingContext2D
支持所有当前的引擎。
[Exposed =(Window ,Worker )]
interface OffscreenCanvasRenderingContext2D {
readonly attribute OffscreenCanvas canvas ;
};
OffscreenCanvasRenderingContext2D includes CanvasState ;
OffscreenCanvasRenderingContext2D includes CanvasTransform ;
OffscreenCanvasRenderingContext2D includes CanvasCompositing ;
OffscreenCanvasRenderingContext2D includes CanvasImageSmoothing ;
OffscreenCanvasRenderingContext2D includes CanvasFillStrokeStyles ;
OffscreenCanvasRenderingContext2D includes CanvasShadowStyles ;
OffscreenCanvasRenderingContext2D includes CanvasFilters ;
OffscreenCanvasRenderingContext2D includes CanvasRect ;
OffscreenCanvasRenderingContext2D includes CanvasDrawPath ;
OffscreenCanvasRenderingContext2D includes CanvasText ;
OffscreenCanvasRenderingContext2D includes CanvasDrawImage ;
OffscreenCanvasRenderingContext2D includes CanvasImageData ;
OffscreenCanvasRenderingContext2D includes CanvasPathDrawingStyles ;
OffscreenCanvasRenderingContext2D includes CanvasTextDrawingStyles ;
OffscreenCanvasRenderingContext2D includes CanvasPath ;
OffscreenCanvasRenderingContext2D
对象是一个用于绘制到 OffscreenCanvas 对象的 bitmap
的渲染上下文。 它与 CanvasRenderingContext2D
对象相似,但有以下不同:
不支持 用户界面 功能;
其 canvas
属性指的是 OffscreenCanvas
对象,而不是 canvas
元素;
一个 OffscreenCanvasRenderingContext2D
对象有一个在对象创建时初始化的 位图。
这个 位图 有一个可以设置为 true 或 false 的 原点清晰 标志。最初,当创建其中一个位图时,其 原点清晰 标志必须设置为 true。
一个 OffscreenCanvasRenderingContext2D
对象也有一个可以设置为 true 或 false 的 alpha 标志。最初,当上下文创建时,其 alpha 标志必须设置为 true。当一个
OffscreenCanvasRenderingContext2D
对象的 alpha
标志设置为 false 时,其 alpha 通道必须固定为
1.0(完全不透明),并且尝试更改任何像素的 alpha 组件必须被静默忽略。
一个 OffscreenCanvasRenderingContext2D
对象也有一个类型为 预定义颜色空间
的 颜色空间 设置。上下文的 位图 的颜色空间设置为上下文的 颜色空间。
一个 OffscreenCanvasRenderingContext2D
对象有一个 关联的 OffscreenCanvas
对象,即创建该 OffscreenCanvasRenderingContext2D
对象的 OffscreenCanvas
对象。
offscreenCanvas = offscreenCanvasRenderingContext2D.canvas
离屏 2D 上下文创建算法,传递一个 target(一个 OffscreenCanvas
对象)和一些可选参数,包括以下步骤:
如果算法传递了一些参数,则让 arg 为第一个这样的参数。否则,让 arg 为未定义。
让 settings 为 将
arg 转换为字典类型 CanvasRenderingContext2DSettings
的结果。(这可能会抛出异常)。
让 context 为一个新的 OffscreenCanvasRenderingContext2D
对象。
设置 context 的 关联的 OffscreenCanvas
对象 为 target。
设置 context 的 颜色空间 为
settings["colorSpace
"]。
设置 context 的 位图 为一个新创建的位图,其尺寸由 target
的
width
和 height
属性指定,并将 target 的位图设置为相同的位图(以便它们共享)。
如果 context 的 alpha 标志设置为 true,初始化 context 的 位图 的所有像素为 透明黑色。否则,初始化像素为 不透明黑色。
返回 context。
建议实现短路 窗口事件循环 的图形更新步骤,以便将 占位
canvas
元素
的内容更新到显示。这可能意味着,例如,位图内容被直接复制到映射到 占位 canvas
元素
的物理显示位置的图形缓冲区。这种或类似的短路方法可以显著减少显示延迟,特别是在 OffscreenCanvas
从 worker 事件循环 更新且 窗口事件循环
忙碌的情况下。然而,这样的捷径不能有任何脚本可观察的副作用。这意味着提交的位图仍然需要发送到 占位 canvas
元素,以防元素用作 CanvasImageSource
、ImageBitmapSource
或调用 toDataURL()
或 toBlob()
。
canvas
属性在获取时,必须返回这个 OffscreenCanvasRenderingContext2D
的 关联的 OffscreenCanvas
对象。
canvas
API
提供了指定画布后台存储色彩空间的机制。所有 canvas API 的默认后台存储色彩空间是 'srgb'。
当将画布渲染到输出设备时,必须对画布的后台存储应用色彩空间转换。该色彩空间转换必须与对具有相同色彩空间配置文件的img
元素所应用的色彩空间转换相同。
在向2D上下文绘制内容时,所有输入必须在绘制前转换到上下文的色彩空间。梯度颜色停止点的插值必须在转换到上下文的色彩空间后进行。Alpha 混合必须在转换到上下文的色彩空间后进行。
不存在颜色空间未定义的 2D 上下文输入。CSS 颜色的颜色空间在 CSS Color 中定义。未指定色彩配置文件信息的图像的颜色空间假定为 'srgb',如 CSS Color 的 未标记颜色的颜色空间 部分所指定。[CSSCOLOR]
当用户代理要根据type和可选的quality创建位图作为文件的序列化时,它必须创建一个type指定格式的图像文件。如果在创建图像文件过程中发生错误(例如内部编码器错误),则序列化的结果为null。[PNG]
图像文件的像素数据必须是按一个图像像素对应一个坐标空间单位比例缩放的位图像素数据,并且如果所使用的文件格式支持编码分辨率元数据,则分辨率必须为96dpi(一个图像像素对应一个CSS像素)。
如果提供了type,则它必须被解释为一个MIME类型,指定要使用的格式。如果该类型有任何参数,则必须视为不支持。
例如,值"image/png
"意味着生成PNG图像,值"image/jpeg
"意味着生成JPEG图像,而值"image/svg+xml
"意味着生成SVG图像(这将要求用户代理跟踪位图的生成方式,这是一个不太可能但潜在的很棒的功能)。
用户代理必须支持PNG("image/png
")。用户代理可以支持其他类型。如果用户代理不支持请求的类型,则它必须使用PNG格式创建文件。[PNG]
用户代理必须在确定是否支持该类型之前,将提供的类型转换为ASCII小写。
对于不支持alpha通道的图像类型,序列化的图像必须是位图图像,使用不透明黑色背景通过source-over合成操作器合成。
对于支持颜色配置文件的图像类型,序列化的图像必须包含一个指示底层位图色彩空间的颜色配置文件。对于不支持颜色配置文件的图像类型,序列化的图像必须使用色彩空间转换,转换为'srgb'色彩空间,并使用'相对比色法'的渲染意图。
因此,在2D上下文中,调用drawImage()
方法将toDataURL()
或toBlob()
方法的输出渲染到画布上,给定适当的尺寸,除了可能将画布的颜色剪裁到更窄的色域外,没有可见效果。
如果type是支持可变质量的图像格式(例如"image/jpeg
"),quality被给定,并且type不是"image/png
",那么,如果Type(quality)为Number,并且quality在0.0到1.0范围内(含),用户代理必须将quality视为期望的质量水平。否则,用户代理必须使用其默认质量值,就好像没有给出quality参数一样。
在此使用类型测试,而不是简单地将quality声明为Web IDLdouble
,是一个历史遗留问题。
不同的实现对“质量”可能有略微不同的解释。当未指定质量时,使用一个实现特定的默认值,该值在压缩率、图像质量和编码时间之间代表一个合理的折衷。
canvas
元素的安全性本节为非规范性内容。
信息泄漏可能发生在来自一个源的脚本可以访问来自另一个源(不同源)的图像信息(例如读取像素)时。
为减轻这一风险,使用canvas
元素、OffscreenCanvas
对象和ImageBitmap
对象的位图被定义为具有指示它们是否源清洁的标志。所有位图在开始时其源清洁标志设置为true。当使用跨源图像时,该标志设置为false。
toDataURL()
、toBlob()
和getImageData()
方法检查该标志,并会抛出一个"SecurityError
" DOMException
而不是泄露跨源数据。
origin-clean标志的值从源的位图通过ImageBitmap
对象通过createImageBitmap()
传播到新的ImageBitmap
对象。相反,如果源图像是ImageBitmap
对象,其位图的origin-clean标志设置为false,那么目标canvas
元素的位图将通过drawImage
将其origin-clean标志设置为false。
在某些情况下,该标志可以被重置;例如,当更改绑定到CanvasRenderingContext2D
的canvas
元素的宽度
或高度
内容属性值时,位图被清除,其源清洁标志被重置。
当使用ImageBitmapRenderingContext
时,源清洁标志的值在通过transferFromImageBitmap()方法将ImageBitmap
对象传输到canvas
时传播。
预乘alpha指的是一种表示图像透明度的方法,另一种是非预乘alpha。
在非预乘alpha下,像素的红、绿、蓝通道表示该像素的颜色,其alpha通道表示该像素的不透明度。
然而,在预乘alpha下,像素的红、绿、蓝通道表示该像素为图像增加的颜色量,其alpha通道表示该像素遮挡其后方的程度。
例如,假设颜色通道范围从0(关闭)到255(全强度),这些示例颜色按以下方式表示:
CSS颜色表示 | 预乘表示 | 非预乘表示 | 颜色描述 | 颜色与其他内容混合的图像 |
---|---|---|---|---|
rgba(255, 127, 0, 1) | 255, 127, 0, 255 | 255, 127, 0, 255 | 完全不透明的橙色 | ![]() |
rgba(255, 255, 0, 0.5) | 127, 127, 0, 127 | 255, 255, 0, 127 | 半透明的黄色 | ![]() |
不可表示 | 255, 127, 0, 127 | 不可表示 | 加法半透明橙色 | ![]() |
不可表示 | 255, 127, 0, 0 | 不可表示 | 加法完全透明橙色 | ![]() |
rgba(255, 127, 0, 0) | 0, 0, 0, 0 | 255, 127, 0, 0 | 完全透明(“不可见”)橙色 | ![]() |
rgba(0, 127, 255, 0) | 0, 0, 0, 0 | 255, 127, 0, 0 | 完全透明(“不可见”)蓝绿色 | ![]() |
将颜色值从非预乘表示转换为预乘表示涉及将颜色的红、绿、蓝通道乘以其alpha通道(重新映射alpha通道的范围,使“完全透明”为0,“完全不透明”为1)。
将颜色值从预乘表示转换为非预乘表示涉及相反的操作:将颜色的红、绿、蓝通道除以其alpha通道。
由于某些颜色只能在预乘alpha下表示(例如,加法颜色),而其他颜色只能在非预乘alpha下表示(例如,持有特定红、绿、蓝值的“不可见”颜色,即使没有不透明度);而在8位整数上的除法和乘法(这是画布的颜色目前存储的方式)会导致精度损失,在不完全不透明的颜色上在预乘和非预乘alpha之间转换是有损的操作。
CanvasRenderingContext2D
的输出位图和OffscreenCanvasRenderingContext2D
的位图必须使用预乘alpha表示透明颜色。
对于画布位图来说,使用预乘alpha表示颜色非常重要,因为它影响了可表示颜色的范围。虽然目前无法直接在画布上绘制加法颜色,因为CSS颜色是非预乘的,无法表示它们,但仍然可以,例如,在WebGL画布上绘制加法颜色,然后通过drawImage()
方法将该WebGL画布绘制到2D画布上。
在所有当前引擎中支持。
本节非规范性。
自定义元素为作者提供了一种构建自己完全功能的DOM元素的方法。虽然作者始终可以在文档中使用非标准元素,并在事后通过脚本或类似方法添加特定于应用程序的行为,但这种元素历来都是不合规且功能不强的。通过定义自定义元素,作者可以告知解析器如何正确构建元素以及该类元素应如何对变化做出反应。
自定义元素是“合理化平台”的更大努力的一部分,通过以低级作者暴露的可扩展性点(如自定义元素定义)来解释现有的平台特性(如HTML元素)。虽然目前自定义元素在功能和语义上都有许多限制,无法完全解释HTML现有元素的行为,但我们希望随着时间的推移能够缩小这一差距。
本节非规范性。
为了说明如何创建一个自主自定义元素,让我们定义一个封装渲染国家旗帜小图标的自定义元素。我们的目标是能够像这样使用它:
< flag-icon country = "nl" ></ flag-icon >
为此,我们首先声明一个自定义元素的类,继承HTMLElement
:
class FlagIcon extends HTMLElement {
constructor() {
super ();
this . _countryCode = null ;
}
static observedAttributes = [ "country" ];
attributeChangedCallback( name, oldValue, newValue) {
// name will always be "country" due to observedAttributes
this . _countryCode = newValue;
this . _updateRendering();
}
connectedCallback() {
this . _updateRendering();
}
get country() {
return this . _countryCode;
}
set country( v) {
this . setAttribute( "country" , v);
}
_updateRendering() {
// Left as an exercise for the reader. But, you'll probably want to
// check this.ownerDocument.defaultView to see if we've been
// inserted into a document with a browsing context, and avoid
// doing any work if not.
}
}
然后我们需要使用这个类来定义元素:
customElements. define( "flag-icon" , FlagIcon);
此时,我们上面的代码将会生效!解析器每次看到flag-icon
标签时,将会构建我们FlagIcon
类的新实例,并告知我们的代码其新的country
属性,我们随后使用它来设置元素的内部状态并在适当时更新其渲染。
您还可以使用DOM API创建flag-icon
元素:
const flagIcon = document. createElement( "flag-icon" )
flagIcon. country = "jp"
document. body. appendChild( flagIcon)
最后,我们还可以直接使用自定义元素构造函数。也就是说,上面的代码等效于:
const flagIcon = new FlagIcon()
flagIcon. country = "jp"
document. body. appendChild( flagIcon)
本节非规范性。
添加一个值为true的静态formAssociated
属性,使自主自定义元素成为与表单关联的自定义元素。ElementInternals
接口帮助您实现表单控件元素常用的函数和属性。
class MyCheckbox extends HTMLElement {
static formAssociated = true ;
static observedAttributes = [ 'checked' ];
constructor() {
super ();
this . _internals = this . attachInternals();
this . addEventListener( 'click' , this . _onClick. bind( this ));
}
get form() { return this . _internals. form; }
get name() { return this . getAttribute( 'name' ); }
get type() { return this . localName; }
get checked() { return this . hasAttribute( 'checked' ); }
set checked( flag) { this . toggleAttribute( 'checked' , Boolean( flag)); }
attributeChangedCallback( name, oldValue, newValue) {
// name will always be "checked" due to observedAttributes
this . _internals. setFormValue( this . checked ? 'on' : null );
}
_onClick( event) {
this . checked = ! this . checked;
}
}
customElements. define( 'my-checkbox' , MyCheckbox);
您可以像使用内置的与表单关联的元素一样使用自定义元素my-checkbox
。例如,将其放入form
或label
中,会将my-checkbox
元素与它们关联,提交form
时将发送my-checkbox
实现提供的数据。
< form action = "..." method = "..." >
< label >< my-checkbox name = "agreed" ></ my-checkbox > I read the agreement.</ label >
< input type = "submit" >
</ form >
本节非规范性。
通过使用ElementInternals
的适当属性,您的自定义元素可以具有默认的可访问性语义。以下代码扩展了上一节中的与表单关联的复选框,以便在可访问性技术中正确设置其默认角色和选中状态:
class MyCheckbox extends HTMLElement {
static formAssociated = true ;
static observedAttributes = [ 'checked' ];
constructor() {
super ();
this . _internals = this . attachInternals();
this . addEventListener( 'click' , this . _onClick. bind( this ));
this . _internals. role = 'checkbox' ;
this . _internals. ariaChecked = 'false' ;
}
get form() { return this . _internals. form; }
get name() { return this . getAttribute( 'name' ); }
get type() { return this . localName; }
get checked() { return this . hasAttribute( 'checked' ); }
set checked( flag) { this . toggleAttribute( 'checked' , Boolean( flag)); }
attributeChangedCallback( name, oldValue, newValue) {
// name will always be "checked" due to observedAttributes
this . _internals. setFormValue( this . checked ? 'on' : null );
this . _internals. ariaChecked = this . checked;
}
_onClick( event) {
this . checked = ! this . checked;
}
}
customElements. define( 'my-checkbox' , MyCheckbox);
请注意,与内置元素一样,这些只是默认设置,可以由页面作者使用role
和aria-*
属性进行覆盖:
<!-- This markup is non-conforming -->
< input type = "checkbox" checked role = "button" aria-checked = "false" >
<!-- This markup is probably not what the custom element author intended -->
< my-checkbox role = "button" checked aria-checked = "false" >
鼓励自定义元素的作者说明其可访问性语义中哪些方面是强大的原生语义,即不应由自定义元素的用户覆盖。在我们的示例中,my-checkbox
元素的作者应说明其role和aria-checked
值是强大的原生语义,从而不鼓励类似上述的代码。
本节非规范性。
定制内置元素是一种不同类型的自定义元素,它们的定义方式和使用方式与自主自定义元素非常不同。它们的存在是为了允许重用HTML现有元素的行为,通过为这些元素扩展新的自定义功能。这一点很重要,因为HTML元素的许多现有行为无法仅通过使用自主自定义元素来复制。相反,定制内置元素允许将自定义的构造行为、生命周期钩子和原型链安装到现有元素上,实质上是在已有元素之上“混合”这些功能。
定制内置元素需要与自主自定义元素不同的语法,因为用户代理和其他软件依靠元素的本地名称来识别元素的语义和行为。也就是说,定制内置元素在现有行为基础上进行构建的概念,关键在于扩展的元素保留其原始的本地名称。
在此示例中,我们将创建一个名为plastic-button
的定制内置元素,它的行为像一个普通按钮,但每次点击时都会添加精美的动画效果。我们首先定义一个类,就像之前一样,不过这次我们扩展的是HTMLButtonElement
,而不是HTMLElement
:
class PlasticButton extends HTMLButtonElement {
constructor() {
super ();
this . addEventListener( "click" , () => {
// Draw some fancy animation effects!
});
}
}
在定义我们的自定义元素时,我们还必须指定extends
选项:
customElements. define( "plastic-button" , PlasticButton, { extends : "button" });
一般来说,所扩展的元素的名称不能仅通过查看其扩展的元素接口来确定,因为许多元素共享相同的接口(例如,q
和blockquote
都共享HTMLQuoteElement
)。
要从解析的HTML源文本构造我们的定制内置元素,我们在button
元素上使用is
属性:
< button is = "plastic-button" > Click Me!</ button >
尝试将定制内置元素作为自主自定义元素使用将不会生效;也就是说,<plastic-button>Click me?</plastic-button>
只会创建一个没有特殊行为的HTMLElement
。
如果需要以编程方式创建定制内置元素,可以使用以下形式的createElement()
:
const plasticButton = document. createElement( "button" , { is: "plastic-button" });
plasticButton. textContent = "Click me!" ;
和之前一样,构造函数也能生效:
const plasticButton2 = new PlasticButton();
console. log( plasticButton2. localName); // will output "button"
console. assert( plasticButton2 instanceof PlasticButton);
console. assert( plasticButton2 instanceof HTMLButtonElement);
请注意,当以编程方式创建定制内置元素时,is
属性将不会出现在DOM中,因为它没有被显式设置。但是,在序列化时将被添加到输出中:
console. assert( ! plasticButton. hasAttribute( "is" ));
console. log( plasticButton. outerHTML); // will output '<button is="plastic-button"></button>'
无论它是如何创建的,所有button
特殊的行为方式都适用于这样的“塑料按钮”:它们的焦点行为、参与表单提交的能力、disabled
属性等。
定制内置元素旨在允许扩展具有有用的用户代理提供行为或API的现有HTML元素。因此,它们只能扩展本规范中定义的现有HTML元素,不能扩展诸如bgsound
、blink
、isindex
、keygen
、multicol
、nextid
或spacer
等被定义为使用HTMLUnknownElement作为其元素接口的遗留元素。
这样做的一个原因是为了未来的兼容性:如果定义了一个扩展当前未知元素(例如combobox
)的定制内置元素,这将阻止本规范在未来定义一个combobox
元素,因为派生的定制内置元素的消费者将依赖于其基本元素没有有趣的用户代理提供行为。
本节非规范性。
如下面所述,并且如上所述,仅定义和使用名为taco-button
的元素并不意味着此类元素代表按钮。也就是说,诸如网页浏览器、搜索引擎或辅助技术等工具不会仅根据其定义的名称自动将生成的元素视为按钮。
为了向各种用户传达所需的按钮语义,同时仍使用自主自定义元素,需要采用多种技术:
添加tabindex
属性将使taco-button
变得可聚焦。请注意,如果taco-button
在逻辑上被禁用,则需要移除tabindex
属性。
添加ARIA角色和各种ARIA状态和属性有助于向辅助技术传达语义。例如,将role设置为"button
"将传达这是一个按钮的语义,使用户能够通过其辅助技术使用通常的按钮交互成功地与控件进行交互。设置aria-label
属性以赋予按钮一个可访问名称,而不是让辅助技术遍历其子文本节点并宣布它们。当按钮在逻辑上被禁用时,将aria-disabled
状态设置为"true
"将向辅助技术传达按钮的禁用状态。
添加事件处理程序以处理常见的按钮行为有助于向网页浏览器用户传达按钮的语义。在这种情况下,最相关的事件处理程序是将适当的keydown
事件代理为click
事件,这样您就可以通过键盘和点击来激活按钮。
除了为taco-button
元素提供的任何默认视觉样式外,还需要更新视觉样式以反映逻辑状态的变化,例如变为禁用;也就是说,无论样式表对taco-button
有什么规则,都需要对taco-button[disabled]
有规则。
考虑到这些要点,一个全功能的taco-button
负责传达按钮语义(包括能够被禁用)可能看起来像这样:
class TacoButton extends HTMLElement {
static observedAttributes = [ "disabled" ];
constructor() {
super ();
this . _internals = this . attachInternals();
this . _internals. role = "button" ;
this . addEventListener( "keydown" , e => {
if ( e. code === "Enter" || e. code === "Space" ) {
this . dispatchEvent( new PointerEvent( "click" , {
bubbles: true ,
cancelable: true
}));
}
});
this . addEventListener( "click" , e => {
if ( this . disabled) {
e. preventDefault();
e. stopImmediatePropagation();
}
});
this . _observer = new MutationObserver(() => {
this . _internals. ariaLabel = this . textContent;
});
}
connectedCallback() {
this . setAttribute( "tabindex" , "0" );
this . _observer. observe( this , {
childList: true ,
characterData: true ,
subtree: true
});
}
disconnectedCallback() {
this . _observer. disconnect();
}
get disabled() {
return this . hasAttribute( "disabled" );
}
set disabled( flag) {
this . toggleAttribute( "disabled" , Boolean( flag));
}
attributeChangedCallback( name, oldValue, newValue) {
// name will always be "disabled" due to observedAttributes
if ( this . disabled) {
this . removeAttribute( "tabindex" );
this . _internals. ariaDisabled = "true" ;
} else {
this . setAttribute( "tabindex" , "0" );
this . _internals. ariaDisabled = "false" ;
}
}
}
即使有了这种相当复杂的元素定义,对于使用者来说,这个元素也并不愉快:它将不断“自发”地生成tabindex
属性,并且它选择的tabindex="0"
可聚焦行为可能与当前平台上的button
行为不匹配。这是因为目前没有办法为自定义元素指定默认的聚焦行为,迫使使用tabindex
属性来实现(即使它通常是用于允许用户覆盖默认行为)。
相比之下,如前一节所示,一个简单的定制内置元素将自动继承button
元素的语义和行为,无需手动实现这些行为。一般来说,对于任何在HTML现有元素之上构建具有复杂行为和语义的元素,定制内置元素将更容易开发、维护和使用。
本节非规范性。
由于元素定义可以随时发生,非自定义元素可以创建,然后在注册适当的定义后,变成自定义元素。我们称这个过程为将元素从普通元素“升级”为自定义元素。
升级可以实现某些场景,其中可能更希望在相关元素最初创建之后(例如由解析器创建之后)再注册自定义元素定义。它们允许对自定义元素中的内容进行渐进增强。例如,在以下HTML文档中,img-viewer
的元素定义是异步加载的:
<!DOCTYPE html>
< html lang = "en" >
< title > Image viewer example</ title >
< img-viewer filter = "Kelvin" >
< img src = "images/tree.jpg" alt = "A beautiful tree towering over an empty savannah" >
</ img-viewer >
< script src = "js/elements/img-viewer.js" async ></ script >
这里的img-viewer
元素的定义是使用带有script
元素加载的,并标记有async
属性,放置在标记中的<img-viewer>
标签之后。在脚本加载时,img-viewer
元素将被视为未定义的元素,类似于span
。一旦脚本加载,它将定义img-viewer
元素,并且页面上现有的img-viewer
元素将被升级,应用自定义元素的定义(可能包括应用由字符串“Kelvin”标识的图像滤镜,增强图像的视觉效果)。
请注意,升级仅适用于文档树中的元素。(正式来说,即已连接的元素。)未插入文档的元素将保持未升级状态。以下示例说明了这一点:
<!DOCTYPE html>
< html lang = "en" >
< title > Upgrade edge-cases example</ title >
< example-element ></ example-element >
< script >
"use strict" ;
const inDocument = document. querySelector( "example-element" );
const outOfDocument = document. createElement( "example-element" );
// Before the element definition, both are HTMLElement:
console. assert( inDocument instanceof HTMLElement);
console. assert( outOfDocument instanceof HTMLElement);
class ExampleElement extends HTMLElement {}
customElements. define( "example-element" , ExampleElement);
// After element definition, the in-document element was upgraded:
console. assert( inDocument instanceof ExampleElement);
console. assert( ! ( outOfDocument instanceof ExampleElement));
document. body. appendChild( outOfDocument);
// Now that we've moved the element into the document, it too was upgraded:
console. assert( outOfDocument instanceof ExampleElement);
</ script >
用户代理提供的内置元素具有某些状态,这些状态可以根据用户交互和其他因素随时间变化,并通过伪类向网页作者暴露。例如,一些表单控件具有“无效”状态,通过:invalid
伪类暴露。
与内置元素类似,自定义元素也可以有各种状态,自定义元素的作者希望以类似于内置元素的方式暴露这些状态。
这是通过:state()
伪类来完成的。自定义元素作者可以使用states
属性来添加和移除这些自定义状态,然后这些状态作为:state()
伪类的参数暴露出来。
以下示例展示了如何使用:state()
来为自定义复选框元素设置样式。假设LabeledCheckbox
不通过内容属性暴露其“checked”状态。
< script >
class LabeledCheckbox extends HTMLElement {
constructor() {
super ();
this . _internals = this . attachInternals();
this . addEventListener( 'click' , this . _onClick. bind( this ));
const shadowRoot = this . attachShadow({ mode: 'closed' });
shadowRoot. innerHTML =
`<style>
:host::before {
content: '[ ]';
white-space: pre;
font-family: monospace;
}
:host(:state(checked))::before { content: '[x]' }
</style>
<slot>Label</slot>` ;
}
get checked() { return this . _internals. states. has( 'checked' ); }
set checked( flag) {
if ( flag)
this . _internals. states. add( 'checked' );
else
this . _internals. states. delete ( 'checked' );
}
_onClick( event) {
this . checked = ! this . checked;
}
}
customElements. define( 'labeled-checkbox' , LabeledCheckbox);
</ script >
< style >
labeled-checkbox { border : dashed red ; }
labeled-checkbox : state ( checked ) { border : solid ; }
</ style >
< labeled-checkbox > You need to check this</ labeled-checkbox >
自定义伪类甚至可以针对影子部分。以下示例是上述示例的扩展,展示了这一点:
< script >
class QuestionBox extends HTMLElement {
constructor() {
super ();
const shadowRoot = this . attachShadow({ mode: 'closed' });
shadowRoot. innerHTML =
`<div><slot>Question</slot></div>
<labeled-checkbox part='checkbox'>Yes</labeled-checkbox>` ;
}
}
customElements. define( 'question-box' , QuestionBox);
</ script >
< style >
question-box :: part ( checkbox ) { color : red ; }
question-box :: part ( checkbox ) : state ( checked ) { color : green ; }
</ style >
< question-box > Continue?</ question-box >
在编写自定义元素构造函数时,作者必须遵守以下一致性要求:
不带参数的super()
调用必须是构造函数体中的第一条语句,以在运行其他代码之前建立正确的原型链和this值。
除非是简单的提前返回(return
或return this
),否则return
语句不得出现在构造函数体内。
构造函数不得使用document.write()
或document.open()
方法。
元素的属性和子节点不得被检查,因为在非升级情况下不会有任何属性和子节点,依赖升级会降低元素的可用性。
元素不得获得任何属性或子节点,因为这违反了使用createElement
或createElementNS
方法的用户的期望。
一般来说,工作应尽可能推迟到connectedCallback
中,尤其是涉及获取资源或渲染的工作。但是请注意,connectedCallback
可以被调用多次,因此任何真正一次性的初始化工作需要防止其运行两次的保护措施。
通常,构造函数应用于设置初始状态和默认值,并设置事件监听器以及可能的shadow root。
在元素创建期间,这些要求中的几个要么直接要么间接地被检查,未遵守这些要求将导致无法通过解析器或DOM API实例化自定义元素。即使在构造函数启动的微任务中完成工作也是如此,因为构造后可能会立即发生微任务检查点。
在编写自定义元素反应时,作者应避免操作节点树,因为这可能导致意外结果。
元素的connectedCallback
可以在元素断开连接之前排队,但由于回调队列仍在处理,它会导致不再连接的元素的connectedCallback
:
class CParent extends HTMLElement {
connectedCallback() {
this . firstChild. remove();
}
}
customElements. define( "c-parent" , CParent);
class CChild extends HTMLElement {
connectedCallback() {
console. log( "CChild connectedCallback: isConnected =" , this . isConnected);
}
}
customElements. define( "c-child" , CChild);
const parent = new CParent(),
child = new CChild();
parent. append( child);
document. body. append( parent);
// Logs:
// CChild connectedCallback: isConnected = false
自定义元素是一个自定义的元素。非正式地,这意味着它的构造函数和原型是由作者定义的,而不是由用户代理定义的。这种由作者提供的构造函数被称为自定义元素构造函数。
可以定义两种不同类型的自定义元素:
自主自定义元素,定义时没有extends
选项。这些类型的自定义元素的本地名称等于其定义名称。
定制内置元素,定义时具有extends
选项。这些类型的自定义元素的本地名称等于extends
选项中传递的值,它们的定义名称用作is
属性的值,因此必须是有效的自定义元素名称。
在自定义元素创建之后,更改is
属性的值不会更改元素的行为,因为它作为元素的is
值保存。
自主自定义元素具有以下元素定义:
is
属性外form
,对于与表单关联的自定义元素——将元素与form
元素关联
disabled
,对于与表单关联的自定义元素——表单控件是否被禁用readonly
,对于与表单关联的自定义元素——影响willValidate
,以及自定义元素作者添加的任何行为
name
,对于与表单关联的自定义元素——用于表单提交和form.elements
API中的元素名称
HTMLElement
)
自主自定义元素没有任何特殊意义:它代表它的子元素。定制内置元素继承它扩展的元素的语义。
任何对元素功能相关的无命名空间属性,只要由元素作者确定,可以指定在自主自定义元素上,只要属性名称与XML兼容并且不包含ASCII大写字母。例外是is
属性,不能在自主自定义元素上指定(如果指定也没有效果)。
定制内置元素遵循基于它们扩展的元素的常规属性要求。要添加基于自定义属性的行为,请使用data-*
属性。
如果元素与自定义元素定义相关联且其与表单关联字段设置为true,则自主自定义元素被称为与表单关联的自定义元素。
name
属性表示与表单关联的自定义元素的名称。disabled
属性用于使与表单关联的自定义元素不可交互,并防止其提交值被提交。form
属性用于明确将与表单关联的自定义元素与其表单所有者关联。
readonly
属性的与表单关联的自定义元素指定元素禁止约束验证。用户代理不会为该属性提供任何其他行为,但自定义元素作者应尽可能使用其存在使其控件以某种适当的方式不可编辑,类似于内置表单控件上的readonly属性的行为。
约束验证:如果在与表单关联的自定义元素上指定readonly
属性,则元素禁止约束验证。
与表单关联的自定义元素的重置算法是将自定义元素回调
反应排入队列,其中元素、回调名称“formResetCallback
”和空参数列表。
有效的自定义元素名称是一个字符序列name,它满足以下所有要求:
name必须匹配PotentialCustomElementName
生成:
PotentialCustomElementName ::=
[a-z] (PCENChar)* '-'
(PCENChar)*
PCENChar ::=
"-" | "." | [0-9] | "_" | [a-z] | #xB7 | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x203F-#x2040] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
name不得是以下任何一个:
annotation-xml
color-profile
font-face
font-face-src
font-face-uri
font-face-format
font-face-name
missing-glyph
这些要求确保了有效自定义元素名称的若干目标:
它们以ASCII小写字母开头,确保HTML解析器将它们视为标签而不是文本。
它们不包含任何ASCII大写字母,确保用户代理始终可以ASCII大小写不敏感地处理HTML元素。
它们包含连字符,用于命名空间,并确保前向兼容性(因为将来不会向HTML、SVG或MathML添加包含连字符的本地名称元素)。
它们始终可以使用createElement()
和createElementNS()
创建,这些方法的限制超出了解析器的限制。
除了这些限制之外,还允许使用多种名称,以最大限度地灵活应对诸如<math-α>
或<emotion-😍>
等用例。
自定义元素定义描述了一个自定义元素,包括:
CustomElementConstructor
回调函数类型值,包装自定义元素构造函数
sequence<DOMString>
connectedCallback
"、 "disconnectedCallback
"、
"adoptedCallback
"、
"attributeChangedCallback
"、 "formAssociatedCallback
"、
"formDisabledCallback
"、
"formResetCallback
"和"formStateRestoreCallback
"。相应的值是Web
IDLFunction
回调函数类型值,或null。默认情况下,每个条目的值为null。
attachInternals()
。
attachShadow()
。
要查找自定义元素定义,给定document、namespace、localName和is,执行以下步骤。它们将返回自定义元素定义或null:
如果namespace不是HTML命名空间,返回null。
如果document的浏览上下文为null,返回null。
让registry成为document的相关全局对象的CustomElementRegistry
对象。
如果registry中存在一个自定义元素定义,其name和local name都等于localName,则返回该自定义元素定义。
如果registry中存在一个自定义元素定义,其name等于is且local name等于localName,则返回该自定义元素定义。
返回null。
CustomElementRegistry
接口支持所有当前引擎。
每个 Window
对象
都与一个唯一的 CustomElementRegistry
实例关联,该实例在创建 Window
对象时分配。
自定义元素注册表与 Window
对象关联,
而不是 Document
对象,因为每个 自定义元素构造函数
都继承自
HTMLElement
接口,并且每个 Window
对象只有一个
HTMLElement
接口。
支持所有当前引擎。
customElements
属性的
Window
接口
必须返回该 CustomElementRegistry
对象。
[Exposed =Window ]
interface CustomElementRegistry {
[CEReactions ] undefined define (DOMString name , CustomElementConstructor constructor , optional ElementDefinitionOptions options = {});
(CustomElementConstructor or undefined ) get (DOMString name );
DOMString ? getName (CustomElementConstructor constructor );
Promise <CustomElementConstructor > whenDefined (DOMString name );
[CEReactions ] undefined upgrade (Node root );
};
callback CustomElementConstructor = HTMLElement ();
dictionary ElementDefinitionOptions {
DOMString extends ;
};
每个 CustomElementRegistry
都有一组 自定义元素定义,最初为空。通常,
本规范中的算法通过名称、本地名称或构造函数在注册表中查找元素。
每个 CustomElementRegistry
也有一个 元素定义正在运行 标志,用于防止重新进入元素定义。它最初未设置。
每个 CustomElementRegistry
也有一个 when-defined 承诺映射,
将有效的自定义元素名称映射到承诺。它用于实现 whenDefined()
方法。
window.customElements.define(name,
constructor)
支持所有当前引擎。
window.customElements.define(name, constructor,
{ extends: baseLocalName })
NotSupportedError
"
DOMException
。
window.customElements.get(name)
支持所有当前引擎。
window.customElements.getName(constructor)
window.customElements.whenDefined(name)
CustomElementRegistry/whenDefined
支持所有当前引擎。
SyntaxError
DOMException
的被拒绝的 promise。
window.customElements.upgrade(root)
支持所有当前引擎。
元素定义 是将一个 自定义元素定义
添加到 CustomElementRegistry
的过程。通过 define()
方法实现。当调用时,
define(name, constructor,
options)
方法必须执行以下步骤:
如果 IsConstructor(constructor) 为 false,则抛出
TypeError
。
如果 name 不是 有效的自定义元素名称,则抛出
"SyntaxError
" DOMException
。
如果这个 CustomElementRegistry
包含一个具有 name 名称的条目,则抛出
"NotSupportedError
" DOMException
。
如果这个 CustomElementRegistry
包含一个具有 constructor 构造函数的条目,
则抛出 "NotSupportedError
" DOMException
。
将 localName 设置为 name。
将 extends 设置为 options 中 extends
成员的值
,如果不存在此类成员,则为 null。
如果 extends 不为 null,则:
如果 extends 是一个 有效的自定义元素名称,则抛出
"NotSupportedError
" DOMException
。
如果 extends 和 HTML
命名空间 的元素接口为 HTMLUnknownElement
(例如,如果 extends 没有
表示本规范中的元素定义),则抛出
"NotSupportedError
" DOMException
。
将 localName 设置为 extends。
如果这个 CustomElementRegistry
的
元素定义正在运行
标志已设置,则抛出 "NotSupportedError
" DOMException
。
设置这个 CustomElementRegistry
的
元素定义正在运行
标志。
将 formAssociated 设置为 false。
将 disableInternals 设置为 false。
将 disableShadow 设置为 false。
将 observedAttributes 设置为空的 sequence<DOMString>
。
在捕获任何异常的情况下运行以下子步骤:
让 prototype 为 ? Get(constructor, "prototype")。
让 lifecycleCallbacks 成为一个包含键 "connectedCallback
",
"disconnectedCallback
","adoptedCallback
" 和
"attributeChangedCallback
" 的映射,
每个键的值都为 null。
对于 lifecycleCallbacks 中的每个键 callbackName,按前一步列出的顺序:
如果键 "attributeChangedCallback
"
的 lifecycleCallbacks 条目的值不为 null,则:
让 disabledFeatures 为一个空的 sequence<DOMString>
。
让 disabledFeaturesIterable 为 ? Get(constructor, "disabledFeatures")。
如果 disabledFeaturesIterable 不为 undefined,则将
disabledFeatures 设置为 将
disabledFeaturesIterable 转换为 sequence<DOMString>
的结果。重新抛出任何来自
转换的异常。
如果 disabledFeatures 包含 "internals
",则将 disableInternals 设置为 true。
如果 disabledFeatures 包含 "shadow
",则将 disableShadow 设置为 true。
让 formAssociatedValue 为 ? Get( constructor, "formAssociated")。
将 formAssociated 设置为
将 formAssociatedValue 转换为
boolean
的结果。重新抛出任何来自转换的异常。
如果 formAssociated 为 true,对于每个
"formAssociatedCallback
","formResetCallback
",
"formDisabledCallback
" 和
"formStateRestoreCallback
" callbackName:
然后,无论上述步骤是否抛出异常,都执行以下子步骤:
取消设置这个 CustomElementRegistry
的
元素定义正在运行 标志。
最后,如果第一组子步骤抛出了异常,则重新抛出该异常(从而终止此算法)。否则,继续进行。
将 definition 设置为一个新的 自定义元素定义,其 名称 为 name,本地名称 为 localName, 构造函数 为 constructor,观察的属性 为 observedAttributes,生命周期回调 为 lifecycleCallbacks, 表单关联 为 formAssociated,禁用内部 为 disableInternals,以及 禁用阴影 为 disableShadow。
将 definition 添加到这个 CustomElementRegistry
中。
让 document 为这个 CustomElementRegistry
的
相关全局
对象 的 关联的
Document
。
让 upgrade candidates 为所有符合以下条件的元素,它们是 shadow-including 包含后代 元素,
其命名空间为 HTML 命名空间 且本地名称为 localName,按
shadow-including 树顺序 排列。另外,如果
extends 非空,则仅
包括其 is
值 等于 name 的元素。
对于 upgrade candidates 中的每个元素 element,入队一个 自定义元素升级反应 给定 element 和 definition。
如果这个 CustomElementRegistry
的
when-defined promise
map
包含一个键为 name 的条目:
让 promise 为该条目的值。
用 constructor 解决 promise。
从这个 CustomElementRegistry
的
when-defined
promise
map 中删除键为
name 的条目。
当调用时,get(name)
方法必须执行以下
步骤:
如果这个 CustomElementRegistry
包含一个具有 name 名称的条目,则返回该条目的
构造函数。
否则,返回 undefined。
getName(constructor)
方法的
步骤如下:
如果这个 CustomElementRegistry
包含一个具有 constructor 构造函数的条目,
则返回该条目的 名称。
返回 null。
当调用时,whenDefined(name)
方法必须执行以下步骤:
如果 name 不是一个 有效的自定义元素名称,则返回 一个
被拒绝的 promise,并带有一个 "SyntaxError
"
DOMException
。
如果这个 CustomElementRegistry
包含一个具有 name 名称的条目,则返回 一个
已解决的 promise,该 promise 的值为该条目的 构造函数。
让 map 成为这个 CustomElementRegistry
的
when-defined
promise map。
如果 map 中不包含一个键为 name 的条目,则在 map 中创建一个键为 name 且值为一个新 promise 的条目。
让 promise 成为 map 中键为 name 的条目的值。
返回 promise。
whenDefined()
方法可用于
在所有适当的 自定义
元素 被 定义 之前避免执行某些操作。在
这个示例中,我们
将其与 :defined
伪类结合使用,以在确保使用的所有 自主自定义元素 都已定义之前隐藏动态加载的文章内容。
articleContainer. hidden = true ;
fetch( articleURL)
. then( response => response. text())
. then( text => {
articleContainer. innerHTML = text;
return Promise. all(
[... articleContainer. querySelectorAll( ":not(:defined)" )]
. map( el => customElements. whenDefined( el. localName))
);
})
. then(() => {
articleContainer. hidden = false ;
});
当调用时,upgrade(root)
方法必须执行
以下步骤:
让 candidates 为一个 列表,包含所有 root 的 shadow-including 包含后代 元素, 按 shadow-including 树 顺序 排列。
upgrade()
方法允许随意升级
元素。通常元素在连接时会自动升级,
但如果需要在准备连接元素之前升级,可以使用此方法。
const el = document. createElement( "spider-man" );
class SpiderMan extends HTMLElement {}
customElements. define( "spider-man" , SpiderMan);
console. assert( ! ( el instanceof SpiderMan)); // not yet upgraded
customElements. upgrade( el);
console. assert( el instanceof SpiderMan); // upgraded!
为了 升级一个元素,给定输入的 自定义元素定义 definition 和一个元素 element,执行以下步骤:
如果 element 的 自定义元素状态 不是 "undefined
" 或
"uncustomized
",则返回。
在以下示例中,可能由于该算法的重入调用而发生这种情况:
<!DOCTYPE html>
< x-foo id = "a" ></ x-foo >
< x-foo id = "b" ></ x-foo >
< script >
// Defining enqueues upgrade reactions for both "a" and "b"
customElements. define( "x-foo" , class extends HTMLElement {
constructor() {
super ();
const b = document. querySelector( "#b" );
b. remove();
// While this constructor is running for "a", "b" is still
// undefined, and so inserting it into the document will enqueue a
// second upgrade reaction for "b" in addition to the one enqueued
// by defining x-foo.
document. body. appendChild( b);
}
})
</ script >
因此,当第二次调用 "b
" 时,此步骤将使算法提前退出。
将 element 的 自定义元素定义 设置为 definition。
将 element 的 自定义元素状态 设置为 "failed
"。
升级成功后,将其设置为 "custom
"。现在,我们将其设置为 "failed
",以便任何重入调用都会触发上面的提前退出步骤。
对于 element 的 属性列表 中的每个
attribute,按顺序 入队一个自定义元素回调反应
与 element,回调名称 "attributeChangedCallback
",以及包含
attribute 的本地名称、null、attribute 的值和 attribute 的命名空间的参数列表。
如果 element 是 连接的,则 入队一个自定义元素回调反应 与 element,回调名称
"connectedCallback
",以及一个空的参数列表。
将 element 添加到 definition 的 构造栈 的末尾。
让 C 成为 definition 的 构造函数。
执行以下子步骤并捕获任何异常:
如果 definition 的 禁用 shadow 为真且
element 的 shadow root
非空,则抛出一个 "NotSupportedError
"
DOMException
。
这是必要的,因为 attachShadow()
不使用 查找自定义元素定义,而 attachInternals()
使用。
将 element 的 自定义元素状态 设置为 "precustomized
"。
让 constructResult 成为 构造 C 的结果,没有参数。
如果 C 不符合规范地
使用带有 [CEReactions]
扩展属性的 API,则在 C 完成并控制返回此算法之前,该算法开头入队的反应将在此步骤中执行。否则,它们将在 C 和升级过程的其余部分完成后执行。
如果 SameValue(constructResult, element) 为假,
则抛出一个 TypeError
。
如果 C 在调用 super()
之前构造了相同自定义元素的另一个实例,或者如果 C 使用 JavaScript
的
return
覆盖功能从构造函数返回一个任意 HTMLElement
对象,则会发生这种情况。
然后,无论上述步骤是否抛出异常,执行以下子步骤:
从 definition 的 构造栈 的末尾移除最后一个条目。
假设 C 调用了 super()
(如果它是 符合规范的,则会这样做),并且调用成功,这将是替换我们在该算法开头推送的
element 的 已构造标记。(HTML 元素构造函数 会执行此替换。)
如果 C 没有调用 super()
(即它不 符合规范),或者 HTML 元素构造函数 中的任何步骤抛出异常,则该条目仍将是
element。
最后,如果上述步骤抛出异常,则:
如果上述步骤抛出异常,则 element 的 自定义元素状态 将保持 "failed
" 或 "precustomized
"。
如果 element 是 表单关联自定义元素,则:
重置表单所有者 为
element。如果 element 与一个 表单
元素关联,则
入队一个自定义元素回调反应
与 element,回调名称 "formAssociatedCallback
",以及 « 与之关联的 表单
»。
如果 element 是 禁用的,则
入队一个自定义元素回调反应
与 element,回调名称 "formDisabledCallback
" 和 « true »。
将 element 的 自定义元素状态 设置为 "custom
"。
为了 尝试升级一个元素,给定输入的 元素 element,执行以下步骤:
让 definition 成为 查找自定义元素定义 的结果,给定
element 的 节点文档、element 的命名空间、element 的本地名称和
element 的 is
值。
如果 definition 不为 null,则 入队一个自定义元素升级反应,给定 element 和 definition。
一个 自定义元素 能够通过运行作者代码来响应某些事件:
当它 连接
时,其 connectedCallback
会被调用,没有参数。
当它 断开连接 时,其
disconnectedCallback
会被调用,没有参数。
当它被 采纳 到一个新的
文档中时,其 adoptedCallback
会被调用,传入旧文档和新文档作为参数。
当其任意属性被 更改、添加、移除 或 替换 时,其
attributeChangedCallback
会被调用,传入属性的本地名称、旧值、新值和命名空间作为参数。(当属性被添加或移除时,属性的旧值或新值被认为是 null。)
当用户代理 重置表单所有者 一个
表单关联自定义元素 并更改表单所有者时,其
formAssociatedCallback
会被调用,传入新表单所有者(如果没有所有者则为 null)作为参数。
当 禁用
状态的
表单关联自定义元素 发生变化时,其
formDisabledCallback
会被调用,传入新状态作为参数。
当用户代理更新 表单关联自定义元素 的值
代表用户或 作为导航的一部分
时,其
formStateRestoreCallback
会被调用,传入新状态和一个表示原因的字符串 "autocomplete
" 或 "restore
" 作为参数。
我们将这些反应统称为 自定义元素反应。
自定义元素反应 的调用方式非常谨慎,以避免在细微操作中运行作者代码。实际上,它们会被延迟到“返回用户脚本之前”。这意味着在大多数情况下,它们似乎是同步执行的,但在复杂的复合操作(如 克隆 或 范围 操作)中,它们将延迟到所有相关用户代理处理步骤完成后,然后作为一个批次运行。
此外,这些反应的精确排序是通过一个较为复杂的队列堆栈系统来管理的,详见下文。该系统的目的是确保 自定义元素反应 总是在触发动作的相同顺序中调用,至少在单个 自定义元素 的本地上下文中。(由于 自定义元素反应 代码可以执行自己的变更,因此不可能跨多个元素提供全局排序保证。)
每个 同源窗口代理 有一个 自定义元素反应堆栈,最初为空。同源窗口代理 的 当前元素队列 是其 元素队列 堆栈顶部的项。堆栈中的每个项目是一个 元素队列,最初也是空的。元素队列 中的每个项目都是一个元素。(这些元素不一定是 自定义的,因为该队列也用于 升级。)
每个自定义元素反应栈都有一个关联的备用元素队列,这是一个最初为空的元素队列。在影响DOM的操作过程中,如果没有通过带有[CEReactions]
装饰的API,或者没有通过解析器的为标记创建元素算法,则元素会被推入备用元素队列。一个例子是用户发起的编辑操作,它会修改可编辑元素的子元素或属性。为了防止在处理备用元素队列时发生重入,每个自定义元素反应栈还有一个处理备用元素队列的标志,最初未设置。
所有元素都有一个关联的 自定义元素反应队列,最初为空。自定义元素反应队列 中的每个项目有两种类型之一:
这在以下示意图中总结:
为了 在适当的元素队列中入队一个元素,给定一个元素 element,运行以下步骤:
如果 reactionsStack 为空,则:
为了 入队一个自定义元素回调反应,给定一个 自定义 元素 element,一个回调名称 callbackName 和一个参数列表 args,执行以下步骤:
让 definition 成为 element 的 自定义元素定义。
让 callback 成为 definition 的 生命周期 回调 中 键为 callbackName 的条目的值。
如果 callback 为 null,则返回。
如果 callbackName 为 "attributeChangedCallback
",则:
让 attributeName 成为 args 的第一个元素。
如果 definition 的 观察到的 属性 不包含 attributeName,则返回。
将一个新的 回调反应 添加到 element 的 自定义元素 反应队列 中,使用回调函数 callback 和参数 args。
将一个元素入队到 适当的元素队列,给定 element。
为了 入队一个自定义元素升级反应,给定一个元素 element 和一个 自定义元素定义 definition,执行以下步骤:
将一个新的 升级反应 添加到 element 的 自定义元素 反应队列 中,包含 自定义元素定义 definition。
将一个元素入队到 适当的元素队列,给定 element。
为了 调用自定义元素反应 在一个 元素队列 queue 中,执行以下步骤:
当 queue 不是 空 时:
让 element 成为 出队 的 queue 的结果。
让 reactions 成为 element 的 自定义元素反应 队列。
重复直到 reactions 为空:
为了确保 自定义元素反应 被适当地触发,我们引入了 [CEReactions]
IDL 扩展属性。它表示相关算法需要补充额外步骤,以便适当地跟踪和调用 自定义元素反应。
这个 [CEReactions]
扩展属性不得带参数,不得出现在操作、属性、设置器或删除器之外。此外,它不得出现在只读属性上。
带有 [CEReactions]
扩展属性的操作、属性、设置器或删除器必须运行以下步骤来代替其描述中指定的步骤:
运行原始指定的步骤,捕获任何异常。如果步骤返回一个值,则让 value 成为返回的值。如果它们引发异常,则让 exception 成为引发的异常。
调用自定义元素反应 在 queue 中。
如果原始步骤引发了异常 exception,重新引发 exception。
如果原始步骤返回了值 value,返回 value。
这个扩展属性的意图有些微妙。实现其目标的一种方法是说平台上的每个操作、属性、设置器和删除器都必须插入这些步骤,并允许实现者优化不必要的情况(在没有可能导致 自定义元素反应 发生的 DOM 变更时)。
然而,实际上这种不精确性可能会导致 自定义元素反应 的非互操作实现,因为某些实现可能会忘记在某些情况下调用这些步骤。相反,我们选择了显式注释所有相关 IDL 构造的方法,以确保互操作行为并帮助实现者轻松定位这些步骤所需的所有情况。
任何用户代理引入的非标准 API,如果可能修改 DOM 以导致 入队一个自定义元素回调反应 或 入队一个
自定义元素升级反应,例如通过修改任何属性或子元素,必须也带有 [CEReactions]
属性。
在撰写本文时,已知以下非标准或尚未标准化的 API 属于此类:
HTMLInputElement
的
webkitdirectory
和 incremental
IDL 属性
HTMLLinkElement
的
scope
IDL 属性
某些功能是为了自定义元素作者可用,但不是自定义元素使用者。这些功能由 element.attachInternals()
方法提供,该方法返回一个 ElementInternals
实例。
ElementInternals
的属性和方法允许控制用户代理提供给所有元素的内部功能。
element.attachInternals()
返回一个 ElementInternals
对象,目标为 自定义元素
element。如果 element 不是一个 自定义元素,如果 "internals" 特性在元素定义中被禁用,或者在同一个元素上调用两次,则抛出异常。
每个 HTMLElement
都有一个 附加内部(为空或一个
ElementInternals
对象),初始为空。
Support in all current engines.
attachInternals()
方法的步骤如下:
如果 this
的
is
值 不为空,则抛出 "NotSupportedError
" DOMException
。
让 definition 成为 查找自定义元素定义 的结果,给定 this 的
节点文档、其命名空间、其本地名称和 null 作为 is
值。
如果 definition 为空,则抛出 "NotSupportedError
" DOMException
。
如果 definition 的 禁用内部 为真,则抛出 "NotSupportedError
" DOMException
。
如果 this
的 附加内部
不为空,则抛出
"NotSupportedError
" DOMException
。
如果 this
的 自定义元素状态 不是 "precustomized
" 或
"custom
",则抛出
"NotSupportedError
" DOMException
。
设置 this
的 附加内部
为一个新的
ElementInternals
实例,其 目标元素 为 this。
ElementInternals
接口支持所有当前引擎。
ElementInternals
接口的 IDL 如下,各种操作和属性在以下章节中定义:
[Exposed =Window ]
interface ElementInternals {
// Shadow root access
readonly attribute ShadowRoot
? shadowRoot ;
// Form-associated custom elements
undefined setFormValue ((File or USVString or FormData )? value ,
optional (File or USVString or FormData )? state );
readonly attribute HTMLFormElement ? form ;
undefined setValidity (optional ValidityStateFlags flags = {},
optional DOMString message ,
optional HTMLElement anchor );
readonly attribute boolean willValidate ;
readonly attribute ValidityState validity ;
readonly attribute DOMString validationMessage ;
boolean checkValidity ();
boolean reportValidity ();
readonly attribute NodeList labels ;
// Custom state pseudo-class
[SameObject ] readonly attribute CustomStateSet states ;
};
// Accessibility semantics
ElementInternals includes ARIAMixin ;
dictionary ValidityStateFlags {
boolean valueMissing = false ;
boolean typeMismatch = false ;
boolean patternMismatch = false ;
boolean tooLong = false ;
boolean tooShort = false ;
boolean rangeUnderflow = false ;
boolean rangeOverflow = false ;
boolean stepMismatch = false ;
boolean badInput = false ;
boolean customError = false ;
};
每个 ElementInternals
都有一个 目标元素,
这是一个 自定义元素。
internals.shadowRoot
返回 ShadowRoot
用于 internals 的 目标元素,如果 目标元素 是 shadow 主机,否则为
null。
支持所有当前引擎。
shadowRoot
获取器步骤如下:
如果 target 不是 shadow 主机,则返回 null。
令 shadow 为 target 的 shadow 根。
如果 shadow 的 对元素内部可用 为 false,则返回 null。
返回 shadow。
internals.setFormValue(value)
将 internals 的 目标元素 的 状态 和 提交值 都设置为 value。
如果 value 为 null,则元素不会参与表单提交。
internals.setFormValue(value,
state)
将 internals 的 目标元素 的 提交值 设置为 value,并将其 状态 设置为 state。
如果 value 为 null,则元素不会参与表单提交。
internals.form
internals.setValidity(flags,
message [, anchor ])
将 internals 的 目标元素
标记为符合 flags 参数指示的约束条件,并将元素的验证消息设置为 message。如果指定了
anchor,用户代理可能会在表单所有者进行交互式验证或调用
reportValidity()
时使用它来指示
internals 的
目标元素
的约束问题。
internals.setValidity({})
将 internals 的 目标元素 标记为满足其约束条件。
internals.willValidate
如果 internals 的 目标元素 在表单提交时将被验证,则返回 true;否则返回 false。
internals.validity
返回 internals 的 目标元素
的 ValidityState
对象。
internals.validationMessage
返回将在检查 internals 的 目标元素 的有效性时显示给用户的错误消息。
valid = internals.checkValidity()
如果 internals 的 目标元素
没有有效性问题,则返回 true;否则返回 false,并在该元素上触发一个 invalid
事件。
valid = internals.reportValidity()
如果 internals 的 目标元素
没有有效性问题,则返回 true;否则返回 false,在该元素上触发一个 invalid
事件,并且(如果事件未被取消)向用户报告问题。
internals.labels
每个 表单关联的自定义元素 都有一个
提交值。它用于在表单提交时提供一个或多个 条目。
提交值 的初始值为 null,
提交值 可以是
null、字符串、
File
,或一个 列表
条目。
每个 表单关联的自定义元素 都有一个
状态。
它是用户代理可以用来恢复用户为该元素输入的信息。状态 的初始值为 null,
状态 可以是 null、字符串、
File
,或一个 列表 条目。
setFormValue()
方法由自定义元素作者用于设置元素的
提交值 和 状态,从而将这些信息传达给用户代理。
当用户代理认为恢复一个 表单关联的自定义元素 的
状态 是个好主意时,例如 在导航后 或重启用户代理时,
他们可以 排队一个自定义元素回调反应 并调用该元素,回调名为
"formStateRestoreCallback
",参数列表包含要恢复的状态和 "restore
"。
如果用户代理有表单填充辅助功能,则在调用该功能时,它可以 排队一个自定义元素回调反应 并调用
表单关联的自定义元素,回调名为
"formStateRestoreCallback
",参数列表包含由状态值历史和一些启发式方法确定的状态值和 "autocomplete
"。
一般来说,状态 是用户指定的信息,而 提交值 是经过规范化或清理后适合提交给服务器的值。以下示例具体说明了这一点:
假设我们有一个 表单关联的自定义元素,它要求用户指定日期。用户指定
"3/15/2019",但控件希望将
"2019-03-15"
提交给服务器。"3/15/2019" 将是该元素的 状态,而 "2019-03-15"
将是
提交值。
假设你开发了一个模拟现有 复选框
input
类型的自定义元素。其
提交值 将是其
value
内容属性的值,或字符串
"on"
。其
状态 将是
"checked"
、"unchecked"
、"checked/indeterminate"
或
"unchecked/indeterminate"
之一。
支持所有当前引擎。
setFormValue(value,
state)
方法步骤如下:
如果 element 不是 表单关联的自定义元素,则抛出
"NotSupportedError
"
DOMException
。
否则,如果 state 是
FormData
对象,则将
element 的
状态
设置为 state 的 条目列表
的 克隆。
否则,将 element 的 状态 设置为 state。
每个 表单关联的自定义元素 都有名为
valueMissing
、typeMismatch
、
patternMismatch
、tooLong
、
tooShort
、rangeUnderflow
、
rangeOverflow
、stepMismatch
和
customError
的有效性标志。它们的初始值为 false。
每个 表单关联的自定义元素 都有一个 验证消息 字符串。它的初始值为空字符串。
每个 表单关联的自定义元素 都有一个 验证锚 元素。它的初始值为 null。
支持所有当前引擎。
setValidity(flags, message,
anchor)
方法步骤如下:
如果 element 不是 表单关联的自定义元素,则抛出
"NotSupportedError
"
DOMException
。
如果 flags 包含一个或多个 true 值并且 message 未给定或为空字符串,则抛出
TypeError
。
对于 flags 的每个条目 flag → value,将 element 的名为 flag 的有效性标志设置为 value。
如果未给定 message 或 element 的所有有效性标志均为 false,则将 element 的 验证消息 设置为空字符串,否则设置为 message。
如果 element 的 customError
有效性标志为 true,则将 element 的
自定义有效性错误消息 设置为 element 的
验证消息。否则,将
element 的
自定义有效性错误消息 设置为空字符串。
如果未给定 anchor,则将 element 的 验证锚
设置为 null。否则,如果 anchor 不是 包含影子的后代,
则抛出 "NotFoundError
"
DOMException
。否则,将
element 的
验证锚 设置为
anchor。
ElementInternals/validationMessage
支持所有当前引擎。
validationMessage
getter 步骤如下:
如果 element 不是 表单关联的自定义元素,则抛出
"NotSupportedError
"
DOMException
。
返回 element 的 验证消息。
条目构建算法 适用于 表单关联的自定义元素,给定一个元素 element 和一个 条目列表 entry list,包括以下步骤:
如果 element 的 提交值 是一个 列表 的 条目,则将 element 的每个 提交值 添加到 entry list,并返回。
在这种情况下,用户代理不会引用 name
内容属性值。
表单关联的自定义元素
的实现负责决定
条目 的名称。它们可以是
name
内容属性值,它们可以是基于
name
内容属性值的字符串,也可以与
name
内容属性无关。
如果元素的 提交值
不为
null,则使用
name
属性值和
提交值
创建一个条目,并将其添加到 entry list。
internals.role [ = value ]
internals.aria* [ = value ]
设置或获取 internals 的目标元素的各种默认 ARIA 状态或属性值,除非页面作者使用
aria-*
属性覆盖它们。
每个自定义元素都有一个内部内容属性映射,这是一个映射,最初为空。有关其如何影响平台可访问性 API 的信息,请参见与 ARIA 和平台可访问性 API 相关的要求部分。
internals.states.add(value)
将字符串 value 添加到元素的状态集合中,以作为伪类暴露。
internals.states.has(value)
如果 value 在元素的状态集合中,则返回 true,否则返回 false。
internals.states.delete(value)
如果元素的状态集合中有 value,则将其删除并返回 true。否则返回 false。
internals.states.clear()
从元素的状态集合中删除所有值。
for (const stateName of internals.states)
for (const stateName of internals.states.entries())
for (const stateName of internals.states.keys())
for (const stateName of internals.states.values())
遍历元素的状态集合中的所有值。
internals.states.forEach(callback)
通过为每个值调用 callback,遍历元素的状态集合中的所有值。
internals.states.size
返回元素的状态集合中的值的数量。
每个自定义元素都有一个状态集合,这是一个CustomStateSet
,最初为空。
[Exposed =Window ]
interface CustomStateSet {
setlike <DOMString >;
};
对于states
的getter步骤是返回this
的状态集合。
状态集合可以暴露由存在/不存在字符串值表示的布尔状态。如果作者想要暴露一个可以有三个值的状态,它可以转换为三个排他性布尔状态。例如,一个叫做readyState
的状态,具有"loading"
、"interactive"
和"complete"
值,可以映射到三个排他性的布尔状态,"loading"
、"interactive"
和"complete"
:
// Change the readyState from anything to "complete".
this . _readyState = "complete" ;
this . _internals. states. delete ( "loading" );
this . _internals. states. delete ( "interactive" );
this . _internals. states. add( "complete" );
本规范未提供描述面包屑导航菜单的机器可读方式。建议作者仅在段落中使用一系列链接。可以使用nav
元素将包含这些段落的部分标记为导航块。
在以下示例中,可以通过两条路径到达当前页面。
< nav >
< p >
< a href = "/" > Main</ a > ▸
< a href = "/products/" > Products</ a > ▸
< a href = "/products/dishwashers/" > Dishwashers</ a > ▸
< a > Second hand</ a >
</ p >
< p >
< a href = "/" > Main</ a > ▸
< a href = "/second-hand/" > Second hand</ a > ▸
< a > Dishwashers</ a >
</ p >
</ nav >
本规范未定义用于标记一组页面的关键字列表(也称为标签云)的任何特定标记。通常,建议作者使用带有明确内联计数的ul
元素来标记此类列表,然后使用样式表隐藏这些计数并将其转换为表现效果,或者使用SVG。
这里包含了一个短标签云中的三个标签:
< style >
. tag-cloud > li > span { display : none ; }
. tag-cloud > li { display : inline ; }
. tag-cloud-1 { font-size : 0.7 em ; }
. tag-cloud-2 { font-size : 0.9 em ; }
. tag-cloud-3 { font-size : 1.1 em ; }
. tag-cloud-4 { font-size : 1.3 em ; }
. tag-cloud-5 { font-size : 1.5 em ; }
@ media speech {
. tag-cloud > li > span { display : inline }
}
</ style >
...
< ul class = "tag-cloud" >
< li class = "tag-cloud-4" >< a title = "28 instances" href = "/t/apple" > apple</ a > < span > (popular)</ span >
< li class = "tag-cloud-2" >< a title = "6 instances" href = "/t/kiwi" > kiwi</ a > < span > (rare)</ span >
< li class = "tag-cloud-5" >< a title = "41 instances" href = "/t/pear" > pear</ a > < span > (very popular)</ span >
</ ul >
每个标签的实际频率使用title
属性给出。提供了一个CSS样式表将标记转换为不同大小单词的云,但对于不支持CSS或不是视觉呈现的用户代理,标记包含类似“(热门)”或“(稀有)”的注释,以按频率分类各种标签,从而使所有用户都能受益于这些信息。
使用ul
元素(而不是ol
),因为顺序并不特别重要:尽管列表实际上是按字母顺序排列的,但如果按标签长度排序,它传达的信息也会相同。
本规范没有定义用于标记对话、会议记录、聊天记录、剧本对话、即时消息日志以及其他不同参与者轮流发言的情况的特定元素。
相反,鼓励作者使用p
元素和标点符号来标记对话。需要标记发言者以便样式化的作者,建议使用span
或b
。用i
元素包裹文本的段落可用于标记舞台指示。
这个例子通过引用阿博特和科斯特洛的著名小品《谁在一垒》来演示这一点:
< p > Costello: Look, you gotta first baseman?
< p > Abbott: Certainly.
< p > Costello: Who's playing first?
< p > Abbott: That's right.
< p > Costello becomes exasperated.
< p > Costello: When you pay off the first baseman every month, who gets the money?
< p > Abbott: Every dollar of it.
以下示例展示了如何标记即时消息(IM)对话记录,使用data
元素为每行提供Unix时间戳。注意,时间戳以time_t
格式提供,这不是time
元素支持的格式,因此使用了data
元素。如果作者希望使用time
元素支持的日期和时间格式来标记数据,则可以使用该元素代替data
元素。这可能是有利的,因为这样可以让数据分析工具明确无误地检测时间戳,而无需与页面作者进行协调。
< p > < data value = "1319898155" > 14:22</ data > < b > egof</ b > I'm not that nerdy, I've only seen 30% of the star trek episodes
< p > < data value = "1319898192" > 14:23</ data > < b > kaj</ b > if you know what percentage of the star trek episodes you have seen, you are inarguably nerdy
< p > < data value = "1319898200" > 14:23</ data > < b > egof</ b > it's unarguably
< p > < data value = "1319898228" > 14:23</ data > < i > * kaj blinks</ i >
< p > < data value = "1319898260" > 14:24</ data > < b > kaj</ b > you are not helping your case
HTML没有好的方式来标记图表,因此来自游戏的互动对话描述更难以标记。这个示例展示了一种可能的约定,使用dl
元素列出对话中每个节点的可能回复。另一种选择是将对话描述为DOT文件,并将结果输出为SVG图像以放入文档中。[DOT]
< p > Next, you meet a fisher. You can say one of several greetings:
< dl >
< dt > "Hello there!"
< dd >
< p > She responds with "Hello, how may I help you?"; you can respond with:
< dl >
< dt > "I would like to buy a fish."
< dd > < p > She sells you a fish and the conversation finishes.
< dt > "Can I borrow your boat?"
< dd >
< p > She is surprised and asks "What are you offering in return?".
< dl >
< dt > "Five gold." (if you have enough)
< dt > "Ten gold." (if you have enough)
< dt > "Fifteen gold." (if you have enough)
< dd > < p > She lends you her boat. The conversation ends.
< dt > "A fish." (if you have one)
< dt > "A newspaper." (if you have one)
< dt > "A pebble." (if you have one)
< dd > < p > "No thanks", she replies. Your conversation options
at this point are the same as they were after asking to borrow
her boat, minus any options you've suggested before.
</ dl >
</ dd >
</ dl >
</ dd >
< dt > "Vote for me in the next election!"
< dd > < p > She turns away. The conversation finishes.
< dt > "Madam, are you aware that your fish are running away?"
< dd >
< p > She looks at you skeptically and says "Fish cannot run, miss".
< dl >
< dt > "You got me!"
< dd > < p > The fisher sighs and the conversation ends.
< dt > "Only kidding."
< dd > < p > "Good one!" she retorts. Your conversation options at this
point are the same as those following "Hello there!" above.
< dt > "Oh, then what are they doing?"
< dd > < p > She looks at her fish, giving you an opportunity to steal
her boat, which you do. The conversation ends.
</ dl >
</ dd >
</ dl >
在一些游戏中,对话更简单:每个角色只是有一组固定的台词。在这个示例中,游戏FAQ/攻略列出了一些已知的每个角色可能的回复:
< section >
< h1 > Dialogue</ h1 >
< p >< small > Some characters repeat their lines in order each time you interact
with them, others randomly pick from amongst their lines. Those who respond in
order have numbered entries in the lists below.</ small >
< h2 > The Shopkeeper</ h2 >
< ul >
< li > How may I help you?
< li > Fresh apples!
< li > A loaf of bread for madam?
</ ul >
< h2 > The pilot</ h2 >
< p > Before the accident:
< ul >
< li > I'm about to fly out, sorry!
< li > Sorry, I'm just waiting for flight clearance and then I'll be off!
</ ul >
< p > After the accident:
< ol >
< li > I'm about to fly out, sorry!
< li > Ok, I'm not leaving right now, my plane is being cleaned.
< li > Ok, it's not being cleaned, it needs a minor repair first.
< li > Ok, ok, stop bothering me! Truth is, I had a crash.
</ ol >
< h2 > Clan Leader</ h2 >
< p > During the first clan meeting:
< ul >
< li > Hey, have you seen my daughter? I bet she's up to something nefarious again...
< li > Nice weather we're having today, eh?
< li > The name is Bailey, Jeff Bailey. How can I help you today?
< li > A glass of water? Fresh from the well!
</ ul >
< p > After the earthquake:
< ol >
< li > Everyone is safe in the shelter, we just have to put out the fire!
< li > I'll go and tell the fire brigade, you keep hosing it down!
</ ol >
</ section >
HTML没有专门的机制来标记脚注。以下是建议的替代方法。
对于简短的行内注释,可以使用title
属性。
在这个例子中,对话中的两个部分使用title
属性进行了类似脚注的注释。
< p > < b > Customer</ b > : Hello! I wish to register a complaint. Hello. Miss?
< p > < b > Shopkeeper</ b > : < span title = "Colloquial pronunciation of 'What do you'"
> Watcha</ span > mean, miss?
< p > < b > Customer</ b > : Uh, I'm sorry, I have a cold. I wish to make a complaint.
< p > < b > Shopkeeper</ b > : Sorry, < span title = "This is, of course, a lie." > we're
closing for lunch</ span > .
不幸的是,目前不建议依赖title
属性,因为许多用户代理没有按照本规范的要求以可访问的方式暴露该属性(例如,需要使用鼠标等指示设备才能显示工具提示,这排除了仅使用键盘的用户和仅使用触摸设备的用户,如使用现代手机或平板电脑的人)。
如果使用title
属性,可以使用CSS将读者的注意力引向具有该属性的元素。
例如,以下CSS在具有title
属性的元素下方放置虚线。
[title] { border-bottom : thin dashed; }
对于较长的注释,应使用a
元素,指向文档中的一个稍后的元素。惯例是链接内容为方括号中的数字。
在此示例中,对话中的脚注链接到对话下方的一个段落。然后,该段落反向链接回对话,让用户可以返回脚注的位置。
< p > Announcer: Number 16: The < i > hand</ i > .
< p > Interviewer: Good evening. I have with me in the studio tonight
Mr Norman St John Polevaulter, who for the past few years has been
contradicting people. Mr Polevaulter, why < em > do</ em > you
contradict people?
< p > Norman: I don't. < sup >< a href = "#fn1" id = "r1" > [1]</ a ></ sup >
< p > Interviewer: You told me you did!
...
< section >
< p id = "fn1" >< a href = "#r1" > [1]</ a > This is, naturally, a lie,
but paradoxically if it were true he could not say so without
contradicting the interviewer and thus making it false.</ p >
</ section >
对于侧注,即适用于整个文本段落而不仅仅是特定单词或句子的较长注释,应使用aside
元素。
在此示例中,对话后提供了一个侧栏,为其提供了一些背景。
< p > < span class = "speaker" > Customer</ span > : I will not buy this record, it is scratched.
< p > < span class = "speaker" > Shopkeeper</ span > : I'm sorry?
< p > < span class = "speaker" > Customer</ span > : I will not buy this record, it is scratched.
< p > < span class = "speaker" > Shopkeeper</ span > : No no no, this's'a tobacconist's.
< aside >
< p > In 1970, the British Empire lay in ruins, and foreign
nationalists frequented the streets — many of them Hungarians
(not the streets — the foreign nationals). Sadly, Alexander
Yalt has been publishing incompetently-written phrase books.
</ aside >
对于图表或表格,脚注可以包含在相关的figcaption
或caption
元素中,或在周围的文章中。
在此示例中,表格中包含有脚注的单元格,并在文章中给出脚注。使用figure
元素为表格及其脚注组合提供单个说明。
< figure >
< figcaption > Table 1. Alternative activities for knights.</ figcaption >
< table >
< tr >
< th > Activity
< th > Location
< th > Cost
< tr >
< td > Dance
< td > Wherever possible
< td > £0< sup >< a href = "#fn1" > 1</ a ></ sup >
< tr >
< td > Routines, chorus scenes< sup >< a href = "#fn2" > 2</ a ></ sup >
< td > Undisclosed
< td > Undisclosed
< tr >
< td > Dining< sup >< a href = "#fn3" > 3</ a ></ sup >
< td > Camelot
< td > Cost of ham, jam, and spam< sup >< a href = "#fn4" > 4</ a ></ sup >
</ table >
< p id = "fn1" > 1. Assumed.</ p >
< p id = "fn2" > 2. Footwork impeccable.</ p >
< p id = "fn3" > 3. Quality described as "well".</ p >
< p id = "fn4" > 4. A lot.</ p >
</ figure >
一个元素被称为实际禁用,如果它是以下之一:
button
元素,该元素被禁用input
元素,该元素被禁用select
元素,该元素被禁用textarea
元素,该元素被禁用optgroup
元素,该元素具有禁用
属性
option
元素,该元素被禁用
fieldset
元素,该元素是禁用的
fieldset这个定义用于确定哪些元素是可聚焦的,以及哪些元素匹配:enabled
和:disabled
伪类。
CSS 值和单位 将 'attr()' 函数中属性名称的大小写敏感性留给宿主语言定义。[CSSVALUES]
当将 CSS 'attr()' 函数的属性名称部分与 HTML 元素 在 HTML 文档 中的无命名空间属性名称进行比较时,CSS 'attr()' 函数的名称部分必须首先被 转换为 ASCII 小写。当与其他属性进行比较时,函数必须根据其原始大小写进行比较。在这两种情况下,要匹配的值必须 相同(因此比较是区分大小写的)。
这与下一节中指定的 CSS 属性选择器 的名称部分比较相同。
选择器 将元素名称、属性名称和属性值的大小写敏感性留给宿主语言定义。[SELECTORS]
当将 CSS 元素 类型选择器 与 HTML 元素 在 HTML 文档 中进行比较时,CSS 元素 类型选择器 必须首先被 转换为 ASCII 小写。当与其他元素进行比较时,选择器必须根据其原始大小写进行比较。在这两种情况下,要匹配的值必须 相同(因此比较是区分大小写的)。
当将 CSS 属性选择器 的名称部分与 HTML 元素 在 HTML 文档 中的属性名称进行比较时,CSS 属性选择器 的名称部分必须首先被 转换为 ASCII 小写。当与其他属性进行比较时,选择器必须根据其原始大小写进行比较。在这两种情况下,比较都是区分大小写的。
属性选择器 在 HTML 元素 的 HTML 文档 中必须将以下名称的属性的 值 视为 ASCII 不区分大小写:
accept
accept-charset
align
alink
axis
bgcolor
charset
checked
clear
codetype
color
compact
declare
defer
dir
direction
disabled
enctype
face
frame
hreflang
http-equiv
lang
language
link
media
method
multiple
nohref
noresize
noshade
nowrap
readonly
rel
rev
rules
scope
scrolling
selected
shape
target
text
type
valign
valuetype
vlink
例如,选择器[bgcolor="#ffffff"]
将匹配任何具有bgcolor
属性且值为#ffffff
、#FFFFFF
和#fffFFF
的HTML元素。即使bgcolor
对某个元素没有效果(例如div
),也会匹配。
选择器[type=a s]
将匹配任何type
属性值为a
的HTML元素,但不会匹配属性值为A
的元素,因为有s
标志。
为了选择器匹配的目的,所有其他属性值和所有其他内容必须被视为完全完全相同。这包括:
Selectors定义了当ID和类选择器(如#foo
和.bar
)在怪异模式文档中匹配元素时,将以ASCII大小写不敏感的方式进行匹配。然而,这不适用于名称部分为"id
"或"class
"的属性选择器。选择器[class="foobar"]
将在怪异模式下也将其值视为区分大小写。
有许多动态选择器可以与 HTML 一起使用。本节定义了这些选择器何时与 HTML 元素匹配。 [SELECTORS] [CSSUI]
:defined
在所有当前引擎中支持。
:link
在所有当前引擎中支持。
:visited
在所有当前引擎中支持。
所有具有 a
元素的
href
属性的元素,以及所有具有 area
元素的
href
属性的元素,必须匹配 :link
和
:visited
之一。
其他规范可能会应用更具体的规则,规定这些元素如何匹配这些 伪类,以缓解某些隐私问题,这些问题适用于此要求的直接实现。
:active
在所有当前引擎中支持。
为了确定某个特定元素是否被激活,以定义 :active
伪类,HTML 用户代理必须使用以下列表中的第一个相关条目。
button
元素input
元素,并且其 type
属性处于
提交按钮、图像按钮、重置按钮或 按钮 状态
href
属性的 a
元素
href
属性的 area
元素
例如,如果用户通过按下空格键使用键盘按下一个 button
元素,则该元素将在接收到 keydown
事件和接收到 keyup
事件之间匹配此 伪类。
该元素 被激活。
一个元素在用户开始表示触发元素的激活行为的意图时处于 正式激活状态,并且在用户停止表示触发元素的激活行为的意图时,或者元素的激活行为运行完成时,或者以先到者为准。
一个元素在用户使用指示设备指示元素时,并且指示设备处于“按下”状态(例如,对于鼠标,在按下鼠标按钮和释放鼠标按钮之间;对于多点触控环境中的手指,当手指触摸显示表面时),被称为 被主动指向。
根据 Selectors 中的定义,:active
还匹配被 激活 的元素的 扁平树 祖先。 [SELECTORS]
此外,任何作为当前匹配 :active
的
label
元素的 标记控件 的元素也匹配 :active
。
(但它不算作被 激活。)
:hover
在所有当前引擎中支持。
:hover
伪类 被定义为匹配用户用指示设备指示的元素。在定义
:hover
伪类 时,HTML 用户代理必须将元素视为用户用指示设备指示的元素。
根据 Selectors 中的定义,:hover
还匹配被 扁平树 祖先的元素指定。 [SELECTORS]
此外,任何作为当前匹配 :hover
的
label
元素的 标记控件 的元素也匹配
:hover
。
(但它不算作被 指定。)
特别考虑如下片段:
< p > < label for = c > < input id = a > </ label > < span id = b > < input id = c > </ span > </ p >
如果用户使用指示设备指示 ID 为 "a
" 的元素,则 p
元素
(及其在上面的代码片段中未显示的所有祖先元素),label
元素,ID 为 "a
" 的元素,以及
ID 为 "c
" 的元素将匹配 :hover
伪类。ID 为 "a
" 的元素通过被 指定 匹配;label
和 p
元素通过
Selectors 中的扁平树祖先条件匹配;
以及 ID 为 "c
" 的元素通过上述关于 标记控件
的附加条件匹配(即其 label
元素匹配 :hover
)。但是,ID
为 "b
" 的元素不匹配 :hover
:其扁平树后代未被指定,尽管该扁平树后代匹配
:hover
。
:focus
在所有当前引擎中支持。
它本身不是 可导航容器;并且
以下任何一个为真:
它是 顶级可遍历对象的当前焦点链 中的一个元素;或者
:target
在所有当前引擎中支持。
对于 CSS :target
伪类,文档
的目标元素是包含 文档
的 目标元素
的列表,如果它不为空,否则包含没有元素的列表。 [SELECTORS]
:popover-open
在所有当前引擎中支持。
:popover-open
伪类 被定义为匹配任何 HTML
元素,其 popover
属性不处于 无弹出框状态,并且其 弹出框可见性状态 为 显示 状态。
:enabled
在所有当前引擎中支持。
:enabled
伪类 必须匹配任何 button
、input
、select
、textarea
、optgroup
、option
、fieldset
元素,或未被 实际禁用 的 表单关联自定义元素。
:disabled
在所有当前引擎中支持。
:checked
在所有当前引擎中支持。
:indeterminate
在所有当前引擎中支持。
:indeterminate
伪类
必须匹配以下类别中的任何元素:
:default
在所有当前引擎中支持。
:placeholder-shown
:placeholder-shown
伪类 必须匹配以下类别中的任何元素:
input
元素具有一个 placeholder
属性,其值当前正在呈现给用户textarea
元素具有一个 placeholder
属性,其值当前正在呈现给用户:valid
在所有当前引擎中支持。
:invalid
在所有当前引擎中支持。
:user-valid
:user-valid
伪类 必须匹配 input
、textarea
和 select
元素,其 用户有效性 为 true、约束验证候选,并且 满足其约束。
:user-invalid
:user-invalid
伪类 必须匹配 input
、textarea
和 select
元素,其 用户有效性 为 true、约束验证候选,但不 满足其约束。
:in-range
在所有当前引擎中支持。
:out-of-range
所有当前引擎都支持。
:out-of-range
伪类 必须匹配作为 约束验证候选 的所有元素、具有 范围限制
并且
范围不足 或 范围超出。
:required
在所有当前引擎中支持。
:optional
在所有当前引擎中支持。
:autofill
:-webkit-autofill
:autofill
和 :-webkit-autofill
伪类 必须匹配已被用户代理自动填充的 input
元素。当用户编辑自动填充字段时,这些伪类必须停止匹配。
这种自动填充可能的一种方式是通过 autocomplete
属性,但即使没有该属性,用户代理也可以进行自动填充。
:read-only
在所有当前引擎中支持。
:read-write
在所有当前引擎中支持。
:read-write
伪类 必须匹配属于以下类别的任何元素,出于选择器的目的,这些类别被认为是 用户可变的:[SELECTORS]
input
元素,其应用了 readonly
属性,并且是 可变的(即不具有 readonly
属性,并且不 禁用)
textarea
元素,不具有 readonly
属性,并且不 禁用
input
元素也不是 textarea
元素
:read-only
伪类 必须匹配所有其他 HTML 元素。
:modal
:dir(ltr)
:dir(rtl)
:state(identifier)
伪类必须匹配所有 自定义元素,其 状态集 的 集合条目 包含
identifier。
:playing
:paused
:seeking
:buffering
:buffering
伪类 必须匹配所有 媒体元素,其 paused
属性为假,networkState
属性为 NETWORK_LOADING
,且准备状态为
HAVE_CURRENT_DATA
或更低。
:stalled
:stalled
伪类 必须匹配所有 媒体元素,其匹配 :buffering
伪类,且 当前停滞
为真。
:muted
:volume-locked
:volume-locked
伪类 必须匹配所有 媒体元素,当用户代理的 音量锁定 为真时。
本规范未定义元素何时匹配 :lang()
动态 伪类,因为在
选择器
中以与语言无关的方式已足够详细地定义。[SELECTORS]
本节是非规范性的。
有时候,希望用特定的机器可读标签来注释内容,例如允许通用脚本提供针对页面定制的服务,或使来自不同作者的内容能够被单一脚本一致地处理。
为此,作者可以使用本节中描述的微数据功能。微数据允许在文档中添加名称-值对的嵌套组,与现有内容并行存在。
本节是非规范性的。
从高层次来看,微数据由一组名称-值对组成。每组称为项目,每个名称-值对是一个属性。项目和属性由常规元素表示。
要创建一个项目,使用itemscope
属性。
要为项目添加属性,使用itemprop
属性在项目的一个子代上。
这里有两个项目,每个都有属性 "name":
< div itemscope >
< p > My name is < span itemprop = "name" > Elizabeth</ span > .</ p >
</ div >
< div itemscope >
< p > My name is < span itemprop = "name" > Daniel</ span > .</ p >
</ div >
没有与微数据相关属性的标记不会对微数据模型产生任何影响。
这两个例子在微数据层面上与前面两个例子完全等效:
< div itemscope >
< p > My < em > name</ em > is < span itemprop = "name" > E< strong > liz</ strong > abeth</ span > .</ p >
</ div >
< section >
< div itemscope >
< aside >
< p > My name is < span itemprop = "name" >< a href = "/?user=daniel" > Daniel</ a ></ span > .</ p >
</ aside >
</ div >
</ section >
属性通常具有字符串值。
这里的项目有三个属性:
< div itemscope >
< p > My name is < span itemprop = "name" > Neil</ span > .</ p >
< p > My band is called < span itemprop = "band" > Four Parts Water</ span > .</ p >
< p > I am < span itemprop = "nationality" > British</ span > .</ p >
</ div >
当字符串值是URL时,它通过a
元素及其href
属性,img
元素及其src
属性,或其他链接或嵌入外部资源的元素来表示。
在这个例子中,该项目有一个属性 "image",其值是一个 URL:
< div itemscope >
< img itemprop = "image" src = "google-logo.png" alt = "Google" >
</ div >
当字符串值为某种机器可读格式,不适合人类使用时,它通过value
属性的data
元素来表示,元素内容中给出人类可读版本。
这里有一个项目,其属性值是一个产品ID。由于ID不适合人类阅读,产品的名称作为人类可见文本使用,而不是ID。
< h1 itemscope >
< data itemprop = "product-id" value = "9678AOU879" > The Instigator 2000</ data >
</ h1 >
这里使用meter
元素给出了一个评分。
< div itemscope itemtype = "http://schema.org/Product" >
< span itemprop = "name" > Panasonic White 60L Refrigerator</ span >
< img src = "panasonic-fridge-60l-white.jpg" alt = "" >
< div itemprop = "aggregateRating"
itemscope itemtype = "http://schema.org/AggregateRating" >
< meter itemprop = "ratingValue" min = 0 value = 3.5 max = 5 > Rated 3.5/5</ meter >
(based on < span itemprop = "reviewCount" > 11</ span > customer reviews)
</ div >
</ div >
同样地,对于日期和时间相关的数据,可以使用time
元素及其datetime
属性。
在这个例子中,该项目有一个属性 "birthday",其值是一个日期:
< div itemscope >
I was born on < time itemprop = "birthday" datetime = "2009-05-10" > May 10th 2009</ time > .
</ div >
通过在声明属性的元素上添加itemscope
属性,属性本身也可以是名称-值对的组。
不属于其他项目的项目称为顶级微数据项目。
在这个例子中,外部项目表示一个人,内部项目表示一个乐队:
< div itemscope >
< p > Name: < span itemprop = "name" > Amanda</ span ></ p >
< p > Band: < span itemprop = "band" itemscope > < span itemprop = "name" > Jazz Band</ span > (< span itemprop = "size" > 12</ span > players)</ span ></ p >
</ div >
这里的外部项目有两个属性,"name" 和 "band"。"name" 是 "Amanda",而 "band" 本身也是一个项目,有两个属性,"name" 和 "size"。"band" 的名称是 "Jazz Band",而 "size" 是 "12"。
这个例子中的外部项目是一个顶级微数据项目。
不是itemscope
属性元素的后代的属性,可以使用itemref
属性与项目关联。该属性接受一个元素ID列表,除了遍历具有itemscope
属性的元素的子元素外,还会遍历这些ID列表中的元素。
这个例子与前一个相同,但所有属性都与它们的项目分开:
< div itemscope id = "amanda" itemref = "a b" ></ div >
< p id = "a" > Name: < span itemprop = "name" > Amanda</ span ></ p >
< div id = "b" itemprop = "band" itemscope itemref = "c" ></ div >
< div id = "c" >
< p > Band: < span itemprop = "name" > Jazz Band</ span ></ p >
< p > Size: < span itemprop = "size" > 12</ span > players</ p >
</ div >
这与前一个例子产生相同的结果。第一个项目有两个属性:"name" 设置为 "Amanda","band" 设置为另一个项目。第二个项目有两个进一步的属性:"name" 设置为 "Jazz Band","size" 设置为 "12"。
一个项目可以有多个同名但不同值的属性。
这个例子描述了一种冰淇淋,有两种口味:
< div itemscope >
< p > Flavors in my favorite ice cream:</ p >
< ul >
< li itemprop = "flavor" > Lemon sorbet</ li >
< li itemprop = "flavor" > Apricot sorbet</ li >
</ ul >
</ div >
因此,这个项目有两个属性,都是 "flavor",其值分别为 "Lemon sorbet" 和 "Apricot sorbet"。
引入属性的元素也可以同时引入多个属性,以避免某些属性具有相同值时的重复。
这里我们看到一个项目有两个属性,"favorite-color" 和 "favorite-fruit",它们的值都是 "orange":
< div itemscope >
< span itemprop = "favorite-color favorite-fruit" > orange</ span >
</ div >
重要的是要注意,微数据与标记微数据的文档内容之间没有关系。
例如,以下两个例子之间没有语义上的区别:
< figure >
< img src = "castle.jpeg" >
< figcaption >< span itemscope >< span itemprop = "name" > The Castle</ span ></ span > (1986)</ figcaption >
</ figure >
< span itemscope >< meta itemprop = "name" content = "The Castle" ></ span >
< figure >
< img src = "castle.jpeg" >
< figcaption > The Castle (1986)</ figcaption >
</ figure >
两者都有一个带有标题的图形,并且两者都有一个与图形完全无关的项目,该项目有一个名称-值对,名称是 "name",值是 "The Castle"。唯一的区别是,如果用户将标题从文档中拖出,在前一种情况下,该项目将包含在拖放数据中。在任何情况下,图像都不会与该项目有任何关联。
本节是非规范性的。
前一节中的示例显示了如何在不期望其微数据被重用的页面上标记信息。然而,微数据在其他作者和读者能够合作以新的方式使用标记的上下文中最有用。
为此,有必要为每个项目赋予一个类型,例如 "https://example.com/person"、"https://example.org/cat" 或 "https://band.example.net/"。类型被标识为URL。
项目的类型作为与itemscope
属性相同元素上的itemtype
属性的值给出。
这里,项目的类型是 "https://example.org/animals#cat":
< section itemscope itemtype = "https://example.org/animals#cat" >
< h1 itemprop = "name" > Hedral</ h1 >
< p itemprop = "desc" > Hedral is a male american domestic
shorthair, with a fluffy black fur with white paws and belly.</ p >
< img itemprop = "img" src = "hedral.jpeg" alt = "" title = "Hedral, age 18 months" >
</ section >
在这个例子中,"https://example.org/animals#cat" 项目有三个属性:"name" ("Hedral")、"desc" ("Hedral is...") 和 "img" ("hedral.jpeg")。
类型为属性提供了上下文,从而选择了一个词汇表:对于类型为 "https://census.example/person" 的项目来说,属性 "class" 可能指的是个人的经济阶层,而对于类型为
"https://example.com/school/teacher" 的项目来说,属性 "class" 可能指的是教师被分配的教室。几个类型可以共享一个词汇表。例如,类型
"https://example.org/people/teacher
" 和 "https://example.org/people/engineer
"
可以被定义为使用相同的词汇表(尽管某些属性在这两种情况下可能不会特别有用,例如,"https://example.org/people/engineer
" 类型可能通常不会与
"classroom
" 属性一起使用)。使用相同词汇表定义的多个类型可以通过在属性值中列出用空格分隔的URL列表来赋予一个项目。然而,如果两个类型不使用相同的词汇表,则不能为一个项目赋予这两个类型。
本节是非规范性的。
有时候,一个项目提供了关于一个有全局标识符的话题的信息。例如,书籍可以通过其ISBN号进行标识。
词汇表(由itemtype
属性标识)可以被设计为使得项目通过在itemid
属性中给出的URL来明确地与它们的全局标识符关联。
itemid
属性中给出的URL的确切含义取决于所使用的词汇表。
这里,一个项目谈论的是一本特定的书:
< dl itemscope
itemtype = "https://vocab.example.net/book"
itemid = "urn:isbn:0-330-34032-8" >
< dt > Title
< dd itemprop = "title" > The Reality Dysfunction
< dt > Author
< dd itemprop = "author" > Peter F. Hamilton
< dt > Publication date
< dd >< time itemprop = "pubdate" datetime = "1996-01-26" > 26 January 1996</ time >
</ dl >
在这个例子中,"https://vocab.example.net/book
" 词汇表会定义itemid
属性使用指向书籍ISBN的urn:
URL。
本节是非规范性的。
使用微数据意味着使用词汇表。对于某些目的,即席词汇表就足够了。对于其他情况,则需要设计一个词汇表。在可能的情况下,鼓励作者重用现有词汇表,因为这使内容重用更容易。
在设计新词汇表时,可以使用URL创建标识符,或者,对于属性,可以使用简单的单词(不带点或冒号)。对于URL,通过只使用对应作者控制页面的标识符,可以避免与其他词汇表冲突。
例如,如果Jon和Adam分别在example.com
的https://example.com/~jon/...
和https://example.com/~adam/...
撰写内容,那么他们可以分别选择形式为
"https://example.com/~jon/name" 和 "https://example.com/~adam/name" 的标识符。
仅为普通单词的属性名只能在为其设计的类型上下文中使用;使用URL命名的属性可以在任何类型的项目中重用。如果一个项目没有类型,并且不是另一个项目的一部分,那么如果其属性名只是普通单词,则不打算是全局唯一的,而是仅用于有限的范围。一般来说,鼓励作者使用具有全局唯一名称(URL)的属性,或者确保其项目有类型。
这里,一个项目是 "https://example.org/animals#cat",大多数属性的名称是在该类型上下文中定义的单词。还有一些其他属性,其名称来自其他词汇表。
< section itemscope itemtype = "https://example.org/animals#cat" >
< h1 itemprop = "name https://example.com/fn" > Hedral</ h1 >
< p itemprop = "desc" > Hedral is a male American domestic
shorthair, with a fluffy < span
itemprop = "https://example.com/color" > black</ span > fur with < span
itemprop = "https://example.com/color" > white</ span > paws and belly.</ p >
< img itemprop = "img" src = "hedral.jpeg" alt = "" title = "Hedral, age 18 months" >
</ section >
这个例子中有一个类型为 "https://example.org/animals#cat" 的项目,具有以下属性:
属性 | 值 |
name | Hedral |
https://example.com/fn | Hedral |
desc | Hedral 是一只雄性美国本土短毛猫,拥有蓬松的黑色毛发,白色的爪子和肚子。 |
https://example.com/color | black |
https://example.com/color | white |
img | .../hedral.jpeg |
微数据模型由称为项目的名称-值对组组成。
每个组称为一个项目。每个项目可以有项目类型、全局标识符(如果由项目类型指定的词汇表支持项目的全局标识符),以及一个名称-值对列表。名称-值对中的每个名称称为属性,每个属性有一个或多个值。每个值要么是一个字符串,要么本身就是一个名称-值对组(即一个项目)。名称相对于彼此是无序的,但如果某个特定名称有多个值,它们确实有相对顺序。
Support in all current engines.
每个HTML 元素可以指定一个itemscope
属性。itemscope
属性是一个布尔属性。
具有itemscope
属性的元素会创建一个新的项目,即一组名称-值对。
Support in all current engines.
具有itemscope
属性的元素可以指定一个itemtype
属性,以提供该项目的类型。
如果指定,itemtype
属性必须具有一个值,该值是无序的一组唯一空格分隔的标记,其中没有任何标记与其他标记相同,每个标记都是有效的URL字符串,且是一个绝对URL,并且所有标记都使用相同的词汇表。属性的值必须至少有一个标记。
项目类型是项目通过按ASCII空白符分割元素的itemtype
属性的值获得的标记。如果itemtype
属性缺失或以这种方式解析没有找到标记,则该项目被认为没有项目类型。
项目类型必须都是适用规范中定义的类型,且必须都使用相同的词汇表。
除非该规范另有规定,否则作为项目类型给出的URL不应被自动取消引用。
规范可以定义其项目类型可以取消引用以提供帮助信息。例如,词汇表的作者被鼓励在给定的URL处提供有用的信息。
项目类型是不透明的标识符,用户代理不得取消引用未知的项目类型或以其他方式解构它们,以确定如何处理使用它们的项目。
没有指定itemscope
属性的元素不得指定itemtype
属性。
当一个项目具有项目类型或它是属性的值时,该项目被称为类型化项目。相关类型对于一个类型化项目来说是该项目的项目类型,如果它有任何类型,或者是它作为属性的值的项目的相关类型。
Support in all current engines.
具有itemscope
属性和引用定义为支持项目的全局标识符的词汇表的itemtype
属性的元素,也可以指定一个itemid
属性,以提供该项目的全局标识符,以便它可以与网页其他地方的其他项目相关联。
如果指定,itemid
属性必须具有一个有效的可能被空格包围的URL值。
全局标识符是项目的其元素的itemid
属性的值(如果有的话),相对于指定属性的元素的节点文档进行解析。如果itemid
属性缺失或解析失败,则该项目被认为没有全局标识符。
没有同时指定itemscope
属性和itemtype
属性的元素,不得指定itemid
属性,且具有itemscope
属性但其itemtype
属性指定了不支持项目全局标识符的词汇表的元素,也不得指定itemid
属性,如该词汇表规范所定义。
全局标识符的确切含义由词汇表的规范确定。这样的规范负责定义是否允许存在具有相同全局标识符的多个项目(无论在同一页面上还是在不同页面上),以及在处理具有相同ID的多个项目时该词汇表的处理规则是什么。
Support in all current engines.
具有itemscope
属性的元素可以指定itemref
属性,以提供额外的元素列表,以便遍历找到该项目的名称-值对。
如果指定,itemref
属性必须具有一个无序的一组唯一空格分隔的标记,其中没有任何标记与其他标记相同,并且由同一树中的元素ID组成。
没有指定itemscope
属性的元素不得指定itemref
属性。
itemref 属性不是微数据数据模型的一部分。它只是一个语法构造,旨在帮助作者在数据不遵循方便的树结构时添加注释。例如,它允许作者在表格中标记数据,以便每列定义一个单独的项目,同时将属性保留在单元格中。
此示例显示了一个用于描述模型铁路制造商产品的简单词汇表。该词汇表只有五个属性名称:
此词汇表定义了四种项目类型:
使用此词汇表的每个项目可以根据产品的不同分配一个或多个这些类型。
因此,机车可以标记为:
< dl itemscope itemtype = "https://md.example.com/loco
https://md.example.com/lighting" >
< dt > Name:
< dd itemprop = "name" > Tank Locomotive (DB 80)
< dt > Product code:
< dd itemprop = "product-code" > 33041
< dt > Scale:
< dd itemprop = "scale" > HO
< dt > Digital:
< dd itemprop = "digital" > Delta
</ dl >
转辙灯改装套件可能标记为:
< dl itemscope itemtype = "https://md.example.com/track
https://md.example.com/lighting" >
< dt > Name:
< dd itemprop = "name" > Turnout Lantern Kit
< dt > Product code:
< dd itemprop = "product-code" > 74470
< dt > Purpose:
< dd > For retrofitting 2 < span itemprop = "track-type" > C</ span > Track
turnouts. < meta itemprop = "scale" content = "HO" >
</ dl >
没有照明的客车可能标记为:
< dl itemscope itemtype = "https://md.example.com/passengers" >
< dt > Name:
< dd itemprop = "name" > Express Train Passenger Car (DB Am 203)
< dt > Product code:
< dd itemprop = "product-code" > 8710
< dt > Scale:
< dd itemprop = "scale" > Z
</ dl >
在创建新词汇表时需要非常小心。通常,可以采取层次化的方法来处理类型,从而产生一个每个项目只有一个类型的词汇表,这通常更容易管理。
itemprop
属性Support in all current engines.
每个HTML元素都可以指定一个itemprop
属性,如果这样做为一个或多个项目添加一个或多个属性(如下定义)。
如果指定,itemprop
属性必须具有一个值,该值是无序的一组唯一的空格分隔标记,其中没有任何标记与其他标记相同,表示它添加的名称-值对的名称。属性的值必须至少有一个标记。
每个标记必须是以下之一:
引入定义的属性名称的规范必须确保所有此类属性名称不包含U+002E句点字符(.)、U+003A冒号字符(:)和任何ASCII空白字符。
上述规则禁止非URL值中的U+003A冒号字符(:),因为否则无法将它们与URL区分开来。包含U+002E句点字符(.)的值保留用于将来的扩展。禁止使用ASCII空白字符,因为否则这些值将被解析为多个标记。
当具有itemprop
属性的元素为多个项目添加属性时,上述关于标记的要求适用于每个项目。
元素的属性名称是指该元素的itemprop
属性的值在按ASCII空白符分割时包含的标记,保留顺序但删除重复项(仅保留每个名称的第一次出现)。
在一个项目中,属性相对于彼此是无序的,除了具有相同名称的属性,它们按照 定义项目属性的算法给出的顺序排列。
在下面的示例中,"a" 属性的值是 "1" 和 "2",按此顺序,但 "a" 属性是否在 "b" 属性之前并不重要:
< div itemscope >
< p itemprop = "a" > 1</ p >
< p itemprop = "a" > 2</ p >
< p itemprop = "b" > test</ p >
</ div >
因此,以下内容是等效的:
< div itemscope >
< p itemprop = "b" > test</ p >
< p itemprop = "a" > 1</ p >
< p itemprop = "a" > 2</ p >
</ div >
同样,以下内容也是等效的:
< div itemscope >
< p itemprop = "a" > 1</ p >
< p itemprop = "b" > test</ p >
< p itemprop = "a" > 2</ p >
</ div >
以及以下内容:
< div id = "x" >
< p itemprop = "a" > 1</ p >
</ div >
< div itemscope itemref = "x" >
< p itemprop = "b" > test</ p >
< p itemprop = "a" > 2</ p >
</ div >
由具有itemprop
属性的元素添加的名称-值对的属性值如下列表中第一个匹配的情况所示:
itemscope
属性
该值是由该元素创建的项目。
meta
元素
该值是该元素的content
属性的值(如果有),如果没有此属性,则为空字符串。
audio
、embed
、iframe
、img
、source
、track
或video
元素该值是根据元素的src
属性的值进行编码、解析和序列化URL的结果,相对于元素的节点文档,在设置属性时,如果没有此属性或结果为失败,则为空字符串。
a
、area
或link
元素该值是根据元素的href
属性的值进行编码、解析和序列化URL的结果,相对于元素的节点文档,在设置属性时,如果没有此属性或结果为失败,则为空字符串。
object
元素该值是根据元素的data
属性的值进行编码、解析和序列化URL的结果,相对于元素的节点文档,在设置属性时,如果没有此属性或结果为失败,则为空字符串。
data
元素
该值是该元素的value
属性的值(如果有),否则为空字符串。
meter
元素
该值是该元素的value
属性的值(如果有),否则为空字符串。
time
元素
该值是该元素的datetime值。
该值是该元素的后代文本内容。
URL属性元素是a
、area
、audio
、embed
、iframe
、img
、link
、object
、source
、track
和video
元素。
如果属性的值,如属性定义所述,是一个绝对URL,则必须使用URL属性元素来指定该属性。
这些要求仅因为属性值恰好匹配URL的语法而适用。它们仅在属性明确定义为采用此类值时才适用。
例如,关于首次登月的书可以被称为“mission:moon”。定义标题为字符串的词汇表中的“title”属性不会期望在a
元素中给出标题,即使它看起来像一个URL。另一方面,如果有一个(范围非常狭窄的!)词汇表,用于“标题看起来像URL的书籍”,其中的“title”属性被定义为接受URL,那么该属性会期望在a
元素(或其他URL属性元素之一)中给出标题,因为上述要求。
为了找到由元素root定义的项目的属性,用户代理必须运行以下步骤。这些步骤也用于标记微数据错误。
让results、memory和pending成为空的元素列表。
将元素root添加到memory中。
如果有的话,将root的子元素添加到pending中。
如果root具有itemref
属性,按ASCII空白符分割itemref
属性的值。对于每个生成的标记ID,如果root的树中有一个具有ID为ID的元素,则将第一个这样的元素添加到pending中。
当pending不为空时:
按照树顺序对results进行排序。
返回results。
文档中不得包含任何项目,这些项目的属性查找算法发现任何微数据错误。
如果其元素没有itemprop
属性,则该项目是顶级微数据项目。
在文档
中,所有itemref
属性必须使得由将每个项目表示为图中的节点,并将项目的每个属性的值为另一个项目的属性表示为图中连接这两个项目的边,从而形成的图中没有循环。
文档中不得包含任何具有itemprop
属性的元素,这些属性在确定文档中所有属性时不会被发现为任何项目的属性。
在此示例中,使用来自表示作品的项目的itemref
,将单个许可声明应用于两个作品:
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< title > Photo gallery</ title >
</ head >
< body >
< h1 > My photos</ h1 >
< figure itemscope itemtype = "http://n.whatwg.org/work" itemref = "licenses" >
< img itemprop = "work" src = "images/house.jpeg" alt = "A white house, boarded up, sits in a forest." >
< figcaption itemprop = "title" > The house I found.</ figcaption >
</ figure >
< figure itemscope itemtype = "http://n.whatwg.org/work" itemref = "licenses" >
< img itemprop = "work" src = "images/mailbox.jpeg" alt = "Outside the house is a mailbox. It has a leaflet inside." >
< figcaption itemprop = "title" > The mailbox.</ figcaption >
</ figure >
< footer >
< p id = "licenses" > All images licensed under the < a itemprop = "license"
href = "http://www.opensource.org/licenses/mit-license.php" > MIT
license</ a > .</ p >
</ footer >
</ body >
</ html >
以上结果是两个类型为"http://n.whatwg.org/work
"的项目,一个是:
images/house.jpeg
http://www.opensource.org/licenses/mit-license.php
...另一个是:
images/mailbox.jpeg
http://www.opensource.org/licenses/mit-license.php
目前,itemscope
、itemprop
和其他微数据属性仅为HTML元素定义。这意味着具有字面名称“itemscope
”、“itemprop
”等的属性不会在其他命名空间(如SVG)中的元素上引发微数据处理。
因此,在以下示例中,只有一个项目,而不是两个。
< p itemscope ></ p > <!-- this is an item (with no properties and no type) -->
< svg itemscope ></ svg > <!-- this is not, it's just an SVG svg
element with an invalid unknown attribute -->
本节中的词汇表主要用于演示如何指定词汇表,但它们本身也是可用的。
具有 项目类型 http://microformats.org/profile/hcard
的项目代表个人或组织的联系信息。
该词汇表不支持项目的全局标识符。
以下是该类型的定义的属性名称。它们基于 vCard 格式规范 (vCard) 及其扩展中定义的词汇表,可以找到有关如何解释这些值的更多信息。[RFC6350]
kind
描述项目所代表的联系类型。
值必须是与kind strings之一相同的文本。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在一个名为 kind
的属性。
fn
提供与个人或组织的名称相对应的格式化文本。
值必须是文本。
在每个类型为 http://microformats.org/profile/hcard
的项目中,必须存在一个名为 fn
的属性。
n
提供个人或组织的结构化名称。
值必须是一个具有零个或多个
family-name
、given-name
、additional-name
、honorific-prefix
和 honorific-suffix
属性的项目。
在每个类型为 http://microformats.org/profile/hcard
的项目中,必须存在一个名为 n
的属性。
family-name
(inside n
)提供个人的姓氏或组织的全名。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 n
属性的值的项目中,可以存在任意数量的名为 family-name
的属性。
given-name
(inside n
)提供个人的名字。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 n
属性的值的项目中,可以存在任意数量的名为 given-name
的属性。
additional-name
(inside n
)提供个人的任何附加名称。
值必须是文本。
在形成类型
为 http://microformats.org/profile/hcard
的项目的 n
属性的值的项目中,可以存在任意数量的名为 additional-name
的属性。
honorific-prefix
(inside n
)提供个人的荣誉前缀。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 n
属性的值的项目中,可以存在任意数量的名为 honorific-prefix
的属性。
honorific-suffix
(inside n
)提供个人的荣誉后缀。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 n
属性的值的项目中,可以存在任意数量的名为 honorific-suffix
的属性。
nickname
提供个人或组织的昵称。
昵称是代替或附加于个人、地点或事物的描述性名称。它还可以用于指定由 fn
或 n
属性指定的正式名称的熟悉形式。
值必须是文本。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 nickname
的属性。
photo
提供个人或组织的照片。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 photo
的属性。
bday
提供个人或组织的出生日期。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在一个名为 bday
的属性。
anniversary
提供个人或组织的纪念日。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在一个名为 anniversary
的属性。
sex
提供个人的生物性别。
值必须是以下之一:
F
,表示“女性”,M
,表示“男性”,N
,表示“无或不适用”,O
,表示“其他”,U
,表示“未知”。在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在一个名为 sex
的属性。
gender-identity
提供个人的性别认同。
值必须是文本。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在一个名为 gender-identity
的属性。
adr
提供个人或组织的邮寄地址。
值必须是一个具有零个或多个
type
、post-office-box
、extended-address
和 street-address
属性的项目,并且可以选择包含 locality
属性、region
属性、postal-code
属性和 country-name
属性。
如果在形成类型为 http://microformats.org/profile/hcard
的项目的 adr
属性的值的项目中不存在任何
type
属性,则隐含 address type string
work
。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 adr
的属性。
type
(inside adr
)提供邮寄地址的类型。
值必须是与address type strings之一相同的文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 adr
属性的值的项目中,可以存在任意数量的名为 type
的属性,但在每个此类
adr
属性项目中,每个不同的值只允许有一个 type
属性。
post-office-box
(inside adr
)提供个人或组织的邮寄地址中的邮政信箱组件。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 adr
属性的值的项目中,可以存在任意数量的名为 post-office-box
的属性。
vCard 劝告作者不要使用此字段。
extended-address
(inside adr
)提供个人或组织的邮寄地址的附加组件。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 adr
属性的值的项目中,可以存在任意数量的名为 extended-address
的属性。
vCard 劝告作者不要使用此字段。
street-address
(inside adr
)提供个人或组织的邮寄地址中的街道地址组件。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 adr
属性的值的项目中,可以存在任意数量的名为 street-address
的属性。
locality
(inside adr
)提供个人或组织的邮寄地址中的地方(例如城市)组件。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 adr
属性的值的项目中,可以存在一个名为
locality
的属性。
region
(inside adr
)提供个人或组织的邮寄地址中的地区(例如州或省)组件。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 adr
属性的值的项目中,可以存在一个名为
region
的属性。
postal-code
(inside adr
)提供个人或组织的邮寄地址中的邮政编码组件。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 adr
属性的值的项目中
,可以存在一个名为 postal-code
的属性。
country-name
(inside adr
)提供个人或组织的邮寄地址中的国家名称组件。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 adr
属性的值的项目中,可以存在一个名为
country-name
的属性。
tel
提供个人或组织的电话号码。
值必须是可以解释为
CCITT 规范 E.163 和 X.121 中定义的电话号码的文本,或是一个具有零个或多个 type
属性和一个 value
属性的项目。[E163] [X121]
如果在形成类型为 http://microformats.org/profile/hcard
的项目的 tel
属性的值的项目中不存在任何
type
属性,或如果此类
tel
属性的值是文本,则隐含 telephone type
string voice
。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 tel
的属性。
type
(inside tel
)提供电话号码的类型。
值必须是与telephone type strings之一相同的文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 tel
属性的值的项目中,可以存在任意数量的名为 type
的属性,但在每个此类
tel
属性项目中,每个不同的值只允许有一个 type
属性。
value
(inside tel
)提供个人或组织的实际电话号码。
值必须是可以解释为 CCITT 规范 E.163 和 X.121 中定义的电话号码的文本。[E163] [X121]
在形成类型为 http://microformats.org/profile/hcard
的项目的 tel
属性的值
的项目中,必须存在一个名为 value
的属性。
email
提供个人或组织的电子邮件地址。
值必须是文本。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 email
的属性。
impp
提供与个人或组织进行即时消息和存在协议通信的 URL。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 impp
的属性。
lang
提供个人或组织理解的语言。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 lang
的属性。
tz
提供个人或组织的时区。
值必须是文本,并且必须符合以下语法:
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 tz
的属性。
geo
提供个人或组织的地理位置。
值必须是文本,并且必须符合以下语法:
标有星号 (*) 的可选组件应包含在内,并且应各有六位数。
值指定纬度和经度,按此顺序(即“LAT LON”顺序),以十进制度数表示。经度表示以本初子午线为界的东、西位置,分别用正实数和负实数表示。纬度表示以赤道为界的南、北位置,分别用正实数和负实数表示。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 geo
的属性。
title
提供个人或组织的职务、职能或职位。
值必须是文本。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 title
的属性。
role
提供个人或组织的角色、职业或业务类别。
值必须是文本。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 role
的属性。
logo
提供个人或组织的标志。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 logo
的属性。
agent
提供将代表个人或组织行动的其他人的联系信息。
值必须是一个类型为
http://microformats.org/profile/hcard
的项目,或一个 绝对 URL,或文本。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 agent
的属性。
org
提供组织的名称和单位。
值必须是文本,或是一个具有一个 organization-name
属性和零个或多个 organization-unit
属性的项目。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 org
的属性。
organization-name
(inside org
)提供组织的名称。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 org
属性的值的项目中,必须存在一个名为
organization-name
的属性。
organization-unit
(inside org
)提供组织单位的名称。
值必须是文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 org
属性的值的项目中,可以存在任意数量的名为 organization-unit
的属性。
member
提供表示组成员的 URL。
在类型为 http://microformats.org/profile/hcard
的项目中,如果该项目还有一个名为 kind
的属性,其值为 "group
",则可以存在任意数量的名为
member
的属性。
related
提供与另一个实体的关系。
值必须是一个具有一个
url
属性和一个
rel
属性的项目。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 related
的属性。
url
(inside related
)提供相关实体的 URL。
在形成类型为 http://microformats.org/profile/hcard
的项目的 related
属性的值的项目中,必须存在一个名为 url
的属性。
rel
(inside related
)提供实体与相关实体之间的关系。
值必须是与relationship strings之一相同的文本。
在形成类型为 http://microformats.org/profile/hcard
的项目的 related
属性的值的项目中,必须存在一个名为 rel
的属性。
categories
提供个人或组织可以分类的类别或标签的名称。
值必须是文本。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 categories
的属性。
note
提供有关个人或组织的补充信息或评论。
值必须是文本。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 note
的属性。
rev
提供联系信息的修订日期和时间。
值必须是有效的全球日期和时间字符串的文本。
该值区分了当前修订版本和其他版本的信息。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 rev
的属性。
sound
提供与个人或组织相关的声音文件。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 sound
的属性。
uid
提供与个人或组织相对应的全球唯一标识符。
值必须是文本。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在一个名为 uid
的属性。
url
提供与个人或组织相关的 URL。
在每个类型为 http://microformats.org/profile/hcard
的项目中,可以存在任意数量的名为 url
的属性。
类型的 kind strings 是:
individual
表示单个实体(例如一个人)。
group
表示多个实体(例如一个邮件列表)。
org
表示一个不是人的单个实体(例如一家公司)。
location
表示一个地理位置(例如一座办公楼)。
地址类型字符串(address type strings)是:
home
表示住宅的邮寄地址。
work
表示工作地点的邮寄地址。
电话类型字符串(telephone type strings)是:
home
表示住宅号码。
work
表示工作地点的电话号码。
text
表示该电话号码支持短信(SMS)。
voice
表示语音电话号码。
fax
表示传真电话号码。
cell
表示手机号码。
video
表示视频会议电话号码。
pager
表示寻呼机电话号码。
textphone
表示为听力或言语障碍者设计的电信设备号码。
关系字符串(relationship strings)是:
emergency
紧急联系人。
agent
代表此实体行事的其他实体。
具有 XFN 定义的意义。[XFN]
给定 文档
中的节点列表
nodes,用户代理必须运行以下算法来 提取这些节点表示的任何 vCard 数据(仅返回第一个 vCard):
如果 nodes 中没有任何节点是 项,其 项类型为 http://microformats.org/profile/hcard
,则没有
vCard。中止算法,不返回任何内容。
让 node 成为 nodes 中的第一个 项,其 项类型为 http://microformats.org/profile/hcard
的节点。
让 output 成为空字符串。
添加一个 vCard
行,类型为 "BEGIN
",值为 "VCARD
" 到 output。
添加一个 vCard
行,类型为 "PROFILE
",值为 "VCARD
" 到 output。
添加一个 vCard
行,类型为 "VERSION
",值为 "4.0
" 到 output。
添加一个 vCard
行,类型为 "SOURCE
",值为文档的 URL 的
转义的 vCard
文本字符串 到 output。
如果
title
元素 不为 null,添加一个
vCard 行,类型为 "NAME
",值为
title
元素 的 后代文本内容 的 转义的 vCard 文本字符串 到 output。
让 sex 成为空字符串。
让 gender-identity 成为空字符串。
对于每个作为 项的属性的元素 element:对于每个在 属性名称 中的名称 name,运行以下子步骤:
让 parameters 成为空的名称-值对集合。
从以下列表中运行适当的子步骤集。这些步骤将设置一个变量 value,在下一步中使用。
n
让 value 成为空字符串。
将 subitem 中名为 family-name
的第一个 vCard 子属性的结果附加到 value。
将 subitem 中名为 given-name
的第一个 vCard 子属性的结果附加到 value。
将 subitem 中名为 additional-name
的第一个 vCard 子属性的结果附加到 value。
将 subitem 中名为 honorific-prefix
的第一个 vCard 子属性的结果附加到 value。
将 subitem 中名为 honorific-suffix
的第一个 vCard 子属性的结果附加到 value。
adr
让 value 成为空字符串。
将 subitem 中名为 post-office-box
的 vCard 子属性集合的结果附加到 value。
将 subitem 中名为 extended-address
的 vCard 子属性集合的结果附加到 value。
将 subitem 中名为 street-address
的 vCard 子属性集合的结果附加到 value。
将 subitem 中名为 locality
的第一个 vCard 子属性的结果附加到 value。
将 subitem 中名为 region
的第一个 vCard 子属性的结果附加到 value。
将 subitem 中名为 postal-code
的第一个 vCard 子属性的结果附加到 value。
将 subitem 中名为 country-name
的第一个 vCard 子属性的结果附加到 value。
如果 subitem 中有名为 type
的属性,并且第一个此类属性的 值 不是 项,且其值仅由
ASCII 字母数字 组成,则添加一个名为 "TYPE
"
的参数,其值为该属性的 值 到 parameters。
org
让 value 成为空字符串。
将 subitem 中名为 organization-name
的第一个 vCard 子属性的结果附加到 value。
对于 subitem 中每个名为 organization-unit
的属性,运行以下步骤:
将一个 U+003B 分号字符 (;) 附加到 value。
将该属性的 转义的 vCard 文本字符串 的结果附加到 value。
http://microformats.org/profile/hcard
且 name 是 related
让 value 成为空字符串。
如果 subitem 中有名为 url
的属性,并且其元素是 URL
属性元素,则将该属性的 转义的 vCard 文本字符串 的结果附加到
value,并添加一个名为 "VALUE
" 且值为 "URI
" 的参数到 parameters。
如果 subitem 中有名为 rel
的属性,并且第一个此类属性的 值 不是 项,且其值仅由
ASCII 字母数字 组成,则添加一个名为
"RELATION
"
且值为该属性 值
的参数到 parameters。
让 value 成为 subitem 中名为 value
的第一个 vCard 子属性的结果。
如果在subitem中有一个名为type
的属性,并且第一个此类属性的值不是项,且其值仅包含ASCII
字母数字字符,则添加一个名为"TYPE
"的参数,其值为该属性的值到parameters。
sex
如果这是找到的第一个此类属性,则将 sex 设置为属性的 值。
gender-identity
如果这是找到的第一个此类属性,则将 gender-identity 设置为属性的 值。
让 value 成为属性的 值。
如果 element 是 URL 属性元素 之一,则添加一个名为 "VALUE
"
且值为
"URI
" 的参数到 parameters。
否则,如果 name 是 bday
或 anniversary
且 value 是 有效日期字符串,则添加一个名为 "VALUE
" 且值为
"DATE
" 的参数到 parameters。
否则,如果 name 是 rev
且 value 是 有效全球日期和时间字符串,则添加一个名为
"VALUE
" 且值为 "DATE-TIME
" 的参数到 parameters。
在 value 中的每个 U+005C 反斜杠字符 (\) 前面加上另一个 U+005C 反斜杠字符 (\)。
在 value 中的每个 U+002C 逗号字符 (,) 前面加上一个 U+005C 反斜杠字符 (\)。
除非 name 是 geo
,否则在
value 中的每个 U+003B 分号字符 (;) 前面加上一个 U+005C 反斜杠字符 (\)。
用一个 U+005C 反斜杠字符 (\) 后跟一个 U+006E 拉丁小写字母 n 字符 (n) 替换 value 中的每对 U+000D 回车 U+000A 换行字符 (CRLF)。
用一个 U+005C 反斜杠字符 (\) 后跟一个 U+006E 拉丁小写字母 n 字符 (n) 替换 value 中剩余的每个 U+000D 回车 (CR) 或 U+000A 换行 (LF) 字符。
添加一个 vCard 行,类型为 name,参数为 parameters,值为 value 到 output。
如果 sex 或 gender-identity 的值不是空字符串,添加一个 vCard 行,类型为 "GENDER
",值由 sex、一个
U+003B 分号字符 (;) 和 gender-identity 连接而成到 output。
添加一个 vCard
行,类型为 "END
",值为 "VCARD
" 到 output。
当上述算法要求用户代理 添加一个 vCard 行,由类型 type,可选参数和值 value 组成到字符串 output 时,它必须运行以下步骤:
让 line 成为空字符串。
将 type 转换为 ASCII 大写 附加到 line。
如果有任何参数,则按添加的顺序依次为每个参数运行这些子步骤:
将一个 U+003B 分号字符 (;) 附加到 line。
将参数的名称附加到 line。
将一个 U+003D 等号字符 (=) 附加到 line。
将参数的值附加到 line。
将一个 U+003A 冒号字符 (:) 附加到 line。
将 value 附加到 line。
将 maximum length 设为 75。
当 line 的 码点长度 大于 maximum length 时:
将 line 的前 maximum length 个码点附加到 output。
从 line 中移除前 maximum length 个码点。
将一个 U+000D 回车字符 (CR) 附加到 output。
将一个 U+000A 换行字符 (LF) 附加到 output。
将一个 U+0020 空格字符附加到 output。
将 maximum length 设为 74。
将 line 的剩余部分附加到 output。
将一个 U+000D 回车字符 (CR) 附加到 output。
将一个 U+000A 换行字符 (LF) 附加到 output。
当上述步骤要求用户代理获取名为 subname 的 vCard 子属性集合 的结果时,用户代理必须运行以下步骤:
让 value 成为空字符串。
对于 subitem 中每个名为 subname 的属性,运行以下子步骤:
如果这是 subitem 中名为 subname 的第一个属性(忽略之前步骤跳过的任何属性),则在 value 中附加一个 U+002C 逗号字符 (,)。
将该属性的 转义的 vCard 文本字符串 的结果附加到 value。
返回 value。
当上述步骤要求用户代理获取名为 subname 的 第一个 vCard 子属性 的结果时,用户代理必须运行以下步骤:
如果 subitem 中没有名为 subname 的属性,则返回空字符串。
返回 subitem 中第一个名为 subname 的属性的 转义的 vCard 文本字符串 的结果。
当上述算法要求用户代理 转义 vCard 文本字符串 value 时,用户代理必须使用以下步骤:
在 value 中的每个 U+005C 反斜杠字符 (\) 前面加上另一个 U+005C 反斜杠字符 (\)。
在 value 中的每个 U+002C 逗号字符 (,) 前面加上一个 U+005C 反斜杠字符 (\)。
在 value 中的每个 U+003B 分号字符 (;) 前面加上一个 U+005C 反斜杠字符 (\)。
用一个 U+005C 反斜杠字符 (\) 后跟一个 U+006E 拉丁小写字母 n 字符 (n) 替换 value 中的每对 U+000D 回车 U+000A 换行字符 (CRLF)。
用一个 U+005C 反斜杠字符 (\) 后跟一个 U+006E 拉丁小写字母 n 字符 (n) 替换 value 中剩余的每个 U+000D 回车 (CR) 或 U+000A 换行 (LF) 字符。
返回变更后的 value。
如果输入不符合 http://microformats.org/profile/hcard
项类型 和 定义的属性名称
的规则,此算法可能会生成无效的 vCard 输出。
本节为非规范性内容。
以下是一个名为“Jack Bauer”的虚构角色的长示例 vCard:
< section id = "jack" itemscope itemtype = "http://microformats.org/profile/hcard" >
< h1 itemprop = "fn" >
< span itemprop = "n" itemscope >
< span itemprop = "given-name" > Jack</ span >
< span itemprop = "family-name" > Bauer</ span >
</ span >
</ h1 >
< img itemprop = "photo" alt = "" src = "jack-bauer.jpg" >
< p itemprop = "org" itemscope >
< span itemprop = "organization-name" > Counter-Terrorist Unit</ span >
(< span itemprop = "organization-unit" > Los Angeles Division</ span > )
</ p >
< p >
< span itemprop = "adr" itemscope >
< span itemprop = "street-address" > 10201 W. Pico Blvd.</ span >< br >
< span itemprop = "locality" > Los Angeles</ span > ,
< span itemprop = "region" > CA</ span >
< span itemprop = "postal-code" > 90064</ span >< br >
< span itemprop = "country-name" > United States</ span >< br >
</ span >
< span itemprop = "geo" > 34.052339;-118.410623</ span >
</ p >
< h2 > Assorted Contact Methods</ h2 >
< ul >
< li itemprop = "tel" itemscope >
< span itemprop = "value" > +1 (310) 597 3781</ span > < span itemprop = "type" > work</ span >
< meta itemprop = "type" content = "voice" >
</ li >
< li >< a itemprop = "url" href = "https://en.wikipedia.org/wiki/Jack_Bauer" > I'm on Wikipedia</ a >
so you can leave a message on my user talk page.</ li >
< li >< a itemprop = "url" href = "http://www.jackbauerfacts.com/" > Jack Bauer Facts</ a ></ li >
< li itemprop = "email" >< a href = "mailto:j.bauer@la.ctu.gov.invalid" > j.bauer@la.ctu.gov.invalid</ a ></ li >
< li itemprop = "tel" itemscope >
< span itemprop = "value" > +1 (310) 555 3781</ span > < span >
< meta itemprop = "type" content = "cell" > mobile phone</ span >
</ li >
</ ul >
< ins datetime = "2008-07-20 21:00:00+01:00" >
< meta itemprop = "rev" content = "2008-07-20 21:00:00+01:00" >
< p itemprop = "tel" itemscope >< strong > Update!</ strong >
My new < span itemprop = "type" > home</ span > phone number is
< span itemprop = "value" > 01632 960 123</ span > .</ p >
</ ins >
</ section >
需要奇数行换行,因为换行在微数据中是有意义的:例如,在转换为 vCard 格式时,换行会被保留。
此示例显示了一个网站的联系信息(使用address
元素),其中包含一个具有两个街道组成部分的地址:
< address itemscope itemtype = "http://microformats.org/profile/hcard" >
< strong itemprop = "fn" >< span itemprop = "n" itemscope >< span itemprop = "given-name" > Alfred</ span >
< span itemprop = "family-name" > Person</ span ></ span ></ strong > < br >
< span itemprop = "adr" itemscope >
< span itemprop = "street-address" > 1600 Amphitheatre Parkway</ span > < br >
< span itemprop = "street-address" > Building 43, Second Floor</ span > < br >
< span itemprop = "locality" > Mountain View</ span > ,
< span itemprop = "region" > CA</ span > < span itemprop = "postal-code" > 94043</ span >
</ span >
</ address >
vCard词汇可以仅用于标记人的姓名:
< span itemscope itemtype = "http://microformats.org/profile/hcard"
>< span itemprop = fn >< span itemprop = "n" itemscope >< span itemprop = "given-name"
> George</ span > < span itemprop = "family-name" > Washington</ span ></ span
></ span ></ span >
这会创建一个包含两个名称-值对的单项,一个名称为“fn”,值为“George Washington”;另一个名称为“n”,其值为第二个项,第二个项有两个名称-值对,分别是“given-name”和“family-name”,值分别为“George”和“Washington”。这被定义为映射到以下vCard:
BEGIN:VCARD PROFILE:VCARD VERSION:4.0 SOURCE:document's address FN:George Washington N:Washington;George;;; END:VCARD
具有项目类型http://microformats.org/profile/hcalendar#vevent
的项表示一个事件。
该词汇不支持项目的全局标识符。
以下是该类型的定义属性名。它们基于互联网日历和调度核心对象规范(iCalendar)中定义的词汇,可以在那里找到有关如何解释这些值的更多信息。[RFC5545]
这里只使用了iCalendar词汇中与事件相关的部分;该词汇无法表达完整的iCalendar实例。
attach
提供与事件相关的文档地址。
每个具有类型http://microformats.org/profile/hcalendar#vevent
的项中可以存在任意数量名称为attach
的属性。
categories
提供事件可以分类的类别或标签的名称。
值必须是文本。
每个具有类型http://microformats.org/profile/hcalendar#vevent
的项中可以存在任意数量名称为categories
的属性。
class
提供有关事件信息的访问分类。
值必须是以下值之一的文本:
public
private
confidential
这只是建议性的,不能视为保密措施。
每个具有类型http://microformats.org/profile/hcalendar#vevent
的项中可以存在一个名称为class
的属性。
comment
提供有关事件的评论。
值必须是文本。
每个具有类型http://microformats.org/profile/hcalendar#vevent
的项中可以存在任意数量名称为comment
的属性。
description
提供事件的详细描述。
值必须是文本。
每个具有类型description
的项中可以存在一个名称为description
的属性。
geo
提供事件的地理位置。
值必须是文本,并且必须符合以下语法:
标有星号(*)的可选组件应包括在内,并且每个组件应有六位数字。
该值指定纬度和经度,按顺序(即“LAT LON”排序),以十进制度数表示。经度表示东、西方向的经度,分别用正或负实数表示。纬度表示北、南方向的纬度,分别用正或负实数表示。
每个具有类型http://microformats.org/profile/hcalendar#vevent
的项中可以存在一个名称为geo
的属性。
location
提供事件的地点。
值必须是文本。
resources
提供事件所需的资源。
值必须是文本。
status
提供事件的确认状态。
值必须是以下值之一的文本:
tentative
confirmed
canceled
summary
提供事件的简短摘要。
值必须是文本。
用户代理在使用该值时应将值中的U+000A换行符(LF)字符替换为U+0020空格字符。
dtend
提供事件结束的日期和时间。
如果具有名称dtend
的属性出现在具有类型http://microformats.org/profile/hcalendar#vevent
的项中,并且该项中具有名称dtstart
的属性的值是一个有效日期字符串,那么名称为dtend
的属性的值必须也是一个有效日期字符串。否则,该属性的值必须是一个有效的全球日期和时间字符串。
无论哪种情况,该值都必须晚于同一项中dtstart
属性的值。
dtend
属性给出的时间不包括在内。因此,对于全天事件,dtend
属性的值将是事件结束后的那一天。
每个具有类型http://microformats.org/profile/hcalendar#vevent
的项中可以存在一个名称为dtend
的属性,只要该http://microformats.org/profile/hcalendar#vevent
没有名称为duration
的属性。
dtstart
提供事件开始的日期和时间。
值必须是一个有效日期字符串或一个有效的全球日期和时间字符串。
duration
提供事件的持续时间。
值必须是一个有效的事件持续时间字符串。
表示的持续时间是值中整数表示的所有持续时间的总和。
每个具有类型duration
的项中可以存在一个名称为duration
的属性,只要该http://microformats.org/profile/hcalendar#vevent
没有名称为dtend
的属性。
transp
提供事件在日历中是否被视为占用时间,以用于自由-忙碌时间搜索。
值必须是以下值之一的文本:
opaque
transparent
contact
提供事件的联系信息。
值必须是文本。
url
提供事件的URL。
uid
提供与事件相对应的全球唯一标识符。
值必须是文本。
exdate
提供尽管有重复规则,但事件不发生的日期和时间。
值必须是一个有效日期字符串或一个有效的全球日期和时间字符串。
rdate
提供事件重复发生的日期和时间。
值必须是以下之一的文本:
rrule
提供一个规则,用于查找事件发生的日期和时间。
created
提供事件信息首次在日历系统中创建的日期和时间。
值必须是一个有效的全球日期和时间字符串。
last-modified
提供事件信息在日历系统中最后修改的日期和时间。
值必须是一个有效的全球日期和时间字符串。
每个具有类型last-modified
的项中可以存在一个名称为last-modified
的属性。
sequence
提供事件信息的修订号。
字符串是有效的事件持续时间字符串,如果它符合以下模式:
一个U+0050拉丁大写字母P字符(P)。
以下之一:
一个有效的非负整数后跟一个U+0057拉丁大写字母W字符(W)。整数表示该周数的持续时间。
以下至少一种,按此顺序可能两种都有:
给定文档
中的节点列表nodes,用户代理必须运行以下算法来提取由这些节点表示的任何vEvent数据:
如果nodes中的任何节点都不是具有类型http://microformats.org/profile/hcalendar#vevent
的项,则没有vEvent数据。中止算法,不返回任何内容。
让output为空字符串。
添加一个iCalendar行,类型为"BEGIN
",值为"VCALENDAR
"到output。
添加一个iCalendar行,类型为"PRODID
",值为表示用户代理的用户代理特定字符串到output。
添加一个iCalendar行,类型为"VERSION
",值为"2.0
"到output。
对于nodes中每个具有类型http://microformats.org/profile/hcalendar#vevent
的项节点node,运行以下步骤:
添加一个iCalendar行,类型为"BEGIN
",值为"VEVENT
"到output。
添加一个iCalendar行,类型为"DTSTAMP
",值为表示当前日期和时间的iCalendar
DATE-TIME字符串,并带有注释"VALUE=DATE-TIME
",到output。[RFC5545]
对于node的属性元素element的每个名称name,运行以下适当的子步骤:
跳过该属性。
dtend
dtstart
exdate
rdate
created
last-modified
让value是从属性的值中去除所有U+002D连字符(-)和U+003A冒号(:)字符的结果。
如果属性的值是一个有效日期字符串,则添加一个iCalendar行,类型为name,值为value到output,并带有注释"VALUE=DATE
"。
否则,如果属性的值是一个有效的全球日期和时间字符串,则添加一个iCalendar行,类型为name,值为value到output,并带有注释"VALUE=DATE-TIME
"。
否则,跳过该属性。
添加一个iCalendar行,类型为name,值为属性的值到output。
添加一个iCalendar行,类型为"END
",值为"VEVENT
"到output。
添加一个iCalendar行,类型为"END
",值为"VCALENDAR
"到output。
当上述算法要求用户代理添加一个iCalendar行,其由类型type,值value和可选的 注释组成,到字符串output时,它必须运行以下步骤:
让line为空字符串。
将type转换为ASCII大写,并附加到line。
如果有注释:
在line后附加一个U+003B分号字符(;)。
将注释附加到line。
在line后附加一个U+003A冒号字符(:)。
在value中的每个U+005C反斜杠字符(\)前添加另一个U+005C反斜杠字符(\)。
在value中的每个U+002C逗号字符(,)前添加一个U+005C反斜杠字符(\)。
在value中的每个U+003B分号字符(;)前添加一个U+005C反斜杠字符(\)。
将value中的每个U+000D回车字符(U+000A换行字符)对(CRLF)替换为一个U+005C反斜杠字符(\)后跟一个U+006E拉丁小写字母n字符(n)。
将value中的每个剩余的U+000D回车字符(CR)或U+000A换行字符(LF)替换为一个U+005C反斜杠字符(\)后跟一个U+006E拉丁小写字母n字符(n)。
将value附加到line。
让maximum length为75。
当line的代码点长度大于maximum length时:
将line的前maximum length个代码点附加到output。
从line中移除前maximum length个代码点。
在output后附加一个U+000D回车字符(CR)。
在output后附加一个U+000A换行字符(LF)。
在output后附加一个U+0020空格字符。
让maximum length为74。
将(剩余的)line附加到output。
在output后附加一个U+000D回车字符(CR)。
在output后附加一个U+000A换行字符(LF)。
如果输入不符合http://microformats.org/profile/hcalendar#vevent
的类型和定义的属性名称的规则,此算法可能会生成无效的iCalendar输出。
本节是非规范性的。
下面是一个使用 vEvent 词汇标记事件的页面示例:
< body itemscope itemtype = "http://microformats.org/profile/hcalendar#vevent" >
...
< h1 itemprop = "summary" > Bluesday Tuesday: Money Road</ h1 >
...
< time itemprop = "dtstart" datetime = "2009-05-05T19:00:00Z" > May 5th @ 7pm</ time >
(until < time itemprop = "dtend" datetime = "2009-05-05T21:00:00Z" > 9pm</ time > )
...
< a href = "http://livebrum.co.uk/2009/05/05/bluesday-tuesday-money-road"
rel = "bookmark" itemprop = "url" > Link to this page</ a >
...
< p > Location: < span itemprop = "location" > The RoadHouse</ span ></ p >
...
< p >< input type = button value = "Add to Calendar"
onclick = "location = getCalendar(this)" ></ p >
...
< meta itemprop = "description" content = "via livebrum.co.uk" >
</ body >
getCalendar()
函数留给读者作为练习。
同一页面还可以提供一些标记,例如以下内容,以便复制粘贴到博客中:
< div itemscope itemtype = "http://microformats.org/profile/hcalendar#vevent" >
< p > I'm going to
< strong itemprop = "summary" > Bluesday Tuesday: Money Road</ strong > ,
< time itemprop = "dtstart" datetime = "2009-05-05T19:00:00Z" > May 5th at 7pm</ time >
to < time itemprop = "dtend" datetime = "2009-05-05T21:00:00Z" > 9pm</ time > ,
at < span itemprop = "location" > The RoadHouse</ span > !</ p >
< p >< a href = "http://livebrum.co.uk/2009/05/05/bluesday-tuesday-money-road"
itemprop = "url" > See this event on livebrum.co.uk</ a > .</ p >
< meta itemprop = "description" content = "via livebrum.co.uk" >
</ div >
具有 项目类型 http://n.whatwg.org/work
的项代表一部作品(例如文章、图像、视频、歌曲等)。此类型主要用于允许作者包含作品的许可信息。
以下是该类型的定义属性名称。
work
标识所描述的作品。
每个具有类型 http://n.whatwg.org/work
的
项中必须存在一个名称为 work
的属性。
title
给出作品的名称。
每个具有类型 http://n.whatwg.org/work
的
项中可以存在一个名称为 title
的属性。
author
给出作品的作者或创作者之一的姓名或联系信息。
值必须是类型为 http://microformats.org/profile/hcard
的 项 或文本。
每个具有类型 http://n.whatwg.org/work
的
项中可以存在任意数量名称为 author
的属性。
license
标识作品可用的许可证之一。
每个具有类型 http://n.whatwg.org/work
的
项中可以存在任意数量名称为 license
的属性。
本节是非规范性的。
这个示例展示了一张嵌入的图片,标题为 我的池塘,同时根据 Creative Commons Attribution-Share Alike 4.0 国际许可协议和 MIT 许可协议授权。
< figure itemscope itemtype = "http://n.whatwg.org/work" >
< img itemprop = "work" src = "mypond.jpeg" >
< figcaption >
< p >< cite itemprop = "title" > My Pond</ cite ></ p >
< p >< small > Licensed under the < a itemprop = "license"
href = "https://creativecommons.org/licenses/by-sa/4.0/" > Creative
Commons Attribution-Share Alike 4.0 International License</ a >
and the < a itemprop = "license"
href = "http://www.opensource.org/licenses/mit-license.php" > MIT
license</ a > .</ small >
</ figcaption >
</ figure >
给定 Document
中的节点列表
nodes,用户代理必须运行以下算法,将这些节点中的微数据提取为 JSON 形式:
令 result 为一个空对象。
令 items 为一个空数组。
对于 nodes 中的每个 node,检查该元素是否是 顶级微数据项,如果是,则获取该元素的对象并将其添加到 items 中。
向 result 添加一个名为 "items
" 的条目,其值为数组 items。
返回 result 序列化为 JSON 的结果,以最短的方式表示(即在标记之间没有空白,没有数字中的不必要的零,并且仅对没有专用转义序列的字符使用 Unicode
转义),并在合适的时候在数字表示中使用小写 "e
"。[JSON]
该算法返回一个带有单一属性的对象,该属性是一个数组,而不是直接返回数组,以便在必要时将来可以扩展该算法。
当用户代理需要获取项的对象 item 时,可以选择传递一个元素列表 memory,它必须运行以下子步骤:
令 result 为一个空对象。
如果没有传递 memory,则令 memory 为一个空列表。
将 item 添加到 memory 中。
如果 item 具有任何项类型,则向
result 添加一个名为 "type
" 的条目,其值为一个数组,按
itemtype
属性中指定的顺序列出
item 的 项类型。
令 properties 为一个空对象。
对于具有一个或多个属性名称的每个元素 element,并且是 item 的属性中的一个,按算法返回的顺序,运行以下子步骤:
向 result 添加一个名为 "properties
" 的条目,其值为对象 properties。
返回 result。
例如,采用以下标记:
<!DOCTYPE HTML>
< html lang = "en" >
< title > My Blog</ title >
< article itemscope itemtype = "http://schema.org/BlogPosting" >
< header >
< h1 itemprop = "headline" > Progress report</ h1 >
< p >< time itemprop = "datePublished" datetime = "2013-08-29" > today</ time ></ p >
< link itemprop = "url" href = "?comments=0" >
</ header >
< p > All in all, he's doing well with his swim lessons. The biggest thing was he had trouble
putting his head in, but we got it down.</ p >
< section >
< h1 > Comments</ h1 >
< article itemprop = "comment" itemscope itemtype = "http://schema.org/UserComments" id = "c1" >
< link itemprop = "url" href = "#c1" >
< footer >
< p > Posted by: < span itemprop = "creator" itemscope itemtype = "http://schema.org/Person" >
< span itemprop = "name" > Greg</ span >
</ span ></ p >
< p >< time itemprop = "commentTime" datetime = "2013-08-29" > 15 minutes ago</ time ></ p >
</ footer >
< p > Ha!</ p >
</ article >
< article itemprop = "comment" itemscope itemtype = "http://schema.org/UserComments" id = "c2" >
< link itemprop = "url" href = "#c2" >
< footer >
< p > Posted by: < span itemprop = "creator" itemscope itemtype = "http://schema.org/Person" >
< span itemprop = "name" > Charlotte</ span >
</ span ></ p >
< p >< time itemprop = "commentTime" datetime = "2013-08-29" > 5 minutes ago</ time ></ p >
</ footer >
< p > When you say "we got it down"...</ p >
</ article >
</ section >
</ article >
通过上述算法(假设页面的 URL 是 https://blog.example.com/progress-report
)将其转换为以下 JSON:
{
"items" : [
{
"type" : [ "http://schema.org/BlogPosting" ],
"properties" : {
"headline" : [ "Progress report" ],
"datePublished" : [ "2013-08-29" ],
"url" : [ "https://blog.example.com/progress-report?comments=0" ],
"comment" : [
{
"type" : [ "http://schema.org/UserComments" ],
"properties" : {
"url" : [ "https://blog.example.com/progress-report#c1" ],
"creator" : [
{
"type" : [ "http://schema.org/Person" ],
"properties" : {
"name" : [ "Greg" ]
}
}
],
"commentTime" : [ "2013-08-29" ]
}
},
{
"type" : [ "http://schema.org/UserComments" ],
"properties" : {
"url" : [ "https://blog.example.com/progress-report#c2" ],
"creator" : [
{
"type" : [ "http://schema.org/Person" ],
"properties" : {
"name" : [ "Charlotte" ]
}
}
],
"commentTime" : [ "2013-08-29" ]
}
}
]
}
}
]
}
仅在一个引擎中支持。
支持所有当前引擎。
所有 hidden
内容属性。
属性是一个 ,具有以下关键词和状态:
关键词 | 状态 | 简要描述 |
---|---|---|
hidden
|
hidden | 不会被渲染。 |
(空字符串) | ||
until-found
|
hidden until found | 不会被渲染,但内容可以通过 | 和 访问。
该属性的 缺失值默认值 为 not hidden 状态,其 无效值默认值 为 状态。
当一个元素具有 在渲染部分建议的规则 实现这些要求。
属性并处于 状态时,表示该元素尚未或不再与页面的当前状态直接相关,或者它用于声明将由页面其他部分重用的内容,而不是由用户直接访问。 用户代理不应渲染处于 状态的元素。此要求可以通过样式层间接实现。例如,Web 浏览器可以通过当一个元素具有
属性并处于 状态时,表示该元素像 状态一样被隐藏,但元素内部的内容可以通过 和 访问。当这些功能尝试滚动到目标在元素子树内时,用户代理将删除 属性以显示内容,然后再滚动到它。除了删除 属性外,还会在删除 属性之前触发一个名为 的事件。Web 浏览器在 渲染部分 中所述。
属性处于 状态时,将使用 'content-visibility: hidden' 而不是 'display: none',如由于此属性通常使用 CSS 实现,因此也可以使用 CSS 覆盖它。例如,对所有元素应用 'display: block' 的规则将取消
状态的效果。因此,作者在编写样式表时必须小心,以确保属性仍按预期样式呈现。此外,不支持 状态的旧版用户代理将使用 'display: none' 而不是 'content-visibility: hidden',因此建议作者确保其样式表不会更改 元素的 'display' 或 'content-visibility' 属性。由于具有
属性并处于 状态的元素使用 'content-visibility: hidden' 而不是 'display: none',因此 状态与 状态有两个不同之处:元素需要受
的影响,才能通过页面查找显示出来。这意味着如果处于 状态的元素的 'display' 值为 'none'、'contents' 或 'inline',则该元素不会被页面查找显示。元素在
时 仍会具有一个框,这意味着边框、外边距和内边距仍会在元素周围呈现。在以下示例中,属性用于在用户登录之前隐藏网页游戏的主屏幕:
< h1 > The Example Game</ h1 >
< section id = "login" >
< h2 > Login</ h2 >
< form >
...
<!-- calls login() once the user's credentials have been checked -->
</ form >
< script >
function login() {
// switch screens
document. getElementById( 'login' ). hidden = true ;
document. getElementById( 'game' ). hidden = false ;
}
</ script >
</ section >
< section id = "game" hidden >
...
</ section >
属性不得用于隐藏可以在其他显示中合法显示的内容。例如,使用 隐藏选项卡对话框中的面板是错误的,因为选项卡界面只是一个溢出显示——同样可以只显示一个带有滚动条的大页面上的所有表单控件。类似地,使用此属性隐藏内容只是因为一种显示是不正确的——如果某些内容被标记为 ,它会在所有显示中隐藏,包括例如屏幕阅读器。
自身没有 for
属性的
和
元素如果没有
属性,也不得引用 的元素。
在这两种情况下,这种引用会导致用户困惑。
然而,元素和脚本可以在其他上下文中引用
的元素。例如,使用
属性链接到带有 属性的部分是不正确的。 如果内容不适用或不相关,则没有理由链接到它。然而,使用 ARIA
属性引用隐藏的描述是可以的。 虽然隐藏描述意味着它们本身没有用处,但它们可以以某种方式编写,使它们在从它们描述的元素引用的特定上下文中有用。类似地,具有
元素带有 属性的情况可以用作脚本图形引擎的屏外缓冲区,表单控件可以使用其 属性引用一个隐藏的 元素。被
属性隐藏的部分中的元素仍然是活动的,例如,这些部分中的脚本和表单控件仍然分别执行和提交。 只有它们的展示给用户的方式发生了变化。支持所有当前引擎。
hidden
获取步骤如下:
如果
属性处于 状态,则返回 " "。如果设置了
属性,则返回 true。返回 false。
设置步骤如下:
如果给定值是与 "
" ASCII 不区分大小写匹配的字符串, 则将 属性设置为 " "。否则,如果给定值为 false,则移除
属性。否则,如果给定值为空字符串,则移除
属性。否则,如果给定值为 null,则移除
属性。否则,如果给定值为 0,则移除
属性。否则,如果给定值为 NaN,则移除
属性。否则,将
属性设置为空字符串。祖先 hidden-until-found 显示算法 的步骤如下:
当 currentNode 在
中具有父节点时:如果 currentNode 具有
属性并处于 状态,则:,名为 , 在currentNode上。
从currentNode中移除
属性。将 currentNode 设置为 currentNode 在
中的父节点。可遍历导航项的 系统可见性状态,包括其创建时的初始值,由用户代理决定。它表示,例如,浏览器窗口是否最小化,浏览器标签当前是否在后台,或者系统元素(如任务切换器)是否遮挡了页面。
当用户代理确定 系统可见性状态 对于 可遍历导航项 traversable 已更改为 newState 时,它必须执行以下步骤:
对每个 navigable 进行迭代 navigables 按什么顺序?:
令 document 为 navigable 的 活动文档。
在 用户交互任务源 上针对 document 的 相关全局对象 更新文档的可见性状态,将 newState 应用于 document。
Document
有一个 可见性状态,可以是 "hidden
" 或
"visible
",初始值为
"hidden
"。
支持所有当前引擎。
visibilityState
获取步骤如下,返回 this 的 可见性状态。
支持所有当前引擎。
hidden
获取步骤如下,如果
this 的 可见性状态 为
"hidden
",则返回 true,否则返回 false。
要 更新 Document
的可见性状态
document 为
visibilityState,请执行以下步骤:
如果 document 的 可见性状态 等于 visibilityState,则返回。
将 document 的 可见性状态 设置为 visibilityState。
队列 一个新的 VisibilityStateEntry
,其
可见性状态 为
visibilityState,其 时间戳 为 当前高分辨率时间,适用于 document 的 相关全局对象。
运行 屏幕方向更改步骤,适用于 document。 [SCREENORIENTATION]
运行 视图转换页面可见性更改步骤,适用于 document。
运行其他规范中可能定义的任何 页面可见性更改步骤,包括 可见性状态 和 document。
规范作者最好提交 pull request,将调用直接添加到他们的规范中,而不是使用 页面可见性更改步骤 钩子,以确保跨规范调用顺序的良好定义。截至撰写本文时,以下规范已知具有 页面可见性更改步骤,它们将以未指定的顺序运行:Device Posture API 和 Web NFC。[DEVICEPOSTURE] [WEBNFC]
在 document 上触发一个名为 visibilitychange
的事件,其 bubbles
属性初始化为 true。
VisibilityStateEntry
接口仅在一个引擎中支持。
VisibilityStateEntry
接口从文档变为活跃状态起公开可见性更改。
function wasHiddenBeforeFirstContentfulPaint() {
const fcpEntry = performance. getEntriesByName( "first-contentful-paint" )[ 0 ];
const visibilityStateEntries = performance. getEntriesByType( "visibility-state" );
return visibilityStateEntries. some( e =>
e. startTime < fcpEntry. startTime &&
e. name === "hidden" );
}
由于隐藏页面可能导致渲染和其他用户代理操作的限制,因此通常使用可见性更改作为此类限制发生的指示。然而,其他情况也可能导致不同浏览器中的限制,例如长时间的不活动。
[Exposed =(Window )]
interface VisibilityStateEntry : PerformanceEntry {
readonly attribute DOMString name ; // shadows inherited name
readonly attribute DOMString entryType ; // shadows inherited entryType
readonly attribute DOMHighResTimeStamp startTime ; // shadows inherited startTime
readonly attribute unsigned long duration ; // shadows inherited duration
};
VisibilityStateEntry
关联一个 DOMHighResTimeStamp
时间戳。
VisibilityStateEntry
关联一个 "visible
" 或 "hidden
" 可见性状态。
entryType
获取步骤如下,返回 "visibility-state
"。
startTime
获取步骤如下,返回 this 的 时间戳。
duration
获取步骤如下,返回 0。
另见 inert
以了解同名属性的解释。
节点(特别是元素和文本节点)可以是惰性的。当一个节点是惰性时:
点击测试必须表现得如同'pointer-events' CSS 属性被设置为 'none'。
文本选择功能必须表现得如同'user-select' CSS 属性被设置为 'none'。
如果它是可编辑的,节点表现得如同它是不可编辑的。
用户代理在页面查找时应忽略该节点。
惰性节点通常不能被聚焦,用户代理不会将惰性节点暴露给无障碍 API 或辅助技术。作为命令的惰性节点将如上所述变得无法操作。
然而,用户代理可以允许用户覆盖对页面查找和文本选择的限制。
默认情况下,节点不是惰性的。
文档
document 如果 subject 是 document 的 顶层 中最顶层的
对话框
元素,则 subject 被模态对话框阻塞。
当 document 被如此阻塞时,除了 subject 元素及其 平树 后代外,每个与
document 连接 的节点都必须变得 惰性。
subject 还可以通过 inert
属性变为惰性,但只有在
subject 本身上指定时(即 subject 可以逃避祖先的惰性);subject 的 扁平树 后代可以以类似方式变为惰性。
对话框
元素的 showModal()
方法通过 将 对话框
元素添加到其 节点文档 的 顶层,触发此机制。
inert
属性支持所有当前引擎。
inert
属性是一个 布尔属性,通过其存在表示元素及其所有未能逃避惰性状态的 平树 后代(例如模态对话框)将被用户代理设为 惰性。
惰性子树不应包含对理解或使用页面中不处于惰性状态的部分至关重要的内容或控件。惰性子树中的内容对所有用户来说都是不可感知的,也不可交互。除非内容在视觉上以某种方式被遮挡,否则作者不应将元素指定为惰性。在大多数情况下,作者不应在单个表单控件上指定
inert
属性。在这些情况下,disabled
属性可能更合适。
以下示例显示如何将被“加载中”消息遮挡的部分加载内容标记为惰性。
< section aria-labelledby = s1 >
< h3 id = s1 > Population by City</ h3 >
< div class = container >
< div class = loading >< p > Loading...</ p ></ div >
< div inert >
< form >
< fieldset >
< legend > Date range</ legend >
< div >
< label for = start > Start</ label >
< input type = date id = start >
</ div >
< div >
< label for = end > End</ label >
< input type = date id = end >
</ div >
< div >
< button > Apply</ button >
</ div >
</ fieldset >
</ form >
< table >
< caption > From 20-- to 20--</ caption >
< thead >
< tr >
< th > City</ th >
< th > State</ th >
< th > 20-- Population</ th >
< th > 20-- Population</ th >
< th > Percentage change</ th >
</ tr >
</ thead >
< tbody >
<!-- ... -->
</ tbody >
</ table >
</ div >
</ div >
</ section >
“加载中”覆盖层遮挡了惰性内容,使其在视觉上明显不可访问。注意,标题和“加载中”文本不是具有 inert
属性的元素的后代。这将确保所有用户都能访问此文本,而惰性内容无法被任何人交互。
默认情况下,没有持久的视觉指示元素或其子树是惰性的。此类内容的适当视觉样式通常取决于上下文。例如,惰性的屏外导航面板不需要默认样式,因为其屏外位置在视觉上遮挡了内容。同样,模态 对话框
元素的背景将用作视觉上遮挡网页惰性内容的手段,而不是专门样式化惰性内容。
然而,对于许多其他情况,强烈建议作者清楚地标明文档的哪些部分是活动的,哪些是惰性的,以避免用户混淆。特别值得记住的是,并非所有用户都能同时看到页面的所有部分;例如,屏幕阅读器用户、小设备或放大镜用户,甚至使用特别小窗口的用户可能无法看到页面的活动部分,如果惰性部分没有明显标明是惰性的,可能会感到沮丧。
支持所有当前引擎。
inert
IDL 属性必须 反映
同名内容属性。
为了防止某些可能令用户讨厌的 API 滥用(例如,打开弹出窗口或振动手机),用户代理仅在用户主动与网页交互或至少与页面交互过一次时才允许使用这些 API。这种“主动交互”状态通过本节定义的机制来维护。
为了跟踪用户激活,每个 窗口
W 有两个相关的值:
一个上次激活时间戳,可以是一个 DOMHighResTimeStamp
,
正无穷大(表示 W 从未被激活),或负无穷大(表示激活已被消耗)。初始值为正无穷大。
一个上次历史操作激活时间戳,可以是一个 DOMHighResTimeStamp
或正无穷大,初始值为正无穷大。
用户代理还定义了一个短暂激活持续时间,这是一个常量,用于指示用户激活在某些用户激活控制的 API(例如打开弹出窗口)中可用的时间。
短暂激活持续时间预期最多为几秒钟,以便用户可以感知与页面交互和页面调用激活控制的 API 之间的联系。
然后我们有以下 W 的布尔用户激活状态:
当给定 W 的 当前高分辨率时间 大于等于 W 中的 上次激活时间戳时,称 W 具有粘性激活。
这是 W 的历史激活状态,表示用户是否曾在 W 中进行过交互。它开始为 false,然后在 W 获得第一个激活通知时变为 true(并且永远不会变回 false)。
当给定 W 的 当前高分辨率时间 大于等于 W 中的 上次激活时间戳 且小于 W 中的 上次激活时间戳 加上 短暂激活持续时间时,称 W 具有短暂激活。
这是 W 的当前激活状态,表示用户最近是否在 W 中进行了交互。它开始为 false,并在 W 获得每个 激活通知 后保持 true 一段有限的时间。
如果短暂激活状态因为自上次用户激活以来短暂激活持续时间已过而变为 false,则该短暂激活状态被视为已过期。请注意,通过 激活消耗,它甚至可以在到期时间之前变为 false。
当 W 的 上次历史操作激活时间戳 不等于 W 的 上次激活时间戳 时,称 W 具有 历史操作激活。
这是用户激活的一种特殊变体,用于允许访问某些会话历史 API,如果使用过于频繁,会使用户更难使用 浏览器 UI 进行回溯。它开始为 false,并在用户与 W 交互时变为 true,但通过 历史操作激活消耗 重置为 false。这确保了这些 API 不能在没有中间用户激活的情况下连续多次使用。但与短暂激活不同,这些 API 没有必须使用的时间限制。
上次激活时间戳和上次历史操作激活时间戳 即使在 文档
更改其完全活跃状态后(例如,在导航离开
文档
后,或导航到缓存的
文档
后)仍然保留。这意味着粘性激活状态跨越多个导航,只要相同的
文档
被重用。对于短暂激活状态,原始到期时间保持不变(即,该状态仍在从原始激活触发输入事件起的短暂激活持续时间限制内到期)。在决定是否基于粘性激活或短暂激活时,考虑这一点非常重要。
当用户交互在文档
document中触发激活触发输入事件时,用户代理必须在调度事件之前执行以下激活通知步骤:
让windows为«document的相关全局对象»。
扩展windows,包括document的每个后代可导航的活跃窗口,过滤掉仅包含其可导航的那些document的源与document的源相同的。
对每个window在windows中:
在给定window的情况下,通知关闭观察者管理器关于用户激活。
激活触发输入事件是任何其isTrusted
属性为
true 且其type
为以下之一的事件:
"keydown
",前提是按键不是Esc键或用户代理保留的快捷键;
"mousedown
";
"pointerdown
",前提是事件的pointerType
为"mouse
";
"pointerup
",前提是事件的pointerType
不是"mouse
";
"touchend
"。
激活消耗
API在本规范和其他规范中定义,可以通过执行以下步骤来消耗用户激活,给定一个窗口
W:
历史操作激活消耗 API可以通过执行以下步骤来消耗历史操作用户激活,给定一个窗口
W:
如果W的可导航为 null,则返回。
对每个window在windows中,将window的上次历史操作激活时间戳设置为window的上次激活时间戳。
请注意页面中受激活通知与激活消耗影响的浏览上下文集合的不对称性:激活消耗会更改(为 false)页面中所有浏览上下文的短暂激活状态,而激活通知仅更改这些浏览上下文的子集的状态。这里消耗的全面性是故意的:它防止恶意网站从单一用户激活中多次调用激活消耗
API(可能通过利用深层的iframe
层次结构)。
依赖用户激活的API被分为不同的级别:
这些API要求粘性激活状态为true,因此在第一次用户激活之前,它们是被阻止的。
这些API要求历史操作激活状态为true,并且每次调用时它们会消耗历史操作用户激活,以防止每次用户激活多次调用。
UserActivation
接口每个Window
都有一个关联的UserActivation
,这是一个UserActivation
对象。在创建Window
对象时,必须将其关联的UserActivation
设置为在Window
对象的相关领域中创建的新UserActivation
对象。
[Exposed =Window ]
interface UserActivation {
readonly attribute boolean hasBeenActive ;
readonly attribute boolean isActive ;
};
partial interface Navigator {
[SameObject ] readonly attribute UserActivation
userActivation ;
};
navigator.userActivation.hasBeenActive
返回窗口是否具有粘性激活。
navigator.userActivation.isActive
返回窗口是否具有短暂激活。
userActivation
获取步骤是返回 this的 相关全局对象的 关联 UserActivation
。
hasBeenActive
获取步骤是如果 this的 相关全局对象具有 粘性激活,则返回
true,否则返回 false。
isActive
获取步骤是如果 this的 相关全局对象具有 短暂激活,则返回 true,否则返回 false。
为了用户代理自动化和应用测试的目的,本规范为Web Driver规范定义了以下扩展命令。用户代理支持以下扩展命令是可选的。 [WEBDRIVER]
HTTP Method | URI Template |
---|---|
POST |
/session/{session id}/window/consume-user-activation |
远程端步骤是:
HTML中的某些元素具有激活行为,这意味着用户可以激活它们。这通常由click
事件触发。
用户代理应允许用户手动触发具有激活行为的元素,例如使用键盘或语音输入,或通过鼠标点击。当用户以点击以外的方式触发具有定义的激活行为的元素时,交互事件的默认操作必须是在该元素上触发click
事件。
element.click()
支持所有当前引擎。
表现为元素被点击。
每个元素都有一个关联的点击进行中标志,初始状态为未设置。
click()
方法必须执行以下步骤:
如果该元素是一个禁用的表单控件,则返回。
如果该元素的点击进行中标志已设置,则返回。
设置该元素的点击进行中标志。
触发一个合成指针事件,名为click
,
在该元素上,并设置not trusted flag。
取消该元素的点击进行中标志。
ToggleEvent
接口支持所有当前引擎。
支持所有当前引擎。
[Exposed =Window ]
interface ToggleEvent : Event {
constructor (DOMString type , optional ToggleEventInit eventInitDict = {});
readonly attribute DOMString oldState ;
readonly attribute DOMString newState ;
};
dictionary ToggleEventInit : EventInit {
DOMString oldState = "";
DOMString newState = "";
};
event.oldState
当从关闭状态过渡到打开状态时,设置为"closed
",或者当从打开状态过渡到关闭状态时,设置为"open
"。
event.newState
当从关闭状态过渡到打开状态时,设置为"open
",或者当从打开状态过渡到关闭状态时,设置为"closed
"。
支持所有当前引擎。
支持所有当前引擎。
oldState
和newState
属性必须返回它们初始化的值。
一个切换任务跟踪器是一个结构体,包含以下内容:
ToggleEvent
。
oldState
属性的值。
本节为非规范性内容。
HTML用户界面通常由多个交互小部件组成,例如表单控件、可滚动区域、链接、对话框、浏览器标签页等。这些小部件形成一个层次结构,其中一些(例如浏览器标签页、对话框)包含其他小部件(例如链接、表单控件)。
当使用键盘与界面交互时,键输入从系统通过交互小部件的层次结构传递到一个活跃的小部件,该小部件被称为聚焦。
考虑在图形环境中运行的浏览器标签页中运行的HTML应用程序。假设该应用程序有一个包含一些文本控件和链接的页面,并且当前正在显示一个包含文本控件和按钮的模式对话框。
在这种情况下,可聚焦小部件的层次结构将包括浏览器窗口,其子节点将包括包含HTML应用程序的浏览器标签页。标签页本身将有各种链接和文本控件作为其子节点,以及对话框。对话框本身将包含文本控件和按钮作为其子节点。
在此示例中,如果聚焦的小部件是对话框中的文本控件,那么键输入将从图形系统传递到①网络浏览器,然后到②标签页,再到③对话框,最后到④文本控件。
键盘事件总是针对这个聚焦元素。
当顶级遍历项可以接收来自操作系统的键盘输入时,它具有系统焦点,这些输入可能针对其活动文档的后代导航项。
当顶级遍历项的系统可见性状态为"可见",并且它具有系统焦点或与其直接相关的用户代理小部件可以接收来自操作系统的键盘输入时,它具有用户注意力。
当浏览器窗口失去焦点时,用户注意力会丧失,而系统焦点可能会被浏览器窗口中的其他系统小部件(如地址栏)占用。
当一个文档完全活动且其节点导航项的顶级遍历项具有用户注意力时,该文档是一个具有用户注意力的顶级遍历项的完全活动后代。
术语“可聚焦区域”用于指可以成为此类键盘输入目标的界面区域。可聚焦区域可以是元素、元素的部分或由用户代理管理的其他区域。
每个可聚焦区域都有一个DOM锚点,它是一个表示可聚焦区域在DOM中的位置的节点对象。(当可聚焦区域本身是一个节点时,它就是其自己的DOM锚点。)在某些API中,DOM锚点用作可聚焦区域的替代,当没有其他DOM对象可以表示可聚焦区域时使用。
下表描述了哪些对象可以是可聚焦区域。左列中的单元格描述了可以是可聚焦区域的对象;右列中的单元格描述了这些元素的DOM锚点。(跨越两列的单元格是非规范性示例。)
可聚焦区域 | DOM 锚点 |
---|---|
示例 | |
满足以下所有条件的元素:
|
元素本身。 |
|
|
与图像地图关联的area元素的形状,该图像地图与正在渲染且不处于惰性状态的img元素关联。 | img元素。 |
在以下示例中,area元素在每个图像上创建两个形状。第一个形状的DOM锚点是第一个img元素,第二个形状的DOM锚点是第二个img元素。
|
|
正在渲染且不处于惰性状态或禁用状态的元素的用户代理提供的子小部件。 | 为其创建可滚动区域的元素。 |
用于video元素的用户界面控件、number类型输入框中的上下按钮、details元素渲染的一部分使其可以使用键盘输入打开或关闭。 |
|
正在渲染且不处于惰性状态的元素的可滚动区域。 | 为其创建可滚动区域的元素。 |
CSS中的'overflow'属性的'scroll'值通常会创建一个可滚动区域。 |
|
具有非空浏览上下文且不处于惰性状态的文档的视口。 | 创建视口的文档。 |
iframe的内容。 |
|
由用户代理确定为可聚焦区域的任何其他元素或元素的一部分,特别是为了辅助可访问性或更好地匹配平台惯例。 | 元素本身。 |
用户代理可以使所有列表项的项目符号成为顺序可聚焦的,以便用户可以更轻松地导航列表。 同样,用户代理可以使所有带有title属性的元素顺序可聚焦,以便可以访问它们的建议信息。 |
导航容器(例如iframe)是一个可聚焦区域,但路由到导航容器的键事件会立即路由到其内容导航项的活动文档。同样,在顺序焦点导航中,导航容器本质上只是其内容导航项的活动文档的占位符。
每个文档中的一个可聚焦区域被指定为文档的聚焦区域。哪个控件被指定为聚焦区域会随时间变化,基于本规范中的算法。
即使文档不是完全活动的且不显示给用户,它仍然可以有一个聚焦区域。如果文档的完全活动状态发生变化,其聚焦区域将保持不变。
顶级遍历项的当前聚焦区域是通过以下算法返回的可聚焦区域或空值:
如果顶级遍历项没有系统焦点,则返回null。
将候选项设置为顶级遍历项的活动文档。
当候选项的聚焦区域是具有非空内容导航项的导航容器时:将候选项设置为该导航容器的内容导航项的活动文档。
如果候选项的聚焦区域非空,则将候选项设置为候选项的聚焦区域。
返回候选项。
顶级遍历项的当前焦点链是顶级遍历项的当前聚焦区域的焦点链(如果顶级遍历项非空),否则为空列表。
当元素是可聚焦区域的DOM锚点时,当该可聚焦区域成为顶级遍历项的当前聚焦区域时,该元素获得焦点。当元素是顶级遍历项的当前聚焦区域的可聚焦区域的DOM锚点时,它被聚焦。
可聚焦区域的焦点链是按以下方式构建的有序列表:
让输出为一个空列表。
将当前对象设置为主题。
当条件为真时:
将当前对象附加到输出。
如果当前对象是area元素的形状,则将该area元素附加到输出。
否则,如果当前对象的DOM锚点是一个元素而不是当前对象本身,则将当前对象的DOM锚点附加到输出。
如果当前对象是可聚焦区域,则将当前对象设置为当前对象的DOM锚点的节点文档。
否则,如果当前对象是其节点导航项的父项非空的文档,则将当前对象设置为当前对象的节点导航项的父项。
否则,跳出循环。
返回输出。
链从主题开始,并(如果主题是或可以是顶级遍历项的当前聚焦区域)沿焦点层次结构向上延续,直到顶级遍历项的文档。
所有作为可聚焦区域的元素都被称为可聚焦。
可聚焦区域有两种特殊类型的可聚焦性:
可聚焦区域被称为顺序可聚焦,如果它包含在其文档的顺序焦点导航顺序中,并且用户代理确定它是顺序可聚焦的。
可聚焦区域被称为点击可聚焦,如果用户代理确定它是点击可聚焦的。用户代理应考虑具有非空tabindex值的可聚焦区域为点击可聚焦。
不可聚焦的元素不是可聚焦区域,因此既不是顺序可聚焦的,也不是点击可聚焦的。
可聚焦是关于元素是否可以通过编程方式聚焦的声明,例如通过focus()方法或autofocus属性。相比之下,顺序可聚焦和点击可聚焦决定了用户代理如何响应用户交互:分别是顺序焦点导航和作为激活行为。
用户代理可能会根据用户偏好确定一个元素不是顺序可聚焦的,即使它是可聚焦的并包含在其文档的顺序焦点导航顺序中。例如,macOS用户可以设置用户代理跳过非表单控件元素,或在使用Tab键进行顺序焦点导航时跳过链接(而不是使用Option和Tab键)。
同样,用户代理可能会确定一个元素不是点击可聚焦的,即使它是可聚焦的。例如,在某些用户代理中,点击非可编辑表单控件不会聚焦它,即用户代理已确定此类控件不是点击可聚焦的。
因此,一个元素可以是可聚焦的,但既不是顺序可聚焦的,也不是点击可聚焦的。例如,在某些用户代理中,具有负整数tabindex值的非可编辑表单控件不能通过用户交互聚焦,只能通过编程API聚焦。
当用户激活一个点击可聚焦的可聚焦区域时,用户代理必须在可聚焦区域上运行聚焦步骤,聚焦触发设置为"点击"。
注意,聚焦不是一种激活行为,即在元素上调用click()方法或调度一个合成的click事件不会使元素获得焦点。
如果节点是文档、影子宿主、插槽或处于弹出显示状态且设置了弹出调用器的元素,则该节点是焦点导航范围所有者。
每个焦点导航范围所有者都有一个焦点导航范围,这是一个元素列表。其内容如下所示:
每个元素都有一个关联的焦点导航所有者,该所有者可以是null或焦点导航范围所有者。其内容通过以下算法确定:
如果元素的父元素为null,则返回null。
如果元素的父元素是一个影子宿主,则返回元素的分配插槽。
如果元素的父元素是影子根,则返回父元素的宿主。
如果元素的父元素是文档元素,则返回父元素的节点文档。
如果元素处于弹出显示状态且设置了弹出调用器,则返回元素。
返回元素的父元素的关联焦点导航所有者。
然后,给定的焦点导航范围所有者的焦点导航范围包含所有关联焦点导航所有者是该范围所有者的元素。
焦点导航范围内元素的顺序不会影响本规范中的任何算法。只有在下文定义的tabindex有序焦点导航范围和扁平化tabindex有序焦点导航范围概念中才会变得重要。
tabindex有序焦点导航范围是一个包含可聚焦区域和焦点导航范围所有者的列表。每个焦点导航范围所有者都有一个tabindex有序焦点导航范围,其内容如下:
它包含范围所有者焦点导航范围内的所有元素,这些元素本身是焦点导航范围所有者,除非这些元素的tabindex值为负整数。
它包含所有DOM锚点是范围所有者焦点导航范围内元素的可聚焦区域,除非这些可聚焦区域的tabindex值为负整数。
tabindex有序焦点导航范围内的顺序由每个元素的tabindex值确定,如下文所述。
这些规则并未给出精确的顺序,因为它们主要由“应该”声明和相对顺序组成。
扁平化tabindex有序焦点导航范围是一个包含可聚焦区域的列表。每个焦点导航范围所有者拥有一个独特的扁平化tabindex有序焦点导航范围,其内容通过以下算法确定:
让结果为范围所有者的tabindex有序焦点导航范围的克隆。
对于结果中的每个项:
如果项不是焦点导航范围所有者,则继续。
如果项不是可聚焦区域,则用该项的扁平化tabindex有序焦点导航范围中的所有项替换项。
否则,在项之后插入项的扁平化tabindex有序焦点导航范围的内容。
tabindex
属性支持所有当前引擎。
tabindex
内容属性允许作者使元素及将该元素作为其 DOM
锚点的区域成为 可聚焦区域,允许或阻止它们成为 顺序可聚焦,并确定它们在 顺序焦点导航中的相对顺序。
“tab index”这个名字来源于使用 Tab 键在可聚焦元素之间导航的常见用法。“tabbing”指的是向前移动通过 顺序可聚焦 可聚焦区域。
如果指定了 tabindex
属性,则其值必须是 有效整数。正数指定元素的
可聚焦区域在 顺序焦点导航顺序中的相对位置,负数表示控件不是 顺序可聚焦。
开发者在为 tabindex
属性使用 0 以外的值时应谨慎,因为正确处理这种情况很复杂。
以下是对 tabindex
属性值可能行为的非规范性总结。下面的处理模型给出了更精确的规则。
tabindex 值 是指元素的 tabindex
属性值,使用 解析整数的规则
进行解析。如果解析失败或未指定属性,则 tabindex 值 为 null。
tabindex值的可聚焦区域是其DOM锚点的tabindex值。
元素的tabindex值必须按如下解释:
用户代理应遵循平台惯例来确定元素是否应被视为 可聚焦区域,如果是,还应决定元素及其任何 可聚焦区域 是否为 顺序可聚焦,以及它们在 tabindex-有序焦点导航范围中的相对位置。如果元素是 焦点导航范围所有者,则必须将其包括在其 tabindex-有序焦点导航范围 中,即使它不是 可聚焦区域。
对于同一个 焦点导航范围 的元素和 可聚焦区域,它们在 tabindex-有序焦点导航范围内的相对顺序应为 包含阴影树顺序。
用户代理必须将元素视为 可聚焦区域,但应将元素从任何 tabindex-有序焦点导航范围中省略。
一个有效的忽略顺序焦点导航不允许作者引导到元素的理由是,如果用户的唯一移动焦点的机制是顺序焦点导航。例如,仅使用键盘的用户无法点击负 tabindex
的文本控件,因此用户的用户代理将完全合理地允许用户无论如何都可以切换到该控件。
用户代理必须允许元素被视为 可聚焦区域,并且应允许元素及其作为其 DOM 锚点的任何 可聚焦区域成为 顺序可聚焦。
对于同一个 焦点导航范围 的元素和 可聚焦区域,它们在 tabindex-有序焦点导航范围内的相对顺序应为 包含阴影树顺序。
用户代理必须允许元素被视为 可聚焦区域,并应允许元素及其作为其 DOM 锚点的任何 可聚焦区域成为 顺序可聚焦,并应将元素(在下文中称为 candidate)和上述 可聚焦区域 放置在 tabindex-有序焦点导航范围中,以便它们在同一个 焦点导航范围内的其他元素和 可聚焦区域 相对位置如下:
支持所有当前引擎。
tabIndex
IDL
属性必须 反映 tabindex
内容属性的值。如果元素是 a
,area
,button
,frame
,iframe
,input
,object
,select
,textarea
,或
SVG a
元素,或是 summary
元素是 其父详细信息的摘要,则 默认值 为 0。否则,默认值 为 -1。
基于元素类型的不同默认值是一个历史遗留问题。
为了获取可聚焦区域,针对一个focusTarget(可以是一个元素,但不是可聚焦区域,或者是一个可导航元素),给定一个可选的字符串focus trigger(默认值为
"other
"),运行以下列表中第一个匹配的一组步骤:
area
元素,这些形状是可聚焦区域返回元素的第一个可滚动区域,按照平面树的先序深度优先遍历顺序。[CSSSCOPING]
文档
的文档元素让focusedElement成为顶级可遍历元素的当前聚焦区域的DOM 锚点。
如果focusTarget是focusedElement的包含影的包容祖先,则返回focusedElement。
返回focusTarget的焦点委派,给定focus trigger。
对于顺序可聚焦,处理影宿主和委派焦点是在构建顺序焦点导航顺序时完成的。也就是说,聚焦步骤在顺序焦点导航中不会被调用到这样的影宿主。
返回null。
焦点委派用于focusTarget,给定一个可选字符串focus trigger(默认值为
"other
"),步骤如下:
设whereToLook为focusTarget。
设autofocusDelegate为whereToLook的自动焦点委派,给定focus trigger。
如果autofocusDelegate不为null,则返回autofocusDelegate。
对于每个 whereToLook 的 后代中的 descendant,按照树的顺序:
设focusableArea为null。
如果focusTarget是dialog
元素,且descendant是顺序可聚焦的,则将focusableArea设为descendant。
否则,如果focusTarget不是dialog
,且descendant是可聚焦区域,则将focusableArea设为descendant。
否则,将focusableArea设为获取descendant的可聚焦区域,给定focus trigger的结果。
如果focusableArea不为null,则返回focusableArea。
返回null。
上面的算法实质上返回了第一个合适的可聚焦区域,其DOM 锚点和focusTarget之间的路径在任何影树边界上委派焦点。
自动焦点委派用于focusTarget,给定focus trigger,步骤如下:
返回null。
聚焦步骤用于对象new focus target,这个目标可以是可聚焦区域,也可以是一个元素,但不是可聚焦区域,或者是一个可导航元素,步骤如下。这些步骤可以选择性地使用fallback target和字符串focus trigger。
如果new focus target不是可聚焦区域,则将new focus target设为获取new focus target的可聚焦区域,如果传递了focus trigger。
如果new focus target为null,则:
如果没有指定fallback target,则返回。
否则,将new focus target设为fallback target。
如果new focus target是一个具有非空内容可导航元素的可导航容器,则将new focus target设为内容可导航元素的活动文档。
如果new focus target是顶级可遍历元素的当前聚焦区域,则返回。
设old chain为new focus target所在顶级可遍历元素的当前焦点链。
设new chain为new focus target的焦点链。
运行焦点更新步骤,分别使用old chain、new chain和new focus target。
用户代理必须立即运行 聚焦步骤,以便于 可聚焦区域或 可导航 candidate 在用户尝试将焦点移到 candidate 时。
对象 old focus target 的失焦步骤如下,old focus target 可以是 可聚焦区域或不是 可聚焦区域的元素:
如果old focus target是一个影宿主,其影根的委派焦点为真,且old focus target的影根是包含影的包容祖先,顶级可遍历元素的当前聚焦区域的DOM 锚点,则将old focus target设为该顶级可遍历元素的当前聚焦区域。
如果old focus target是惰性的,则返回。
如果old focus target是area
元素,且其一个形状是顶级可遍历元素的当前聚焦区域,或者,如果old
focus target是一个具有一个或多个可滚动区域的元素,且其中一个是顶级可遍历元素的当前聚焦区域,则将old
focus target设为该顶级可遍历元素的当前聚焦区域。
设old chain为old focus target所在顶级可遍历元素的当前焦点链。
如果old focus target不是old chain中的一个条目,则返回。
如果old focus target不是可聚焦区域,则返回。
设topDocument为old chain的最后一个条目。
如果topDocument的节点可导航具有系统焦点,则运行聚焦步骤,用于topDocument的视口。
否则,应用任何相关的特定平台的惯例,从topDocument的节点可导航中移除系统焦点,并运行焦点更新步骤,给定old chain、一个空列表和null。
失焦步骤并不总是导致焦点改变,即使应用于顶级可遍历元素的当前聚焦区域。例如,如果顶级可遍历元素的当前聚焦区域是一个视口,则通常会保持其焦点,直到另一个可聚焦区域被显式聚焦,使用聚焦步骤。
焦点更新步骤,给定一个old chain、一个new chain和一个new focus target,步骤如下:
如果old chain的最后一个条目和new chain的最后一个条目相同,则从old chain中弹出最后一个条目,从new chain中弹出最后一个条目,并重新执行此步骤。
对于old chain中的每个entry,按顺序运行以下子步骤:
如果entry是input
元素,且change
事件适用于该元素,且该元素没有定义的激活行为,且用户在控件聚焦时更改了元素的值或其选定文件列表,但未提交更改(使其与控件首次聚焦时不同),则:
如果entry是一个元素,则设blur event target为entry。
如果entry是一个文档
对象,则设blur event
target为该文档
对象的相关全局对象。
否则,设blur event target为null。
如果entry是old chain的最后一个条目,且entry是一个元素
,且new
chain的最后一个条目也是一个元素
,则设blur
event target为new
chain的最后一个条目。否则,设blur event target为null。
如果blur event target不为null,则触发一个焦点事件,名为blur
,在blur event
target上,blur event target作为相关目标。
应用任何相关的特定平台 的惯例以聚焦new focus target。(例如,一些平台在焦点进入文本控件时会选择控件的内容。)
对new chain中的每个entry,按逆序运行以下子步骤:
如果entry是可聚焦区域,且文档的聚焦区域不是entry:
将document的相关全局对象的导航API的在进行中的导航期间焦点改变设为真。
指定entry为文档的聚焦区域。
如果entry是一个元素,则设focus event target为entry。
如果entry是一个文档
对象,则设focus event
target为该文档
对象的相关全局对象。
否则,设focus event target为null。
如果entry是new chain的最后一个条目,且entry是一个元素
,且old
chain的最后一个条目也是一个元素
,则设related
focus target为old
chain的最后一个条目。否则,设related focus target为null。
如果focus event target不为null,则触发一个焦点事件,名为focus
,在focus event
target上,related focus target作为相关目标。
要触发一个焦点事件,名为e,在元素t上,给定一个相关目标r,触发一个事件,名为e,在t上,使用FocusEvent
,relatedTarget
属性初始化为r,view
属性初始化为t的节点文档的相关全局对象,并设置组合标志。
当一个键事件要在顶级可遍历元素中路由时,用户代理必须运行以下步骤:
设target area为顶级可遍历元素的当前聚焦区域。
断言:target area不为null,因为键事件只会路由到具有系统焦点的顶级可遍历元素。因此,target area是一个可聚焦区域。
设target node为target area的DOM 锚点。
如果target node不是惰性的,则:
设canHandle为分派键事件在target node上的结果。
如果canHandle为真,则让target area处理键事件。这可能包括在target node上触发一个click
事件。
具有焦点步骤,给定一个文档
对象target,步骤如下:
当为真时:
每个文档
都有一个顺序焦点导航顺序,它对文档中的一些或全部可聚焦区域相对彼此进行排序。其内容和顺序由文档的平展的tabindex-有序焦点导航范围给出。
根据定义平展的tabindex-有序焦点导航范围的规则,顺序不一定与文档的树顺序相关。
如果一个可聚焦区域被从其文档的顺序焦点导航顺序中省略,那么通过顺序焦点导航无法到达它。
还可以有一个顺序焦点导航起点。它最初未设置。当用户指示应移动时,用户代理可以设置它。
例如,如果用户点击文档内容,用户代理可以将其设置为用户点击的位置。
要求用户代理在导航到片段时将顺序焦点导航起点设置为目标元素。
当用户请求将焦点从顶级可遍历元素的当前聚焦区域移动到下一个或上一个可聚焦区域(例如按tab键的默认操作),或当用户请求首先顺序移动焦点到顶级可遍历元素时(例如从浏览器的地址栏),用户代理必须使用以下算法:
设starting point为顶级可遍历元素的当前聚焦区域,如果用户请求从那里顺序移动焦点,或者设为顶级可遍历元素本身,如果用户请求从该顶级可遍历元素外部移动焦点。
如果定义了一个顺序焦点导航起点并且它在starting point内部,则设starting point为该顺序焦点导航起点。
设direction为向前,如果用户请求下一个控件;如果用户请求上一个控件,则为向后。
通常,按tab请求下一个控件,按shift + tab请求上一个控件。
循环:设selection mechanism为顺序,如果starting point是可导航元素,或者starting point在其文档的顺序焦点导航顺序中。
否则,starting point不在其文档的顺序焦点导航顺序中;设selection mechanism为DOM。
设candidate为运行顺序导航搜索算法的结果,参数为starting point、direction和selection mechanism。
如果candidate不为null,则为candidate运行聚焦步骤并返回。
否则,取消设置顺序焦点导航起点。
如果starting point是顶级可遍历元素,或者是顶级可遍历元素中的可聚焦区域,用户代理应适当将焦点转移到其自身的控件(如果有),遵循direction,然后返回。
例如,如果direction是向后,则浏览器渲染区域之前的最后一个顺序可聚焦控件将是要聚焦的控件。
如果用户代理没有顺序可聚焦控件——例如,kiosk模式的浏览器——那么用户代理可以改为重新开始这些步骤,将starting point设为顶级可遍历元素本身。
否则,starting point是一个可聚焦区域,位于子可导航元素中。将starting point设为该子可导航元素的父元素,然后返回到标记为循环的步骤。
顺序导航搜索算法包含以下步骤。此算法有三个参数:starting point、direction和selection mechanism。
从下表中选择适当的单元格,并按照该单元格中的说明进行。
适当的单元格是指列标题描述direction的列和行标题描述starting point和selection mechanism的第一行交叉的单元格。
direction为向前 | direction为向后 | |
---|---|---|
starting point为可导航元素 | 设candidate为starting point的活动文档中的第一个适合的顺序可聚焦区域,如果有的话;否则为null。 | 设candidate为starting point的活动文档中的最后一个适合的顺序可聚焦区域,如果有的话;否则为null。 |
selection mechanism为DOM | 设candidate为starting point后的主文档中的第一个适合的顺序可聚焦区域,如果有的话;否则为null。 | 设candidate为starting point前的主文档中的最后一个适合的顺序可聚焦区域,如果有的话;否则为null。 |
selection mechanism为顺序 | 设candidate为starting point后的主顺序焦点导航顺序中的第一个适合的顺序可聚焦区域,如果有的话;否则为null。 | 设candidate为starting point前的主顺序焦点导航顺序中的最后一个适合的顺序可聚焦区域,如果有的话;否则为null。 |
适合的顺序可聚焦区域是其DOM锚不惰性且是顺序可聚焦的可聚焦区域。
主文档是starting point所属的文档
。
主顺序焦点导航顺序是starting point所属的顺序焦点导航顺序。
主顺序焦点导航顺序是主文档的顺序焦点导航顺序,但仅在starting point在该顺序焦点导航顺序中时使用(当它不在该顺序中时,selection mechanism将为DOM)。
如果candidate是一个具有非空内容可导航元素的可导航容器,则设new candidate为使用candidate的内容可导航元素作为第一个参数,direction作为第二个参数,顺序作为第三个参数运行顺序导航搜索算法的结果。
如果new candidate为null,则设starting point为candidate,并返回到此算法的顶部。否则,设candidate为new candidate。
返回candidate。
dictionary FocusOptions {
boolean preventScroll = false ;
boolean focusVisible ;
};
documentOrShadowRoot.activeElement
Support in all current engines.
Support in all current engines.
返回文档中最深的元素,键事件通过或被路由到该元素。粗略地说,这就是文档中聚焦的元素。
对于此 API,当一个子可导航元素被聚焦时,它的容器在其父元素的活动文档中是聚焦的。例如,如果用户将焦点移到iframe
中的文本控件上,那么iframe
是在activeElement
API 中返回的元素,位于该iframe
的节点文档中。
同样,当聚焦的元素位于与documentOrShadowRoot不同的节点树中时,返回的元素将是位于与documentOrShadowRoot相同节点树中的宿主,如果documentOrShadowRoot是聚焦元素的包含阴影的祖先,否则为null。
document.hasFocus()
Support in all current engines.
如果键事件被路由到或通过该文档,则返回true;否则返回false。粗略地说,这对应于文档或嵌套在其中的文档被聚焦。
window.focus()
Support in all current engines.
将焦点移到窗口的可导航元素,如果有的话。
element.focus([ { preventScroll: true } ])
Support in all current engines.
将焦点移到该元素。
默认情况下,此方法还会将该元素滚动到视图中。提供preventScroll
选项并将其设置为true可防止这种行为。
element.blur()
Support in all current engines.
将焦点移到视口。不建议使用此方法;如果您想聚焦视口,请在focus()
方法上调用Document
的文档元素。
不要使用此方法隐藏焦点环,如果您发现焦点环不美观。相反,使用:focus-visible
伪类覆盖'outline'属性,并提供另一种方式来显示哪个元素被聚焦。请注意,如果没有提供替代的聚焦样式,页面对于主要使用键盘导航或使用焦点轮廓帮助导航的视力减弱用户将变得非常难用。
例如,要隐藏textarea
元素的轮廓并改用黄色背景来指示焦点,您可以使用:
textarea:focus-visible { outline : none; background : yellow; color : black; }
activeElement
属性的getter必须运行以下步骤:
让candidate成为DOM
anchor的focused area,属于此DocumentOrShadowRoot
的节点文档。
将candidate设置为重新定向candidate到此DocumentOrShadowRoot
的结果。
如果candidate的根不是此DocumentOrShadowRoot
,则返回null。
如果candidate不是Document
对象,则返回candidate。
如果candidate的document element为非null,则返回该document element。
返回null。
hasFocus()
方法在Document
对象上调用时,必须返回以Document
对象作为参数运行聚焦步骤的结果。
focus()
方法在调用时,必须运行以下步骤:
Support in all current engines.
在blur()
方法步骤中,不执行任何操作。
从历史上看,focus()
和blur()
方法实际上影响了包含可导航元素的系统小部件(例如,标签或窗口)的系统级焦点,但敌对站点广泛滥用这种行为,损害用户利益。
在元素上调用的focus(options)
方法,调用时,必须运行以下步骤:
如果元素被标记为焦点锁定,则返回。
将元素标记为焦点锁定。
运行元素的聚焦步骤。
如果options的focusVisible
字典成员的值为true,或不存在但用户代理以实现定义的方式确定最好这样做,则指示焦点。
如果options的preventScroll
字典成员的值为false,则在给定“auto”、“center”和“center”的情况下将元素滚动到视图中。
将元素取消标记为焦点锁定。
在元素上调用的blur()
方法,调用时,应为调用该方法的元素运行失焦步骤。出于可用性原因,用户代理可以有选择性地或统一地忽略对此方法的调用。
例如,如果blur()
方法被不明智地用于美学原因删除焦点环,则页面将无法使用键盘用户。忽略对此方法的调用将允许键盘用户与页面进行交互。
autofocus
属性autofocus
内容属性允许作者指示元素在页面加载时获得焦点,使用户可以直接开始输入而无需手动聚焦主要元素。
当在autofocus
属性在dialog
元素内或HTML元素的popover
属性设置时,它将在对话框或弹出框显示时获得焦点。
要找到给定element的最近的祖先自动聚焦范围根元素:
不得有两个具有相同最近的祖先自动聚焦范围根元素的元素,它们都指定了autofocus
属性。
每个Document
都有一个最初为空的自动聚焦候选者 列表。
每个Document
都有一个最初为假的自动聚焦处理标志布尔值。
当一个指定了autofocus
属性的元素被插入到文档中时,运行以下步骤:
如果用户已经表示(例如,通过开始在表单控件中输入)他们不希望更改焦点,则可选地返回。
令target为该元素的节点文档。
如果target不是完全活跃,则返回。
如果target的活跃沙箱标志集具有沙箱自动功能浏览上下文标志,则返回。
对于target的祖先可导航对象的每个ancestorNavigable:如果ancestorNavigable的活跃文档的来源与target的来源不同,则返回。
在将元素存储在自动聚焦候选者列表之前,我们不会检查元素是否是可聚焦区域,因为即使在插入时它不是可聚焦区域,它也可能在刷新自动聚焦候选者看到它时变成可聚焦的。
要刷新自动聚焦候选者,请运行以下步骤:
如果topDocument的自动聚焦处理标志为真,则返回。
令candidates为topDocument的自动聚焦候选者。
如果candidates为空,则返回。
如果topDocument的焦点区域不是topDocument本身,或topDocument具有非null目标元素,则:
当candidates不为空时:
令element为candidates[0]。
令doc为element的节点文档。
如果doc的节点可导航对象的顶级可遍历对象与topDocument的节点可导航对象不同,则从candidates中移除element并继续。
在这种情况下,element是当前最佳候选者,但doc尚未准备好自动聚焦。我们将在下次调用刷新自动聚焦候选者时再试。
从candidates中移除element。
令target为element。
如果target不是可聚焦区域,则将target设置为获取可聚焦区域的结果。
自动聚焦候选者可以包含不是可聚焦区域的元素。除了在获取可聚焦区域算法中处理的特殊情况外,这可能发生,因为具有autofocus
属性的非可聚焦区域元素被插入到文档中且它从未变成可聚焦的,或者因为元素是可聚焦的,但在它存储在自动聚焦候选者中时其状态发生了变化。
如果target不为null,则:
这处理了文档加载期间的自动聚焦。show()
和showModal()
方法也处理dialog
元素的autofocus
属性。
聚焦元素并不意味着如果浏览器窗口失去焦点,用户代理必须聚焦浏览器窗口。
仅在一个引擎中支持。
autofocus
IDL属性必须反映同名的内容属性。
在以下代码片段中,文本控件将在文档加载时获得焦点。
< input maxlength = "256" name = "q" value = "" autofocus >
< input type = "submit" value = "Search" >
autofocus
属性适用于所有元素,而不仅仅是表单控件。这允许以下示例:
< div contenteditable autofocus > Edit < strong > me!</ strong >< div >
本节为非规范性内容。
每个可以激活或聚焦的元素都可以使用accesskey
属性分配一个单一的键组合来激活它。
确切的快捷键由用户代理确定,基于用户的键盘信息、平台上已有的键盘快捷键以及页面上指定的其他快捷键,使用accesskey
属性中提供的信息作为指南。
为了确保在各种输入设备上都有相关的键盘快捷键可用,作者可以在accesskey
属性中提供多个备选项。
每个备选项由一个字符组成,例如字母或数字。
用户代理可以向用户提供键盘快捷键列表,但也鼓励作者这样做。accessKeyLabel
IDL属性返回一个字符串,表示用户代理分配的实际键组合。
在此示例中,作者提供了一个可以使用快捷键调用的按钮。为了支持完整键盘,作者提供了"C"作为可能的键。为了支持仅配备数字键盘的设备,作者提供了"1"作为另一个可能的键。
< input type = button value = Collect onclick = "collect()"
accesskey = "C 1" id = c >
为了告诉用户快捷键是什么,作者在此脚本中选择将键组合明确添加到按钮的标签中:
function addShortcutKeyLabel( button) {
if ( button. accessKeyLabel != '' )
button. value += ' (' + button. accessKeyLabel + ')' ;
}
addShortcutKeyLabel( document. getElementById( 'c' ));
不同平台上的浏览器即使是相同的键组合也会显示不同的标签,基于该平台上的惯例。例如,如果键组合是Control键、Shift键和字母C,Windows浏览器可能显示"Ctrl+Shift+C",而Mac浏览器可能显示"^⇧C",Emacs浏览器可能只显示"C-C"。同样,如果键组合是Alt键和Escape键,Windows可能使用"Alt+Esc",Mac可能使用"⌥⎋",而Emacs浏览器可能使用"M-ESC"或"ESC ESC"。
因此,一般来说,试图解析从accessKeyLabel
IDL属性返回的值是不明智的。
accesskey
属性所有当前引擎支持。
所有HTML 元素都可以设置accesskey
内容属性。accesskey
属性的值由用户代理用作创建激活或聚焦元素的键盘快捷键的指南。
如果指定,值必须是有序的唯一空格分隔标记集合,这些标记中的每一个都不能与其他标记相同,并且每个标记的长度必须恰好为一个代码点。
在以下示例中,提供了各种链接的访问键,以便熟悉该站点的键盘用户可以更快地导航到相关页面:
< nav >
< p >
< a title = "Consortium Activities" accesskey = "A" href = "/Consortium/activities" > Activities</ a > |
< a title = "Technical Reports and Recommendations" accesskey = "T" href = "/TR/" > Technical Reports</ a > |
< a title = "Alphabetical Site Index" accesskey = "S" href = "/Consortium/siteindex" > Site Index</ a > |
< a title = "About This Site" accesskey = "B" href = "/Consortium/" > About Consortium</ a > |
< a title = "Contact Consortium" accesskey = "C" href = "/Consortium/contact" > Contact</ a >
</ p >
</ nav >
在以下示例中,搜索字段被赋予两个可能的访问键,“s”和“0”(按此顺序)。具有完整键盘的设备上的用户代理可能会选择Ctrl + Alt + S作为快捷键,而只有数字键盘的小设备上的用户代理可能只会选择单纯的0键:
< form action = "/search" >
< label > Search: < input type = "search" name = "q" accesskey = "s 0" ></ label >
< input type = "submit" >
</ form >
在以下示例中,描述了按钮的可能访问键。然后,一个脚本尝试更新按钮的标签,以告知用户代理选择的键组合。
< input type = submit accesskey = "N @ 1" value = "Compose" >
...
< script >
function labelButton( button) {
if ( button. accessKeyLabel)
button. value += ' (' + button. accessKeyLabel + ')' ;
}
var inputs = document. getElementsByTagName( 'input' );
for ( var i = 0 ; i < inputs. length; i += 1 ) {
if ( inputs[ i]. type == "submit" )
labelButton( inputs[ i]);
}
</ script >
在某个用户代理上,按钮的标签可能变成"Compose (⌘N)"。在另一个用户代理上,它可能变成"Compose (Alt+⇧+1)"。如果用户代理没有分配键,它将只是"Compose"。确切的字符串取决于分配的访问键是什么,以及用户代理如何表示该键组合。
元素的分配访问键是从该元素的accesskey
内容属性派生的键组合。最初,一个元素不得有分配访问键。
每当元素的accesskey
属性被设置、更改或删除时,用户代理必须通过运行以下步骤来更新元素的分配访问键:
如果该元素没有accesskey
属性,则跳到下面的回退步骤。
否则,按ASCII空格拆分属性的值,并将keys作为生成的标记。
依次对keys中的每个值,按属性值中出现的顺序运行以下子步骤:
如果该值不是长度恰好为一个代码点的字符串,则跳过该值的其余步骤。
如果该值不对应系统键盘上的键,则跳过该值的其余步骤。
如果用户代理可以找到零个或多个修饰键的组合,与对应于属性中给定值的键组合使用,则用户代理可以将该组合分配为元素的分配访问键并返回。
回退:用户代理可以选择一个键组合作为元素的分配访问键,然后返回。
如果执行到此步骤,元素没有分配访问键。
一旦用户代理为元素选择并分配了访问键,除非accesskey
内容属性更改或元素移至另一个Document
,用户代理不应更改元素的分配访问键。
当用户按下与元素的分配访问键对应的键组合时,如果元素定义了一个命令,命令的 部分为假(可见),命令的禁用状态部分也为假(启用),该元素在具有非空浏览上下文的文档中,并且该元素及其任何祖先都没有指定 属性,则用户代理必须触发命令的动作。
用户代理可能会以其他方式显示具有accesskey
属性的元素,例如在响应特定键组合时显示的菜单中。
所有当前引擎支持。
accessKey
IDL属性必须反映 accesskey
内容属性。
accessKeyLabel
IDL属性必须返回一个表示元素的分配访问键的字符串(如果有)。如果元素没有分配访问键,则IDL属性必须返回空字符串。
contenteditable
内容属性所有当前引擎支持。
interface mixin ElementContentEditable {
[CEReactions ] attribute DOMString contentEditable ;
[CEReactions ] attribute DOMString enterKeyHint ;
readonly attribute boolean isContentEditable ;
[CEReactions ] attribute DOMString inputMode ;
};
Global_attributes/contenteditable
所有当前引擎支持。
contenteditable
内容属性是一个枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
true |
true | 元素是可编辑的。 |
(空字符串) | ||
false |
false | 元素不可编辑。 |
plaintext-only |
plaintext-only | 仅元素的纯文本内容可编辑;禁用富文本格式。 |
该属性的缺省值和无效值缺省都是inherit状态。inherit状态表示元素的可编辑性基于父元素的状态。
例如,考虑一个包含表单
和文本区域
的新文章发布页面,用户预期使用HTML编写文章:
< form method = POST >
< fieldset >
< legend > New article</ legend >
< textarea name = article > < p>Hello world.< /p></ textarea >
</ fieldset >
< p >< button > Publish</ button ></ p >
</ form >
当启用脚本时,textarea
元素可以使用contenteditable
属性替换为富文本控件:
< form method = POST >
< fieldset >
< legend > New article</ legend >
< textarea id = textarea name = article > < p>Hello world.< /p></ textarea >
< div id = div style = "white-space: pre-wrap" hidden >< p > Hello world.</ p ></ div >
< script >
let textarea = document. getElementById( "textarea" );
let div = document. getElementById( "div" );
textarea. hidden = true ;
div. hidden = false ;
div. contentEditable = "true" ;
div. oninput = ( e) => {
textarea. value = div. innerHTML;
};
</ script >
</ fieldset >
< p >< button > Publish</ button ></ p >
</ form >
启用的功能,例如插入链接,可以使用document.execCommand()
API,或使用Selection
API和其他DOM API来实现。[EXECCOMMAND] [SELECTION] [DOM]
contenteditable
属性也可以用于实现很好的效果:
<!doctype html>
< html lang = en >
< title > Live CSS editing!</ title >
< style style = white-space:pre contenteditable >
html { margin : .2 em ; font-size : 2 em ; color : lime ; background : purple }
head , title , style { display : block }
body { display : none }
</ style >
element.contentEditable [ = value ]
根据contenteditable
属性的状态,返回"true
"、"plaintext-only
"、"false
"或"inherit
"。
可以设置,以更改该状态。
如果新值不是这些字符串之一,则抛出"SyntaxError
" DOMException
。
element.isContentEditable
支持所有当前的引擎。
如果元素是可编辑的,则返回true;否则,返回false。
contentEditable
IDL属性在获取时,如果内容属性设置为true状态,则返回字符串"true
";如果内容属性设置为plaintext-only状态,则返回"plaintext-only
";如果内容属性设置为false状态,则返回"false
";否则返回"inherit
"。在设置时,如果新值与字符串"inherit
"的ASCII不区分大小写匹配,则必须删除内容属性;如果新值与字符串"true
"的ASCII不区分大小写匹配,则必须将内容属性设置为字符串"true
";如果新值与字符串"plaintext-only
"的ASCII不区分大小写匹配,则必须将内容属性设置为字符串"plaintext-only
";如果新值与字符串"false
"的ASCII不区分大小写匹配,则必须将内容属性设置为字符串"false
";否则,属性设置器必须抛出"SyntaxError
" DOMException
。
isContentEditable
IDL属性在获取时,如果元素是编辑主机或可编辑,则返回true;否则,返回false。
designMode
getter 和 setterdocument.designMode [ = value ]
支持所有当前的引擎。
如果文档是可编辑的,则返回"on
",如果不是则返回"off
"。
可以设置,以改变文档的当前状态。这将使文档聚焦并重置文档中的选择。
Document
对象有一个相关的设计模式启用,这是一个布尔值。它最初为false。
designMode
getter步骤是:如果this的设计模式启用为true,则返回"on
";否则返回"off
"。
designMode
setter步骤如下:
将value转换为ASCII小写。
建议作者在'white-space'属性上设置编辑主机和通过这些编辑机制原始创建的标记,值为'pre-wrap'。默认的HTML空白处理不适用于所见即所得编辑,并且在某些极端情况下,如果'white-space'保持默认值,换行将无法正常工作。
如果使用默认的'normal'值,会出现问题,例如用户输入"yellow␣␣ball",两个单词之间有两个空格(这里用"␣"表示)。根据默认值的编辑规则'white-space' ('normal'),生成的标记将包含"yellow ball"或"yellow ball";即,在两个单词之间将有一个不间断空格以及一个常规空格。这是必要的,因为'white-space'的'normal'值要求将相邻的常规空格折叠在一起。
在前一种情况下,即使"yellow"本身可能适合行末,"yellow⍽"(这里用"⍽"表示不间断空格)可能会换行到下一行;在后一种情况下,如果换行到行首,"⍽ball"将有不间断空格的可见缩进。
当'white-space'设置为'pre-wrap'时,编辑规则将只是简单地在单词之间放置两个常规空格,如果这两个单词在行末被拆分,空格将在渲染时整齐地被移除。
编辑主机是指具有contenteditable
属性且状态为true或plaintext-only的HTML元素,或其设计模式启用为true的子HTML元素的Document
。
术语活动范围、编辑主机和可编辑的定义,作为编辑主机或可编辑元素的用户界面要求,execCommand()
、queryCommandEnabled()
、queryCommandIndeterm()
、queryCommandState()
、queryCommandSupported()
和queryCommandValue()
方法,文本选择,以及删除选择算法在execCommand中定义。[EXECCOMMAND]
用户代理可以支持对可编辑文本的拼写和语法检查,无论是在表单控件中(例如textarea
元素的值),还是在编辑主机中的元素(例如使用contenteditable
)。
对于每个元素,用户代理必须通过默认设置或用户表达的偏好来建立默认行为。每个元素有三种可能的默认行为:
spellcheck
属性明确禁用,则会检查该元素的拼写和语法。
spellcheck
属性明确启用,否则不会检查该元素的拼写和语法。
支持所有当前的引擎。
spellcheck
属性是一个枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
true |
true | 将检查拼写和语法。 |
(空字符串) | ||
false |
false | 不会检查拼写和语法。 |
该属性的缺失值默认值和无效值默认值均为默认状态。默认状态表示元素应根据默认行为进行操作,可能基于父元素自身的spellcheck
状态,如下所定义。
element.spellcheck [ = value ]
如果元素要进行拼写和语法检查,则返回true;否则返回false。
可以设置,以覆盖默认值并设置spellcheck
内容属性。
spellcheck
IDL属性在获取时,如果元素的spellcheck
内容属性处于true状态,或者如果元素的spellcheck
内容属性处于默认状态且元素的默认行为为默认启用,或者如果元素的spellcheck
内容属性处于默认状态且元素
的默认行为为默认继承且元素的父元素的spellcheck
IDL属性会返回true;否则,如果上述条件都不适用,则该属性必须返回false。
spellcheck
IDL属性不受覆盖spellcheck
内容属性的用户偏好的影响,因此可能不会反映实际的拼写检查状态。
在设置时,如果新值为true,则必须将元素的spellcheck
内容属性设置为"true
",否则必须设置为"false
"。
用户代理在考虑此功能的可检查文本时应仅考虑以下文本部分:
input
元素的值(即未指定readonly
属性且未禁用)。readonly
属性且未禁用的textarea
元素的值。
Text
节点中的文本。
对于作为Text
节点一部分的文本,与该文本相关联的元素是第一个字符的直接父元素。对于属性中的文本,是属性的元素。对于input
和textarea
元素的值,是元素本身。
要确定适用元素(如上所述)中的单词、句子或其他文本部分是否启用了拼写和语法检查,用户代理必须使用以下算法:
spellcheck
内容属性,则:如果该属性处于true状态,则启用检查;否则,如果该属性处于false状态,则禁用检查。spellcheck
内容属性且不处于默认状态,则:如果最近的这样的祖先的spellcheck
内容属性处于true状态,则启用检查;否则,禁用检查。如果某个单词/句子/文本启用了检查,用户代理应在该文本中标记拼写和语法错误。用户代理在建议拼写和语法修正时应考虑文档中给出的其他语义。用户代理可以使用元素的语言来确定使用哪些拼写和语法规则,也可以使用用户的
首选语言设置。用户代理应尽可能使用input
元素属性,例如pattern
,以确保生成的值有效。
如果禁用检查,用户代理不应标记该文本的拼写或语法错误。
在以下示例中,ID为"a"的元素将用于确定是否检查单词"Hello"的拼写错误。在此示例中,将不会检查。
< div contenteditable = "true" >
< span spellcheck = "false" id = "a" > Hell</ span >< em > o!</ em >
</ div >
在以下示例中,ID为"b"的元素将启用检查(input
元素属性值中的前导空格字符会导致属性被忽略,因此无论默认值如何,都使用祖先元素的值)。
< p spellcheck = "true" >
< label > Name: < input spellcheck = " false" id = "b" ></ label >
</ p >
本规范未定义拼写和语法检查器的用户界面。用户代理可以提供按需检查,可以在启用检查时进行持续检查,或者使用其他接口。
用户代理在用户输入到可编辑区域时提供写作建议,无论是在表单控件中(例如textarea
元素)还是在编辑主机中的元素。
writingsuggestions
内容属性是一个枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
true |
true | 此元素应提供写作建议。 |
(空字符串) | ||
false |
false | 此元素不应提供写作建议。 |
该属性的缺失值默认值是默认状态。默认状态表示元素应根据默认行为进行操作,可能基于父元素自身的writingsuggestions
状态,如下所定义。
element.writingSuggestions [ = value ]
如果用户代理要在元素的范围内提供写作建议,则返回"true
";否则返回"false
"。
可以设置,以覆盖默认值并设置writingsuggestions
内容属性。
给定element的计算写作建议值由以下步骤确定:
如果element的writingsuggestions
内容属性处于false状态,则返回"false
"。
如果element的writingsuggestions
内容属性处于默认状态,element有父元素,并且element的父元素的计算写作建议值为"false
",则返回"false
"。
返回"true
"。
writingSuggestions
getter步骤如下:
writingSuggestions
IDL属性不受覆盖writingsuggestions
内容属性的用户偏好的影响,因此可能不会反映实际的写作建议状态。
writingSuggestions
setter步骤如下:
将this的writingsuggestions
内容属性设置为给定值。
用户代理只有在运行以下算法给定element返回true时,才应在元素的范围内提供建议:
如果用户禁用了写作建议,则返回false。
如果以下条件都不成立:
则返回false。
如果element有一个具有writingsuggestions
内容属性的包含祖先,该属性不处于默认状态,且最近的此类祖先的writingsuggestions
内容属性处于false状态,则返回false。
否则,返回true。
本规范未定义写作建议的用户界面。用户代理可以提供按需建议、用户输入时的持续建议、内联建议、弹出窗口中的自动填充建议,或者使用其他接口。
某些输入文本的方法,例如移动设备上的虚拟键盘,以及语音输入,通常通过自动将句子的首字母大写来帮助用户(在使用这种惯例的语言中编写文本时)。实现自动大写的虚拟键盘在即将输入应自动大写的字母时,可能会自动切换为显示大写字母(但允许用户将其切换回小写)。其他类型的输入,例如语音输入,可能以一种不允许用户先进行干预的方式执行自动大写。autocapitalize
属性允许作者控制这种行为。
通常实现的autocapitalize
属性不会影响使用物理键盘输入时的行为。(因此,以及用户在某些情况下可以覆盖自动大写行为或在初始输入后编辑文本的能力,不应依赖该属性进行任何类型的输入验证。)
autocapitalize
属性可用于 编辑宿主上,以控制托管的可编辑区域的自动大写行为,也可用于 input
或 textarea
元素上,以控制该元素输入文本时的行为,或用于 form
元素上,以控制与该 form
元素关联的所有 自动大写和自动更正继承的元素 的默认行为。
autocapitalize
属性永远不会导致input
元素在其type
属性处于URL、Email或Password状态时启用自动大写。(此行为包含在下面的使用的自动大写提示算法中。)
自动大写处理模型基于选择以下五个自动大写提示之一,定义如下:
用户代理和输入法应自行确定是否启用自动大写。
不应应用自动大写(所有字母应默认为小写)。
每个句子的第一个字母应默认为大写字母;所有其他字母应默认为小写。
每个单词的第一个字母应默认为大写字母;所有其他字母应默认为小写。
所有字母应默认为大写。
Global_attributes/autocapitalize
支持所有当前的引擎。
autocapitalize
属性是一个枚举属性,其状态是可能的自动大写提示。属性状态指定的自动大写提示与其他考虑因素结合形成使用的自动大写提示,它通知用户代理的行为。此属性的关键字及其状态映射如下:
关键字 | 状态 |
---|---|
off |
none |
none |
|
on |
sentences |
sentences |
|
words |
words |
characters |
characters |
element.autocapitalize [ = value ]
返回元素的当前自动大写状态,如果尚未设置,则返回空字符串。注意,对于从form
元素继承其状态的input
和textarea
元素,此操作将返回form
元素的自动大写状态,但对于在可编辑区域中的元素,此操作将不会返回编辑主机的自动大写状态(除非此元素实际上是编辑主机)。
可以设置,以设置autocapitalize
内容属性(从而更改元素的自动大写行为)。
要计算元素element的自身自动大写提示,请运行以下步骤:
如果 element 上存在 autocapitalize
内容属性,并且其值不是空字符串,则返回该属性的状态。
如果 element 是一个自动大写和自动更正继承的元素,并且有一个非空的表单所有者,则返回 element 的自身自动大写提示,即其表单所有者的提示。
返回 默认。
autocapitalize
getter步骤如下:
autocapitalize
setter步骤是将autocapitalize
内容属性设置为给定值。
支持可定制自动大写行为的用户代理,如果希望允许Web开发人员控制此功能,则在元素中输入文本期间,应计算该元素的使用的自动大写提示。这将是一个描述文本输入该元素时推荐的自动大写行为的自动大写提示。
用户代理或输入法可以选择在某些情况下忽略或覆盖使用的自动大写提示。
元素element的使用的自动大写提示是使用以下算法计算的:
断言:此步骤永远不会被触及,因为文本输入仅在符合上述条件的元素中发生。
某些文本输入方法通过在用户打字时自动更正拼写错误来帮助用户,此过程也称为自动更正。用户代理可以支持表单控件中的可编辑文本(例如 textarea
元素的值)或 编辑宿主中的元素(例如,使用 contenteditable
)的自动更正。自动更正可能伴随用户界面,提示文本即将被更正或已被更正,通常在插入标点符号、空格或新段落后执行拼写错误的自动更正。autocorrect
属性允许作者控制此类行为。
autocorrect
属性可用于编辑宿主,以控制托管的可编辑区域的自动更正行为,也可用于 input
或 textarea
元素,以控制插入文本时的行为,或用于
form
元素,以控制与该 form
相关联的所有 自动大写和自动更正继承的元素的默认行为。
autocorrect
属性永远不会使自动更正对 input
元素启用, 如果其 type
属性处于 URL、电子邮件 或 密码 状态之一。(该行为包含在下面的已使用自动更正状态算法中。)
autocorrect
属性是一个枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简短描述 |
---|---|---|
on
| on | 允许用户代理在用户打字时自动更正拼写错误。是否在打字时自动更正拼写由用户代理决定,可能取决于元素以及用户的偏好。 |
(空字符串) | ||
off
| off | 用户代理不允许在用户打字时自动更正拼写错误。 |
autocorrect
getter
步骤为:如果元素的 已使用自动更正状态 为 on,则返回 true;如果已使用自动更正状态为 off,则返回 false。setter
步骤为:如果给定值为
true,则将元素的 autocorrect
属性设置为
"on
";否则设置为 "off
"。
要计算元素 element 的 已使用自动更正状态,运行以下步骤:
如果 element 是一个 input
元素,并且其 type
属性处于 URL、电子邮件 或 密码状态之一,则返回
off。
如果 element 上存在 autocorrect
内容属性,则返回该属性的状态。
如果 element 是一个自动大写和自动更正继承的元素,并且有一个非空的表单所有者,则返回其表单所有者的
autocorrect
属性状态。
返回 on。
autocorrect
返回元素的自动更正行为。注意,对于自动大写和自动更正继承的元素,如果它们从 form
元素继承状态,那么将返回 form
元素的自动更正行为,但对于可编辑区域中的元素,不会返回
编辑宿主的自动更正行为(除非该元素实际上是 编辑宿主)。
autocorrect
=
value
更新 autocorrect
内容属性(从而更改元素的自动更正行为)。
在以下示例中,input
元素将不允许自动更正,因为它没有
autocorrect
内容属性,因此继承自 form
元素,该元素的属性为 "off
"。然而,textarea
元素将允许自动更正,因为它有一个值为
"on
" 的 autocorrect
内容属性。
< form autocorrect = "off" >
< input type = "search" >
< textarea autocorrect = "on" ></ textarea >
</ form >
inputmode
属性用户代理可以在表单控件(例如textarea
元素的值)或编辑主机中的元素(例如,使用contenteditable
)上支持inputmode
属性。
支持所有当前引擎。
inputmode
内容属性是一个枚举属性,指定了对用户输入内容最有帮助的输入机制类型。
关键字 | 描述 |
---|---|
none |
用户代理不应显示虚拟键盘。此关键字适用于渲染自身键盘控件的内容。 |
text |
用户代理应显示能够在用户本地语言中输入文本的虚拟键盘。 |
tel |
用户代理应显示能够输入电话号码的虚拟键盘。这应包括0到9的数字键、“#”字符键和“*”字符键。在某些地区,这还可以包括字母助记标签(例如,在美国,标有“2”的键历史上还标有字母A、B和C)。 |
url |
用户代理应显示能够在用户本地语言中输入文本的虚拟键盘,并带有帮助输入URL的键,例如“/”和“.”字符键以及快速输入域名中常见字符串(如“www.”或“.com”)的键。 |
email |
用户代理应显示能够在用户本地语言中输入文本的虚拟键盘,并带有帮助输入电子邮件地址的键,例如“@”字符键和“.”字符键。 |
numeric |
用户代理应显示能够输入数字的虚拟键盘。此关键字对于PIN码输入很有用。 |
decimal |
用户代理应显示能够输入分数数字的虚拟键盘。应显示数字键和适合本地语言的格式分隔符。 |
search |
用户代理应显示为搜索优化的虚拟键盘。 |
支持所有当前引擎。
inputMode
IDL属性必须反映inputmode
内容属性,仅限于已知值。
当inputmode
未指定(或处于用户代理不支持的状态)时,用户代理应确定要显示的默认虚拟键盘。应使用诸如输入type
或pattern
属性之类的上下文信息来确定应向用户显示哪种类型的虚拟键盘。
enterkeyhint
属性用户代理可以在表单控件(例如textarea
元素的值)或编辑主机中的元素(例如,使用contenteditable
)上支持enterkeyhint
属性。
Global_attributes/enterkeyhint
支持所有当前引擎。
enterkeyhint
内容属性是一个枚举属性,指定虚拟键盘上回车键显示的操作标签(或图标)。这允许作者自定义回车键的显示,以便为用户提供更多帮助。
关键字 | 描述 |
---|---|
enter |
用户代理应显示“enter”操作的提示,通常插入新行。 |
done |
用户代理应显示“done”操作的提示,通常表示没有更多输入,输入法编辑器(IME)将关闭。 |
go |
用户代理应显示“go”操作的提示,通常表示将用户带到他们输入的文本目标。 |
next |
用户代理应显示“next”操作的提示,通常将用户带到下一个接受文本的字段。 |
previous |
用户代理应显示“previous”操作的提示,通常将用户带到上一个接受文本的字段。 |
search |
用户代理应显示“search”操作的提示,通常将用户带到搜索结果页面。 |
send |
用户代理应显示“send”操作的提示,通常表示将文本发送到目标。 |
支持所有当前引擎。
enterKeyHint
IDL属性必须反映enterkeyhint
内容属性,仅限于已知值。
当enterkeyhint
未指定(或处于用户代理不支持的状态)时,用户代理应确定要显示的默认操作标签(或图标)。应使用诸如inputmode
、type
或pattern
属性之类的上下文信息来确定应在虚拟键盘上显示的操作标签(或图标)。
本节定义了页面内查找 —— 一种常见的用户代理机制,允许用户在页面内容中搜索特定信息。
通过页面内查找接口提供对页面内查找功能的访问。这是一个由用户代理提供的用户界面,允许用户指定输入和搜索参数。此接口可以通过快捷方式或菜单选择出现。
在页面内查找接口中的文本输入和设置的组合代表用户的查询。这通常包括用户想要搜索的文本以及可选设置(例如,仅限于整词搜索的能力)。
用户代理根据给定的查询处理页面内容,并识别出零个或多个匹配项,这些匹配项是满足用户查询的内容范围。
其中一个匹配项被标识为活动匹配项。它被高亮显示并滚动到视图中。用户可以通过使用页面内查找接口前进活动匹配项来浏览匹配项。
问题 #3539
追踪了标准化当前未指定的window.find()
API的页面内查找的方式。
当页面内查找开始搜索匹配项时,页面中所有没有设置[CSSCONTAIN]
属性的 元素,其第二槽位的 应变得可访问,而不修改 属性,以使页面内查找能够搜索其中的内容。同样,具有 属性并处于 状态的所有HTML元素,其 应变得可访问,而不修改 属性,以使页面内查找能够搜索其中的内容。页面内查找结束后,这些 元素和具有 属性并处于 状态的元素应再次跳过其内容。整个过程必须同步进行(因此对用户或作者代码不可见)。当页面内查找选择新的
时,请执行以下步骤:让node成为
中的第一个节点。,给定node的 来运行以下步骤:
在node上运行
。在node上运行
。当页面内查找像这样自动展开 元素时,它会触发 事件。与页面内查找触发的单独 事件一样,此事件可能会被页面用来发现用户在页面内查找对话框中输入的内容。如果页面创建了一个带有当前搜索词和用户可能输入的每个下一个字符的微小可滚动区域,并且观察到浏览器滚动到哪个字符,它可以将该字符添加到搜索词中并更新可滚动区域以逐步构建搜索词。通过将每个可能的下一个匹配项包装在一个关闭的 元素中,页面可以监听 事件而不是 事件。这种攻击可以通过不对用户在页面内查找对话框中输入的每个字符进行操作来解决。
页面内查找过程在文档的上下文中调用,可能会影响该文档的选择。具体来说,定义活动匹配项的范围可以决定当前的选择。然而,这些选择更新可能会在页面内查找过程中的不同时间发生(例如,在页面内查找接口关闭时或在活动匹配项范围变化时)。
用户可以通过一种实现定义(并且可能是设备特定的)方式向用户代理发送关闭请求。这表示用户希望关闭当前显示在屏幕上的某些内容,如弹出窗口、菜单、对话框、选择器或显示模式。
一些示例关闭请求如下:
桌面平台上的Esc键。
某些移动平台(如Android)上的返回按钮或手势。
任何辅助技术的取消手势,如iOS VoiceOver的两指擦拭"z"手势。
游戏控制器上的标准"返回"按钮,如DualShock游戏手柄上的圆圈按钮。
每当用户代理收到针对文档
的潜在关闭请求时,必须在给定document的相关全局对象的用户交互任务源上排队一个全局任务,以执行以下关闭请求步骤:
如果document的全屏元素不为null,则:
这不会触发任何相关事件,如keydown
;它只会最终触发fullscreenchange
事件。
可选地,跳到标记为替代处理的步骤。
例如,如果用户代理检测到用户对当前网页反复拦截关闭请求感到沮丧,它可能会采取这条路径。
根据UI Events或其他相关规范,触发任何相关事件。[UIEVENTS]
在UI Events模型中,相关事件的一个示例是在用户按下键盘上的Esc键时,UI Events建议触发的keydown
和keyup
序列。在大多数带键盘的平台上,这被视为关闭请求,因此会触发这些关闭请求步骤。
一个在UI Events模型之外的相关事件示例是,当用户通过使用取消手势发送关闭请求时,辅助技术合成的Esckeydown
和keyup
序列。
如果没有触发此类事件,则event为null;否则,event为表示其中一个触发事件的事件
对象。如果触发了多个事件,选择哪个是实现定义的,但如果为Esc键触发了keydown
和keyup
事件,用户代理必须选择keydown
事件。
如果event不为null,并且其取消标志已设置,则返回。
如果document不是完全活动的,则返回。
此步骤是必要的,因为如果event不为null,则事件监听器可能导致document不再是完全活动的。
如果closedSomething为true,则返回。
替代处理:否则,没有监视到关闭请求。用户代理可以改为将此交互解释为其他操作,而不是将其解释为关闭请求。
在Esc键是关闭请求的平台上,用户代理将首先触发适当初始化的keydown
和keyup
事件序列。如果网页开发者通过调用preventDefault()
取消keyup
事件,则不会发生任何进一步的操作。但如果事件未被取消触发,则用户代理将继续处理关闭监视器。
在返回按钮是潜在关闭请求的平台上,没有涉及事件,因此当按下返回按钮时,用户代理将直接处理关闭监视器。如果有一个活动的关闭监视器,那么它将被触发。如果没有,用户代理可以将按下返回按钮解释为另一种方式,例如作为请求按-1的增量遍历历史记录。
每个窗口
都有一个关闭监视器管理器,这是一个具有以下结构的项:
关闭监视器管理器的大部分复杂性来自防滥用保护,旨在防止开发人员禁用用户的历史记录遍历功能,对于某些平台,关闭请求的回退操作是历史记录遍历的主要机制。特别是:
关闭监视器的分组设计为,如果在没有历史动作激活的情况下创建了多个关闭监视器,它们将被分组在一起,以便用户触发的关闭请求会关闭组中的所有关闭监视器。这确保了网页开发人员无法通过创建关闭监视器来拦截无限数量的关闭请求;相反,他们最多可以创建等于1+用户激活页面的次数的数量。
下次用户交互允许新组的布尔值鼓励网页开发人员以与单个用户激活相关的方式创建关闭监视器。如果没有它,每次用户激活都会增加允许的组数,即使网页开发人员没有利用这些用户激活来创建关闭监视器。简而言之:
允许:用户交互;在其自己的组中创建一个关闭监视器;用户交互;在第二个独立组中创建一个关闭监视器。
不允许:用户交互;用户交互;在其自己的组中创建一个关闭监视器;在第二个独立组中创建一个关闭监视器。
允许:用户交互;用户交互;在其自己的组中创建一个关闭监视器;与前一个分组的关闭监视器。
此保护对于维护我们期望的最多创建(1 + 用户激活页面的次数)组的不变量并不重要。一个坚定的滥用者只会每次用户交互创建一个关闭监视器,将它们“存储”以供将来滥用。但是,此系统会为正常情况带来更可预测的行为,并鼓励非滥用开发人员直接响应用户交互来创建关闭监视器。
要通知关闭监视器管理器用户激活给定窗口
window:
让manager成为window的关闭监视器管理器。
如果manager的下次用户交互允许新组为true,则递增manager的允许的组数。
将manager的下次用户交互允许新组设置为false。
一个窗口,一个窗口
。
一个取消动作,一个接受布尔参数并返回布尔值的算法。参数指示取消动作算法是否可以通过算法的返回值阻止关闭请求继续。如果布尔参数为true,则算法可以返回true表示调用者将继续执行关闭动作,或返回false表示调用者将退出。如果参数为false,则返回值始终为false。此算法永远不会抛出异常。
一个关闭动作,一个不接受参数且不返回任何值的算法。此算法永远不会抛出异常。
一个正在运行取消动作的布尔值。
如果closeWatcher的活动为closeWatcher的窗口的关闭监视器管理器包含任何包含closeWatcher 的列表。
要建立关闭监视器,给定窗口
window,一个步骤列表cancelAction,和一个步骤列表closeAction:
断言:window的相关Document
是完全活动的。
让closeWatcher成为一个新的关闭监视器,具有以下属性:
让manager成为window的关闭监视器管理器。
否则:
将manager的下次用户交互允许新组设置为true。
返回closeWatcher。
要请求关闭一个关闭监视器 closeWatcher:
如果closeWatcher 未激活,则返回true。
如果closeWatcher的正在运行取消动作为true,则返回true。
让window成为closeWatcher的窗口。
如果window的相关Document
不是完全活动的,则返回true。
如果window的关闭监视器管理器的组的大小小于window的关闭监视器管理器的允许的组数,并且window具有历史动作激活,则让canPreventClose为true;否则为false。
将closeWatcher的正在运行取消动作设置为true。
让shouldContinue成为运行closeWatcher的取消动作给定canPreventClose的结果。
将closeWatcher的正在运行取消动作设置为false。
如果shouldContinue为false,则:
断言:canPreventClose为true。
消费历史动作用户激活给定window。
返回false。
请注意,由于这些子步骤消费历史动作用户激活,请求关闭一个关闭监视器两次而没有任何中间的用户激活将导致canPreventClose在第二次为false。
关闭 closeWatcher。
返回true。
要关闭一个关闭监视器 closeWatcher:
如果closeWatcher 未激活,则返回。
如果closeWatcher的窗口的相关Document
不是完全活动的,则返回。
销毁 closeWatcher。
运行closeWatcher的关闭动作。
要销毁一个关闭监视器 closeWatcher:
要处理关闭监视器给定窗口
window:
让processedACloseWatcher为false。
返回processedACloseWatcher。
CloseWatcher
接口[Exposed =Window ]
interface CloseWatcher : EventTarget {
constructor (optional CloseWatcherOptions options = {});
undefined requestClose ();
undefined close ();
undefined destroy ();
attribute EventHandler oncancel ;
attribute EventHandler onclose ;
};
dictionary CloseWatcherOptions {
AbortSignal signal ;
};
watcher = new CloseWatcher()
watcher = new CloseWatcher({ signal })
创建一个新的 CloseWatcher
实例。
如果提供了 signal
选项,则可以通过中止给定的 AbortSignal
来销毁 watcher(如同调用 watcher.destroy()
一样)。
如果已经有任何 close
watcher 处于活动状态,并且 Window
没有 history-action
activation,那么生成的 CloseWatcher
将会在任何 close
request 响应时与那个已经激活的 close
watcher 一起关闭。(这个已经激活的 close
watcher
不一定是 CloseWatcher
对象;它可以是一个模态 dialog
元素,或者是一个由带有 popover
属性的元素生成的弹出窗口。)
watcher.requestClose()
模拟发送一个 close
request,目标是 watcher,通过首先触发一个 cancel
事件,如果该事件没有通过 preventDefault()
被取消,则继续触发一个 close
事件,然后将关闭监视器停用,如同调用 watcher.destroy()
。
这是一个辅助工具,可以用于将取消和关闭逻辑整合到 cancel
和 close
事件处理程序中,通过让所有非 close request
的关闭操作调用此方法。
watcher.close()
立即触发 close
事件,然后将关闭监视器停用,如同调用 watcher.destroy()
。
watcher.destroy()
停用 watcher,使其不再接收 close
事件,并且可以构造新的独立 CloseWatcher
实例。
这是为了在相关的 UI 元素以其他方式被拆除而不是被关闭时调用。
每个 CloseWatcher
实例都有一个 内部关闭监视器,它是一个 关闭监视器。
new CloseWatcher(options)
构造步骤如下:
如果 this 的 相关全局对象 的 关联 Document
不是 完全活动的,则抛出 "InvalidStateError
" DOMException
。
让 closeWatcher 成为 建立一个关闭监视器 的结果,给定 this 的 相关全局对象,其中:
cancelAction 给定
canPreventClose 的返回结果是 触发一个名为 cancel
的事件在 this,并且 cancelable
属性初始化为 canPreventClose。
closeAction 的结果是 触发一个名为
close
的事件在 this。
requestClose()
方法步骤是 请求关闭 this 的 内部关闭监视器。
close()
方法步骤是 关闭 this
的 内部关闭监视器。
destroy()
方法步骤是 销毁 this
的 内部关闭监视器。
以下是所有实现 CloseWatcher
接口的对象必须支持的 事件处理程序(及其对应的 事件处理程序事件类型),作为 事件处理程序 IDL
属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
oncancel |
cancel
|
onclose |
close
|
如果希望实现一个自定义选择控件,该控件在用户提供的 close
request 时自动关闭,以及当按下关闭按钮时关闭,以下代码展示了如何使用 CloseWatcher
API 来处理关闭请求:
const watcher = new CloseWatcher();
const picker = setUpAndShowPickerDOMElement();
let chosenValue = null ;
watcher. onclose = () => {
chosenValue = picker. querySelector( 'input' ). value;
picker. remove();
};
picker. querySelector( '.close-button' ). onclick = () => watcher. requestClose();
注意如何将收集选择值的逻辑集中在 CloseWatcher
对象的 close
事件处理程序中,通过在关闭按钮的 click
事件处理程序中调用 requestClose()
来委托该逻辑。
cancel
事件在 CloseWatcher
对象上可用于防止 close
事件触发,并且防止 CloseWatcher
被销毁。一个典型的用例如下:
watcher. oncancel = async ( e) => {
if ( hasUnsavedData && e. cancelable) {
e. preventDefault();
const userReallyWantsToClose = await askForConfirmation( "Are you sure you want to close?" );
if ( userReallyWantsToClose) {
hasUnsavedData = false ;
watcher. close();
}
}
};
出于防止滥用的目的,这个事件只有在页面具有 history-action activation 时才是 cancelable
,并且在任何给定的
close request
之后将失去。这样可以确保如果用户在没有任何干预的用户激活的情况下两次发送关闭请求,第二次请求将肯定成功;第二次请求忽略任何 cancel
事件处理程序的 preventDefault()
调用,并继续关闭 CloseWatcher
。
结合以上两个例子展示了 requestClose()
和 close()
的区别。由于我们在关闭按钮的 click
事件处理程序中使用了 requestClose()
,点击该按钮将触发
CloseWatcher
的 cancel
事件,从而在有未保存数据的情况下可能会要求用户确认。如果我们使用了 close()
,那么这个检查将被跳过。有时这是合适的,但通常
requestClose()
是用户触发的关闭请求的更好选择。
除了用于 cancel
事件的 用户激活 限制外,对于
CloseWatcher
构造还有一种更微妙的用户激活门控。如果在没有用户激活的情况下创建多个 CloseWatcher
,则新创建的会与最近创建的
关闭监视器
分组,以便一个单一的 关闭请求
会关闭它们两个:
window. onload = () => {
// This will work as normal: it is the first close watcher created without user activation.
( new CloseWatcher()). onclose = () => { /* ... */ };
};
button1. onclick = () => {
// This will work as normal: the button click counts as user activation.
( new CloseWatcher()). onclose = () => { /* ... */ };
};
button2. onclick = () => {
// These will be grouped together, and both will close in response to a single close request.
( new CloseWatcher()). onclose = () => { /* ... */ };
( new CloseWatcher()). onclose = () => { /* ... */ };
};
这意味着调用 destroy()
、close()
或 requestClose()
是非常重要的。这样做是恢复“免费”未分组关闭监视器槽的唯一方法。这些在没有用户激活的情况下创建的关闭监视器对于像会话不活动超时对话框或服务器触发事件的紧急通知等情况非常有用,这些不是用户激活生成的。
所有当前引擎均支持。
本节定义了一种基于事件的拖放机制。
本规范未具体定义 拖放操作 实际上是什么。
在具有指针设备的可视介质上,拖动操作可以是一个 mousedown
事件的默认操作,该事件后跟一系列 mousemove
事件,而放下可以通过松开鼠标来触发。
当使用指针设备以外的输入模式时,用户可能需要明确表明他们打算执行拖放操作,分别说明他们希望拖动什么以及希望将其放置在哪里。
无论如何实现,拖放操作必须有一个起点(例如鼠标点击的位置,或选择用于拖动的元素或选择的开始),可以有任意数量的中间步骤(鼠标在拖动过程中移动经过的元素,或用户在循环浏览可能的放置点时选择的元素),并且必须有一个终点(鼠标按钮松开时上方的元素,或最终选择的元素),或被取消。终点必须是放下发生之前最后一次选择的可能的放置点(因此如果操作未取消,必须至少有一个中间步骤中的元素)。
本节为非规范性内容。
要使一个元素可拖动,给该元素添加一个 draggable
属性,并设置一个
dragstart
事件监听器,
用于存储被拖动的数据。
事件处理程序通常需要检查是否不是文本选择被拖动,然后需要将数据存储到 DataTransfer
对象中,
并设置允许的效果(复制、移动、链接或某种组合)。
例如:
< p > What fruits do you like?</ p >
< ol ondragstart = "dragStartHandler(event)" >
< li draggable = "true" data-value = "fruit-apple" > Apples</ li >
< li draggable = "true" data-value = "fruit-orange" > Oranges</ li >
< li draggable = "true" data-value = "fruit-pear" > Pears</ li >
</ ol >
< script >
var internalDNDType = 'text/x-example' ; // set this to something specific to your site
function dragStartHandler( event) {
if ( event. target instanceof HTMLLIElement) {
// use the element's data-value="" attribute as the value to be moving:
event. dataTransfer. setData( internalDNDType, event. target. dataset. value);
event. dataTransfer. effectAllowed = 'move' ; // only allow moves
} else {
event. preventDefault(); // don't allow selection to be dragged
}
}
</ script >
要接受一个放置操作,放置目标必须监听以下事件:
dragenter
事件处理程序通过取消事件报告放置目标是否可能愿意接受放置。
dragover
事件处理程序通过设置与事件关联的dropEffect
属性来指定将向用户显示的反馈。此事件也需要被取消。
drop
事件处理程序最后一次有机会接受或拒绝放置。如果接受放置,事件处理程序必须在目标上执行放置操作。此事件需要被取消,以便源可以使用dropEffect
属性的值。否则,放置操作将被拒绝。
例如:
< p > Drop your favorite fruits below:</ p >
< ol ondragenter = "dragEnterHandler(event)" ondragover = "dragOverHandler(event)"
ondrop = "dropHandler(event)" >
</ ol >
< script >
var internalDNDType = 'text/x-example' ; // set this to something specific to your site
function dragEnterHandler( event) {
var items = event. dataTransfer. items;
for ( var i = 0 ; i < items. length; ++ i) {
var item = items[ i];
if ( item. kind == 'string' && item. type == internalDNDType) {
event. preventDefault();
return ;
}
}
}
function dragOverHandler( event) {
event. dataTransfer. dropEffect = 'move' ;
event. preventDefault();
}
function dropHandler( event) {
var li = document. createElement( 'li' );
var data = event. dataTransfer. getData( internalDNDType);
if ( data == 'fruit-apple' ) {
li. textContent = 'Apples' ;
} else if ( data == 'fruit-orange' ) {
li. textContent = 'Oranges' ;
} else if ( data == 'fruit-pear' ) {
li. textContent = 'Pears' ;
} else {
li. textContent = 'Unknown Fruit' ;
}
event. target. appendChild( li);
}
</ script >
要从显示中移除原始元素(被拖动的元素),可以使用dragend
事件。
在我们的示例中,这意味着更新原始标记以处理该事件:
< p > What fruits do you like?</ p >
< ol ondragstart = "dragStartHandler(event)" ondragend = "dragEndHandler(event)" >
...as before...
</ ol >
< script >
function dragStartHandler( event) {
// ...as before...
}
function dragEndHandler( event) {
if ( event. dataTransfer. dropEffect == 'move' ) {
// remove the dragged element
event. target. parentNode. removeChild( event. target);
}
}
</ script >
拖放操作所依赖的数据,称为拖放数据存储,包括以下信息:
一个拖放数据存储项列表,这是一个表示拖动数据的项目列表,每个项目包括以下信息:
数据的类型:
文本。
带有文件名的二进制数据。
给出数据类型或格式的Unicode字符串,通常由MIME类型给出。出于遗留原因,一些不是MIME类型的值会被特殊处理。API不会强制使用MIME类型;其他值也可以使用。然而,在所有情况下,这些值都会被API转换为ASCII小写。
每个类型字符串最多只能有一个文本项目。
Unicode或二进制字符串,在某些情况下还带有文件名(也是Unicode字符串),根据拖放数据项类型。
拖放数据存储项列表按添加到列表中的顺序排序;最近添加的在最后。
以下信息用于在拖动期间生成UI反馈:
一个拖放数据存储模式,它是以下之一:
一个拖放数据存储允许的效果状态,它是一个字符串。
当拖放数据存储创建时,它必须初始化为其拖放数据存储项列表为空,没有拖放数据存储默认反馈,没有拖放数据存储位图和拖放数据存储热点坐标,其拖放数据存储模式为受保护模式,其拖放数据存储允许的效果状态为字符串"未初始化
"。
DataTransfer
接口在所有当前引擎中支持。
DataTransfer
对象用于公开拖放操作所依赖的拖放数据存储。
[Exposed =Window ]
interface DataTransfer {
constructor ();
attribute DOMString dropEffect ;
attribute DOMString effectAllowed ;
[SameObject ] readonly attribute DataTransferItemList items ;
undefined setDragImage (Element image , long x , long y );
/* old interface */
readonly attribute FrozenArray <DOMString > types ;
DOMString getData (DOMString format );
undefined setData (DOMString format , DOMString data );
undefined clearData (optional DOMString format );
[SameObject ] readonly attribute FileList files ;
};
dataTransfer = new DataTransfer()
在所有当前引擎中支持。
创建一个新的DataTransfer
对象,并带有一个空的拖放数据存储。
dataTransfer.dropEffect [ = value ]
在所有当前引擎中支持。
返回当前选择的操作类型。如果当前操作类型不是effectAllowed
属性允许的操作类型之一,则操作会失败。
可以设置以更改选择的操作类型。
dataTransfer.effectAllowed [ = value ]
在所有当前引擎中支持。
返回要允许的操作类型。
可以在dragstart
事件期间设置,以更改允许的操作。
可能的值为"none
"、"copy
"、"copyLink
"、"copyMove
"、"link
"、"linkMove
"、"move
"、"all
"和"uninitialized
"。
dataTransfer.items
在所有当前引擎中支持。
返回一个DataTransferItemList
对象,包含拖动数据。
dataTransfer.setDragImage(element, x, y)
在所有当前引擎中支持。
使用给定的元素更新拖动反馈,替换之前指定的反馈。
dataTransfer.types
在所有当前引擎中支持。
返回一个frozen
array,列出在dragstart
事件中设置的格式。此外,如果有任何文件被拖动,则其中一个类型将是字符串"Files
"。
data = dataTransfer.getData(format)
在所有当前引擎中支持。
返回指定的数据。如果没有此类数据,则返回空字符串。
dataTransfer.setData(format, data)
在所有当前引擎中支持。
添加指定的数据。
dataTransfer.clearData([ format ])
在所有当前引擎中支持。
移除指定格式的数据。如果省略了参数,则移除所有数据。
dataTransfer.files
在所有当前引擎中支持。
返回一个FileList对象,包含被拖动的文件(如果有)。
DataTransfer
对象在拖放事件期间创建时只在这些事件被触发时有效。
DataTransfer
对象在有效期间与拖放数据存储相关联。
DataTransfer
对象有一个关联的types数组,它是一个FrozenArray<DOMString>
,初始为空。当DataTransfer
对象的拖放数据存储项列表的内容发生变化,或当DataTransfer
对象不再与拖放数据存储相关联时,运行以下步骤:
令L为一个空序列。
如果DataTransfer
对象仍然与拖放数据存储相关联,则:
对于DataTransfer
对象的拖放数据存储项列表中的每个text类型项,向L中添加一项,包含该项的类型字符串。
如果DataTransfer
对象的拖放数据存储项列表中有任何File类型项,则向L中添加一项,包含字符串"Files
"。(此值可以与其他值区分开,因为它不是小写的。)
将DataTransfer
对象的types数组设置为从L创建冻结数组的结果。
当调用DataTransfer()
构造函数时,必须返回一个新创建的DataTransfer
对象,并按如下初始化:
将dropEffect
和effectAllowed
设置为"none"。
dropEffect
属性控制在拖放操作期间用户得到的拖放反馈。当创建DataTransfer
对象时,dropEffect
属性被设置为一个字符串值。获取时,必须返回其当前值。设置时,如果新值是"none
"、"copy
"、"link
"或"move
"之一,则属性的当前值必须设置为新值。其他值必须被忽略。
effectAllowed
属性在拖放处理模型中用于在dragenter
和dragover
事件期间初始化dropEffect
属性。当创建DataTransfer
对象时,effectAllowed
属性被设置为一个字符串值。获取时,必须返回其当前值。设置时,如果拖放数据存储的模式是读/写模式,并且新值是"none
"、"copy
"、"copyLink
"、"copyMove
"、"link
"、"linkMove
"、"move
"、"all
"或"uninitialized
"之一,则属性的当前值必须设置为新值。否则,必须保持不变。
items
属性必须返回与DataTransfer
对象关联的DataTransferItemList
对象。
setDragImage(image, x, y)
方法必须运行以下步骤:
如果DataTransfer
对象不再与拖放数据存储相关联,则返回。什么都不做。
如果image是img
元素,则将拖放数据存储位图设置为元素的图像(按其自然尺寸);否则,将拖放数据存储位图设置为从给定元素生成的图像(生成的确切机制目前未指定)。
将拖放数据存储热点坐标设置为给定的x、y坐标。
types
属性必须返回此DataTransfer
对象的types数组。
getData(format)
方法必须运行以下步骤:
如果DataTransfer
对象不再与拖放数据存储相关联,则返回空字符串。
将format设置为第一个参数,并转换为ASCII小写。
令convert-to-URL为false。
如果format等于"text
",则将其更改为"text/plain
"。
如果format等于"url
",则将其更改为"text/uri-list
"并将convert-to-URL设置为true。
令result为拖放数据存储项列表中Plain Unicode string类型且类型字符串等于format的项的数据。
如果convert-to-URL为true,则按照text/uri-list
数据的适当方式解析result,然后将result设置为列表中的第一个URL(如果有),否则设置为空字符串。[RFC2483]
返回result。
setData(format, data)
方法必须运行以下步骤:
如果DataTransfer
对象不再与拖放数据存储相关联,则返回。什么都不做。
将format设置为第一个参数,并转换为ASCII小写。
如果format等于"text
",则将其更改为"text/plain
"。
如果format等于"url
",则将其更改为"text/uri-list
"。
clearData(format)
方法必须运行以下步骤:
如果DataTransfer
对象不再与拖放数据存储相关联,则返回。什么都不做。
如果方法在没有参数的情况下调用,则移除拖放数据存储项列表中每个Plain Unicode string类型的项,并返回。
将format设置为format,并转换为ASCII小写。
如果format等于"text
",则将其更改为"text/plain
"。
如果format等于"url
",则将其更改为"text/uri-list
"。
方法clearData()
不影响是否在拖动中包含了任何文件,因此属性types
的列表在调用clearData()
后可能仍然不为空(如果在拖动中包含了任何文件,则仍会包含字符串"Files
")。
files
属性必须返回一个liveFileList
序列,包含通过以下步骤找到的File
对象。此外,对于给定的FileList
对象和给定的底层文件,每次必须使用相同的File
对象。
以空列表L开始。
如果DataTransfer
对象不再与拖放数据存储相关联,则FileList
为空。返回空列表L。
通过这些步骤找到的文件就是列表L中的文件。
此版本的API在拖动过程中不公开文件的类型。
DataTransferItemList
接口支持所有当前的引擎。
每个DataTransfer
对象都与一个DataTransferItemList
对象相关联。
[Exposed =Window ]
interface DataTransferItemList {
readonly attribute unsigned long length ;
getter DataTransferItem (unsigned long index );
DataTransferItem ? add (DOMString data , DOMString type );
DataTransferItem ? add (File data );
undefined remove (unsigned long index );
undefined clear ();
};
items.length
支持所有当前的引擎。
返回拖拽数据存储中的项数。
items[index]
返回代表拖拽数据存储中第index项的DataTransferItem
对象。
items.remove(index)
支持所有当前的引擎。
移除拖拽数据存储中的第index项。
items.clear()
支持所有当前的引擎。
移除拖拽数据存储中的所有项。
items.add(data)
支持所有当前的引擎。
items.add(data, type)
将给定数据的新项添加到拖拽数据存储中。如果数据是纯文本,则还需要提供type字符串。
当DataTransferItemList
对象的DataTransfer
对象与拖拽数据存储相关联时,DataTransferItemList
对象的模式与拖拽数据存储模式相同。当DataTransferItemList
对象的DataTransfer
对象未与拖拽数据存储相关联时,DataTransferItemList
对象的模式为禁用模式。本节中引用的拖拽数据存储(仅在DataTransferItemList
对象未处于禁用模式时使用)是与DataTransferItemList
对象的DataTransfer
对象相关联的拖拽数据存储。
length
属性在对象处于禁用模式时必须返回零;否则,它必须返回拖拽数据存储项列表中的项数。
当DataTransferItemList
对象未处于禁用模式时,其支持的属性索引是列表的索引,位于拖拽数据存储项列表中。
要确定索引属性 i 的值,用户代理必须返回表示DataTransferItemList
对象的第i项的DataTransferItem
对象。每次从该DataTransferItemList
对象获取特定项时,必须返回相同的对象。DataTransferItem
对象必须与首次创建时与DataTransferItemList
对象关联的相同DataTransfer
对象相关联。
add()
方法必须运行以下步骤:
如果DataTransferItemList
对象未处于读/写模式,返回null。
跳转到以下列表中的适当步骤集:
如果拖拽数据存储项列表中已有一项,其类型为text,且其类型字符串与方法的第二个参数值相等,转换为ASCII小写,则抛出DOMException
异常,"NotSupportedError
"。
否则,将一项添加到拖拽数据存储项列表中,其类型为text,类型字符串与方法的第二个参数值相等,转换为ASCII小写,其数据为方法的第一个参数给定的字符串。
File
添加一项到拖拽数据存储项列表中,其类型为File,其类型字符串为type
,转换为ASCII小写,其数据与File
的数据相同。
确定索引属性的值,对应于新添加的项,并返回该值(新创建的DataTransferItem
对象)。
remove(index)
方法必须运行以下步骤:
如果DataTransferItemList
对象未处于读/写模式,抛出DOMException
异常,"InvalidStateError
"。
如果拖拽数据存储不包含第index项,则返回。
从拖拽数据存储中移除第index项。
clear()
方法,如果DataTransferItemList
对象处于读/写模式,必须移除所有拖拽数据存储中的项。否则,不做任何操作。
DataTransferItem
接口支持所有当前的引擎。
每个 DataTransferItem
对象都与一个 DataTransfer
对象关联。
[Exposed =Window ]
interface DataTransferItem {
readonly attribute DOMString kind ;
readonly attribute DOMString type ;
undefined getAsString (FunctionStringCallback ? _callback );
File ? getAsFile ();
};
callback FunctionStringCallback = undefined (DOMString data );
item.kind
支持所有当前的引擎。
返回拖拽数据项类型之一:“string”或“file”。
item.type
支持所有当前的引擎。
返回拖拽数据项类型字符串。
item.getAsString(callback)
支持所有当前的引擎。
如果拖拽数据项类型是text,则使用字符串数据作为参数调用回调函数。
file = item.getAsFile()
支持所有当前的引擎。
当 DataTransferItem
对象的 DataTransfer
对象关联一个拖拽数据存储且该拖拽数据存储的拖拽数据存储项列表仍包含DataTransferItem
对象表示的项时,DataTransferItem
对象的模式与拖拽数据存储模式相同。当DataTransferItem
对象的DataTransfer
对象没有关联一个拖拽数据存储,或DataTransferItem
对象表示的项已从相关拖拽数据存储项列表中移除时,DataTransferItem
对象的模式为禁用模式。本节中引用的拖拽数据存储(仅在DataTransferItem
对象不处于禁用模式时使用)是DataTransferItem
对象的DataTransfer
对象关联的拖拽数据存储。
kind
属性在DataTransferItem
对象处于禁用模式时返回空字符串;否则,它返回以下表中第二列中给定的字符串,其中第一列中的单元格包含拖拽数据项类型
:
类型 | 字符串 |
---|---|
文本 | "string " |
文件 | "file " |
type
属性在DataTransferItem
对象处于禁用模式时返回空字符串;否则,它返回拖拽数据项类型字符串
。
getAsString(callback)
方法必须按以下步骤执行:
如果callback为null,则返回。
如果DataTransferItem
对象不处于读/写模式或只读模式,则返回。回调函数不会被调用。
如果拖拽数据项类型
不是文本,则返回。回调函数不会被调用。
否则,队列一个任务
以调用callback,传递由DataTransferItem
对象表示的项的实际数据作为参数。
getAsFile()
方法必须按以下步骤执行:
如果DataTransferItem
对象不处于读/写模式或只读模式,则返回null。
如果拖拽数据项类型
不是文件,则返回null。
返回一个新的File
对象,表示由DataTransferItem
对象表示的项的实际数据。
DragEvent
接口支持所有当前的引擎。
支持所有当前的引擎。
拖放处理模型涉及多个事件。它们都使用 DragEvent
接口。
[Exposed =Window ]
interface DragEvent : MouseEvent {
constructor (DOMString type , optional DragEventInit eventInitDict = {});
readonly attribute DataTransfer ? dataTransfer ;
};
dictionary DragEventInit : MouseEventInit {
DataTransfer ? dataTransfer = null ;
};
event.dataTransfer
支持所有当前的引擎。
返回事件的 DataTransfer
对象。
尽管为了与其他事件接口保持一致,DragEvent
接口有一个构造函数,但它并不是特别有用。特别是,没有办法从脚本中创建有用的 DataTransfer
对象,因为 DataTransfer
对象在拖放过程中由浏览器协调处理和安全模型。
DragEvent
接口的
dataTransfer
属性必须返回它被初始化时的值。它表示事件的上下文信息。
当用户代理需要在某个元素上触发名为 e 的拖放事件(DND),使用特定的 拖放数据存储,并可选地带有特定的 related target,用户代理必须运行以下步骤:
如果没有提供特定的 related target,将 related target 设置为 null。
将 window 设置为指定目标元素的 文档
对象的相关全局对象。
如果 e 是 dragstart
,则将
拖放数据存储模式 设置为 读/写模式,并将
dataDragStoreWasChanged 设置为 true。
将 dataTransfer 设置为一个新创建的 DataTransfer
对象,该对象与给定的 拖放数据存储 相关联。
将 effectAllowed
属性设置为 拖放数据存储
的 拖放数据存储允许的效果状态。
将 dropEffect
属性设置为 "none
",如果
e 是 dragstart
、drag
或
dragleave
;如果
e 是 drop
或 dragend
,则将其设置为对应于当前拖动操作的值;否则根据
effectAllowed
属性的值和拖放源的值,如下表所示:
effectAllowed
|
dropEffect
|
---|---|
"none "
|
"none "
|
"copy "
|
"copy "
|
"copyLink "
|
"copy ",或
如适用,"link "
|
"copyMove "
|
"copy ",或
如适用,"move "
|
"all "
|
"copy ",或
如适用,"link "
或 "move "
|
"link "
|
"link "
|
"linkMove "
|
"link ",或
如适用,"move "
|
"move "
|
"move "
|
"uninitialized "
当拖动的是文本控件中的选区时 |
"move ",或
如适用,"copy "
或 "link "
|
"uninitialized "
当拖动的是选区时 |
"copy ",或
如适用,"link "
或 "move "
|
"uninitialized "
当拖动的是带有 href
属性的 a
元素时 |
"link ",或
如适用,"copy "
或 "move "
|
任何其他情况 | "copy ",或
如适用,"link "
或 "move "
|
在上表中提供的 可能适当的替代值 的情况下,如果平台约定表明用户请求这些替代效果,则用户代理可以使用列出的替代值。
例如,Windows 平台约定是拖动时按住 "alt" 键表示首选链接数据,而不是移动或复制它。因此,在 Windows 系统上,如果在按住 "alt" 键时,根据上表,"link
"
是一个选项,用户代理可以选择它,而不是 "copy
"
或 "move
"。
将 event 设置为使用 DragEvent
创建事件的结果。
初始化 event 的 type
属性为 e,bubbles
属性为 true,view
属性为 window,relatedTarget
属性为 related target,以及 dataTransfer
属性为 dataTransfer。
如果 e 不是 dragleave
或 dragend
,则初始化
event 的 cancelable
属性为 true。
根据输入设备的状态初始化 event 的鼠标和键盘属性,就像它们是用户交互事件一样。
如果没有相关的指点设备,则将 event 的
screenX
、screenY
、clientX
、clientY
和 button
属性初始化为
0。
在指定目标元素上分派 event。
将 拖放数据存储允许的效果状态 设置为
dataTransfer 的 effectAllowed
属性的当前值。(它只能在 e 是 dragstart
时更改。)
断开 dataTransfer 与 拖放数据存储 的关联。
当用户尝试开始拖动操作时,用户代理必须执行以下步骤。即使拖动实际上是从另一个文档或应用程序开始的,并且用户代理在拖动操作与其管理下的文档交互之前并不知道该拖动操作,用户代理也必须像执行了这些步骤一样行事。
确定正在拖动的内容,如下所示:
如果拖动操作是在选择上调用的,那么正在拖动的是该选择。
否则,如果拖动操作是在Document
上调用的,则它是从用户尝试拖动的节点开始沿着祖先链向上的第一个具有IDL属性draggable
设置为true的元素。如果没有这样的元素,那么没有任何内容被拖动;返回,拖放操作从未开始。
否则,拖动操作是在用户代理的管理范围之外调用的。正在拖动的内容由开始拖动的文档或应用程序定义。
创建一个拖放数据存储。本节中步骤随后触发的所有DND事件都必须使用此拖放数据存储。
确定哪个DOM节点是源节点,如下所示:
如果正在拖动的是选择,那么源节点是用户开始拖动的Text
节点(通常是用户最初点击的Text
节点)。如果用户没有指定特定节点,例如如果用户只是告诉用户代理开始拖动“选择”,那么源节点是包含部分选择的第一个Text
节点。
否则,如果正在拖动的是元素,那么源节点是正在拖动的元素。
否则,源节点是另一个文档或应用程序的一部分。当本规范要求在这种情况下在源节点上调度事件时,用户代理必须遵循与该情况相关的平台特定约定。
在拖放操作过程中,会在源节点上触发多个事件。
确定拖动节点列表,如下所示:
如果正在拖动的是选择,则在拖放数据存储项目列表中添加一项,其属性设置如下:
text/plain
"
否则,如果正在拖动任何文件,则为每个文件在拖放数据存储项目列表中添加一项,其属性设置如下:
application/octet-stream
"
目前只能从可导航外部拖动文件,例如从文件管理器应用程序。
如果拖动是从应用程序外部开始的,用户代理必须根据正在拖动的数据适当地在拖放数据存储项目列表中添加项目,适当时遵守平台约定;但是,如果平台约定不使用 MIME类型标记拖动数据,则用户代理必须尽力尝试将类型映射到MIME类型,并且无论如何,所有拖放数据项类型字符串必须转换为ASCII小写。
用户代理还可以以其他形式(例如HTML)添加一个或多个代表选择或拖动元素的项目。
如果拖动节点列表不为空,则将这些节点中的微数据提取为JSON格式,并在拖放数据存储项目列表中添加一项,其属性设置如下:
application/microdata+json
运行以下子步骤:
设定urls为空列表。
对于拖动节点列表中的每个node:
href
属性的a
元素
href
内容属性的值,并相对于元素的节点文档,将编码解析和序列化的URL的结果添加到urls。
src
属性的img
元素
src
内容属性的值,并相对于元素的节点文档,将编码解析和序列化的URL的结果添加到urls。
如果urls仍然为空,则返回。
设定url string为按添加顺序连接urls中的字符串,以U+000D CARRIAGE RETURN U+000A LINE FEED字符对(CRLF)分隔。
在拖放数据存储项目列表中添加一项,其属性设置如下:
text/uri-list
根据用户代理的情况适当更新拖放数据存储默认反馈(如果用户正在拖动选择,那么选择可能是此反馈的基础;如果用户正在拖动元素,则使用该元素的渲染;如果拖动在用户代理外部开始,则使用平台约定确定拖动反馈)。
触发一个
DND
事件,名为dragstart
,
在源节点上。
如果事件被取消,则不应发生拖放操作;返回。
由于没有注册事件监听器的事件几乎永远不会被取消,如果作者没有明确阻止,拖放操作对用户始终可用。
触发一个指针事件,在源节点上,名为pointercancel
,并按照Pointer Events的要求触发任何其他后续事件。[POINTEREVENTS]
拖放反馈必须从以下第一个可用来源生成:
从用户代理要启动拖放操作的那一刻起,直到拖放操作结束,必须抑制设备输入事件(例如鼠标和键盘事件)。
在拖动操作期间,用户直接指示的元素称为即时用户选择。(只有元素可以被用户选择;其他节点不能作为拖放目标提供。)但是,即时用户选择不一定是当前目标元素,即当前选择用于拖放操作的元素。
即时用户选择会随着用户选择不同的元素而改变(通过指向设备指向它们,或通过其他方式选择它们)。当前目标元素会随着即时用户选择的改变而改变,基于文档中的事件监听器的结果,如下所述。
当前目标元素和即时用户选择都可以为null,表示没有选择目标元素。它们也可以是其他(基于DOM的)文档或其他(非Web)程序中的元素。(例如,用户可以将文本拖动到文字处理器。)当前目标元素最初为null。
此外,还有当前拖动操作,它可以取值为"none
","copy
","link
"和"move
"。最初,其值为"none
"。用户代理会根据以下步骤更新它。
从拖动操作启动的那一刻起,用户代理必须立即并且在拖动操作持续时间内每350ms(±200ms)排队执行任务,依次执行以下步骤:
如果用户代理在下一个迭代到期时仍在执行上一个迭代(如果有),则返回本次迭代(实际上是“跳过拖放操作的丢失帧”)。
触发一个DND事件,名为drag
,在源节点上。如果此事件被取消,用户代理必须将当前拖动操作设置为"none
"
(无拖动操作)。
如果drag
事件未被取消且用户尚未结束拖放操作,请根据以下情况检查拖放操作的状态:
如果用户指示的即时用户选择与上一次迭代(或如果这是第一次迭代)不同,并且此即时用户选择与当前目标元素不同,则按以下步骤更新当前目标元素:
如果前一步导致当前目标元素发生变化,
并且前一个目标元素不为null或不是非DOM文档的一部分,则在前一个目标元素上
触发一个名为
dragleave
的DND事件,并将新的当前目标元素作为特定的
related target。
如果当前目标元素是一个DOM元素,
则在此当前目标元素
上触发一个名为
dragover
的DND事件。
如果dragover
事件未被取消,请运行以下列表中的适当步骤:
textarea
,或input
元素,其type
属性处于文本状态)或编辑主机或可编辑元素,并且拖放数据存储项目列表中有一个项,其拖放数据项类型字符串为"text/plain
",且拖放数据项种类为文本否则(如果dragover
事件被取消),根据effectAllowed
和dropEffect
属性的值设置当前拖动操作,如下表所示:
effectAllowed
|
dropEffect
|
拖动操作 |
---|---|---|
"uninitialized ","copy ","copyLink ","copyMove ",或"all "
|
"copy "
|
"copy "
|
"uninitialized ","link ","copyLink ","linkMove ",或"all "
|
"link "
|
"link "
|
"uninitialized ","move ","copyMove ","linkMove ",或"all "
|
"move "
|
"move "
|
任何其他情况 | "none "
|
否则,如果当前目标元素不是DOM元素,请使用平台特定机制确定正在执行的拖动操作(无、复制、链接或移动),并相应地设置当前拖动操作。
更新拖动反馈(例如鼠标光标)以匹配当前拖动操作,如下所示:
拖动操作 | 反馈 |
---|---|
"copy "
|
如果在此处释放,数据将被复制。 |
"link "
|
如果在此处释放,数据将被链接。 |
"move "
|
如果在此处释放,数据将被移动。 |
"none "
|
不允许操作,在此处释放将取消拖放操作。 |
否则,如果用户结束了拖放操作(例如通过释放鼠标按钮在鼠标驱动的拖放界面中),或者drag
事件被取消,则这将是最后一次迭代。运行以下步骤,然后停止拖放操作:
如果当前拖动操作是"none
"(无拖动操作),或者如果用户通过取消操作结束了拖放操作(例如按下Escape键),或者当前目标元素为null,则拖动操作失败。运行以下子步骤:
否则,拖动操作可能成功;运行以下子步骤:
设定dropped为true。
如果事件被取消,将当前拖动操作设置为
dropEffect
属性的值,该属性属于
DragEvent
对象的
dataTransfer
对象,以上状态在事件调度完成后确定。
否则,事件未被取消;执行事件的默认操作,具体取决于目标如下:
textarea
,或input
元素,其type
属性处于文本状态)或编辑主机或可编辑元素,并且拖放数据存储项目列表中有一个项,其拖放数据项类型字符串为"text/plain
",且拖放数据项种类为文本将拖放数据存储项目列表中第一个具有text/plain
类型字符串和文本种类的实际数据插入到文本控制、
编辑主机或可编辑元素中,方式与平台特定约定一致(例如在当前鼠标光标位置插入,或在字段末尾插入)。
运行以下列表中的适当步骤作为dragend
事件的默认操作:
move
",并且拖放操作的源是完全包含在编辑主机内的DOM选择删除选择。
move
",并且拖放操作的源是文本控制中的选择
用户代理应从相关文本控制中删除拖动选择。
none
"
拖动被取消。如果平台约定规定这需要向用户表示(例如通过动画将拖动选择返回到拖放操作的源),则这样做。
事件没有默认操作。
为了本步骤的目的,文本控制是textarea
元素或input
元素,其type
属性处于文本、搜索、电话、URL、电子邮件、密码或数字状态。
鼓励用户代理考虑如何响应靠近可滚动区域边缘的拖动。例如,如果用户将链接拖动到长页面的视口底部,可能需要滚动页面,以便用户可以将链接放到页面更低的位置。
此模型与涉及的节点来自哪个Document
对象无关;事件按上述描述触发,其余处理模型按上述描述运行,无论操作涉及多少文档。
本节为非规范性内容。
以下事件涉及拖放模型。
事件名称 | 目标 | 是否可取消? | 拖放数据存储模式 | dropEffect
|
默认操作 |
---|---|---|---|---|---|
dragstart
在所有当前引擎中支持。 Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
源节点 | ✓ 可取消 | 读/写模式 | "none "
|
启动拖放操作 |
drag
在所有当前引擎中支持。 Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
源节点 | ✓ 可取消 | 保护模式 | "none "
|
继续拖放操作 |
dragenter
在所有当前引擎中支持。 Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
即时用户选择或body元素 | ✓ 可取消 | 保护模式 | 基于effectAllowed 值 |
拒绝即时用户选择作为潜在目标元素 |
dragleave
在所有当前引擎中支持。 Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
上一个目标元素 | — | 保护模式 | "none "
|
无 |
dragover
在所有当前引擎中支持。 Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
当前目标元素 | ✓ 可取消 | 保护模式 | 基于effectAllowed 值 |
将当前拖放操作重置为“none” |
drop
在所有当前引擎中支持。 Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
当前目标元素 | ✓ 可取消 | 只读模式 | 当前拖放操作 | 视情况而定 |
dragend
在所有当前引擎中支持。 Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
源节点 | — | 保护模式 | 当前拖放操作 | 视情况而定 |
所有这些事件都冒泡,都是组合的,并且effectAllowed
属性始终具有dragstart
事件后的值,在dragstart
事件中默认为"uninitialized
"。
draggable
属性在所有当前引擎中支持。
所有HTML元素都可以设置draggable
内容属性。draggable
属性是一个枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
true |
true | 元素将是可拖动的。 |
false |
false | 元素将不可拖动。 |
属性的缺省值和无效值默认都是auto状态。auto状态使用用户代理的默认行为。
具有draggable
属性的元素应当也具有title
属性,以便于非视觉交互时命名元素。
element.draggable [ = value ]
如果元素是可拖动的,返回true;否则,返回false。
可以设置,以覆盖默认值并设置draggable
内容属性。
draggable
IDL属性,其值取决于以下描述的内容属性,控制元素是否可拖动。一般来说,只有文本选择是可拖动的,但draggable
IDL属性为true的元素也会变得可拖动。
如果一个元素的draggable
内容属性的状态是true,则draggable
IDL属性必须返回true。
否则,如果元素的draggable
内容属性的状态是false,则draggable
IDL属性必须返回false。
否则,元素的draggable
内容属性的状态是auto。如果该元素是img
元素、object
元素(表示图像),或具有href
内容属性的a
元素,draggable
IDL属性必须返回true;否则,draggable
IDL属性必须返回false。
如果draggable
IDL属性设置为false,draggable
内容属性必须设置为字面值"false
"。如果draggable
IDL属性设置为true,draggable
内容属性必须设置为字面值"true
"。
用户代理不得在DataTransfer
对象在dragstart
事件期间添加的数据在drop
事件之前提供给脚本,否则,如果用户将敏感信息从一个文档拖动到第二个文档,过程中经过一个恶意第三文档,恶意文档可能会拦截数据。
出于同样的原因,用户代理必须认为只有用户明确结束拖动操作时才算成功——如果任何脚本结束拖动操作,必须被认为是不成功的(取消),并且drop
事件不得触发。
用户代理应注意不要响应脚本操作启动拖放操作。例如,在鼠标和窗口环境中,如果脚本在用户按下鼠标按钮时移动窗口,用户代理不会认为这是启动拖动操作。这很重要,因为否则用户代理可能会在未经用户同意的情况下将数据从敏感来源拖动到恶意文档中。
用户代理应在拖动和放置时过滤潜在的活动(脚本)内容(例如HTML),使用已知安全功能的白名单。同样,相对URL应转换为绝对URL,以避免引用发生意外变化。本规范未规定如何执行此操作。
考虑一个恶意页面提供一些内容并让用户选择和拖放(或复制和粘贴)该内容到受害页面的contenteditable
区域。如果浏览器不确保仅拖动安全内容,选择中的潜在不安全内容(如脚本和事件处理程序),一旦放置(或粘贴)到受害站点,便会获得受害站点的权限。这将使跨站脚本攻击成为可能。
popover
属性支持所有当前引擎。
所有 HTML 元素 都可以设置 popover
内容属性。当指定时,该元素不会被渲染,直到它显示出来,此时它会在其他页面内容之上进行渲染。
popover
属性是一个全局属性,允许作者灵活地确保弹出功能可以应用于具有最相关语义的元素。
以下示例展示了如何在网站的全局导航中创建一个弹出子导航链接列表。
< ul >
< li >
< a href = ... > All Products</ a >
< button popovertarget = sub-nav >
< img src = down-arrow.png alt = "Product pages" >
</ button >
< ul popover id = sub-nav >
< li >< a href = ... > Shirts</ a >
< li >< a href = ... > Shoes</ a >
< li >< a href = ... > Hats etc.</ a >
</ ul >
</ li >
<!-- other list items and links here -->
</ ul >
在没有可访问性语义的元素上使用popover
时,例如div
元素,作者应使用适当的ARIA属性以确保弹出框的可访问性。
以下展示了创建自定义菜单弹出框的基本标记,其中由于使用了autofocus
属性,第一个菜单项将在弹出框被调用时接收到键盘焦点。使用箭头键导航菜单项和激活行为仍需要作者编写脚本。构建自定义菜单小部件的其他要求在WAI-ARIA规范中定义。
< button popovertarget = m > Actions</ button >
< div role = menu id = m popover >
< button role = menuitem tabindex = -1 autofocus > Edit</ button >
< button role = menuitem tabindex = -1 > Hide</ button >
< button role = menuitem tabindex = -1 > Delete</ button >
</ div >
弹出框可以用于显示状态消息,确认用户执行的操作。以下展示了如何在output
元素中显示一个弹出框。
< button id = submit > Submit</ button >
< p >< output >< span popover = manual ></ span ></ output ></ p >
< script >
const sBtn = document. getElementById( "submit" );
const outSpan = document. querySelector( "output [popover=manual]" );
let successMessage;
let errorMessage;
/* define logic for determining success of action
and determining the appropriate success or error
messages to use */
sBtn. addEventListener( "click" , ()=> {
if ( success ) {
outSpan. textContent = successMessage;
}
else {
outSpan. textContent = errorMessage;
}
outSpan. showPopover();
setTimeout( function () {
outSpan. hidePopover();
}, 10000 );
});
</ script >
在output
元素中插入一个弹出框元素通常会在其变得可见时让屏幕阅读器朗读内容。根据内容的复杂性或频率,这对这些辅助技术的用户来说可能是有用的,也可能是令人烦恼的。使用output
元素或其他ARIA实时区域时,请记住这一点,以确保最佳的用户体验。
The popover
attribute is an enumerated
attribute with the following keywords and states:
关键字 | 状态 | 简要描述 |
---|---|---|
auto |
auto | 打开时关闭其他弹出框;具有轻解散并响应关闭请求。 |
(空字符串) | ||
manual |
manual | 不关闭其他弹出框;不轻解散或响应关闭请求。 |
支持所有当前引擎。
popover
IDL属性必须反映popover属性,仅限于已知值。
每个HTML元素都有一个弹出框可见状态,初始为 ,具有以下潜在值:
隐藏
显示
Document
有一个弹出框指针按下目标,这是一个HTML元素或null,初始为null。
每个HTML元素都有一个弹出框调用器,这是一个HTML元素或null,初始设置为null。
每个HTML元素都有一个弹出框显示或隐藏,这是一个布尔值,初始设置为false。
每个HTML元素有一个弹出框切换任务跟踪器,这是一个切换任务跟踪器或null,初始为null。
每个HTML元素有一个弹出框关闭监视器,这是一个关闭监视器或null,初始为null。
以下属性变化步骤,给定element,localName,oldValue,value,和namespace,适用于所有HTML元素:
如果namespace不为null,则返回。
如果localName不是popover
,则返回。
如果element的弹出框可见状态处于显示状态且oldValue和value处于不同的状态,则运行隐藏弹出框算法,给定element,true,true,和false。
element.showPopover()
popover
属性处于自动状态,则这也会关闭所有其他自动弹出框,除非它们是根据顶层弹出框祖先算法的element的祖先。element.hidePopover()
display: none
来隐藏弹出框element。element.togglePopover()
支持所有当前引擎。
showPopover()
方法步骤是运行显示弹出框,给定this,true和null。
要显示弹出框,给定一个HTML元素element,一个布尔值throwExceptions,以及一个HTML元素或nullinvoker:
如果运行检查弹出框有效性,给定element,false,throwExceptions,和null的结果为false,则返回。
让document成为element的节点文档。
让nestedShow成为element的弹出框显示或隐藏。
设置element的弹出框显示或隐藏为true。
让cleanupShowingFlag成为以下步骤:
如果nestedShow为false,则将element的弹出框显示或隐藏设置为false。
如果触发名为beforetoggle
的事件的结果,使用ToggleEvent
,并将可取消
属性初始化为true,将oldState
属性初始化为"closed
",并将newState
属性初始化为"open
"在element上为false,则运行cleanupShowingFlag并返回。
如果运行检查弹出框有效性,给定element,false,throwExceptions,和document的结果为false,则运行cleanupShowingFlag并返回。
检查弹出框有效性再次被调用,因为触发beforetoggle
事件可能会断开此元素或更改其popover
属性。
让shouldRestoreFocus为false。
让originalType成为element的popover
属性的值。
让ancestor成为运行顶层弹出框祖先算法,给定element,invoker,和true的结果。
如果ancestor为null,则将ancestor设置为document。
运行隐藏所有弹出框直到,给定ancestor,false,和非nestedShow。
如果originalType不等于element的popover
属性的值,则:
如果throwExceptions为true,则抛出一个"InvalidStateError
" DOMException
。
返回。
如果运行检查弹出框有效性,给定element,false,throwExceptions,和document的结果为false,则运行cleanupShowingFlag并返回。
检查弹出框有效性再次被调用,因为运行隐藏所有弹出框直到以上可能触发beforetoggle
事件,并且事件处理程序可能会断开此元素或更改其popover
属性。
如果运行顶层自动弹出框在document上的结果为null,则将shouldRestoreFocus设置为true。
这确保了焦点仅返回到堆栈中的第一个弹出框之前的聚焦元素。
将element的之前聚焦的元素设置为null。
将元素添加到顶层,给定element。
将element的弹出框调用器设置为invoker。
运行弹出框聚焦步骤,给定element。
如果shouldRestoreFocus为true并且element的popover
属性不在无弹出框状态,则将element的之前聚焦的元素设置为originallyFocusedElement。
排队一个弹出框切换事件任务,给定element,"closed
",和"open
"。
运行cleanupShowingFlag。
要排队一个弹出框切换事件任务,给定一个元素element,一个字符串oldState,和一个字符串newState:
如果element的弹出框切换任务跟踪器不为null,则:
将oldState设置为element的弹出框切换任务跟踪器的旧状态。
从其任务队列中移除element的弹出框切换任务跟踪器的任务。
将element的弹出框切换任务跟踪器设置为null。
排队一个元素任务,给定DOM操作任务源和element,运行以下步骤:
触发一个名为toggle
的事件在element上,使用ToggleEvent
,并将oldState
属性初始化为oldState,newState
属性初始化为newState。
将element的弹出框切换任务跟踪器设置为null。
将element的弹出框切换任务跟踪器设置为一个包含刚排队的任务的结构,和旧状态设置为oldState。
在所有当前引擎中支持。
hidePopover()
方法步骤如下:
要隐藏弹出框,给定一个HTML元素 element,一个布尔值focusPreviousElement,一个 布尔值fireEvents,以及一个布尔值throwExceptions:
如果运行检查弹出框有效性,给定element, true,throwExceptions,和null的结果为false,则返回。
让document成为element的节点文档。
让nestedHide成为element的弹出框显示或隐藏。
将element的弹出框显示或隐藏设置为true。
如果nestedHide为true,则将fireEvents设置为false。
让cleanupSteps为以下步骤:
让autoPopoverListContainsElement为true,如果document的 显示 自动弹出 框列表的最后一个项目是element,否则 为false。
将element的弹出框调用器设置为null。
如果fireEvents为true:
触发一个名为beforetoggle
的事件,使用ToggleEvent
,
并初始化oldState
属性为"open
",newState
属性为"closed
",在element上。
如果autoPopoverListContainsElement为true并且document的 显示 自动弹出框列表的最后一个项目不是 element,则运行隐藏所有弹出框直到,给定 element, focusPreviousElement,以及false。
如果运行检查弹出框有效性,给定 element, true,throwExceptions,以及null的结果为false,则运行cleanupSteps并 返回。
检查弹出框有效性再次被调用,
因为
触发beforetoggle
事件可能已断开
element或更改其popover
属性。
请求从顶层移除元素,给定 element。
否则,立即从顶层移除元素,给定 element。
将element的弹出框可见状态设置为 。
如果fireEvents为true,则排队一个弹出框切换事件任务,
给定element,"open
",和"closed
"。
让previouslyFocusedElement成为element的之前聚焦的 元素。
如果previouslyFocusedElement不为null,则:
将element的之前聚焦的元素设置为null。
如果focusPreviousElement为true,并且document的文档的聚焦区域的DOM锚点是 element的阴影包含的包容性后代,则运行聚焦步骤,给定 previouslyFocusedElement;在执行此步骤时,视口不应滚动。
运行cleanupSteps。
在所有当前引擎中支持。
togglePopover(force)
方法步骤如下:
要隐藏所有弹出框直到,给定一个HTML元素或
文档
endpoint,一个布尔值
focusPreviousElement,以及一个布尔值fireEvents:
让document成为endpoint的节点文档。
让closeAllOpenPopovers成为一个执行以下步骤的算法:
如果endpoint是一个文档
,
则运行
closeAllOpenPopovers并返回。
让repeatingHide为false。
至少执行一次以下步骤:
让lastToHide为null。
让foundEndpoint为false。
对于document的每个popover的显示自动弹出框列表:
如果popover是endpoint ,则将foundEndpoint设置为 true。
否则,如果foundEndpoint为true,则将lastToHide设置为 popover并打破。
如果foundEndpoint为false,则运行closeAllOpenPopovers并 返回。
当lastToHide不为null且lastToHide的弹出框 可见状态是显示且 document的显示自动弹出框列表不为空时:
运行隐藏弹出框算法,给定 document的显示 自动弹出框列表的最后一个元素,focusPreviousElement, fireEvents,以及false。
将repeatingHide设置为true,如果document的显示 自动弹出框 列表包含endpoint且document的显示 自动弹出框 列表的最后一个元素不是endpoint,否则为false。
如果repeatingHide为true,则将fireEvents设置为false。
并且保持执行它们直到 repeatingHide为true。
隐藏所有弹出框直到 算法在几种情况下被使用,以隐藏所有在发生某些事情时不保持打开的弹出框。例如,在轻解散弹出框期间,此算法确保我们仅关闭与用户单击的节点无关的弹出框。
要找到最上层弹出框祖先,给定一个节点
newPopoverOrTopLayerElement,一个HTML元素或
null invoker,以及一个布尔值isPopover,执行以下步骤。它们返回一个HTML
元素或null。
最上层弹出框祖先算法将返回提供的弹出框或顶层 元素的最上层(在 显示 自动弹出框列表中最新的) 祖先弹出框。弹出框可以通过多种方式相互关联,形成弹出框树。存在两条路径,通过这些路径一个弹出框(称为“子”弹出框)可以有一个最上层的祖先弹出框(称为“父”弹出框):
弹出框在节点树中彼此嵌套。在这种情况下,后代弹出框是“子”,其最上层的祖先弹出框是“父”。
调用元素(例如按钮
)
具有指向弹出框的popovertarget
属性。在这种情况下,
弹出框是“子”,而调用元素所在的弹出框子树是“父”。调用者必须在弹出框中,并引用一个打开的弹出框。
在上述每个关系中,父弹出框必须严格早于 显示自动 弹出框列表中的子弹出框,否则它不会形成有效的祖先关系。这消除了非显示弹出框和自指(例如包含一个指向自身的调用元素的弹出框),并允许从连接的(可能是循环的)图构建一个格式良好的树。只有自动弹出框被考虑。
如果提供的元素是一个顶层元素,例如一个对话框
并且没有
作为弹出框显示,那么最上层弹出框祖先只会在节点树中查找第一个弹出框。
如果isPopover为true:
否则:
断言:invoker为null。
让popoverPositions成为一个空的有序映射。
让index为0。
让document成为newPopoverOrTopLayerElement的节点文档。
对于document的每个popover的显示自动弹出框列表:
设置popoverPositions[popover]为 index。
将index增加1。
如果isPopover为true,则设置 popoverPositions[newPopoverOrTopLayerElement]为index。
将index增加1。
让topmostPopoverAncestor为null。
让checkAncestor成为一个给定candidate执行以下步骤的算法:
如果candidate为null,则返回。
让candidateAncestor成为运行最近包含的打开弹出框的结果,给定 candidate。
如果candidateAncestor为null,则返回。
让candidatePosition成为 popoverPositions[candidateAncestor]。
如果topmostPopoverAncestor为null或 popoverPositions[topmostPopoverAncestor]小于 candidatePosition,则将topmostPopoverAncestor设置为 candidateAncestor。
运行checkAncestor,给定newPopoverOrTopLayerElement在平坦树中的父节点。
运行checkAncestor,给定invoker。
返回topmostPopoverAncestor。
要找到最近包含的打开弹出框,给定一个节点
node,执行以下步骤。它们返回一个HTML
元素或null。
让currentNode成为node。
当currentNode不为null时:
返回null。
要找到最上层自动弹出框,给定一个
文档
document,执行以下步骤。它们返回一个HTML元素或
null。
要执行弹出框聚焦步骤,给定一个HTML 元素subject:
如果subject具有自动聚焦
属性,则让control成为subject。
否则,让control成为自动聚焦委托,
给定subject为"other
"。
如果control为null,则返回。
运行聚焦 步骤,给定control。
将topDocument的自动聚焦处理标志设置为true。
要检查弹出框有效性,对于一个HTML元素
element,给定一个布尔值expectedToBeShowing,一个布尔值
throwExceptions,以及一个文档
或null
expectedDocument
执行以下步骤。它们抛出异常或返回一个布尔值。
如果element的popover
属性处于
无弹出框状态,则:
如果throwExceptions为true,则抛出一个
"NotSupportedError
" DOMException
。
返回false。
如果以下任意一项为真:
则返回false。
如果以下任意一项为真:
则:
如果throwExceptions为true,则抛出一个
"InvalidStateError
" DOMException
。
返回false。
返回true。
要获取显示自动弹出框列表,对于一个
文档
document:
让popovers为« »。
对于每个元素
element,在
document的顶层:
如果element的popover
属性处于自动状态并且element的弹出框
可见状态是显示,则追加element到popovers。
返回popovers。
按钮 可能具有以下内容属性:
popovertarget
popovertargetaction
如果指定,popovertarget
属性值必须是具有popover
属性的元素的ID,且在与具有popovertarget
属性的按钮
相同的树中。
popovertargetaction
属性是一个
枚举属性,具有以下关键字和状态:
关键字 | 状态 | 简要描述 |
---|---|---|
toggle
|
toggle | 显示或隐藏目标弹出框元素。 |
show
|
show | 显示目标弹出框元素。 |
hide
|
hide | 隐藏目标弹出框元素。 |
尽可能确保弹出框元素紧跟在其触发元素之后放置在DOM中。这样做将有助于确保弹出框在为使用辅助技术(例如屏幕阅读器)的用户提供逻辑编程阅读顺序时被暴露。
以下示例展示了如何使用popovertarget
属性
结合popovertargetaction
属性来显示和关闭弹出框:
< button popovertarget = "foo" popovertargetaction = "show" >
Show a popover
</ button >
< article popover = "auto" id = "foo" >
This is a popover article!
< button popovertarget = "foo" popovertargetaction = "hide" > Close</ button >
</ article >
如果未指定popovertargetaction
属性,默认操作将是切换相关的弹出框。以下示例展示了如何仅在触发按钮上指定popovertarget
属性即可在打开和关闭状态之间切换手动弹出框。手动弹出框不会响应轻触消失或关闭请求:
< input type = "button" popovertarget = "foo" value = "Toggle the popover" >
< div popover = manual id = "foo" >
This is a popover!
</ div >
interface mixin PopoverInvokerElement {
[CEReactions ] attribute Element ? popoverTargetElement ;
[CEReactions ] attribute DOMString popoverTargetAction ;
};
HTMLButtonElement/popoverTargetElement
支持所有当前引擎。
HTMLInputElement/popoverTargetElement
支持所有当前引擎。
popoverTargetElement
IDL 属性必须
反映 popovertarget
属性。
HTMLButtonElement/popoverTargetAction
支持所有当前引擎。
HTMLInputElement/popoverTargetAction
支持所有当前引擎。
popoverTargetAction
IDL
属性必须
反映 popovertargetaction
属性,仅限于已知值。
要运行给定 Node
node 的 弹出窗口目标属性激活行为:
让 popover 成为 node 的 弹出窗口目标元素。
如果 popover 为 null,则返回。
如果 node 的 popovertargetaction
属性在 显示 状态且
popover 的 弹出窗口可见状态 为 显示,则返回。
如果 node 的 popovertargetaction
属性在 隐藏 状态且
popover 的 弹出窗口可见状态 为 ,则返回。
如果 popover 的 弹出窗口可见状态 为 显示,则运行给定 popover、 true、true 和 false 的 隐藏弹出窗口算法。
否则,如果 popover 的 弹出窗口可见状态 为 ,且运行给定 popover、 false、false 和 null 的 检查弹出窗口有效性 的结果为 true, 则运行给定 popover、false 和 node 的 显示弹出窗口。
要获取给定 Node
node 的 弹出窗口目标元素,执行以下步骤。
它们返回一个 HTML 元素
或
null。
如果 node 不是一个 按钮,则返回 null。
如果 node 是 禁用的,则返回 null。
让 popoverElement 成为运行 node 的 获取 popovertarget
关联的元素 的结果。
如果 popoverElement 为 null,则返回 null。
返回 popoverElement。
“轻量关闭”意味着点击弹出窗口外部,且该弹出窗口的 popover
属性处于 auto
状态,将关闭该弹出窗口。这是除了这种弹出窗口响应关闭请求的方式之外的另一种方式。
要 轻量关闭打开的弹出窗口,给定一个 事件
event:
让 target 成为 event 的 目标。
让 document 成为 target 的 节点文档。
让 topmostPopover 成为运行 最上层自动弹出窗口 给定 document 的结果。
如果 topmostPopover 为 null,则返回。
如果 event 是一个 指针事件
且 event 的 type
是 "pointerdown
",
则:将 document 的 弹出窗口pointerdown目标 设置为运行
最上层点击的弹出窗口 给定
target 的结果。
如果 event 是一个 指针事件
且 event 的 type
是 "pointerup
",
则:
让 ancestor 成为运行 最上层点击的弹出窗口 给定 target 的结果。
如果 ancestor 是 document 的 弹出窗口pointerdown目标, 则将 sameTarget 设为 true。
将 document 的 弹出窗口pointerdown目标 设置为 null。
如果 ancestor 为 null,则将 ancestor 设置为 document。
如果 sameTarget 为 true,则运行 隐藏所有弹出窗口直到 给定 ancestor,false 和 true。
轻量关闭打开的弹出窗口 将由 指针事件规范调用,当用户在页面上点击或触摸任何地方时。
要找到 最上层点击的弹出窗口,给定一个 节点
node:
让 clickedPopover 成为运行 最近的包含打开的弹出窗口 给定 node 的结果。
让 invokerPopover 成为运行 最近的包含的目标弹出窗口 给定 node 的结果。
让 getStackPosition 成为一个算法,给定一个 HTML 元素 popover,执行以下步骤:
让 popoverList 成为 popover 的 节点文档 的 显示的自动弹出窗口列表。
如果 popover 在 popoverList 中,则返回 popoverList 中 popover 的索引 + 1。
返回 0。
如果运行 getStackPosition 给定 clickedPopover 的结果 大于运行 getStackPosition 给定 invokerPopover 的结果, 则返回 clickedPopover。
返回 invokerPopover。
要找到 最近的包含的目标弹出窗口 给定一个 节点
node:
让 currentNode 成为 node。
当 currentNode 不为 null 时:
本节描述的功能最直接适用于网页浏览器。不过,除非另有规定,本节定义的要求确实适用于所有用户代理,无论它们是否为网页浏览器。
来源是网络安全模型的基本单位。网络平台中共享来源的两个行为体被认为彼此信任并具有相同的权威。具有不同来源的行为体被认为可能是敌对的,并且在不同程度上彼此隔离。
例如,如果Example Bank的网站,托管于bank.example.com
,尝试检查Example
Charity的网站,托管于charity.example.org
的DOM,则会引发"SecurityError
"DOMException
。
一个来源是以下之一:
来源可以共享,例如在多个文档
对象之间。此外,来源通常是不可变的。只有元组来源的域可以更改,并且只能通过document.domain
API更改。
一个有效域的origin是按以下步骤计算的:
来源的序列化是通过将以下算法应用于给定的origin获得的字符串:
("https
", "xn--maraa-rta.example
", null, null)的序列化结果是"https://xn--maraa-rta.example
"。
以前还存在来源的Unicode序列化。然而,它从未被广泛采用。
两个来源,A和B,如果以下算法返回true,则称为同源:
两个来源,A和B,如果以下算法返回true,则称为同源域:
A | B | 同源 | 同源域 |
---|---|---|---|
("https ", "example.org ", null, null) |
("https ", "example.org ", null, null) |
✅ | ✅ |
("https ", "example.org ", 314, null) |
("https ", "example.org ", 420, null) |
❌ | ❌ |
("https ", "example.org ", 314, "example.org ") |
("https ", "example.org ", 420, "example.org ") |
❌ | ✅ |
("https ", "example.org ", null, null) |
("https ", "example.org ", null, "example.org ") |
✅ | ❌ |
("https ", "example.org ", null, "example.org ") |
("http ", "example.org ", null, "example.org ") |
❌ | ❌ |
scheme-and-host是一个元组,包含一个方案(一个ASCII字符串)和一个主机(一个主机)。
站点是一个不透明来源或一个scheme-and-host。
要获取站点,给定一个来源origin,请执行以下步骤:
如果origin是不透明来源,则返回origin。
如果以下算法返回true,则两个站点,A和B,称为相同站点:
站点的序列化是通过将以下算法应用于给定的站点site获得的字符串:
必须从上下文中清楚地知道序列化值是站点,而不是来源,因为两者之间不一定有语法上的区别。例如,来源("https
",
"shop.example
",
null, null)和站点("https
", "shop.example
")具有相同的序列化:" https://shop.example
"。
如果以下算法返回true,则两个来源,A和B称为无方案相同站点:
如果以下算法返回true,则两个来源,A和B称为相同站点:
与同源和同源域概念不同,对于无方案相同站点和相同站点,忽略端口和域组件。
由于在URL中解释的原因,应尽可能避免使用相同站点和无方案相同站点概念,最好使用同源检查。
鉴于wildlife.museum
、museum
和com
是公共后缀,而example.com
不是:
A | B | 无方案相同站点 | 相同站点 |
---|---|---|---|
("https ", "example.com ") |
("https ", "sub.example.com ") |
✅ | ✅ |
("https ", "example.com ") |
("https ", "sub.other.example.com ") |
✅ | ✅ |
("https ", "example.com ") |
("http ", "non-secure.example.com ") |
✅ | ❌ |
("https ", "r.wildlife.museum ") |
("https ", "sub.r.wildlife.museum ") |
✅ | ✅ |
("https ", "r.wildlife.museum ") |
("https ", "sub.other.r.wildlife.museum ") |
✅ | ✅ |
("https ", "r.wildlife.museum ") |
("https ", "other.wildlife.museum ") |
❌ | ❌ |
("https ", "r.wildlife.museum ") |
("https ", "wildlife.museum ") |
❌ | ❌ |
("https ", "wildlife.museum ") |
("https ", "wildlife.museum ") |
✅ | ✅ |
("https ", "example.com ") |
("https ", "example.com. ") |
❌ | ❌ |
document.domain [ = domain ]
返回用于安全检查的当前域。
可以设置为一个去除子域的值,以改变来源的域,以允许相同域的其他子域页面(如果它们也这样做)相互访问。这使得同一域不同主机上的页面可以同步访问彼此的DOM。
在沙盒化的iframe
中,具有不透明来源的Document
,以及没有浏览上下文的Document
,设置器会抛出"SecurityError
"异常。如果crossOriginIsolated
或originAgentCluster
返回true,设置器将不起作用。
避免使用document.domain
设置器。它削弱了同源政策提供的安全保护。当使用共享主机时,这尤其严重;例如,如果一个不受信任的第三方能够在同一IP地址但不同端口上托管一个HTTP服务器,那么在使用document.domain
设置器后,同一个主机上两个不同站点的正常同源保护将失效,因为在比较来源时端口将被忽略。
由于这些安全陷阱,此功能正在从Web平台中逐步移除。(这是一个需要多年完成的漫长过程。)
相反,请使用postMessage()
或MessageChannel
对象,以安全的方式跨来源通信。
domain
取值器步骤如下:
domain
设置器步骤如下:
如果此对象的浏览上下文为空,则抛出"SecurityError
"DOMException
。
如果此对象的活动沙盒标志集中设置了沙盒document.domain
浏览上下文标志,则抛出"SecurityError
"DOMException
。
如果effectiveDomain为空,则抛出"SecurityError
"DOMException
。
如果给定的值不是
effectiveDomain的可注册域后缀并且不等于effectiveDomain,则抛出"SecurityError
"DOMException
。
要确定hostSuffixString 是否是 originalHost的可注册域后缀或是否等于它:
如果hostSuffixString为空字符串,则返回false。
令hostSuffix为解析hostSuffixString的结果。
如果hostSuffix失败,则返回false。
如果hostSuffix不等于 originalHost,则:
返回true。
hostSuffixString | originalHost | 是否是可注册域后缀或是否等于 | 备注 |
---|---|---|---|
"0.0.0.0 " |
0.0.0.0 |
✅ | |
"0x10203 " |
0.1.2.3 |
✅ | |
"[0::1] " |
::1 |
✅ | |
"example.com " |
example.com |
✅ | |
"example.com " |
example.com. |
❌ | 尾随点是有意义的。 |
"example.com. " |
example.com |
❌ | |
"example.com " |
www.example.com |
✅ | |
"com " |
example.com |
❌ | 在撰写本文时,com 是一个公共后缀。 |
"example " |
example |
✅ | |
"compute.amazonaws.com " |
example.compute.amazonaws.com |
❌ | 在撰写本文时,*.compute.amazonaws.com 是一个公共后缀。 |
"example.compute.amazonaws.com " |
www.example.compute.amazonaws.com |
❌ | |
"amazonaws.com " |
www.example.compute.amazonaws.com |
❌ | |
"amazonaws.com " |
test.amazonaws.com |
✅ | 在撰写本文时,amazonaws.com 是一个可注册域。 |
通过安全上下文传递的Document
可以使用
`Origin-Agent-Cluster
`
HTTP响应头请求将其置于基于源的代理集群中。此头是一个结构化头,其值必须是布尔值。[STRUCTURED-FIELDS]
根据创建和初始化新的Document
对象中的处理模型,不是结构化头布尔值 true(即 `?1
`)的值将被忽略。
使用此头的结果是生成的Document
的代理集群键是其源,而不是相应的站点。在可观察的效果方面,这意味着尝试使用document.domain
放宽同源限制将无效,无法将WebAssembly.Module
对象发送到跨源Document
(即使它们是同站点)。在幕后,这种隔离可以允许用户代理更有效地分配与代理集群对应的特定实现资源,例如进程或线程。
请注意,在浏览上下文组内,`Origin-Agent-Cluster
`头绝不会导致同源Document
对象最终出现在不同的代理集群中,即使一个发送了头而另一个没有。这是通过历史代理集群键映射来防止的。
这意味着如果之前加载的同源页面在同一浏览上下文组中省略了该头,则即使设置了该头,originAgentCluster
getter 也可以返回 false。同样,即使未设置该头,它也可以返回 true。
originAgentCluster
getter步骤是返回周围代理的代理集群的是否以来源为键。
具有不透明来源的Document
可以无条件地被认为是基于来源的;对于它们来说,头没有影响,originAgentCluster
getter 将始终返回 true。
同样,其代理集群的跨源隔离模式不为 "none
"
的Document
会自动基于来源。`Origin-Agent-Cluster
`
头可能对实现资源分配提供额外
的提示,因为用于实现跨源隔离的 `跨源打开者策略
`
和 `跨源嵌入者策略
`
头更多的是确保同一地址空间中的所有内容都选择进入。但是,添加它不会对作者代码产生额外的可观察效果。
一个跨源打开者策略值允许在顶级浏览上下文中导航到的文档强制创建一个新的顶级浏览上下文及其对应的组。可能的值是:
unsafe-none
"same-origin-allow-popups
"same-origin
"其行为与 "same-origin-allow-popups
"
相同,另外任何创建的辅助浏览上下文需要包含也具有相同跨源打开者策略的同源文档,否则它将对打开者关闭。
same-origin-plus-COEP
"其行为与 "same-origin
"
相同,另外它将设置(新的)顶级浏览上下文的组的跨源隔离模式为 "逻辑隔离
"
或 "具体隔离
"。
"same-origin-plus-COEP
"
不能通过 `跨源打开者策略
`
头直接设置,而是通过同时设置
`Cross-Origin-Opener-Policy: same-origin
`
和 `Cross-Origin-Embedder-Policy
`
头,其值与跨源隔离兼容。
一个跨源打开者策略由以下内容组成:
一个值,它是一个跨源打开者策略值,初始值为 "unsafe-none
"。
一个报告端点,它是字符串或null,初始值为null。
一个仅报告值,它是一个跨源打开者策略值,初始值为 "unsafe-none
"。
一个仅报告报告端点,它是字符串或null,初始值为null。
要匹配跨源打开者策略值,给定一个跨源打开者策略值 A,一个源 originA,一个跨源打开者策略值 B,以及一个源 originB,按以下步骤操作:
如果 A 是
"unsafe-none
"
且 B 也是 "unsafe-none
",则返回true。
如果 A 是 "unsafe-none
"
或 B 是 "unsafe-none
",则返回false。
如果 A 是 B 且 originA 与 originB 是同源,则返回true。
返回false。
Headers/Cross-Origin-Opener-Policy
支持所有当前引擎。
一个文档
的打开者策略源自于
`Cross-Origin-Opener-Policy
`
和
`Cross-Origin-Opener-Policy-Report-Only
` HTTP 响应头。这些头部是结构化头部,其值必须是标记。[STRUCTURED-FIELDS]
有效的标记值是打开者策略值。标记还可以附加参数;其中,"report-to
" 参数可以有一个有效的 URL
字符串,用于标识适当的报告端点。[REPORTING]
根据下面描述的处理模型,如果此头部包含无效值,用户代理将忽略此头部。同样,如果该值无法解析为标记,用户代理也将忽略此头部。
要在给定一个响应 response 和一个环境 reservedEnvironment 的情况下获取跨源打开者策略,请按以下步骤操作:
让 policy 成为一个新的跨源打开者策略。
如果 reservedEnvironment 是一个非安全上下文,则返回 policy。
让 parsedItem 成为获取结构化字段值的结果,给定 `Cross-Origin-Opener-Policy
`
和 "item
" 从 response 的头部列表。
如果 parsedItem 不为 null,则:
如果 parsedItem[0] 是 "same-origin
",则:
让 coep 成为获取跨源嵌入者策略的结果,来自 response 和 reservedEnvironment。
如果 coep 的值与跨源隔离兼容,则将 policy 的值设置为
"same-origin-plus-COEP
"。
否则,将 policy 的值设置为
"same-origin
"。
如果 parsedItem[0] 是 "same-origin-allow-popups
",则将
policy 的值设置为 "same-origin-allow-popups
"。
如果 parsedItem[1]["report-to
"]存在,并且它是一个字符串,则将 policy 的报告端点设置为
parsedItem[1]["report-to
"]。
将 parsedItem 设置为获取结构化字段值的结果,给定 `Cross-Origin-Opener-Policy-Report-Only
`
和 "item
" 从 response 的头部列表。
如果 parsedItem 不为 null,则:
如果 parsedItem[0] 是 "same-origin
",则:
让 coep 成为获取跨源嵌入者策略的结果,来自 response 和 reservedEnvironment。
如果 coep 的值与跨源隔离兼容或 coep 的仅报告值与跨源隔离兼容,则将 policy 的仅报告值设置为
"same-origin-plus-COEP
"。
仅报告 COOP 还考虑仅报告 COEP 来分配特殊的 "same-origin-plus-COEP
"
值。这使开发者在部署 COOP 和 COEP 的顺序上有更多的自由。
否则,将 policy 的仅报告值设置为 "same-origin
"。
如果 parsedItem[0] 是 "same-origin-allow-popups
",则将
policy 的仅报告值设置为 "same-origin-allow-popups
"。
如果 parsedItem[1]["report-to
"]存在并且它是一个字符串,则将 policy 的仅报告端点设置为 parsedItem[1]["report-to
"]。
返回 policy。
为了检查 COOP 值是否需要浏览上下文组切换,给定一个布尔值isInitialAboutBlank,两个源 responseOrigin和activeDocumentNavigationOrigin,以及两个跨域 opener 策略值 responseCOOPValue和 activeDocumentCOOPValue:
如果匹配activeDocumentCOOPValue、activeDocumentNavigationOrigin、 responseCOOPValue和responseOrigin的结果为 true,则返回 false。
如果以下所有条件都为真:
isInitialAboutBlank;
activeDocumentCOOPValue的值
为"same-origin-allow-popups
";
且
responseCOOPValue为"unsafe-none
",
则返回 false。
返回 true。
为了检查强制执行仅报告 COOP 是否需要浏览上下文组切换,给定一个布尔值 isInitialAboutBlank,两个源 responseOrigin、activeDocumentNavigationOrigin,以及两个跨域 opener 策略 responseCOOP 和activeDocumentCOOP:
如果检查 COOP 值是否需要浏览上下文组切换的结果为 false, 给定isInitialAboutBlank、responseOrigin、 activeDocumentNavigationOrigin、responseCOOP的仅报告值和 activeDocumentCOOPReportOnly的仅报告值, 则返回 false。
匹配仅报告策略允许网站在其所有页面上指定相同的仅报告跨域 opener 策略,并且不会因这些页面之间的导航收到违规报告。
如果检查 COOP 值是否需要浏览上下文组切换的结果为 true, 给定isInitialAboutBlank、responseOrigin、 activeDocumentNavigationOrigin、responseCOOP的值和 activeDocumentCOOPReportOnly的仅报告值, 则返回 true。
如果检查 COOP 值是否需要浏览上下文组切换的结果为 true, 给定isInitialAboutBlank、responseOrigin、 activeDocumentNavigationOrigin、responseCOOP的仅报告值和 activeDocumentCOOPReportOnly的值, 则返回 true。
返回 false。
跨域 opener 策略执行结果是一个结构体,包含以下项目:
一个布尔值需要浏览上下文组切换,初始值为 false。
一个布尔值仅因报告需要浏览上下文组切换,初始值为 false。
一个URL url。
一个源 origin。
一个跨域 opener 策略 跨域 opener 策略。
一个布尔值当前上下文是导航源,初始值为 false。
为了执行响应的跨域 opener 策略,给定一个浏览上下文 browsingContext,一个URL responseURL,一个源 responseOrigin,一个跨域 opener 策略 responseCOOP,一个跨域 opener 策略执行结果 currentCOOPEnforcementResult,以及一个引用 referrer:
令newCOOPEnforcementResult为一个新的跨域 opener 策略执行结果,其中包含
令isInitialAboutBlank为browsingContext的活动文档的是否初始about:blank
。
如果isInitialAboutBlank为 true 且browsingContext的初始 URL为 null,则将 browsingContext的初始 URL设置为 responseURL。
如果检查 COOP 值是否需要浏览上下文组切换的结果为 true, 给定isInitialAboutBlank、currentCOOPEnforcementResult的跨域 opener 策略的值、 currentCOOPEnforcementResult的源、 responseCOOP的值和 responseOrigin,则:
将newCOOPEnforcementResult的需要浏览上下文组切换设置为 true。
如果browsingContext的组的浏览上下文集的大小大于 1,则:
队列一个违规报告用于在导航到
COOP 响应时进行浏览上下文组切换,包括responseCOOP、
"enforce
"、responseURL、
currentCOOPEnforcementResult的url、
currentCOOPEnforcementResult的源、
responseOrigin和
referrer。
队列一个违规报告用于在离开
COOP 响应时进行浏览上下文组切换,包括
currentCOOPEnforcementResult的跨域
opener 策略、"enforce
"、
currentCOOPEnforcementResult的url、
responseURL、currentCOOPEnforcementResult的源、
responseOrigin和
currentCOOPEnforcementResult的当前上下文是导航源。
如果检查强制执行仅报告 COOP 是否需要浏览上下文组切换的结果为 true, 给定isInitialAboutBlank、responseOrigin、 currentCOOPEnforcementResult的源、 responseCOOP和currentCOOPEnforcementResult的跨域 opener 策略, 则:
将result的仅因报告需要浏览上下文组切换设置为 true。
如果browsingContext的组的浏览上下文集的大小大于 1,则:
队列一个违规报告用于在导航到
COOP 响应时进行浏览上下文组切换,包括responseCOOP、
"reporting
"、responseURL、
currentCOOPEnforcementResult的url、
currentCOOPEnforcementResult的源、
responseOrigin和
referrer。
队列一个违规报告用于在离开
COOP 响应时进行浏览上下文组切换,包括
currentCOOPEnforcementResult的跨域
opener 策略、"reporting
"、
currentCOOPEnforcementResult的url、
responseURL、currentCOOPEnforcementResult的源、
responseOrigin和
currentCOOPEnforcementResult的当前上下文是导航源。
返回newCOOPEnforcementResult。
为了获取用于导航响应的浏览上下文,给定一个浏览上下文 browsingContext,一个 沙箱标志集 sandboxFlags,一个跨域 opener 策略 navigationCOOP,以及一个跨域 opener 策略执行结果 coopEnforcementResult:
如果browsingContext不是一个顶级浏览上下文,则 返回browsingContext。
如果coopEnforcementResult的需要浏览上下文组切换为 false,则:
如果coopEnforcementResult的仅因报告需要浏览上下文组切换为 true,则将browsing context的虚拟浏览上下文组 ID设置为一个新的唯一标识符。
返回browsingContext。
令newBrowsingContext为创建一个新的顶级浏览上下文和文档的第一个返回值。
在这种情况下,我们将执行浏览上下文组交换。
browsingContext将不会被我们即将创建的新文档
使用。
如果它没有被其他文档
使用(例如后退/前进缓存中的文档),则用户代理可能在此时销毁它。
如果navigationCOOP的值为
"same-origin-plus-COEP
",
则将
newBrowsingContext的组的跨域隔离模式设置为"逻辑
"
或"具体
"。
选择由
实现定义。
如果sandboxFlags不为空,则:
返回newBrowsingContext。
访问者-被访问者关系是一个枚举,用于描述发生访问的两个浏览上下文之间的关系。它可以取以下值:
要检查两个浏览上下文之间的访问是否应被报告,给定两个浏览上下文accessor和accessed、一个JavaScript属性名P,以及一个环境设置对象environment:
如果P不是一个跨域可访问窗口属性名,则返回。
令accessorInclusiveAncestorOrigins为通过获取accessor的每个活动文档的源而获得的列表。
令accessedInclusiveAncestorOrigins为通过获取accessed的每个活动文档的源而获得的列表。
如果accessorInclusiveAncestorOrigins中的任何一个与accessorTopDocument的源不是同源,或者accessedInclusiveAncestorOrigins中的任何一个与accessedTopDocument的源不是同源,则返回。
这避免了向具有跨域打开者策略报告的顶级框架泄露跨域iframe的信息。
如果accessor的顶级浏览上下文的虚拟浏览上下文组ID是accessed的顶级浏览上下文的虚拟浏览上下文组ID,则返回。
令accessorAccessedRelationship为值为无 的新的访问者-被访问者关系。
如果accessed的顶级浏览上下文的打开者浏览上下文是accessor或是accessor的一个祖先,则将accessorAccessedRelationship设置为访问者是打开者。
如果accessor的顶级浏览上下文的打开者浏览上下文是accessed或是accessed的一个祖先,则将accessorAccessedRelationship设置为访问者是被打开者。
为访问排队违规报告,给定accessorAccessedRelationship、accessorTopDocument的打开者策略、accessedTopDocument的打开者策略、accessor的活动文档的URL、accessed的活动文档的URL、accessor的顶级浏览上下文的初始URL、accessed的顶级浏览上下文的初始URL、accessor的活动文档的源、accessed的活动文档的源、accessor的顶级浏览上下文的创建时的打开者源、accessed的顶级浏览上下文的创建时的打开者源、accessorTopDocument的引用、accessedTopDocument的引用、P和environment。
要对要发送报告的URL进行清理,给定一个URLurl:
要在导航到COOP响应时为浏览上下文组切换排队违规报告,给定一个跨域打开者策略coop、一个字符串disposition、一个URLcoopURL、一个URLpreviousResponseURL、两个源coopOrigin和previousResponseOrigin,以及一个引用referrer:
如果coop的报告端点为空,则返回。
令coopValue为coop的值。
如果disposition为"reporting
",则将coopValue设置为coop的仅报告值。
令serializedReferrer为空字符串。
令body为一个包含以下属性的新对象:
键 | 值 |
---|---|
disposition | disposition |
effectivePolicy | coopValue |
previousResponseURL | 如果coopOrigin和previousResponseOrigin是同源,这是previousResponseURL的清理,否则为null。 |
referrer | serializedReferrer |
type | "navigation-to-response " |
要在从COOP响应导航时为浏览上下文组切换排队违规报告,给定一个跨域打开者策略coop、一个字符串disposition、一个URLcoopURL、一个URLnextResponseURL、两个源coopOrigin和nextResponseOrigin,以及一个布尔值isCOOPResponseNavigationSource:
如果coop的报告端点为空,则返回。
令coopValue为coop的值。
如果disposition为"reporting
",则将coopValue设置为coop的仅报告值。
令body为一个包含以下属性的新对象:
键 | 值 |
---|---|
disposition | disposition |
effectivePolicy | coopValue |
nextResponseURL | 如果coopOrigin和nextResponseOrigin是同源,或者isCOOPResponseNavigationSource为true,则这是nextResponseURL的清理,否则为null。 |
type | "navigation-from-response " |
要为访问排队违规报告,给定一个访问者-被访问者关系accessorAccessedRelationship、两个跨域打开者策略accessorCOOP和accessedCOOP、四个URLaccessorURL、accessedURL、accessorInitialURL、accessedInitialURL、四个源accessorOrigin、accessedOrigin、accessorCreatorOrigin和accessedCreatorOrigin、两个引用accessorReferrer和accessedReferrer、一个字符串propertyName,以及一个环境设置对象environment:
如果coop的报告端点为空,则返回。
令coopValue为coop的值。
如果disposition为"reporting
",则将coopValue设置为coop的仅报告值。
如果accessorAccessedRelationship是访问者是打开者:
为访问已打开的窗口排队违规报告,给定accessorCOOP、accessorURL、accessedURL、accessedInitialURL、accessorOrigin、accessedOrigin、accessedCreatorOrigin、propertyName和environment。
为从打开者的访问排队违规报告,给定accessedCOOP、accessedURL、accessorURL、accessedOrigin、accessorOrigin、propertyName和accessedReferrer。
否则,如果accessorAccessedRelationship是访问者是被打开者:
为访问打开者排队违规报告,给定accessorCOOP、accessorURL、accessedURL、accessorOrigin、accessedOrigin、propertyName、accessorReferrer和environment。
为从已打开窗口的访问排队违规报告,给定accessedCOOP、accessedURL、accessorURL、accessorInitialURL、accessedOrigin、accessorOrigin、accessorCreatorOrigin和propertyName。
否则:
为访问其他窗口排队违规报告,给定accessorCOOP、accessorURL、accessedURL、accessorOrigin、accessedOrigin、propertyName和environment。
为从其他窗口的访问排队违规报告,给定accessedCOOP、accessedURL、accessorURL、accessedOrigin、accessorOrigin和propertyName。
要为访问打开者排队违规报告,给定一个跨域打开者策略coop、两个URLcoopURL和openerURL、两个源coopOrigin和openerOrigin、一个字符串propertyName、一个引用referrer,以及一个环境设置对象environment:
令sourceFile、lineNumber和columnNumber为触发此报告的相关脚本URL和问题位置。
令serializedReferrer为空字符串。
令body为一个包含以下属性的新对象:
键 | 值 |
---|---|
disposition | "reporting " |
effectivePolicy | coop的仅报告值 |
property | propertyName |
openerURL | 如果coopOrigin和openerOrigin是同源,这是openerURL的清理,否则为null。 |
referrer | serializedReferrer |
sourceFile | sourceFile |
lineNumber | lineNumber |
columnNumber | columnNumber |
type | "access-to-opener " |
要为访问已打开的窗口排队违规报告,给定一个跨域打开者策略coop、三个URLcoopURL、openedWindowURL和initialWindowURL、三个源coopOrigin、openedWindowOrigin和openerInitialOrigin、一个字符串propertyName,以及一个环境设置对象environment:
令sourceFile、lineNumber和columnNumber为触发此报告的相关脚本URL和问题位置。
令body为一个包含以下属性的新对象:
键 | 值 |
---|---|
disposition | "reporting " |
effectivePolicy | coop的仅报告值 |
property | propertyName |
openedWindowURL | 如果coopOrigin和openedWindowOrigin是同源,这是openedWindowURL的清理,否则为null。 |
openedWindowInitialURL | 如果coopOrigin和openerInitialOrigin是同源,这是initialWindowURL的清理,否则为null。 |
sourceFile | sourceFile |
lineNumber | lineNumber |
columnNumber | columnNumber |
type | "access-to-opener " |
要为访问其他窗口排队违规报告,给定一个跨域打开者策略coop、两个URLcoopURL和otherURL、两个源coopOrigin和otherOrigin、一个字符串propertyName,以及一个环境设置对象environment:
令sourceFile、lineNumber和columnNumber为触发此报告的相关脚本URL和问题位置。
令body为一个包含以下属性的新对象:
键 | 值 |
---|---|
disposition | "reporting " |
effectivePolicy | coop的仅报告值 |
property | propertyName |
otherURL | 如果coopOrigin和otherOrigin是同源,这是otherURL的清理,否则为null。 |
sourceFile | sourceFile |
lineNumber | lineNumber |
columnNumber | columnNumber |
type | "access-to-opener " |
要为从打开者的访问排队违规报告,给定一个跨域打开者策略coop、两个URLcoopURL和openerURL、两个源coopOrigin和openerOrigin、一个字符串propertyName,以及一个引用referrer:
如果coop的报告端点为空,则返回。
令serializedReferrer为空字符串。
令body为一个包含以下属性的新对象:
键 | 值 |
---|---|
disposition | "reporting " |
effectivePolicy | coop的仅报告值 |
property | propertyName |
openerURL | 如果coopOrigin和openerOrigin是同源,这是openerURL的清理,否则为null。 |
referrer | serializedReferrer |
type | "access-to-opener " |
要为从已打开窗口的访问排队违规报告,给定一个跨域打开者策略coop、三个URLcoopURL、openedWindowURL和initialWindowURL、三个源coopOrigin、openedWindowOrigin和openerInitialOrigin,以及一个字符串propertyName:
如果coop的报告端点为空,则返回。
令body为一个包含以下属性的新对象:
键 | 值 |
---|---|
disposition | "reporting " |
effectivePolicy | coopValue |
property | coop的仅报告值 |
openedWindowURL | 如果coopOrigin和openedWindowOrigin是同源,这是openedWindowURL的清理,否则为null。 |
openedWindowInitialURL | 如果coopOrigin和openerInitialOrigin是同源,这是initialWindowURL的清理,否则为 null。 |
type | "access-to-opener " |
要为从其他窗口的访问排队违规报告,给定一个跨域打开者策略coop、两个URLcoopURL和otherURL、两个源coopOrigin和otherOrigin、以及一个字符串propertyName:
如果coop的报告端点为空,则返回。
令body为一个包含以下属性的新对象:
键 | 值 |
---|---|
disposition | "reporting " |
effectivePolicy | coop的仅报告值 |
property | propertyName |
otherURL | 如果coopOrigin和otherOrigin是同源,这是otherURL的清理,否则为null。 |
sourceFile | sourceFile |
lineNumber | lineNumber |
columnNumber | columnNumber |
type | "access-to-opener " |
Headers/Cross-Origin-Embedder-Policy
支持所有当前的引擎。
嵌入策略值是三个字符串之一,用于控制在没有资源所有者明确许可的情况下获取跨域资源。
unsafe-none
"
require-corp
"credentialless
"使用此值时,获取跨域无CORS资源时不包含凭证。作为交换,不需要明确的`跨域资源策略
`
头。其他带凭证的请求需要服务器通过CORS
协议或`跨域资源策略
`
头明确许可。
嵌入策略值是与跨域隔离兼容的,如果它是"credentialless
"
或"require-corp
"。
嵌入策略包括:
一个值,即嵌入策略值,初始为"unsafe-none
"。
一个报告端点字符串,初始为空字符串。
一个仅报告值,即嵌入策略值,初始为"unsafe-none
"。
一个仅报告报告端点字符串,初始为空字符串。
"coep
"报告类型是一个报告类型,其值
为"coep
"。它对可见ReportingObserver
。
`Cross-Origin-Embedder-Policy
`和`Cross-Origin-Embedder-Policy-Report-Only
` HTTP响应标头允许服务器为一个嵌入策略声明环境设置对象。这些标头是结构化标头,其值必须是标记。[STRUCTURED-FIELDS]
有效的标记值是嵌入策略值。标记也可能附有参数;其中,“report-to
”参数可以有一个有效的URL字符串,用于标识适当的报告端点。[REPORTING]
处理模型在存在无法解析为标记的标头时会默认开放(默认为“unsafe-none
”)。这包括由多个实例组合在一起而意外创建的列表:Cross-Origin-Embedder-Policy
标头出现在给定响应中:
`Cross-Origin-Embedder-Policy `
|
最终嵌入策略值 |
---|---|
没有传递标头 | "unsafe-none "
|
`require-corp ` |
"require-corp "
|
`unknown-value ` |
"unsafe-none "
|
`require-corp, unknown-value ` |
"unsafe-none "
|
`unknown-value, unknown-value ` |
"unsafe-none "
|
`unknown-value, require-corp ` |
"unsafe-none "
|
`require-corp, require-corp ` |
"unsafe-none "
|
要从响应response和一个环境environment获取嵌入策略:
让policy成为一个新的嵌入策略。
如果environment是一个非安全上下文,那么返回policy。
让parsedItem成为获取结构化字段值的结果,其中`Cross-Origin-Embedder-Policy
`和"item
"来自response的标头列表。
如果parsedItem非空且parsedItem[0]是与跨域隔离兼容:
将parsedItem设置为获取结构化字段值的结果,其中`Cross-Origin-Embedder-Policy-Report-Only
`和"item
"来自response的标头列表。
如果parsedItem非空且parsedItem[0]是与跨域隔离兼容:
返回policy。
要检查导航响应是否遵循其嵌入策略,给定一个响应response,一个可导航的对象navigable,以及一个嵌入策略responsePolicy:
如果navigable不是一个子可导航对象,则返回true。
如果parentPolicy的仅报告值与跨域隔离兼容,而responsePolicy的值不兼容,则队列一个跨域嵌入策略继承违规,参数为response,"navigation
",parentPolicy的仅报告端点,"reporting
",和navigable的容器文档的相关设置对象。
队列一个跨域嵌入策略继承违规,参数为response,"navigation
",parentPolicy的报告端点,"enforce
",和navigable的容器文档的相关设置对象。
返回false。
要检查全局对象的嵌入策略,给定一个WorkerGlobalScope
workerGlobalScope,一个环境设置对象owner,以及一个响应response:
如果workerGlobalScope不是一个DedicatedWorkerGlobalScope
对象,则返回true。
让policy成为workerGlobalScope的嵌入策略。
如果ownerPolicy的仅报告值与跨域隔离兼容,而policy的值不兼容,则队列一个跨域嵌入策略继承违规,参数为response,"worker initialization
",ownerPolicy的仅报告端点,"reporting
"
,和owner。
队列一个跨域嵌入策略继承违规,参数为response,"worker initialization
",ownerPolicy的报告端点,"enforce
",和owner。
返回false。
要队列一个跨域嵌入策略继承违规,给定一个响应response,一个字符串type,一个字符串endpoint,一个字符串disposition,以及一个环境设置对象settings:
让serialized成为序列化一个响应URL以用于报告的结果,参数为response。
让body成为一个包含以下属性的新对象:
key | value |
---|---|
type | type |
blockedURL | serialized |
disposition | disposition |
队列 body作为settings的"coep
"报告类型,发送到endpoint。
沙盒标志集是一个包含以下零个或多个标志的集合,这些标志用于限制可能不受信任的资源的能力:
此标志防止内容导航到除沙盒浏览上下文自身之外的浏览上下文(或进一步嵌套在其内部的浏览上下文),辅助浏览上下文(受下面定义的沙盒辅助导航浏览上下文标志保护),以及顶级浏览上下文(受下面定义的无用户激活的沙盒顶级导航浏览上下文标志和有用户激活的沙盒顶级导航浏览上下文标志保护)。
如果没有设置沙盒辅助导航浏览上下文标志,则在某些情况下,这些限制仍然允许弹出窗口(新的顶级浏览上下文)被打开。这些浏览上下文总是有一个允许的沙盒导航器,在创建浏览上下文时设置,允许创建它们的浏览上下文实际导航它们。(否则,沙盒导航浏览上下文标志即使它们被打开也会阻止它们被导航。)
此标志防止内容创建新的辅助浏览上下文,例如使用target
属性或window.open()
方法。
此标志防止内容导航其顶级浏览上下文并防止内容关闭其顶级浏览上下文。仅当沙盒浏览上下文的活动窗口没有短暂激活时才会参考此标志。
当无用户激活的沙盒顶级导航浏览上下文标志未设置时,内容可以导航其顶级浏览上下文,但其他浏览上下文仍然受沙盒导航浏览上下文标志和可能的沙盒辅助导航浏览上下文标志保护。
此标志防止内容导航其顶级浏览上下文并防止内容关闭其顶级浏览上下文。仅当沙盒浏览上下文的活动窗口有短暂激活时才会参考此标志。
与无用户激活的沙盒顶级导航浏览上下文标志相同,此标志仅影响顶级浏览上下文;如果未设置,其他浏览上下文可能仍受其他标志保护。
此标志将内容强制进入不透明来源,从而防止其访问来自同一来源的其他内容。
此标志还防止脚本读取或写入document.cookie
IDL属性,并阻止访问localStorage
。
此标志阻止表单提交。
此标志禁用指针锁定API。[POINTERLOCK]
此标志阻止脚本执行。
document.domain
浏览上下文标志此标志防止内容使用document.domain
设置器。
此标志防止内容使用以下任何功能来生成模态对话框:
此标志禁用锁定屏幕方向的能力。[SCREENORIENTATION]
此标志禁用演示API。[PRESENTATION]
当用户代理解析沙盒指令时,给定一个字符串input,一个沙盒标志集output,它必须运行以下步骤:
在ASCII空白字符上拆分input,以获得tokens。
让output为空。
将以下标志添加到output中:
沙盒辅助导航浏览上下文标志,除非tokens包含allow-popups
关键字。
无用户激活的沙盒顶级导航浏览上下文标志,除非tokens包含allow-top-navigation
关键字。
有用户激活的沙盒顶级导航浏览上下文标志,除非tokens包含allow-top-navigation-by-user-activation
关键字或allow-top-navigation
关键字。
这意味着如果存在allow-top-navigation
,则allow-top-navigation-by-user-activation
关键字将不起作用。因此,指定两者是文档符合性错误。
沙盒来源浏览上下文标志,除非tokens包含allow-same-origin
关键字。
allow-same-origin
关键字适用于两种情况。
首先,它可以用于允许来自同一站点的内容被沙盒以禁用脚本,但仍允许访问沙盒内容的DOM。
其次,它可以用于嵌入来自第三方网站的内容,沙盒以防止该网站打开弹出窗口等,而不阻止嵌入页面与其原始站点进行通信,使用数据库API存储数据等。
沙盒表单浏览上下文标志,除非tokens包含allow-forms
关键字。
沙盒指针锁定浏览上下文标志,除非tokens包含allow-pointer-lock
关键字。
沙盒脚本浏览上下文标志,除非tokens包含allow-scripts
关键字。
沙盒自动功能浏览上下文标志,除非tokens包含allow-scripts
关键字(如上所述)。
此标志由与脚本相同的关键字放松,因为当脚本启用时,这些功能也可以简单地实现,并且当沙盒时强制作者使用脚本来实现这些功能而不是允许他们使用声明性功能是不幸的。
沙盒传播到辅助浏览上下文标志,除非tokens包含allow-popups-to-escape-sandbox
关键字。
沙盒模态标志,除非tokens包含allow-modals
关键字。
沙盒方向锁定浏览上下文标志,除非tokens包含allow-orientation-lock
关键字。
沙盒演示浏览上下文标志,除非tokens包含allow-presentation
关键字。
沙盒下载浏览上下文标志,除非tokens包含allow-downloads
关键字。
沙盒自定义协议导航浏览上下文标志,除非tokens包含allow-top-navigation-to-custom-protocols
关键字、allow-popups
关键字,或allow-top-navigation
关键字。
每个顶级浏览上下文都有一个弹出沙盒标志集,它是一个沙盒标志集。当创建浏览上下 文时,其弹出沙盒标志集必须为空。它由选择可导航规则和获得导航响应的浏览上下文算法填充。
每个iframe
元素都有一个iframe
沙盒标志集,它是一个沙盒标志集。iframe
沙盒标志集中的哪些标志在任何特定时间设置,取决于iframe
元素的sandbox
属性。
每个Document
都有一个活动沙盒标志集,它是一个沙盒标志集。当创建Document
时,其活动沙盒标志集必须为空。它由导航算法填充。
每个CSP列表cspList都有CSP派生沙盒标志,它是一个沙盒标志集。它是以下算法的返回值:
让directives为空的有序集。
对每个cspList中的策略:
如果directives为空,则返回一个空的沙盒标志集。
让directive为directives[directives的大小- 1]。
返回解析沙盒指令directive的结果。
要确定创建沙盒标志对于浏览上下文browsing context,给定null或一个元素embedder,返回以下联合中存在的标志:
如果embedder为null,则:在browsing context的弹出沙盒标志集上设置的标志。
如果embedder是一个元素,则:在embedder的iframe
沙盒标志集上设置的标志。
策略容器是包含适用于Document
、WorkerGlobalScope
或WorkletGlobalScope
的策略的结构。它具有以下项目:
将其他策略移入策略容器中。
要克隆一个策略容器,给定一个策略容器policyContainer:
要确定一个URLurl是否需要将策略容器存储在历史记录中:
要从提取响应创建策略容器,给定一个响应response和一个环境或null的environment:
如果response的URL的scheme是"blob
",则返回response的URL的blob URL条目的环境的策略容器的克隆。
让result为一个新的策略容器。
将result的CSP列表设置为给定response的解析响应的内容安全策略的结果。
如果environment非null,则将result的嵌入策略设置为给定response和environment的获取嵌入策略的结果。否则,将其设置为"unsafe-none
"。
将result的引用策略设置为给定response的解析`Referrer-Policy
`头的结果。[REFERRERPOLICY]
返回result。
要确定导航参数策略容器,给定一个responseURL和四个策略容器或null的historyPolicyContainer、initiatorPolicyContainer、parentPolicyContainer和responsePolicyContainer:
如果historyPolicyContainer不为null,则:
断言:responseURL需要将策略容器存储在历史记录中。
返回historyPolicyContainer的克隆。
如果responseURL是about:srcdoc
,则:
如果responseURL是本地的且initiatorPolicyContainer不为null,则返回initiatorPolicyContainer的克隆。
如果responsePolicyContainer不为null,则返回responsePolicyContainer。
返回一个新的策略容器。
要初始化worker global scope的策略容器,给定一个WorkerGlobalScope
workerGlobalScope、一个响应response和一个环境environment:
否则,将workerGlobalScope的策略容器设置为给定response和environment的从提取响应创建策略容器的结果。
Window
、WindowProxy
和 Location
对象的安全基础设施尽管通常情况下对象不能跨源访问,但如果没有一些网络依赖的遗留例外情况,网络平台就不会保持其本质。
本节使用JavaScript规范中的术语和排版约定。[JAVASCRIPT]
当执行安全检查时,使用platformObject、identifier和type运行以下步骤:
对于platformObject的每个e,从CrossOriginProperties:
如果SameValue(e.[[Property]], identifier)为true,则:
如果type是"method
"并且e既没有[[NeedsGet]]也没有[[NeedsSet]],则返回。
否则,如果type是"getter
"并且e.[[NeedsGet]]为true,则返回。
否则,如果type是"setter
"并且e.[[NeedsSet]]为true,则返回。
如果IsPlatformObjectSameOrigin(platformObject)为false,则抛出"SecurityError
"DOMException
。
Window
和Location
对象都具有[[CrossOriginPropertyDescriptorMap]]内部槽,其值最初为空映射。
[[CrossOriginPropertyDescriptorMap]]内部槽包含一个映射,映射的键是(currentGlobal,objectGlobal,propertyKey)元组,值是属性描述符,作为currentGlobal检查来自objectGlobal的Window
或Location
对象时对脚本可见内容的记忆化。它由CrossOriginGetOwnPropertyHelper懒惰地填充,并在以后的查找中咨询它。
用户代理应该允许映射中保存的值连同其对应的键一起被垃圾收集,只要没有任何东西引用该值的任何部分。也就是说,只要垃圾收集是不可观察的。
例如,使用const href = Object.getOwnPropertyDescriptor(crossOriginLocation, "href").set
,映射中的值及其对应的键不能被垃圾收集,因为这将是可观察的。
用户代理可以进行优化,在设置document.domain
时从映射中删除键值对。这是不可观察的,因为document.domain
不能重新访问之前的值。
例如,在www.example.com上将document.domain
设置为"example.com
"意味着用户代理可以从映射中删除所有键的一部分为www.example.com的键值对,因为这再也不能成为源的一部分,因此相应的值永远不能从映射中检索到。
如果 O 是 Location
对象,则返回 « { [[Property]]: "href
", [[NeedsGet]]: false, [[NeedsSet]]: true }, { [[Property]]:
"replace
" } »。
返回 « { [[Property]]: "window
", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]:
"self
", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "location
",
[[NeedsGet]]: true, [[NeedsSet]]: true }, { [[Property]]: "close
" }, { [[Property]]:
"closed
", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "focus
" }, {
[[Property]]: "blur
" }, { [[Property]]: "frames
", [[NeedsGet]]: true, [[NeedsSet]]:
false }, { [[Property]]: "length
", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]:
"top
", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "opener
",
[[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "parent
", [[NeedsGet]]: true,
[[NeedsSet]]: false }, { [[Property]]: "postMessage
" } »。
此抽象操作不返回 完成记录。
在此算法中不需要将索引属性列入白名单,因为它们由 WindowProxy
对象直接处理。
JavaScript 属性名 P 是 跨域可访问的 window 属性名,如果它是
"window
"、"self
"、"location
"、"close
"、"closed
"、"focus
"、"blur
"、"frames
"、"length
"、"top
"、"opener
"、"parent
"、"postMessage
",或数组索引属性名。
如果 P 是 "then
",%Symbol.toStringTag%,
%Symbol.hasInstance%,或 %Symbol.isConcatSpreadable%,则返回
PropertyDescriptor{
[[Value]]: undefined,
[[Writable]]: false,
[[Enumerable]]: false,
[[Configurable]]: true }。
此抽象操作不返回 完成记录。
这里的 当前设置对象 大致对应于 "调用者",因为此检查发生在
执行上下文 进入 JavaScript 执行上下文堆栈 之前。例如,在代码 w.document
中,此步骤在 document
getter 被执行为 WindowProxy
w 的 [[Get]] 算法的一部分之前调用。
如果此抽象操作返回 undefined 并且没有自定义行为,则调用者需要抛出 "SecurityError
" DOMException
。
实际上,这是通过调用者调用 CrossOriginPropertyFallback
来处理的。
对于每个 e 的 CrossOriginProperties(O):
如果 SameValue(e.[[Property]], P) 为 true,则:
如果 O 的 [[CrossOriginPropertyDescriptorMap]] 内部槽的值包含一个键为 crossOriginKey 的条目,则返回该条目的值。
让 originalDesc 为 OrdinaryGetOwnProperty(O, P)。
让 crossOriginDesc 为 undefined。
如果 e 的 [[NeedsGet]] 和 [[NeedsSet]] 不存在,则:
让 value 为 originalDesc 的 [[Value]]。
如果 IsCallable(value) 为 true,则将 value 设置为在 当前领域 中创建的匿名内置函数,该函数执行与 IDL 操作 P 在对象 O 上的操作相同的步骤。
将 crossOriginDesc 设置为 PropertyDescriptor{ [[Value]]: value, [[Enumerable]]: false, [[Writable]]: false, [[Configurable]]: true }。
否则:
将 crossOriginGet 设置为 undefined。
如果 e 的 [[NeedsGet]] 为 true,则将 crossOriginGet 设置为在 当前领域 中创建的匿名内置函数,该函数执行与 IDL 属性 P 在对象 O 上的 getter 相同的步骤。
将 crossOriginSet 设置为 undefined。
如果 e 的 [[NeedsSet]] 为 true,则将 crossOriginSet 设置为在 当前领域 中创建的匿名内置函数,该函数执行与 IDL 属性 P 在对象 O 上的 setter 相同的步骤。
将 crossOriginDesc 设置为 PropertyDescriptor{ [[Get]]: crossOriginGet, [[Set]]: crossOriginSet, [[Enumerable]]: false, [[Configurable]]: true }。
在 O 的 [[CrossOriginPropertyDescriptorMap]] 内部槽中的值中创建一个键为 crossOriginKey 且值为 crossOriginDesc 的条目。
返回 crossOriginDesc。
返回 undefined。
此抽象操作不返回 完成记录。
此处生成的属性描述符是可配置的原因是为了保留 JavaScript 规范所需的 基本内部方法的不变量。 特别是,由于属性的值可以因导航而更改,因此要求属性是可配置的。(但是,请参见 tc39/ecma262 issue #672 以及该规范其他地方对此的引用,以了解我们无法保留这些不变量的情况,以兼容现有的 web 内容。)[JAVASCRIPT]
属性描述符是不可枚举的原因是为了兼容现有的 web 内容,尽管这与同源行为不匹配。详情请参见 issue #3183。
让 desc 为 ? O.[[GetOwnProperty]](P).
断言:desc 不为 undefined。
如果 IsDataDescriptor(desc) 为 true,则返回 desc.[[Value]]。
断言:IsAccessorDescriptor(desc) 为 true。
让 getter 为 desc.[[Get]]。
如果 getter 为 undefined,则抛出 "SecurityError
"
DOMException
。
返回 ? Call(getter, Receiver)。
让 desc 为 ? O.[[GetOwnProperty]](P).
断言:desc 不为 undefined。
如果 desc.[[Set]] 存在且其值不为 undefined,则:
执行 ? Call(setter, Receiver, « V »)。
返回 true。
让 keys 成为一个新的空 列表。
对于每个 e 的 CrossOriginProperties(O), 将 e.[[Property]] 附加到 keys。
返回 keys 和 « "then
",
%Symbol.toStringTag%,%Symbol.hasInstance%,%Symbol.isConcatSpreadable%
» 的串联。
此抽象操作不返回 完成记录。
Window
对象在所有当前引擎中支持。
[Global =Window ,
Exposed =Window ,
LegacyUnenumerableNamedProperties ]
interface Window : EventTarget {
// the current browsing context
[LegacyUnforgeable ] readonly attribute WindowProxy window ;
[Replaceable ] readonly attribute WindowProxy self ;
[LegacyUnforgeable ] readonly attribute Document document ;
attribute DOMString name ;
[PutForwards =href , LegacyUnforgeable ] readonly attribute Location location ;
readonly attribute History history ;
readonly attribute Navigation navigation ;
readonly attribute CustomElementRegistry customElements ;
[Replaceable ] readonly attribute BarProp locationbar ;
[Replaceable ] readonly attribute BarProp menubar ;
[Replaceable ] readonly attribute BarProp personalbar ;
[Replaceable ] readonly attribute BarProp scrollbars ;
[Replaceable ] readonly attribute BarProp statusbar ;
[Replaceable ] readonly attribute BarProp toolbar ;
attribute DOMString status ;
undefined close ();
readonly attribute boolean closed ;
undefined stop ();
undefined focus ();
undefined blur ();
// other browsing contexts
[Replaceable ] readonly attribute WindowProxy frames ;
[Replaceable ] readonly attribute unsigned long length ;
[LegacyUnforgeable ] readonly attribute WindowProxy ? top ;
attribute any opener ;
[Replaceable ] readonly attribute WindowProxy ? parent ;
readonly attribute Element ? frameElement ;
WindowProxy ? open (optional USVString url = "", optional DOMString target = "_blank", optional [LegacyNullToEmptyString ] DOMString features = "");
// Since this is the global object, the IDL named getter adds a NamedPropertiesObject exotic
// object on the prototype chain. Indeed, this does not make the global object an exotic object.
// Indexed access is taken care of by the WindowProxy exotic object.
getter object (DOMString name );
// the user agent
readonly attribute Navigator navigator ;
[Replaceable ] readonly attribute Navigator clientInformation ; // legacy alias of .navigator
readonly attribute boolean originAgentCluster ;
// user prompts
undefined alert ();
undefined alert (DOMString message );
boolean confirm (optional DOMString message = "");
DOMString ? prompt (optional DOMString message = "", optional DOMString default = "");
undefined print ();
undefined postMessage (any message , USVString targetOrigin , optional sequence <object > transfer = []);
undefined postMessage (any message , optional WindowPostMessageOptions options = {});
// also has obsolete members
};
Window includes GlobalEventHandlers ;
Window includes WindowEventHandlers ;
dictionary WindowPostMessageOptions : StructuredSerializeOptions {
USVString targetOrigin = "/";
};
window.window
在所有当前引擎中支持。
window.frames
在所有当前引擎中支持。
window.self
在所有当前引擎中支持。
这些属性都返回 window。
window.document
在所有当前引擎中支持。
返回与 window 关联的 Document
。
document.defaultView
在所有当前引擎中支持。
返回与 document 关联的 Window
,如果有的话,否则返回 null。
Window
对象有一个 关联的
Document
,这是一个 Document
对象。它
在创建 Window
对象时设置,并且只有在从
导航 从 初始
about:blank
Document
时才会更改。
Window
的 浏览上下文 是它的 关联
Document
的 浏览上下文。
它要么是 null,要么是一个
浏览上下文。
Window
的 可导航对象 是 可导航对象,其 活动文档
是 Window
的 关联
Document
的,或者如果没有这样的 可导航对象 则为 null。
window
、frames
和 self
的 getter 步骤是返回
this 的 相关领域 的
[[GlobalEnv]] 的 [[GlobalThisValue]]。
document
的 getter
步骤是返回
this 的 关联
Document
。
与 Window
对象关联的 Document
对象可以在一种情况下更改:当 导航 算法 为第一次加载的页面创建新的
Document
对象 时
在 浏览上下文
中。在这种特定情况下,初始
about:blank
页面的 Window
对象会被重用,并获得一个新的 Document
对象。
defaultView
的 getter 步骤是:
返回 this
的 浏览上下文
的
WindowProxy
对象。
在所有当前引擎中支持。
由于历史原因,Window
对象还必须有一个可写的、可配置的、不可枚举的属性,名称为 HTMLDocument
,其值是 Document
接口对象。
window = window.open([ url [, target [, features ] ] ])
Support in all current engines.
打开一个窗口以显示url(默认为"about:blank
"),并返回它。target(默认为"_blank
")指定新窗口的名称。如果已经存在具有该名称的窗口,则重新使用它。features参数可以包含一个逗号分隔的标记集:
noopener
"noreferrer
"这些行为等同于noopener和noreferrer链接类型在超链接上的行为。
popup
"globalThis. open( "https://email.example/message/CAOOOkFcWW97r8yg=SsWg7GgCmp4suVX9o85y8BvNRqMjuc5PXg" , undefined , "noopener,popup" );
window.name [ = value ]
Support in all current engines.
返回窗口的名称。
可以设置以更改名称。
window.close()
Support in all current engines.
关闭窗口。
window.closed
Support in all current engines.
如果窗口已关闭,则返回 true,否则返回 false。
window.stop()
Support in all current engines.
取消文档加载。
窗口打开步骤,给定一个字符串url、一个字符串target和一个字符串features,如下:
让sourceDocument成为入口全局对象的关联Document
。
如果target是空字符串,则将target设置为"_blank
"。
让tokenizedFeatures成为标记化的features的结果。
让noopener和noreferrer为 false。
如果tokenizedFeatures["noopener
"]存在,则:
将noopener设置为解析tokenizedFeatures["noopener
"]作为布尔特性的结果。
移除tokenizedFeatures["noopener
"]。
如果tokenizedFeatures["noreferrer
"]存在,则:
将noreferrer设置为解析tokenizedFeatures["noreferrer
"]作为布尔特性的结果。
移除tokenizedFeatures["noreferrer
"]。
让referrerPolicy为空字符串。
如果noreferrer为 true,则将noopener设置为
true,并将referrerPolicy设置为"no-referrer
"。
让targetNavigable和windowType成为应用选择可导航对象的规则的结果,给定target、sourceDocument的节点可导航对象和noopener。
如果有一个用户代理支持按住 Ctrl 键点击链接以在新标签页中打开它,并且用户按住 Ctrl 键点击一个元素,其onclick
处理程序使用window.open()
API在iframe
元素中打开页面,则用户代理可以覆盖目标浏览上下文的选择以改为目标新标签页。
如果targetNavigable为 null,则返回 null。
如果windowType为"new and unrestricted
"或"new with no opener
",则:
将targetNavigable的活动浏览上下文的是弹出窗口设置为检查是否请求弹出窗口的结果,给定tokenizedFeatures。
设置浏览上下文功能,给targetNavigable的活动浏览上下文,给定tokenizedFeatures。[CSSOMVIEW]
让urlRecord成为about:blank
的URL 记录。
如果urlRecord失败,则抛出一个"SyntaxError
"DOMException
。
如果urlRecord与about:blank
匹配,则执行URL
和历史记录更新步骤,给定targetNavigable的活动文档和urlRecord。
这是必要的,以防url类似于about:blank?foo
。如果url只是普通的about:blank
,这将不会有任何作用。
否则,导航targetNavigable到urlRecord,使用sourceDocument,设置referrerPolicy为referrerPolicy,并设置exceptionsEnabled为 true。
否则:
如果url不是空字符串,则:
如果urlRecord失败,则抛出一个"SyntaxError
"DOMException
。
导航targetNavigable到urlRecord,使用sourceDocument,设置referrerPolicy为referrerPolicy,并设置exceptionsEnabled为 true。
如果noopener为 false,则将targetNavigable的活动浏览上下文的开启者浏览上下文设置为sourceDocument的浏览上下文。
如果noopener为 true 或windowType为"new with no opener
",则返回 null。
返回targetNavigable的活动WindowProxy
。
open(url, target, features)
方法步骤是运行窗口打开步骤,给定url、target和features。
该方法提供了一个机制用于导航现有的浏览上下文或打开并导航一个辅助浏览上下文。
标记化features参数:
让tokenizedFeatures成为一个新的有序映射。
让position指向features的第一个代码点。
当position没有超出features的末尾时:
让name为空字符串。
让value为空字符串。
收集一系列代码点,它们不是features中的特性分隔符,给定position。将name设置为收集的字符,转换为 ASCII 小写。
将name设置为规范化特性名称name的结果。
当position没有超出features的末尾且features中position处的代码点不是 U+003D (=) 时:
这会跳到第一个 U+003D (=),但不会跳过 U+002C (,) 或非分隔符。
如果features中position处的代码点是特性分隔符:
如果name不是空字符串,则将tokenizedFeatures[name]设置为value。
返回tokenizedFeatures。
为了检查是否设置了窗口特性,给定tokenizedFeatures、featureName和defaultValue:
如果tokenizedFeatures[featureName]存在,则返回解析tokenizedFeatures[featureName]作为布尔特性的结果。
返回defaultValue。
为了检查是否请求了弹出窗口,给定tokenizedFeatures:
如果tokenizedFeatures是空的,则返回 false。
如果tokenizedFeatures["popup
"]存在,则返回解析tokenizedFeatures["popup
"]作为布尔特性的结果。
让location成为检查是否设置了窗口特性的结果,给定tokenizedFeatures、"location
"和
false。
让toolbar成为检查是否设置了窗口特性的结果,给定tokenizedFeatures、"toolbar
"和
false。
如果location和toolbar都为 false,则返回 true。
让menubar成为检查是否设置了窗口特性的结果,给定tokenizedFeatures、"menubar
"和
false。
如果menubar为 false,则返回 true。
让resizable成为检查是否设置了窗口特性的结果,给定tokenizedFeatures、"resizable
"和
true。
如果resizable为 false,则返回 true。
让scrollbars成为检查是否设置了窗口特性的结果,给定tokenizedFeatures、"scrollbars
"和
false。
如果scrollbars为 false,则返回 true。
让status成为检查是否设置了窗口特性的结果,给定tokenizedFeatures、"status
"和
false。
如果status为 false,则返回 true。
返回 false。
一个代码点是特性分隔符,如果它是ASCII 空白、U+003D (=) 或 U+002C (,)。
出于遗留原因,有些特性名称有别名。为了规范化特性名称name,切换name:
screenx
"left
"。screeny
"top
"。innerwidth
"width
"。innerheight
"height
"。为了解析布尔特性,给定一个字符串value:
如果value为空字符串,则返回 true。
如果value是"yes
",则返回 true。
如果value是"true
",则返回 true。
让parsed成为解析value为整数的规则的结果。
如果parsed是错误,则将其设置为 0。
如果parsed为 0,则返回 false,否则返回 true。
name
getter 步骤:
name
setter 步骤:
close()
方法步骤:
如果thisTraversable不是顶级遍历,则返回。
如果thisTraversable的正在关闭为 true,则返回。
让browsingContext成为thisTraversable的活动浏览上下文。
如果所有以下条件都为真:
那么:
将 thisTraversable 的 is closing 设置为 true。
navigable是可脚本关闭的,如果其活动浏览上下文是由脚本(而不是用户操作)创建的辅助浏览上下文,或者如果它是一个顶级遍历,其会话历史条目的大小为 1。
closed
getter
步骤是返回
true,如果this的浏览上下文为 null 或其正在关闭为
true;否则返回 false。
stop()
方法步骤:
Window
对象上的索引访问window.length
所有当前引擎均支持。
返回文档树子导航的数量。
window[index]
返回与指定的文档树子导航对应的WindowProxy
。
length
getter 步骤是返回this的关联的Document
的文档树子导航的大小。
通过WindowProxy
对象的[[GetOwnProperty]]
内部方法定义对文档树子导航的索引访问。
Window
对象上的命名访问window[name]
返回指定的元素或元素集合。
通常情况下,依赖这种方式会导致代码不稳定。随着新功能的添加,哪些ID映射到此API可能会随时间变化。例如,使用document.getElementById()
或document.querySelector()
来代替这种方式。
Window
对象window的文档树子导航目标名称属性集
是运行以下步骤的返回值:
令children为window的文档树子导航。
令firstNamedChildren为一个空的有序集合。
对于children中的每个navigable:
令names为一个空的有序集合。
对于firstNamedChildren中的每个navigable:
返回names。
以下例子中,假设https://elsewhere.example/
设置window.name
为“spices
”,当一切加载完毕后,评估window.spices
将会得到undefined:
< iframe src = https://elsewhere.example.com/ ></ iframe >
< iframe name = spices ></ iframe >
Window
对象支持命名属性。Window
对象window的支持的属性名称在任何时候由以下内容组成,按提供它们的元素的树顺序排列,忽略后来的重复项:
window的文档树子导航目标名称属性集;
所有embed
、
form
、
img
和object
元素的name
内容属性值,这些元素具有非空的name
内容属性,并且在window的关联Document
中作为其根的文档树中;
所有具有非空id
内容属性的HTML元素,并且在window的关联Document
中作为其根的文档树中。
要确定命名属性name在Window
对象window中的值,用户代理必须返回以下步骤中获得的值:
令objects为window中具有名称name的命名对象列表。
至少会有一个这样的对象,因为否则算法不会被Web IDL调用。
如果objects包含一个navigable,则:
令container为window的关联Document
的后代中第一个其内容导航在objects中的导航容器。
返回container的内容导航的活动WindowProxy
。
否则,如果objects只有一个元素,则返回该元素。
否则,返回一个HTMLCollection
,其根为window的关联Document
,其过滤器仅匹配window中具有名称name的命名对象。(根据定义,这些都将是元素。)
Window
对象window的命名对象,就上述算法而言,包括以下内容:
window的关联Document
的文档树子导航,其目标名称为name;
具有name
内容属性的embed
、
form
、
img
或object
元素,其值为name,并且在window的关联Document
中作为其根的文档树中;
具有id
内容属性的HTML元素,其值为name,并且在window的关联Document
中作为其根的文档树中。
由于Window
接口具有[Global]
扩展属性,其命名属性遵循命名属性对象的规则,而不是传统平台对象的规则。
window.top
所有当前引擎都支持。
window.opener [ = value ]
所有当前引擎都支持。
如果没有,或者已被设置为 null,则返回 null。
可以设置为 null。
window.parent
所有当前引擎都支持。
返回父导航对象的WindowProxy
。
window.frameElement
所有当前引擎都支持。
返回可导航容器元素。
如果没有,或者在跨域情况下,则返回 null。
top
获取步骤如下:
opener
获取步骤如下:
如果current为 null,则返回 null。
如果current的opener 浏览上下文为 null,则返回 null。
返回current的opener 浏览上下文的WindowProxy
对象。
opener
设置步骤如下:
如果给定值为 null,并且此的浏览上下文不为 null,则将此的浏览上下文的opener 浏览上下文设置为 null。
如果给定值不为 null,则执行DefinePropertyOrThrow(此,"opener
",{
[[Value]]: 给定值,[[Writable]]: true,[[Enumerable]]: true,[[Configurable]]: true
})。
将window.opener
设置为
null 会清除opener
浏览上下文引用。实际上,这将阻止未来的脚本访问其opener 浏览上下文的Window
对象。
默认情况下,脚本可以通过window.opener
getter
访问其opener 浏览上下文的Window
对象。例如,脚本可以设置window.opener.location
,使opener 浏览上下文进行导航。
parent
获取步骤如下:
如果navigable为 null,则返回 null。
返回navigable的活动WindowProxy
。
frameElement
获取步骤如下:
如果current为 null,则返回 null。
让container为current的容器。
如果container为 null,则返回 null。
返回container。
这些属性返回 null 的一个示例如下:
<!DOCTYPE html>
< iframe ></ iframe >
< script >
"use strict" ;
const element = document. querySelector( "iframe" );
const iframeWindow = element. contentWindow;
element. remove();
console. assert( iframeWindow. top === null );
console. assert( iframeWindow. parent === null );
console. assert( iframeWindow. frameElement === null );
</ script >
由于历史原因,Window
接口具有一些表示某些网络浏览器界面元素可见性的属性。
出于隐私和互操作性的原因,这些属性现在返回的值表示Window
的浏览上下文的是否为弹出窗口属性是 true 还是 false。
每个界面元素由一个BarProp
对象表示:
所有当前引擎均支持。
[Exposed =Window ]
interface BarProp {
readonly attribute boolean visible ;
};
window.locationbar.visible
所有当前引擎均支持。
window.menubar.visible
所有当前引擎均支持。
window.personalbar.visible
所有当前引擎均支持。
window.scrollbars.visible
所有当前引擎均支持。
window.statusbar.visible
所有当前引擎均支持。
window.toolbar.visible
所有当前引擎均支持。
如果Window
不是弹出窗口,则返回true;否则返回false。
所有当前引擎均支持。
visible
获取器步骤为:
如果browsingContext为 null,则返回 true。
BarProp
对象BarProp
对象BarProp
对象BarProp
对象BarProp
对象BarProp
对象locationbar
属性必须返回地址栏BarProp
对象。
menubar
属性必须返回菜单栏BarProp
对象。
personalbar
属性必须返回个人栏BarProp
对象。
scrollbars
属性必须返回滚动条BarProp
对象。
statusbar
属性必须返回状态栏BarProp
对象。
toolbar
属性必须返回工具栏BarProp
对象。
由于历史原因,status
属性在Window
对象上,获取时必须返回最后设置的字符串,设置时必须将其设置为新值。当创建Window
对象时,属性必须设置为空字符串。它不执行任何其他操作。
Window
对象的脚本设置要设置窗口环境设置对象,给定一个URL creationURL,一个JavaScript执行上下文 execution context,null或一个环境 reservedEnvironment,一个URL topLevelCreationURL,和一个来源 topLevelOrigin,请执行以下步骤:
让realm为execution context的Realm组件的值。
让window为realm的全局对象。
让settings object为一个新的环境设置对象,其算法定义如下:
返回execution context。
返回window的关联Document
的模块映射。
返回window的关联Document
的当前基础URL。
返回window的关联Document
的来源。
返回window的关联Document
的策略容器。
如果以下两者都成立,则返回true,否则返回false:
返回window的关联Document
的加载时间信息的导航开始时间。
如果reservedEnvironment为非null,则:
将settings object的id设置为reservedEnvironment的id,目标浏览上下文设置为reservedEnvironment的目标浏览上下文,活跃的服务worker设置为reservedEnvironment的活跃的服务worker。
将reservedEnvironment的id设置为空字符串。
否则,将settings object的id设置为一个新的唯一不透明字符串,将settings object的目标浏览上下文设置为null,并将settings object的活跃的服务worker设置为null。
将settings object的创建URL设置为creationURL,settings object的顶级创建URL设置为topLevelCreationURL,settings object的顶级来源设置为topLevelOrigin。
将realm的[[HostDefined]]字段设置为settings object。
WindowProxy
特殊对象WindowProxy
是一个包装了Window
普通对象的特殊对象,通过间接方式将大多数操作传递给被包装的对象。每个浏览上下文都有一个关联的WindowProxy
对象。当浏览上下文导航时,与该浏览上下文关联的Window
对象会发生变化。
WindowProxy
特殊对象必须使用普通的内部方法,除非明确指定了其他方式。
每个WindowProxy
对象都有一个[[Window]]内部槽,表示被包装的Window
对象。
尽管WindowProxy
被命名为“代理”,它并没有像真正的代理那样在其目标的内部方法上进行多态分派,这是为了在WindowProxy
和Location
对象之间重用机制。只要Window
对象仍然是一个普通对象,这种方式是不可观察的,可以实现任意一种。
让W成为[[Window]]
内部槽的值。
如果IsPlatformObjectSameOrigin(W)为真,则返回!OrdinaryGetPrototypeOf(W)。
返回null。
返回!SetImmutablePrototype(this, V)。
返回true。
返回false。
让W成为[[Window]]
内部槽的值。
如果P是一个数组索引属性名,则:
让index成为!ToUint32(P)。
让children成为W的关联Document
的文档树子导航项。
让value为undefined。
如果index小于children的大小,则:
按升序排序children,如果navigableA的容器比navigableB的容器更早插入到W的关联Document
中,则navigableA小于navigableB。
将value设置为children[index]的活动WindowProxy
。
如果value是undefined,则:
如果IsPlatformObjectSameOrigin(W)为真,则返回undefined。
返回PropertyDescriptor{ [[Value]]: value, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: true }。
如果IsPlatformObjectSameOrigin(W)为真,则返回!OrdinaryGetOwnProperty(W, P)。
这是JavaScript规范的基本内部方法的不变性的故意违反,以保持与现有网络内容的兼容性。详情见tc39/ecma262 issue #672。[JAVASCRIPT]
让property成为CrossOriginGetOwnPropertyHelper(W, P)。
如果property不是undefined,则返回property。
如果property是undefined,并且P在W的文档树子导航目标名称属性集合中,则:
让value成为W中名为P的命名对象的活动WindowProxy
。
返回PropertyDescriptor{ [[Value]]: value, [[Enumerable]]: false, [[Writable]]: false, [[Configurable]]: true }。
属性描述符为不可枚举的原因是为了与现有网络内容兼容,尽管这与同源行为不匹配。详情见issue #3183。
返回?CrossOriginPropertyFallback(P)。
让 W 成为 this 的 [[Window]] 内部槽的值。
如果 IsPlatformObjectSameOrigin(W) 为真,则:
如果 P 是一个 数组索引属性名,返回 false。
返回 ? OrdinaryDefineOwnProperty(W, P, Desc)。
这是 JavaScript 规范的 故意违反,以保持与现有网络内容的兼容性。详情见 tc39/ecma262 issue #672。[JAVASCRIPT]
抛出一个 "SecurityError
" DOMException
。
让 W 成为 this 的 [[Window]] 内部槽的值。
根据当前全局对象的 当前全局对象 的 浏览上下文、W 的 浏览上下文、P 以及当前设置对象来检查是否应报告两个浏览上下文之间的访问。
如果 IsPlatformObjectSameOrigin(W) 为真,则返回 ? OrdinaryGet(this, P, Receiver)。
返回 ? CrossOriginGet(this, P, Receiver)。
this 被传递而不是 W,因为 OrdinaryGet 和 CrossOriginGet 将调用 [[GetOwnProperty]] 内部方法。
让 W 成为 this 的 [[Window]] 内部槽的值。
根据当前全局对象的 当前全局对象 的 浏览上下文、W 的 浏览上下文、P 以及当前设置对象来检查是否应报告两个浏览上下文之间的访问。
如果 IsPlatformObjectSameOrigin(W) 为真,则:
如果 P 是一个 数组索引属性名,则返回 false。
返回 ? OrdinarySet(W, P, V, Receiver)。
返回 ? CrossOriginSet(this, P, V, Receiver)。
this 被传递而不是 W,因为 CrossOriginSet 将调用 [[GetOwnProperty]] 内部方法。
让 W 成为 this 的 [[Window]] 内部槽的值。
如果 IsPlatformObjectSameOrigin(W) 为真,则:
如果 P 是一个 数组索引属性名,则:
让 desc 成为 ! this.[[GetOwnProperty]](P)。
如果 desc 是 undefined,则返回 true。
返回 false。
返回 ? OrdinaryDelete(W, P)。
抛出一个 "SecurityError
" DOMException
。
让 W 成为 this 的 [[Window]] 内部槽的值。
让 maxProperties 成为 W 的 关联 Document
的 文档树子导航的 大小。
让 keys 成为 范围 0 到 maxProperties,不包括 maxProperties。
如果 IsPlatformObjectSameOrigin(W) 为真,则返回 keys 和 OrdinaryOwnPropertyKeys(W) 的连接。
返回 keys 和 !CrossOriginOwnPropertyKeys(W) 的连接。
Location
接口支持所有当前的引擎。
支持所有当前的引擎。
支持所有当前的引擎。
每个 Window
对象都关联着一个唯一的
Location
对象实例,在创建
Window
对象时分配。
Location
异常对象是通过一系列的IDL、创建后调用JavaScript内部方法以及覆盖JavaScript内部方法定义的。由于其具有严格的安全策略,在实现这个对象时请特别小心。
要创建一个 Location
对象,请执行以下步骤:
让 valueOf 成为 location 的 相关领域.[[Intrinsics]].[[%Object.prototype.valueOf%]]。
执行 ! location.[[DefineOwnProperty]]("valueOf
", { [[Value]]: valueOf,
[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })。
执行 ! location.[[DefineOwnProperty]](%Symbol.toPrimitive%, { [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })。
将 [[DefaultProperties]] 内部槽的值设置为 location.[[OwnPropertyKeys]]()。
返回 location。
添加 valueOf
和 %Symbol.toPrimitive% 自有数据属性,以及所有 Location
的 IDL
属性都标记为
[LegacyUnforgeable]
,这是因为遗留代码会查阅
Location
接口,或将其字符串化,以确定 文档
URL,然后以安全敏感的方式使用它。特别是,valueOf
、%Symbol.toPrimitive% 和
[LegacyUnforgeable]
字符串化防护措施确保了诸如 foo[location] = bar
或 location + ""
之类的代码不会被误导。
document.location [ = value ]
window.location [ = value ]
返回具有当前页面位置的 Location
对象。
可设置,以导航到另一个页面。
Document
对象的 location
获取步骤是返回
this 的
相关全局对象 的 Location
对象,如果 this 是
完全活动的,否则为 null。
Window
对象的 location
获取步骤是返回 this 的
Location
对象。
Location
对象提供其关联的 Document
的 URL 的表示,以及 导航 和 重新加载 关联的
可导航对象 的方法。
[Exposed =Window ]
interface Location { // but see also additional creation steps and overridden internal methods
[LegacyUnforgeable ] stringifier attribute USVString href ;
[LegacyUnforgeable ] readonly attribute USVString origin ;
[LegacyUnforgeable ] attribute USVString protocol ;
[LegacyUnforgeable ] attribute USVString host ;
[LegacyUnforgeable ] attribute USVString hostname ;
[LegacyUnforgeable ] attribute USVString port ;
[LegacyUnforgeable ] attribute USVString pathname ;
[LegacyUnforgeable ] attribute USVString search ;
[LegacyUnforgeable ] attribute USVString hash ;
[LegacyUnforgeable ] undefined assign (USVString url );
[LegacyUnforgeable ] undefined replace (USVString url );
[LegacyUnforgeable ] undefined reload ();
[LegacyUnforgeable , SameObject ] readonly attribute DOMStringList ancestorOrigins ;
};
location.toString()
location.href
所有当前的引擎都支持。
所有当前的引擎都支持。
返回 Location
对象的 URL。
可以设置,以导航到指定的 URL。
location.origin
所有当前的引擎都支持。
返回 Location
对象的 URL 的来源。
location.protocol
所有当前的引擎都支持。
返回 Location
对象的 URL 的方案。
可以设置,以导航到相同 URL 并更改方案。
location.host
所有当前的引擎都支持。
返回 Location
对象的 URL 的主机和端口(如果与方案的默认端口不同)。
可以设置,以导航到相同 URL 并更改主机和端口。
location.hostname
所有当前的引擎都支持。
返回 Location
对象的 URL 的主机。
可以设置,以导航到相同 URL 并更改主机。
location.port
所有当前的引擎都支持。
返回 Location
对象的 URL 的端口。
可以设置,以导航到相同 URL 并更改端口。
location.pathname
所有当前的引擎都支持。
返回 Location
对象的 URL 的路径。
可以设置,以导航到相同 URL 并更改路径。
location.search
所有当前的引擎都支持。
返回 Location
对象的 URL 查询字符串(如果非空,包含前导的 "?
")。
可以设置,以导航到相同 URL 并更改查询字符串(忽略前导的 "?
")。
location.hash
所有当前的引擎都支持。
返回 Location
对象的 URL 片段(如果非空,包含前导的 "#
")。
可以设置,以导航到相同 URL 并更改片段(忽略前导的 "#
")。
location.assign(url)
所有当前的引擎都支持。
导航到指定的 URL。
location.replace(url)
所有当前的引擎都支持。
从会话历史中删除当前页面并导航到指定的 URL。
location.reload()
所有当前的引擎都支持。
重新加载当前页面。
location.ancestorOrigins
返回一个 DOMStringList
对象,列出 祖先导航的 活动文档的来源。
A Location
对象有一个关联的相关Document
,它是其相关全局对象的浏览上下文的活动文档,如果此Location
对象的相关全局对象的浏览上下文非空,否则为null。
A Location
对象有一个关联的url,它是此Location
对象的相关Document
的URL,如果此Location
对象的相关Document
非空,否则为about:blank
。
A Location
对象有一个关联的祖先来源列表。当创建Location
对象时,其祖先来源列表必须设置为一个DOMStringList
对象,其关联列表是以下步骤生成的字符串列表:
令output为一个新的列表。
令current为Location
对象的相关Document
。
当current的容器文档非空时:
返回output。
要Location
-对象导航到location到一个URL
url,可选地给定一个NavigationHistoryBehavior
historyHandling(默认 "auto
"):
令sourceDocument为Location
对象的Document
。
如果location的相关Document
尚未完全加载,并且sourceDocument没有暂时激活,则将historyHandling设置为"replace"。
导航navigable到url,使用sourceDocument,并将historyHandling设置为historyHandling。
以下是href
的getter步骤:
如果Location
对象的相关Document
非空且其origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
返回Location
对象的url
,序列化。
以下是href
的setter步骤:
如果Location
对象的相关Document
为null,则返回。
令url为给定值的URL解析结果,相对于入口设置对象。
如果url解析失败,则抛出一个SyntaxError
DOMException
。
导航Location
对象到url。
href
的setter故意没有安全检查。
以下是
origin
的getter步骤:
如果Location
对象的相关Document
非空且其origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
返回Location
对象的url
的origin
的序列化结果。
以下是protocol
的getter步骤:
如果Location
对象的相关Document
非空且其origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
返回Location
对象的url
的scheme
,后跟":
"。
以下是protocol
的setter步骤:
如果Location
对象的相关Document
为null,则返回。
如果Location
对象的相关Document
的origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
令copyURL为Location
对象的url
的副本。
令possibleFailure为基本URL解析给定值加上":
",使用copyURL作为URL,并使用方案开始状态作为状态重写。
由于URL解析器忽略多个连续的冒号,提供值"https:
"(甚至"https::::
")与提供值"https
"相同。
如果possibleFailure解析失败,则抛出一个SyntaxError
DOMException
。
如果copyURL的方案不是HTTP(S)方案,则终止这些步骤。
导航Location
对象到copyURL。
以下是host
的getter步骤:
如果Location
对象的相关Document
非空且其origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
令url为Location
对象的url
。
如果url的主机为null,则返回空字符串。
如果url的端口为null,则返回url的主机,序列化。
返回url的主机,序列化,后跟":
"和url的端口,序列化。
以下是host
的setter步骤:
如果Location
对象的相关Document
为null,则返回。
如果Location
对象的相关Document
的origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
令copyURL为Location
对象的url
的副本。
如果copyURL有一个不透明路径,则返回。
基本URL解析给定值,使用copyURL作为URL,并使用主机状态作为状态重写。
导航Location
对象到copyURL。
以下是hostname
的getter步骤:
如果Location
对象的相关Document
非空且其origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
如果Location
对象的url
的主机为null,则返回空字符串。
返回Location
对象的url
的主机,序列化。
以下是hostname
的setter步骤:
如果Location
对象的相关Document
为null,则返回。
如果Location
对象的相关Document
的origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
令copyURL为Location
对象的url
的副本。
如果copyURL有一个不透明路径,则返回。
基本URL解析给定值,使用copyURL作为URL,并使用主机名状态作为状态重写。
导航Location
对象到copyURL。
以下是port
的getter步骤:
如果Location
对象的相关Document
非空且其origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOM Exception
。
如果Location
对象的url
的端口为null,则返回空字符串。
返回Location
对象的url
的端口,序列化。
以下是port
的setter步骤:
如果Location
对象的相关Document
为null,则返回。
如果Location
对象的相关Document
的origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
令copyURL为Location
对象的url
的副本。
如果copyURL不能具有用户名/密码/端口,则返回。
如果给定值为空字符串,则将copyURL的端口设置为null。
否则,基本URL解析给定值,使用copyURL作为URL,并使用端口状态作为状态重写。
导航Location
对象到copyURL。
以下是pathname
的getter步骤:
如果Location
对象的相关Document
非空且其origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
返回URL路径序列化Location
对象的url
的结果。
以下是pathname
的setter步骤:
如果Location
对象的相关Document
为null,则返回。
如果Location
对象的相关Document
的origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
令copyURL为Location
对象的url
的副本。
如果copyURL有一个不透明路径,则返回。
将copyURL的路径设置为空列表。
基本URL解析给定值,使用copyURL作为URL,并使用路径开始状态作为状态重写。
导航Location
对象到copyURL。
以下是search
的getter步骤:
如果Location
对象的相关Document
非空且其origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
如果Location
对象的url
的查询为null或空字符串,则返回空字符串。
返回"?
",后跟Location
对象的url
的查询。
以下是search
的setter步骤:
如果Location
对象的相关Document
为null,则返回。
如果Location
对象的相关Document
的origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
令copyURL为Location
对象的url
的副本。
如果给定值为空字符串,将copyURL的查询设置为null。
否则,执行以下子步骤:
令input为给定值,移除单个前导"?
",如果有的话。
将copyURL的查询设置为空字符串。
基本URL解析input,使用null,相关Document
的字符编码,copyURL作为URL,并使用查询状态作为状态重写。
导航Location
对象到copyURL。
以下是hash
的getter步骤:
如果Location
对象的相关Document
非空且其origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
如果Location
对象的url
的片段为null或空字符串,则返回空字符串。
返回"#
",后跟Location
对象的url
的片段。
以下是hash
的setter步骤:
如果Location
对象的相关Document
为null,则返回。
如果Location
对象的相关Document
的origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
令copyURL为Location
对象
的url
的副本。
令input为给定值,移除单个前导"#
",如果有的话。
将copyURL的片段设置为空字符串。
基本URL解析input,使用copyURL作为URL,并使用片段状态作为状态重写。
如果copyURL的片段是Location
对象的url
的片段,则返回。
此提前返回是为了兼容已部署的内容,后者冗余设置location.hash
以进行滚动。它不适用于其他片段导航机制,如location.href
的setter或location.assign()
。
导航Location
对象到copyURL。
与a元素和area元素的等效API不同,hash
的setter不会特殊处理空字符串,以保持与已部署脚本的兼容性。
以下是assign(url)
方法步骤:
如果Location
对象的相关Document
为null,则返回。
如果Location
对象的相关Document
的origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
令urlRecord为URL解析给定url的结果,相对于入口设置对象。
如果urlRecord解析失败,则抛出一个SyntaxError
DOMException
。
导航Location
对象到urlRecord。
以下是replace(url)
方法步骤:
如果Location
对象的相关Document
为null,则返回。
令urlRecord为URL解析给定url的结果,相对于入口设置对象。
如果urlRecord解析失败,则抛出一个SyntaxError
DOMException
。
导航Location
对象到urlRecord,给定"replace"。
replace()
方法故意没有安全检查。
以下是reload()
方法步骤:
令document为Location
对象的相关Document
。
如果document为null,则返回。
如果document的origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
重新加载document的节点可导航对象。
以下是ancestorOrigins
的getter步骤:
如果Location
对象的相关Document
为null,则返回一个空列表。
如果Location
对象的相关Document
的origin
与入口设置对象的origin
不具有相同的来源域,则抛出一个SecurityError
DOMException
。
否则,返回Location
对象的祖先来源列表。
关于ancestorOrigins
属性如何工作的详细信息仍有争议,可能会改变。更多信息请参见问题#1918。
如前所述,Location
奇异对象出于安全目的需要额外的逻辑。Location
对象必须使用普通的内部方法,除非另有明确规定。
此外,每个Location
对象都有一个表示其创建时属性的[[DefaultProperties]]内部槽。
如果IsPlatformObjectSameOrigin(this)
为true,则返回OrdinaryGetPrototypeOf(this)
。
返回null。
返回SetImmutablePrototype(this, V)
。
返回true。
返回false。
如果IsPlatformObjectSameOrigin(this)
为true,则:
令desc为OrdinaryGetOwnProperty(this, P)
。
如果this
的[[DefaultProperties]]
内部槽包含P,则将desc的[[Configurable]]
设置为true。
返回desc。
令property为CrossOriginGetOwnPropertyHelper(this, P)
。
如果property不为undefined,则返回property。
返回CrossOriginPropertyFallback(P)
。
如果IsPlatformObjectSameOrigin(this)
为true,则:
如果this
的[[DefaultProperties]]
内部槽包含P,则返回false。
返回OrdinaryDefineOwnProperty(this, P, Desc)
。
抛出一个SecurityError
DOMException
。
如果IsPlatformObjectSameOrigin(this)
为true,则返回OrdinaryGet(this, P, Receiver)
。
返回CrossOriginGet(this, P, Receiver)
。
如果IsPlatformObjectSameOrigin(this)
为true,则返回OrdinarySet(this, P, V, Receiver)
。
返回CrossOriginSet(this, P, V, Receiver)
。
如果IsPlatformObjectSameOrigin(this)
为true,则返回OrdinaryDelete(this, P)
。
抛出一个SecurityError
DOMException
。
如果IsPlatformObjectSameOrigin(this)
为true,则返回OrdinaryOwnPropertyKeys(this)
。
返回CrossOriginOwnPropertyKeys(this)
。
History
接口所有当前引擎支持。
所有当前引擎支持。
enum ScrollRestoration { " auto " , " manual " };
[Exposed =Window ]
interface History {
readonly attribute unsigned long length ;
attribute ScrollRestoration scrollRestoration ;
readonly attribute any state ;
undefined go (optional long delta = 0);
undefined back ();
undefined forward ();
undefined pushState (any data , DOMString unused , optional USVString ? url = null );
undefined replaceState (any data , DOMString unused , optional USVString ? url = null );
};
history.length
所有当前引擎支持。
history.scrollRestoration
所有当前引擎支持。
history.scrollRestoration = value
history.state
所有当前引擎支持。
返回 活动会话历史条目 的 经典历史 API 状态,反序列化为 JavaScript 值。
history.go()
重新加载当前页面。
history.go(delta)
所有当前引擎支持。
在当前 可遍历的可导航对象的 会话历史条目列表中向前或向后移动指定的步数。
零步将重新加载当前页面。
如果步数超出范围,则不执行任何操作。
history.back()
所有当前引擎支持。
在当前 可遍历的可导航对象的 会话历史条目列表中向后移动一步。
如果没有前一页,则不执行任何操作。
history.forward()
所有当前引擎支持。
在当前 可遍历的可导航对象的 会话历史条目列表中向前移动一步。
如果没有下一页,则不执行任何操作。
history.pushState(data, "")
所有当前引擎支持。
将一个新条目添加到会话历史中,其 经典历史 API 状态设置为 data 的序列化。活动历史条目 的 URL 将被复制并用作新条目的 URL。
(第二个参数存在是为了历史原因,不能省略;传递空字符串是传统做法。)
history.pushState(data, "", url)
将一个新条目添加到会话历史中,其 经典历史 API 状态设置为 data 的序列化,并将其 URL 设置为 url。
如果当前 Document
无法将其 URL 重写为
url,将抛出 "SecurityError
"
DOMException
。
(第二个参数存在是为了历史原因,不能省略;传递空字符串是传统做法。)
history.replaceState(data, "")
所有当前引擎支持。
将 活动会话历史条目 的 经典历史 API 状态 更新为 data 的结构化克隆。
(第二个参数存在是为了历史原因,不能省略;传递空字符串是传统做法。)
history.replaceState(data, "", url)
将 活动会话历史条目 的 经典历史 API 状态 更新为 data 的结构化克隆,并将其 URL 更新为 url。
如果当前 Document
无法将其 URL 重写为
url,将抛出 "SecurityError
"
DOMException
。
(第二个参数存在是为了历史原因,不能省略;传递空字符串是传统做法。)
Document
有一个
history 对象,一个 History
对象。
history
获取器步骤是返回 this 的 相关
Document
的 history 对象。
每个 History
对象都有
state,初始值为 null。
每个 History
对象都有一个 length,一个非负整数,初始值为 0。
每个 History
对象都有一个 index,一个非负整数,初始值为 0。
虽然 index 没有直接暴露,但可以从同步导航期间 length 的变化中推断出来。事实上,这就是它的用途。
length
获取器步骤是:
如果 this 的 相关全局对象 的 相关
Document
不是 完全活跃,则抛出一个
"SecurityError
" DOMException
。
scrollRestoration
获取器步骤是:
如果 this 的 相关全局对象 的 相关
Document
不是 完全活跃,则抛出一个
"SecurityError
" DOMException
。
scrollRestoration
设置器步骤是:
如果 this 的 相关全局对象 的 相关
Document
不是 完全活跃,则抛出一个
"SecurityError
" DOMException
。
state
获取器步骤是:
如果 this 的 相关全局对象 的 相关
Document
不是 完全活跃,则抛出一个
"SecurityError
" DOMException
。
go(delta)
方法步骤是根据给定的 delta delta traverse
this。
back()
方法步骤是根据给定的 -1
delta traverse this。
forward()
方法步骤是根据给定的
+1 delta traverse
this。
根据一个给定整数 delta 来 delta traverse 一个 History
对象
history:
让 document 为 history 的 相关全局对象 的 相关
Document
。
如果 document 不是 完全活跃,则抛出一个 "SecurityError
" DOMException
。
根据 document 的 节点可导航 的 可遍历导航,delta 和 sourceDocument 设置为 document 来 遍历历史。
pushState(data, unused, url)
方法步骤是根据
this,data,url 和 "push
"
运行 共享历史推/替换状态步骤。
replaceState(data, unused, url)
方法步骤是根据
this,data,url 和 "replace
"
运行 共享历史推/替换状态步骤。
共享历史推/替换状态步骤,根据 History
history,一个值 data,一个 标量值字符串 或
null
的 url,以及一个 历史处理行为 historyHandling:
让 document 为 history 的相关 Document
。
如果 document 不是 完全活跃,则抛出一个 "SecurityError
" DOMException
。
可选地,返回。(例如,用户代理可能会禁止调用这些方法,这些方法是在定时器上调用的,或者从未在响应明确的用户操作触发的事件侦听器中调用,或者以 快速连续调用的方式调用的。)
让 serializedData 为 StructuredSerializeForStorage(data) 的结果。重新抛出任何异常。
让 newURL 为 document 的 URL。
如果 url 不是 null 或空字符串,则:
将 newURL 设置为根据 编码解析一个 URL 给定 url,相对于 history 的 relevant settings object。
如果 newURL 是失败,则抛出一个 "SecurityError
" DOMException
。
如果 document 不能将其 URL 重写 为 newURL,则抛出一个 "SecurityError
" DOMException
。
这里的空字符串特殊情况是历史性的,并导致在比较诸如 location.href = ""
(它对空字符串执行 URL 解析)与
history.pushState(null, "", "")
(它绕过它)时产生不同的结果 URL。
让 continue 为 在 navigation 上触发一个推/替换/重新加载
navigate
事件 的结果,navigationType 设置为
historyHandling,isSameDocument 设置为 true,destinationURL 设置为
newURL,classicHistoryAPIState 设置为
serializedData。
如果 continue 是 false,则返回。
根据 URL 和历史更新步骤,给定 document 和 newURL 运行步骤,serializedData 设置为 serializedData 和 historyHandling 设置为 historyHandling。
用户代理可以限制每页添加到会话历史的状态对象数量。如果一个页面达到 实现定义的限制,用户代理必须在添加新条目后立即删除会话历史中该 Document
对象的第一个条目。(因此状态历史作为一个先进先出缓冲区用于逐出,但作为一个后进先出缓冲区用于导航。)
一个 Document
document 可以将其 URL 重写 为一个 URL targetURL,如果以下算法返回
true:
让documentURL成为document的URL。
如果targetURL和documentURL在scheme、username、 password、host或port 组件上有所不同,则返回 false。
如果targetURL的scheme是 HTTP(S) scheme,则返回 true。
如果targetURL的scheme是
"file
",则:
如果targetURL和documentURL在路径组件上有所不同,则返回 false。
返回 true。
如果targetURL和documentURL在路径组件或查询组件上有所不同,则 返回 false。
对于其他类型的 URL,只有片段的差异是允许的。
返回 true。
document 的 URL | targetURL | 可以重写 URL |
---|---|---|
https://example.com/home
|
https://example.com/home#about
|
✅ |
https://example.com/home
|
https://example.com/home?page=shop
|
✅ |
https://example.com/home
|
https://example.com/shop
|
✅ |
https://example.com/home
|
https://user:pass@example.com/home
|
❌ |
https://example.com/home
|
http://example.com/home
|
❌ |
file:///path/to/x
|
file:///path/to/x#hash
|
✅ |
file:///path/to/x
|
file:///path/to/x?search
|
✅ |
file:///path/to/x
|
file:///path/to/y
|
❌ |
about:blank
|
about:blank#hash
|
✅ |
about:blank
|
about:blank?search
|
❌ |
about:blank
|
about:srcdoc
|
❌ |
data:text/html,foo
|
data:text/html,foo#hash
|
✅ |
data:text/html,foo
|
data:text/html,foo?search
|
❌ |
data:text/html,foo
|
data:text/html,bar
|
❌ |
data:text/html,foo
|
data:bar
|
❌ |
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43
|
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43#hash
|
✅ |
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43
|
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43?search
|
❌ |
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43
|
blob:https://example.com/anything
|
❌ |
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43
|
blob:path
|
❌ |
请注意,只有 Document
的 URL
是重要的,而不是它的 origin。它们可能在一些情况下不匹配,例如继承了来源的 about:blank
Document
,在被沙盒化的
iframe
中,或者当使用了 document.domain
设置器时。
考虑一个游戏,用户可以沿着一条线导航,使用户始终在某个坐标,并且用户可以书签对应于特定坐标的页面,以便以后返回。
实现该游戏中 x=5 位置的静态页面可能如下所示:
<!DOCTYPE HTML>
<!-- this is https://example.com/line?x=5 -->
< html lang = "en" >
< title > Line Game - 5</ title >
< p > You are at coordinate 5 on the line.</ p >
< p >
< a href = "?x=6" > Advance to 6</ a > or
< a href = "?x=4" > retreat to 4</ a > ?
</ p >
这种系统的问题在于每次用户点击时,整个页面都必须重新加载。以下是一种使用脚本的替代方法:
<!DOCTYPE HTML>
<!-- this starts off as https://example.com/line?x=5 -->
< html lang = "en" >
< title > Line Game - 5</ title >
< p > You are at coordinate < span id = "coord" > 5</ span > on the line.</ p >
< p >
< a href = "?x=6" onclick = "go(1); return false;" > Advance to 6</ a > or
< a href = "?x=4" onclick = "go(-1); return false;" > retreat to 4</ a > ?
</ p >
< script >
var currentPage = 5 ; // prefilled by server
function go( d) {
setupPage( currentPage + d);
history. pushState( currentPage, "" , '?x=' + currentPage);
}
onpopstate = function ( event) {
setupPage( event. state);
}
function setupPage( page) {
currentPage = page;
document. title = 'Line Game - ' + currentPage;
document. getElementById( 'coord' ). textContent = currentPage;
document. links[ 0 ]. href = '?x=' + ( currentPage+ 1 );
document. links[ 0 ]. textContent = 'Advance to ' + ( currentPage+ 1 );
document. links[ 1 ]. href = '?x=' + ( currentPage- 1 );
document. links[ 1 ]. textContent = 'retreat to ' + ( currentPage- 1 );
}
</ script >
在不支持脚本的系统中,这种方法仍然像之前的例子一样工作。然而,对于支持脚本的用户来说,现在可以更快地导航,因为不需要网络访问即可获得相同的体验。此外,与仅使用简单脚本的方法相比,书签和会话历史导航仍然有效。
在上面的例子中,传递给 pushState()
方法的 data 参数与发送到服务器的信息相同,但形式更方便,这样脚本在用户导航时不必每次都解析 URL。
大多数应用程序希望为其所有历史记录条目使用相同的滚动恢复模式值。为了实现这一点,他们可以尽早设置scrollRestoration
属性(例如,在文档头部
元素中的第一个脚本
元素中),以确保添加到会话历史记录的任何条目都能获得所需的滚动恢复模式。
< head >
< script >
if ( 'scrollRestoration' in history)
history. scrollRestoration = 'manual' ;
</ script >
</ head >
本节为非规范性内容。
导航 API 由全局 navigation
属性提供,提供了一种现代且以 Web 应用为中心的方式来管理导航和历史记录条目。它是经典 location
和 history
API 的继承者。
该 API 提供的一项功能是检查会话历史记录条目。例如,以下代码将以有序列表显示条目的 URL:
const ol = document. createElement( "ol" );
ol. start = 0 ; // so that the list items' ordinal values match up with the entry indices
for ( const entry of navigation. entries()) {
const li = document. createElement( "li" );
if ( entry. index < navigation. currentEntry. index) {
li. className = "backward" ;
} else if ( entry. index > navigation. currentEntry. index) {
li. className = "forward" ;
} else {
li. className = "current" ;
}
li. textContent = entry. url;
ol. append( li);
}
navigation.entries()
数组包含 NavigationHistoryEntry
实例,除了这里显示的 url
和 index
属性外,还具有其他有用的属性。请注意,该数组仅包含表示当前 navigable 的 NavigationHistoryEntry
对象,因此其内容不受 navigable containers
内的导航影响,例如 iframe
,或在导航
API 本身在 iframe
中使用的情况下不受 parent navigable
的导航影响。此外,它仅包含表示相同 origin 的 session history entries 的
NavigationHistoryEntry
对象,这意味着如果用户在当前来源之前或之后访问了其他来源,将不会有相应的 NavigationHistoryEntry
。
导航 API 还可用于导航、重新加载或浏览历史记录:
< button onclick = "navigation.reload()" > Reload</ button >
< input type = "url" id = "navigationURL" >
< button onclick = "navigation.navigate(navigationURL.value)" > Navigate</ button >
< button id = "backButton" onclick = "navigation.back()" > Back</ button >
< button id = "forwardButton" onclick = "navigation.forward()" > Forward</ button >
< select id = "traversalDestinations" ></ select >
< button id = "goButton" onclick = "navigation.traverseTo(traversalDestinations.value)" > Traverse To</ button >
< script >
backButton. disabled = ! navigation. canGoBack;
forwardButton. disabled = ! navigation. canGoForward;
for ( const entry of navigation. entries()) {
traversalDestinations. append( new Option( entry. url, entry. key));
}
</ script >
请注意,导航操作再次仅限于相同 origin 的目标,这意味着,例如,如果上一个
session
history entry 是来自另一个来源的页面,那么 navigation.canGoBack
将为 false。
导航 API 最强大的部分是 navigate
事件,每当当前 navigable
中几乎任何导航或浏览发生时,它都会触发:
navigation. onnavigate = event => {
console. log( event. navigationType); // "push", "replace", "reload", or "traverse"
console. log( event. destination. url);
console. log( event. userInitiated);
// ... and other useful properties
};
(当导航的目的地是一个新文档时,此事件不会因为地址栏发起的导航或从其他窗口发起的导航而触发。)
大多数时候,事件的 cancelable
属性为 true,这意味着可以使用 preventDefault()
来取消此事件:
navigation. onnavigate = event => {
if ( event. cancelable && isDisallowedURL( event. destination. url)) {
alert( `Please don't go to ${ event. destination. url} !` );
event. preventDefault();
}
};
cancelable
属性在某些 "traverse
"
导航中将为 false,例如在 子导航元素中进行的导航、跨越到新源的导航,或者当用户尝试在前一次调用 preventDefault()
阻止他们进行导航后不久再次尝试进行导航时。
NavigateEvent
的
intercept()
方法允许拦截导航并将其转换为同文档导航:
navigation. addEventListener( "navigate" , e => {
// Some navigations, e.g. cross-origin navigations, we cannot intercept.
// Let the browser handle those normally.
if ( ! e. canIntercept) {
return ;
}
// Similarly, don't intercept fragment navigations or downloads.
if ( e. hashChange || e. downloadRequest !== null ) {
return ;
}
const url = new URL( event. destination. url);
if ( url. pathname. startsWith( "/articles/" )) {
e. intercept({
async handler() {
// The URL has already changed, so show a placeholder while
// fetching the new content, such as a spinner or loading page.
renderArticlePagePlaceholder();
// Fetch the new content and display when ready.
const articleContent = await getArticleContent( url. pathname, { signal: e. signal });
renderArticlePage( articleContent);
}
});
}
});
请注意,handler
函数可以返回一个表示导航异步进度和成功或失败的 promise。在 promise 仍处于待定状态时,浏览器 UI 可以将导航视为正在进行中(例如,通过显示加载指示器)。导航 API 的其他部分也会对这些 promise
做出反应,例如 navigation.navigate()
的返回值:
const { committed, finished } = await navigation. navigate( "/articles/the-navigation-api-is-cool" );
// The committed promise will fulfill once the URL has changed, which happens
// immediately (as long as the NavigateEvent wasn't canceled).
await committed;
// The finished promise will fulfill once the Promise returned by handler() has
// fulfilled, which happens once the article is downloaded and rendered. (Or,
// it will reject, if handler() fails along the way).
await finished;
Navigation
接口[Exposed =Window ]
interface Navigation : EventTarget {
sequence <NavigationHistoryEntry > entries ();
readonly attribute NavigationHistoryEntry ? currentEntry ;
undefined updateCurrentEntry (NavigationUpdateCurrentEntryOptions options );
readonly attribute NavigationTransition ? transition ;
readonly attribute NavigationActivation ? activation ;
readonly attribute boolean canGoBack ;
readonly attribute boolean canGoForward ;
NavigationResult navigate (USVString url , optional NavigationNavigateOptions options = {});
NavigationResult reload (optional NavigationReloadOptions options = {});
NavigationResult traverseTo (DOMString key , optional NavigationOptions options = {});
NavigationResult back (optional NavigationOptions options = {});
NavigationResult forward (optional NavigationOptions options = {});
attribute EventHandler onnavigate ;
attribute EventHandler onnavigatesuccess ;
attribute EventHandler onnavigateerror ;
attribute EventHandler oncurrententrychange ;
};
dictionary NavigationUpdateCurrentEntryOptions {
required any state ;
};
dictionary NavigationOptions {
any info ;
};
dictionary NavigationNavigateOptions : NavigationOptions {
any state ;
NavigationHistoryBehavior history = "auto";
};
dictionary NavigationReloadOptions : NavigationOptions {
any state ;
};
dictionary NavigationResult {
Promise <NavigationHistoryEntry > committed ;
Promise <NavigationHistoryEntry > finished ;
};
enum NavigationHistoryBehavior {
" auto " ,
" push " ,
" replace "
};
每个 Window
都有一个关联的 导航 API,它是一个 Navigation
对象。在创建
Window
对象时,它的 导航 API
必须设置为在 Window
对象的 相关领域
中创建的 新 Navigation
对象。
navigation
getter
的步骤是返回 此对象的
导航
API。
以下是所有实现 Navigation
接口的对象必须支持的 事件处理程序(及其对应的
事件处理程序事件类型),作为 事件处理程序 IDL 属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onnavigate |
navigate
|
onnavigatesuccess |
navigatesuccess
|
onnavigateerror |
navigateerror
|
oncurrententrychange |
currententrychange
|
每个 Navigation
都有一个关联的 条目列表,一个包含 NavigationHistoryEntry
对象的 列表,最初为空。
每个 Navigation
都有一个关联的 当前条目索引,一个整数,最初为 -1。
一个 Navigation
navigation 的 当前条目 是运行以下步骤的结果:
如果 navigation 禁用了条目和事件,则返回 null。
如果以下步骤返回 true,则一个 Navigation
navigation 禁用了条目和事件:
让 document 成为 navigation 的 相关全局对象 的 关联的
Document
。
如果 document 不是 完全活动,则返回 true。
如果 document 的 初始
about:blank
是 true,则返回 true。
返回 false。
要获取 会话历史条目 she 在
Navigation
navigation 中的 导航 API 条目索引:
导航 API 中使用的一个关键类型是 NavigationType
枚举:
enum NavigationType {
" push " ,
" replace " ,
" reload " ,
" traverse "
};
这捕获了主要的 web 开发者可见的“导航”类型,这些类型(如在其他地方所述)并不完全对应于本标准的单一导航算法。每个值的含义如下:
push
"push
",或调用history.pushState()
。
replace
"replace
",或调用history.replaceState()
。
reload
"traverse
" NavigationType
枚举的值空间是规范内部 历史处理行为
类型的值空间的超集。本标准的几个部分利用了这种重叠,通过将 历史处理行为 传递给期望 NavigationType
的算法。
根据给定的Navigation
navigation、列表的新会话历史条目 newSHEs和会话历史条目
initialSHE来初始化新文档的导航 API 条目:
如果navigation已禁用条目和事件,则返回。
对于每个newSHE中的newSHEs:
让newNHE成为在navigation的相关领域中创建的新的 NavigationHistoryEntry
。
将newNHE的会话历史条目设置为newSHE。
newSHEs最初将来自获取导航 API 的会话历史条目,因此每个newSHE都将与initialSHE相同同源。
将navigation的当前条目索引设置为在navigation中获取导航 API 条目索引的initialSHE的结果。
根据给定的Navigation
navigation、列表的新会话历史条目 newSHEs和会话历史条目
reactivatedSHE来更新重新激活的导航 API 条目:
如果navigation已禁用条目和事件,则返回。
让newNHEs成为一个新的空列表。
对于每个newSHE中的newSHEs:
让newNHE为null。
如果oldNHEs包含一个NavigationHistoryEntry
matchingOldNHE,其会话历史条目为newSHE,则:
将newNHE设置为matchingOldNHE。
从 oldNHEs中删除matchingOldNHE。
否则:
将newNHE设置为在navigation的相关领域中创建的新的 NavigationHistoryEntry
。
将newNHE的会话历史条目设置为newSHE。
追加 newNHE到newNHEs。
newSHEs最初将来自获取导航 API 的会话历史条目,因此每个newSHE都将与reactivatedSHE相同同源。
在此循环结束时,oldNHEs中剩余的所有NavigationHistoryEntry
表示在bfcache中Document
时已被处理的会话历史条目。
将navigation的条目列表设置为newNHEs。
将navigation的当前条目索引设置为在navigation中获取导航 API 条目索引的reactivatedSHE的结果。
在 navigation的相关全局对象上给定的导航和遍历任务源上排队一个全局任务以运行以下步骤:
我们通过一个任务延迟这些步骤,以确保dispose
事件将在pageshow
事件之后触发。这确保pageshow
是页面在重新激活时收到的第一个事件。
(但是,本算法的其余部分在pageshow
事件触发之前运行。这确保navigation.entries()
和navigation.currentEntry
将在任何pageshow
事件处理程序期间具有正确更新的值。)
根据给定的Navigation
navigation、会话历史条目 destinationSHE和NavigationType
navigationType来更新同一文档导航的导航
API
条目:
如果navigation已禁用条目和事件,则返回。
让oldCurrentNHE成为navigation的当前条目。
让disposedNHEs成为一个新的空列表。
如果navigationType是"traverse
",则:
将navigation的当前条目索引设置为在navigation中获取导航 API 条目索引的destinationSHE的结果。
此算法仅针对同一文档遍历调用。跨文档遍历将改为调用初始化新文档的导航 API 条目或更新重新激活的导航 API 条目。
否则,如果navigationType是"push
",则:
否则,如果navigationType是"replace
",则:
追加 oldCurrentNHE到disposedNHEs。
如果navigation的正在进行的API方法跟踪器不为null,则通知关于提交的条目给定navigation的正在进行的API方法跟踪器和navigation的当前条目。
重要的是在触发dispose
或currententrychange
事件之前执行此操作,因为事件处理程序可能会启动另一个导航,或以其他方式更改navigation的正在进行的API方法跟踪器的值。
请参阅其他导航API事件的讨论以了解我们这样做的原因。
触发一个名为currententrychange
的事件在navigation上,使用NavigationCurrentEntryChangeEvent
,其navigationType
属性初始化为navigationType,其from
初始化为oldCurrentNHE。
对于 disposedNHEs中的每个disposedNHE:
在实现中,同一文档导航可能会导致会话历史条目通过从会话历史条目列表的末尾掉下来而被处理。这还未由上述算法(或本标准的任何其他部分)处理。请参阅问题 #8620以跟踪定义此类情况下正确行为的进展。
NavigationHistoryEntry
接口[Exposed =Window ]
interface NavigationHistoryEntry : EventTarget {
readonly attribute USVString ? url ;
readonly attribute DOMString key ;
readonly attribute DOMString id ;
readonly attribute long long index ;
readonly attribute boolean sameDocument ;
any getState ();
attribute EventHandler ondispose ;
};
entry.url
此导航历史条目的 URL。
如果条目对应于与当前不同的 Document
(即
sameDocument
为 false),并且该 Document
是使用 "no-referrer
" 或 "origin
" 的 referrer policy 获取的,则该条目的 URL 可能返回 null,因为这表明该 Document
隐藏了其 URL,即使是对其他同源页面也是如此。
entry.key
表示此导航历史条目在导航历史列表中位置的用户代理生成的随机 UUID 字符串。该值将在其他由于 "replace
"
导航而替换此条目的 NavigationHistoryEntry
实例中重用,并且会在重新加载和会话恢复时保留。
这对于使用 navigation.traverseTo(key)
导航回到导航历史列表中的该条目非常有用。
entry.id
表示此特定导航历史条目的用户代理生成的随机 UUID 字符串。此值不会被其他 NavigationHistoryEntry
实例重用。此值将在重新加载和会话恢复时保留。
这对于使用其他存储 API 将数据与此导航历史条目关联非常有用。
entry.index
此 NavigationHistoryEntry
在 navigation.entries()
中的索引,或如果该条目不在导航历史条目列表中,则为 −1。
entry.sameDocument
指示此导航历史条目是否与当前的 Document
相同。例如,当条目表示片段导航或单页应用导航时,此值将为 true。
entry.getState()
返回存储在此条目中的状态的 反序列化结果,该状态是使用 navigation.navigate()
或 navigation.updateCurrentEntry()
添加到条目中的。此状态在重新加载和会话恢复时保留。
请注意,除非状态值是原始类型,否则通常情况下 entry.getState() !== entry.getState()
,因为每次都会返回一个新的反序列化结果。
此状态与经典历史 API 的 history.state
无关。
每个 NavigationHistoryEntry
都有一个关联的 会话历史条目,这是一个 会话历史条目。
NavigationHistoryEntry
nhe 的 key 是通过以下算法的返回值给出的:
如果 nhe 的 相关全局对象 的 关联的
Document
不是 完全激活的,则返回空字符串。
返回 nhe 的 会话历史条目 的 导航 API key。
NavigationHistoryEntry
nhe 的 ID 是通过以下算法的返回值给出的:
如果 nhe 的 相关全局对象 的 关联的
Document
不是 完全激活的,则返回空字符串。
NavigationHistoryEntry
nhe 的 index 是通过以下算法的返回值给出的:
如果 nhe 的 相关全局对象 的 关联的
Document
不是 完全激活的,则返回 -1。
url
getter 的步骤为:
让 document 成为 此 的 相关全局对象
的 关联的
Document
。
如果 document 不是 完全激活的,则返回空字符串。
如果 she 的 document
不等于 document,并且
she
的 document
state
的 request referrer policy
是
"no-referrer
" 或 "origin
",则返回 null。
index
getter 的步骤是返回 此 的 index。
sameDocument
getter 的步骤是:
让 document 成为 此 的 相关全局对象
的 关联的
Document
。
如果 document 不是 完全激活的,则返回 false。
getState()
方法的步骤是:
如果 此 的 相关全局对象 的 关联的
Document
不是 完全激活的,则返回 undefined。
返回 StructuredDeserialize(此 的 会话历史条目 的 导航 API 状态)。重新抛出任何异常。
这在理论上可能会抛出异常,例如尝试反序列化一个大 ArrayBuffer
时,如果没有足够的内存。
以下是 事件处理程序(及其对应的 事件处理程序事件类型),所有实现 NavigationHistoryEntry
接口的对象都必须支持这些事件处理程序,作为 事件处理程序 IDL 属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
ondispose |
dispose
|
entries = navigation.entries()
返回一个包含 NavigationHistoryEntry
实例的数组,这些实例代表当前的
导航历史条目列表,即所有与该 navigable
相关的 会话历史条目,这些条目与当前会话历史条目同源并连续。
navigation.currentEntry
返回与当前会话历史条目对应的 NavigationHistoryEntry
。
navigation.updateCurrentEntry({ state })
更新当前会话历史条目的导航API状态,而不执行像 navigation.reload()
那样的导航。
此方法最好用于捕捉已经发生并需要反映在导航API状态中的页面更新。对于需要通过状态更新驱动页面更新的情况,应使用 navigation.navigate()
或 navigation.reload()
,这些方法会触发
navigate
事件。
navigation.canGoBack
如果当前会话历史条目(即 currentEntry
)
不是导航历史条目列表中的第一个(即在 entries()
中),则返回 true。
这意味着存在一个先前的 会话历史条目,并且其
文档状态的 源
与当前 文档
的 源 同源。
navigation.canGoForward
如果当前会话历史条目(即 currentEntry
)
不是导航历史条目列表中的最后一个(即在 entries()
中),则返回 true。
这意味着存在一个下一个 会话历史条目,并且其
文档状态的
源
与当前 文档
的 源 同源。
The entries()
方法步骤如下:
请注意,由于 Web IDL 的序列类型转换规则,每次调用都会创建一个新的 JavaScript 数组对象。即
navigation.entries() !== navigation.entries()
。
The currentEntry
getter 步骤是返回 当前条目。
The updateCurrentEntry(options)
方法步骤如下:
令 current 为 当前条目。
如果 current 为 null,则抛出 "InvalidStateError
"
DOMException
。
令 serializedState 为 StructuredSerializeForStorage(options["state
"]),
重抛任何异常。
触发名为 currententrychange
的事件,
使用 NavigationCurrentEntryChangeEvent
,
其 navigationType
属性
初始化为 null,其 from
初始化为 current。
The canGoBack
getter 步骤如下:
The canGoForward
getter 步骤如下:
返回 true。
{ committed, finished } = navigation.navigate(url)
{ committed, finished } = navigation.navigate(url, options)
导航 当前页面到给定的 url。 options可以包含以下值:
info
可以设置为任何值;它将填充对应 info
属性
的
相应 NavigateEvent
。
state
可以设置为任何
可序列化的值;它将填充状态
通过 navigation.currentEntry.getState()
一旦导航完成,对于同文档导航。(对于跨文档导航将被忽略。)
默认情况下,这将执行完整导航(即跨文档导航,除非给定的URL仅在 片段与当前
不同)。可以使用 navigateEvent.intercept()
方法将其转换为同文档导航。
返回的承诺将如下所示:
对于被中止的导航,两个承诺都会拒绝
"AbortError
" DOMException
。
对于使用 navigateEvent.intercept()
方法创建的同文档导航,committed
将立即兑现,finished
将根据传递给 intercept()
的处理程序返回的任何承诺兑现或拒绝。
对于其他同文档导航(例如未拦截的 片段导航),两个承诺都会立即兑现。
对于跨文档导航,或者结果为204或205 状态或`Content-Disposition: attachment
`
服务器返回的标头字段的导航(因此实际上不会导航),两个承诺都不会解决。
在所有情况下,当返回的承诺兑现时,将会是
NavigationHistoryEntry
进行导航的条目。
{ committed, finished } = navigation.reload(options)
重新加载
当前页面。options可以包含info
和state
,
其行为如上所述。
通过使用navigateEvent.intercept()
方法可以覆盖默认执行从网络或缓存重新加载当前页面的行为。这样做将意味着此调用仅更新状态或传递相应的info
,
加上执行navigate
事件处理程序认为合适的任何操作。
返回的承诺将如下所示:
如果通过使用navigateEvent.intercept()
方法拦截重新加载,committed
将立即兑现,finished
将根据传递给intercept()
的处理程序返回的任何承诺兑现或拒绝。
否则,两个承诺都不会解决。
{ committed, finished } = navigation.traverseTo(key)
{ committed, finished } = navigation.traverseTo(key, { info })
遍历到最近的 会话历史条目,匹配给定
key的 NavigationHistoryEntry
。info
可以设置为任何值;
它将填充相应 info
属性的相应
NavigateEvent
。
如果到那个 会话历史条目 的遍历已经在
进行中,那么这
将返回该原始遍历的承诺,而 info
将被忽略。
返回的承诺将如下所示:
如果在 navigateEvent.intercept()
方法拦截的同文档遍历中,committed
将在遍历
处理并更新 navigation.currentEntry
时兑现,finished
将根据传递给 intercept()
的处理程序返回的任何承诺兑现或拒绝。
对于非拦截的同文档遍历,两个承诺将在遍历处理并更新navigation.currentEntry
时兑现。
对于跨文档遍历,包括尝试跨文档遍历但结果为204或205的Content-Disposition: attachment
标头字段的导航(因此实际上不会遍历),两个承诺都不会解决。
{ committed, finished } = navigation.back(key)
{ committed, finished } = navigation.back(key, { info })
遍历到最近的前一个 会话历史条目,这将
导致此 可导航
的遍历,即,它对应于一个不同的
NavigationHistoryEntry
并因此将导致 navigation.currentEntry
的更改。info
可以设置为任何值;它将填充
相应 info
属性的相应
NavigateEvent
。
如果到那个 会话历史条目 的遍历已经在
进行中,那么这将返回该原始遍历的承诺,而 info
将被忽略。
返回的承诺行为等同于 traverseTo()
返回的承诺。
{ committed, finished } = navigation.forward(key)
{ committed, finished } = navigation.forward(key, { info })
遍历到最近的前一个 会话历史条目,这将导致此
可导航
的遍历,即,它对应于一个不同的
NavigationHistoryEntry
并因此将导致 navigation.currentEntry
的更改。info
可以设置为任何值;它将填充
相应 info
属性的相应
NavigateEvent
。
如果到那个 会话历史条目 的遍历已经在
进行中,那么这将返回该原始遍历的承诺,而 info
将被忽略。
返回的承诺行为等同于 traverseTo()
返回的承诺。
navigate(url, options)
方法步骤如下:
如果 urlRecord 是失败,则返回一个 早期错误结果,用于
"SyntaxError
" DOMException
。
令 document 是 此的 相关全局对象的 关联
Document
。
如果 options["history
"]
是 "push
",
并且 导航必须是一个替换 给定
urlRecord 和 document,则返回一个 早期错误结果 用于
一个
"NotSupportedError
" DOMException
。
令 serializedState 为 StructuredSerializeForStorage(state)。 如果这抛出一个异常,则 返回一个 早期错误结果 用于 该 异常。
重要的是要提前执行此步骤,因为序列化可以调用Web开发人员代码,这反过来可能会更改我们在后续步骤中检查的各种内容。
如果 document 不是 完全活动,则返回一个 早期错误结果 用于
一个
"InvalidStateError
" DOMException
。
如果 document 的 卸载计数器 大于0,则
返回
一个
早期错误结果 用于
一个
"InvalidStateError
" DOMException
。
令 apiMethodTracker 是 可能设置即将到来的非遍历API方法跟踪器的结果,给定 此给定 info 和 serializedState。
导航
document 的 节点
可导航到 urlRecord 使用 document,历史处理设置为 options["history
"]
和 navigationAPIState 设置为
serializedState。
与 location.assign()
和类似方法不同,
它们暴露在 同源域
边界之外,
navigation.navigate()
只能由代码访问
具有直接同步访问 window.navigation
属性。因此,我们避免了关于归因于导航源文档的复杂情况,我们不需要处理 允许沙箱导航
检查及其随附的 exceptionsEnabled 标志。我们只是
将所有导航视为来自 Document
对应于此
Navigation
对象本身(即 document)。
如果 此的 即将到来的非遍历 API 方法跟踪器 是 apiMethodTracker,那么:
如果 即将到来的非遍历
API 方法跟踪器 仍然是
apiMethodTracker,这意味着 navigate 算法在
到达 内部
navigate
事件
触发算法 之前退出了,该算法会 将即将到来的API方法跟踪器提升为正在进行。
设置 此的 即将到来的 非遍历 API 方法跟踪器 为 null。
返回一个 早期错误结果 用于
一个 "AbortError
" DOMException
。
返回一个 导航 API 方法跟踪器派生结果, 用于 apiMethodTracker。
reload(options)
方法步骤如下:
令 document 是 此的 相关全局对象的 关联
Document
。
令 serializedState 为 StructuredSerializeForStorage(undefined)。
如果 options["state
"]
存在,则设置 serializedState 为
StructuredSerializeForStorage(options["state
"])。
如果这抛出一个异常,则
返回一个 早期错误结果 用于
该
异常。
重要的是要提前执行此步骤,因为序列化可以调用Web开发人员代码,这反过来可能会更改我们在后续步骤中检查的各种内容。
否则:
如果 document 不是
完全活动,则返回一个 早期错误结果 用于
一个
"InvalidStateError
" DOMException
。
如果 document 的 卸载计数器 大于0,则
返回
一个
早期错误结果 用于
一个
"InvalidStateError
" DOMException
。
令 apiMethodTracker 是 可能设置即将到来的非遍历API方法跟踪器的结果,给定 此给定 info 和 serializedState。
返回一个 导航 API 方法跟踪器派生结果, 用于 apiMethodTracker。
traverseTo(key, options)
方法步骤如下:
如果 此的 当前条目
索引 是 -1,则返回一个 早期
错误结果 用于 "InvalidStateError
"
DOMException
。
如果 此的 条目 列表 不
包含 一个
NavigationHistoryEntry
其 会话
历史条目 的 导航
API 键 等于 key,则返回一个 早期错误结果 用于
一个
"InvalidStateError
" DOMException
。
返回的结果是 执行导航 API 遍历 给定 此、key 和 options。
back(options)
方法步骤如下:
如果 此的 当前条目
索引 是 -1 或 0,则返回一个 早期错误结果 用于
一个
"InvalidStateError
" DOMException
。
返回的结果是 执行导航 API 遍历 给定 此、key 和 options。
forward(options)
方法步骤如下:
如果 此的 当前条目
索引 是 -1 或 等于 此的 条目 列表 的 大小 -
1,则返回一个 早期错误结果 用于
一个 "InvalidStateError
" DOMException
。
返回的结果是 执行导航 API 遍历 给定 此、key 和 options。
要 执行导航 API 遍历
给定 Navigation
navigation、字符串 key 和
NavigationOptions
options:
令 document 是 navigation 的 相关全局对象的
关联
Document
。
如果 document 不是 完全活动,则返回一个 早期错误结果 用于
一个
"InvalidStateError
" DOMException
。
如果 document 的 卸载计数器 大于0,则
返回
一个
早期错误结果 用于
一个
"InvalidStateError
" DOMException
。
令 current 是 当前条目 的 navigation。
如果 key 等于 current 的 会话历史
条目 的 导航 API 键,则返回 «[
"committed
"
→ 一个
解决的
承诺 current,"finished
"
→ 一个
解决的承诺 current ]»。
如果 navigation 的 即将到来的遍历 API 方法 跟踪器[key] 存在,则 返回 一个 导航 API 方法跟踪器派生结果 对于 navigation 的 即将到来的遍历 API 方法跟踪器[key]。
令 apiMethodTracker 是 添加即将到来的遍历API方法跟踪器的结果, 给定 navigation、key 和 info。
令 navigable 是 document 的 节点 可导航。
令 traversable 是 navigable 的 可遍历的 可导航。
令 sourceSnapshotParams 是 快照源快照参数的结果, 给定 document。
将以下会话历史遍历步骤附加到 traversable:
令 navigableSHEs 是 获取会话历史条目的结果, 给定 navigable。
令 targetSHE 是 会话历史条目在 navigableSHEs 中, 其 导航 API 键 是 key。如果不存在这样的条目,则:
在
导航和遍历任务源上排队一个全局任务,给定
navigation 的 相关全局对象,
以
拒绝完成的承诺
对于 apiMethodTracker,出现一个
"InvalidStateError
" DOMException
。
中止这些步骤。
如果 navigation 的 条目 列表已过时,则 会 走这条路径 相比于 navigableSHEs,在对历史变更做出反应时,所有相关线程和进程正在同步时,可能会出现短暂的时期。
如果 targetSHE 是 navigable 的 活动 会话历史条目,那么 中止这些 步骤。
如果之前 排队 遍历已经将我们带到此 会话历史条目,则可能会发生这种情况。 在这种情况下 先前的遍历已经处理了 apiMethodTracker。
令 result 是 应用遍历历史步骤的结果,
由 targetSHE 的 步骤 给出
traversable,给定
sourceSnapshotParams、
navigable 和 "none
"。
如果 result 是 "canceled-by-beforeunload
",则
在 导航和遍历任务源上排队一个全局任务,给定
navigation 的 相关全局对象,
拒绝完成的承诺 对于
apiMethodTracker,出现一个新的
"AbortError
" DOMException
创建于
navigation 的 相关领域。
如果 result 是 "initiator-disallowed
",则 在 导航和
遍历
任务源上排队一个全局任务,给定
navigation 的 相关全局对象,
拒绝完成的承诺 对于
apiMethodTracker,出现一个新的
"SecurityError
" DOMException
创建于
navigation 的 相关领域。
当 result 是 "canceled-by-beforeunload
" 或 "initiator-disallowed
" 时,
navigate
事件从未触发,中止正在进行的
导航 将是不正确的;它将导致一个 navigateerror
事件没有一个先前的 navigate
事件。
在 "canceled-by-navigate
" 的情况下,navigate
被 触发,但是 内部
navigate
事件触发算法 将负责
中止正在进行的
导航。
返回一个 导航 API 方法跟踪器派生结果 对于 apiMethodTracker。
早期错误结果 用于一个异常
e 是一个 NavigationResult
字典实例给定 «[ "committed
"
→ 一个
被拒绝的承诺
e,"finished
"
→ 一个
被拒绝的承诺 e ]»。
导航 API 方法跟踪器派生结果 对于
一个 导航 API 方法
跟踪器 是一个 NavigationResult
字典实例给定 «[ "committed
"
→ apiMethodTracker 的 已提交的承诺,
"finished
"
→ apiMethodTracker 的 完成的承诺 ]»。
在任何给定的导航期间(广义上的导航),Navigation
对象需要跟踪以下内容:
状态 | 持续时间 | 解释 |
---|---|---|
NavigateEvent
|
事件触发期间 | 这样如果导航在事件触发期间被取消,我们可以取消事件 |
事件的中止控制器 | 直到传递给intercept() 的处理程序返回的所有承诺都已解决
|
这样如果导航被取消,我们可以发送中止信号 |
是否有新的元素被聚焦 | 直到传递给intercept() 的处理程序返回的所有承诺都已解决
|
这样如果有新的元素被聚焦,焦点不会被重置 |
被导航到的NavigationHistoryEntry
|
从确定起,直到传递给intercept() 的处理程序返回的所有承诺都已解决
|
这样我们知道用什么来解决任何committed 和finished 承诺
|
任何返回的finished 承诺
|
直到传递给intercept() 的处理程序返回的所有承诺都已解决
|
这样我们可以适当地解决或拒绝它 |
状态 | 持续时间 | 解释 |
---|---|---|
任何state
|
事件触发期间 | 这样我们可以更新当前条目的导航API状态,如果事件在触发后没有被取消 |
状态 | 持续时间 | 解释 |
---|---|---|
任何info
|
直到任务被排队以触发navigate 事件
|
这样我们可以在经过会话历史遍历队列后使用它来触发navigate
|
任何返回的committed 承诺
|
直到会话历史被更新(在同一任务内) | 这样我们可以适当地解决或拒绝它 |
是否调用了intercept()
|
直到会话历史被更新(在同一任务内) | 这样我们可以抑制正常的滚动恢复逻辑,使用scroll 选项给出的行为
|
我们也不能假设任何给定时间内只有一个导航请求,因为网络开发人员代码可能会这样:
const p1 = navigation. navigate( url1). finished;
const p2 = navigation. navigate( url2). finished;
也就是说,在这种情况下,我们需要确保在导航到url2
的同时,我们仍然保留p1
的承诺,以便我们可以拒绝它。我们不能
在第二次调用navigate()
时立即移除任何正在进行的导航承诺。
我们通过将以下内容与每个Navigation
关联来实现这一点:
正在进行的navigate
事件,一个NavigateEvent
或null,初始为null。
正在进行的导航期间焦点更改,一个布尔值,初始为false。
正在进行的导航期间抑制正常滚动恢复,一个布尔值,初始为false。
正在进行的API方法跟踪器,一个导航API方法跟踪器或null,初始为null。
即将进行的非遍历API方法跟踪器,一个导航API方法跟踪器或null,初始为null。
即将进行的遍历API方法跟踪器,一个有序映射,从字符串到导航API方法跟踪器,初始为空。
此处未存储在导航API方法跟踪器中的状态是即使对于不是通过导航API方法启动的导航也需要跟踪的状态。
导航对象,一个Navigation
键,一个字符串或null
信息,一个JavaScript值
序列化状态,一个序列化状态或null
提交到条目,一个NavigationHistoryEntry
或null
提交的承诺,一个承诺
完成的承诺,一个承诺
所有这些状态然后通过以下算法进行管理。
要可能设置即将进行的非遍历API方法跟踪器,给定一个Navigation
navigation,一个JavaScript值info,以及一个序列化状态-或-nullserializedState:
让committedPromise和finishedPromise成为在navigation的相关领域中创建的新承诺。
标记为已处理finishedPromise。
让apiMethodTracker成为一个新的导航API方法跟踪器,具有:
断言:navigation的即将进行的非遍历API方法跟踪器为null。
如果navigation没有禁用条目和事件,则将navigation的即将进行的非遍历API方法跟踪器设置为apiMethodTracker。
如果navigation禁用条目和事件,则committedPromise和finishedPromise将永远不会实现(因为我们从未为这种Document
创建一个NavigationHistoryEntry
对象,所以我们没有什么可以用来解决它们);没有NavigationHistoryEntry
可以应用serializedState;也没有navigate
事件可以包含info。因此,我们不需要跟踪这个API方法调用。
返回apiMethodTracker。
要添加一个即将进行的遍历API方法跟踪器,给定一个Navigation
navigation,一个字符串destinationKey,以及一个JavaScript值info:
让committedPromise和finishedPromise成为在navigation的相关领域中创建的新承诺。
标记为已处理finishedPromise。
参见前面的讨论关于为什么这样做。
让apiMethodTracker成为一个新的导航API方法跟踪器,具有:
将navigation的即将进行的遍历API方法跟踪器[key]设置为apiMethodTracker。
返回apiMethodTracker。
要将即将进行的API方法跟踪器提升为正在进行,给定一个Navigation
navigation和一个字符串或nulldestinationKey:
断言:navigation的正在进行的API方法跟踪器为null。
如果destinationKey不为null,则:
断言:navigation的即将进行的非遍历API方法跟踪器为null。
如果navigation的即将进行的遍历API方法跟踪器[destinationKey] 存在,则:
将navigation的正在进行的API方法跟踪器设置为navigation的即将进行的遍历API方法跟踪器[destinationKey]。
移除navigation的即将进行的遍历API方法跟踪器[destinationKey]。
否则:
将navigation的正在进行的API方法跟踪器设置为navigation的即将进行的非遍历API方法跟踪器。
将navigation的即将进行的非遍历API方法跟踪器设置为null。
要清理一个导航API方法跟踪器 apiMethodTracker:
让navigation成为apiMethodTracker的导航对象。
如果navigation的正在进行的API方法跟踪器是apiMethodTracker,则将navigation的正在进行的API方法跟踪器设置为null。
否则:
让key成为apiMethodTracker的键。
断言:key不为null。
断言:navigation的即将进行的遍历API方法跟踪器[key] 存在。
移除navigation的即将进行的遍历API方法跟踪器[key]。
要通知提交到条目,给定一个导航API方法跟踪器
apiMethodTracker和一个NavigationHistoryEntry
nhe:
将apiMethodTracker的提交到条目设置为nhe。
如果apiMethodTracker的序列化状态不为null,则将nhe的会话历史条目的导航API状态设置为apiMethodTracker的序列化状态。
如果为null,则我们通过navigation.traverseTo()
遍历到nhe,这不允许更改状态。
在此时,apiMethodTracker的序列化状态不再需要。实现可能希望清除它以 避免在导航API方法跟踪器的生命周期内保持它。
用nhe解决apiMethodTracker的提交的承诺。
在此时,apiMethodTracker的提交的承诺仅在尚未返回给作者代码的情况下需要。实现可能希望清除它以避免在导航API方法跟踪器的生命周期内保持它。
要解决完成的承诺,对于一个导航API方法跟踪器 apiMethodTracker:
用其提交到条目解决apiMethodTracker的提交的承诺。
通常,通知提交到条目先前已经在apiMethodTracker上被调用,因此这将什么都不做。然而,在某些情况下,解决完成的承诺直接被调用,在这种情况下,这一步是必要的。
清理apiMethodTracker。
要拒绝完成的承诺,对于一个导航API方法跟踪器 apiMethodTracker,以及一个JavaScript值exception:
要中止正在进行的导航,给定一个Navigation
navigation和一个可选的DOMException
error:
让event成为navigation的正在进行的navigate
事件。
断言:event不为null。
将navigation的正在进行的导航期间焦点更改设置为false。
将navigation的正在进行的导航期间抑制正常滚动恢复设置为false。
如果未给出error,则让error成为在navigation的相关领域中创建的新的"AbortError
" DOMException
。
将navigation的正在进行的navigate
事件设置为null。
让 errorInfo 成为从 error 中提取错误信息的结果。
例如,如果因为调用 window.stop()
达到该算法,那么这些属性可能最终会根据调用 window.stop()
的脚本行初始化。但如果是因为用户点击了停止按钮,这些属性可能最终会使用默认值,如空字符串或0。
触发一个名为 navigateerror
的事件在 navigation 上,使用
ErrorEvent
,并根据
errorInfo 初始化附加属性。
如果navigation的过渡不为null,则:
要通知导航API关于中止导航在一个可导航对象 navigable:
如果此算法正在navigable的活动窗口的相关代理的事件循环上运行,则继续执行以下步骤。否则,在 navigable的活动窗口上排队一个全局任务,给定导航和遍历任务源。
如果navigation的正在进行的navigate
事件为null,则返回。
中止正在进行的导航,给定navigation。
要通知导航API关于子可导航对象的销毁,给定一个可导航对象 navigable:
通知导航API关于中止导航在navigable。
让traversalAPIMethodTrackers成为navigation的即将进行的遍历API方法跟踪器的克隆。
对于每个
apiMethodTracker在traversalAPIMethodTrackers中:拒绝完成的承诺,对于apiMethodTracker,给定一个新的"AbortError
" DOMException
,在navigation的相关领域中创建。
正在进行的导航概念最直接地通过navigation.transition
属性暴露给网络开发人员,这是NavigationTransition
接口的一个实例:
[Exposed =Window ]
interface NavigationTransition {
readonly attribute NavigationType navigationType ;
readonly attribute NavigationHistoryEntry from ;
readonly attribute Promise <undefined > finished ;
};
navigation.transition
一个NavigationTransition
,表示任何尚未到达navigatesuccess
或navigateerror
阶段的正在进行的导航(如果存在);如果没有这样的过渡正在进行,则为null。
由于navigation.currentEntry
(以及location.href
等其他属性)在导航时立即更新,此navigation.transition
属性对于确定这样的导航何时尚未完全解决,根据传递给navigateEvent.intercept()
的任何处理程序非常有用。
navigation.transition.navigationType
navigation.transition.from
此过渡来自的NavigationHistoryEntry
。这对于与navigation.currentEntry
进行比较很有用。
navigation.transition.finished
一个承诺,在navigatesuccess
事件触发时实现,或在navigateerror
事件触发时被拒绝。
每个Navigation
都有一个过渡,这是一个NavigationTransition
或null,初始为null。
每个NavigationTransition
都有一个关联的导航类型,这是一个NavigationType
。
每个NavigationTransition
都有一个关联的来自条目,这是一个NavigationHistoryEntry
。
每个NavigationTransition
都有一个关联的完成的承诺,这是一个承诺。
navigationType
获取步骤是返回this的导航类型。
NavigationActivation
接口[Exposed =Window ]
interface NavigationActivation {
readonly attribute NavigationHistoryEntry ? from ;
readonly attribute NavigationHistoryEntry entry ;
readonly attribute NavigationType navigationType ;
};
navigation.activation
NavigationActivation
,包含最近一次跨文档导航的信息,即“激活”此Document
的导航。
虽然navigation.currentEntry
和Document
的URL可以由于同一文档导航而定期更新,但navigation.activation
保持不变,并且其属性仅在Document
从历史中重新激活时才会更新。
navigation.activation.entry
NavigationHistoryEntry
,等同于navigation.currentEntry
属性在Document
激活时的值。
navigation.activation.from
一个 NavigationHistoryEntry
,
代表了在当前 Document
之前活跃的 Document
。
如果前一个 Document
与当前文档不是同源,或是
初始
about:blank
Document
,那么这个值将为
null。
有些情况下,from
或 entry
NavigationHistoryEntry
对象不适合用作 traverseTo()
方法的目标,因为它们可能不会保留在历史记录中。例如,Document
可以通过 location.replace()
或初始条目被 history.replaceState()
替换来激活。
然而,这些条目的 url
属性和 getState()
方法仍然可以访问。
navigation.activation.navigationType
每个Navigation
都有一个关联的activation,其值为null或NavigationActivation
对象,初始值为null。
每个NavigationActivation
具有:
旧条目,null或NavigationHistoryEntry
。
新条目,null或NavigationHistoryEntry
。
导航类型,NavigationType
。
activation
获取器步骤是返回this的activation。
navigationType
获取器步骤是返回this的导航类型。
navigate
事件导航API的一个主要功能是navigate
事件。该事件在任何导航(在广义上)上触发,允许Web开发者监控此类外出导航。在许多情况下,该事件是可取消的
,这允许防止导航发生。而在其他情况下,可以使用intercept()
方法拦截导航并用同一文档导航替换NavigateEvent
类。
NavigateEvent
接口[Exposed =Window ]
interface NavigateEvent : Event {
constructor (DOMString type , NavigateEventInit eventInitDict );
readonly attribute NavigationType navigationType ;
readonly attribute NavigationDestination destination ;
readonly attribute boolean canIntercept ;
readonly attribute boolean userInitiated ;
readonly attribute boolean hashChange ;
readonly attribute AbortSignal signal ;
readonly attribute FormData
? formData ;
readonly attribute DOMString ? downloadRequest ;
readonly attribute any info ;
readonly attribute boolean hasUAVisualTransition ;
undefined intercept (optional NavigationInterceptOptions options = {});
undefined scroll ();
};
dictionary NavigateEventInit : EventInit {
NavigationType navigationType = "push";
required NavigationDestination destination ;
boolean canIntercept = false ;
boolean userInitiated = false ;
boolean hashChange = false ;
required AbortSignal signal ;
FormData ? formData = null ;
DOMString ? downloadRequest = null ;
any info ;
boolean hasUAVisualTransition = false ;
};
dictionary NavigationInterceptOptions {
NavigationInterceptHandler handler ;
NavigationFocusReset focusReset ;
NavigationScrollBehavior scroll ;
};
enum NavigationFocusReset {
" after-transition " ,
" manual "
};
enum NavigationScrollBehavior {
" after-transition " ,
" manual "
};
callback NavigationInterceptHandler = Promise <undefined > ();
event.navigationType
event.destination
表示导航目标的NavigationDestination
对象。
event.canIntercept
如果可以调用intercept()
来拦截该导航并将其转换为同一文档导航,替换其通常行为,则为true;否则为false。
一般来说,当当前Document
可以将其URL重写为目标URL时,这将为true,除了跨文档"traverse
"导航,在这种情况下,它将始终为false。
event.userInitiated
event.hashChange
对于片段导航
为true;否则为false。
event.signal
如果导航被取消,例如用户按下浏览器的“停止”按钮或另一个导航中断了此导航,此AbortSignal
将被中止。
预期模式是开发者将此信号传递给任何异步操作,如fetch()
,作为处理此导航的一部分。
event.formData
如果此导航是代表POST表单提交的"push
"或"replace
"导航,则表示提交的表单条目的FormData
;否则为null。
(特别是,对于重新加载"reload
"或重新访问由表单提交创建的会话历史条目
的"traverse
"导航,这将为null。)
event.downloadRequest
表示是否请求此导航为下载,使用a
或area
元素的download
属性:
如果未请求下载,则此属性为null。
如果请求下载,则返回作为download
属性值提供的文件名。(这可能是空字符串。)
请注意,请求下载并不总是意味着下载会发生:例如,下载可能会被浏览器安全策略阻止,或由于未指定的原因,最终被视为“push
”导航。
同样,导航即使没有请求下载,也可能最终成为下载,因为目标服务器以Content-Disposition: attachment
头响应。
最后,请注意,使用浏览器UI发起的下载(例如,通过右键点击并选择保存链接的目标)不会触发navigate
事件。
event.info
通过发起此导航的导航API方法传递的任意JavaScript值,如果导航是由用户或其他API发起的,则为undefined。
event.hasUAVisualTransition
如果用户代理在分派此事件之前为此导航执行了视觉过渡,则返回true。如果为true,最佳用户体验是作者同步更新DOM到导航后的状态。
event.intercept({ handler, focusReset, scroll })
拦截此导航,防止其正常处理,而是将其转换为同类型的同一文档导航到目标URL。
handler
选项可以是返回promise的函数。处理程序函数将在navigate
事件触发后运行,并且navigation.currentEntry
属性已同步更新。此返回的promise用于指示导航的持续时间和成功或失败。它解决后,浏览器通过加载旋转UI或辅助技术向用户发出导航完成的信号。此外,还会触发navigatesuccess
或navigateerror
事件,Web应用程序的其他部分可以响应。
默认情况下,使用此方法将在任何处理程序返回的promise解决时重置焦点。焦点将重置到第一个设置了autofocus
属性的元素,或者如果未设置该属性,则重置到body元素。focusReset
选项可以设置为“manual
”以避免此行为。
默认情况下,使用此方法将延迟浏览器的滚动恢复逻辑,用于“traverse
”或“reload
”导航,或在处理程序返回的promise解决之前,“push
”或“replace
”导航的滚动重置/滚动到片段逻辑。scroll
选项可以设置为“manual
”以完全关闭此导航的任何浏览器驱动的滚动行为,或在promise解决之前调用scroll()
来提前触发此行为。
如果canIntercept
为false,或isTrusted
为false,则此方法将抛出“
SecurityError
”DOMException
。如果在事件分派期间不同步调用它,将抛出“
InvalidStateError
”DOMException
。
event.scroll()
对于“traverse
”或“reload
”导航,使用浏览器的常规滚动恢复逻辑恢复滚动位置。
对于“push
”或“replace
”导航,或将滚动位置重置到文档顶部,或滚动到片段
,如果有的话。
如果多次调用,或在由于scroll
选项保留为“after-transition
”而导致的自动后滚动处理之后调用,或在导航提交之前调用,此方法将抛出“
InvalidStateError
”DOMException
。
每个NavigateEvent
都有一个拦截状态,可以是"none
"、"intercepted
"、"committed
"、"scrolled
"或"finished
",初始值为"none
"。
每个NavigateEvent
都有一个导航处理程序列表,一个NavigationInterceptHandler
回调的列表,初始为空。
每个NavigateEvent
都有一个焦点重置行为,一个NavigationFocusReset
或null,初始值为null。
每个NavigateEvent
都有一个滚动行为,一个NavigationScrollBehavior
或null,初始值为null。
每个NavigateEvent
都有一个中止控制器,一个AbortController
或null,初始值为null。
每个NavigateEvent
都有一个经典历史API状态,一个序列化状态或null。仅在某些情况下使用,其中事件的navigationType
为"push
"或"replace
",并在事件触发时适当设置。
navigationType
,destination
,canIntercept
,userInitiated
,hashChange
,signal
,formData
,downloadRequest
,info
,以及hasUAVisualTransition
属性必须返回其初始化的值。
intercept(options)
方法步骤为:
如果this的canIntercept
属性初始化为false,则抛出一个"SecurityError
"DOMException
。
如果this的dispatch标志未设置,则抛出一个"InvalidStateError
"DOMException
。
如果options["focusReset
"]存在,则:
如果this的焦点重置行为不为null,并且不等于options["focusReset
],则用户代理可以向控制台报告警告,指出之前调用intercept()
的focusReset
选项被新值覆盖,并且之前的值将被忽略。
将this的焦点重置行为设置为options["focusReset
]。
scroll()
方法步骤为:
如果this的拦截状态不是"committed
",则抛出一个"InvalidStateError
"DOMException
。
为了NavigateEvent
event 执行共享检查:
如果event的相关全局对象
的关联的
不是Document
完全活动
,则抛出“
InvalidStateError
”DOMException
。
如果event的isTrusted
属性初始化为false,则抛出“
SecurityError
”DOMException
。
如果event的取消标志
已设置,则抛出“
InvalidStateError
”DOMException
。
NavigationDestination
接口[Exposed =Window ]
interface NavigationDestination {
readonly attribute USVString url ;
readonly attribute DOMString key ;
readonly attribute DOMString id ;
readonly attribute long long index ;
readonly attribute boolean sameDocument ;
any getState ();
};
event.destination.url
正在导航到的 URL。
event.destination.key
目标 NavigationHistoryEntry
的 key
属性的值,
如果这是一个 "traverse
"
导航,否则为空字符串。
event.destination.id
目标 NavigationHistoryEntry
的 id
属性的值,
如果这是一个 "traverse
"
导航,否则为空字符串。
event.destination.index
目标 NavigationHistoryEntry
的 index
属性的值,
如果这是一个 "traverse
"
导航,否则为 −1。
event.destination.sameDocument
指示此次导航是否是到与当前 Document
相同的文档。例如,在片段导航或 history.pushState()
导航中,这将为 true。
注意,此属性指示导航的原始性质。如果使用 navigateEvent.intercept()
将跨文档导航转换为同文档导航,不会改变此属性的值。
event.destination.getState()
对于 "traverse
"
导航,返回存储在目标 会话历史条目 中的状态的
反序列化。
对于 "push
"
或 "replace
"
导航,返回传递给 navigation.navigate()
的状态的
反序列化,如果导航是由该方法启动的,否则返回 undefined。
对于 "reload
"
导航,返回传递给 navigation.reload()
的状态的
反序列化,如果重新加载是由该方法启动的,否则返回 undefined。
每个 NavigationDestination
都有一个 URL,即 URL。
每个 NavigationDestination
都有一个 entry,即
NavigationHistoryEntry
或 null。
只有当 NavigationDestination
对应一个 "traverse
"
导航时,它才会是非 null。
每个 NavigationDestination
都有一个 state,即 序列化状态。
每个 NavigationDestination
都有一个 is same document,即布尔值。
url
getter 步骤是返回
this 的 URL,序列化。
key
getter 步骤是:
id
getter 步骤是:
index
getter 步骤是:
sameDocument
getter 步骤是返回
this 的 is same document。
getState()
方法步骤是返回
StructuredDeserialize(this 的 state)。
标准的其他部分通过本节中给出的一系列包装算法触发 navigate
事件。
要在给定 会话历史条目 destinationSHE 和一个可选的 用户导航参与 userInvolvement(默认 "none
")的情况下在 Navigation
navigation 上触发 traverse navigate
事件:
让 event 成为 创建事件 的结果,给定
NavigateEvent
,
在 navigation 的 相关领域 中。
将 event 的 经典历史 API 状态 设置为 null。
让 destination 成为 新的 NavigationDestination
,在 navigation 的 相关领域 中创建。
让 destinationNHE 成为 NavigationHistoryEntry
,在
navigation 的 条目列表 中,其 会话历史条目 是
destinationSHE,如果不存在这样的
NavigationHistoryEntry
,
则为 null。
如果 destinationNHE 非 null,则:
将 destination 的 entry 设置为 destinationNHE。
将 destination 的 state 设置为 destinationSHE 的 navigation API state。
否则,
将 destination 的 entry 设置为 null。
将 destination 的 state 设置为 StructuredSerializeForStorage(null)。
将 destination 的 is
same document 设置为 true,如果 destinationSHE 的 document 等于 navigation 的 相关全局对象 的 关联
Document
;
否则为 false。
返回执行 内部 navigate
事件触发算法 的结果,给定
navigation,"traverse
",
event,destination,userInvolvement,null 和 null。
要在给定 NavigationType
navigationType、一个 URL destinationURL、一个布尔值 isSameDocument、一个可选的 用户导航参与
userInvolvement
(默认
"none
")、一个可选的 条目
列表-或-null formDataEntryList(默认
null),
一个
可选的 序列化
状态 navigationAPIState(默认
StructuredSerializeForStorage(null)),以及一个可选的 序列化
状态-或-null classicHistoryAPIState
(默认
null)的情况下在 Navigation
navigation 上触发 push/replace/reload
navigate
事件:
让 event 成为 创建事件 的结果,给定
NavigateEvent
,
在 navigation 的 相关领域 中。
将 event 的 经典历史 API 状态 设置为 classicHistoryAPIState。
让 destination 成为 新的 NavigationDestination
,在 navigation 的 相关领域 中创建。
将 destination 的 URL 设置为 destinationURL。
将 destination 的 entry 设置为 null。
将 destination 的 state 设置为 navigationAPIState。
将 destination 的 is same document 设置为 isSameDocument。
返回执行 内部 navigate
事件触发
算法 的结果,给定
navigation、navigationType、event、destination、
userInvolvement、formDataEntryList 和 null。
要在给定 URL destinationURL、一个
用户导航参与 userInvolvement 和一个字符串
filename 的情况下在 Navigation
navigation 上触发下载请求 navigate
事件:
让 event 成为 创建事件 的结果,给定
NavigateEvent
,
在 navigation 的 相关领域 中。
将 event 的 经典历史 API 状态 设置为 null。
让 destination 成为 新的 NavigationDestination
,
在 navigation 的 相关领域 中创建。
将 destination 的 URL 设置为 destinationURL。
将 destination 的 entry 设置为 null。
将 destination 的 state 设置为 StructuredSerializeForStorage(null)。
将 destination 的 is same document 设置为 false。
返回执行 内部 navigate
事件触发
算法 的结果,给定
navigation,"push
",
event、
destination、userInvolvement、null 和 filename。
内部 navigate
事件触发算法
包括以下步骤,给定 Navigation
navigation、
NavigationType
navigationType、NavigateEvent
event、NavigationDestination
destination、用户导航参与 userInvolvement、一个 条目 列表-或-null
formDataEntryList 和一个字符串或-null downloadRequestFilename:
如果 navigation 禁用条目和事件,则:
断言:navigation 的 正在进行的 API 方法追踪器 为 null。
断言:navigation 的 即将进行的非 traverse API 方法追踪器 为 null。
断言:navigation 的 即将进行的 traverse API 方法追踪器 为空。
返回 true。
这些断言成立是因为 traverseTo()
,
back()
和 forward()
将在禁用条目和事件时立即失败(因为没有条目可以遍历),如果我们的起点是
navigate()
或 reload()
,
那么我们就避免
设置
即将进行的非 traverse API 方法追踪器。
将 destinationKey 设置为 null。
如果 destination 的 entry 非 null,则将 destinationKey 设置为 destination 的 entry 的 key。
断言:destinationKey 不是空字符串。
给定 navigation 和 destinationKey,将即将进行的 API 方法追踪器提升为正在进行。
让 apiMethodTracker 成为 navigation 的 正在进行的 API 方法追踪器。
让 document 成为 navigation 的 相关全局对象 的
关联
Document
。
如果 document 可以重写其 URL 为
destination 的
URL,并且 destination 的
is same document 为 true 或者
navigationType 不是 "traverse
",
则将 event 的 canIntercept
初始化为 true。否则,将其初始化为
false。
如果以下任一条件成立:
navigationType 不是 "traverse
";
traverseCanBeCanceled 为 true,
则将 event 的 cancelable
初始化为
true。否则,将其初始化为 false。
将 event 的 navigationType
初始化为
navigationType。
将 event 的 destination
初始化为 destination。
将 event 的 downloadRequest
初始化为
downloadRequestFilename。
如果 apiMethodTracker 不是 null,则将 event 的 info
初始化为 apiMethodTracker 的 信息。否则,将其初始化为
undefined。
此时 apiMethodTracker 的 信息 不再需要,可以将其设为 null,而不是保持其在导航 API 方法 追踪器的整个生命周期中存活。
将 event 的 hasUAVisualTransition
初始化为 true,如果用户代理显示了document 的 最新
条目的缓存渲染状态。否则,将其初始化为 false。
将 event 的 中止控制器 设置为 新的
AbortController
,
在
navigation 的 相关领域 中创建。
将 currentURL 设置为 document 的 URL。
如果以下所有条件都成立:
event 的 经典历史 API 状态 是 null;
destination 的 is same document 是 true;
则将 event 的 hashChange
初始化为 true。否则,将其初始化为
false。
此处的第一个条件意味着 hashChange
对于 片段导航 为
true,但对于
history.pushState(undefined, "", "#fragment")
之类的情况为 false。
如果 userInvolvement 不是 "none
",则将
event 的 userInitiated
初始化为 true。否则,将其初始化为 false。
如果 formDataEntryList 不是 null,则将 event 的 formData
初始化为 新的
FormData
,
在 navigation 的 相关领域 中创建,
与 formDataEntryList 关联。否则,将其初始化为 null。
断言:navigation 的 正在进行的
navigate
事件 为 null。
将 navigation 的 正在进行的 navigate
事件 设置为 event。
将 navigation 的 在正在进行的导航期间更改焦点 设置为 false。
将 navigation 的 在正在进行的导航期间抑制正常滚动恢复 设置为 false。
让 dispatchResult 成为 分发 event 的结果, 在 navigation 上。
如果 dispatchResult 为 false:
让 endResultIsSameDocument 为 true,如果 event 的 拦截状态 不是
"none
" 或 event 的 destination
的
is same document 为 true。
如果 event 的 拦截
状态 不是 "none
":
将 event 的 拦截状态 设置为
"committed
"。
让 fromNHE 成为 当前 条目 的 navigation。
断言:fromNHE 不是 null。
将 navigation 的 过渡 设置为 新的
NavigationTransition
,
在 navigation 的 相关领域 中创建,其 导航类型 是
navigationType,其 来自条目
是 fromNHE,其 完成的
promise 是在 navigation 的 相关领域 中创建的一个新 promise。
标记 为 已处理 navigation 的 过渡 的 完成的 promise。
请参阅有关其他完成的 promise 的讨论 以了解为什么要这样 做。
如果 navigationType 是 "traverse
",
则将 navigation 的
在正在进行的导航期间抑制正常滚动恢复
设置为 true。
如果 event 的 滚动
行为 设置为 "过渡后
",
则滚动
恢复将在 完成
相关 NavigateEvent
时发生。
否则,将不会有滚动恢复。也就是说,
没有通过 intercept()
拦截的导航会经过正常的滚动
恢复过程;此类导航的滚动恢复要么是手动完成的,由 Web 开发人员完成,要么是在过渡后完成的。
如果 navigationType 是 "push
"
或
"replace
",
则运行 URL
和历史
更新步骤,给定 document 和 event 的 destination
的
URL,serialiedData 设置为
event 的
经典历史 API
状态,并且
historyHandling
设置为
navigationType。
如果 navigationType 是 "reload
",
则我们将 重载 转换为
"同一文档重载",对于此类重载,
URL
和历史更新步骤 不适用。
仍然会发生与导航 API 相关的事情,例如更新 活动会话
历史条目 的 导航
API 状态,如果
这是由于调用 navigation.reload()
引起的,以及所有的 正在进行的导航跟踪。
如果 navigationType 是 "traverse
",
则此事件触发作为 遍历过程的一部分,
该过程将负责执行适当的会话历史条目更新。
如果 endResultIsSameDocument 为 true:
让 promisesList 成为空的 列表。
如果 promisesList 的 大小 为 0,则将 promisesList 设置为 « 一个以 undefined 解决的 promise »。
在给定零个 promise 与给定≥1个 promise 时,等待所有安排其成功和失败步骤之间存在细微的时间差异。对于大多数使用 等待所有 的情况,
这并不重要。然而,对于此 API,可能会同时触发许多事件和 promise 处理程序,这种差异很容易观察到:它可能
导致事件/promise 处理程序顺序变化。(涉及的某些事件和 promise 包括:navigatesuccess
/ navigateerror
,
currententrychange
,
dispose
,
apiMethodTracker 的 promise,以及 navigation.transition.finished
的 promise。)
等待所有 promisesList,具有以下成功步骤:
断言:event 等于 navigation 的 正在进行的
navigate
事件。
将 navigation 的 正在进行的 navigate
事件 设置为 null。
完成 event,给定 true。
触发事件
命名为 navigatesuccess
在 navigation 上。
如果 apiMethodTracker 不是 null,则 解决完成的 promise 为 apiMethodTracker。
如果 navigation 的 过渡 不是 null,则 解析 navigation 的 过渡 的 完成的 promise 与 undefined。
将 navigation 的 过渡 设置为 null。
并且以下失败步骤给定原因 rejectionReason:
断言:event 等于 navigation 的正在进行的
navigate
事件。
将 navigation 的正在进行的 navigate
事件 设置为 null。
完成 event 给定 false。
让 errorInfo 成为从 rejectionReason 中提取错误信息的结果。
触发一个事件,名为
navigateerror
,在
navigation 上,使用
ErrorEvent
,并根据
errorInfo 初始化附加属性。
如果 apiMethodTracker 非 null,则使用 rejectionReason拒绝完成的 promise为 apiMethodTracker。
如果 navigation 的过渡不为 null,则使用 rejectionReason 拒绝 navigation 的过渡的完成的 promise。
将 navigation 的过渡设置为 null。
否则,如果 apiMethodTracker 不是 null,则 清理 apiMethodTracker。
运行脚本后清理,给定 navigation 的 相关 设置对象。
根据前述说明, 这将停止抑制任何潜在的 promise 处理程序微任务,导致它们在此时或之后运行。
如果 event 的 拦截
状态 是 "none
",则返回 true。
返回 false。
通过调用navigateEvent.intercept()
,
Web 开发人员可以抑制同一文档导航的正常滚动和焦点行为,
而是在稍后的时间点调用类似跨文档导航的行为。本节中的算法在这些适当的稍后时间点调用。
要完成一个NavigateEvent
event,给定一个布尔值 didFulfill:
如果 event 的 拦截
状态 是 "none
",则返回。
可能重置焦点给定 event。
如果 didFulfill 为 true,则 可能处理滚动行为 给定 event。
将 event 的 拦截状态设置为
"finished
"。
要可能重置焦点给定一个NavigateEvent
event:
让 focusChanged 成为 navigation 的 在进行中的导航期间焦点改变。
将 navigation 的 在进行中的导航期间焦点改变设置为 false。
如果 focusChanged 为 true,则返回。
如果 event 的 焦点重置
行为是 "manual
",
则返回。
如果它留作 null,那么我们将其视为 "after-transition
",
并继续
前进。
让 document 成为 event 的 相关全局对象的 关联的Document
。
让 focusTarget 成为 document 的 自动聚焦委托。
如果 focusTarget 为 null,则将 focusTarget 设置为 document 的 body 元素。
如果 focusTarget 为 null,则将 focusTarget 设置为 document 的 document 元素。
将 顺序焦点导航起点移动到 focusTarget。
要可能处理滚动行为给定一个NavigateEvent
event:
如果 event 的 拦截
状态是 "scrolled
",则返回。
如果 event 的 滚动行为是
"manual
",
则返回。
如果它留作 null,那么我们将其视为 "after-transition
",
并继续
前进。
处理滚动行为给定 event。
要处理滚动行为给定一个NavigateEvent
event:
将 event 的 拦截状态设置为
"scrolled
"。
如果 event 的 navigationType
初始化为 "traverse
"
或 "reload
",
则恢复滚动位置数据,
给定 event 的 相关全局对象 的 可导航对象 的
活动会话历史条目。
否则:
让 document 成为 event 的 相关全局对象的
关联的
Document
。
如果 document 的 指示部分是 null,则 滚动到文档的开头,给定 document。[CSSOMVIEW]
否则,滚动到片段标识符,给定 document。
由于其复杂性,NavigateEvent
接口有自己的专门部分。
NavigationCurrentEntryChangeEvent
接口
[Exposed =Window ]
interface NavigationCurrentEntryChangeEvent : Event {
constructor (DOMString type , NavigationCurrentEntryChangeEventInit eventInitDict );
readonly attribute NavigationType ? navigationType ;
readonly attribute NavigationHistoryEntry from ;
};
dictionary NavigationCurrentEntryChangeEventInit : EventInit {
NavigationType ? navigationType = null ;
required NavigationHistoryEntry from ;
};
event.navigationType
返回导致当前条目更改的导航类型,如果更改是由于 navigation.updateCurrentEntry()
,
则返回 null。
event.from
返回 navigation.currentEntry
在当前条目更改之前的先前值。
如果 navigationType
是 null 或 "reload
",
那么此值将与 navigation.currentEntry
相同。在这种情况下,事件表明条目的内容已更改,即使我们没有移动到新条目或替换当前条目。
navigationType
和 from
属性必须返回它们初始化时的值。
PopStateEvent
接口支持所有当前引擎。
支持所有当前引擎。
[Exposed =Window ]
interface PopStateEvent : Event {
constructor (DOMString type , optional PopStateEventInit eventInitDict = {});
readonly attribute any state ;
readonly attribute boolean hasUAVisualTransition ;
};
dictionary PopStateEventInit : EventInit {
any state = null ;
boolean hasUAVisualTransition = false ;
};
event.state
Support in all current engines.
返回提供给pushState()
或replaceState()
的信息的副本。
event.hasUAVisualTransition
如果用户代理在分派此事件之前执行了视觉过渡,则返回true。如果为true,最佳用户体验是作者同步更新DOM到导航后的状态。
state
属性必须返回它被初始化时的值。它表示事件的上下文信息,如果所代表的状态是文档
的初始状态,则为null。
hasUAVisualTransition
属性必须返回它被初始化时的值。
HashChangeEvent
接口HashChangeEvent/HashChangeEvent
Support in all current engines.
Support in all current engines.
[Exposed =Window ]
interface HashChangeEvent : Event {
constructor (DOMString type , optional HashChangeEventInit eventInitDict = {});
readonly attribute USVString oldURL ;
readonly attribute USVString newURL ;
};
dictionary HashChangeEventInit : EventInit {
USVString oldURL = "";
USVString newURL = "";
};
event.oldURL
Support in all current engines.
event.newURL
Support in all current engines.
oldURL
属性必须返回它被初始化时的值。它表示事件的上下文信息,特别是从中遍历的会话历史条目的URL。
newURL
属性必须返回它被初始化时的值。它表示事件的上下文信息,特别是遍历到的会话历史条目的URL。
PageSwapEvent
接口[Exposed =Window ]
interface PageSwapEvent : Event {
constructor (DOMString type , optional PageSwapEventInit eventInitDict = {});
readonly attribute NavigationActivation
? activation ;
readonly attribute ViewTransition
? viewTransition ;
};
dictionary PageSwapEventInit : EventInit {
NavigationActivation ? activation = null ;
ViewTransition
? viewTransition = null ;
};
event.activation
一个代表跨文档导航目标和类型的NavigationActivation
对象。对于跨域导航,这将为null。
event.activation.entry
一个代表即将变为活动状态的NavigationHistoryEntry
的文档
。
event.activation.from
一个等同于事件触发时navigation.currentEntry
属性值的NavigationHistoryEntry
。
event.activation.navigationType
event.viewTransition
返回一个ViewTransition
对象,该对象表示事件触发时活动的出站跨文档视图转换。如果没有此类转换,则返回null。
activation
属性和viewTransition
属性必须返回它们被初始化时的值。
PageRevealEvent
接口[Exposed =Window ]
interface PageRevealEvent : Event {
constructor (DOMString type , optional PageRevealEventInit eventInitDict = {});
readonly attribute ViewTransition
? viewTransition ;
};
dictionary PageRevealEventInit : EventInit {
ViewTransition
? viewTransition = null ;
};
event.viewTransition
返回一个ViewTransition
对象,该对象表示事件触发时活动的入站跨文档视图转换。如果没有此类转换,则返回null。
viewTransition
属性必须返回它被初始化时的值。
PageTransitionEvent
接口PageTransitionEvent/PageTransitionEvent
Support in all current engines.
Support in all current engines.
[Exposed =Window ]
interface PageTransitionEvent : Event {
constructor (DOMString type , optional PageTransitionEventInit eventInitDict = {});
readonly attribute boolean persisted ;
};
dictionary PageTransitionEventInit : EventInit {
boolean persisted = false ;
};
event.persisted
Support in all current engines.
对于pageshow
事件,如果页面是新加载的(并且将触发load
事件),则返回false。否则,返回true。
对于pagehide
事件,如果页面最后一次消失,则返回false。否则,返回true,表示如果用户导航回此页面,该页面可能会被重用(如果文档
的可挽救状态保持为true)。
导致页面不可挽救的因素包括:
persisted
属性必须返回它被初始化时的值。它表示事件的上下文信息。
要在窗口
window上触发一个名为eventName的页面转换事件,并带有一个布尔值persisted,请在window上触发一个名为eventName的事件,使用PageTransitionEvent
,将persisted
属性初始化为persisted,将cancelable
属性初始化为true,将bubbles
属性初始化为true,并设置legacy
target override flag。
cancelable
和bubbles
的值没有意义,因为取消事件无济于事,且不可能超过窗口
对象冒泡。它们被设置为true是出于历史原因。
BeforeUnloadEvent
接口Support in all current engines.
[Exposed =Window ]
interface BeforeUnloadEvent : Event {
attribute DOMString returnValue ;
};
没有BeforeUnloadEvent
特定的初始化方法。
BeforeUnloadEvent
接口是一个遗留接口,它不仅允许通过取消事件来控制检查是否取消卸载,还可以通过将returnValue
属性设置为空字符串以外的值来控制。作者应该使用preventDefault()
方法或其他取消事件的手段,而不是使用returnValue
。
returnValue
属性控制检查是否取消卸载的过程。当事件被创建时,该属性必须被设置为空字符串。在获取时,它必须返回最后设置的值。在设置时,该属性必须被设置为新值。
这个属性是DOMString
仅仅是出于历史原因。任何除了空字符串以外的值都会被视为请求用户确认。
NotRestoredReasons
接口[Exposed =Window ]
interface NotRestoredReasonDetails {
readonly attribute DOMString reason ;
[Default ] object toJSON ();
};
[Exposed =Window ]
interface NotRestoredReasons {
readonly attribute DOMString ? src ;
readonly attribute DOMString ? id ;
readonly attribute DOMString ? name ;
readonly attribute DOMString ? url ;
readonly attribute FrozenArray <NotRestoredReasonDetails >? reasons ;
readonly attribute FrozenArray <NotRestoredReasons >? children ;
[Default ] object toJSON ();
};
notRestoredReasonDetails.reason
返回一个字符串,该字符串解释了为什么文档未能从前进/后退缓存中获取。有关可能的字符串值,请参阅bfcache阻止详细信息的定义。
notRestoredReasons.src
返回文档的src属性,如果其节点导航的容器是iframe
元素。如果未设置或它不是iframe
元素,则此值可以为null。
notRestoredReasons.id
notRestoredReasons.name
返回文档的name属性,如果其节点导航的容器是iframe
元素。如果未设置或它不是iframe
元素,则此值可以为null。
notRestoredReasons.url
返回文档的URL,如果文档在跨域的iframe
中,则返回null。因为在原始src
设置之后,iframe
可能导航了,所以除了src
之外还会报告此值。
notRestoredReasons.reasons
返回文档的NotRestoredReasonDetails数组。如果文档在跨域的iframe
中,则此值为null。
notRestoredReasons.children
返回一个包含文档子元素的NotRestoredReasons的数组。如果文档在跨域的iframe
中,则此值为null。
NotRestoredReasonDetails对象有一个支持结构,一个未恢复原因详细信息或null,最初为null。
reason
的getter步骤是返回this的支持结构的原因。
给定一个未恢复原因详细信息的backingStruct
和一个领域realm,创建一个NotRestoredReasonDetails
对象:
让notRestoredReasonDetails成为一个在realm中创建的新NotRestoredReasonDetails
对象。
将notRestoredReasonDetails的支持结构设置为backingStruct。
返回notRestoredReasonDetails。
原因,一个字符串,最初为空。
原因是一个表示页面未能从前进/后退缓存恢复的原因的字符串。该字符串是以下之一:
fetch
"文档
发起的fetch仍在进行中并被取消,因此页面未处于可存储在前进/后退缓存中的稳定状态。navigation-failure
"文档
的原始导航出错,因此防止将结果错误文档存储在前进/后退缓存中。
parser-aborted
"文档
从未完成其初始HTML解析,因此防止将未完成的文档存储在前进/后退缓存中。
websocket
"WebSocket
连接被关闭,因此页面未处于可存储在前进/后退缓存中的稳定状态。[WEBSOCKETS]lock
"masked
"文档
有在跨域iframe
中的子元素,并且它们阻止了前进/后退缓存;或者此文档
因用户代理特定的原因无法被前进/后退缓存。
NotRestoredReasons对象有一个支持结构,一个未恢复原因或null,最初为null。
NotRestoredReasons对象有一个原因数组,一个FrozenArray<NotRestoredReasonDetails>
或null,最初为null。
NotRestoredReasons对象有一个子数组,一个FrozenArray<NotRestoredReasons>
或null,最初为null。
name
的getter步骤是返回this的支持结构的name。
url
的getter步骤是:
给定一个未恢复原因的backingStruct和一个领域realm,创建一个NotRestoredReasons
对象:
让notRestoredReasons成为一个在realm中创建的新NotRestoredReasons
对象。
将notRestoredReasons的支持结构设置为backingStruct。
否则:
否则:
返回notRestoredReasons。
src,一个字符串或null,最初为null。
id,一个字符串或null,最初为null。
name,一个字符串或null,最初为null。
url,一个URL或null,最初为null。
Document
的未恢复原因 是其 节点导航的 活动会话历史条目的 文档状态
的 未恢复原因,如果 Document
的
节点导航 是 顶级可遍历;否则为 null。
该标准包含了几个相关的概念,用于分组文档序列。简要的、非规范性的总结如下:
Navigables
是用户面对的文档序列表示,即它们代表可以在文档之间导航的东西。典型的例子是网页浏览器中的标签页或窗口,或者是iframe
,或是frame
在frameset
中。
Traversable navigables 是一种特殊类型的navigable,它们控制自身及其子navigables的会话历史。也就是说,除了它们自己的文档系列外,它们还代表一个树形结构的更多文档系列,并能够在线性遍历中通过此树的扁平视图前后移动。
Browsing
contexts 是开发者面对的文档系列表示。它们与WindowProxy
对象一一对应。每个navigable可以呈现一系列的browsing
contexts,在某些定义明确的情况下,这些browsing contexts之间会发生切换。
大部分标准使用navigables语言工作,但某些API暴露了browsing context切换的存在,因此标准的某些部分需要以browsing contexts的形式工作。
navigable通过其活动会话历史条目向用户展示一个Document
。每个navigable具有:
一个id,一个新的唯一内部值。
一个parent,一个navigable或null。
一个当前会话历史条目,一个会话历史条目。
这只能在父可遍历的navigable的会话历史遍历队列中修改。
一个活动会话历史条目,一个会话历史条目。
一个正在关闭布尔值,初始为false。
这只有在顶级可遍历navigable中才会设置为true。
一个正在延迟load
事件的布尔值,初始为false。
这只有在navigable的父非null的情况下才会设置为true。
当前会话历史条目和活动会话历史条目通常是相同的,但在以下情况下它们会不同步:
navigable的活动document是其活动会话历史条目的document。
这可以从navigable的顶级可遍历的会话历史遍历队列中安全读取。虽然navigable的活动历史条目可以同步更改,但新条目将始终具有相同的Document
。
navigable的活动浏览上下文是其活动document的浏览上下文。如果这个navigable是一个可遍历的navigable,那么其活动浏览上下文将是一个顶级浏览上下文。
navigable的活动WindowProxy
是其活动浏览上下文关联的WindowProxy
。
navigable的活动窗口是其活动WindowProxy
的[[Window]]。
这将始终等于navigable的活动document的相关全局对象;这是由激活算法保持同步的。
navigable的目标名称是其活动会话历史条目的文档状态的导航目标名称。
要获取 节点 navigable,给定一个节点node,返回其活跃文档为node的节点文档的navigable,如果没有这样的navigable,则返回 null。
要初始化 navigable navigable navigable,给定一个文档状态documentState和一个可选的navigable-或-null parent(默认值为 null):
让entry成为一个新的会话历史条目,具有
调用此算法的负责初始化entry的步骤;它将保持为"pending
",直到完成。
设置navigable的当前会话历史条目为entry。
设置navigable的活动会话历史条目为entry。
设置navigable的父为parent。
可遍历的navigable是一个navigable,它还控制自身及其子navigables的会话历史条目应该是当前会话历史条目和活动会话历史条目。
除了navigable的属性外,可遍历的navigable还具有:
一个当前会话历史步骤,一个数字,初始值为0。
一个会话历史遍历队列,一个会话历史遍历并行队列,是启动一个新的会话历史遍历并行队列的结果。
一个正在运行嵌套的应用历史步骤布尔值,初始为false。
一个系统可见性状态,值为"hidden
"或"visible
"。
请参阅页面可见性部分以了解此项的要求。
要获取navigable inputNavigable的可遍历的navigable:
将navigable设为inputNavigable。
当navigable不是一个可遍历的navigable时,将navigable设为navigable的父。
返回navigable。
顶级可遍历对象是一个可遍历的navigable,其父级为空。
目前,所有可遍历的navigable都是顶级可遍历对象。未来的提案设想引入非顶级的可遍历对象。
用户代理持有一个顶级可遍历对象集(一个包含顶级可遍历对象的集合)。这些通常以浏览器窗口或浏览器标签页的形式呈现给用户。
获取navigable inputNavigable的顶级可遍历对象的方法:
给定一个浏览上下文(可为空)opener、一个字符串targetName和一个可选的navigable openerNavigableForWebDriver,创建一个新的顶级可遍历对象的方法:
设document为空。
如果opener为空,则将document设为创建一个新的顶级浏览上下文和文档的第二个返回值。
否则,将document设为创建一个新的辅助浏览上下文和文档的第二个返回值,给定opener。
设documentState为一个新的文档状态,包含以下内容:
设traversable为一个新的可遍历的navigable。
初始化navigable traversable给定documentState。
设initialHistoryEntry为traversable的活动会话历史条目。
将initialHistoryEntry的步骤设为0。
如果opener非空,则传统克隆一个可遍历的存储棚,给定opener的顶级可遍历对象和traversable。[STORAGE]
调用WebDriver BiDi navigable created,传入traversable和openerNavigableForWebDriver。
返回traversable。
给定一个URL initialNavigationURL和一个可选的POST资源(可为空)initialNavigationPostResource(默认值为空),创建一个新的顶级可遍历对象的方法:
将traversable设为创建一个新的顶级可遍历对象的结果,给定null和空字符串。
导航 traversable到initialNavigationURL,使用traversable的活动文档,其中documentResource设为initialNavigationPostResource。
我们将这些初始导航视为traversable自己导航,这将确保所有相关的安全检查通过。
返回traversable。
某些元素(例如,iframe
元素)可以向用户展示导航元素。这些元素被称为导航容器。
每个导航容器都有一个内容导航元素,它可以是一个导航元素或null。初始值为null。
一个导航元素navigable的容器是其navigable的导航容器,或null(如果没有这样的元素)。
一个导航元素navigable的容器文档是通过执行以下步骤得到的结果:
一个文档
document的容器文档是通过执行以下步骤得到的结果:
一个导航元素navigable是另一个导航元素potentialParent的子导航元素,当navigable的父级是potentialParent时。我们也可以简单地说一个导航元素“是一个子导航元素”,这意味着它的父级非null。
一个导航容器container的内容文档是通过执行以下步骤得到的结果:
如果container的内容导航元素为null,则返回null。
返回document。
一个导航容器container的内容窗口是通过执行以下步骤得到的结果:
如果container的内容导航元素为null,则返回null。
返回container的内容导航元素的活动WindowProxy
的对象。
要创建一个新的子导航元素,给定一个元素element:
让parentNavigable为element的节点导航元素。
让browsingContext和document为执行创建新的浏览上下文和文档的结果,给定element的节点文档、element和group。
让targetName为null。
如果element有一个name
内容属性,则将targetName设置为该属性的值。
让documentState为一个新的文档状态,其中
让navigable为一个新的导航元素。
初始化导航元素navigable,给定documentState和parentNavigable。
将element的内容导航元素设置为navigable。
让historyEntry为navigable的活动会话历史条目。
让traversable为parentNavigable的可遍历导航元素。
将以下会话历史遍历步骤追加到traversable中:
调用WebDriver BiDi导航元素创建,传入traversable。
一种用于可视化文档序列的方法,特别是navigables及其会话历史条目,是Jake 图表。一个典型的 Jake 图表如下所示:
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
top |
/t-a | /t-a#foo | /t-b | ||
frames[0] |
/i-0-a | /i-0-b | |||
frames[1] |
/i-1-a | /i-1-b |
在这里,每个编号的列表示 traversable 的会话历史步骤的可能值。每一行描绘了一个navigable,它在不同的 URL 和文档之间进行转换。第一行,标记为
top
,是顶层
traversable,其他行是子
navigables。文档由每个单元格的背景颜色表示,新背景颜色表示该navigable中的新文档。URL
由单元格的文本内容表示;通常为简洁起见,使用相对 URL,除非特别调查跨源情况。一个给定的 navigable 可能在某一步不存在,在这种情况下,相应的单元格为空。粗斜体的步骤号表示
traversable 的当前会话历史步骤,所有带有粗斜体 URL 的单元格表示该行的 navigable 的当前会话历史条目。
因此,上述 Jake 图表描述了以下事件序列:
一个顶层
traversable被创建,起始 URL 为/t-a
,两个子 navigables分别起始于/i-0-a
和/i-1-a
。
第一个子 navigable 被导航到另一个文档,URL
为/i-0-b
。
第二个子 navigable 被导航到另一个文档,URL
为/i-1-b
。
顶层 traversable 被导航到相同的文档,其
URL 更新为/t-a#foo
。
顶层 traversable 被导航到另一个文档,URL
为/t-b
。(请注意,这个文档当然不会携带旧文档的子 navigables。)
traversable 被通过 delta 进行遍历,delta 为 -3,返回到步骤 1。
Jake 图表是可视化多个 navigables、导航和遍历交互的强大工具。它们无法捕捉所有可能的交互 —— 例如,它们仅适用于单层嵌套 —— 但我们将在本标准中使用它们来说明几个复杂的情况。
Jake 图表以其创造者 Jake Archibald 的名字命名。
在本标准的算法中,经常需要查看从给定文档
开始的navigables集合。
本节包含了一组整理的算法来收集这些 navigables。
这些算法的返回值是有序的,父元素出现在子元素之前。调用者依赖于这种顺序。
从文档
而不是navigable开始通常更好,因为它能让调用者意识到他们是否从完全活跃的文档
开始。虽然非完全活跃的文档
确实有祖先和后代
navigables,但它们通常表现得好像没有(例如,在window.parent
获取器中)。
文档
document的祖先 navigables按以下步骤给出:
让navigable为document的节点 navigable的父元素。
让ancestors为一个空列表。
当navigable不为 null 时:
返回ancestors。
文档
document的包括自身在内的祖先 navigables按以下步骤给出:
让navigables为document的祖先 navigables。
将document的节点 navigable添加到navigables的末尾。
返回navigables。
文档
document的后代 navigables按以下步骤给出:
让navigables为一个新列表。
让navigableContainers为一个列表,包含document的所有包含影子 DOM 的后代,它们是navigable 容器,按包含影子 DOM 的树顺序排序。
对于navigableContainers中的每个navigableContainer:
如果navigableContainer的内容 navigable为 null,则继续。
扩展navigables,包括navigableContainer的内容 navigable的活跃文档的包括自身在内的后代 navigables。
返回navigables。
文档
document的包括自身在内的后代 navigables按以下步骤给出:
让navigables为« document的节点 navigable »。
扩展navigables,包括document的后代 navigables。
返回navigables。
这些后代收集算法描述的是查看后代文档
对象的 DOM
树。实际上,这通常不可行,因为 DOM 树可能在调用算法的进程之外。因此,实施通常在跨进程间复制适当的树。
文档
document的文档树子 navigables按以下步骤给出:
如果document的节点 navigable为 null,则返回空列表。
让navigables为一个新列表。
让navigableContainers为一个列表,包含document的所有后代,它们是navigable 容器,按树顺序排序。
对于navigableContainers中的每个navigableContainer:
如果navigableContainer的内容 navigable为 null,则继续。
将navigableContainer的内容 navigable添加到navigables的末尾。
返回navigables。
要销毁子 navigable,给定一个navigable 容器 container:
让navigable为container的内容 navigable。
如果navigable为 null,则返回。
将container的内容 navigable设置为 null。
在给定navigable的情况下,通知导航 API 关于子 navigable 销毁的情况。
让parentDocState为container的节点 navigable的活跃会话历史条目的文档状态。
让traversable为container的节点 navigable的可遍历 navigable。
将以下会话历史遍历步骤附加到traversable:
给定traversable,更新 navigable 的创建/销毁。
调用WebDriver BiDi navigable 销毁,传入navigable。
要销毁顶级 traversable,给定一个顶级 traversabletraversable:
让browsingContext为traversable的活跃浏览上下文。
移除 browsingContext。
从用户界面中移除traversable(例如,在标签浏览器中关闭或隐藏其标签)。
从用户代理的顶级 traversable 集合中移除traversable。
调用WebDriver BiDi navigable 销毁,传入traversable。
用户代理可以随时销毁顶级 traversable(通常在响应用户请求时)。
要关闭顶级 traversabletraversable:
如果traversable的正在关闭为 true,则返回。
让toUnload为traversable的活跃文档的包括自身在内的后代 navigables。
如果对于toUnload的检查卸载是否被取消结果为 true,则返回。
将以下会话历史遍历步骤附加到traversable:
可导航对象可以被赋予目标名称,这些字符串允许某些API(例如window.open()
或a
元素的target
属性)将导航指向该可导航对象。
一个有效的可导航目标名称是任何至少包含一个字符且不包含ASCII制表符或换行符以及U+003C(<),且不以U+005F(_)开头的字符串。(以U+005F(_)开头的名称是保留给特殊关键词的。)
一个有效的可导航目标名称或关键词是任何字符串,它要么是有效的可导航目标名称,要么与以下之一ASCII不区分大小写匹配:_blank
、_self
、_parent
或_top
。
这些值的含义取决于页面是否被沙盒化,如下表(非规范性)所示。在此表中,“当前”指链接或脚本所在的可导航对象,“父级”指链接或脚本所在的可导航对象的父级,“顶级”指链接或脚本所在的可导航对象的顶级可遍历对象,“新建”指具有null父级的新可遍历对象(这可能会使用辅助浏览上下文,取决于各种用户偏好和用户代理策略),“无”表示不会发生任何事情,“可能新建”表示如果allow-popups
关键词也在sandbox
属性中指定(或者用户覆盖了沙盒),则与“新建”相同,否则与“无”相同。
关键词 | 普通效果 | 在带有...的iframe 中的效果
|
|
---|---|---|---|
sandbox="" |
sandbox="allow-top-navigation" |
||
未指定,针对链接和表单提交 | 当前 | 当前 | 当前 |
空字符串 | 当前 | 当前 | 当前 |
_blank |
新建 | 可能新建 | 可能新建 |
_self |
当前 | 当前 | 当前 |
如果没有父级的_parent |
当前 | 当前 | 当前 |
如果父级也是顶级的_parent |
父级/顶级 | 无 | 父级/顶级 |
如果存在且不是顶级的父级_parent |
父级 | 无 | 无 |
如果顶级是当前的_top |
当前 | 当前 | 当前 |
如果顶级不是当前的_top |
顶级 | 无 | 顶级 |
不存在的名称 | 新建 | 可能新建 | 可能新建 |
存在且是子级的名称 | 指定的子级 | 指定的子级 | 指定的子级 |
存在且是当前的名称 | 当前 | 当前 | 当前 |
存在且是顶级祖先的名称 | 指定的祖先 | 无 | 指定的祖先/顶级 |
存在且不是顶级祖先的名称 | 指定的祖先 | 无 | 无 |
具有共同顶级的其他存在名称 | 指定的 | 无 | 无 |
如果熟悉且一个允许的沙盒导航器,则顶级不同的存在名称 | 指定的 | 指定的 | 指定的 |
如果熟悉但不是一个允许的沙盒导航器,则顶级不同的存在名称 | 指定的 | 无 | 无 |
如果不熟悉,则顶级不同的存在名称 | 新建 | 可能新建 | 可能新建 |
大多数关于沙盒浏览上下文的限制是由其他算法应用的,例如导航算法,而不是选择可导航对象的规则。
选择可导航对象的规则,给定一个字符串name,一个可导航对象currentNavigable和一个布尔值noopener如下:
令chosen为null。
令windowType为“existing or none
”。
如果name是空字符串或ASCII大小写不敏感匹配“_self
”,则将chosen设置为currentNavigable。
否则,如果name是ASCII大小写不敏感匹配“_parent
”,则将chosen设置为currentNavigable的父级,如果有的话,否则为currentNavigable。
否则,如果name是ASCII大小写不敏感匹配“_top
”,则将chosen设置为currentNavigable的可遍历对象。
否则,如果name不是ASCII大小写不敏感匹配“_blank
”,存在一个可导航对象,其目标名称与name相同,currentNavigable的活动浏览上下文与该可导航对象的活动浏览上下文相熟,且用户代理确定这两个浏览上下文之间的关系足够紧密,可以相互访问,则将chosen设置为该可导航对象。如果有多个匹配的可导航对象,用户代理应以某种任意一致的方式选择一个,例如最近打开的,最近关注的或关系更密切的,并将chosen设置为它。
这将在问题#313中更加具体。
否则,请求新建一个顶级可遍历对象,其发生情况取决于用户代理的配置和能力——由以下列表中的第一个适用选项的规则确定:
用户代理可以通知用户已阻止弹出窗口。
用户代理可以向开发者控制台报告已阻止弹出窗口。
将windowType设置为“new and unrestricted
”。
令currentDocument为currentNavigable的活动文档。
如果currentDocument的打开者策略的值是“same-origin
”或“same-origin-plus-COEP
”,且currentDocument的源与currentDocument的相关设置对象的顶级源不同源,则:
将noopener设置为true。
将name设置为“_blank
”。
将windowType设置为“new with no opener
”。
在存在跨域起始者策略的情况下,与顶级浏览上下文的活动文档跨域的嵌套文档总是将noopener设置为true。
令chosen为null。
令targetName为空字符串。
如果name不是ASCII大小写不敏感匹配“_blank
”,则将targetName设置为name。
如果noopener为true,则将chosen设置为根据null、targetName和currentNavigable创建新顶级可遍历对象的结果。
否则:
将chosen设置为根据currentNavigable的活动浏览上下文、targetName和currentNavigable创建新顶级可遍历对象的结果。
如果sandboxingFlagSet设置了沙盒导航浏览上下文标志,则将chosen的活动浏览上下文的一个允许的沙盒导航器设置为currentNavigable的活动浏览上下文。
如果sandboxingFlagSet设置了沙盒传播到辅助浏览上下文标志,则sandboxingFlagSet中设置的所有标志都必须在chosen的活动浏览上下文的弹出沙盒标志集中设置。
将chosen设置为currentNavigable。
什么也不做。
鼓励用户代理提供一种方式让用户配置用户代理始终选择currentNavigable。
返回chosen和windowType。
浏览上下文是一个系列文档的编程表示,其中多个文档可以存在于一个可导航对象中。每个浏览上下文都有一个对应的WindowProxy
对象,以及以下内容:
一个打开者浏览上下文,一个浏览上下文或null,初始为null。
一个创建时的打开者来源,一个来源或null,初始为null。
一个是弹出窗口布尔值,初始为false。
一个是辅助窗口布尔值,初始为false。
一个初始URL,一个URL或null,初始为null。
一个虚拟浏览上下文组ID整数,初始为0。这用于跨域起始者策略报告,以跟踪如果报告仅策略被强制执行时会发生的浏览上下文组切换。
一个浏览上下文的活动窗口是其WindowProxy
对象的[[Window]]内部槽值。一个浏览上下文的活动文档是其活动窗口的关联的Document
。
一个浏览上下文的顶级可遍历对象是其活动文档的节点可导航对象的顶级可遍历对象。
一个浏览上下文的辅助浏览上下文是其是辅助窗口为true的情况。辅助浏览上下文始终是顶级浏览上下文。
尚不清楚是否需要单独的是辅助窗口概念。在问题#5680中,指出我们可以通过使用打开者浏览上下文是否为null来简化。
现代规范应避免在大多数情况下使用浏览上下文概念,除非它们处理的是浏览上下文组切换和代理集群分配的细节。相反,文档
和可导航对象概念通常更合适。
Document
的浏览上下文是一个浏览上下文或null,初始为null。
一个文档
不一定有一个非null的浏览上下文。特别是,数据挖掘工具可能永远不会实例化浏览上下文。使用诸如createDocument()
这样的API创建的文档
从不具有非null的浏览上下文。而且,最初为一个iframe
元素创建的文档
,在该元素被从文档中移除后,没有关联的浏览上下文,因为该浏览上下文已被设为null。
一般来说,窗口
对象和文档
对象之间存在一对一的映射,只要文档
对象有一个非null的浏览上下文。有一个例外。当浏览上下文从初始的about:blank
文档
导航到另一个文档时,会出现这种情况,这将通过替换进行。
要创建一个新的浏览上下文和文档,给定null或一个文档
对象creator,null或一个元素embedder,以及一个浏览上下文组group:
让browsingContext成为一个新的浏览上下文。
让unsafeContextCreationTime成为unsafe shared current time。
让creatorOrigin为null。
让creatorBaseURL为null。
如果creator非null,则:
将creatorOrigin设为creator的origin。
将creatorBaseURL设为creator的document base URL。
将browsingContext的virtual browsing context group ID设为creator的browsing context的top-level browsing context的virtual browsing context group ID。
让sandboxFlags成为determining the creation sandboxing flags的结果,给定browsingContext和embedder。
让origin成为determining the origin的结果,给定about:blank
、sandboxFlags和creatorOrigin。
让permissionsPolicy成为creating a permissions policy的结果,给定embedder和origin。[PERMISSIONSPOLICY]
让agent成为obtaining a similar-origin window agent的结果,给定origin、group和false。
让realm execution context成为creating a new realm的结果,给定agent和以下定制内容:
对于global object,创建一个新的Window
对象。
对于global this binding,使用browsingContext的WindowProxy
对象。
让topLevelCreationURL成为about:blank
,如果embedder为null;否则embedder的relevant settings
object的top-level creation URL。
让topLevelOrigin成为origin,如果embedder为null;否则embedder的relevant settings object的top-level origin。
Set up a window environment
settings object with about:blank
,
realm execution context, null, topLevelCreationURL, and topLevelOrigin。
让loadTimingInfo成为新的document load timing info with its navigation start time set to the result of calling coarsen time with unsafeContextCreationTime and the new environment settings object's cross-origin isolated capability。
让document成为新的
Document
,with:
html
"text/html
"
quirks
"about:blank
如果creator非null,则:
将document的referrer设为serialization of creator的URL。
将document的policy container设为creator的policy container的clone。
如果creator的origin是same origin with creator的relevant settings object的top-level origin,则将document的opener policy设为creator的browsing context的top-level browsing context的active document的opener policy。
Assert: document的URL和document的relevant settings object的creation URL是about:blank
。
将document标记为ready for post-load tasks。
Populate
with
html
/head
/body
given document。
Make active document。
Completely finish loading document。
返回browsingContext和document。
要创建一个新的顶级浏览上下文和文档:
让group和document成为creating a new browsing context group and document的结果。
返回group的browsing context set[0]和document。
要创建一个新的辅助浏览上下文和文档,给定一个浏览上下文opener:
让group成为openerTopLevelBrowsingContext的组。
Assert:group非null,因为navigating直接调用了此操作。
让browsingContext和document成为creating a new browsing context and document的结果,使用opener的active document、null和group。
将browsingContext的is auxiliary设置为true。
Append browsingContext to group。
将browsingContext的opener browsing context设置为opener。
将browsingContext的virtual browsing context group ID设置为openerTopLevelBrowsingContext的virtual browsing context group ID。
将browsingContext的opener origin at creation设置为opener的active document的origin。
返回browsingContext和document。
要确定来源,给定一个URLurl,一个sandboxing flag setsandboxFlags,以及一个origin-or-null sourceOrigin:
如果sandboxFlags设置了其sandboxed origin browsing context flag,则返回一个新的opaque origin。
如果url为null,则返回一个新的opaque origin。
如果url是about:srcdoc
,则:
Assert:sourceOrigin非null。
返回sourceOrigin。
如果urlmatches
about:blank
并且sourceOrigin非null,则返回sourceOrigin。
返回url的origin。
返回sourceOrigin的情况会导致两个Document
具有相同的底层origin,这意味着document.domain
会影响到两个文档。
如果以下算法返回 true,则浏览上下文potentialDescendant被称为浏览上下文potentialAncestor的祖先:
令potentialDescendantDocument为potentialDescendant的活动文档。
如果potentialDescendantDocument不是完全活动的,则返回 false。
令ancestorBCs为通过获取potentialDescendantDocument的每个成员的活动文档的浏览上下文的列表。
如果ancestorBCs包含potentialAncestor,则返回 true。
返回 false。
顶级浏览上下文是其活动文档的节点可导航对象是可遍历的可导航对象的浏览上下文。
这不是必须是顶级可遍历对象。
浏览上下文start的顶级浏览上下文是以下算法的结果:
返回navigable的活动浏览上下文。
浏览上下文A被认为与第二个浏览上下文B熟悉的熟悉,如果以下算法返回 true:
顶层浏览上下文具有一个相关的 组(为 null 或 浏览上下文组)。它最初为 null。
用户代理持有一个 浏览上下文组集(一个 集合的浏览上下文组)。
浏览上下文组持有一个浏览上下文集(一个 集合 的顶层浏览上下文)。
顶层浏览上下文会在组 被 创建时 添加到 组中。所有后续添加到 组中的顶层浏览上下文将 是辅助浏览上下文。
浏览上下文组具有一个相关的代理集群映射(一个弱 映射,将代理集群 密钥映射到代理集群)。用户 代理负责收集代理集群,当认为它们不再被访问时。
浏览上下文组具有一个相关的历史代理集群密钥 映射,这是一个 映射,将 来源 映射到 代理集群密钥。此 映射用于通过记录先前为给定来源使用的代理集群密钥来确保 来源密钥代理集群 功能的一致性。
历史代理集群密钥映射仅在 浏览上下文组的生命周期内增加条目。
浏览上下文组具有跨源隔离模式,这是一种
跨源隔离模式。它最初
是 "none
"。
跨源隔离模式 是三种可能值之一:
"none
","logical
",或 "concrete
"。
"logical
"
和 "concrete
"
类似。它们都用于
浏览上下文组,其中:
每个顶层文档
具有
`Cross-Origin-Opener-Policy: same-origin
`,
并且
每个文档
具有 `Cross-Origin-Embedder-Policy
`
头
其值是 与跨源隔离兼容。
在某些平台上,很难提供安全属性以安全访问由 跨源隔离能力限制的
API。因此,只有"concrete
"
能够授予该能力。
"logical
"
用于不支持
此功能的平台,其中仍将应用跨源隔离强加的各种限制,
但不授予该能力。
要创建 一个新的浏览上下文组和文档:
让group成为一个新的 浏览上下文组。
让browsingContext和document成为 创建 新的浏览上下文和文档与 null、null 和 group 的结果。
将 browsingContext 附加到 group。
返回group和document。
要附加一个顶层浏览上下文 browsingContext到一个浏览上下文组 group:
要移除一个顶层浏览上下文 browsingContext:
附加和移除是帮助定义 浏览
上下文组生命周期的基本操作。它们由高级创建和销毁操作调用,用于
文档
和浏览上下文。
当没有文档
对象,其
浏览上下文等于给定的 浏览
上下文(即所有此类文档
都已销毁),并且该浏览上下文的WindowProxy
适合垃圾回收,那么该浏览上下文将永远不会再被访问。如果它是一个顶层浏览上下文,那么在此时用户代理必须
将其移除。
文档
d被称为完全活动,当d是一个活动文档时
的可导航
navigable,且navigable是顶层可遍历或navigable的容器文档是完全活动。
由于它们与元素相关联,子
可导航总是与特定的文档
,它们的容器文档,在它们的父导航中绑定在一起。用户
代理不得允许用户与子
可导航交互,如果它们的容器文档本身不是完全活动的。
以下示例说明了一个文档
如何
成为其活动文档的节点可导航,但不完全是
完全活动。这里a.html
加载到浏览器窗口中,
b-1.html
开始加载到一个iframe
中,如图所示,
b-2.html
和c.html
省略(它们可以只是一个空文档)。
<!-- a.html -->
<!DOCTYPE html>
< html lang = "en" >
< title > Navigable A</ title >
< iframe src = "b-1.html" ></ iframe >
< button onclick = "frames[0].location.href = 'b-2.html'" > Click me</ button >
<!-- b-1.html -->
<!DOCTYPE html>
< html lang = "en" >
< title > Navigable B</ title >
< iframe src = "c.html" ></ iframe >
此时,a.html
、b-1.html
和 c.html
给出的文档都是它们各自的 活动文档 的 节点可导航。它们也都是 完全活动 的。
欢迎来到龙之咽喉。导航、会话历史和遍历会话历史是本标准中最复杂的部分之一。
基本概念似乎并不那么困难:
你可以在这里看到一些复杂的交织,遍历会引起导航(即,通过网络获取存储的 URL),导航必须与会话历史列表接口,以确保完成后用户看到的是正确的内容。但真正的问题在于各种边缘情况和交互的 web 平台功能:
子可导航(例如,包含在iframe
中的那些)也可以导航和遍历,但这些导航需要线性化为单个会话历史列表,因为用户只有一个用于整个可遍历导航(例如,浏览器标签)的前进/后退接口。
由于用户可以在会话历史中一次向后遍历多个步骤(例如,通过按住后退按钮),当涉及子可导航时,他们可能会同时遍历多个可导航。这需要在所有涉及的可导航之间同步,这可能涉及多个事件循环,甚至是代理集群。
在导航过程中,服务器可以响应 204 或 205 状态代码或带有 `Content-Disposition: attachment
`
头的响应,这会导致导航中止并且可导航停留在其原始的活动文档上。(如果这发生在遍历引发的导航期间会更糟糕!)
各种其他 HTTP 头,如 `Location
`,`Refresh
`,`X-Frame-Options
`,以及内容安全策略的头,会影响获取过程,或Document
创建过程,或两者。`跨源开放者策略
`
头甚至会影响浏览上下文的选择和创建过程!
某些导航(即片段导航和单页应用导航)是同步的,这意味着 JavaScript 代码期望立即观察到导航结果。这需要与树中所有其他可导航看到的会话历史视图同步,这可能会出现竞争条件并需要解决会话历史的冲突视图。
平台积累了各种需要特殊处理的导航相关功能,例如 javascript:
URL,srcdoc
iframe
,以及
beforeunload
事件。
在接下来的内容中,我们尝试通过将这些复杂性适当地分隔到标记的部分和算法中,并在可能的情况下给予适当的介绍词来引导读者。然而,如果你想真正理解导航和会话历史,通常的建议将是无价的。
步骤,一个非负整数或 "pending
",初始值为 "pending
"。
URL,一个 URL
文档状态,一个文档状态。
经典历史 API 状态,这是序列化状态,初始值为 StructuredSerializeForStorage(null)。
导航 API 状态,这是一个序列化状态,初始值为 StructuredSerializeForStorage(undefined)。
导航 API 密钥,这是一个字符串,初始值为 生成一个随机 UUID 的结果。
导航 API ID,这是一个字符串,初始值为 生成一个随机 UUID 的结果。
持久化的用户状态,这是实现定义的,初始值为 null
例如,一些用户代理可能希望持久化表单控件的值。
建议持久化表单控件值的用户代理也持久化它们的方向性(元素的 dir
属性的值)。这可以防止在用户最初以显式的、非默认的方向性输入值时,在历史遍历后值显示不正确。
序列化状态是表示用户界面状态的对象的序列化(通过 StructuredSerializeForStorage)。我们有时非正式地称 "状态对象",这些是作者提供的表示用户界面状态的对象,或者是通过StructuredDeserialize 反序列化序列化状态创建的对象。
页面可以通过添加 序列化状态到会话历史中。这些状态在用户(或脚本)回到历史记录时被反序列化并返回给脚本,从而使作者即使在单页应用程序中也能使用 "导航" 隐喻。
序列化状态旨在用于两个主要目的:首先,存储URL中状态的预解析描述,这样在简单情况下,作者不必进行解析(尽管仍需要解析以处理用户传递的URL,因此这只是一个小优化)。其次,作者可以存储不会存储在 URL 中的状态,因为它仅适用于当前的文档
实例,如果打开一个新的文档
,需要重新构建这些状态。
后者的一个例子是,跟踪弹出div
动画的精确坐标,以便在用户回退时,可以使其动画到相同的位置。或者,可以用它来保持指向数据缓存的指针,这些数据将根据
URL 中的信息从服务器获取,这样在前进和后退时,不必重新获取信息。
滚动恢复模式表示在遍历到条目时,用户代理是否应该恢复持久化的滚动位置(如果有)。滚动恢复模式包括以下之一:
auto
"manual
"文档状态在会话历史条目中保存有关如何呈现和(如有必要)重新创建文档
的状态。它包括:
文档,一个文档
或 null,初始值为 null。
历史策略容器,一个策略容器或 null,初始值为 null。
请求引用者,可以是"no-referrer
"、"client
",或一个URL,初始值为"client
"。
发起者来源,这是一个来源或 null,初始值为 null。
来源,这是一个来源或 null,初始值为 null。
这是我们为"about:
"协议设置的文档
的来源。我们将其存储在此,因为在遍历期间恢复这些文档
时,也会使用它,因为它们是在不访问网络的情况下本地重构的。它还用于在会话历史条目被重新填充之前和之后比较来源。如果来源发生变化,导航目标名称将被清除。
关于基本 URL,这是一个URL或 null,初始值为 null。
这将仅为 "about:
"-模式的
文档
填充,并将作为这些文档的后备基本
URL。这是启动者文档
的文档基本 URL的快照。
资源,一个字符串,POST 资源或 null,初始值为 null。
字符串被视为 HTML。它用于存储iframe
srcdoc
文档的源代码。
重新加载待处理布尔值,初始值为 false。
曾经填充布尔值,初始值为 false。
导航目标名称字符串,初始值为空字符串。
未恢复原因,一个未恢复原因或 null,初始值为 null。
用户代理可以销毁一个文档及其后代,给定具有非 null 文档的文档状态,只要文档
不是完全活动的。
除上述限制外,本标准未规定用户代理应何时销毁文档状态中存储的文档,或保持其缓存。
POST 资源具有:
请求体,一个字节序列或失败。
这仅在并行访问,因此不需要存储在内存中。然而,每次必须返回相同的字节序列。如果由于资源在磁盘上发生变化,或者资源无法再访问,则必须将其设置为失败。
请求内容类型,可以是
`application/x-www-form-urlencoded
`,`multipart/form-data
`,或
`text/plain
`。
嵌套历史具有:
这将稍后包含跨重新加载标识子可导航的方法。
会话历史中的多个连续条目可以共享相同的文档状态。当通过正常导航到达初始条目时,这种情况可能发生,并且通过history.pushState()
添加以下条目。或者,它可以通过导航到片段来实现。
共享相同文档状态(因此它们只是一个特定文档的不同状态)的所有条目在结构上都是连续的。
这是最近由给定文档
表示的条目。一个文档
可以随时间表示许多会话历史条目,因为许多连续的会话历史条目可以共享相同的文档状态,如上所述。
为了保持唯一的真实来源,所有对可遍历导航项的会话历史条目的修改都需要同步。这特别重要,因为会话历史受到所有后代导航项的影响,因此涉及多个事件循环。为此,我们使用会话历史遍历并行队列结构。
会话历史遍历并行队列与并行队列非常相似。它有一个算法集,一个有序集。
在会话历史遍历并行队列的算法集中的条目可以是算法步骤,也可以是同步导航步骤,这是涉及目标导航项(导航项)的一种特殊的算法步骤。
为了将会话历史遍历步骤附加到给定算法步骤的traversable,将steps附加到traversable的会话历史遍历队列的算法集中。
为了将涉及导航项targetNavigable的会话历史同步导航步骤附加到给定算法步骤的traversable,将steps作为目标导航项targetNavigable的同步导航步骤附加到traversable的会话历史遍历队列的算法集中。
为了启动一个新的会话历史遍历并行队列:
令sessionHistoryTraversalQueue为一个新的会话历史遍历并行队列。
并行运行以下步骤:
返回sessionHistoryTraversalQueue。
本节包含在操纵会话历史时执行的各种操作。最好的理解它们的方法是查看它们的调用位置。
要获取一个可导航对象navigable的会话历史条目:
让traversable成为navigable的可遍历导航对象。
如果navigable是traversable,则返回traversable的会话历史条目。
对于 docState的docStates:
断言:不会到达此步骤。
要获取给定整数targetStep的可导航对象navigable的会话历史条目,步骤如下:
让rawEntries成为获取会话历史条目的结果,用于navigable。
让entriesForNavigationAPI成为一个新的空的列表。
让startingIndex成为rawEntries中具有最大步骤小于或等于targetStep的会话历史条目的索引。
参见此示例以了解为什么这是最大步骤小于或等于targetStep。
将rawEntries[startingIndex]附加到entriesForNavigationAPI。
设i为startingIndex − 1。
当i > 0时:
设i为startingIndex + 1。
当i < rawEntries的大小时:
返回entriesForNavigationAPI。
要清除前进会话历史的可遍历导航对象navigable:
要获取作为traversable的一部分的所有已用历史步骤:
例如,点击超链接、表单提交,以及window.open()
和location.assign()
方法都可能导致导航。
在我们进入导航算法之前,我们需要建立其使用的几个重要结构。
源快照参数 结构用于捕获发起导航的文档的数据。在导航开始时进行快照,并在整个导航过程中使用。它具有以下项目:
要快照源快照参数,给定一个文档sourceDocument,返回一个新的源快照参数,其中
目标快照参数 结构用于捕获被导航的导航对象的数据。与源快照参数类似,它在导航开始时进行快照,并在整个导航过程中使用。它具有以下项目:
要快照目标快照参数,给定一个导航对象targetNavigable,返回一个新的目标快照参数,其中沙盒标志设置为给定targetNavigable的活动浏览上下文和targetNavigable的容器时确定的创建沙盒标志的结果。
导航过程的很大一部分涉及确定如何创建一个新的文档,这最终在创建和初始化一个Document
对象算法中完成。该算法的参数通过一个导航参数 结构进行跟踪,该结构具有以下项目:
文档
后接受它的算法
文档
预留的环境文档
的来源文档
的策略容器
文档
的沙盒标志集文档
的跨源开启者策略
NavigationTimingType
用于 创建导航时序条目 为新的 文档
文档
的关于基本URL的URL或null一旦创建了一个导航参数结构,本标准不会对其任何项目进行变更。它们只会传递给其他算法。
导航ID是在导航过程中生成的UUID字符串。它用于与WebDriver BiDi规范进行接口,以及跟踪正在进行的导航。[WEBDRIVERBIDI]
在创建文档
之后,相关的可遍历导航对象的会话历史会更新。NavigationHistoryBehavior
枚举用于向导航算法指示所需的会话历史更新类型。它是以下之一:
push
"replace
"auto
"
push
"或"replace
"。通常它会变成"push
",但在某些情况下会变成"replace
"。
历史处理行为是一个NavigationHistoryBehavior
,它是"push
"或"replace
",即已经解决了任何初始"auto
"值。
导航必须是替换,如果以下任何情况为真,给定一个url和一个文档
document:
url的方案是"javascript
";
或
document的是初始about:blank
为真。
平台的各个部分会跟踪用户是否参与了导航。用户导航参与如下之一:
browser UI
"
activation
"
none
"为了方便某些调用站点,用户导航参与定义为:
要将导航对象
navigable导航到一个url,使用文档
sourceDocument,可选的documentResource(默认null),可选的response(默认null),可选的exceptionsEnabled(默认false),可选的NavigationHistoryBehavior
historyHandling(默认"auto
"),可选的navigationAPIState(默认null),可选的formDataEntryList(默认null),可选的referrerPolicy(默认空字符串)和可选的userInvolvement(默认"none
"):
如果formDataEntryList不为null,则将cspNavigationType设为"form-submission
",否则设为"other
"。
将sourceSnapshotParams设为根据sourceDocument的源快照参数的快照结果。
将initiatorOriginSnapshot设为sourceDocument的来源。
将initiatorBaseURLSnapshot设为sourceDocument的文档基本URL。
如果sourceDocument的节点导航对象不被允许通过沙盒导航导航navigable,则:
如果exceptionsEnabled为true,则抛出"SecurityError
" DOMException
。
返回。
将navigationId设为生成一个随机UUID的结果。
如果周围的代理等于navigable的活动文档的相关代理,则继续这些步骤。否则,在navigable的活动窗口上排队一个全局任务,以继续这些步骤。
如果navigable的活动文档的卸载计数器大于0,则调用WebDriver BiDi导航失败,并返回。
将container设为navigable的容器。
如果container是一个iframe元素并且将惰性加载元素步骤返回true,则停止观察惰性加载元素并将container的惰性加载恢复步骤设为null。
如果给定url和navigable的活动文档导航必须是替换的,则将historyHandling设为"replace
"。
如果navigable的父级不为null,则将navigable的延迟加载事件模式设为true。
将targetBrowsingContext设为navigable的活动浏览上下文。
将targetSnapshotParams设为根据navigable的目标快照参数的快照结果。
调用WebDriver BiDi导航开始,并传入targetBrowsingContext和一个新的WebDriver
BiDi导航状态,其id为navigationId,状态为"pending
",URL为url。
如果
navigable的持续导航为"traversal
",则:
调用WebDriver BiDi导航失败,并传入targetBrowsingContext和一个新的WebDriver
BiDi导航状态,其id为navigationId,状态为"canceled
",URL为url。
返回。
设置navigable的持续导航为navigationId。
如果url的方案是"javascript
",则:
排队一个全局任务,在navigable的活动窗口上导航到一个javascript:
URL,并传入navigable,url,historyHandling,initiatorOriginSnapshot和cspNavigationType。
返回。
如果以下所有条件都为真:
userInvolvement不是"浏览器UI
";
navigable的活动文档的来源与sourceDocument的来源相同;
navigable的活动文档的初始about:blank
为false;并且
url的方案是一个取方案,
则:
将navigation设为navigable的活动窗口的导航API。
将entryListForFiring设为formDataEntryList,如果documentResource是一个POST资源;否则为null。
将navigationAPIStateForFiring设为navigationAPIState,如果navigationAPIState不为null;否则,StructuredSerializeForStorage(undefined)。
将continue设为触发一个push/replace/reload
navigate
事件的结果,传入navigation,navigationType设为historyHandling,isSameDocument设为false,userInvolvement设为userInvolvement,formDataEntryList设为entryListForFiring,destinationURL设为url,navigationAPIState设为navigationAPIStateForFiring。
如果continue为false,则返回。
并行运行这些步骤:
将unloadPromptCanceled设为检查是否取消卸载的结果,针对navigable的活动文档的包含后代导航对象。
如果unloadPromptCanceled为true,或navigable的持续导航不再为navigationId,则:
调用WebDriver BiDi导航失败,并传入targetBrowsingContext和一个新的WebDriver
BiDi导航状态,其id为navigationId,状态为"canceled
",URL为url。
中止这些步骤。
排队一个全局任务,在navigable的活动窗口上中止一个文档及其后代。
如果url匹配about:blank
或about:srcdoc
,则:
将documentState的来源设为initiatorOriginSnapshot。
将documentState的基本URL设为initiatorBaseURLSnapshot。
将historyEntry设为一个新的会话历史条目,URL设为url,文档状态设为documentState。
将navigationParams设为null。
如果response不为null:
导航算法仅在对象和嵌入元素处理模型的一部分或处理multipart/x-mixed-replace响应的部分时提供响应。
将policyContainer设为确定导航参数策略容器的结果,给定响应的URL,null,源文档的策略容器的克隆,导航对象的容器文档的政策容器和null。
将finalSandboxFlags设为目标快照参数的沙盒标志和策略容器的CSP列表的联合。
将responseOrigin设为确定响应的来源的结果,给定响应的URL,最终沙盒标志和文档状态的发起者来源。
将coop设为一个新的跨域开启策略。
将coopEnforcementResult设为一个新的跨域开启策略执行结果,包含以下内容:
将navigationParams设为一个新的导航参数,包含以下内容:
尝试填充历史条目的文档,给定historyEntry,navigable,"navigate
",sourceSnapshotParams,targetSnapshotParams,navigationId,navigationParams,cspNavigationType,并将allowPOST设为true,completionSteps设为以下步骤:
附加会话历史遍历步骤到navigable的可遍历对象以完成跨文档导航,给定navigable,historyHandling和historyEntry。
虽然通常的跨文档导航情况将首先进入填充会话历史条目,所有未被中止的导航最终都将调用以下算法之一。
要完成跨文档导航,给定一个导航对象navigable、历史处理行为historyHandling和会话历史条目historyEntry:
设置navigable的是否延迟load
事件为false。
如果historyEntry的文档为null,则返回。
这意味着尝试填充历史条目的文档最终未创建文档,可能由于导航被后续导航取消、204 No Content响应等原因。
如果以下所有条件都为真:
navigable的父对象为null;
如果historyHandling是"replace
",则将entryToReplace设为navigable的活动会话历史条目;否则为null。
将traversable设为navigable的可遍历导航对象。
将targetStep设为null。
将targetEntries设为获取navigable的会话历史条目的结果。
如果entryToReplace为null,则:
清除traversable的前向会话历史。
将targetStep设为traversable的当前会话历史步骤 + 1。
将historyEntry的步骤设为targetStep。
将historyEntry追加到targetEntries。
否则:
应用targetStep到traversable,给定historyHandling。
javascript:
URL
的特殊情况javascript:
URL 在问题跟踪器上有一个专用标签,记录了其规范的各种问题。
要 导航到 javascript:
URL,给定一个 navigable
targetNavigable,一个 URL url,一个 历史处理行为
historyHandling,一个 来源
initiatorOrigin,以及一个字符串 cspNavigationType:
如果 initiatorOrigin 与 targetNavigable 的 活动文档 的 来源 不是 同源域,则返回。
让 request 成为一个新的 请求,其 URL 为 url。
这是一个合成的 请求,仅用于连接到下一步。它永远不会触及网络。
如果根据 内容安全策略应阻止的导航请求类型
给定 request 和 cspNavigationType 的结果是 "Blocked
",则返回。[CSP]
让 newDocument 成为 评估 javascript:
URL 的结果,给定
targetNavigable,url 和 initiatorOrigin。
如果 newDocument 为 null,则返回。
在这种情况下,一些 JavaScript 代码已执行,但没有创建新的 文档
,所以我们不会执行导航。
让 entryToReplace 成为 targetNavigable 的 活动会话历史条目。
让 oldDocState 成为 entryToReplace 的 文档状态。
让 documentState 成为一个新的 文档状态,其中包含
让 historyEntry 成为一个新的 会话历史条目,包含
对于 URL,我们不使用
url,即实际的 javascript:
URL,这意味着 javascript:
URL 永远不会存储在会话历史中,因此无法被遍历到。
附加会话历史遍历步骤到 targetNavigable 的 可遍历对象,以 完成跨文档导航,与 targetNavigable、historyHandling 和 historyEntry。
要 评估 javascript:
URL,给定一个 navigable
targetNavigable,一个 URL url,和一个 来源
newDocumentOrigin:
让 urlString 成为运行 URL 序列化器 在 url 上的结果。
让 encodedScriptSource 成为从 urlString 中移除前导 "javascript:
" 的结果。
让 baseURL 成为 settings 的 API 基本 URL。
让 script 成为 创建经典脚本 的结果,给定 scriptSource、settings、baseURL 和 默认脚本获取选项。
让 evaluationStatus 成为 运行经典脚本 script 的结果。
让 result 为 null。
如果 evaluationStatus 是正常完成,并且 evaluationStatus.[[Value]] 是字符串,则将 result 设置为 evaluationStatus.[[Value]]。
否则,返回 null。
让 response 成为一个新的 响应,包含
Content-Type
`,`text/html;charset=utf-8
`)
»编码为 UTF-8 意味着一旦 HTML 解析器解码响应主体,未配对的 代理将不会进行回传。
让 finalSandboxFlags 成为 policyContainer 的 CSP 列表 的 CSP 派生的沙盒标志。
让 coopEnforcementResult 成为一个新的 跨来源打开策略执行结果,包含
让 navigationParams 成为一个新的 导航参数,包含
返回 加载 HTML 文档 的结果,给定 navigationParams。
要导航到片段,给定一个 navigable navigable,一个 URL url,一个 历史处理行为 historyHandling,一个 用户导航参与度 userInvolvement,一个 序列化状态 或 null navigationAPIState,以及一个 导航 ID navigationId:
让 destinationNavigationAPIState 成为 navigable 的 活动会话历史条目 的 导航 API 状态。
如果 navigationAPIState 不是 null,则将 destinationNavigationAPIState 设置为 navigationAPIState。
让 continue 成为 触发 push/replace/reload navigate
事件 在 navigation 上的结果,navigationType 设置为
historyHandling,isSameDocument 设置为 true,userInvolvement 设置为
userInvolvement,destinationURL 设置为
url,navigationAPIState 设置为
destinationNavigationAPIState。
如果 continue 为 false,则返回。
让 historyEntry 成为一个新的 会话历史条目,包含
对于使用 navigation.navigate()
执行的导航,state
选项提供的值用于新的 导航 API
状态。(如果未提供该选项的值,则会将其设置为 undefined
的序列化形式。)对于其他片段导航,包括用户发起的导航,导航 API 状态 从前一个条目继承。
经典历史 API 状态 永远不会被继承。
让 entryToReplace 成为 navigable 的 活动会话历史条目,如果 historyHandling 是 "replace
",否则为
null。
让 scriptHistoryIndex 成为 history 的 索引。
让 scriptHistoryLength 成为 history 的 长度。
如果 historyHandling 是 "push
",则:
将 history 的 状态 设置为 null。
增加 scriptHistoryIndex。
将 scriptHistoryLength 设置为 scriptHistoryIndex + 1。
将 navigable 的 活动会话历史条目 设置为 historyEntry。
更新文档以应用历史步骤,给定 navigable 的 活动文档、historyEntry、true、scriptHistoryIndex、scriptHistoryLength 和 historyHandling。
由于单次片段导航,该算法将被调用两次:一次是同步调用,其中设置最佳猜测值 scriptHistoryIndex 和
scriptHistoryLength,history.state
被置为 null,并触发各种事件;另一次是异步调用,其中设置索引和长度的最终值,history.state
保持不变,并且不会触发任何事件。
如果滚动失败,因为 文档
是新的且相关的 ID 尚未解析,那么第二次异步调用 更新文档以应用历史步骤 将处理滚动。
让 traversable 成为 navigable 的 可遍历的 navigable。
附加以下会话历史同步导航步骤,涉及 navigable 到 traversable:
完成同一文档导航,给定 traversable、navigable、historyEntry、entryToReplace 和 historyHandling。
调用 WebDriver BiDi 片段导航,使用 navigable 的 活动浏览上下文 和新的 WebDriver BiDi 导航状态,其中 id 是
navigationId,url 是
url,并且 状态 是
"完成
"。
要完成同一文档导航,给定一个 可遍历的 navigable traversable,一个 navigable targetNavigable,一个 会话历史条目 targetEntry,一个 会话历史条目 或 null entryToReplace,以及一个 历史处理行为 historyHandling:
这被 片段导航 和 URL 和历史更新步骤 使用,它们是唯一同步更新会话历史的算法。由于是同步的,这些算法在 顶级可遍历对象 的 会话历史遍历队列 之外执行。这使得它们与 顶级可遍历对象 的 当前会话历史步骤 不同步,因此该算法用于解决由于竞争条件引起的冲突。
如果 targetNavigable 的 活动会话历史条目 不是 targetEntry,则返回。
让 targetStep 为 null。
让 targetEntries 成为 获取 targetNavigable 的会话历史条目 的结果。
如果 entryToReplace 是 null,则:
将 targetStep 设置为 traversable 的 当前会话历史步骤 + 1。
将 targetEntry 的 步骤 设置为 targetStep。
附加 targetEntry 到 targetEntries。
否则:
应用推送/替换历史步骤 targetStep 到 traversable,给定 historyHandling。
即使对于 "replace
"
导航,也会执行此操作,因为它解决了多个同步导航的竞争条件。
尝试创建非 fetch 方案文档 的输入是 非 fetch 方案导航参数 结构体。它是 导航参数 的轻量版本,仅携带与非 fetch 方案 导航情况相关的参数。它具有以下 项目:
一个 来源,可能用于用户界面提示以确认调用外部软件包
这与 文档状态 的 发起者来源 略有不同,因为 非 fetch 方案导航参数 的 发起者来源 跟随重定向链,直到非 fetch 方案 URL。
NavigationTimingType
,用于
创建导航时序条目 为新的 文档
如果 url 将通过不影响 navigable 的机制处理,例如因为 url 的 方案 在外部处理,则:
通过显示某种内联内容来处理 url,例如错误消息,因为指定的方案不是支持的协议之一,或者内联提示用户选择给定方案的 已注册处理程序。返回 显示内联内容 的结果,给定 navigable、navigationParams 的 id 和 navigationParams 的 导航时序类型。
在使用已注册的处理程序的情况下,将调用 导航,使用新的 URL。
要 移交给外部软件,给定一个 URL 或 响应 resource、一个 navigable navigable、一个 沙盒标志集 sandboxFlags、一个布尔值 hasTransientActivation,以及一个 来源 initiatorOrigin,用户代理应:
如果以下所有条件都为真:
navigable 不是 顶级可遍历对象;
sandboxFlags 设置了其 沙盒自定义协议导航浏览上下文标志;以及
sandboxFlags 设置了其 沙盒顶级导航带用户激活浏览上下文标志,或者 hasTransientActivation 为 false,
那么无需调用外部软件包即可返回。
在 iframe 中导航到外部软件对用户来说可以看作是一个新弹出窗口或一个新的顶级导航。这就是为什么只有在 iframe
中指定了 allow-popups
、allow-top-navigation
、allow-top-navigation-by-user-activation
或 allow-top-navigation-to-custom-protocols
时才允许。
执行 resource 的适当移交,同时尝试减轻这是试图利用目标软件的风险。例如,用户代理可以提示用户确认 initiatorOrigin 是否允许调用相关的外部软件。特别是,如果 hasTransientActivation 为 false,则在没有用户确认的情况下,用户代理不应调用外部软件包。
例如,目标软件的 URL 处理程序中可能存在漏洞,恶意页面会试图通过诱使用户点击链接来利用此漏洞。
有几种情况可能会在导航过程的早期介入并使整个过程停止。当由于会话历史遍历导致多个可导航元素同时导航时,这尤其令人兴奋。
如果以下步骤返回 true,则 可导航元素source被沙盒允许导航第二个可导航元素target,给定源快照参数sourceSnapshotParams:
如果source是target,则返回 true。
如果source是target的祖先,则返回 true。
如果target是source的祖先,则:
如果target不是顶级可遍历,则返回 true。
如果sourceSnapshotParams的具有瞬态激活为 true,并且sourceSnapshotParams的沙盒标志的带用户激活的沙盒顶级导航浏览上下文标志被设置,则返回 false。
如果sourceSnapshotParams的具有瞬态激活为 false,并且sourceSnapshotParams的沙盒标志的不带用户激活的沙盒顶级导航浏览上下文标志被设置,则返回 false。
返回 true。
如果target是顶级可遍历:
如果source是target的一个允许的沙盒导航器,则返回 true。
如果sourceSnapshotParams的沙盒标志的沙盒导航浏览上下文标志被设置,则返回 false。
返回 true。
如果sourceSnapshotParams的沙盒标志的沙盒导航浏览上下文标志被设置,则返回 false。
返回 true。
为列表的可导航元素navigablesThatNeedBeforeUnload,给定一个可选的可遍历可导航元素traversable、一个可选整数targetStep和一个可选的用户导航参与或-nulluserInvolvementForNavigateEvent,运行这些步骤。它们返回
"canceled-by-beforeunload
"、"canceled-by-navigate
"或"continue
"。
让documentsToFireBeforeunload成为navigablesThatNeedBeforeUnload中每个项目的活动文档。
令unloadPromptShown为 false。
令finalStatus为"continue
"。
如果给定了traversable,则:
断言:已给定targetStep和userInvolvementForNavigateEvent。
令targetEntry为根据traversable和targetStep获取目标历史记录项的结果。
如果targetEntry不是traversable的当前会话历史记录项,并且targetEntry的文档状态的来源与traversable的当前会话历史记录项的文档状态的来源相同,则:
在这种情况下,我们将在此处为traversable触发navigate
事件。由于在某些情况下它可能会被取消,我们需要将其与稍后发生的其他遍历navigate
事件分开处理。
此外,因为我们希望在navigate
事件之前触发beforeunload
事件,这意味着我们需要在此处为traversable触发beforeunload
(如果适用),而不是将其作为下面遍历documentsToFireBeforeunload的循环的一部分。
断言:userInvolvementForNavigateEvent不为 null。
令eventsFired为 false。
如果navigablesThatNeedBeforeUnload包含traversable,则needsBeforeunload为 true;否则为 false。
如果needsBeforeunload为 true,则移除traversable的活动文档从documentsToFireBeforeunload中。
在traversable的活动窗口上给定导航和遍历任务源队列一个全局任务,以执行以下步骤:
如果needsBeforeunload为 true,则:
令(unloadPromptShownForThisDocument,
unloadPromptCanceledByThisDocument)为根据traversable的活动文档和
false 运行触发beforeunload
的步骤的结果。
如果unloadPromptShownForThisDocument为 true,则将unloadPromptShown设置为 true。
如果unloadPromptCanceledByThisDocument为
true,则将finalStatus设置为"canceled-by-beforeunload
"。
如果finalStatus为"canceled-by-beforeunload
",则中止这些步骤。
令navigateEventResult为在navigation上触发遍历navigate
事件的结果,给定targetEntry和userInvolvementForNavigateEvent。
如果navigateEventResult为
false,则将finalStatus设置为"canceled-by-navigate
"。
将eventsFired设置为 true。
等待eventsFired为 true。
如果finalStatus不是"continue
",则返回finalStatus。
令totalTasks为documentsThatNeedBeforeunload的大小。
令completedTasks为 0。
对于documents的每个document,在document的相关全局对象上队列一个全局任务,给定导航和遍历任务源以运行步骤:
令(unloadPromptShownForThisDocument,
unloadPromptCanceledByThisDocument)为根据document和unloadPromptShown运行触发beforeunload
的步骤的结果。
如果unloadPromptShownForThisDocument为 true,则将unloadPromptShown设置为 true。
如果unloadPromptCanceledByThisDocument为
true,则将finalStatus设置为"canceled-by-beforeunload
"。
增加completedTasks。
等待completedTasks为totalTasks。
返回finalStatus。
触发beforeunload
的步骤给定一个Document
document和一个布尔值unloadPromptShown如下:
令unloadPromptCanceled为 false。
增加document的卸载计数器1。
令eventFiringResult为在document的相关全局对象上触发事件的结果,事件名称为beforeunload
,使用BeforeUnloadEvent
,可取消
属性初始化为
true。
如果以下所有条件均为 true:
unloadPromptShown为 false;
eventFiringResult为 false,或event的returnValue
属性不是空字符串;并且
显示卸载提示不太可能令人烦恼、欺骗或无意义,
然后:
将unloadPromptShown设置为 true。
调用WebDriver BiDi 用户提示已打开,参数为document的相关全局对象、"beforeunload
"和""。
询问用户是否确认他们希望卸载文档,并在等待用户响应时暂停。
显示给用户的消息不可自定义,而是由用户代理决定的。特别是,returnValue
属性的实际值被忽略。
如果用户未确认页面导航,则将unloadPromptCanceled设置为 true。
调用WebDriver BiDi 用户提示已关闭,参数为document的相关全局对象,如果unloadPromptCanceled为 false 则为 true,否则为 false。
减少document的卸载计数器1。
返回(unloadPromptShown, unloadPromptCanceled)。
为可导航元素navigable 设置正在进行的导航为newValue:
如果navigable的正在进行的导航等于newValue,则返回。
通知导航 API 中止导航,给定navigable。
将navigable的正在进行的导航设置为newValue。
为可导航元素navigable,给定一个可选的序列化状态或-nullnavigationAPIState(默认为 null)和一个可选的用户导航参与userInvolvement(默认"none
"),重新加载:
如果userInvolvement不是"浏览器 UI
",则:
令destinationNavigationAPIState为navigable的活动会话历史记录项的导航 API 状态。
如果navigationAPIState不是 null,则将destinationNavigationAPIState设置为navigationAPIState。
令continue为在navigation上触发推送/替换/重新加载navigate
事件的结果,其中navigationType设置为"reload
",isSameDocument设置为 false,userInvolvement设置为userInvolvement,destinationURL设置为navigable的活动会话历史记录项的URL,navigationAPIState设置为destinationNavigationAPIState。
如果continue为 false,则返回。
令traversable为navigable的可遍历可导航元素。
将以下会话历史记录遍历步骤附加到traversable:
应用重新加载历史记录步骤到traversable。
给定一个可遍历可导航元素traversable、一个整数delta,和一个可选的Document
sourceDocument,按增量遍历历史记录:
令sourceSnapshotParams和initiatorToCheck为 null。
令userInvolvement为"浏览器 UI
"。
如果给定了sourceDocument,则:
将以下会话历史记录遍历步骤附加到traversable:
令allSteps为获取所有使用的历史记录步骤的结果,针对traversable。
令currentStepIndex为traversable的当前会话历史记录步骤在allSteps中的索引。
令targetStepIndex为currentStepIndex加上delta。
如果allSteps[targetStepIndex]不存在,则中止这些步骤。
应用遍历历史记录步骤allSteps[targetStepIndex]到traversable,给定sourceSnapshotParams、initiatorToCheck和userInvolvement。
除了导航算法之外,会话历史记录条目还可以通过另一种机制推送或替换,即URL和历史记录更新步骤。这些步骤中最著名的调用者是history.replaceState()
和history.pushState()
API,但标准的其他部分也需要更新活动历史记录条目,并使用这些步骤来完成此操作。
URL和历史记录更新步骤,给定一个文档
document,一个URLnewURL,一个可选的序列化状态或-nullserializedData(默认null),以及一个可选的历史记录处理行为historyHandling(默认"replace
"),步骤如下:
令navigable为document的节点可导航。
令activeEntry为navigable的活动会话历史记录条目。
令newEntry为新的会话历史记录条目,其具有
如果document的是初始about:blank
为
true,则将historyHandling设置为"replace
"。
这意味着在初始about:blank
文档
上调用pushState()
的行为与调用replaceState()
相同。
令entryToReplace为activeEntry,如果historyHandling是"replace
",否则为
null。
如果historyHandling是"push
",则:
这些是立即同步访问的临时最佳猜测值。
如果serializedData不为 null,则恢复历史记录对象状态,给定document和newEntry。
将document的URL设置为newURL。
由于这既不是导航也不是历史记录遍历,因此不会触发hashchange
事件。
将document的最新条目设置为newEntry。
将navigable的活动会话历史记录条目设置为newEntry。
更新同一文档导航的导航 API 条目,给定document的相关全局对象的导航 API、newEntry和historyHandling。
令traversable为navigable的可遍历可导航。
将以下会话历史记录同步导航步骤附加到traversable中涉及navigable:
完成同一文档导航,给定traversable、navigable、newEntry、entryToReplace和historyHandling。
虽然片段导航和URL和历史记录更新步骤都执行同步历史记录更新,但只有片段导航包含同步调用更新文档以应用历史记录步骤。URL和历史记录更新步骤在上述算法中执行一些选定的更新,省略了其他更新。这有点不幸的历史事故,通常导致Web 开发者的不满,因为这种不一致。例如,这意味着popstate
事件会为片段导航触发,但不会为history.pushState()
调用触发。
如概述中所解释的,导航和遍历都涉及创建一个会话历史条目,然后尝试填充其文档成员,以便它可以在可导航中呈现。
这涉及使用已给定的响应;使用存储在会话历史条目中的srcdoc资源;或获取。该过程有多种失败模式,这些模式可能导致不做任何事情(将可导航保留在其当前的活动文档
上)或导致用错误文档填充会话历史条目。
为了尝试填充历史条目的文档,给定一个会话历史条目entry,一个可导航navigable,一个NavigationTimingType
navTimingType,一个源快照参数sourceSnapshotParams,一个目标快照参数targetSnapshotParams,一个可选的导航ID或nullnavigationId(默认为null),一个可选的导航参数或nullnavigationParams(默认为null),一个可选的字符串cspNavigationType(默认为"other
"),一个可选的布尔值allowPOST(默认为false),以及可选的算法步骤completionSteps(默认为一个空的算法),请执行以下步骤:
令currentBrowsingContext为navigable的活动浏览上下文。
如果navigationParams为null,则:
如果documentResource是字符串,则将navigationParams设置为结果,从srcdoc资源创建导航参数,给定entry、navigable、targetSnapshotParams、navigationId和navTimingType。
否则,如果以下所有条件为真:
然后将navigationParams设置为结果,通过获取创建导航参数,给定entry、navigable、sourceSnapshotParams、targetSnapshotParams、cspNavigationType、navigationId和navTimingType。
否则,如果 entry的URL的方案不是fetch方案,则将navigationParams设置为一个新的非fetch方案导航参数,其中包含:
为了从srcdoc资源创建导航参数,给定一个会话历史条目entry,一个可导航navigable,一个目标快照参数targetSnapshotParams,一个导航ID或nullnavigationId,以及一个NavigationTimingType
navTimingType:
令response为一个新的响应,其中:
about:srcdoc
Content-Type
`,`text/html
`)
»令responseOrigin为结果,确定来源,给定response的URL、targetSnapshotParams的沙盒标志和entry的文档状态的来源。
令coop为一个新的跨源打开者策略。
令coopEnforcementResult为一个新的跨源打开者策略执行结果,其中:
令policyContainer为结果,确定导航参数策略容器,给定response的URL、entry的文档状态的历史策略容器、null、navigable的容器文档的策略容器,以及null。
返回一个新的导航参数,其中:
此算法会更改entry。
令request为一个新的请求,其中:
如果documentResource是一个POST资源,则:
如果navigable的容器非空:
令response为null。
令responseOrigin为null。
令fetchController为null。
令 coopEnforcementResult 为一个新的 跨域打开者策略执行结果,其属性为:
令 finalSandboxFlags 为一个空的 沙盒标志集。
令 responsePolicyContainer 为 null。
令 responseCOOP 为一个新的 跨域打开者策略。
令 locationURL 为 null。
令 currentURL 为 request的 当前URL。
令 commitEarlyHints 为 null。
当条件成立时:
如果 request的 保留客户端 不为 null 且 currentURL的 来源 与 request的 保留客户端的 创建URL的 来源 不同,则:
如果 request的 保留客户端 为 null,则:
如果给定 request 和 cspNavigationType 的 内容安全策略应该阻止该类型的导航请求
的结果是"Blocked
",则将 response 设置为 网络错误 并
中断。[CSP]
将 response 设置为 null。
如果 fetchController 为 null,则将 fetchController 设置为 抓取 request 的结果,processEarlyHintsResponse 设置为下述 processEarlyHintsResponse,processResponse 设置为下述 processResponse,useParallelQueue 设置为 true。
令 processEarlyHintsResponse 为给定 earlyResponse 的下述算法:
令 processResponse 为给定 fetchedResponse 的下述算法:
将 response 设置为 fetchedResponse。
否则,处理下一个手动重定向对 fetchController。
这将在我们第一次迭代循环期间调用上述提供的 processResponse,从而设置 response。
导航手动处理重定向,因为导航是唯一关心重定向到mailto:
URL等的地方。
等待直到 response 为非 null,或者 navigable的 正在进行的导航 变更为不再等于 navigationId。
如果发生后一个条件,则 中止 fetchController,并返回。
否则,继续进行。
如果 request的 主体 为 null,则将 entry的 文档状态的 资源 设置为 null。
抓取会在特定重定向时取消 主体。
将 responsePolicyContainer 设置为 从抓取响应创建策略容器 给定 response 和 request的 保留客户端 的结果。
将 finalSandboxFlags 设置为 集合并集 由 targetSnapshotParams的 沙盒标志 和 responsePolicyContainer的 CSP列表 的 CSP派生沙盒标志 的结果。
将 responseOrigin 设置为 确定来源 给定 response的 URL,finalSandboxFlags,和 entry的 文档状态的 发起者来源 的结果。
如果 response 是重定向,则 response的 URL 将是导致重定向到 response的 位置URL 的URL;它不会是 位置URL 本身。
如果 navigable 是一个 顶级遍历,则:
将 responseCOOP 设置为 获取跨域打开者策略 给定 response 和 request的 保留客户端 的结果。
将 coopEnforcementResult 设置为 执行响应的跨域打开者策略 给定 navigable的 活动浏览上下文,response的 URL,responseOrigin,responseCOOP,coopEnforcementResult 和 request的 引用者 的结果。
如果 finalSandboxFlags 不为空且 responseCOOP的 值 不为"unsafe-none
",则将
response 设置为一个适当的 网络错误
并
中断。
这将导致网络错误,因为不能同时使用跨域打开者策略为响应提供一个干净的环境,并将导航到该响应的结果沙盒化。
如果 response 不是一个 网络错误,navigable 是一个 子导航,并且执行 跨域资源策略检查 给定 navigable的 容器文档的 来源,navigable的 容器文档的 相关设置对象,request的 目标,response,和 true 的结果是阻止,则将 response 设置为一个 网络错误 并 中断。
这里我们对父导航而非navigable本身运行 跨域资源策略检查。因为我们关心嵌入内容对父上下文的同源性,而不是导航源。
如果 locationURL 为失败或 null,则 中断。
将 entry的 经典历史API状态 设置为 StructuredSerializeForStorage(null)。
令 oldDocState 为 entry的 文档状态。
将 entry的 文档状态 设置为一个新的 文档状态,其属性为:
对于导航情况,只有entry引用oldDocState,它是在导航算法的早期创建的。所以对于导航,这在功能上只是更新entry的文档状态。对于遍历情况,可能相邻的会话历史条目也引用oldDocState,在这种情况下,即使我们更新了entry的文档状态,它们仍会继续引用它。
oldDocState的历史策略容器在这里仅在遍历情况下非null,此时我们在导航到一个需要在历史中存储策略容器的URL时填充它。
设置如下 Jake图所示:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
top |
/a | /a#foo | /a#bar | /b |
还假设步骤0、1和2中的条目共享的文档状态具有空的文档,即bfcache未启用。
现在考虑场景:我们向后遍历到步骤2,但这次抓取/a
时,服务器响应的`Location
`头指向/c
。也就是说,locationURL指向/c
,因此我们到了这一步而不是中断循环。
在这种情况下,我们替换了占据步骤2的文档状态,但不替换占据步骤0和1的条目的文档状态。结果的Jake图如下所示:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
top |
/a | /a#foo | /c#bar | /b |
注意,即使我们最终在重定向链回到原始URL中进行这种替换,例如,如果/c
本身有一个`Location
`头指向/a
。这种情况下将如下所示:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
top |
/a | /a#foo | /a#bar | /b |
将 currentURL 设置为 locationURL。
将 entry的 URL 设置为 currentURL。
如果 locationURL 是一个 URL,其 方案 不是 fetch 方案,则返回一个新的 非 fetch 方案导航参数,其属性为:
此时,request的 当前URL 是最后一个具有 URL 的重定向链中的 fetch 方案,在重定向到一个非 fetch 方案 URL 之前。这个 URL 的 来源 将用于导航到非 fetch 方案 URL。
如果以下任一条件成立:
则返回 null。
将 resultPolicyContainer 设置为 确定导航参数策略容器给定 response的 URL,entry的 文档状态的 历史策略容器,sourceSnapshotParams的 源策略容器,null和responsePolicyContainer。
如果 navigable的 容器 是一个 iframe
,且
response的 计时允许通过标志 已设置,则将 容器的
待定资源计时开始时间 设置为 null。
如果 iframe
允许报告资源计时,则我们不需要运行其回退步骤,因为正常的报告会发生。
返回一个新的 导航参数,其属性为:
一个元素有一个浏览上下文范围来源,如果它的 文档
的 节点可导航
是一个
顶级可遍历对象,或者如果它的所有 文档
的 祖先可导航对象 都有 活动文档,且这些活动文档的 来源
与该元素的 节点文档 的 来源
相同。如果一个元素有一个 浏览上下文范围来源,那么它的值是该元素的 节点文档的来源。
此定义有问题,需要调查其意图:见问题#4703。
要加载文档给定导航参数navigationParams、源快照参数sourceSnapshotParams,和initiatorOrigin,执行以下步骤。它们返回一个文档
或null。
将 type 设置为 navigationParams的 计算的类型。
如果用户代理已配置为使用除在可导航中渲染内容以外的某种机制来处理给定type的资源,则跳过此步骤。否则,如果type是以下类型之一:
text/css
"
text/plain
"
text/vtt
"
multipart/x-mixed-replace
"
multipart/x-mixed-replace
文档的结果,给定navigationParams、sourceSnapshotParams和initiatorOrigin。application/pdf
"text/pdf
"否则,继续进行。
明确支持的 XML MIME 类型 是一个 XML MIME
类型,用户代理配置为使用外部应用程序呈现内容,或者用户代理具有专用的处理规则。例如,具有内置 Atom 提要查看器的网络浏览器将被认为明确支持 application/atom+xml
MIME 类型。
明确支持的 JSON MIME 类型 是一个 JSON MIME 类型,用户代理配置为使用外部应用程序呈现内容,或者用户代理具有专用的处理规则。
在这两种情况下,外部应用程序或用户代理将直接在navigationParams的可导航中内联显示内容,或将其交给外部软件。两者都在下面的步骤中进行。
否则,文档的type是这样的资源将不会影响navigationParams的可导航,例如因为资源将交给外部应用程序,或者因为它是未知类型,将作为下载处理。将其交给外部软件,给定navigationParams的响应、navigationParams的可导航、navigationParams的最终沙盒标志集合、sourceSnapshotParams的是否具有临时激活,和initiatorOrigin。
返回 null。
对于导航和遍历,一旦我们确定了在会话历史中要前往的地方,很多工作都是将这一概念应用到可遍历的导航和相关的文档
。对于导航,这项工作通常在过程的末尾进行;对于遍历,这是开始。
确保可遍历的导航最终到达正确的会话历史步骤尤其复杂,因为它可能涉及多个可遍历导航的子孙的协调,并行填充,然后同步以确保每个人对结果有相同的看法。这更复杂,因为存在同步的同文档导航与跨文档导航混合在一起,以及网页的某些相对时间预期。
改变可导航的连续状态用于在应用历史步骤算法期间存储信息,允许算法的一部分在其他部分完成后继续。它是一个结构,包含:
文档
尽管所有对可遍历的导航的更新最终都在同一个应用历史步骤算法中进行,每个可能的入口点都有一些小的定制:
对于给定可遍历的导航traversable的可导航创建/销毁更新:
让step为traversable的当前会话历史步骤。
返回将历史步骤step应用于traversable的结果,给定false、null、null、null和null。
对于给定非负整数step和历史处理行为historyHandling的应用推送/替换历史步骤:
返回将历史步骤step应用于traversable的结果,给定false、null、null、null和historyHandling。
应用推送/替换历史步骤从不传递源快照参数或发起可导航到应用历史步骤。这是因为这些检查在导航算法中更早进行。
对于给定可遍历的导航traversable的应用重新加载历史步骤:
应用重新加载历史步骤从不传递源快照参数或发起可导航到应用历史步骤。这是因为重新加载始终被视为由navigable本身进行,即使在parent.location.reload()
的情况下也是如此。
对于给定非负整数step的可遍历的导航traversable,带有源快照参数sourceSnapshotParams、可导航initiatorToCheck和用户导航参与 userInvolvement的应用遍历历史步骤:
返回将历史步骤step应用于traversable的结果,给定true、sourceSnapshotParams、initiatorToCheck、userInvolvement和"traverse
"。
现在是算法本身。
对于给定非负整数step的可遍历的导航traversable,带有布尔值checkForCancelation、源快照参数-或-nullsourceSnapshotParams、可导航-或-nullinitiatorToCheck、用户导航参与-或-nulluserInvolvementForNavigateEvents和导航类型
-或-nullnavigationType,执行以下步骤。它们返回"initiator-disallowed
"、"canceled-by-beforeunload
"、"canceled-by-navigate
"或"applied
"。
让targetStep为获取已用步骤的结果,给定traversable和step。
如果initiatorToCheck不为null,则:
断言:sourceSnapshotParams不为null。
对于每个navigable的获取所有当前会话历史条目将更改或重新加载的可导航:如果initiatorToCheck未被沙箱允许导航,则返回"initiator-disallowed
"。
让navigablesCrossingDocuments为获取所有可能经历跨文档遍历的可导航的结果,给定traversable和targetStep。
如果checkForCancelation为true,并且检查卸载是否取消的结果不为"continue
",则返回该结果。
让changingNavigables为获取所有当前会话历史条目将更改或重新加载的可导航的结果,给定traversable和targetStep。
让nonchangingNavigablesThatStillNeedUpdates为获取所有仅需要历史对象长度/索引更新的可导航的结果,给定traversable和targetStep。
对于每个changingNavigables的navigable:
让totalChangeJobs为changingNavigables的大小。
让completedChangeJobs为0。
让changingNavigableContinuations为一个空的队列,包含改变的可导航连续状态。
该队列用于将changingNavigables的操作分为两部分。具体来说,changingNavigableContinuations保存第二部分的数据。
对于 changingNavigables 中的每个 navigable,在 navigable 的 活动窗口 上,根据 导航和遍历任务源 排队一个全局任务 以运行以下步骤:
这组步骤分为两部分,以允许在文档卸载之前处理同步导航。状态存储在 changingNavigableContinuations 中用于第二部分。
让displayedEntry为navigable的活动会话历史条目。
让targetEntry为navigable的当前会话历史条目。
让changingNavigableContinuation为一个改变的可导航连续状态,包含:
如果displayedEntry是targetEntry,且targetEntry的文档状态的重新加载挂起为false,则:
将changingNavigableContinuation的仅更新设置为true。
将changingNavigableContinuation加入队列到changingNavigableContinuations。
中止这些步骤。
切换navigationType:
如果targetEntry的文档为null,或者targetEntry的文档状态的重新加载挂起为true,则:
让navTimingType为"back_forward
",如果targetEntry的文档为null;否则为"reload
"。
让targetSnapshotParams为快照目标快照参数的结果,给定navigable。
让potentiallyTargetSpecificSourceSnapshotParams为sourceSnapshotParams。
如果potentiallyTargetSpecificSourceSnapshotParams为null,则将其设置为快照源快照参数的结果,给定navigable的活动文档。
在这种情况下,没有明确的遍历/重新加载来源。我们将这种情况视为navigable自己导航,但注意targetEntry的原始发起者的某些属性保留在targetEntry的文档状态中,例如发起者起源和引用来源,这将适当地影响导航。
并行,尝试填充历史条目的文档,给定targetEntry、navigable、potentiallyTargetSpecificSourceSnapshotParams、targetSnapshotParams,带有allowPOST设置为allowPOST和完成步骤,在navigable的活动窗口上的导航和遍历任务源上排队一个全局任务,以执行afterDocumentPopulated。
否则,立即运行afterDocumentPopulated。
在这两种情况下,让afterDocumentPopulated为以下步骤:
如果targetEntry的文档为null,则将changingNavigableContinuation的仅更新设置为true。
这意味着我们尝试填充文档,但未能成功,例如服务器返回204。
这些类型的导航或遍历失败将不会通过任何导航API(例如,任何导航API方法跟踪器的承诺或navigateerror
事件)传达给导航API。这么做会泄露跨起源情况下其他起源响应时间的信息,并且在跨起源与同起源情况下提供不同的结果被认为太过混乱。
然而,实现可能会利用这个机会清除任何navigation.transition.finished
承诺的处理程序,因为此时它们保证永远不会运行。而且,它们可能希望向控制台报告警告,如果导航API的任何部分发起了这些导航,以使网络开发人员明白为什么他们的承诺永远不会解决和事件永远不会触发。
如果targetEntry的文档的起源与oldOrigin不同,则将targetEntry的经典历史API状态设置为StructuredSerializeForStorage(null)。
这会在起源与之前加载的targetEntry未发生重定向的情况下发生变化时清除历史状态。这可能是由于CSP沙箱标头的更改。
如果以下所有条件都为真:
将changingNavigableContinuation加入队列到changingNavigableContinuations。
此作业的其余部分稍后在此算法中运行。
让navigablesThatMustWaitBeforeHandlingSyncNavigation为一个空的集合。
当completedChangeJobs不等于totalChangeJobs时:
如果traversable的正在运行嵌套应用历史步骤为false,则:
让changingNavigableContinuation为从changingNavigableContinuations中出列的结果。
如果changingNavigableContinuation为空,则继续。
让displayedDocument为changingNavigableContinuation的显示的文档。
让targetEntry为changingNavigableContinuation的目标条目。
让navigable为changingNavigableContinuation的可导航。
让(scriptHistoryLength,scriptHistoryIndex)为获取历史对象长度和索引的结果,给定traversable和targetStep。
这些值可能已更改自上次计算以来。
附加navigable到navigablesThatMustWaitBeforeHandlingSyncNavigation。
一旦可导航到达遍历中的此点,另外排队的同步导航步骤很可能是意图在此遍历之后而不是之前发生,因此它们不再跳过队列。更多细节请参阅此处。
让entriesForNavigationAPI为获取导航API的会话历史条目的结果,给定navigable和targetStep。
如果changingNavigableContinuation的仅更新为true,或targetEntry的文档是displayedDocument,则:
这是一个同文档导航:我们在不卸载的情况下继续。
否则:
断言:navigationType不为null。
停用文档以进行跨文档导航,给定displayedDocument、userNavigationInvolvement、targetEntry、navigationType和afterPotentialUnloads。
在两种情况下,让afterPotentialUnloads为以下步骤:
如果changingNavigableContinuation的仅更新为false,则激活历史条目targetEntry,对于navigable。
让updateDocument为一个算法步骤,执行更新文档以应用历史步骤,给定targetEntry的文档、targetEntry、changingNavigableContinuation的仅更新、scriptHistoryLength、scriptHistoryIndex、navigationType、entriesForNavigationAPI和displayedEntry。
如果targetEntry的文档等于displayedDocument,则执行updateDocument。
否则,在 targetEntry 的 文档 的 相关全局对象 上,根据 导航和遍历任务源 排队一个全局任务 以执行 updateDocument。
递增completedChangeJobs。
让totalNonchangingJobs为大小的nonchangingNavigablesThatStillNeedUpdates。
此步骤起故意等待所有先前的操作完成,因为它们包括处理同步导航,这些导航也会发布任务以更新历史长度和索引。
让completedNonchangingJobs为0。
让(scriptHistoryLength,scriptHistoryIndex)为获取历史对象长度和索引的结果,给定traversable和targetStep。
对于 nonchangingNavigablesThatStillNeedUpdates 中的每个 navigable,在 navigable 的 活动窗口 上,根据 导航和遍历任务源 排队一个全局任务 以运行以下步骤:
等待completedNonchangingJobs等于totalNonchangingJobs。
将traversable的当前会话历史步骤设置为targetStep。
返回"applied
"。
要停用文档以进行跨文档导航,给定一个Document
displayedDocument,一个用户导航参与userNavigationInvolvement,一个会话历史条目targetEntry,一个NavigationType
navigationType和一个afterPotentialUnloads,它是一个不接收参数的算法:
让navigable为displayedDocument的节点可导航。
让potentiallyTriggerViewTransition为false。
让isBrowserUINavigation为true,如果userNavigationInvolvement是"浏览器UI
";否则为false。
将potentiallyTriggerViewTransition设置为调用导航是否可以触发跨文档视图转换?的结果,给定displayedDocument、targetEntry的文档、navigationType和isBrowserUINavigation。
如果potentiallyTriggerViewTransition为false,则:
让firePageSwapBeforeUnload为以下步骤:
触发pageswap
事件,给定displayedDocument、targetEntry、navigationType和null。
设置正在进行的导航为navigable为null。
这允许新的导航开始,而在遍历期间它们被阻止。
卸载文档及其后代,给定displayedDocument、targetEntry的文档、afterPotentialUnloads和firePageSwapBeforeUnload。
否则,在 navigable 的 活动窗口 上,根据 导航和遍历任务源 排队一个全局任务 以运行以下步骤:
让proceedWithNavigationAfterViewTransitionCapture为以下步骤:
让viewTransition为设置跨文档视图转换的结果,给定displayedDocument、targetEntry的文档、navigationType和proceedWithNavigationAfterViewTransitionCapture。
触发pageswap
事件,给定displayedDocument、targetEntry、navigationType和viewTransition。
如果viewTransition为null,则运行proceedWithNavigationAfterViewTransitionCapture。
在视图转换开始的情况下,视图转换算法负责调用proceedWithNavigationAfterViewTransitionCapture。
要触发pageswap
事件,给定一个Document
displayedDocument,一个会话历史条目targetEntry,一个NavigationType
navigationType和一个ViewTransition
-或-nullviewTransition:
让activation为null。
如果以下所有条件都为真:
targetEntry的文档的未通过跨起源重定向创建为false,或者targetEntry的文档的最新条目不为null,
则:
通过切换navigationType确定destinationEntry:
将activation设置为在displayedDocument的相关领域中创建的一个新的新的NavigationActivation
,其中
这意味着导航期间的跨起源重定向将导致旧文档的激活
为空的PageSwapEvent
,除非从bfcache恢复新文档。
触发一个事件,名为pageswap
,在displayedDocument的相关全局对象上,使用PageSwapEvent
,其激活
设置为activation,其viewTransition
设置为viewTransition。
要激活会话历史条目session history entryentry,用于navigablenavigable:
让newDocument为entry的文档。
断言:newDocument的初始about:blank
为false,即我们永远不会回到初始about:blank
Document
,因为当我们导航离开它时,它总是被替换。
设置navigable的活动会话历史条目为entry。
激活newDocument。
要获取使用的步骤,给定可遍历的可导航对象traversable和一个非负整数step,执行以下步骤。它们返回一个非负整数。
让steps为获取所有使用过的历史步骤在traversable中。
返回steps中小于或等于step的最大项目。
要获取历史对象的长度和索引,给定可遍历的可导航对象traversable和一个非负整数step,执行以下步骤。它们返回一个元组,包含两个非负整数。
让steps为获取所有使用过的历史步骤在traversable中。
让scriptHistoryLength为steps的大小。
假设step已通过获取使用的步骤进行调整。
让scriptHistoryIndex为step在steps中的索引。
返回(scriptHistoryLength, scriptHistoryIndex)。
要获取所有当前会话历史条目将更改或重新加载的可导航对象,给定可遍历的可导航对象traversable和一个非负整数targetStep,执行以下步骤。它们返回一个列表,包含navigables。
让results为一个空的列表。
让navigablesToCheck为« traversable »。
此列表将在下面的循环中扩展。
对每个navigable在navigablesToCheck中:
让targetEntry为获取目标历史条目的结果,给定navigable和targetStep。
如果targetEntry不是navigable的当前会话历史条目或targetEntry的文档状态的重新加载挂起为true,则附加navigable到results。
如果targetEntry的文档是navigable的文档,且targetEntry的文档状态的重新加载挂起为false,则扩展navigablesToCheck与navigable的子可导航对象。
将子可导航对象添加到navigablesToCheck意味着这些可导航对象也将在此循环中被检查。只有在navigable的活动文档不会在此遍历中更改时才会检查子可导航对象。
返回results。
要获取仅需要历史对象长度/索引更新的所有可导航对象,给定可遍历的可导航对象traversable和一个非负整数targetStep,执行以下步骤。它们返回一个列表,包含navigables。
其他可导航对象可能不会受到遍历的影响。例如,如果响应为204,当前活动文档将保持不变。此外,导航到204之后的“返回”操作将更改当前会话历史条目,但活动会话历史条目将已是正确的。
让results为一个空的列表。
让navigablesToCheck为« traversable »。
此列表将在下面的循环中扩展。
对每个navigable在navigablesToCheck中:
返回results。
要获取目标历史条目,给定navigablenavigable和一个非负整数step,执行以下步骤。它们返回一个会话历史条目。
为了了解为什么获取目标历史条目返回具有最大值的步骤小于或等于输入步骤,请考虑以下Jake图:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
top |
/t | /t#foo | ||
frames[0] |
/i-0-a | /i-0-b |
对于输入步骤1,top
可导航对象的目标历史条目是/t
条目,其步骤为0,而frames[0]
可导航对象的目标历史条目是/i-0-b
条目,其步骤为1:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
top |
/t | /t#foo | ||
frames[0] |
/i-0-a | /i-0-b |
同样,给定输入步骤3,我们得到top
条目,其步骤为3,和frames[0]
条目,其步骤为1:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
top |
/t | /t#foo | ||
frames[0] |
/i-0-a | /i-0-b |
要获取所有可能经历跨文档遍历的可导航对象,给定可遍历的可导航对象traversable和一个非负整数targetStep,执行以下步骤。它们返回一个列表,包含navigables。
从traversable的会话历史遍历队列的角度来看,这些文档在由targetStep描述的遍历期间有可能进行跨文档遍历。如果目标文档的状态码为HTTP 204 No Content,它们将不会经历跨文档遍历。
请注意,如果给定的navigable可能经历跨文档遍历,此算法将返回navigable,但不会返回其子可导航对象。这些将被卸载,而不是遍历。
让results为一个空的列表。
让navigablesToCheck为« traversable »。
此列表将在下面的循环中扩展。
对每个navigable在navigablesToCheck中:
让targetEntry为获取目标历史条目的结果,给定navigable和targetStep。
如果targetEntry的文档不是navigable的文档或targetEntry的文档状态的重新加载挂起为true,则附加navigable到results。
尽管navigable的活动历史条目可以同步更改,但
新条目将始终具有相同的文档
,因此访问navigable的文档是可靠的。
否则,扩展navigablesToCheck与navigable的子可导航对象。
将子可导航对象添加到navigablesToCheck意味着这些可导航对象也将在此循环中被检查。只有在navigable的活动文档不会在此遍历中更改时才会检查子可导航对象。
返回results。
要更新历史步骤应用的文档,给定Document
document,会话历史条目entry,布尔值doNotReactivate,整数scriptHistoryLength和scriptHistoryIndex,NavigationType
-或-nullnavigationType,一个可选的列表,包含会话历史条目entriesForNavigationAPI,和一个可选的会话历史条目previousEntryForActivation:
如果document的最新条目为null,则设documentIsNew为true;否则为false。
如果document的最新条目不是entry,则设documentsEntryChanged为true;否则为false。
如果documentsEntryChanged为true,则:
将document的最新条目设为entry。
恢复历史对象状态,给定document和entry。
如果documentIsNew为false,则:
断言:navigationType不是null。
更新相同文档导航的导航API条目,给定navigation,entry和navigationType。
触发名为popstate
的事件,在document的相关全局对象上,使用PopStateEvent
,其中state
属性初始化为document的历史对象的状态,并且hasUAVisualTransition
初始化为true,如果用户代理执行了可视化过渡,以显示document的最新条目的缓存渲染状态。
恢复持久化状态,给定entry。
如果oldURL的片段不等于entry的URL的片段,则在document的相关全局对象上排队一个全局任务,在DOM操作任务源上触发名为hashchange
的事件,在document的
相关全局对象上,使用HashChangeEvent
,其中oldURL
属性初始化为oldURL的序列化值,newURL
属性初始化为entry的URL的序列化值。
否则:
断言:entriesForNavigationAPI被提供。
恢复持久化状态,给定entry。
初始化新文档的导航API条目,给定navigation、entriesForNavigationAPI和entry。
如果以下条件都为真:
previousEntryForActivation被提供;
navigationType非null;并且
navigationType是"reload
"或previousEntryForActivation的文档不是document,
则:
如果navigation的激活为null,则将navigation的激活设为一个新的NavigationActivation
对象,在navigation的相关领域中。
让previousEntryIndex为在navigation内获取导航API条目索引的结果,给定previousEntryForActivation。
如果previousEntryIndex是非负的,则将activation的旧条目设为navigation的条目列表[previousEntryIndex]。
否则,如果以下条件都为真:
navigationType是"replace
";
previousEntryForActivation的文档的初始about:blank
为false,
则将activation的旧条目设为一个新的NavigationHistoryEntry
,在navigation的相关领域中,其会话历史条目为previousEntryForActivation。
将activation的导航类型设为navigationType。
如果documentIsNew为true,则:
尝试滚动到片段,给定document。
此时脚本可能会运行新创建的文档document。
否则,如果documentsEntryChanged为false且doNotReactivate为false,则:
documentsEntryChanged可以为false,原因之一是我们从bfcache恢复,或者我们异步完成了同步导航,这已经同步设置了document的最新条目。参数doNotReactivate区分了这两种情况。
要恢复历史对象状态,给定Document
document和会话历史条目entry:
要激活一个Document
document:
让window为document的相关全局对象。
将document的浏览上下文的WindowProxy
的[[Window]]内部槽值设为window。
排队 一个新的
VisibilityStateEntry
,其
可见性状态 是
document 的 可见性状态,其 时间戳 为零。
要重新激活一个Document
document,给定会话历史条目reactivatedEntry和一个列表,包含会话历史条目entriesForNavigationAPI:
此算法在document从bfcache恢复后更新,即再次完全激活之后。其他规范如果希望监视此更改为完全激活状态的变化,建议将步骤添加到此算法中,以便清楚地了解由于此更改而发生的事件顺序。
更新重新激活的导航API条目,给定document的相关全局对象的导航API,entriesForNavigationAPI和reactivatedEntry。
如果document的当前文档就绪状态是"complete
",并且document的页面显示标志为false,则:
将document的页面显示标志设为true。
将document的已显示标志设为false。
更新文档的可见性状态为"visible
"。
触发一个页面过渡事件,名为pageshow
,在document的相关全局对象上,带有true。
要尝试滚动到片段,给定一个Document
document,请执行以下步骤并行:
等待一个实现定义的时间。(这旨在允许用户代理在面对性能问题时优化用户体验。)
在document的相关全局对象上排队一个全局任务,在导航和遍历任务源上运行这些步骤:
要使文档不可挽救,给定一个Document
document和一个字符串reason:
附加 details 到 document 的 bfcache 阻止详情。
将document的可挽救状态设为false。
要为文档状态建立未恢复的原因,给定Document
document:
让notRestoredReasonsForDocument成为一个新的未恢复原因。
将notRestoredReasonsForDocument的原因设为document的克隆副本bfcache阻止详情。
对于document的文档树子导航中的每个navigable:
让childDocument为navigable的活动文档。
为文档状态建立未恢复的原因,给定childDocument。
将document的节点导航的活动会话历史条目的文档状态的未恢复原因设为notRestoredReasonsForDocument。
要为顶级可遍历及其后代建立未恢复的原因,给定顶级可遍历topLevelTraversable:
为文档状态建立未恢复的原因,给定topLevelTraversable的活动文档。
让crossOriginDescendants为一个空的列表。
让crossOriginDescendantsPreventsBfcache为false。
对于crossOriginDescendants中的每个crossOriginNavigable:
如果crossOriginDescendantsPreventsBfcache为true,则使文档不可挽救,给定topLevelTraversable的活动文档和"masked
"。
一个Document
有一个布尔值已显示,最初为false。它用于确保pagereveal
事件在每次激活Document
时触发一次(初次渲染时一次,以及每次重新激活时一次)。
要显示一个Document
document:
如果document的已显示为true,则返回。
将document的已显示设为true。
让transition为解析跨文档视图转换的结果,针对document。
触发一个事件,命名为pagereveal
,在document的相关全局对象上,使用PageRevealEvent
,并将其viewTransition
设置为transition。
如果transition不为null,则:
激活视图转换可能会解析/拒绝承诺,因此通过包装准备/清理激活,我们确保在下一个渲染步骤之前处理这些承诺。
尽管pagereveal
保证在显示页面的最新版本的第一个更新渲染步骤中触发,但用户代理可以在触发之前显示页面的缓存帧。这可以防止pagereveal
处理程序的存在延迟此类缓存帧的显示。
要滚动到片段,给定一个Document
document:
将document的目标元素设为null。
滚动到文档的开头,针对document。[CSSOMVIEW]
返回。
否则:
一个Document
的指示部分是其URL的片段所标识的部分,或如果片段未标识任何内容则为null。片段的语义在将其映射到节点时由定义Document
所使用的MIME类型的规范定义(例如,片段的处理对于XML MIME类型是由RFC7303负责的)。[RFC7303]
每个Document
也有一个目标元素,用于定义:target
伪类并由上述算法更新。初始为null。
对于一个HTML文档 document,其指示部分是给定document和document的URL的选择指示部分的结果。
要选择指示部分,给定一个Document
document和一个URL url:
将fragment设为url的片段。
如果fragment是空字符串,则返回特殊值文档顶部。
将potentialIndicatedElement设为找到的潜在指示元素的结果,给定document和fragment。
如果potentialIndicatedElement不为null,则返回potentialIndicatedElement。
将fragmentBytes设为百分比解码 fragment的结果。
将decodedFragment设为运行无BOM的UTF-8解码在fragmentBytes上的结果。
将potentialIndicatedElement设为找到的潜在指示元素的结果,给定document和decodedFragment。
如果potentialIndicatedElement不为null,则返回potentialIndicatedElement。
如果decodedFragment与字符串top
进行ASCII不区分大小写匹配,则返回文档顶部。
返回null。
要找到潜在的指示元素,给定一个Document
document和一个字符串fragment,运行以下步骤:
要将持久化状态保存到会话历史条目 entry:
要从会话历史条目 entry中恢复持久化状态:
如果entry的滚动恢复模式是“auto
”,并且entry的文档的相关全局对象的导航API的在进行中的导航期间抑制正常滚动恢复为假,则恢复滚动位置数据,给定entry。
用户代理不恢复滚动位置并不意味着滚动位置将保持在任何特定值(例如(0,0))。实际的滚动位置取决于导航类型和用户代理的特定缓存策略。因此,Web应用程序不能假定任何特定的滚动位置,而是建议将其设置为所需的值。
如果在进行中的导航期间抑制正常滚动恢复为真,则恢复滚动位置数据可能仍会在稍后作为相关NavigateEvent
的完成的一部分发生,或者通过navigateEvent.scroll()
方法调用。
可选地,更新entry的文档及其渲染的其他方面,例如用户代理先前在entry的持久化用户状态中记录的表单字段的值。
这甚至可以包括更新dir
属性,textarea
元素或input
元素的type
属性在文本、搜索、电话、URL或电子邮件状态,如果持久化状态包括这些控件中用户输入的方向性。
作为此过程的一部分恢复表单控件的值不会触发任何input
或change
事件,但可以触发与表单相关的自定义元素的formStateRestoreCallback
。
每个Document
都有一个布尔值已被用户滚动,初始值为假。如果用户滚动文档,用户代理必须将该文档的已被用户滚动设置为真。
Document
的可恢复滚动区域是document的视口,以及所有document的可滚动区域,不包括任何可导航容器。
子导航滚动恢复作为这些导航的Document
的会话历史条目的状态恢复的一部分进行处理。
要恢复滚动位置数据,给定一个会话历史条目 entry:
将document设为entry的文档。
如果document的已被用户滚动为真,则用户代理应返回。
用户代理应尝试使用entry的滚动位置数据恢复entry的文档的可恢复滚动区域的滚动位置。用户代理可能会继续尝试定期执行此操作,直到document的已被用户滚动变为真。
这被表述为一种尝试,可能会重复直到成功或用户滚动,因为滚动位置数据指示的相关内容可能需要一些时间从网络加载。
滚动恢复可能会受到滚动锚定的影响。[CSSSCROLLANCHORING]
使用以下算法之一加载文档时,我们使用以下步骤来创建并初始化一个Document
对象,给定一个类型
type,内容类型 contentType,以及导航参数 navigationParams:
Document
对象在创建新的浏览上下文和文档时也会创建;此算法从不创建这样的初始about:blank
Document
。此外,可以通过各种API创建无浏览上下文的Document
对象,例如document.implementation.createHTMLDocument()
。
根据browsingContext、navigationParams的最终沙盒标志集、navigationParams的跨源打开者策略以及navigationParams的COOP执行结果,将browsingContext设置为获取用于导航响应的浏览上下文的结果。
这可能会导致浏览上下文组切换,在这种情况下,browsingContext将是一个新创建的浏览上下文,而不是navigationParams的可导航对象的活动浏览上下文。在这种情况下,创建的Window
、Document
和代理将不会被使用;由于创建的Document
的来源是不透明的不透明,我们将在本算法稍后创建一个新的代理和Window
以配合新的Document
。
让permissionsPolicy成为根据navigationParams的可导航对象的容器、navigationParams的来源和navigationParams的响应来创建权限策略的结果。[PERMISSIONSPOLICY]
此创建权限策略算法使用传递的来源。如果document.domain
已被用于navigationParams的可导航对象的容器文档,则其来源不能与传递的来源为同源域,因为这些步骤在document创建之前运行,因此它本身尚未使用document.domain
。请注意,这意味着权限策略检查比进行同源检查要不那么宽松。
请参见下面的一些实际示例。
如果navigationParams的请求非空,则将creationURL设置为navigationParams的请求的当前URL。
让window为空。
如果browsingContext的活动文档的初始about:blank
为真,并且browsingContext的活动文档的来源与navigationParams的来源为同源域,则将window设置为browsingContext的活动窗口。
这意味着无论是初始about:blank
Document
,还是即将创建的新Document
,它们都将共享同一个Window
对象。
否则:
让oacHeader成为从navigationParams的响应的标头列表中获取“Origin-Agent-Cluster
”的结构化字段值的结果。
如果oacHeader不为空且oacHeader[0]为布尔值真,则让requestsOAC为真;否则为假。
让agent成为根据navigationParams的来源、browsingContext的组和requestsOAC获取的相似来源窗口代理的结果。
根据agent和以下自定义项创建一个新领域的结果,让realmExecutionContext成为:
对于全局对象,创建一个新的Window
对象。
对于全局this绑定,使用browsingContext的WindowProxy
对象。
将window设置为realmExecutionContext领域组件的全局对象。
让topLevelCreationURL成为creationURL。
让 topLevelOrigin成为navigationParams的来源。
如果navigable的容器不为空,则:
使用creationURL、realmExecutionContext、navigationParams的保留环境、topLevelCreationURL和topLevelOrigin设置窗口环境设置对象。
让loadTimingInfo成为一个新的文档加载计时信息,其导航开始时间设置为navigationParams的响应的计时信息的开始时间。
让document成为一个新的Document
,具有以下属性:
loading
"将window的关联Document
设置为document。
为Document
运行CSP初始化,给定document。[CSP]
如果navigationParams的请求非空,则:
如果navigationParams的fetch控制器不为空,则:
根据navigationParams的响应的计时信息、redirectCount、navigationParams的导航计时类型和navigationParams的响应的服务worker计时信息,创建导航计时条目。
如果navigationParams的响应具有“刷新
”标头,则:
我们目前没有处理多个“刷新
”标头的规范。这在issue #2900中被跟踪。
如果navigationParams的提交早期提示不为空,则使用document调用navigationParams的提交早期提示。
返回document。
在这个例子中,尽管在子文档尝试使用PaymentRequest
时,它们为同源域,但子文档仍不允许使用它。在初始化子文档时,只有父文档设置了document.domain
,而子文档没有。
<!-- https://foo.example.com/a.html -->
<!doctype html>
< script >
document. domain = 'example.com' ;
</ script >
< iframe src = b.html ></ iframe >
<!-- https://bar.example.com/b.html -->
<!doctype html>
< script >
document. domain = 'example.com' ; // This happens after the document is initialized
new PaymentRequest( …); // Not allowed to use
</ script >
在这个例子中,尽管在子文档尝试使用PaymentRequest
时,它们不是同源域,但子文档仍被允许使用它。在初始化子文档时,没有任何文档设置document.domain
,因此同源域回退到正常的同源检查。
<!-- https://example.com/a.html -->
<!doctype html>
< iframe src = b.html ></ iframe >
<!-- The child document is now initialized, before the script below is run. -->
< script >
document. domain = 'example.com' ;
</ script >
<!-- https://example.com/b.html -->
<!doctype html>
< script >
new PaymentRequest( …); // Allowed to use
</ script >
为了在给定Document
document的情况下填充html
/head
/body
:
为了加载HTML文档,给定导航参数 navigationParams:
让document成为创建和初始化Document
对象的结果,给定"html
"、"text/html
"和
navigationParams。
如果document的URL是
about:blank
,那么填充
html
/head
/body
给定document。
这个特殊情况,即使是非初始
about:blank
Document
也被同步赋予了它们的元素节点,这是为了与部署的内容兼容。换句话说,使用空的字节序列来异步填充document的HTML解析器是不可兼容的。
否则,创建一个HTML解析器并将其与document关联。 在获取运行时,网络任务源放置在任务队列中的每个任务必须填充解析器的输入字节流以获取的字节,并使HTML解析器对输入流执行适当的处理。
在获取运行时,网络任务源放置在任务队列中的第一个任务必须在任务被HTML解析器处理后,给定document、navigationParams的响应和"media
",处理链接头。
在任何脚本执行发生之前,用户代理必须等待脚本可以在新创建的文档中运行对于document为真。
输入字节流将字节转换为字符以供标记化器使用。此过程部分依赖于资源的实际内容类型元数据中找到的字符编码信息;计算类型不用于此目的。
当没有更多字节可用时,用户代理必须在网络任务源上给document的相关全局对象排队一个全局任务,让解析器处理隐含的EOF字符,这最终导致触发load
事件。
返回document。
当需要内联显示XML文件时,给定导航参数
navigationParams和字符串type,用户代理必须遵循XML、XML中的命名空间、XML媒体类型、DOM及其他相关规范中的要求,创建并初始化一个Document
对象
document,给定"xml
"、type和
navigationParams,并返回该Document
。他们还必须创建一个相应的XML解析器。[XML] [XMLNS] [RFC7303]
[DOM]
在撰写本文时,XML规范社区尚未实际指定XML与DOM如何交互。
网络任务源在获取过程中放置在任务队列中的第一个任务,必须在任务被XML解析器处理后,处理链接头,给定document、navigationParams的响应和"media
"。
实际的HTTP头和其他元数据,而不是由本规范中的算法变更或暗示的头,必须用于根据上述规范中的规则确定字符编码。一旦确定了字符编码,文档的字符编码必须设置为该字符编码。
在任何脚本执行发生之前,用户代理必须等待脚本可以在新创建的文档中运行对于新创建的Document
为真。
一旦解析完成,用户代理必须将document的WebDriver BiDi期间加载导航ID设置为null。
对于HTML文档,这将在解析完成后重置,并触发load事件。
解析过程中产生的错误信息(例如,XML命名空间格式正确性错误)可以通过修改Document
来内联报告。
要加载一个文本文档,给定导航参数 navigationParams和一个字符串type:
让document成为创建并初始化一个Document
对象的结果,给定"html
"、type和
navigationParams。
将document的解析器不能更改模式标志设置为true。
将document的模式设置为"no-quirks
"。
创建一个HTML解析器并将其与document关联。像标记器已经发出一个标签名为“pre”的开始标签token后跟一个U+000A换行符(LF)字符一样操作,并将HTML解析器的标记器切换到PLAINTEXT状态。在获取运行时网络任务源放置在任务队列上的每个任务都必须用获取的字节填充解析器的输入字节流并使HTML解析器对输入流进行适当的处理。
document的编码必须设置为解析过程中用于解码文档的字符编码。
在获取运行时网络任务源放置在任务队列上的第一个任务,在任务被HTML解析器处理后,必须处理链接头,给定document、navigationParams的响应和"media
"。
在任何脚本执行发生之前,用户代理必须等待脚本可以在新创建的文档中运行对于document为真。
当没有更多的字节可用时,用户代理必须在 document 的 相关全局对象 上根据 网络任务源 排队一个全局任务,让解析器处理隐含的
EOF 字符,这最终会触发一个 load
事件。
用户代理可以向document的head
元素添加内容,例如链接到样式表、提供脚本或为文档提供title
。
特别地,如果用户代理支持RFC 3676的Format=Flowed
功能,则用户代理需要应用额外的样式以使文本正确换行并处理引用功能。这可以通过例如CSS扩展来执行。
返回document。
将纯文本文档的字节转换为实际字符的规则,以及将文本实际呈现给用户的规则,由资源的计算出的MIME类型(即type)的规范定义。
multipart/x-mixed-replace
文档要加载一个
multipart/x-mixed-replace
文档,给定导航参数
navigationParams,源快照参数
sourceSnapshotParams,
以及来源
initiatorOrigin:
让firstPartNavigationParams成为navigationParams的副本。
将firstPartNavigationParams的响应设置为一个新的响应,表示 navigationParams的响应的主体的多部分流的第一部分。
让document成为加载文档的结果,给定 firstPartNavigationParams、sourceSnapshotParams和 initiatorOrigin。
对于从navigationParams的响应获得的每个附加的主体部分,用户代理必须导航
document的节点导航到navigationParams的请求的URL,使用
document,将响应设置为
navigationParams的响应和历史处理设置为"替换
"。
返回document。
为了将这些主体部分作为完整的独立资源处理的算法目的,用户代理在到达紧跟在主体部分之后的边界时,必须表现得好像这些资源没有更多字节一样。
因此,每个加载的主体部分确实会触发load
事件(以及
unload
事件)。
要加载媒体文档,给定navigationParams和一个字符串type:
让document成为创建并初始化Document
对象的结果,给定"html
"、type和
navigationParams。
将document的模式
设置为"no-quirks
"。
使用html
/head
/body
填充给定的document。
将一个用于媒体的元素host element,如下所述,附加到body
元素中。
将适当的属性设置为图像、视频或音频资源的地址,如下所述。
用户代理可以向document的head
元素或
host element添加内容或属性,例如链接到样式表、提供脚本、给文档一个标题
或使媒体自动播放。
表现得好像用户代理已停止解析document。
返回document。
为媒体创建的元素host element是下表第二列中给出的元素,第一列描述了媒体类型。要设置的适当属性是同一行第三列给出的属性。
媒体类型 | 媒体的元素 | 适当的属性 |
---|---|---|
图像 | img
|
src
|
视频 | video
|
src
|
音频 | audio
|
src
|
在任何脚本执行发生之前,用户代理必须等待脚本可以在新创建的文档中运行对新创建的Document
为真。
当用户代理创建文档以内联显示用户代理页面或 PDF 查看器时,提供一个可导航对象
navigable、一个导航 ID
navigationId、一个NavigationTimingType
navTimingType,用户代理应:
让origin成为一个新的不透明来源。
让coop成为一个新的跨来源打开策略。
让coopEnforcementResult成为一个新的跨来源打开策略执行结果,具有以下属性:
让navigationParams成为一个新的导航参数,具有以下属性:
让document成为创建并初始化一个Document
对象的结果,给定"html
"、"text/html
"和
navigationParams。
要么将document与一个不使用正常Document
渲染规则的自定义渲染关联,要么修改document,直到它代表用户代理要渲染的内容。
返回document。
因为我们确保生成的Document
的来源是不透明的,
并且生成的Document
不能运行
具有访问 DOM 的脚本,这个Document
的存在和属性对 Web
开发者代码是不可观察的。这意味着大多数上述值,例如
text/html
类型,并不重要。
同样,navigationParams中的大多数项目没有任何可观察的效果,除了防止Document
创建算法混乱,因此设置为默认值。
页面设置完成后,用户代理必须表现得好像已停止解析。
一个Document
有一个完全加载时间(一个时间或空值),最初为空。
一个Document
被认为是完全加载的,如果它的完全加载时间不是空值。
要完全完成加载一个Document
document:
将document的完全加载时间设置为当前时间。
让container成为document的节点可导航对象的容器。
在document是初始about:blank
Document
在一个框架
或iframe
的情况下,这是空值,因为在调用这个算法的浏览上下文创建时,尚未建立容器关系。(这是在创建一个新的子可导航对象的后续步骤中发生的。)
其结果是,以下步骤什么也不做,即我们不会在这种情况下在容器元素上触发异步加载
事件。相反,在处理iframe
属性的特殊初始插入情况下,会触发同步加载
事件。
如果container是一个iframe
元素,则在container上给定iframe
加载事件步骤,排队一个元素任务到DOM 操作任务源。
否则,如果container不是空值,则在container上给定排队一个元素任务到DOM 操作任务源,触发一个名为加载
的事件。
一个Document
有一个可回收状态,最初必须为真,还有一个页面显示标志,最初必须为假。页面显示标志用于确保脚本以一致的方式接收pageshow
和pagehide
事件(例如,它们永远不会在没有中间pageshow
事件的情况下连续接收两个pagehide
事件,反之亦然)。
一个Document
有一个DOMHighResTimeStamp
暂停时间,最初为0。
事件循环有一个终止嵌套级别计数器,最初必须为0。
Document
对象有一个卸载计数器,用于在以下算法运行时忽略某些操作。最初,计数器必须设置为零。
要卸载一个Document
oldDocument,给定一个可选的Document
newDocument:
让unloadTimingInfo成为一个新的文档卸载时间信息。
如果未给出newDocument,则将unloadTimingInfo设置为空。
在这种情况下,没有需要了解oldDocument卸载时间的新文档。
否则,如果newDocument的事件循环不是oldDocument的事件循环,则用户代理可能并行卸载oldDocument。在这种情况下,用户代理应将unloadTimingInfo设置为空。
在这种情况下,newDocument的加载不受oldDocument卸载时间的影响,因此传达该时间信息没有意义。
让intendToKeepInBfcache为真,如果用户代理打算将oldDocument保留在会话历史条目中,以便以后用于历史遍历。
如果oldDocument不是可回收的,或者有任何后代用户代理不打算以相同方式保留的oldDocument(包括由于其缺乏可回收性),则此值必须为假。
将eventLoop的终止嵌套级别增加1。
将oldDocument的卸载计数器增加1。
如果intendToKeepInBfcache为假,则将oldDocument的可回收状态设置为假。
如果oldDocument的页面显示为真:
如果 unloadTimingInfo 不是 null,则将 unloadTimingInfo 的 卸载事件开始时间 设置为 newDocument 的 相关全局对象 给定的 当前高分辨率时间,并根据 oldDocument 的 相关设置对象 的 跨源隔离能力 粗化。
如果 oldDocument 的 可挽救状态 为 false,则在 oldDocument
的
相关全局对象 上 触发一个名为 unload
的事件,并设置
legacy target override flag。
如果 unloadTimingInfo 不是 null,则将 unloadTimingInfo 的 卸载事件结束时间 设置为 newDocument 的 相关全局对象 给定的 当前高分辨率时间,并根据 oldDocument 的 相关设置对象 的 跨源隔离能力 粗化。
将eventLoop的终止嵌套级别减少1。
将oldDocument的已被用户滚动设置为假。
如果oldDocument的节点可导航对象是顶级可遍历对象,则根据oldDocument的节点可导航对象,构建顶级可遍历对象及其后代的未恢复原因。
将oldDocument的卸载计数器减少1。
如果给出了newDocument,newDocument的不是通过跨域重定向创建的,并且newDocument的来源与oldDocument的来源相同,则将newDocument的先前文档卸载时间设置为unloadTimingInfo。
要卸载文档及其后代,给定一个Document
document,一个可选的Document
-或-nullnewDocument(默认值为null),一个可选的步骤集合afterAllUnloads,和一个可选的步骤集合firePageSwapSteps:
让childNavigables成为document的子可导航对象。
让numberUnloaded为0。
对于每个childNavigable的以何顺序?,在childNavigable的活动窗口上,导航和遍历任务源上排队一个全局任务以执行以下步骤:
等待直到numberUnloaded等于childNavigable的大小。
在document的相关全局对象上,在导航和遍历任务源上排队一个全局任务,以执行以下步骤:
如果给出了firePageSwapSteps,则运行firePageSwapSteps。
卸载document,如果newDocument不为空,则传递它。
如果给出了afterAllUnloads,则运行它。
本规范定义了以下卸载文档清理步骤。其他规范可以定义更多步骤。给定一个Document
document:
让window成为document的相关全局对象。
对于每个WebTransport
对象transport,其相关全局对象是window,运行上下文清理步骤,给定transport。
如果document的可回收状态为假,则:
对于每个EventSource
对象eventSource,其相关全局对象等于window,强制关闭eventSource。
如果规范作者发送拉取请求以直接在其规范中添加从此处调用的步骤,而不是使用卸载文档清理步骤钩子,将更好,以确保跨规范调用顺序明确。在撰写本文时,已知以下规范具有卸载文档清理步骤,这些步骤将按未指定的顺序运行:全屏API,Web NFC,XML媒体类型,WebDriver BiDi,计算压力,文件API,媒体捕获和流,画中画,屏幕方向,服务worker,Web锁定API,Web音频API,WebRTC。[FULLSCREEN][WEBNFC][WEBDRIVERBIDI][COMPUTEPRESSURE][FILEAPI][MEDIASTREAM][PICTUREINPICTURE][SCREENORIENTATION][SW][WEBLOCKS][WEBAUDIO][WEBRTC]
问题#8906跟踪明确这些步骤的顺序的工作。
要销毁一个
Document
document:
中止 document。
将document的可回收状态 设置为false。
让ports成为MessagePort
列表,其相关全局对象的关联Document
是
document。
对于ports中的每个port,解开 port。
将document的浏览上下文设置为 null。
从每个WorkerGlobalScope
对象的所有者集合中移除document。
对于document的每个worklet全局作用域中的workletGlobalScope,终止 workletGlobalScope。
即使在销毁后,在我们销毁子可导航对象的情况下,Document
对象本身可能仍然可以被脚本访问。
要销毁文档及其后代,给定一个Document
document和一个可选的步骤集合afterAllDestruction,请按照以下步骤并行执行:
如果document不是完全活跃的,则:
让childNavigables成为document的子可导航对象。
让numberDestroyed为0。
对于childNavigable的每个childNavigable,在childNavigable的活动窗口中,排队一个全局任务以执行以下步骤:
等待直到numberDestroyed等于childNavigable的大小。
在document的相关全局对象中排队一个全局任务以执行以下步骤:
销毁document。
如果给定了afterAllDestruction,则运行它。
要中止一个Document
document:
取消在document上下文中fetch
算法的任何实例,丢弃为其排队的任何任务,并丢弃从网络收到的任何进一步数据。如果这导致了fetch
算法的任何实例被取消或任何排队的任务或任何网络数据被丢弃,那么给定document和"fetch
",使文档不可回收。
如果 document 的 WebDriver BiDi 的加载期间导航 ID 不是 null,则:
调用 WebDriver BiDi 导航中止,使用 document 的 浏览上下文 和一个新的 WebDriver BiDi 导航状态,其中 id 是
document 的 加载期间导航 ID,状态
是
"canceled
",以及
url 是
document 的 URL。
将 document 的 WebDriver BiDi 的加载期间导航 ID 设置为 null。
如果document有一个活动解析器
,则:
将document的活动解析器被中止
设置为true。
将document的可回收设置为false。
给定document和"parser-aborted
",使文档不可回收
。
要中止文档及其后代,给定一个Document
document:
让descendantNavigables成为document的后代可导航对象
。
对于
descendantNavigable的每个descendantNavigables
按什么顺序?,在
descendantNavigable的活动窗口中排队一个全局任务以执行以下步骤:
中止
document。
要停止加载一个可导航对象
navigable:
让document成为navigable的活动文档
。
如果document的卸载计数器
为0,并且navigable的正在进行的导航
是一个导航ID
,则设置
navigable的正在进行的导航为null。
这将导致中止navigable的任何正在进行的导航,因为在导航期间的某些点,正在进行的导航
的更改将导致进一步的工作被放弃。
中止文档及其后代
,给定document。
通过其用户界面
,用户代理还允许停止遍历,即正在进行的导航
为"traversal
"的情况。上述算法未考虑这一点。(另一方面,用户代理不允许window.stop()
停止遍历,因此上述算法对该调用者是正确的。)参见问题#6905
。
X-Frame-Options
`
头部支持所有当前引擎。
`X-Frame-Options
`
HTTP响应头是一种控制是否以及如何将Document
加载到子导航对象中的传统方式。它被frame-ancestors
CSP指令取代,该指令提供了对相同情况的更细粒度控制。最初在HTTP Header Field X-Frame-Options中定义,但这里的定义和处理模型取代了该文档。
[CSP] [RFC7034]
特别是,HTTP Header Field X-Frame-Options指定了一个`ALLOW-FROM
`变体的头部,但不应实现。
根据以下处理模型,如果在同一个响应中同时使用CSP frame-ancestors
指令和`X-Frame-Options
`头部,则忽略`X-Frame-Options
`。
对于Web开发人员和一致性检查器,其值的ABNF为:
X-Frame-Options = "DENY" / "SAMEORIGIN"
要检查导航响应对`X-Frame-Options
`的遵守情况,给定一个响应 response,一个可导航对象 navigable,一个CSP列表 cspList,以及一个来源
destinationOrigin:
如果navigable不是一个子导航对象,则返回true。
对于 cspList中的每个policy:
如果policy的指令集包含一个frame-ancestors
指令,则返回true。
让rawXFrameOptions成为从response的头部列表获取、解码和分割`X-Frame-Options
`的结果。
让xFrameOptions成为一个新的集合。
对于rawXFrameOptions中的每个value,附加 value,转换为ASCII小写,到xFrameOptions。
如果xFrameOptions的大小大于1,并且xFrameOptions包含`deny
`、`allowall
`或`sameorigin
`中的任何一个,则返回false。
这里的意图是阻止任何尝试应用`X-Frame-Options
`的尝试,这些尝试试图做一些有效的事情,但看起来很困惑。
这是遗留的`ALLOWALL
`值对处理模型的唯一影响。
如果xFrameOptions的大小大于1,则返回true。
这意味着它包含多个无效值,我们将其视为完全省略了该头部。
如果xFrameOptions[0]是`deny
`,则返回false。
如果xFrameOptions[0]是`sameorigin
`,则:
返回true。
如果我们已经到达这一点,那么我们有一个孤立的无效值(可能是一个遗留的`ALLOWALL
`或`ALLOW-FROM
`形式)。这些被视为完全省略了该头部。
下表说明了头部的各种值的处理,包括不符合规定的值:
`X-Frame-Options `
|
有效 | 结果 |
---|---|---|
`DENY ` |
✅ | 禁止嵌入 |
`SAMEORIGIN ` |
✅ | 允许同源嵌入 |
`INVALID ` |
❌ | 允许嵌入 |
`ALLOWALL ` |
❌ | 允许嵌入 |
`ALLOW-FROM=https://example.com/ ` |
❌ | 允许嵌入(来自任何地方) |
下表说明了涉及多个值的各种不符合规定的情况如何处理:
`X-Frame-Options `
|
结果 |
---|---|
`SAMEORIGIN, SAMEORIGIN ` |
允许同源嵌入 |
`SAMEORIGIN, DENY ` |
禁止嵌入 |
`SAMEORIGIN, ` |
禁止嵌入 |
`SAMEORIGIN, ALLOWALL ` |
禁止嵌入 |
`SAMEORIGIN, INVALID ` |
禁止嵌入 |
`ALLOWALL, INVALID ` |
禁止嵌入 |
`ALLOWALL, ` |
禁止嵌入 |
`INVALID, INVALID ` |
允许嵌入 |
无论这些值是以逗号分隔的单个头部值传递,还是以多个头部传递,结果都是相同的。
Refresh
` 头部`Refresh
` HTTP响应头是HTTP等价于 meta
元素,带有
http-equiv
属性,并处于 Refresh
状态。它接受 相同的值,并且工作方式大致相同。其处理模型详述于 创建并初始化一个
Document
对象。
浏览器用户代理应该提供导航、重新加载和停止加载其顶层可导航对象集合中的任何顶层可导航对象的能力。
例如,通过地址栏和重新加载/停止按钮界面。
浏览器用户代理应该提供按增量遍历其顶层可导航对象集合中的任何顶层可导航对象的能力。
例如,通过后退和前进按钮,可能包括长按功能以改变增量。
建议这样的用户代理允许按大于一的增量进行遍历,以避免页面通过填充会话历史记录的虚假条目来“困住”用户。(例如,通过重复调用history.pushState()
或片段导航。)
一些用户代理有将单个“后退”或“前进”按钮按下转化为更大增量的启发式方法,专门用于克服此类滥用。我们正在考虑在问题#7832中指定这些启发式方法。
浏览器用户代理应该为用户提供创建一个新的顶层可导航对象的能力,给定用户提供的或用户代理确定的初始URL。
例如,通过“新建标签页”或“新建窗口”按钮。
浏览器用户代理应该为用户提供任意关闭其顶层可导航对象集合中的任何顶层可导航对象的能力。
例如,通过点击“关闭标签页”按钮。
浏览器用户代理可以提供用户明确导致任何可导航对象(不仅仅是一个顶层可导航对象)导航、重新加载或停止加载的方法。
例如,通过上下文菜单。
浏览器用户代理可以提供用户销毁一个顶层可导航对象的能力。
例如,通过强制关闭包含一个或多个此类顶层可导航对象的窗口。
当用户请求重新加载重新加载其活动会话历史条目的文档状态的资源是POST资源的可导航对象时,用户代理应该首先提示用户确认操作,因为否则交易(例如购买或数据库修改)可能会重复。
当用户请求重新加载重新加载其可导航对象时,用户代理可以提供忽略任何缓存的机制。
上述机制发起的所有导航调用必须将userInvolvement参数设置为`browser UI
`。
上述机制发起的所有重新加载调用必须将userInvolvement参数设置为`browser UI
`。
上述机制发起的 所有按增量遍历历史记录调用必须不传递sourceDocument参数。
上述建议和本规范中的数据结构不旨在对用户代理如何向用户表示会话历史记录施加限制。
例如,虽然顶层可导航对象的会话历史条目存储和维护为列表,并建议用户代理提供界面以按增量遍历该列表,但新型用户代理可以另外或替代地呈现树状视图,每个页面有多个“前进”页面供用户选择。
同样,虽然所有后代可导航对象的会话历史记录存储在其可导航对象中,但用户代理可以向用户呈现更细致的每个可导航对象的会话历史记录视图。
浏览器用户代理可以使用顶层浏览上下文的是否弹出窗口布尔值用于以下目的:
在这两种情况下,用户代理可能还会结合用户偏好,或提供选择是否走弹出窗口路线。
为这些弹出窗口提供最小用户界面的用户代理被鼓励不要隐藏浏览器的地址栏。
各种机制可以导致作者提供的可执行代码在文档的上下文中运行。这些机制包括但可能不限于:
script
元素。javascript:
URLs。addEventListener()
注册的,还是通过显式的 事件处理程序内容属性、事件处理程序 IDL 属性,或其他方式注册的。JavaScript 定义了 代理 的概念。本节提供了该语言级别概念在 Web 平台上的映射。
从概念上讲,代理 概念是 JavaScript 代码运行的架构无关的理想化 "线程"。这种代码可以涉及多个全局对象/realm,它们可以同步访问彼此,因此需要在单个执行线程中运行。
两个 Window
对象具有相同的 代理 并不表示它们可以直接访问彼此 realm 中创建的所有对象。它们必须是
同源域;请参见
IsPlatformObjectSameOrigin。
以下类型的代理存在于 Web 平台上:
包含各种 Window
对象,这些对象可以直接或通过使用 document.domain
彼此到达。
如果包含的 代理集群 的 是按来源键控的 为
true,则所有 Window
对象将是 同源,可以直接彼此到达,并且
document.domain
将无操作。
两个 Window
对象即使是 同源,也可以位于不同的
相似来源窗口代理
中,例如,如果它们各自在自己的
浏览上下文组 中。
包含单个 SharedWorkerGlobalScope
。
包含单个 ServiceWorkerGlobalScope
。
包含单个 WorkletGlobalScope
对象。
虽然给定的 worklet 可以有多个 realm,但每个 realm 需要自己的代理,因为每个 realm 可以独立执行代码,并且与其他 realm 同时执行。
只有 共享
和
专用worker代理 允许使用 JavaScript Atomics
API 进行潜在的 阻塞。
要创建一个代理,给定一个布尔值 canBlock:
让 signifier 成为一个新的唯一内部值。
让 candidateExecution 成为一个新的 候选执行。
让 agent 成为一个新的 代理,其 [[CanBlock]] 为 canBlock,[[Signifier]] 为 signifier,[[CandidateExecution]] 为 candidateExecution,并且 [[IsLockFree1]]、[[IsLockFree2]] 和 [[LittleEndian]] 设置为实现的自行决定。
返回 agent。
对于一个 realm realm,[[Signifier]] 为 realm.[[AgentSignifier]] 的 代理 是该 realm 的代理。
相关代理 对于一个 平台对象 platformObject 是 platformObject 的 相关 realm 的 代理。
JavaScript 还定义了 代理集群 的概念,本标准通过在使用 获取相似来源窗口代理 或 获取worker/worklet 代理 算法创建代理时适当地放置它们,将其映射到 Web 平台。
代理集群 概念对于定义 JavaScript
内存模型至关重要,尤其是在哪些 代理 之间可以共享 SharedArrayBuffer
对象的支持数据。
从概念上讲,代理集群 概念是将多个 "线程"(代理)分组在一起的架构无关的理想化 "进程边界"。规范定义的代理集群 通常比用户代理实现的实际进程边界更严格。通过在规范层面上执行这些理想化的划分,我们确保了 Web 开发者在共享内存方面看到的行为具有可互操作性,即使面对不同和变化的用户代理进程模型。
代理集群 关联有一个 跨源隔离模式,这是一个 跨源隔离模式。它最初是 "无
"。
代理集群 关联有一个 按来源键控(布尔值),最初为 false。
代理集群键 是一个 站点 或 元组来源。如果没有 Web 开发者操作来实现 按来源键控的代理集群,它将是一个 站点。
一个等效的表述是 代理集群键 可以是 方案和主机 或 来源。
要 获取相似来源窗口代理,给定一个 来源 origin,一个 浏览上下文组 group 和一个布尔值 requestsOAC,运行以下步骤:
让 site 成为 获取站点 结果,带有 origin。
将 key 设置为 site。
否则,如果 group 的 历史代理集群键映射[origin] 存在,则将 key 设置为 group 的 历史代理集群键映射[origin]。
否则:
如果 requestsOAC 为 true,则将 key 设置为 origin。
将 group 的 历史代理集群键映射[origin] 设置为 key。
这意味着每个浏览上下文代理集群中只有一个 相似来源窗口代理。(然而,专用worker 和 worklet 代理 可能在同一个集群中。)
以下定义了所有其他类型代理的 代理集群 的分配。
要 获取worker/worklet 代理,给定一个 环境设置对象 或 null outside settings,一个布尔值 isTopLevel 和一个布尔值 canBlock,运行以下步骤:
让 agentCluster 为 null。
如果 isTopLevel 为 true,则:
将 agentCluster 设置为一个新的 代理集群。
将 agentCluster 的 按来源键控 设置为 true。
这些worker可以被认为是按来源键控的。然而,这并不通过任何 API 暴露(就像 originAgentCluster
对于窗口暴露来源键控性一样)。
否则:
让 agent 成为 创建代理 的结果,给定 canBlock。
将 agent 添加到 agentCluster。
返回 agent。
要 获取专用/共享worker代理,给定一个 环境设置对象 outside settings 和一个布尔值 isShared,返回 获取worker/worklet 代理 的结果,给定 outside settings、isShared 和 true。
要 获取 worklet 代理,给定一个 环境设置对象 outside settings,返回 获取worker/worklet 代理 的结果,给定 outside settings、false 和 false。
要 获取服务worker代理,返回 获取worker/worklet 代理 的结果,给定 null、true 和 false。
JavaScript 规范引入了 域 概念,表示运行脚本的全局环境。每个域都带有一个 实现定义的 全局对象;本规范的大部分内容致力于定义该全局对象及其属性。
对于 Web 规范,通常将值或算法与域/全局对象对关联是有用的。当值特定于某种类型的域时,它们直接与相关的全局对象关联,例如在 Window
或 WorkerGlobalScope
接口的定义中。当值在多个域中具有实用性时,我们使用 环境设置对象 概念。
最后,在某些情况下,需要在域/全局对象/环境设置对象出现之前跟踪相关值(例如,在 导航 期间)。这些值在 环境 概念中跟踪。
环境 是一个对象,用于标识当前或潜在执行环境的设置(即 导航参数 的 保留环境 或 请求 的 保留客户端)。环境 具有以下字段:
唯一标识此 环境 的不透明字符串。
在 Window
环境设置对象 的情况下,由于 history.pushState()
等机制,该 URL 可能与其 全局对象 的 关联的
Document
的 URL 不同。
为 null 或 URL,表示“顶层” 环境 的 创建 URL。对于worker和 worklet 来说,它为 null。
目前是 实现定义 的值、null,或 源。对于“顶层”潜在执行环境,它为 null(即当尚无响应时);否则,它是“顶层”环境 的 源。对于专用worker或 worklet,它是其创建者的 顶层源。对于共享或服务worker,它是一个 实现定义 的值。
为 null 或导航请求的目标 浏览上下文。
一个标志,指示环境设置是否完成。它最初未设置。
规范可以为环境定义 环境丢弃步骤。这些步骤以 环境 作为输入。
环境丢弃步骤 仅针对少数环境运行:这些环境将永远不会变为执行就绪状态,因为它们例如未能加载。
环境设置对象 是一个 环境,另外指定了以下算法:
所有使用该设置对象的 JavaScript 执行上下文 共享的执行上下文,即给定 脚本 的所有脚本。当我们 运行经典脚本 或 运行模块脚本 时,此执行上下文将成为 JavaScript 执行上下文堆栈 的顶部,在其上推入另一个特定于相关脚本的执行上下文。(此设置确保 Source Text Module Record 的 Evaluate 知道使用哪个域。)
导入 JavaScript 模块时使用的 模块映射。
在安全检查中使用的 源。
包含用于安全检查策略的 策略容器。
表示使用此 环境设置对象 的脚本是否被允许使用需要跨源隔离的 API 的布尔值。
环境设置对象 的 负责的事件循环 是其 全局对象 的 相关代理 的 事件循环。
全局对象 是一个 JavaScript 对象,是 域 的 [[GlobalObject]] 字段。
在本规范中,所有 域 都通过创建 全局对象,这些对象要么是 Window
、WorkerGlobalScope
,要么是
WorkletGlobalScope
对象。
一个全局对象有一个布尔值 错误报告模式,其初始值为 false。
一个全局对象有一个未处理拒绝的 promises 弱引用集合,这是一个
集合,包含 Promise
对象,初始为空。此集合不得创建其成员的强引用,且实现可以通过实现定义的方式自由地限制其大小,例如在添加新条目时删除旧条目。
一个全局对象有一个即将通知的拒绝 promises 列表,这是一个
列表,包含 Promise
对象,初始为空。
在领域、全局对象和环境设置对象之间始终存在1对1对1的映射关系:
在 创建一个新域 时,在 代理 agent 中,选择性地创建全局对象或全局 this 绑定(或两者),采取以下步骤:
执行 InitializeHostDefinedRealm(),提供创建全局对象和全局 this 绑定的自定义。
让 realm execution context 成为 正在运行的 JavaScript 执行上下文。
这是在上一步中创建的 JavaScript 执行上下文。
从 JavaScript 执行上下文堆栈 中移除 realm execution context。
让 realm 成为 realm execution context 的 Realm 组件。
如果 agent 的 代理集群 的 跨源隔离模式 为 "none
",则:
这是为了兼容 web 内容,未来希望可以去除。Web 开发者仍然可以通过
new WebAssembly.Memory({ shared:true, initial:0, maximum:0 }).buffer.constructor
获取构造函数。
返回 realm execution context。
在整个规范中定义算法步骤时,通常需要指出要使用哪个realm——或者等价地,使用哪个全局对象或 环境设置对象。一般来说,至少有四种可能性:
注意 入口、现任 和 当前 概念是可无条件使用的,而 相关 概念必须应用于特定的 平台对象。
现任 和 入口 概念不应被新规范使用,因为它们过于复杂且不直观。我们正在努力从平台中删除几乎所有现有用法:有关 现任 的 问题 #1430,有关 入口 的 问题 #1431。
一般来说,Web 平台规范应该使用应用于操作对象的 相关 概念(通常是当前方法的 this 值)。这与
JavaScript 规范不一致,在 JavaScript 规范中,通常使用 当前 作为默认值(例如,在确定 域 的 Array
构造函数应在 Array.prototype.map
中用于构造结果时)。但这种不一致在平台中已经根深蒂固,我们必须接受它。
考虑以下页面,其中 a.html
加载在浏览器窗口中,b.html
加载在 iframe
中,如图所示,c.html
和 d.html
省略(它们可以只是空文档):
<!-- a.html -->
<!DOCTYPE html>
< html lang = "en" >
< title > Entry page</ title >
< iframe src = "b.html" ></ iframe >
< button onclick = "frames[0].hello()" > Hello</ button >
<!--b.html -->
<!DOCTYPE html>
< html lang = "en" >
< title > Incumbent page</ title >
< iframe src = "c.html" id = "c" ></ iframe >
< iframe src = "d.html" id = "d" ></ iframe >
< script >
const c = document. querySelector( "#c" ). contentWindow;
const d = document. querySelector( "#d" ). contentWindow;
window. hello = () => {
c. print. call( d);
};
</ script >
每个页面都有其自己的浏览上下文,因此也有其自己的realm、 全局对象 和 环境设置对象。
当响应按下print()
方法的按钮时:
之所以 相关概念通常比当前概念更适合作为默认选择的一个原因是,它更适合创建一个要多次持久化和返回的对象。例如,navigator.getBattery()
方法在调用它的 相关域中创建 Promise 对象。这会产生以下影响:[BATTERY]
<!-- outer.html -->
<!DOCTYPE html>
< html lang = "en" >
< title > Relevant realm demo: outer page</ title >
< script >
function doTest() {
const promise = navigator. getBattery. call( frames[ 0 ]. navigator);
console. log( promise instanceof Promise); // logs false
console. log( promise instanceof frames[ 0 ]. Promise); // logs true
frames[ 0 ]. hello();
}
</ script >
< iframe src = "inner.html" onload = "doTest()" ></ iframe >
<!-- inner.html -->
<!DOCTYPE html>
< html lang = "en" >
< title > Relevant realm demo: inner page</ title >
< script >
function hello() {
const promise = navigator. getBattery();
console. log( promise instanceof Promise); // logs true
console. log( promise instanceof parent. Promise); // logs false
}
</ script >
如果 getBattery()
方法的算法改用 当前域,那么所有结果都会相反。也就是说,在
outer.html
中第一次调用 getBattery()
之后,inner.html
中的 Navigator
对象将永久存储一个在 outer.html
的 域中创建的 Promise
对象,并且像在
hello()
函数内部的调用将返回来自“错误”域的 promise。由于这是不理想的,因此算法使用 相关域,从而给出上述评论中所指出的合理结果。
调用脚本的过程将把域执行上下文推入或弹出到JavaScript执行上下文堆栈中,与其他执行上下文交错在一起。
有了这个定义,我们将入口执行上下文定义为最近推入的JavaScript执行上下文堆栈中是域执行上下文的项。入口域是入口执行上下文的域组件。
所有JavaScript执行上下文必须包含其代码评估状态的一部分,即跳过确定现任计数器值,初始值为零。在准备运行回调和清理运行回调后的状态过程中,该值将增加和减少。
每个事件循环都有一个关联的备用现任设置对象堆栈,初始为空。大致来说,它用于在堆栈上没有作者代码,但作者代码负责以某种方式运行当前算法时确定现任设置对象。准备运行回调和清理运行回调后的状态过程会操纵此堆栈。[WEBIDL]
当使用Web IDL调用作者代码,或当HostEnqueuePromiseJob调用一个promise任务时,它们使用以下算法来跟踪确定现任设置对象的相关数据:
要准备运行回调,使用环境设置对象settings:
将settings推入备用现任设置对象堆栈。
让context成为最上层的脚本执行上下文。
如果context不是null,则增加context的跳过确定现任计数器。
要清理运行回调后的状态,使用环境设置对象settings:
让context成为最上层的脚本执行上下文。
这将与准备运行回调中相应调用的最上层的脚本执行上下文相同。
如果context不是null,则减少context的跳过确定现任计数器。
断言:备用现任设置对象堆栈的最顶层条目是settings。
从备用现任设置对象堆栈中删除settings。
这里,最上层的脚本执行上下文 是JavaScript执行上下文堆栈中具有非null的ScriptOrModule组件的最顶层条目,如果JavaScript执行上下文堆栈中没有这样的条目,则为null。
有了这一切,现任设置对象被确定如下:
让context成为最上层的脚本执行上下文。
如果context是null,或者如果context的跳过确定现任计数器大于零,则:
断言:备用现任设置对象堆栈不是空的。
如果尝试从既不是调用脚本也不是Web IDL调用回调触发的算法中获取现任设置对象,此断言将失败。例如,如果尝试在事件循环中定期运行的算法中获取现任设置对象,而没有作者代码的参与,则会触发此断言。在这种情况下,无法使用现任概念。
返回备用现任设置对象堆栈的最顶层条目。
返回context的域组件的设置对象。
以下一系列示例旨在明确所有不同机制如何共同定义现任概念:
考虑以下初始示例:
<!DOCTYPE html>
< iframe ></ iframe >
< script >
frames[ 0 ]. postMessage( "some data" , "*" );
</ script >
这里有两个有趣的环境设置对象:window
的和frames[0]
的。我们的关注点是:现任设置对象在postMessage()
算法执行时是什么?
它应该是window
的,捕捉到负责使算法发生的作者脚本在window
中执行,而不是在frames[0]
中。这是有道理的:窗口消息步骤使用现任设置对象来确定生成的source
属性,而在这种情况下,window
显然是消息的来源。
现在让我们解释一下上述步骤如何给我们直观期望的window
的相关设置对象。
当窗口消息步骤查找现任设置对象时,最上层的脚本执行上下文将是对应的script
元素:它在算法运行经典脚本过程中,作为ScriptEvaluation的一部分被推入JavaScript执行上下文堆栈。由于没有涉及Web IDL回调调用,context的跳过确定现任计数器为零,因此用于确定现任设置对象;结果是window
的环境设置对象。
(注意,frames[0]
的环境设置对象是相关设置对象,在调用postMessage()
方法时起作用,因此涉及确定消息的目标。而现任用于确定来源。)
考虑以下更复杂的示例:
<!DOCTYPE html>
< iframe ></ iframe >
< script >
const bound = frames[ 0 ]. postMessage. bind( frames[ 0 ], "some data" , "*" );
window. setTimeout( bound);
</ script >
这个例子与前一个非常相似,但通过Function.prototype.bind
和setTimeout()
增加了额外的间接调用。但是,答案应该是相同的:异步调用算法不应改变现任概念。
这次,结果涉及更复杂的机制:
当bound
被转换为Web IDL回调类型时,现任设置对象对应于window
(与上面的初始示例相同)。Web IDL将其存储为生成的回调值的回调上下文。
当setTimeout()
发布的任务执行时,该任务的算法使用Web IDL调用存储的回调值。Web IDL依次调用上述准备运行回调算法。这会将存储的回调上下文推入备用现任设置对象堆栈。此时(在计时器任务内)堆栈上没有作者代码,因此最上层的脚本执行上下文为空,没有增加跳过确定现任计数器。
调用回调然后调用bound
,它依次调用postMessage()
方法的frames[0]
。当postMessage()
算法查找现任设置对象时,堆栈上仍然没有作者代码,因为绑定函数只是直接调用内置方法。因此,最上层的脚本执行上下文将为空:JavaScript执行上下文堆栈只包含与postMessage()
对应的执行上下文,下面没有ScriptEvaluation上下文或类似的内容。
这是我们退回到备用现任设置对象堆栈的地方。如上所述,它将包含最顶层条目,window
的相关设置对象。因此,在执行postMessage()
算法时,将其用作现任设置对象。
考虑这个最终的,更加复杂的示例:
<!-- a.html -->
<!DOCTYPE html>
< button > click me</ button >
< iframe ></ iframe >
< script >
const bound = frames[ 0 ]. location. assign. bind( frames[ 0 ]. location, "https://example.com/" );
document. querySelector( "button" ). addEventListener( "click" , bound);
</ script >
<!-- b.html -->
<!DOCTYPE html>
< iframe src = "a.html" ></ iframe >
< script >
const iframe = document. querySelector( "iframe" );
iframe. onload = function onLoad() {
iframe. contentWindow. document. querySelector( "button" ). click();
};
</ script >
这里又有两个有趣的环境设置对象:a.html
的和b.html
的。当location.assign()
方法触发Location
对象导航算法时,现任设置对象是什么?如前所述,直观上应该是a.html
的:点击
监听器最初是由a.html
调度的,所以即使涉及b.html
的某些东西导致监听器触发,负责的现任还是a.html
的。
回调设置与前一个示例类似:当bound
被转换为Web IDL回调类型时,现任设置对象对应于a.html
,存储为回调的回调上下文。
当click()
方法在b.html
内调用时,它会在分发事件到a.html
内的按钮上。这一次,当准备运行回调算法作为事件分发的一部分执行时,堆栈上有作者代码;最上层的脚本执行上下文是onLoad
函数,它的跳过确定现任计数器会增加。此外,a.html
的环境设置对象(存储为事件处理程序
的回调上下文)被推入备用现任设置对象堆栈。
现在,当Location
对象导航算法查找现任设置对象时,最上层的脚本执行上下文仍然是onLoad
函数的上下文(因为我们使用绑定函数作为回调)。然而,它的跳过确定现任计数器值为一,因此我们退回到备用现任设置对象堆栈。这给了我们a.html
的环境设置对象,如预期。
注意,这意味着即使是iframe
内的a.html
在导航,a.html
本身仍然被用作源文档
,这决定了包括请求客户端在内的许多事项。这
可能是现任概念在网络平台上唯一合理的使用;在所有其他情况下,使用它的后果只是令人困惑,我们希望有一天能将其切换为使用当前或相关概念。
JavaScript规范定义了当前域,也称为"当前Realm记录"。[JAVASCRIPT]
相关域对于平台对象是其[[Realm]]字段的值。
启用脚本是指对于环境设置对象settings,当以下所有条件为真时:
窗口
对象,要么settings的全局对象的关联Document
的活动沙盒标志集未设置其沙盒脚本浏览上下文标志。
禁用脚本是指对于环境设置对象,当脚本未对其启用,即上述任何条件为假时。
启用脚本是指对于节点node,如果node的节点文档的浏览上下文非空,并且脚本已启用,对于node的相关设置对象。
禁用脚本是指当脚本未启用时,即当其节点文档的浏览上下文为空或当脚本已禁用时,对于其相关设置对象。
如果以下算法返回true,则环境environment是一个安全上下文:
如果environment是一个环境设置对象,那么:
令global为environment的全局对象。
如果global是WorkerGlobalScope
,那么:
如果global是WorkletGlobalScope
,则返回true。
Worklet只能在安全上下文中创建。
如果environment的顶级创建URL的URL是否可能可信的结果是"Potentially Trustworthy
",则返回true。
返回false。
脚本是两种可能的结构之一(即经典脚本或模块脚本)。所有脚本都具有以下属性:
以下之一:
一个源文本模块记录,用于JavaScript 模块脚本;
空值,表示解析失败。
一个 JavaScript 值,仅当记录为 null 时才有意义,表示相应的脚本源代码无法解析。
一个表示阻止评估成功的错误的 JavaScript 值。任何运行脚本的尝试都会重新抛出该错误。
这可能是脚本的解析错误,但对于模块脚本,它可能是其依赖项之一的解析错误,或解析模块说明符时产生的错误。
由于此异常值是由 JavaScript 规范提供的,我们知道它永远不会为 null,因此我们使用 null 表示没有发生错误。
空值或用于解析模块说明符的基本URL。当非空时,对于外部脚本,这将是脚本获取的 URL,对于内联脚本,则是包含文档的文档基本 URL。
一个布尔值,如果为 true,则表示不会提供此脚本中的错误信息。这用于静默跨域脚本的错误,因为这可能会泄露私人信息。
模块脚本可以分为四种类型:
如果其记录是源文本模块记录,则模块脚本是JavaScript 模块脚本。
如果其记录是合成模块记录,且通过创建 CSS 模块脚本算法创建,则模块脚本是CSS 模块脚本。CSS 模块脚本表示一个已解析的 CSS 样式表。
如果其记录是合成模块记录,且通过创建 JSON 模块脚本算法创建,则模块脚本是JSON 模块脚本。JSON 模块脚本表示一个已解析的 JSON 文档。
由于 CSS 样式表和 JSON 文档不会导入依赖模块,并且在评估时不会抛出异常,因此获取选项和基本 URL对于CSS 模块脚本和JSON 模块脚本始终为 null。
活动脚本由以下算法确定:
让record为GetActiveScriptOrModule()。
如果record为 null,则返回 null。
返回record.[[HostDefined]]。
活动脚本概念目前仅用于import()
功能,以确定用于解析相对模块说明符的基本 URL。
本节介绍了用于获取脚本的多个算法,接收各种必要的输入,并生成经典脚本或模块脚本。
用于初始获取和获取任何导入模块的加密 nonce 元数据
用于初始获取的完整性元数据
用于初始获取和获取任何导入模块的解析器元数据
用于初始获取和获取任何导入模块的引用者政策
用于初始获取和获取任何导入模块的渲染阻塞布尔值,除非另有说明,否则其值为 false
用于初始获取的优先级
请记住,通过import()
功能,经典脚本可以导入模块脚本。
默认脚本获取选项是一个脚本获取选项,其加密 nonce为空字符串,完整性元数据为空字符串,解析器元数据为"not-parser-inserted
",凭据模式为"same-origin
",引用者政策为空字符串,获取优先级为"auto
"。
给定一个请求request和一个脚本获取选项options,我们定义:
将request的加密 nonce 元数据设置为options的加密 nonce,其完整性元数据设置为options的完整性元数据,其解析器元数据设置为options的解析器元数据,其引用者政策设置为options的引用者政策,其渲染阻塞设置为options的渲染阻塞,其优先级设置为options的获取优先级。
将request的加密 nonce 元数据设置为options的加密 nonce,其完整性元数据设置为options的完整性元数据,其解析器元数据设置为options的解析器元数据,其凭据模式设置为options的凭据模式,其引用者政策设置为options的引用者政策,其渲染阻塞设置为options的渲染阻塞,其优先级设置为options的获取优先级。
给定脚本获取选项originalOptions、URLurl和环境设置对象settingsObject,获取后代脚本获取选项:
让newOptions成为originalOptions的副本。
让integrity为空字符串。
如果settingsObject的全局对象是Window
对象,则将integrity设置为通过url和settingsObject解析模块完整性元数据的结果。
将newOptions的完整性元数据设置为integrity。
将newOptions的获取优先级设置为"auto
"。
返回newOptions。
给定URLurl和环境设置对象settingsObject,解析模块完整性元数据:
以下算法中的多个可以通过 执行获取
钩子 算法进行自定义,该算法接收一个 请求、一个布尔值 isTopLevel
和一个
processCustomFetchResponse
算法。它会使用 processCustomFetchResponse 运行,并提供一个 响应 和一个空值(失败时)或一个 字节序列,该字节序列包含响应体。isTopLevel 对于所有
经典脚本 的获取为 true,并且对于初始获取 获取外部模块脚本图 或 获取模块工作线程脚本图 时为
true,但对于通过 import
语句在整个图中遇到的获取或 import()
表达式的获取为 false。
默认情况下,不提供 执行获取 钩子 将导致以下算法简单地 获取 给定的 请求,并对 请求 和结果的 响应 进行特定算法的自定义。
要在这些特定算法的自定义之上层叠您自己的自定义,提供一个 执行获取 钩子,该钩子会修改给定的 请求,获取 它,然后对结果的 响应 进行特定验证(如果验证失败,则以 网络错误 结束)。
该钩子还可以用于执行更微妙的自定义,例如保持 响应 的缓存,并避免完全执行 获取。
Service Workers 是一个示例,它使用自己选项的钩子运行这些算法。 [SW]
现在是算法本身。
要 获取经典脚本,给定一个 URL url、一个 环境设置 对象 settingsObject、一个 脚本获取选项 options、一个 CORS 设置属性状态 corsSetting、一个 编码 encoding, 以及一个算法 onComplete,执行以下步骤。onComplete 必须是一个算法, 接受 null(失败时)或一个 经典脚本 (成功时)。
让 request 成为 创建潜在 CORS 请求 的结果,
给定 url、"script
" 和 corsSetting。
将 request 的 客户端 设置为 settingsObject。
将 request 的 发起者类型
设置为 "script
"。
设置经典脚本请求,给定 request 和 options。
获取 request,使用以下 processResponseConsumeBody 步骤,给定 响应 response 和 null、失败或一个 字节序列 bodyBytes:
response 可以是 CORS 同源 或 CORS 跨源。这只会影响错误报告的方式。
将 response 设置为 response 的 不安全响应。
如果以下任意条件为真:
则运行 onComplete,给定 null,并中止这些步骤。
由于历史原因,该算法不包括 MIME 类型检查,与本节中的其他脚本获取算法不同。
让 potentialMIMETypeForEncoding 成为 提取 MIME 类型 的结果, 给定 response 的 头部列表。
将 encoding 设置为 传统提取编码 的结果,给定 potentialMIMETypeForEncoding 和 encoding。
这故意忽略了 MIME 类型本质。
让 sourceText 成为 解码 bodyBytes 为 Unicode,使用 encoding 作为回退编码。
如果文件包含 BOM,解码 算法会覆盖 encoding。
如果 response 是 CORS 跨源,则让 mutedErrors 为 true,否则为 false。
让 script 成为 创建经典脚本 的结果,给定 sourceText、settingsObject、response 的 URL、 options、 mutedErrors 和 url。
获取经典的工作脚本
给定一个 URL url,一个 环境设置对象 fetchClient,一个 目标 destination,一个 环境设置对象 settingsObject,一个算法 onComplete,以及一个可选的 执行抓取钩子 performFetch,执行以下步骤。onComplete 必须是一个 算法,接受 null(失败时)或一个 经典脚本(成功时)。
令 request 为一个新的 请求,其 URL 为 url,客户端 为
fetchClient,目标 为
destination,发起者类型
为 "other
",
模式 为 "same-origin
",凭据模式 为 "same-origin
",
解析器元数据 为 "not parser-inserted
",并且其
使用 URL 凭据标志 被设置。
如果提供了 performFetch,则使用 request、true 和 processResponseConsumeBody(如下所定义)运行 performFetch。
否则,抓取 request,将 processResponseConsumeBody 设置为 processResponseConsumeBody(如下所定义)。
在这两种情况下,给定 响应 response 和 null、失败或一个 字节序列 bodyBytes,processResponseConsumeBody 为以下算法:
将 response 设置为 response 的 不安全响应。
如果下列任何条件为真:
那么运行 onComplete,给定 null,并中止这些步骤。
如果下列所有条件为真:
response 的 URL 的 方案 是一个 HTTP(S) 方案;并且
从 response 的 头部列表 中提取的 MIME 类型 不是一个 JavaScript MIME 类型,
那么运行 onComplete,给定 null,并中止这些步骤。
出于历史原因,其他 抓取方案 被免除 MIME 类型检查,以便与历史网页兼容。我们可能会在未来收紧这一点;见 问题 #3255。
令 sourceText 为 UTF-8 解码 bodyBytes 的结果。
令 script 为使用 sourceText、settingsObject、response 的 URL 和 默认脚本抓取选项 创建经典脚本的结果。
运行 onComplete,给定 script。
要 获取经典的工作脚本,给定一个 URL url,一个 环境设置对象 settingsObject,以及一个 可选的 执行 抓取钩子 performFetch,执行以下步骤。该算法在成功时返回一个 经典脚本,在失败时抛出一个异常。
将 response 设置为 null。
将 bodyBytes 设置为 null。
将 request 设置为一个新的 请求,其 URL 为 url,客户端 为
settingsObject,目标 为
"script
",发起者类型
为 "other
",解析器元数据
为 "not parser-inserted
",并且其 使用 URL 凭据标志
被设置。
如果提供了 performFetch,则使用 request、isTopLevel 和 processResponseConsumeBody(如下所定义)运行 performFetch。
否则,抓取 request,将 processResponseConsumeBody 设置为 processResponseConsumeBody(如下所定义)。
在这两种情况下,给定 响应 res 和 null、失败或一个 字节序列 bb,processResponseConsumeBody 为以下算法:
将 bodyBytes 设置为 bb。
将 response 设置为 res。
暂停,直到 response 不为 null。
与本节中的其他算法不同,这里的抓取过程是同步的。
将 response 设置为 response 的 不安全响应。
如果下列任何条件为真:
bodyBytes 为 null 或失败;
从 response 的 头部列表 中提取的 MIME 类型 不是一个 JavaScript MIME 类型,
则抛出一个 "NetworkError
" DOMException
。
令 sourceText 为 UTF-8 解码 bodyBytes 的结果。
令 mutedErrors 如果 response 为 CORS 跨源,则为 true,否则为 false。
令 script 为使用 sourceText、settingsObject、response 的 URL 和 默认脚本抓取选项、以及 mutedErrors 创建经典脚本的结果。
返回 script。
要 获取外部模块脚本图 给定一个 URL url,一个 环境设置对象 settingsObject,一个 脚本 获取选项 options,以及一个算法 onComplete,运行以下步骤。 onComplete 必须是一个算法, 接受 null(失败时)或一个 模块脚本 (成功时)。
禁止进一步的导入映射,给定 settingsObject。
获取单个模块脚本,给定 url,settingsObject,
"script
",options,settingsObject,"client
",true,以及
以下步骤给定 result:
如果 result 为 null,运行 onComplete,给定 null,并中止这些步骤。
获取并链接模块脚本的后代,
给定 result,settingsObject,"script
" 和
onComplete。
要 获取模块预加载模块脚本图,给定一个 URL url, 一个 目的地 destination,一个 环境设置对象 settingsObject,一个 脚本获取选项 options,以及一个算法 onComplete,运行以下步骤。 onComplete 必须是一个算法,接受 null(失败时)或一个 模块脚本(成功时)。
禁止进一步的导入映射,给定 settingsObject。
获取单个模块脚本,给定 url,settingsObject,
destination,options,settingsObject,"client
",true,以及
以下步骤给定 result:
运行 onComplete,给定 result。
如果 result 不为 null,可选地 获取并链接模块脚本的后代, 给定 result,settingsObject,destination 和一个空算法。
通常,这一步将有助于性能,因为它允许预加载将来必然会请求的模块,通过如 获取外部模块脚本图 的算法,该算法获取整个图。然而,用户代理可能希望在带宽受限的情况下,或相关的获取已经在进行中的情况下跳过它们。
要 获取内联模块脚本图,给定一个 字符串 sourceText,一个 URL baseURL,一个 环境设置对象 settingsObject,一个 脚本获取选项 options, 和一个算法 onComplete,运行以下步骤。 onComplete 必须是一个 算法,接受 null(失败时)或一个 模块脚本(成功时)。
禁止进一步的导入映射,给定 settingsObject。
让 script 为 创建 JavaScript 模块脚本 的结果, 使用 sourceText,settingsObject,baseURL 和 options。
获取并链接模块脚本的后代,
给定 script,settingsObject,"script
" 和
onComplete。
要 获取模块工作线程脚本图 给定一个 URL url,一个 环境设置对象 fetchClient,一个 目的地 destination,一个 凭据模式 credentialsMode,一个 环境设置对象 settingsObject,以及一个算法 onComplete,获取工作线程/模块工作线程脚本图,给定 url,fetchClient,destination, credentialsMode,settingsObject 和 onComplete。
要 获取工作线程脚本图,给定一个 URL url,一个 环境设置对象 fetchClient,一个 目的地 destination,一个 凭据模式 credentialsMode,一个 环境设置对象 settingsObject,一个 模块响应映射 moduleResponsesMap,以及一个算法 onComplete,获取工作线程/模块工作线程脚本图,给定 url,fetchClient, destination,credentialsMode,settingsObject, onComplete,以及以下 执行获取挂钩,给定 request 和 processCustomFetchResponse:
让 requestURL 为 request 的 URL。
如果 moduleResponsesMap[requestURL] 为 "fetching
",则 并行等待,直到该条目的值发生变化,
然后在 网络任务源 上 排队一个任务,以继续执行以下步骤。
如果 moduleResponsesMap[requestURL] 存在,则:
让 cached 为 moduleResponsesMap[requestURL]。
使用 cached[0] 和 cached[1] 运行 processCustomFetchResponse。
返回。
设置 moduleResponsesMap[requestURL] 为
"fetching
"。
获取 request,将 processResponseConsumeBody 设置为以下步骤,给定 response response 和 null、失败或一个 字节序列 bodyBytes:
将 moduleResponsesMap[requestURL] 设置为 (response,bodyBytes)。
使用 response 和 bodyBytes 运行 processCustomFetchResponse。
以下算法仅供本规范内部使用,作为 获取外部模块脚本图 或 上述其他类似概念的一部分,不应直接由其他规范使用。
该图示说明了这些算法如何与上述算法以及彼此相关:
要 获取工作线程/模块工作线程脚本图,给定一个 URL url,一个 环境设置对象 fetchClient,一个 目的地 destination,一个 凭据模式 credentialsMode,一个 环境设置对象 settingsObject,一个算法 onComplete,以及一个可选的 执行获取挂钩 performFetch,执行以下步骤。 onComplete 必须是一个接受 null(失败时)或一个 模块脚本(成功时)的算法。
让 options 为一个 脚本获取选项,其
加密随机数
为空字符串,完整性元数据 为空字符串,
解析器元数据 为
"not-parser-inserted
",凭据模式 为
credentialsMode,引用策略 为空字符串,以及 获取优先级 为
"auto
"。
获取单个模块脚本,给定
url,
fetchClient,destination,options,settingsObject,
"client
",true,以及 onSingleFetchComplete 如下定义。如果 performFetch 被给定,也将其传递。
onSingleFetchComplete 给定 result 的算法如下:
如果 result 为 null,则运行 onComplete 给定 null,并中止这些步骤。
获取子孙并链接 result,给定 fetchClient, destination 和 onComplete。如果 performFetch 被给定,也将其传递。
要 获取子孙并链接 一个 模块脚本 moduleScript,给定一个 环境设置对象 fetchClient,一个 目的地 destination,一个算法 onComplete, 以及一个可选的 执行获取挂钩 performFetch,执行以下步骤。 onComplete 必须是一个接受 null(失败时)或一个 模块脚本(成功时)的算法。
让 record 为 moduleScript 的 记录。
如果 record 为 null,则:
让 state 为 记录 { [[ParseError]]: null, [[Destination]]: destination, [[PerformFetch]]: null, [[FetchClient]]: fetchClient }。
如果给定了 performFetch,将 state.[[PerformFetch]] 设置为 performFetch。
让 loadingPromise 为 record.LoadRequestedModules(state).
此步骤将递归加载所有模块的传递依赖项。
在 loadingPromise 完成时,执行以下步骤:
在 loadingPromise 被拒绝时,执行以下步骤:
如果 state.[[ParseError]] 不为 null,将 moduleScript 的 错误重抛 设置为 state.[[ParseError]] 并执行 onComplete,给定 moduleScript。
否则,执行 onComplete,给定 null。
state.[[ParseError]] 为 null 表示 loadingPromise 因加载错误而被拒绝。
要 获取单个模块脚本,给定一个 URL url,一个 环境设置对象 fetchClient,一个 目的地 destination,一个 脚本获取选项 options, 一个 环境设置对象 settingsObject,一个 引用 referrer,一个可选的 模块请求记录 moduleRequest,一个布尔值 isTopLevel,一个算法 onComplete,以及一个可选的 执行获取挂钩 performFetch,执行以下步骤。 onComplete 必须是一个接受 null(失败时)或一个 模块脚本(成功时)的算法。
让 moduleType 为 "javascript-or-wasm
"。
如果给定了 moduleRequest,则将 moduleType 设置为运行 模块请求中的模块类型 步骤的结果,给定 moduleRequest。
断言:运行 模块类型允许 步骤的结果,给定 moduleType 和 settingsObject,为 true。否则,我们不会到达这一点,因为在检查 moduleRequest.[[Attributes]] 时,失败会在 HostLoadImportedModule 或 获取单个导入的模块脚本 时引发。
让 moduleMap 为 settingsObject 的 模块映射。
如果 moduleMap[(url, moduleType)] 是
"fetching
",则等待 并行
直到该条目的值发生变化,然后 排队一个任务 到 网络任务源
以继续执行以下步骤。
如果 moduleMap[(url, moduleType)] 存在,运行 onComplete 给定 moduleMap[(url, moduleType)], 并返回。
将
moduleMap[(url,
moduleType)] 设置为 "fetching
"。
让 request 为一个新的 请求,其
URL 为 url,模式 为 "cors
",引用
为 referrer,客户端 为
fetchClient。
将 request 的 目的地 设置为 运行 从模块类型获取目的地 步骤的结果, 给定 destination 和 moduleType。
如果 destination 为 "worker
"、"sharedworker
" 或
"serviceworker
",并且
isTopLevel 为 true,则将 request 的 模式 设置为
"same-origin
"。
将 request 的 发起者类型
设置为 "script
"。
设置模块脚本请求,给定request和options。
如果给定了performFetch,运行performFetch,传递request、isTopLevel,并且按照下文定义的processResponseConsumeBody处理。
否则,fetch request,并将processResponseConsumeBody设置为按照下文定义的processResponseConsumeBody。
在两种情况下,processResponseConsumeBody给定response response和空、失败或字节序列 bodyBytes,执行以下算法:
response总是CORS同源。
如果以下任一情况为真:
那么设置 moduleMap[(url, moduleType)]为null,运行给定null的onComplete,并中止这些步骤。
让moduleScript为null。
让referrerPolicy为从response中解析`Referrer-Policy
`头的结果。[REFERRERPOLICY]
如果referrerPolicy不是空字符串,设置options的引用者策略为referrerPolicy。
如果mimeType的本质为"application/wasm
",并且moduleType为"javascript-or-wasm
",那么设置moduleScript为创建WebAssembly模块脚本的结果,传递bodyBytes、settingsObject、response的URL和options。
否则:
让sourceText为UTF-8解码 bodyBytes的结果。
如果mimeType是JavaScript
MIME类型,并且moduleType是"javascript-or-wasm
",那么设置moduleScript为创建JavaScript模块脚本的结果,传递sourceText、settingsObject、response的URL和options。
如果mimeType的MIME类型本质为"text/css
",并且moduleType为"css
",那么设置moduleScript为创建CSS模块脚本的结果,传递sourceText和settingsObject。
如果mimeType是JSON
MIME类型,并且moduleType是"json
",那么设置moduleScript为创建JSON模块脚本的结果,传递sourceText和settingsObject。
设置 moduleMap[(url, moduleType)]为moduleScript,并运行onComplete,传递moduleScript。
要 获取单个导入的模块脚本,给定一个 URL url,一个 环境设置对象 fetchClient,一个 目的地 destination,一个 脚本获取选项 options,一个 环境设置对象 settingsObject,一个 引用 referrer,一个 模块请求记录 moduleRequest,一个算法 onComplete,以及一个可选的 执行获取挂钩 performFetch,执行以下步骤。 onComplete 必须是一个接受 null(失败时)或一个 模块脚本(成功时)的算法。
断言:moduleRequest.[[Attributes]] 不包含任何 记录
entry,使得 entry.[[Key]] 不是 "type
",因为我们在 HostGetSupportedImportAttributes 中只要求了
"type
" 属性。
让 moduleType 为运行 模块请求中的模块类型 步骤的结果,给定 moduleRequest。
如果运行 模块类型允许 步骤的结果,给定 moduleType 和 settingsObject 为 false,则运行 onComplete 给定 null,并返回。
获取单个模块脚本,给定 url、fetchClient、destination、options、settingsObject、referrer、moduleRequest、false 和 onComplete。如果给定了 performFetch,也一并传递。
要创建经典脚本,给定一个字符串source,一个环境设置对象settings,一个URLbaseURL,一个脚本抓取选项options,一个可选的布尔值mutedErrors(默认为false),以及一个可选的URL-或-nullsourceURLForWindowScripts(默认为null):
如果mutedErrors为true,则将baseURL设置为about:blank
。
当mutedErrors为true时,baseURL是脚本的CORS跨域响应的URL,它不应暴露给JavaScript。因此,baseURL在此处进行了清理。
如果禁用了脚本对于settings,则将source设置为空字符串。
创建一个新的经典脚本,该算法将随后对其进行初始化。
设置script的设置对象为settings。
设置script的基本URL为baseURL。
设置script的抓取选项为options。
设置script的静默错误为mutedErrors。
记录经典脚本创建时间,给定script和sourceURLForWindowScripts。
让result为ParseScript(source,settings的realm,script)。
这里将script作为最后一个参数传递,确保result.[[HostDefined]]将是script。
如果result是一个错误列表,则:
将script的记录设置为result。
返回script。
从模块请求中获取模块类型的步骤,给定一个ModuleRequest记录moduleRequest,如下所示:
让moduleType为"javascript-or-wasm
"。
如果moduleRequest的[[Attributes]]中有一个记录entry,且entry的[[Key]]是"type
",则:
如果entry的[[Value]]是"javascript-or-wasm
",则将moduleType设置为null。
本规范在内部将"javascript-or-wasm
"模块类型用于JavaScript模块脚本或WebAssembly模块脚本,因此此步骤用于防止使用"javascript-or-wasm
"类型属性导入模块(null的moduleType将导致模块类型允许检查失败)。
否则,将moduleType设置为entry的[[Value]]。
返回moduleType。
模块类型允许的步骤,给定一个字符串moduleType和一个环境设置对象settings,如下所示:
如果moduleType不是"javascript-or-wasm
"、"css
"或"json
",则返回false。
如果moduleType是"css
",且CSSStyleSheet
接口未在settings的realm中暴露,则返回false。
返回true。
从模块类型获取抓取目标的步骤,给定一个目标defaultDestination和一个字符串moduleType,如下所示:
json
",则返回"json
"。css
",则返回"style
"。要运行经典脚本,给定一个经典脚本script,以及一个可选的布尔值rethrow errors(默认为false):
让settings为script的设置对象。
检查我们是否可以运行脚本,使用settings。如果返回"不运行",则返回NormalCompletion(空)。
记录经典脚本执行开始时间,给定script。
准备运行脚本,给定settings。
让evaluationStatus为null。
如果script的待重抛错误不为null,则将evaluationStatus设置为Completion { [[Type]]: throw, [[Value]]: script的待重抛错误, [[Target]]: empty }。
否则,将evaluationStatus设置为ScriptEvaluation(script的记录)。
如果ScriptEvaluation未完成,因为用户代理中止了运行中的脚本,则将evaluationStatus保持为null。
如果evaluationStatus是中止完成,则:
在运行脚本后清理,使用settings。
如果evaluationStatus是正常完成,则返回evaluationStatus。
如果我们到达此步骤,evaluationStatus保持为null,因为脚本在评估过程中被提前中止。返回Completion { [[Type]]: throw, [[Value]]: 一个新的"QuotaExceededError
" DOMException
,
[[Target]]: empty }。
给定一个模块脚本script和一个可选的布尔值preventErrorReporting(默认值为false),以运行一个模块脚本:
让settings成为script的设置对象。
使用settings检查是否可以运行脚本。如果返回“不要运行”,则返回已解决的promise,其值为undefined。
记录模块脚本执行开始时间,给定script。
给定settings,准备运行脚本。
将evaluationPromise设置为null。
如果script的要重新抛出的错误不为null,则将evaluationPromise设置为被拒绝的promise,其值为script的要重新抛出的错误。
否则:
让record成为script的记录。
将evaluationPromise设置为record.Evaluate()。
这一步将递归地评估模块的所有依赖项。
如果由于用户代理中止运行脚本而导致Evaluate无法完成,则将evaluationPromise设置为被拒绝的promise,其值为一个新的“QuotaExceededError
”DOMException
。
如果preventErrorReporting为false,则在evaluationPromise的被拒绝时,将reason传递给报告异常,其中reason来自script的设置对象的全局对象。
使用settings清理运行脚本后的环境。
返回evaluationPromise。
检查是否可以运行脚本的步骤是给定环境设置对象settings,返回“运行”或“不要运行”。
准备运行脚本的步骤如下,给定一个环境设置对象settings:
将settings的域执行上下文压入JavaScript执行上下文栈;它现在是运行的JavaScript执行上下文。
将settings添加到外围代理的事件循环中的当前运行任务的脚本评估环境设置对象集合。
清理运行脚本后的步骤如下,给定一个环境设置对象settings:
断言:settings的域执行上下文是运行的JavaScript执行上下文。
从JavaScript执行上下文栈中移除settings的域执行上下文。
如果JavaScript执行上下文栈现在为空,执行微任务检查点。(如果此操作运行脚本,这些算法将被重新调用。)
这些算法不是由一个脚本直接调用另一个脚本,而是可能以间接方式重新调用,例如,如果一个脚本分派了一个事件并且事件监听器已注册。
运行中的脚本是在[[HostDefined]]字段中,在ScriptOrModule组件中的脚本。
虽然JavaScript规范未考虑这种可能性,但有时有必要终止正在运行的脚本。这将导致任何ScriptEvaluation或源文本模块记录Evaluate的调用立即停止,清空JavaScript执行上下文栈,而不会触发任何常规机制,如finally
块。
[JAVASCRIPT]
用户代理可能会对脚本施加资源限制,例如CPU配额、内存限制、总执行时间限制或带宽限制。当脚本超出限制时,用户代理可能会抛出"QuotaExceededError
"DOMException
,终止脚本,不抛出异常,提示用户或限制脚本执行。
例如,以下脚本永远不会终止。用户代理可能在等待几秒后提示用户终止脚本或让其继续运行。
< script >
while ( true ) { /* loop */ }
</ script >
鼓励用户代理允许用户在被脚本提示时(例如使用window.alert()
API)或由于脚本的行为(例如超出时间限制)时禁用脚本。
如果在脚本执行时禁用脚本,则应立即终止该脚本。
用户代理可能允许用户仅为关闭浏览上下文的目的专门禁用脚本。
例如,上述示例中提到的提示还可以为用户提供一种机制,允许其直接关闭页面,而不运行任何unload
事件处理程序。
在所有当前的引擎中支持。
self.reportError(e)
在全局对象上为给定的值 e 派发一个error
事件,其方式与未处理的异常相同。
从 JavaScript 值 exception 中提取错误信息:
让 attributes 成为由 IDL 属性键控的空映射。
将 attributes[error
]
设置为 exception。
将 attributes[message
],
attributes[filename
],
attributes[lineno
],
和
attributes[colno
]
设置为从 exception 中派生的实现定义的值。
浏览器实现了此处或 JavaScript 规范中未指定的行为,以收集有用的值,包括在不常见的情况下(例如,eval
)。未来,可能会更详细地指定这些行为。
返回 attributes。
为特定的全局对象 global 和可选的布尔值 omitError(默认值为 false),报告异常 exception(它是一个 JavaScript 值):
设 notHandled 为 true。
让 errorInfo 成为从 exception 中提取错误信息的结果。
让 script 成为通过脚本找到的 实现定义的脚本,或为 null。通常应该是正在运行的脚本(尤其是在运行经典脚本期间)。
在不常见的情况下,实现尚未对用于确定错误是否静音的脚本实现互操作行为达成共识。
如果 script 是经典脚本且
script 的静音错误为 true,则将
errorInfo[error
]
设置为 null,将 errorInfo[message
]
设置为 "Script error.
",
将 errorInfo[filename
]
设置为空字符串,
将 errorInfo[lineno
]
设置为 0,
并将 errorInfo[colno
]
设置为 0。
如果 omitError 为 true,则将 errorInfo[error
]
设置为 null。
如果 global 不在错误报告模式中,则:
如果 global 实现了 EventTarget
,
则将 notHandled 设置为触发一个名为 error
的事件的结果,
在 global 上,使用 ErrorEvent
,
并将 cancelable
属性初始化为 true,
并根据 errorInfo 初始化附加属性。
在事件处理程序中返回 true 会根据事件处理程序处理算法取消事件。
将 global 的错误报告模式中 设置为 false。
如果 notHandled 为 true,则:
将 errorInfo[error
]
设置为 null。
如果 global 实现了 DedicatedWorkerGlobalScope
,
则在在
DOM
操作任务源上为 global 关联的 Worker
的相关全局对象排队执行这些步骤:
让 workerObject 成为与 global 关联的 Worker
对象。
将 notHandled 设置为触发一个名为
error
的事件的结果,
在 workerObject 上,使用 ErrorEvent
,
并将 cancelable
属性初始化为 true,
并根据 errorInfo 初始化附加属性。
如果 notHandled 为 true,则为 workerObject 的相关全局对象,将 exception 报告给 omitError 设置为 true。
在所有者领域中实际的 exception 值将不可用,但用户代理仍会携带足够的信息来设置消息、文件名和其他属性,并可能报告给开发人员控制台。
否则,用户代理可以将 exception 报告给开发者控制台。
如果连接 worker 和其 Worker
对象的隐式端口已解除连接(即如果父 worker 已终止),则用户代理必须表现得像该 Worker
对象没有error
事件处理程序,
并且该 worker 的 onerror
属性为 null,但必须按照上述描述的方式行事。
因此,错误报告会向上传播到专用 worker 链的原始 Document
,即使该链上的某些 worker
已被终止和垃圾收集。
该标准的先前版本定义了一个算法来报告异常。作为issue #958 的一部分,该算法已被报告异常所取代,该算法行为不同且采用不同的输入。Issue #10516 追踪了规范生态系统的更新。
reportError(e)
方法步骤是报告异常
e 用于this。
不清楚静音是否适用于此处 。在 Chrome 和 Safari 中,它是静音的,但在 Firefox 中不是。另请参阅issue #958。
在所有当前的引擎中支持。
接口 ErrorEvent
定义如下:
[Exposed=*]
interface ErrorEvent : Event {
constructor (DOMString type , optional ErrorEventInit eventInitDict = {});
readonly attribute DOMString message ;
readonly attribute USVString filename ;
readonly attribute unsigned long lineno ;
readonly attribute unsigned long colno ;
readonly attribute any error ;
};
dictionary ErrorEventInit : EventInit {
DOMString message = "";
USVString filename = "";
unsigned long lineno = 0;
unsigned long colno = 0;
any error ;
};
message
属性必须返回初始化时的值。它表示错误消息。
filename
属性必须返回初始化时的值。它表示错误最初发生的脚本的URL。
lineno
属性必须返回初始化时的值。它表示错误在脚本中发生的行号。
colno
属性必须返回初始化时的值。它表示错误在脚本中发生的列号。
error
属性必须返回初始化时的值。它必须最初被初始化为 undefined。在适当情况下,它被设置为表示错误的对象(例如,在未捕获的异常情况下,设置为异常对象)。
支持所有当前的引擎。
除了同步的运行时脚本错误之外,脚本还可能遇到异步的 Promise 拒绝,这些拒绝通过unhandledrejection
和rejectionhandled
事件进行跟踪。跟踪这些拒绝是通过HostPromiseRejectionTracker抽象操作完成的,但它们的报告方式在这里定义。
要根据全局对象 global,通知关于拒绝的 promises:
将 list 设为 global 的 列表克隆,包含即将通知的拒绝 promises 列表。
如果 list 为空,则返回。
清空 global 的 即将通知的拒绝 promises 列表。
排入一个全局任务到DOM 操作任务源,给定 global,以运行以下步骤:
遍历 list 中的每个 promise p:
如果 p 的 [[PromiseIsHandled]] 为 true,则继续。
将 notCanceled 设为 触发一个事件名为unhandledrejection
,
在
global上,使用 PromiseRejectionEvent
,
其cancelable
属性初始化为 true,promise
属性初始化为
p,以及reason
属性初始化为 p 的 [[PromiseResult]]。
如果 notCanceled 为 true,则用户代理可以将 p 的 [[PromiseResult]] 报告给开发者控制台。
如果 p 的 [[PromiseIsHandled]] 为 false,则将 p 追加到 global 的未处理拒绝的 promises 弱引用集合。
支持所有当前的引擎。
接口PromiseRejectionEvent
定义如下:
[Exposed=*]
interface PromiseRejectionEvent : Event {
constructor (DOMString type , PromiseRejectionEventInit eventInitDict );
readonly attribute object promise ;
readonly attribute any reason ;
};
dictionary PromiseRejectionEventInit : EventInit {
required object promise ;
any reason ;
};
支持所有当前的引擎。
属性promise
必须返回其初始化的值。它表示此通知所涉及的promise。
由于
Promise<T>
类型的Web IDL转换规则总是将输入包装到一个新的promise中,
promise
属性的类型改为object
,
这更适合表示原始promise对象的不透明句柄。
支持所有当前的引擎。
属性reason
必须返回其初始化的值。它表示promise被拒绝的原因。
Import map解析结果是一个类似于结构的脚本,也可以存储在script
元素的结果中,但不计为其他用途的脚本。它具有以下条目:
要创建一个import map解析结果,给定一个字符串input 和一个URLbaseURL:
让result成为一个import map解析结果,其import map为null,待重新抛出的错误为null。
解析import map字符串,给定input和baseURL,捕获任何异常。如果抛出异常,则将result的待重新抛出的错误设置为该异常。否则,将result的import map设置为返回值。
返回result。
要注册一个import map,给定一个Window
global和一个import
map解析结果result:
解析模块说明符算法是将模块说明符字符串转换为URL的主要入口。当不涉及导入映射时,它相对简单,并简化为解析类URL模块说明符。
当存在非空的导入映射时,行为会更加复杂。它会从所有适用的模块说明符映射中检查候选条目,从最具体到最不具体的作用域(回退到顶级未作用域的imports),以及从最具体到最不具体的前缀。对于每个候选条目,解析imports匹配算法将给出以下结果之一:
最终,如果通过任何候选的模块说明符映射没有找到成功的解析,解析模块说明符将抛出异常。因此,结果始终是URL或抛出的异常。
给定一个脚本或null的referringScript和一个字符串 specifier,执行解析模块说明符:
令settingsObject和baseURL为null。
如果referringScript不为null,则:
否则:
令importMap为空导入映射。
如果settingsObject的全局对象实现了Window
,则将importMap设置为settingsObject的全局对象的导入映射。
令baseURLString为baseURL,序列化。
令asURL为解析类URL模块说明符给定specifier和baseURL的结果。
令normalizedSpecifier为asURL的序列化结果,如果asURL不为null;否则为specifier。
对每个 scopePrefix→scopeImports在importMap的作用域中:
如果scopePrefix是baseURLString,或如果scopePrefix以U+002F (/)结尾,并且scopePrefix是baseURLString的代码单元前缀,则:
令scopeImportsMatch为解析imports匹配给定normalizedSpecifier、asURL和scopeImports的结果。
如果scopeImportsMatch不为null,则返回scopeImportsMatch。
令topLevelImportsMatch为解析imports匹配给定normalizedSpecifier、asURL和importMap的imports的结果。
如果topLevelImportsMatch不为null,则返回topLevelImportsMatch。
此时,specifier未被importMap重新映射到任何内容,但它可能已转化为URL。
如果asURL不为null,则返回asURL。
抛出一个TypeError
,表示specifier是一个裸说明符,但未被importMap重新映射到任何内容。
给定一个字符串 normalizedSpecifier、一个URL或null asURL和一个模块说明符映射 specifierMap,执行解析imports匹配:
对每个 specifierKey→resolutionResult在specifierMap中:
如果specifierKey是normalizedSpecifier,则:
如果以下所有条件为真:
那么:
如果resolutionResult为null,则抛出一个TypeError
,表示解析specifierKey被null条目阻止。
这将终止整个解析模块说明符算法,不进行任何进一步的回退。
令afterPrefix为normalizedSpecifier在初始specifierKey前缀之后的部分。
令url为URL解析后的afterPrefix,使用resolutionResult。
如果url失败,则抛出一个TypeError
,表示解析normalizedSpecifier被阻止,因为afterPrefix部分无法相对于映射到的resolutionResult的specifierKey前缀进行URL解析。
这将终止整个解析模块说明符算法,不进行任何进一步的回退。
如果resolutionResult的序列化不是url的代码单元前缀,则抛出一个TypeError
,表示解析normalizedSpecifier被阻止,因为它回溯到了其前缀specifierKey之上。
这将终止整个解析模块说明符算法,不进行任何进一步的回退。
返回url。
返回null。
解析模块说明符算法将回退到更不具体的作用域,或“imports
”,如果可能的话。
给定一个字符串 specifier和一个URL baseURL,执行解析类URL模块说明符:
如果specifier 以“/
”、“./
”或“../
”开头,则:
令url为URL解析后的specifier(无基本URL)。
如果url失败,则返回null。
返回url。
一个import map允许控制模块说明符解析。Import maps通过内联script
元素交付,其type
属性设置为“importmap
”,并且其子文本内容包含import map的JSON表示。
每个文档
仅处理一个import
map。在看到第一个import map后,其它将被忽略,其相应的script
元素将生成错误
事件。同样,一旦导入了任何模块,例如,通过import()
表达式或script
元素,其type
属性设置为“module
”,进一步的import
maps将被忽略。
这些限制,以及不支持外部import maps,是为了使该功能的初始版本简单化。随着实现者带宽的增加,这些限制可能会逐步取消。
import maps最简单的使用是全局重新映射裸模块说明符:
{
"imports" : {
"moment" : "/node_modules/moment/src/moment.js"
}
}
这使得类似import moment from "moment";
的语句能够正常工作,从/node_modules/moment/src/moment.js
URL中获取并评估JavaScript模块。
import map可以通过使用尾随斜杠将一类模块说明符重新映射到一类URL,如下所示:
{
"imports" : {
"moment/" : "/node_modules/moment/src/"
}
}
这使得类似
import localeData from
"moment/locale/zh-cn.js";
的语句能够正常工作,从
/node_modules/moment/src/locale/zh-cn.js
URL中获取并评估JavaScript模块。这样的尾随斜杠映射通常与裸说明符映射结合使用,例如:
{
"imports" : {
"moment" : "/node_modules/moment/src/moment.js" ,
"moment/" : "/node_modules/moment/src/"
}
}
这样,无论是由“moment
”指定的“主模块”,还是由诸如“moment/locale/zh-cn.js
”之类路径指定的“子模块”都可以使用。
裸规范符并不是导入映射可以重新映射的唯一类型的模块规范符。“URL-like”规范符,即那些可以解析为绝对 URL
或以“/
”、“./
”或“../
”开头的规范符,也可以重新映射:
{
"imports" : {
"https://cdn.example.com/vue/dist/vue.runtime.esm.js" : "/node_modules/vue/dist/vue.runtime.esm.js" ,
"/js/app.mjs" : "/js/app-8e0d62a03.mjs" ,
"../helpers/" : "https://cdn.example/helpers/"
}
}
请注意,要重新映射的 URL 以及要映射到的 URL 可以指定为绝对 URL,也可以指定为以“/
”、“./
”或“../
”开头的相对
URL。(不能指定为没有这些起始符号的相对 URL,因为这些符号有助于区分裸模块规范符。)还要注意,尾随斜杠映射在这种情况下也有效。
这种重新映射在规范化后的 URL
上进行,不需要在导入映射键中提供的文字字符串与导入的模块规范符之间匹配。因此,例如,如果此导入映射包含在https://example.com/app.html
中,那么不仅
import "/js/app.mjs"
会被重新映射,import "./js/app.mjs"
和
import "./foo/../js/app.mjs"
也会被重新映射。
所有前面的示例都通过在导入映射中使用顶级的“imports
”键来全局重新映射模块规范符。顶级的“scopes
”键可用于提供本地化的重新映射,这些重新映射仅在引用模块匹配特定
URL 前缀时适用。例如:
{
"scopes" : {
"/a/" : {
"moment" : "/node_modules/moment/src/moment.js"
},
"/b/" : {
"moment" : "https://cdn.example.com/moment/src/moment.js"
}
}
}
有了这个导入映射,import "moment"
语句将会根据包含该语句的引用脚本所在的位置有不同的含义:
在位于/a/
下的脚本中,这将导入/node_modules/moment/src/moment.js
。
在位于/b/
下的脚本中,这将导入https://cdn.example.com/moment/src/moment.js
。
在位于/c/
下的脚本中,这将无法解析,因此会抛出异常。
作用域的一个典型用法是允许在 web 应用中存在多个版本的“相同”模块,其中模块图的一部分导入一个版本,而另一部分导入另一个版本。
作用域可以相互重叠,并且与全局的“imports
”规范符映射重叠。在解析时,作用域会按从最具体到最不具体的顺序进行咨询,其中具体性通过使用代码单元小于操作对作用域进行排序来衡量。因此,例如,“/scope2/scope3/
”被视为比“/scope2/
”更具体,而“/scope2/
”被视为比顶级(无作用域)映射更具体。
以下导入映射说明了这一点:
{
"imports" : {
"a" : "/a-1.mjs" ,
"b" : "/b-1.mjs" ,
"c" : "/c-1.mjs"
},
"scopes" : {
"/scope2/" : {
"a" : "/a-2.mjs"
},
"/scope2/scope3/" : {
"b" : "/b-3.mjs"
}
}
}
这导致了以下解析结果(为简洁起见,使用相对 URL):
Specifier | ||||
---|---|---|---|---|
"a "
|
"b "
|
"c "
|
||
Referrer | /scope1/r.mjs
|
/a-1.mjs
|
/b-1.mjs
|
/c-1.mjs
|
/scope2/r.mjs
|
/a-2.mjs
|
/b-1.mjs
|
/c-1.mjs
|
|
/scope2/scope3/r.mjs
|
/a-2.mjs
|
/b-3.mjs
|
/c-1.mjs
|
导入映射还可以用于为模块提供完整性元数据,以用于Subresource Integrity
检查。[SRI]
以下导入映射对此进行了说明:
{
"imports" : {
"a" : "/a-1.mjs" ,
"b" : "/b-1.mjs" ,
"c" : "/c-1.mjs"
},
"integrity" : {
"/a-1.mjs" : "sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7" ,
"/d-1.mjs" : "sha384-MBO5IDfYaE6c6Aao94oZrIOiC6CGiSN2n4QUbHNPhzk5Xhm0djZLQqTpL0HzTUxk"
}
}
上面的示例为模块/a-1.mjs
和/d-1.mjs
提供了完整性元数据,即使后者没有在映射中定义为导入。
表示导入映射的script
元素的子文本内容必须符合以下导入映射编写要求:
它必须是有效的JSON。[JSON]
该JSON必须表示一个JSON对象,最多可以有三个键"imports
"、"scopes
"和"integrity
"。
如果存在"imports
"、"scopes
"和"integrity
"键,则它们对应的值必须是JSON对象。
如果存在"imports
"键,则其对应的值必须是一个有效的模块说明符映射。
如果存在"scopes
"键,则其对应的值必须是一个JSON对象,其键是有效的URL字符串,其值是有效的模块说明符映射。
如果存在"integrity
"键,则其对应的值必须是一个JSON对象,其键是有效的URL字符串,其值符合完整性属性的要求。
有效的模块说明符映射是一个满足以下要求的JSON对象:
模块说明符映射是一个有序映射,其键为字符串,其值为URL或空值。
模块完整性映射是一个有序映射,其键为URL,其值为将用于完整性元数据的字符串。
空导入映射是一个导入映射,其imports和scopes均为空映射。
每个窗口
都有一个允许导入映射的布尔值,初始为true。
要禁止进一步的导入映射,给定一个环境设置对象settingsObject:
当前导入映射在任何模块加载开始后,或导入一个导入映射后,均被禁止。这些限制可能会在未来的规范修订中取消。
要解析导入映射字符串,给定一个字符串input和一个URLbaseURL:
让parsed为给定input解析JSON字符串为Infra值的结果。
让sortedAndNormalizedImports成为一个空的有序映射。
如果parsed["imports
"]存在,则:
如果parsed["imports
"]不是一个有序映射,则抛出一个TypeError
,表明"imports
"顶级键的值需要是一个JSON对象。
将sortedAndNormalizedImports设置为给定parsed["imports
"]和baseURL排序并规范化模块说明符映射的结果。
让sortedAndNormalizedScopes成为一个空的有序映射。
如果parsed["scopes
"]存在,则:
让normalizedIntegrity成为一个空的有序映射。
如果parsed["integrity
"]存在,则:
如果parsed["integrity
"]不是一个有序映射,则抛出一个TypeError
,表明"integrity
"顶级键的值需要是一个JSON对象。
将normalizedIntegrity设置为给定parsed["integrity
"]和baseURL规范化模块完整性映射的结果。
如果parsed的键包含除"imports
”、“scopes
”或"integrity
”之外的任何项,则用户代理应向控制台报告警告,表明导入映射中存在无效的顶级键。
这可以帮助检测拼写错误。这不是错误,因为这会阻止将来的扩展兼容性地添加。
返回一个导入映射,其imports为sortedAndNormalizedImports,其scopes为sortedAndNormalizedScopes,其integrity为normalizedIntegrity。
从该解析算法生成的导入映射是高度规范化的。例如,给定一个基本URL为https://example.com/base/page.html
的输入
{
"imports" : {
"/app/helper" : "node_modules/helper/index.mjs" ,
"lodash" : "/node_modules/lodash-es/lodash.js"
}
}
«[
"https://example.com/app/helper" → https://example.com/base/node_modules/helper/index.mjs
"lodash" → https://example.com/node_modules/lodash-es/lodash.js
]»
并且(尽管输入字符串中没有任何内容)其范围为空映射。
要排序并规范化模块说明符映射,给定一个有序映射originalMap和一个URLbaseURL:
让normalized成为一个空的有序映射。
对每个specifierKey→value的originalMap进行:
让normalizedSpecifierKey成为给定specifierKey和baseURL规范化说明符键的结果。
如果normalizedSpecifierKey为空,则继续。
如果value不是一个字符串,则:
让addressURL成为给定value和baseURL解析类似URL的模块说明符的结果。
如果addressURL为空,则:
如果specifierKey以U+002F(/)结尾,并且addressURL的序列化结果不以U+002F(/)结尾,则:
将normalized[normalizedSpecifierKey]设置为addressURL。
要排序并规范化范围,给定一个有序映射originalMap和一个URLbaseURL:
让normalized成为一个空的有序映射。
对每个scopePrefix→potentialSpecifierMap的originalMap进行:
如果potentialSpecifierMap不是一个有序映射,则抛出一个TypeError
,表明前缀为scopePrefix的范围的值需要是一个JSON对象。
让scopePrefixURL成为给定scopePrefix和baseURLURL解析的结果。
如果scopePrefixURL解析失败,则:
让normalizedScopePrefix成为scopePrefixURL的序列化结果。
将normalized[normalizedScopePrefix]设置为给定potentialSpecifierMap和baseURL排序并规范化模块说明符映射的结果。
在上述两个算法中,按降序排序键和范围的效果是将"foo/bar/
"放在"foo/
"之前。这反过来使得"foo/bar/
"在模块说明符解析期间比"foo/
"具有更高的优先级。
要规范化模块完整性映射,给定一个有序映射originalMap:
让normalized成为一个空的有序映射。
对每个key→value的originalMap进行:
让resolvedURL成为给定key和baseURL解析类似URL的模块说明符的结果。
与"imports
"不同,完整性映射的键被视为URL,而不是模块说明符。然而,我们使用解析类似URL的模块说明符算法禁止像foo
这样的"裸"相对URL,因为它们可能被误认为是模块说明符。
如果resolvedURL为空,则:
如果value不是一个字符串,则:
将normalized[resolvedURL]设置为value。
返回normalized。
要规范化说明符键,给定一个字符串specifierKey和一个URLbaseURL:
如果specifierKey为空字符串,则:
用户代理可以向控制台报告警告,表明说明符键不能为空字符串。
返回null。
让url成为给定specifierKey和baseURL解析类似URL的模块说明符的结果。
如果url不为空,则返回url的序列化结果。
返回specifierKey。
JavaScript 规范包含许多实现定义的抽象操作,这些操作因主机环境而异。本节为用户代理主机定义了这些操作。
JavaScript 包含一个实现定义的HostEnsureCanAddPrivateElement(O)抽象操作。用户代理必须使用以下实现:[JAVASCRIPT]
如果O是WindowProxy
对象,或实现Location
,则返回完成
{ [[Type]]: throw, [[Value]]: 新的TypeError
}。
返回NormalCompletion(unused)。
JavaScript 私有字段可以应用于任意对象。由于这可能显著复杂化特别是异类主机对象的实现,JavaScript 语言规范提供了这个挂钩,允许主机在满足主机定义标准的对象上拒绝私有字段。在
HTML
的情况下,WindowProxy
和Location
有复杂的语义——尤其是在导航和安全性方面——使得私有字段语义的实现具有挑战性,因此我们的实现只是拒绝这些对象。
JavaScript 包含一个实现定义的HostEnsureCanCompileStrings抽象操作,由动态代码品牌检查提案重新定义。用户代理必须使用以下实现:[JAVASCRIPT] [JSDYNAMICCODEBRANDCHECKS]
执行 ? EnsureCSPDoesNotBlockStringCompilation(realm, parameterStrings, bodyString, codeString, compilationType, parameterArgs, bodyArg)。[CSP]
动态代码品牌检查提案包含一个实现定义的HostGetCodeForEval(argument)抽象操作。用户代理必须使用以下实现:[JSDYNAMICCODEBRANDCHECKS]
如果argument是TrustedScript
对象,则返回argument的data。
否则,返回no-code。
JavaScript 包含一个实现定义的HostPromiseRejectionTracker(promise, operation)抽象操作。用户代理必须使用以下实现:[JAVASCRIPT]
将 script 设为运行中的脚本。
将 settingsObject 设为当前设置对象。
如果 script 不为 null,则将 settingsObject 设为 script 的设置对象。
将 global 设为 settingsObject 的全局对象。
如果 operation 是 "reject
",则:
将 promise 追加到 global 的即将通知的拒绝 promises 列表中。
如果 operation 是 "handle
",则:
如果 global 的即将通知的拒绝 promises 列表包含 promise,则从该列表中移除 promise并返回。
如果 global 的未处理拒绝的 promises 弱引用集合不 包含 promise,则返回。
从 global 的未处理拒绝的 promises 弱引用集合中移除 promise。
排入一个全局任务到DOM 操作任务源,给定
global,以触发一个事件名为rejectionhandled
在 global 上,使用
PromiseRejectionEvent
,
其 promise
属性初始化为
promise,以及 reason
属性初始化为 promise 的 [[PromiseResult]]。
Temporal 提案包含一个实现定义的HostSystemUTCEpochNanoseconds抽象操作。用户代理必须使用以下实现:[JSTEMPORAL]
让settingsObject成为global的相关设置对象。
让time成为settingsObject的当前墙上时间。
让ns成为从Unix纪元到time的纳秒数,四舍五入到最接近的整数。
返回将ns限制在nsMinInstant和nsMaxInstant之间的结果。
Reference/Global_Objects/Promise#Incumbent_settings_object_tracking
仅在一个引擎中支持。
JavaScript 规范定义了作业将在主机上安排并稍后运行,以及封装在作业中调用的JavaScript函数的JobCallback 记录。JavaScript规范包含许多实现定义的抽象操作,允许主机定义作业的调度方式和JobCallback的处理方式。HTML使用这些抽象操作通过保存和恢复承诺中的现任设置对象以及JobCallbacks中的JavaScript执行上下文来跟踪现任设置对象和活动脚本。本节为用户代理主机定义了这些操作。
JavaScript 包含一个实现定义的HostCallJobCallback(callback, V, argumentsList)抽象操作,以便在从任务内部调用 JavaScript 回调时让主机恢复状态。用户代理必须使用以下实现:[JAVASCRIPT]
让incumbent settings成为callback.[[HostDefined]].[[IncumbentSettings]]。
让script execution context成为callback.[[HostDefined]].[[ActiveScriptContext]]。
准备运行回调,使用incumbent settings。
这会在回调运行时影响现任概念。
如果script execution context不为null,则将script execution context压入JavaScript 执行上下文堆栈。
这会在回调运行时影响活动脚本。
让result成为调用(callback.[[Callback]], V, argumentsList)的结果。
如果script execution context不为null,则将script execution context从JavaScript 执行上下文堆栈中弹出。
在回调运行后清理,使用incumbent settings。
返回result。
JavaScript 具有将对象注册到FinalizationRegistry
对象的能力,以便在对象被垃圾回收时安排清理操作。JavaScript
规范包含一个实现定义的HostEnqueueFinalizationRegistryCleanupJob(finalizationRegistry)抽象操作,用于安排清理操作。
清理工作的时机和发生频率在 JavaScript 规范中是实现定义的。不同用户代理可能在垃圾回收的时机和是否发生上存在差异,这会影响WeakRef.prototype.deref()
方法的返回值是否为undefined,以及FinalizationRegistry
清理回调是否发生。在某些流行的网络浏览器中,存在已知情况:对象虽然对
JavaScript 不可访问,但仍然会被垃圾回收器无限期保留。HTML 在执行微任务检查点算法中清理保活的WeakRef
对象。作者最好不要依赖垃圾回收实现的时间细节。
清理操作不会与同步 JavaScript 执行交错发生,而是会在排队的任务中进行。用户代理必须使用以下实现:[JAVASCRIPT]
让global成为finalizationRegistry.[[Realm]]的全局对象。
在JavaScript 引擎任务源上排队一个全局任务,给定global以执行以下步骤:
让entry成为finalizationRegistry.[[CleanupCallback]].[[Callback]].[[Realm]]的环境设置对象。
检查我们是否可以运行脚本,使用entry。如果返回“不可运行”,则返回。
准备运行脚本,使用entry。
这会在清理回调运行时影响entry概念。
让result成为执行CleanupFinalizationRegistry(finalizationRegistry)的结果。
在脚本运行后清理,使用entry。
JavaScript 包含一个实现定义的HostEnqueueGenericJob(job,
realm)抽象操作,用于在特定领域执行通用作业(例如,解析因Atomics.waitAsync
而生成的承诺)。用户代理必须使用以下实现:[JAVASCRIPT]
让global成为realm的全局对象。
在JavaScript 引擎任务源上排队一个全局任务,给定global以执行job()。
JavaScript 包含一个实现定义的HostEnqueuePromiseJob(job, realm)抽象操作,用于调度与 Promise 相关的操作。HTML 将这些操作安排在微任务队列中。用户代理必须使用以下实现:[JAVASCRIPT]
如果realm不为null,则让job settings成为realm的设置对象。否则,让job settings为null。
如果realm不为null,则它是将运行的作者代码的领域。当job由NewPromiseReactionJob返回时,它是承诺的处理程序函数的领域。当job由NewPromiseResolveThenableJob返回时,它是then
函数的领域。
如果realm为null,则不会运行作者代码,或者作者代码保证抛出错误。对于前者,作者可能没有传递代码以运行,例如在promise.then(null, null)
中。对于后者,这是因为传递了被吊销的代理。在这两种情况下,所有步骤中使用job
settings的步骤都将被跳过。
NewPromiseResolveThenableJob 和 NewPromiseReactionJob 在代理被撤销的情况下似乎都提供了非 null 的领域(当前领域记录)。可以更新之前的文本以反映这一点。
排队一个微任务以执行以下步骤:
如果job settings不为null,则检查我们是否可以运行脚本,使用job settings。如果返回“不可运行”,则返回。
如果job settings不为null,则准备运行脚本,使用job settings。
这会在任务运行时影响entry概念。
让result成为job()的结果。
job是由NewPromiseReactionJob或NewPromiseResolveThenableJob返回的抽象闭包。当job由NewPromiseReactionJob返回时,承诺的处理程序函数和当job由NewPromiseResolveThenableJob返回时,then
函数被包装在JobCallback 记录中。HTML 保存现任设置对象和一个JavaScript 执行上下文,用于活动脚本,在HostMakeJobCallback中恢复这些对象,在HostCallJobCallback中再次调用。
如果job settings不为null,则在脚本运行后清理,使用job settings。
如果 result 是异常完成,则 报告一个异常,由 result.[[Value]] 为 realm 的全局对象提供。
存在一个非常棘手的情况,即 HostEnqueuePromiseJob 在被调用时使用了一个 null 领域(例如,因为 Promise.prototype.then 被使用 null 处理程序调用),但作业也可能异常结束(因为 promise 能力的 resolve 或 reject 处理程序抛出异常,可能是因为这是 Promise 的一个子类,它接收提供的函数并将它们包装在抛出异常的函数中,然后再传递给传递给 Promise 超类构造函数的函数。那么应该使用哪个全局对象,考虑到当前的领域在这些步骤中的每一步可能都不同,通过使用来自另一个领域的 Promise 构造函数或 Promise.prototype.then?请参见issue #10526。
JavaScript 包含一个实现定义的HostEnqueueTimeoutJob(job, milliseconds)抽象操作,用于调度一个在超时后执行的操作。HTML 使用超时后运行步骤调度这些操作。用户代理必须使用以下实现:[JAVASCRIPT]
让global成为realm的全局对象。
让timeoutStep成为一个算法步骤,该步骤在JavaScript 引擎任务源上排队一个全局任务,给定global以执行job()。
运行超时后的步骤,给定global、“JavaScript
”、milliseconds和timeoutStep。
JavaScript 包含一个实现定义的HostMakeJobCallback(callable)抽象操作,允许宿主在任务内部调用 JavaScript 回调时附加状态。用户代理必须使用以下实现:[JAVASCRIPT]
让incumbent settings成为现任设置对象。
让active script成为活动脚本。
让script execution context为null。
如果active script不为null,则将script execution context设置为一个新的JavaScript 执行上下文,其 Function 字段设为 null,其 Realm 字段设为active script的设置对象的领域,其 ScriptOrModule 字段设为active script的记录。
如下所示,这是为了将当前的活动脚本传递到调用任务回调的时间点。
在以下情况下,active script为非null,并且以这种方式保存它是有用的:
Promise. resolve( 'import(`./example.mjs`)' ). then( eval);
如果没有此步骤(以及在HostCallJobCallback中使用它的步骤),当评估import()
表达式时,将没有活动脚本,因为eval()
是一个内置函数,不起源于任何特定的脚本。
如果用户点击以下按钮,active script可以为null:
< button onclick = "Promise.resolve('import(`./example.mjs`)').then(eval)" > Click me</ button >
在这种情况下,事件处理程序的 JavaScript 函数将由获取事件处理程序的当前值算法创建,该算法创建一个[[ScriptOrModule]]值为 null 的函数。因此,当承诺机制调用HostMakeJobCallback时,将没有活动脚本可传递。
因此,当评估import()
表达式时,仍然没有活动脚本。幸运的是,我们在HostLoadImportedModule中的实现通过使用当前设置对象的API 基本 URL来处理这种情况。
返回JobCallback 记录 { [[Callback]]: callable, [[HostDefined]]: { [[IncumbentSettings]]: incumbent settings, [[ActiveScriptContext]]: script execution context } }。
JavaScript 规范定义了模块的语法,以及部分与宿主无关的处理模型。本规范定义了其余的处理模型:如何通过设置了script
元素的type
属性为"module
"来引导模块系统,以及如何获取、解析和执行模块。[JAVASCRIPT]
尽管 JavaScript 规范中使用了“脚本”和“模块”的术语,但本规范通常使用经典脚本和模块脚本,因为它们都使用了script
元素。
modulePromise = import(specifier)
返回specifier标识的模块脚本的模块命名空间对象的
promise。这允许在运行时动态导入模块脚本,而不是静态使用import
语句形式。specifier 将相对于活动脚本进行解析。
如果给定的 specifier 无效,或者在获取或评估生成的模块图时遇到失败,返回的 promise 将被拒绝。
url = import.meta.url
此语法只能在模块脚本中使用。
url = import.meta.resolve(specifier)
返回相对于活动脚本解析后的specifier。也就是说,这返回的是使用import(specifier)
导入的
URL。
如果给定的 specifier 无效,将抛出TypeError
异常。
此语法只能在模块脚本中使用。
模块映射是一个有序映射,以包含URL 记录和字符串的元组为键。URL 记录是模块获取时的请求
URL,字符串表示模块的类型(例如"javascript
")。模块映射的值可以是模块脚本、null(用于表示获取失败),或占位符值"fetching
"。模块映射用于确保在每个Document
或worker中,导入的模块脚本仅被获取、解析和执行一次。
由于模块映射的键是由(URL,模块类型)组成,因此以下代码将创建模块映射中的三个不同条目,因为它生成了三个不同的(URL,模块类型)元组(全部为"javascript
"类型):
import "https://example.com/module.mjs" ;
import "https://example.com/module.mjs#map-buster" ;
import "https://example.com/module.mjs?debug=true" ;
也就是说,URL 查询和片段可以变化以在模块映射中创建不同的条目;它们不会被忽略。因此,将执行三个独立的获取和三个独立的模块评估。
相比之下,以下代码在模块映射中只会创建一个条目,因为在对这些输入应用URL 解析器后,生成的URL 记录是相等的:
import "https://example.com/module2.mjs" ;
import "https:example.com/module2.mjs" ;
import "https://///example.com\\module2.mjs" ;
import "https://example.com/foo/../module2.mjs" ;
因此,在第二个例子中,只会发生一次获取和一次模块评估。
由于模块类型也是模块映射键的一部分,因此以下代码将在模块映射中创建两个不同的条目(第一个的类型为"javascript
",第二个的类型为"css
"):
< script type = module >
import "https://example.com/module" ;
</ script >
< script type = module >
import "https://example.com/module" with { type: "css" };
</ script >
这可能会导致执行两次独立的获取和两次独立的模块评估。
实际上,由于尚未指定的内存缓存(参见问题#6110),在基于 WebKit 和 Blink 的浏览器中,资源可能只会被获取一次。此外,只要所有模块类型互斥,在获取单个模块脚本时,模块类型检查将至少会失败一次,因此最多只会发生一次模块评估。
将类型包括在模块映射键中的目的是为了防止错误类型属性的导入阻止相同 specifier 的正确类型导入成功。
当从另一个 JavaScript 模块导入时,JavaScript 模块脚本是默认的导入类型;也就是说,当import
语句缺少type
导入属性时,导入的模块脚本类型将是
JavaScript。尝试使用type
导入属性通过import
语句导入 JavaScript 资源将失败:
< script type = "module" >
// All of the following will fail, assuming that the imported .mjs files are served with a
// JavaScript MIME type. JavaScript module scripts are the default and cannot be imported with
// any import type attribute.
import foo from "./foo.mjs" with { type: "javascript" };
import foo2 from "./foo2.mjs" with { type: "js" };
import foo3 from "./foo3.mjs" with { type: "" };
await import ( "./foo4.mjs" , { with : { type: null } });
await import ( "./foo5.mjs" , { with : { type: undefined } });
</ script >
Reference/Operators/import.meta/resolve
Support in all current engines.
Reference/Operators/import.meta
Support in all current engines.
JavaScript 包含一个实现定义的HostGetImportMetaProperties抽象操作。用户代理必须使用以下实现:[JAVASCRIPT]
令moduleScript为moduleRecord.[[HostDefined]]。
断言:moduleScript的基础 URL不为 null,因为moduleScript是JavaScript 模块脚本。
令steps为以下步骤,给定参数specifier:
令resolveFunction为 ! CreateBuiltinFunction(steps, 1,
"resolve
",
« »)。
返回« Record {
[[Key]]: "url
", [[Value]]: urlString }, Record {
[[Key]]: "resolve
", [[Value]]: resolveFunction }
»。
Import Attributes提案包含一个实现定义的HostGetSupportedImportAttributes抽象操作。用户代理必须使用以下实现:[JSIMPORTATTRIBUTES]
返回« "type
" »。
JavaScript 包含一个 实现定义的 HostLoadImportedModule 抽象操作。用户代理必须使用以下实现: [JAVASCRIPT]
令 settingsObject 为 当前设置对象。
如果 settingsObject 的 全局对象 实现了 WorkletGlobalScope
或
ServiceWorkerGlobalScope
并且 loadState 是未定义的,那么:
loadState 未定义时,当前的获取过程是由动态 import()
调用发起的,直接或加载动态导入模块的传递依赖时。
令 completion 为 完成记录 { [[Type]]: throw,
[[Value]]: 一个新的 TypeError
,
[[Target]]: 空 }。
执行 FinishLoadingImportedModule(referrer, moduleRequest, payload, completion)。
返回。
令 referencingScript 为 null。
令 originalFetchOptions 为 默认脚本获取选项。
令 fetchReferrer 为 "client
"。
如果 referrer 是 脚本记录 或 循环模块记录,则:
将 referencingScript 设置为 referrer.[[HostDefined]]。
将 settingsObject 设置为 referencingScript 的 设置对象。
将 fetchReferrer 设置为 referencingScript 的 基本 URL。
将 originalFetchOptions 设置为 referencingScript 的 获取选项。
referrer 通常是 脚本记录 或 循环模块记录,但事件处理程序的情况除外,依据 获取事件处理程序当前值 算法。例如,给出:
< button onclick = "import('./foo.mjs')" > 点击我</ button >
如果发生 点击
事件,那么当 import()
表达式运行时,GetActiveScriptOrModule 将返回 null,
此操作将使用 当前领域 作为备用
referrer。
如果 referrer 是一个 循环模块记录 并且 moduleRequest 等于 referrer.[[RequestedModules]] 的第一个元素,那么:
对于每个 模块请求记录 requested 在 referrer.[[RequestedModules]] 中:
如果 moduleRequest.[[Attributes]] 包含一个 记录
entry
其中 entry.[[Key]] 不是 "type
",那么:
令 completion 为 完成记录 { [[Type]]: throw,
[[Value]]: 一个新的 语法错误
异常, [[Target]]: 空 }。
执行 完成加载导入模块(referrer, moduleRequest, payload, completion)。
返回。
JavaScript 规范会重新执行此验证,但在此重复它以避免在验证失败时不必要地加载任何依赖项。
解析模块说明符,给定 referencingScript 和 moduleRequest.[[Specifier]],捕获任何异常。如果它们抛出异常,则令 resolutionError 为抛出的异常。
如果前一步抛出了异常,那么:
令 moduleType 为执行 模块请求的模块类型 步骤后的结果,给定 moduleRequest。
如果执行 模块类型允许 步骤的结果为 false,给定 moduleType 和 settingsObject,那么:
此步骤实际上是在第一次调用 HostLoadImportedModule 以处理静态模块依赖列表时验证所有请求的模块说明符和类型属性,以避免任何依赖项具有静态错误时的进一步加载操作。我们将无法解析模块说明符或不支持类型属性的模块视为与无法解析的模块相同;在这两种情况下,语法问题都使得以后无法考虑链接模块。
禁止进一步导入映射,给定 settingsObject。
令 url 为 解析模块说明符 的结果,给定 referencingScript 和 moduleRequest.[[Specifier]],捕获任何异常。如果抛出异常,令 resolutionError 为抛出的异常。
如果前一步抛出了异常,那么:
令 fetchOptions 为 获取子脚本的获取选项 的结果,给定 originalFetchOptions, url, 和 settingsObject。
令 destination 为 "script"
。
令 fetchClient 为 settingsObject。
如果 loadState 不是未定义的,那么:
将 destination 设置为 loadState.[[Destination]]。
将 fetchClient 设置为 loadState.[[FetchClient]]。
获取单个导入的模块脚本,给定 url, fetchClient, destination, fetchOptions, settingsObject, fetchReferrer, moduleRequest,以及 onSingleFetchComplete,如下所述。如果 loadState 不是未定义的且 loadState.[[PerformFetch]] 不是 null,则传递 loadState.[[PerformFetch]] 。
onSingleFetchComplete 给定 moduleScript 的算法如下:
令 completion 为 null。
如果 moduleScript 是 null,则将 completion 设置为 完成记录 { [[Type]]: throw, [[Value]]: 一个新的 TypeError
,
[[Target]]: 空 }。
否则,如果 moduleScript 的 解析错误 不是 null,那么:
否则,将 completion 设置为 完成记录 { [[Type]]: normal,[[Value]]: moduleScript 的 记录,[[Target]]: 空 }。
执行 完成加载导入模块(referrer, moduleRequest, payload, completion)。
为了协调事件、用户交互、脚本、渲染、网络等,用户代理必须使用本节描述的事件循环。每个代理都有一个关联的事件循环,该循环对于该代理是唯一的。
相同来源窗口代理的事件循环称为窗口事件循环。专用worker代理、共享worker代理或服务worker代理的事件循环称为worker事件循环。Worklet 代理的事件循环称为Worklet 事件循环。
事件循环不一定对应于实现线程。例如,多个窗口事件循环可以在单个线程中协作调度。
但是,对于分配了 [[CanBlock]] 设置为 true 的各种worker代理,JavaScript 规范确实对其前进进度提出了要求,实际上在这些情况下需要专用的每代理线程。
事件循环有一个或多个任务队列。任务队列是一个集合,由任务组成。
任务队列是集合,而不是队列,因为事件循环处理模型从所选队列中获取第一个可运行的任务,而不是出队第一个任务。
任务封装了负责以下工作的算法:
在特定Event
对象上分发EventTarget
对象通常由专门的任务完成。
并非所有事件都使用任务队列分发;许多事件在其他任务期间分发。
HTML 解析器标记一个或多个字节,然后处理任何生成的标记,通常是一个任务。
调用回调通常由专门的任务完成。
当算法获取资源时,如果获取以非阻塞方式进行,则资源的一部分或全部可用后对资源的处理由任务执行。
某些元素具有响应 DOM 操作的任务,例如当该元素被插入到文档中时。
正式来说,任务是一个结构体,它具有以下属性:
文档
,对于不在窗口事件循环中的任务则为 null。
如果任务的文档为 null 或完全活跃,则该任务是可运行的。
根据其来源字段,每个任务定义为来自特定的任务来源。对于每个事件循环,每个任务来源必须与特定的任务队列关联。
本质上,任务来源在标准中用于区分逻辑上不同类型的任务,用户代理可能希望在这些任务之间进行区分。任务队列由用户代理用于在给定的事件循环内合并任务来源。
例如,用户代理可以有一个任务队列用于鼠标和键盘事件(与用户交互任务来源关联),另一个队列用于所有其他任务来源。然后,使用事件循环处理模型的初始步骤中赋予的自由,它可以在四分之三的时间内优先处理键盘和鼠标事件,从而保持界面响应,但不会饿死其他任务队列。请注意,在这种设置中,处理模型仍然强制用户代理永远不会按顺序处理来自任何一个任务来源的事件。
每个事件循环都有一个当前运行的任务,它可以是任务或 null。最初,这个值为 null。它用于处理重入性。
每个事件循环都有一个微任务队列,这是一个队列,存放微任务,最初为空。微任务是指通过排队微任务算法创建的任务。
每个事件循环都有一个执行微任务检查点布尔值,最初为 false。它用于防止重新进入执行微任务检查点算法。
每个窗口事件循环都有一个DOMHighResTimeStamp
最后渲染机会时间,初始值为零。
每个窗口事件循环都有一个DOMHighResTimeStamp
最后空闲期开始时间,初始值为零。
要获取窗口事件循环
loop的同循环窗口,返回所有Window
对象,其相关代理的事件循环是loop。
要在任务来源 source上排队一个任务,执行一系列步骤steps,可选地给定一个事件循环event loop和一个文档document:
如果未给定event loop,则将event loop设置为隐含事件循环。
如果未给定document,则将document设置为隐含文档。
令task为一个新的任务。
将task的步骤设置为steps。
将task的来源设置为source。
将task的文档设置为document。
将task的脚本评估环境设置对象集设置为空集合。
令queue为event loop上与source关联的任务队列。
将task附加到queue。
未能将事件循环和文档传递给排队任务意味着依赖模棱两可且定义不清的隐含事件循环和隐含文档概念。规范作者应始终传递这些值,或者使用包装算法排队全局任务或排队元素任务代替。建议使用包装算法。
要在任务来源source上排队全局任务,使用全局对象global和一系列步骤steps:
令document为global的关联的Document
,如果global是Window
对象;否则为 null。
根据source、event loop、document和steps排队任务。
要在任务来源source上排队元素任务,使用元素element和一系列步骤steps:
要排队一个微任务,执行一系列步骤steps,可选地给定一个文档document:
如果未给定document,则将document设置为隐含文档。
令microtask为一个新的任务。
将microtask的步骤设置为steps。
将microtask的来源设置为微任务来源。
将microtask的文档设置为document。
将microtask的脚本评估环境设置对象集设置为空集合。
将microtask排入eventLoop的微任务队列。
如果在其初始执行期间旋转事件循环,则微任务可能会被移到常规任务队列中。这是唯一会咨询微任务的来源、文档和脚本评估环境设置对象集的情况;它们在执行微任务检查点算法中被忽略。
排队任务时的隐含事件循环是从调用算法的上下文中推导出的。通常这很明确,因为大多数规范算法只涉及单个代理(因此只有一个事件循环)。例外是涉及或指定跨代理通信的算法(例如,窗口和worker之间);对于这些情况,不得依赖于隐含事件循环概念,规范必须在排队任务时明确提供事件循环。
在事件循环event loop上排队任务时的隐含文档确定如下:
如果event loop不是窗口事件循环,则返回 null。
如果任务在元素的上下文中排队,则返回元素的节点文档。
如果任务由或为脚本排队,则返回脚本的设置对象的全局对象的关联的Document
。
断言:此步骤永远不会达到,因为前面的条件之一为真。真的吗?
隐含事件循环和隐含文档都定义得模糊,并且具有很大的远程操作性。希望能够删除这些,尤其是隐含文档。详见问题 #4980。
一个事件循环 必须在存在期间持续运行以下步骤:
让 oldestTask 和 taskStartTime 为 null。
让 taskEndTime 为 不安全的共享当前时间。 [HRT]
如果 oldestTask 不是 null,则:
如果这是一个 窗口事件循环,且该 事件循环的任务队列 中没有 可运行的 任务,则:
将此 事件循环的最后空闲期开始时间设置为 不安全的共享当前时间。
让 computeDeadline 成为以下步骤:
对于此相同循环窗口的每个 win,对 win 执行 开始一个空闲期算法, 并返回调用 computeDeadline 的结果,时间粗化,给定 win 的 相关设置对象 的 跨源隔离能力。[REQUESTIDLECALLBACK]
如果这是一个 worker事件循环,则:
如果此 事件循环的
代理的单个 领域的 全局对象 是一个 支持的
DedicatedWorkerGlobalScope
对象,且用户代理认为此时更新其渲染是有益的,那么:
让 now 成为当前高分辨率时间,给定
DedicatedWorkerGlobalScope
。
[HRT]
运行动画帧回调,为此
DedicatedWorkerGlobalScope
,
传递 now 作为时间戳。
更新该专用worker的渲染以反映当前状态。
如果此 事件循环的任务队列中没有 任务,并且
WorkerGlobalScope
对象的关闭标志为 true,则销毁
事件循环,中止这些步骤,并恢复运行worker的步骤,如下面的Web worker部分中所述。
一个 窗口事件循环 eventLoop 也必须 运行以下步骤,并行,只要它存在:
等待至少有一个 可导航对象,其 活动文档 的 相关代理 的 事件循环 是 eventLoop,并且可能有一个 渲染机会。
将 eventLoop 的最后渲染机会时间 设置为 不安全的共享当前时间。
对于每个有 渲染机会的 navigable,在 渲染任务源上 排队全局任务,给定 navigable 的 活动窗口以 更新渲染:
这可能会导致冗余调用更新渲染。然而,这些调用将没有可观察到的效果,因为根据不必要的渲染步骤,不会有必要的渲染。实现可以引入进一步的优化,例如仅在任务尚未排队时才排队此任务。但是,请注意,与任务相关的文档可能在任务处理之前变得不活跃。
让 frameTimestamp 成为 eventLoop 的最后渲染机会时间。
让 docs 成为所有 完全活跃的
Document
对象,相关代理的 事件循环
是
eventLoop,按任意顺序排序,但必须满足以下条件:
在下面的步骤中,遍历 docs 时,每个 Document
必须按列表中的顺序进行处理。
过滤不可渲染的文档:从 docs 中移除任何 Document
对象 doc,如果满足以下任何条件:
我们必须在这里检查渲染机会,除了在并行步骤中检查渲染机会,因为某些共享相同事件循环的文档可能不会在同一时间拥有 渲染机会。
不必要的渲染:从 docs 中移除任何 Document
对象 doc,如果以下所有条件都为真:
从 docs 中移除所有用户代理认为出于其他原因最好跳过更新渲染的 Document
对象。
对于 docs 中的每个 doc,揭示 doc。
对于 docs 中的每个 doc,运行调整大小步骤。
对于 docs 中的每个 doc,运行滚动步骤。
对于 docs 中的每个 doc,评估媒体查询并报告更改。
对于 docs 中的每个 doc,更新动画并发送事件,传递 相对高分辨率时间 给定 frameTimestamp 和 doc 的 相关全局对象 作为时间戳。
对于 docs 中的每个 doc,运行全屏步骤。
对于 docs 中的每个 doc,如果用户代理检测到与 CanvasRenderingContext2D
或
OffscreenCanvasRenderingContext2D
关联的备份存储丢失,则必须为每个 context 运行 上下文丢失步骤:
让 canvas 成为 context 的 canvas
属性的值,如果 context 是 CanvasRenderingContext2D
,
或者是 关联的
OffscreenCanvas
对象,如果 context 不是。
将 context 的上下文丢失设置为 true。
将渲染上下文重置为默认状态给定 context。
让 shouldRestore 成为 触发一个名为
contextlost
的事件的结果,在 canvas 上,cancelable
属性初始化为 true。
如果 shouldRestore 为 false,则中止这些步骤。
尝试通过使用 context 的属性创建一个备份存储并将其与 context 关联来恢复 context。如果失败,则中止这些步骤。
将 context 的上下文丢失设置为 false。
触发一个事件,名为 contextrestored
,在
canvas 上。
对于 docs 中的每个 doc,运行动画帧回调,传递相对高分辨率时间,给定 frameTimestamp 和 doc 的 相关全局对象 作为时间戳。
让 unsafeStyleAndLayoutStartTime 为 不安全的共享当前时间。
对于 docs 中的每个 doc:
让 resizeObserverDepth 为 0。
当条件成立时:
重新计算样式并更新 doc 的布局。
让 hadInitialVisibleContentVisibilityDetermination 为 false。
对于每个具有 ‘auto’ 使用值的元素 ‘content-visibility’:
如果 hadInitialVisibleContentVisibilityDetermination 为 true,则继续。
此步骤的意图是使初始视口接近度确定(立即生效)在此循环的先前步骤中进行的样式和布局计算中反映出来。除首次外的接近度确定将在下一个渲染机会时生效。[CSSCONTAIN]
如果 doc 有活动调整大小观察:
设置 resizeObserverDepth 为广播活动调整大小观察给定 doc 的结果。
如果 doc 有跳过的调整大小观察,则 传递调整大小循环错误给定 doc。
对于 docs 中的每个 doc,如果 doc 的 聚焦区域 不是 可聚焦区域,则 为 doc 的视口运行 聚焦步骤,并设置 doc 的 相关全局对象的 导航API 的 正在进行的导航期间聚焦已更改 为 false。
属性,导致它停止对于 docs 中的每个 doc,执行待定的过渡操作。
对于 docs 中的每个 doc,运行更新交叉观察步骤,传递 相对高分辨率时间 给定 now 和 doc 的 相关全局对象 作为时间戳。
对于 docs 中的每个 doc,记录渲染时间,给定 unsafeStyleAndLayoutStartTime。
对于 docs 中的每个 doc,标记绘制时间。
对于 docs 中的每个 doc,更新 doc 及其节点导航 的渲染或用户界面以反映当前状态。
对于 docs 中的每个 doc,处理顶层移除给定 doc。
一个 可导航对象 有一个渲染机会,如果用户代理当前能够将 可导航对象 的内容展示给用户,考虑到硬件刷新率限制和用户代理为了性能原因进行的节流,但即使内容不在视口内,也会认为内容是可展示的。
一个 可导航对象 的 渲染机会
是基于硬件限制(如显示刷新率)和其他因素(如页面性能或其 活动文档 的
可见性状态 为
"visible
")确定的。渲染机会通常以固定的间隔发生。
本规范不强制要求采用任何特定的模型来选择渲染机会。但例如,如果浏览器试图达到 60Hz 的刷新率,那么渲染机会最多会在每秒 60 次(约 16.7 毫秒)的时间间隔内发生。如果浏览器发现某个 可导航对象 无法维持此速率,它可能会降至该可导航对象每秒 30 次渲染机会,而不是偶尔丢帧。同样,如果某个 可导航对象 不可见,则用户代理可能会决定将该页面降至每秒 4 次甚至更少的渲染机会。
当用户代理要执行微任务检查点时:
如果 事件循环的 正在执行微任务检查点 为真,则返回。
将 事件循环的 正在执行微任务检查点 设置为 true。
对于每个环境设置对象 settingsObject,其负责的事件循环 是此事件循环,通知拒绝的 promises,给定 settingsObject 的全局对象。
执行 清除保持的对象。
当WeakRef.prototype.deref()
返回一个对象时,该对象保持存活,直到下次调用 清除保持的对象(),之后它再次受到垃圾回收的影响。
将 事件循环的 正在执行微任务检查点 设置为 false。
当运行并行的算法要等待稳定状态时, 用户代理必须排队一个微任务,运行以下步骤,并且必须停止执行(当微任务运行时恢复算法的执行,如下步骤所述):
运行算法的 同步部分。
如算法步骤中所述,在适当情况下并行恢复算法的执行。
标记在同步部分中的步骤以 ⌛ 标记。
要求旋转事件循环直到达到条件goal 的算法步骤 等价于替换为以下算法步骤:
task 可能是 微任务。
让 task source 成为 task 的 源。
让 old stack 成为 JavaScript 执行上下文栈 的副本。
如果 task 是 微任务,此步骤将是无操作,因为 正在执行微任务检查点 为 true。
并行:
等待直到条件 goal 满足。
排队一个任务在task source上:
用 old stack 替换 JavaScript 执行上下文栈。
执行出现在这个 旋转事件循环实例中的原始算法中的任何步骤。
这会恢复 task。
停止 task,允许调用它的算法恢复。
与本规范和其他规范中的其他算法不同,它们的行为类似于编程语言的函数调用,旋转事件循环 更像是一个宏,通过扩展成一系列步骤和操作来节省打字和缩进。
一个算法,其步骤是:
做某事。
旋转事件循环直到发生了不起的事情。
做别的事。
是一个简写,经过“宏扩展”后,变成:
做某事。
让 old stack 成为 JavaScript 执行上下文栈 的副本。
并行:
等待直到发生了不起的事情。
排队一个任务 在执行“做某事”的任务源上:
用 old stack 替换 JavaScript 执行上下文栈。
做别的事。
这是一个更完整的替换示例,其中事件循环是从并行工作中排队的任务内部旋转的。使用 旋转事件循环 的版本:
完整扩展版本:
并行:
做并行的事 1。
让 old stack 为 null。
做任务的事 1。
设置 old stack 为 JavaScript 执行上下文栈 的副本。
等待直到发生了不起的事情。
用 old stack 替换 JavaScript 执行上下文栈。
做任务的事 2。
做并行的事 2。
本规范中的某些算法,由于历史原因,要求用户代理在运行 任务时暂停,直到条件 goal 满足。这意味着要运行以下步骤:
让 global 成为 当前全局对象。
让 timeBeforePause 成为 当前高分辨率时间给定 global。
等待直到条件 goal 满足。当用户代理具有暂停的 任务时, 相应的 事件循环不得继续运行其他 任务,并且当前运行的任务 中的任何脚本必须阻塞。然而,用户代理在暂停期间应保持对用户输入的响应能力,尽管由于事件循环不会执行任何操作,因此响应能力会有所降低。
暂停对用户体验非常不利,尤其是在多个文档共享一个事件循环的情况下。用户代理被鼓励尝试替代暂停的方案,例如旋转事件循环,甚至只是继续执行而没有任何形式的暂停执行,只要在尽可能保持与现有内容的兼容性的情况下做到这一点。本规范会很乐意进行更改,如果发现一种不那么激烈且与网络兼容的替代方案。
与此同时,实施者应该意识到用户代理可能试验的各种替代方案可能会改变事件循环行为的细微方面,包括任务和微任务的时间安排。实现者应该继续实验,即使这样做会导致它们违反暂停操作所暗示的确切语义。
以下任务源由本规范和其他规范中的许多不相关的功能使用。
此任务源用于响应用户交互的功能,例如键盘或鼠标输入。
响应用户输入发送的事件(例如 click
事件)必须使用任务通过排队到用户交互任务源触发。[UIEVENTS]
此任务源用于响应网络活动触发的功能。
编写正确与事件循环交互的规范可能会很棘手。这一问题因本规范使用与并发模型无关的术语而更加复杂,因此我们使用了“事件循环”和“并行”等术语,而不是使用更为熟悉的模型特定术语,如“主线程”或“后台线程”。
默认情况下,规范文本通常在事件循环上运行。这源于事件循环处理模型的形式化描述,因为你最终可以将大多数算法追溯到在那里排队的任务。
任何 JavaScript 方法的算法步骤都会被调用者代码调用。而调用者代码只能通过排队任务来运行,这些任务通常起源于script
处理模型的某个地方。
从这一起点出发,首要指导原则是,任何规范需要执行的工作,如果会阻塞事件循环,则必须改为与其并行执行。这包括(但不限于):
执行繁重的计算;
显示面向用户的提示;
执行可能需要涉及外部系统的操作(即“进程外执行”)。
下一个复杂点是,在并行的算法部分中,你不能创建或操作与特定realm、全局对象或环境设置对象关联的对象。(用更熟悉的术语来说,你不能直接从后台线程访问主线程工件。)这样做会创建 JavaScript 代码可观察到的数据竞争,因为毕竟,你的算法步骤是与 JavaScript 代码并行运行的。
然而,你可以操作来自Infra的规范级数据结构和值,因为它们与 realm 无关。它们不会直接暴露给 JavaScript,除非进行特定的转换(通常是通过 Web IDL)。[INFRA] [WEBIDL]
因此,要影响 JavaScript 对象的可观察世界,你必须排队一个全局任务来执行任何此类操作。这确保了你的步骤相对于其他事件循环中发生的事情是正确交错的。此外,在排队全局任务时,你必须选择任务源;这决定了你的步骤相对于其他步骤的相对顺序。如果你不确定使用哪个任务源,请选择一个最适用的通用任务源。最后,你必须指明你的排队任务与哪个全局对象关联;这确保了如果该全局对象处于非活动状态,则任务不会运行。
构建排队全局任务的基础原语是排队任务算法。通常,排队全局任务更好,因为它会自动选择正确的事件循环,并在适当的情况下选择文档。较旧的规范通常使用排队任务,结合隐含事件循环和隐含文档概念,但不推荐这样做。
将这些组合在一起,我们可以为需要异步执行工作的典型算法提供一个模板:
在事件循环上进行任何同步设置工作。这可能包括将realm特定的 JavaScript 值转换为与 realm 无关的规范级值。
在并行执行一组可能耗时的步骤,完全操作与 realm 无关的值,并生成与 realm 无关的结果。
排队一个全局任务,在指定的任务源上,并给定适当的全局对象,将 realm 无关的结果转换回在事件循环上可观察的 JavaScript 对象世界中的可观察效果。
以下是一个“加密”传入的列表的算法,该列表由input的标量值字符串组成,经过解析后作为 URL:
让urls成为一个空的列表。
对于 input的每个string:
如果parsed失败,则返回一个因"SyntaxError
" DOMException
被拒绝的
promise。
让serialized成为将URL 序列化器应用于parsed的结果。
将 serialized添加到urls。
让realm成为当前 realm。
让p成为一个新的 promise。
并行运行以下步骤:
返回p。
以下是关于此算法的几个注意事项:
它在事件循环上先执行 URL 解析,然后再进行并行步骤。这是必要的,因为解析依赖于当前设置对象,而在进入并行步骤后,该对象将不再是当前的。
或者,它可以保存当前设置对象的API 基础 URL的引用,并在并行步骤中使用它;这将是等效的。然而,我们建议像这个例子一样,尽可能提前完成工作。尝试保存正确的值可能容易出错;例如,如果我们只保存了当前设置对象,而不是它的API 基础 URL,可能会出现竞争条件。
Promise 作为可观察的 JavaScript 对象,从未在并行步骤中创建和操作。p在进入这些步骤之前创建,然后在专门为此目的排队的任务中操作。
JavaScript 数组对象的创建也发生在排队任务期间,并且在哪个 realm 中创建数组时,小心地加以说明,因为这在上下文中不再明显。
(关于最后两点,还请参阅whatwg/webidl issue #135和whatwg/webidl issue #371,我们仍在权衡上述 promise 解析模式的细微之处。)
另一个需要注意的事项是,如果此算法是从 Web IDL 指定的操作调用的,并且该操作接受一个sequence
<USVString
>,
则会自动从作者提供的特定realm的 JavaScript 对象转换为与 realm 无关的sequence
<USVString
>
Web IDL 类型,然后我们将其视为列表的标量值字符串。因此,根据你的规范结构,可能还有其他隐式步骤在主事件循环上执行,在这个过程中,这些步骤在准备并行执行中起到了作用。
许多对象可以指定事件处理程序。这些处理程序作为指定对象上的非捕获事件监听器。[DOM]
一个值,可以是null、回调对象或内部原始未编译处理程序。EventHandler
回调函数类型描述了它如何向脚本公开。最初,事件处理程序的值必须设置为null。
一个监听器,可以是null或事件监听器,负责运行事件处理程序处理算法。最初,事件处理程序的监听器必须设置为null。
事件处理程序通过两种方式公开。
第一种方式,适用于所有事件处理程序,是作为事件处理程序IDL属性。
第二种方式是作为事件处理程序内容属性。HTML元素上的事件处理程序和一些Window对象上的事件处理程序通过这种方式公开。
对于这两种方式,事件处理程序通过一个名称来公开,该名称总是以“on
”开头,后跟事件名称。
通常,暴露事件处理程序的对象与添加相应事件监听器的对象是相同的。
然而,body
和 frameset
元素暴露了多个事件处理程序,这些事件处理程序作用于元素的 Window
对象(如果存在)。在任一情况下,我们称该对象为事件处理程序作用的事件处理程序的目标。
要确定事件处理程序的目标,给定一个EventTarget
对象 eventTarget(该对象暴露了事件处理程序)和一个事件处理程序名称
name,按照以下步骤操作:
如果 name 不是
WindowEventHandlers
接口混入的属性成员名称,并且Window
-反映 body
元素的事件处理程序集不包含
name,则返回 eventTarget。
如果 eventTarget 的节点文档不是活动文档,则返回 null。
这可能发生在此对象是没有对应的body
元素的
Window
对象的情况下。
此检查不一定会阻止不是其节点文档的body 元素和
frameset
元素到达下一步。特别是,在活动文档中创建的
body
元素(可能使用 document.createElement()
创建),但未连接的也会有其对应的
Window
对象,作为通过其暴露的多个事件处理程序的
目标。
每个指定了一个或多个事件处理程序的EventTarget
对象都有一个相关的事件处理程序映射,它是表示名称的有序映射,这些名称表示事件处理程序的名称。
当一个指定了一个或多个事件处理程序的EventTarget
对象被创建时,它的事件处理程序映射必须初始化,使其包含该对象作为目标的每个事件处理程序的一个条目,其中这些事件处理程序中的项目设置为它们的初始值。
事件处理程序映射条目的顺序可能是任意的。通过任何操作映射的算法都无法观察到。
对于仅公开在该对象上但有其他对象作为目标的事件处理程序,不会在对象的事件处理程序映射中创建条目。
事件处理程序IDL属性是特定事件处理程序的IDL属性。IDL属性的名称与事件处理程序的名称相同。
具有名称name的事件处理程序IDL属性的getter在调用时必须运行以下步骤:
让eventTarget成为通过确定事件处理程序的目标得出的给定此对象和name的结果。
如果eventTarget为null,则返回null。
返回通过获取事件处理程序的当前值给定eventTarget和name的结果。
具有名称name的事件处理程序IDL属性的setter在调用时必须运行以下步骤:
让eventTarget成为通过确定事件处理程序的目标得出的给定此对象和name的结果。
如果eventTarget为null,则返回。
如果给定的值为null,则停用事件处理程序,给定eventTarget和name。
否则:
某些事件处理程序IDL属性有附加要求,特别是onmessage
属性的MessagePort
对象。
事件处理程序内容属性是特定事件处理程序的内容属性。内容属性的名称与名称相同。
事件处理程序内容属性指定时,必须包含有效的JavaScript代码,该代码在解析时将匹配FunctionBody生成规则,并经过自动分号插入。
以下属性更改步骤用于在事件处理程序内容属性与事件处理程序之间进行同步:[DOM]
如果namespace不为null,或者localName不是element上的事件处理程序内容属性的名称,则返回。
让eventTarget成为通过确定事件处理程序的目标给定element和localName的结果。
如果eventTarget为null,则返回。
如果value为null,则停用事件处理程序,给定eventTarget和localName。
否则:
如果内容安全策略应阻止元素的内联行为?算法在element、“script attribute
”和value上执行时返回“Blocked
”,则返回。[CSP]
让handlerMap成为eventTarget的事件处理程序映射。
让eventHandler成为handlerMap[localName]。
让location成为触发这些步骤执行的脚本位置。
将eventHandler的值设置为内部原始未编译处理程序的value/location。
激活事件处理程序,给定eventTarget和localName。
根据DOM标准,即使oldValue和value相同(将属性设置为其当前值),也会运行这些步骤,但如果oldValue和value都为null(删除不存在的属性),则不会运行这些步骤。[DOM]
要停用事件处理程序,给定EventTarget
对象eventTarget和表示事件处理程序名称的字符串name,执行以下步骤:
让handlerMap成为eventTarget的事件处理程序映射。
让eventHandler成为handlerMap[name]。
将eventHandler的值设置为null。
让listener成为eventHandler的监听器。
如果listener不为null,则移除事件监听器,给定eventTarget和listener。
将eventHandler的监听器设置为null。
要删除所有事件监听器和处理程序,给定EventTarget
对象eventTarget,执行以下步骤:
如果eventTarget有一个相关的事件处理程序映射,则对于eventTarget的相关事件处理程序映射中的每个name → eventHandler,停用事件处理程序,给定eventTarget和name。
移除所有事件监听器,给定eventTarget。
此算法用于定义document.open()
。
要激活事件处理程序,给定EventTarget
对象eventTarget和表示事件处理程序名称的字符串name,执行以下步骤:
让handlerMap成为eventTarget的事件处理程序映射。
让eventHandler成为handlerMap[name]。
如果eventHandler的监听器不为null,则返回。
让callback成为创建一个Web IDLEventListener
实例的结果,该实例表示一个函数的引用,该函数有一个参数,执行事件处理程序处理算法的步骤,给定eventTarget、name及其参数。
EventListener
的回调上下文可以是任意的;它不影响事件处理程序处理算法的步骤。[DOM]
回调明确不是事件处理程序本身。每个事件处理程序最终都会注册相同的回调,即下文定义的算法,该算法负责调用正确的代码并处理代码的返回值。
让listener成为一个新的事件监听器,其类型是与eventHandler对应的事件处理程序事件类型,回调为callback。
需要明确的是,事件监听器与EventListener
不同。
添加事件监听器,给定eventTarget和listener。
将eventHandler的监听器设置为listener。
事件监听器注册仅在事件处理程序的值设置为非null时发生,并且事件处理程序尚未激活。由于监听器是按注册顺序调用的,假设未发生停用,则特定事件类型的事件监听器顺序将始终是:
在事件处理程序的值首次设置为非null之前,通过addEventListener()
注册的事件监听器
然后是当前设置的回调(如果有的话)
最后是事件处理程序的值首次设置为非null之后,通过addEventListener()
注册的事件监听器。
此示例演示了事件监听器的调用顺序。如果用户单击此示例中的按钮,页面将显示四个警报,分别显示文本“ONE”、“TWO”、“THREE”和“FOUR”。
< button id = "test" > Start Demo</ button >
< script >
var button = document. getElementById( 'test' );
button. addEventListener( 'click' , function () { alert( 'ONE' ) }, false );
button. setAttribute( 'onclick' , "alert('NOT CALLED')" ); // event handler listener is registered here
button. addEventListener( 'click' , function () { alert( 'THREE' ) }, false );
button. onclick = function () { alert( 'TWO' ); };
button. addEventListener( 'click' , function () { alert( 'FOUR' ) }, false );
</ script >
然而,在以下示例中,事件处理程序在其初次激活后(并且其事件监听器被移除)被停用,然后在稍后重新激活。页面将按顺序显示五个警报,分别显示“ONE”、“TWO”、“THREE”、“FOUR”和“FIVE”。
< button id = "test" > Start Demo</ button >
< script >
var button = document. getElementById( 'test' );
button. addEventListener( 'click' , function () { alert( 'ONE' ) }, false );
button. setAttribute( 'onclick' , "alert('NOT CALLED')" ); // event handler is activated here
button. addEventListener( 'click' , function () { alert( 'TWO' ) }, false );
button. onclick = null ; // but deactivated here
button. addEventListener( 'click' , function () { alert( 'THREE' ) }, false );
button. onclick = function () { alert( 'FOUR' ); }; // and re-activated here
button. addEventListener( 'click' , function () { alert( 'FIVE' ) }, false );
</ script >
事件对象所实现的接口不会影响事件处理程序是否会被触发。
事件处理程序处理算法用于处理EventTarget
对象eventTarget、表示事件处理程序名称的字符串name以及Event
对象event,按如下步骤进行:
通过eventTarget和name,获取当前事件处理程序的值,并将结果赋给callback。
如果callback为null,则返回。
如果event是ErrorEvent
对象,event的type
为"error
",并且event的currentTarget
实现了WindowOrWorkerGlobalScope
混合接口,则设定special
error event handling为true。否则,设定special error event handling为false。
处理Event
对象event,具体步骤如下:
将 return value 设为调用 callback 的结果,使用 «
event 的 message
、
event 的
filename
、
event 的 lineno
、
event 的 colno
、
event 的 error
»、
"rethrow
",并将 回调此值 设置为
event 的 currentTarget
。
将 return value 设为调用 callback 的结果,使用 «
event »、"rethrow
",并将 回调此值 设置为
event 的 currentTarget
。
如果回调函数抛出异常,它将被重新抛出,从而结束这些步骤。异常将传播到DOM 事件分发逻辑,然后报告该异常。
按如下步骤处理return value:
BeforeUnloadEvent
对象,并且event的type
为"beforeunload
"
在这种情况下,事件处理程序IDL属性的类型将为OnBeforeUnloadEventHandler
,因此return
value将被强制转换为null或DOMString
。
如果return value不是null,则:
设置event的canceled标志。
如果event的returnValue
属性的值为空字符串,则将event的returnValue
属性的值设置为return
value。
如果return value为true,则设置event的canceled标志。
如果return value为false,则设置event的canceled标志。
如果我们进入了这个“否则”子句,因为event的type
为"beforeunload
",但event不是BeforeUnloadEvent
对象,那么return
value永远不会为false,因为在这种情况下return value会被强制转换为null或DOMString
。
EventHandler
回调函数类型表示用于事件处理程序的回调函数。它在Web
IDL中表示如下:
[LegacyTreatNonObjectAsNull ]
callback EventHandlerNonNull = any (Event event );
typedef EventHandlerNonNull ? EventHandler ;
在JavaScript中,任何Function
对象都实现了这个接口。
例如,以下文档片段:
< body onload = "alert(this)" onclick = "alert(this)" >
...当文档加载时,会显示一个提示框,内容为"[object Window]
",而每当用户在页面中点击某物时,会显示另一个提示框,内容为"[object HTMLBodyElement]
"。
函数的返回值会影响事件是否被取消:如上所述,如果返回值为false,事件将被取消。
由于历史原因,平台上有两个例外:
全局对象上的onerror
处理程序,其中返回true会取消事件。
onbeforeunload
处理程序,其中返回任何非null和非undefined的值都会取消事件。
由于历史原因,onerror
处理程序有不同的参数:
[LegacyTreatNonObjectAsNull ]
callback OnErrorEventHandlerNonNull = any ((Event or DOMString ) event , optional DOMString source , optional unsigned long lineno , optional unsigned long colno , optional any error );
typedef OnErrorEventHandlerNonNull ? OnErrorEventHandler ;
window. onerror = ( message, source, lineno, colno, error) => { … };
同样,onbeforeunload
处理程序的返回值也不同:
[LegacyTreatNonObjectAsNull ]
callback OnBeforeUnloadEventHandlerNonNull = DOMString ? (Event event );
typedef OnBeforeUnloadEventHandlerNonNull ? OnBeforeUnloadEventHandler ;
内部原始未编译处理程序是一个包含以下信息的元组:
未编译的脚本体
脚本体来源的位置,以便在需要报告错误时使用
当用户代理要获取事件处理程序的当前值,给定一个EventTarget
对象eventTarget和一个表示事件处理程序名称的字符串name,必须运行以下步骤:
获取eventTarget的事件处理程序映射,并将结果赋给handlerMap。
通过handlerMap[name]获取eventHandler。
如果eventHandler的值是内部原始未编译处理程序,则:
如果 eventTarget 是一个元素,那么将 element 设为 eventTarget,并将 document
设为
element 的节点文档。否则,eventTarget 是一个 Window
对象,将
element 设为 null,并将 document 设为 eventTarget 的 关联的
Document
。
如果 禁用了脚本 对于 document,则返回 null。
将 body 设为 eventHandler 的 值中的未编译脚本体。
将 location 设为脚本体的来源位置,如 由 eventHandler 的 值给出。
如果 element 不为 null 且 element 有 表单所有者, 则将 form owner 设为该 表单所有者。 否则,将 form owner 设为 null。
将 settings object 设为 document 的 相关设置对象。
如果 body 无法解析为 FunctionBody 或者如果解析时检测到 早期错误,则按照以下子步骤进行:
将 settings object 的 领域执行上下文推入 JavaScript 执行上下文堆栈;它现在是 正在运行的 JavaScript 执行上下文。
这是必要的,因此随后的 OrdinaryFunctionCreate 调用会在正确的 领域中进行。
将 function 设为调用 OrdinaryFunctionCreate 的结果,传入的参数如下:
将 realm 设为 settings object 的 领域。
将 scope 设为 realm 的[[GlobalEnv]]。
如果 eventHandler 是一个元素的 事件 处理程序,则将 scope 设为 NewObjectEnvironment(document, true, scope)。
如果 form owner 不为 null,则将 scope 设为 NewObjectEnvironment(form owner, true, scope)。
如果 element 不为 null,则将 scope 设为 NewObjectEnvironment(element, true, scope)。
返回 scope。
从 settings object 的 领域执行上下文中移除 JavaScript 执行上下文堆栈。
将 function 的[[ScriptOrModule]]设为 null。
这样做是因为默认行为,即将创建的函数与堆栈上最近的 脚本相关联,可能会导致路径依赖的结果。例如,由用户交互首次调用的事件处理程序将最终得到 null [[ScriptOrModule]](因为在这种情况下,当活动脚本为 null 时,该算法将首次调用),而由脚本分派事件首次调用的处理程序则会将其 [[ScriptOrModule]] 设置为该脚本。
相反,我们始终将 [[ScriptOrModule]] 设为 null。这反而更加直观;第一个分派事件的脚本应对事件处理程序代码负责的想法是可疑的。
实际上,这仅影响通过 import()
解析相对 URL, 它会查找关联脚本的 基本 URL。将 [[ScriptOrModule]] 设为 null 意味着 HostLoadImportedModule 将
回退到 当前设置对象
的
API 基本
URL。
将 eventHandler 的 值 设为创建一个 Web IDL EventHandler
回调函数对象的结果,该对象的引用为 function,其 回调上下文
为
settings
object。
返回eventHandler的值。
Document
对象和Window
对象上的事件处理程序以下是所有事件处理程序(及其对应的事件处理程序事件类型)必须由所有HTML
元素支持,既作为事件处理程序内容属性,也作为事件处理程序IDL属性;还必须由所有Document
和Window
对象支持,作为事件处理程序IDL属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onabort
支持所有当前的引擎。 Firefox9+Safari3.1+Chrome3+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
abort
|
onauxclick
Firefox53+Safari不支持Chrome55+
Opera?Edge79+ Edge (旧版)?Internet Explorer不支持 Firefox Android53+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
auxclick
|
onbeforeinput |
beforeinput
|
onbeforematch |
beforematch
|
onbeforetoggle |
beforetoggle
|
oncancel
HTMLDialogElement/cancel_event 支持所有当前的引擎。 Firefox98+Safari15.4+Chrome37+
Opera?Edge79+ Edge (旧版)?Internet Explorer不支持 Firefox Android?Safari iOS?Chrome Android不支持WebView Android?Samsung Internet?Opera Android? |
cancel
|
oncanplay
HTMLMediaElement/canplay_event 支持所有当前的引擎。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
canplay
|
oncanplaythrough
HTMLMediaElement/canplaythrough_event 支持所有当前的引擎。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
canplaythrough
|
onchange
支持所有当前的引擎。 Firefox1+Safari3+Chrome1+
Opera9+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+ |
change
|
onclick
支持所有当前的引擎。 Firefox6+Safari3+Chrome1+
Opera11.6+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android6+Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
click
|
onclose |
close
|
oncontextlost |
contextlost
|
oncontextmenu |
contextmenu
|
oncontextrestored |
contextrestored
|
oncopy
支持所有当前的引擎。 Firefox22+Safari3+Chrome1+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
copy
|
oncuechange
HTMLTrackElement/cuechange_event 支持所有当前的引擎。 Firefox68+Safari10+Chrome32+
Opera19+Edge79+ Edge (旧版)14+Internet Explorer不支持 Firefox Android?Safari iOS?Chrome Android?WebView Android4.4.3+Samsung Internet?Opera Android19+ |
cuechange
|
oncut
支持所有当前的引擎。 Firefox22+Safari3+Chrome1+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
cut
|
ondblclick
所有当前引擎均支持。 Firefox6+Safari3+Chrome1+
Opera11.6+Edge79+ Edge (旧版)12+Internet Explorer8+ Firefox Android6+Safari iOS1+Chrome Android不支持WebView Android?Samsung Internet?Opera Android12.1+ |
dblclick
|
ondrag |
drag
|
ondragend |
dragend
|
ondragenter |
dragenter
|
ondragleave |
dragleave
|
ondragover |
dragover
|
ondragstart |
dragstart
|
ondrop |
drop
|
ondurationchange
HTMLMediaElement/durationchange_event 所有当前引擎均支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
durationchange
|
onemptied
HTMLMediaElement/emptied_event 所有当前引擎均支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
emptied
|
onended
所有当前引擎均支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
ended
|
onformdata |
formdata
|
oninput
所有当前引擎均支持。 Firefox6+Safari3.1+Chrome1+
Opera11.6+Edge79+ Edge (旧版)不支持Internet Explorer🔰 9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
input
|
oninvalid |
invalid
|
onkeydown
所有当前引擎均支持。 Firefox6+Safari1.2+Chrome1+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
keydown
|
onkeypress |
keypress
|
onkeyup
所有当前引擎均支持。 Firefox6+Safari1.2+Chrome1+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
keyup
|
onloadeddata
HTMLMediaElement/loadeddata_event 所有当前引擎均支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
loadeddata
|
onloadedmetadata
HTMLMediaElement/loadedmetadata_event 所有当前引擎均支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
loadedmetadata
|
onloadstart
HTMLMediaElement/loadstart_event 所有当前引擎均支持。 Firefox6+Safari4+Chrome3+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
loadstart
|
onmousedown
所有当前引擎均支持。 Firefox6+Safari4+Chrome2+
Opera11.6+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+ |
mousedown
|
onmouseenter
所有当前引擎均支持。 Firefox10+Safari7+Chrome30+
Opera?Edge79+ Edge (旧版)12+Internet Explorer5.5+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
mouseenter
|
onmouseleave
所有当前引擎均支持。 Firefox10+Safari7+Chrome30+
Opera?Edge79+ Edge (旧版)12+Internet Explorer5.5+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
mouseleave
|
onmousemove
所有当前引擎均支持。 Firefox6+Safari4+Chrome2+
Opera11.6+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+ |
mousemove
|
onmouseout
所有当前引擎均支持。 Firefox6+Safari1+Chrome1+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+ |
mouseout
|
onmouseover
所有当前引擎均支持。 Firefox6+Safari4+Chrome2+
Opera9.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+ |
mouseover
|
onmouseup
所有当前引擎均支持。 Firefox6+Safari4+Chrome2+
Opera11.6+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS? Chrome Android ?WebView Android37+Samsung Internet?Opera Android12.1+ |
mouseup
|
onpaste
所有当前引擎均支持。 Firefox22+Safari3+Chrome1+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+ |
paste
|
onpause
所有当前引擎均支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
pause
|
onplay
所有当前引擎均支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
play
|
onplaying
HTMLMediaElement/playing_event 所有当前引擎均支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
playing
|
onprogress
HTMLMediaElement/progress_event 所有当前引擎均支持。 Firefox6+Safari3.1+Chrome3+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
progress
|
onratechange
HTMLMediaElement/ratechange_event 所有当前引擎均支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
ratechange
|
onreset |
reset
|
onscrollend
Firefox109+SafariNoChrome114+
Opera?Edge114+ Edge (旧版)?Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? Firefox109+SafariNoChrome114+
Opera?Edge114+ Edge (旧版)?Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
scrollend
|
onsecuritypolicyviolation
Element/securitypolicyviolation_event 所有当前引擎均支持。 Firefox63+Safari10+Chrome41+
Opera?Edge79+ Edge (旧版)15+Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
securitypolicyviolation
|
onseeked
所有当前引擎均支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
seeked
|
onseeking
HTMLMediaElement/seeking_event 所有当前引擎均支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
seeking
|
onselect
所有当前引擎均支持。 Firefox6+Safari1+Chrome1+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ HTMLTextAreaElement/select_event 所有当前引擎均支持。 Firefox6+Safari1+Chrome1+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
select
|
onslotchange
HTMLSlotElement/slotchange_event 在所有当前引擎中支持。 Firefox63+Safari10.1+Chrome53+
Opera?Edge79+ Edge (旧版)?Internet Explorer不支持 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
slotchange
|
onstalled
HTMLMediaElement/stalled_event 在所有当前引擎中支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
stalled
|
onsubmit
在所有当前引擎中支持。 Firefox1+Safari3+Chrome1+
Opera8+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+ |
submit
|
onsuspend
HTMLMediaElement/suspend_event 在所有当前引擎中支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
suspend
|
ontimeupdate
HTMLMediaElement/timeupdate_event 在所有当前引擎中支持。 Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
timeupdate
|
ontoggle |
toggle
|
onvolumechange
HTMLMediaElement/volumechange_event 在所有当前引擎中支持。 Firefox6+Safari3.1+Chrome3+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+ |
volumechange
|
onwaiting
HTMLMediaElement/waiting_event 在所有当前引擎中支持。 Firefox6+Safari3.1+Chrome3+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+ |
waiting
|
onwebkitanimationend |
webkitAnimationEnd
|
onwebkitanimationiteration |
webkitAnimationIteration
|
onwebkitanimationstart |
webkitAnimationStart
|
onwebkittransitionend |
webkitTransitionEnd
|
onwheel
在所有当前引擎中支持。 Firefox17+Safari7+Chrome31+
Opera?Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS不支持Chrome Android?WebView Android?Samsung Internet?Opera Android? |
wheel
|
以下是必须由所有 事件处理程序(及其对应的 事件处理程序事件类型)支持的
HTML 元素,除了
body
和 frameset
元素之外的所有 HTML 元素,它们必须作为
事件处理程序内容属性和
事件处理程序IDL属性
支持;
必须由所有 Document
对象支持,作为 事件处理程序IDL属性;
必须由所有 Window
对象支持,作为
事件处理程序IDL属性在
Window
对象本身上暴露,并且对应的
事件处理程序内容属性和
事件处理程序IDL属性在
所有由该 Window
对象的
关联的
Document
所拥有的 body
和frameset
元素上暴露:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onblur
在所有当前引擎中均受支持。 Firefox24+Safari3.1+Chrome1+
Opera11.6+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ 在所有当前引擎中均受支持。 Firefox6+Safari5.1+Chrome5+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer11 Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+ |
blur
|
onerror
在所有当前引擎中均受支持。 Firefox6+Safari5.1+Chrome10+
Opera?Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
error
|
onfocus
在所有当前引擎中均受支持。 Firefox24+Safari3.1+Chrome1+
Opera11.6+ Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ 在所有当前引擎中均受支持。 Firefox6+Safari5.1+Chrome5+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer11 Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+ |
focus
|
onload |
load
|
onresize |
resize
|
onscroll
在所有当前引擎中均受支持。 Firefox6+Safari2+Chrome1+
Opera11.6+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+ 在所有当前引擎中均受支持。 Firefox6+Safari1.3+Chrome1+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
scroll
|
我们将本表第一列中列出的集合中的名称称为
Window
反映 body 元素的事件处理程序集合。
以下是必须由Window
对象支持的事件处理程序(及其对应的事件处理程序事件类型),作为事件处理程序
IDL 属性在这些Window
对象上支持,并在所有由该Window
对象的关联
Document
所拥有的body
和frameset
元素上公开相应的事件处理程序内容属性和事件处理程序
IDL 属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onafterprint
在所有当前引擎中均受支持。 Firefox6+Safari13+Chrome63+
Opera?Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
afterprint
|
onbeforeprint
在所有当前引擎中均受支持。 Firefox6+Safari13+Chrome63+
Opera?Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
beforeprint
|
onbeforeunload
在所有当前引擎中均受支持。 Firefox1+Safari3+Chrome1+
Opera12+Edge79+ Edge (旧版)12+Internet Explorer4+ Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
beforeunload
|
onhashchange
在所有当前引擎中均受支持。 Firefox3.6+Safari5+Chrome8+
Opera10.6+Edge79+ Edge (旧版)12+Internet Explorer8+ Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
hashchange
|
onlanguagechange
在所有当前引擎中均受支持。 Firefox32+Safari10.1+Chrome37+
Opera?Edge79+ Edge (旧版)?Internet Explorer不支持 Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet4.0+Opera Android? |
languagechange
|
onmessage
在所有当前引擎中均受支持。 Firefox9+Safari4+Chrome60+
Opera?Edge79+ Edge (旧版)12+Internet Explorer8+ Firefox Android?Safari iOS4+Chrome Android?WebView Android?Samsung Internet?Opera Android47+ |
message
|
onmessageerror
在所有当前引擎中均受支持。 Firefox6+Safari3.1+Chrome3+
Opera11.6+Edge79+ Edge (旧版)12+Internet Explorer 9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ 在所有当前引擎中均受支持。 Firefox57+Safari16.4+Chrome60+
Opera?Edge79+ Edge (旧版)18Internet Explorer不支持 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+ |
messageerror
|
onoffline
在所有当前引擎中均受支持。 Firefox9+Safari4+Chrome3+
Opera?Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
offline
|
ononline
在所有当前引擎中均受支持。 Firefox9+Safari4+Chrome3+
Opera?Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
online
|
onpageswap |
pageswap
|
onpagehide |
pagehide
|
onpagereveal |
pagereveal
|
onpageshow |
pageshow
|
onpopstate
在所有当前引擎中均受支持。 Firefox4+Safari5+Chrome5+
Opera11.5+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11.5+ |
popstate
|
onrejectionhandled
在所有当前引擎中均受支持。 Firefox69+Safari11+Chrome49+
Opera?Edge79+ Edge (旧版)?Internet Explorer不支持 Firefox Android?Safari iOS11.3+Chrome Android?WebView Android?Samsung Internet?Opera Android? |
rejectionhandled
|
onstorage
在所有当前引擎中均受支持。 Firefox45+Safari4+Chrome1+
Opera?Edge79+ Edge (旧版)15+Internet Explorer9+ Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
storage
|
onunhandledrejection
Window/unhandledrejection_event 在所有当前引擎中均受支持。 Firefox69+Safari11+Chrome49+
Opera?Edge79+ Edge (旧版)?Internet Explorer不支持 Firefox Android?Safari iOS11.3+Chrome Android?WebView Android?Samsung Internet?Opera Android? |
unhandledrejection
|
onunload
在所有当前引擎中均受支持。 Firefox1+Safari3+Chrome1+
Opera4+Edge79+ Edge (旧版)12+Internet Explorer4+ Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+ |
unload
|
此事件处理程序列表通过WindowEventHandlers
接口混入的形式,作为事件处理程序IDL属性得以具体化。
以下是必须在Document
对象上支持的事件处理程序(及其对应的事件处理程序事件类型),作为事件处理程序IDL属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onreadystatechange |
readystatechange
|
onvisibilitychange
Document/visibilitychange_event 在所有当前引擎中均受支持。 Firefox56+Safari14.1+Chrome62+
Opera49+Edge79+ Edge (旧版)18Internet Explorer🔰 10+ Firefox Android?Safari iOS?Chrome Android?WebView Android62+Samsung Internet?Opera Android46+ |
visibilitychange
|
interface mixin GlobalEventHandlers {
attribute EventHandler onabort ;
attribute EventHandler onauxclick ;
attribute EventHandler onbeforeinput ;
attribute EventHandler onbeforematch ;
attribute EventHandler onbeforetoggle ;
attribute EventHandler onblur ;
attribute EventHandler oncancel ;
attribute EventHandler oncanplay ;
attribute EventHandler oncanplaythrough ;
attribute EventHandler onchange ;
attribute EventHandler onclick ;
attribute EventHandler onclose ;
attribute EventHandler oncontextlost ;
attribute EventHandler oncontextmenu ;
attribute EventHandler oncontextrestored ;
attribute EventHandler oncopy ;
attribute EventHandler oncuechange ;
attribute EventHandler oncut ;
attribute EventHandler ondblclick ;
attribute EventHandler ondrag ;
attribute EventHandler ondragend ;
attribute EventHandler ondragenter ;
attribute EventHandler ondragleave ;
attribute EventHandler ondragover ;
attribute EventHandler ondragstart ;
attribute EventHandler ondrop ;
attribute EventHandler ondurationchange ;
attribute EventHandler onemptied ;
attribute EventHandler onended ;
attribute OnErrorEventHandler onerror ;
attribute EventHandler onfocus ;
attribute EventHandler onformdata ;
attribute EventHandler oninput ;
attribute EventHandler oninvalid ;
attribute EventHandler onkeydown ;
attribute EventHandler onkeypress ;
attribute EventHandler onkeyup ;
attribute EventHandler onload ;
attribute EventHandler onloadeddata ;
attribute EventHandler onloadedmetadata ;
attribute EventHandler onloadstart ;
attribute EventHandler onmousedown ;
[LegacyLenientThis ] attribute EventHandler onmouseenter ;
[LegacyLenientThis ] attribute EventHandler onmouseleave ;
attribute EventHandler onmousemove ;
attribute EventHandler onmouseout ;
attribute EventHandler onmouseover ;
attribute EventHandler onmouseup ;
attribute EventHandler onpaste ;
attribute EventHandler onpause ;
attribute EventHandler onplay ;
attribute EventHandler onplaying ;
attribute EventHandler onprogress ;
attribute EventHandler onratechange ;
attribute EventHandler onreset ;
attribute EventHandler onresize ;
attribute EventHandler onscroll ;
attribute EventHandler onscrollend ;
attribute EventHandler onsecuritypolicyviolation ;
attribute EventHandler onseeked ;
attribute EventHandler onseeking ;
attribute EventHandler onselect ;
attribute EventHandler onslotchange ;
attribute EventHandler onstalled ;
attribute EventHandler onsubmit ;
attribute EventHandler onsuspend ;
attribute EventHandler ontimeupdate ;
attribute EventHandler ontoggle ;
attribute EventHandler onvolumechange ;
attribute EventHandler onwaiting ;
attribute EventHandler onwebkitanimationend ;
attribute EventHandler onwebkitanimationiteration ;
attribute EventHandler onwebkitanimationstart ;
attribute EventHandler onwebkittransitionend ;
attribute EventHandler onwheel ;
};
interface mixin WindowEventHandlers {
attribute EventHandler onafterprint ;
attribute EventHandler onbeforeprint ;
attribute OnBeforeUnloadEventHandler onbeforeunload ;
attribute EventHandler onhashchange ;
attribute EventHandler onlanguagechange ;
attribute EventHandler onmessage ;
attribute EventHandler onmessageerror ;
attribute EventHandler onoffline ;
attribute EventHandler ononline ;
attribute EventHandler onpagehide ;
attribute EventHandler onpagereveal ;
attribute EventHandler onpageshow ;
attribute EventHandler onpageswap ;
attribute EventHandler onpopstate ;
attribute EventHandler onrejectionhandled ;
attribute EventHandler onstorage ;
attribute EventHandler onunhandledrejection ;
attribute EventHandler onunload ;
};
某些操作和方法定义为在元素上触发事件。例如,click()
方法在
HTMLElement
接口中定义为在元素上触发click
事件。[UIEVENTS]
触发名为e的合成指针事件在target上,带有可选的not trusted flag,意味着执行以下步骤:
使用PointerEvent
创建一个event。
将event的type
属性初始化为e。
将event的bubbles
和cancelable
属性初始化为true。
设置event的composed flag。
如果设置了not trusted flag,将event的isTrusted
属性初始化为false。
根据当前按键输入设备的状态(如果有的话),初始化event的ctrlKey
、shiftKey
、altKey
和metaKey
属性(对于不可用的按键则为false)。
event的getModifierState()
方法应返回适当描述当前按键输入设备状态的值。
返回在target上分派event的结果。
触发click
事件
在target上意味着在target上触发一个名为click
的合成指针事件。
WindowOrWorkerGlobalScope
混入WindowOrWorkerGlobalScope
混入用于那些要暴露在Window
和WorkerGlobalScope
对象上的 API。
鼓励其他标准使用partial
interface mixin WindowOrWorkerGlobalScope { … };
以及适当的引用来进一步扩展它。
typedef (DOMString or Function or TrustedScript ) TimerHandler ;
interface mixin WindowOrWorkerGlobalScope {
[Replaceable ] readonly attribute USVString origin ;
readonly attribute boolean isSecureContext ;
readonly attribute boolean crossOriginIsolated ;
undefined reportError (any e );
// base64 utility methods
DOMString btoa (DOMString data );
ByteString atob (DOMString data );
// timers
long setTimeout (TimerHandler handler , optional long timeout = 0, any ... arguments );
undefined clearTimeout (optional long id = 0);
long setInterval (TimerHandler handler , optional long timeout = 0, any ... arguments );
undefined clearInterval (optional long id = 0);
// microtask queuing
undefined queueMicrotask (VoidFunction callback );
// ImageBitmap
Promise <ImageBitmap > createImageBitmap (ImageBitmapSource image , optional ImageBitmapOptions options = {});
Promise <ImageBitmap > createImageBitmap (ImageBitmapSource image , long sx , long sy , long sw , long sh , optional ImageBitmapOptions options = {});
// structured cloning
any structuredClone (any value , optional StructuredSerializeOptions options = {});
};
Window includes WindowOrWorkerGlobalScope ;
WorkerGlobalScope includes WindowOrWorkerGlobalScope ;
self.isSecureContext
在所有当前引擎中均受支持。
返回此全局对象是否表示安全上下文。 [SECURE-CONTEXTS]
self.origin
在所有当前引擎中均受支持。
返回全局对象的来源,并序列化为字符串。
self.crossOriginIsolated
在所有当前引擎中均受支持。
返回在此全局范围内运行的脚本是否被允许使用需要跨源隔离的 API。这取决于 `Cross-Origin-Opener-Policy
`
和 `Cross-Origin-Embedder-Policy
`
HTTP 响应头以及“cross-origin-isolated
”功能。
强烈建议开发者使用 self.origin
而不是 location.origin
。前者返回环境的来源,后者则返回环境的 URL
的来源。想象以下脚本在https://stargate.example/
上的文档中执行:
var frame = document. createElement( "iframe" )
frame. onload = function () {
var frameWin = frame. contentWindow
console. log( frameWin. location. origin) // "null"
console. log( frameWin. origin) // "https://stargate.example"
}
document. body. appendChild( frame)
self.origin
是一个更可靠的安全指示器。
isSecureContext
的 getter 步骤是,如果此对象的相关设置对象是安全上下文,则返回
true,否则返回 false。
origin
的
getter 步骤是返回此对象的相关设置对象的来源,并将其序列化。
crossOriginIsolated
的 getter 步骤是返回此对象的相关设置对象的跨源隔离能力。
atob()
和btoa()
方法允许开发者将内容与 base64 编码之间相互转换。
在这些 API 中,出于记忆的目的,可以将 "b" 视为代表 "binary"(二进制),将 "a" 视为代表 "ASCII"。不过,在实际操作中,主要是由于历史原因,这些函数的输入和输出都是 Unicode 字符串。
result = self.btoa(data)
在所有当前引擎中均受支持。
将输入数据(格式为只包含 U+0000 到 U+00FF 范围内字符的 Unicode 字符串,每个字符分别表示一个二进制字节,值为 0x00 到 0xFF)转换为其 base64 表示,并返回该表示。
如果输入字符串包含任何超出范围的字符,则抛出DOMException
异常,异常名为"InvalidCharacterError"
。
result = self.atob(data)
在所有当前引擎中均受支持。
将输入数据(格式为包含 base64 编码的二进制数据的 Unicode 字符串)解码,并返回一个包含 U+0000 到 U+00FF 范围内字符的字符串,每个字符分别表示一个二进制字节,值为 0x00 到 0xFF,对应于该二进制数据。
如果输入字符串不是有效的 base64 数据,则抛出DOMException
异常,异常名为"InvalidCharacterError"
。
btoa(data)
方法在data包含任何代码点大于 U+00FF
的字符时,必须抛出DOMException
异常,异常名为"InvalidCharacterError"
。否则,用户代理必须将data转换为一个字节序列,其中第n个字节是data的第n个代码点的八位表示,然后必须对该字节序列应用宽容的 base64 编码并返回结果。
atob(data)
方法的步骤如下:
让decodedData成为在data上运行宽容的 base64 解码的结果。
如果decodedData失败,则抛出DOMException
异常,异常名为"InvalidCharacterError"
。
返回decodedData。
用于动态插入标记到文档中的 API 会与解析器交互,因此它们的行为会根据它们是与HTML 文档(以及HTML 解析器)还是XML 文档(以及XML 解析器)一起使用而有所不同。
Document
对象有一个动态标记插入计数器,该计数器与为令牌创建一个元素算法一起使用,以防止自定义元素构造函数在由解析器调用时使用document.open()
、document.close()
和document.write()
。最初,计数器必须设置为零。
document = document.open()
所有当前引擎都支持。
导致Document
原地替换,就像它是一个新的Document
对象,但重用之前的对象,然后返回该对象。
生成的Document
具有与其关联的HTML解析器,可以使用document.write()
提供数据进行解析。
如果Document
仍在解析中,则该方法无效。
如果Document
是XML文档,则抛出DOMException
异常,"InvalidStateError
"。
如果解析器当前正在执行自定义元素构造函数,则抛出DOMException
异常,"InvalidStateError
"。
window = document.open(url, name, features)
类似于window.open()
方法。
Document
对象有一个活动解析器被中止的布尔值,该值用于防止脚本在文档的活动解析器被中止后调用document.open()
和document.write()
方法(直接或间接)。它最初为false。
document open步骤,给定document,如下:
如果document是XML文档,则抛出DOMException
异常,"InvalidStateError
"。
如果document的动态标记插入计数器大于0,则抛出DOMException
异常,"InvalidStateError
"。
让entryDocument成为入口全局对象的关联的Document
。
如果document的源与entryDocument的源不是同源,则抛出DOMException
异常,"SecurityError
"。
如果document的活动解析器的 脚本嵌套级别大于0,则返回document。
这基本上会导致在解析过程中调用的内联脚本中的document.open()
被忽略,但仍允许它在从非解析器任务(例如计时器回调或事件处理程序)调用时生效。
同样地,如果document的卸载计数器大于0,则返回document。
这基本上会导致在beforeunload
、pagehide
或unload
事件处理程序中调用document.open()
时被忽略,而文档正在卸载中。
如果document的活动解析器被中止为true,则返回document。
这特别会导致在导航开始后(但仅在初始解析期间)调用的document.open()
被忽略。有关更多背景,请参见issue #4723。
如果document的节点可导航非null,并且document的节点可导航的正在进行的导航是导航ID,则停止加载document的节点可导航。
对于document的每个包含阴影的包容性后代node,请根据node执行删除所有事件监听器和处理程序。
如果document是document的相关全局对象的关联Document
,则根据document的相关全局对象执行删除所有事件监听器和处理程序。
替换所有元素为null在document中。
如果document是完全活动的,则:
让newURL成为entryDocument的URL的副本。
如果entryDocument不是document,则将newURL的片段设置为null。
使用document和newURL运行URL和历史记录更新步骤。
将document的是否为初始about:blank
设置为false。
如果document的iframe加载进行中标志已设置,则设置document的静音iframe加载标志。
将document设置为非怪癖模式。
创建一个新的HTML解析器并将其与document关联。这是一个脚本创建的解析器(这意味着它可以通过document.open()
和document.close()
方法关闭,并且在发出结束标记之前,标记器将等待显式调用document.close()
)。编码置信度是无关紧要的。
将插入点设置为指向输入流结束之前的位置(此时输入流将为空)。
更新当前文档准备状态为"loading
"。
这会触发readystatechange
事件,但由于前一步删除了所有事件监听器和处理程序,该事件实际上对作者代码是不可观察的。
返回document。
document
open步骤不会影响Document
是否准备好进行加载后任务或完全加载。
open(unused1, unused2)
方法必须返回使用this执行document
open步骤的结果。
unused1和unused2参数被忽略,但保留在IDL中,以允许调用该函数并传递一个或两个参数的代码继续工作。它们是必要的,因为Web IDL重载解析算法规则,如果没有这些参数,这种调用会引发TypeError
异常。whatwg/webidl issue #581正在调查更改算法以允许其移除。[WEBIDL]
open(url, name, features)
方法必须执行以下步骤:
如果this不是完全活动的,则抛出DOMException
异常,"InvalidAccessError
"。
返回使用url、name和features执行window open步骤的结果。
document.close()
支持所有当前引擎。
关闭由document.open()
方法打开的输入流。
如果Document
是XML文档
,则抛出"InvalidStateError
"DOMException
异常。
如果解析器当前正在执行自定义元素构造函数
,则抛出"InvalidStateError
"DOMException
异常。
close()
方法必须执行以下步骤:
如果this
是XML文档
,则抛出"InvalidStateError
"DOMException
异常。
如果this
的动态标记插入计数器
大于零,则抛出"InvalidStateError
"DOMException
异常。
在解析器的输入流
末尾插入一个显式的"EOF"字符
。
运行标记器,处理生成的标记,直到标记器到达显式的"EOF"字符
或旋转事件循环
。
document.write()
document.write(...text)
支持所有当前引擎。
通常情况下,将给定的字符串添加到Document
的输入流中。
此方法的行为非常特殊。在某些情况下,当解析器运行时,此方法可能会影响HTML解析器
的状态,导致DOM与文档源不符(例如,如果写入的字符串是
"<plaintext>
" 或 "<!--
")。在其他情况下,调用此方法可能会先清除当前页面,就像调用了document.open()
一样。在更多的情况下,此方法只是被忽略,或者抛出异常。用户代理明确允许避免执行通过此方法插入的
。更糟糕的是,这种方法的确切行为在某些情况下可能依赖于网络延迟,这可能导致非常难以调试的故障。由于所有这些原因,强烈建议不要使用此方法。
script
元素
在XML文档
上调用时,抛出"InvalidStateError
"DOMException
异常。
如果解析器当前正在执行自定义元素构造函数
,则抛出"InvalidStateError
"DOMException
异常。
此方法不执行任何清理操作来移除潜在危险的元素和属性,如script
或事件处理程序内容属性
。
Document
对象有一个忽略破坏性写入计数器
,它与script
元素的处理结合使用,防止外部脚本使用document.write()
通过隐式调用document.open()
来摧毁文档。最初,计数器必须设置为零。
document 写入步骤,给定一个 Document
对象
document、
一个列表 text、一个布尔值 lineFeed 和一个字符串 sink,步骤如下:
令 string 为空字符串。
如果 text 包含 字符串,则令 isTrusted 为 false;否则为 true。
对于每个 text 的 value:
如果 value 是一个 TrustedHTML
对象,则将 value 关联的 数据 追加到
string。
否则,将 value 追加到 string。
如果 isTrusted 为 false,则将 string 设置为调用
获取可信类型兼容字符串 算法的结果,使用
TrustedHTML
、
此对象 的 相关全局对象、string、sink 和
"script
"。
如果 lineFeed 为 true,则将 U+000A LINE FEED 追加到 string。
如果 document 是一个 XML 文档,则抛出
"InvalidStateError
" DOMException
。
如果 document 的 动态标记插入计数器
大于 0,则抛出 "InvalidStateError
"
DOMException
。
如果 document 的 活动解析器被中止 为 true,则返回。
如果 插入点 未定义,则:
如果 document 的 卸载计数器 大于 0 或 document 的 忽略破坏性写入计数器 大于 0,则返回。
运行 document 打开步骤,使用 document。
如果 document 的 待处理的阻塞脚本 为空,则让
HTML 解析器
逐个代码点处理 string,在标记化器到达插入点时或当标记化器的处理被树结构构造阶段中止时(这种情况可能发生在
如果标记化器发出了一个 script
结束标签标记)停止。
如果 document.write()
方法是从内联执行的脚本调用的(即由于解析器解析了一组
script
标签而执行),那么这是一个解析器的重入调用。如果 解析器暂停标志 被设置,标记化器将立即中止,且不会解析任何 HTML,根据标记化器的 解析器暂停标志检查。
document.write(...text)
方法步骤是
运行 document
写入步骤,使用 此对象、text、false 和
"Document write
"。
document.writeln()
document.writeln(...text)
支持所有当前引擎。
将给定的字符串添加到Document
的输入流中,并在后面加上一个换行符。如果需要,首先会隐式调用open()
方法。
在XML文档
上调用时,抛出"InvalidStateError
"DOMException
异常。
如果解析器当前正在执行自定义元素构造函数
,则抛出"InvalidStateError
"DOMException
异常。
此方法不执行任何清理操作来移除潜在危险的元素和属性,如script
或事件处理程序内容属性
。
document.writeln(...text)
方法步骤是
运行 document
写入步骤,使用 此对象、text、true 和
"Document writeln
"。
支持所有当前引擎。
partial interface Element {
[CEReactions ] undefined setHTMLUnsafe ((TrustedHTML
or DOMString ) html );
DOMString getHTML (optional GetHTMLOptions options = {});
[CEReactions ] attribute (TrustedHTML
or [LegacyNullToEmptyString ] DOMString ) innerHTML ;
[CEReactions ] attribute (TrustedHTML
or [LegacyNullToEmptyString ] DOMString ) outerHTML ;
[CEReactions ] undefined insertAdjacentHTML (DOMString position , (TrustedHTML
or DOMString ) string );
};
partial interface ShadowRoot {
[CEReactions ] undefined setHTMLUnsafe ((TrustedHTML
or DOMString ) html );
DOMString getHTML (optional GetHTMLOptions options = {});
[CEReactions ] attribute (TrustedHTML
or [LegacyNullToEmptyString ] DOMString ) innerHTML ;
};
dictionary GetHTMLOptions {
boolean serializableShadowRoots = false ;
sequence <ShadowRoot > shadowRoots = [];
};
DOMParser
接口DOMParser
接口允许开发者通过解析字符串(作为 HTML 或 XML)创建新的 Document
对象。
parser = new DOMParser()
支持所有当前引擎。
构造一个新的 DOMParser
对象。
document = parser.parseFromString(string, type)
支持所有当前引擎。
根据 type,使用 HTML 或 XML 解析器解析 string,并返回生成的 Document
。type
可以是 "text/html
"(将调用
HTML 解析器),或者是 "text/xml
"、"application/xml
"、"application/xhtml+xml
"
或 "image/svg+xml
"(将调用
XML 解析器)。
对于 XML 解析器,如果 string 无法解析,返回的 Document
将包含描述结果错误的元素。
请注意,script
元素在解析过程中不会执行,解析结果文档的 编码将始终为 UTF-8。文档的 URL
将继承自 parser 的 相关全局对象。
type 的其他值将导致抛出 TypeError
异常。
DOMParser
的设计,作为一个需要构建然后调用其 parseFromString()
方法的类,是一个不幸的历史遗留问题。如果我们今天设计这个功能,它将是一个独立的函数。对于解析 HTML,现代的替代方法是 Document.parseHTMLUnsafe()
。
此方法不会对潜在危险的元素和属性(如 script
或 事件处理程序内容属性)进行任何清理。
[Exposed =Window ]
interface DOMParser {
constructor ();
[NewObject ] Document
parseFromString ((TrustedHTML
or DOMString ) string , DOMParserSupportedType type );
};
enum DOMParserSupportedType {
" text/html " ,
" text/xml " ,
" application/xml " ,
" application/xhtml+xml " ,
" image/svg+xml "
};
new DOMParser()
构造函数的步骤是不执行任何操作。
parseFromString(string, type)
方法的步骤如下:
调用 获取受信任类型兼容字符串
算法,传入 TrustedHTML
、this
的 相关全局对象、string、"DOMParser parseFromString
"
和 "script
",并将结果存储在 compliantString 中。
创建一个新的 Document
对象,内容类型 为 type,URL
为 this 的 相关全局对象 的 关联的
Document
的 URL。
文档的 编码 将保留为默认的 UTF-8。特别是,解析
compliantString 时找到的任何 XML 声明或 meta
元素都不会有任何效果。
根据 type 切换:
text/html
"根据 document 和 compliantString 执行 从字符串解析 HTML。
返回 document。
要从字符串解析 HTML,给定一个 Document
document 和一个 字符串 html:
将 document 的 类型 设置为
"html
"。
创建一个与 document 关联的 HTML 解析器 parser。
启动 parser,让它运行直到消耗掉刚刚插入输入流中的所有字符。
这可能会改变文档的 模式。
element.setHTMLUnsafe(html)
使用HTML解析器解析html,并用结果替换element的子元素。element为HTML解析器提供上下文。
shadowRoot.setHTMLUnsafe(html)
使用HTML解析器解析html,并用结果替换shadowRoot的子元素。shadowRoot的宿主为HTML解析器提供上下文。
doc = Document.parseHTMLUnsafe(html)
使用HTML解析器解析html,并返回生成的Document
。
注意,解析过程中不会执行script
元素,并且生成的文档的编码将始终为UTF-8。文档的URL将为about:blank
。
这些方法不执行任何清理操作以移除可能危险的元素和属性,如script
或事件处理程序内容属性。
Element
的setHTMLUnsafe(html)
方法的步骤如下:
调用获取受信任类型兼容字符串算法,传入TrustedHTML
、this的相关全局对象、html、"Element setHTMLUnsafe
"和"script
",并将结果存储在compliantHTML中。
给定target、this和compliantHTML,不安全地设置HTML。
ShadowRoot
的setHTMLUnsafe(html)
方法的步骤如下:
调用获取受信任类型兼容字符串算法,传入TrustedHTML
、this的相关全局对象、html、"ShadowRoot setHTMLUnsafe
"和"script
",并将结果存储在compliantHTML中。
给定this、this的shadow宿主和compliantHTML,不安全地设置HTML。
给定一个Element
或DocumentFragment
target、一个Element
contextElement,以及一个字符串html,不安全地设置HTML:
给定contextElement、html和true,使用HTML片段解析算法获取newChildren。
创建一个新的DocumentFragment
,其节点文档为contextElement的节点文档,并将其存储在fragment中。
对于newChildren中的每个node,将其追加到fragment中。
替换所有使用fragment来替换target中的所有内容。
静态的parseHTMLUnsafe(html)
方法的步骤如下:
调用获取受信任类型兼容字符串算法,传入TrustedHTML
、this的相关全局对象、html、"Document parseHTMLUnsafe
"和"script
",并将结果存储在compliantHTML中。
将document的允许声明性Shadow根设置为true。
给定document和compliantHTML,从字符串解析HTML。
返回document。
html = element.getHTML({ serializableShadowRoots, shadowRoots })
返回将element序列化为HTML的结果。element中的Shadow根将根据提供的选项进行序列化:
如果serializableShadowRoots
为true,则所有标记为可序列化的Shadow根将被序列化。
如果提供了shadowRoots
数组,则数组中指定的所有Shadow根将被序列化,无论它们是否被标记为可序列化。
如果未提供任何选项,则不序列化任何Shadow根。
html = shadowRoot.getHTML({ serializableShadowRoots, shadowRoots })
返回将shadowRoot序列化为HTML的结果,并使用其Shadow宿主作为上下文元素。shadowRoot中的Shadow根将根据上述提供的选项进行序列化。
Element
的getHTML(options)
方法的步骤如下:
返回HTML片段序列化算法的结果,传入this、options["serializableShadowRoots
"]和options["shadowRoots
"]。
ShadowRoot
的getHTML(options)
方法的步骤如下:
返回HTML片段序列化算法的结果,传入this、options["serializableShadowRoots
"]和options["shadowRoots
"]。
innerHTML
属性innerHTML
属性在DOM Parsing and Serialization 问题跟踪器中存在一些未解决的问题,记录了规范中的各种问题。
element.innerHTML
返回表示元素内容的 HTML 或 XML 片段。
在 XML 文档的情况下,如果元素无法序列化为 XML,则抛出 "InvalidStateError
"
DOMException
。
element.innerHTML = value
使用从给定字符串解析的节点替换元素的内容。
在 XML 文档的情况下,如果给定字符串格式不正确,则抛出 "SyntaxError
"
DOMException
。
shadowRoot.innerHTML
返回表示 shadow roots 内容的 HTML 片段。
shadowRoot.innerHTML = value
使用从给定字符串解析的节点替换 shadow root 的内容。
这些属性的设置器不会对潜在危险的元素和属性(如script
或 事件处理程序内容属性)进行消毒。
片段序列化算法步骤,给定
Element
、
Document
或
DocumentFragment
node 和布尔值 require well-formed,步骤如下:
让 context document 成为 node 的 节点文档。
如果 context document 是 HTML 文档,则返回 HTML 片段序列化算法 的结果, 参数为 node、false 和 « »。
返回 XML 序列化 的结果, 参数为 node 和 require well-formed。
片段解析算法步骤,给定
Element
context 和字符串 markup,步骤如下:
令 algorithm 为 HTML 片段解析算法。
如果 context 的 节点文档 是 XML 文档,则将 algorithm 设置为 XML 片段解析算法。
令 new children 为调用 algorithm 的结果,参数为 markup,context 设置为 context。
令 fragment 为一个新的 DocumentFragment
,
其 节点文档 为 context 的 节点文档。
这确保了新节点文档 是正确的。
返回 fragment。
Element
的
innerHTML
获取器
步骤为返回运行 片段序列化算法步骤 的结果,
参数为 this
和 true。
ShadowRoot
的
innerHTML
获取器步骤为返回运行 片段序列化算法步骤 的结果,
参数为 this 和 true。
令 compliantString 为调用 获取受信任类型合规字符串
算法的结果,参数为 TrustedHTML
,
this 的 相关全局对象、给定值、"Element innerHTML
" 和
"script
"。
令 context 为 this。
令 fragment 为调用 片段解析算法步骤 的结果,参数为 context 和 compliantString。
如果 context 是一个 template
元素,则将 context 设置为
template
元素的 模板内容(一个
DocumentFragment
)。
全部替换 context 中的 fragment。
ShadowRoot
的
innerHTML
设置器步骤如下:
令 compliantString 为调用 获取受信任类型合规字符串
算法的结果,参数为 TrustedHTML
,
this 的 相关全局对象、给定值、"ShadowRoot innerHTML
" 和
"script
"。
令 fragment 为调用 片段解析算法步骤 的结果,参数为 context 和 compliantString。
outerHTML
属性outerHTML
属性在DOM Parsing and Serialization 问题跟踪器中存在一些未解决的问题,记录了规范中的各种问题。
element.outerHTML
返回表示元素及其内容的 HTML 或 XML 片段。
在 XML 文档的情况下,如果元素无法序列化为 XML,则抛出 "InvalidStateError
"
DOMException
。
element.outerHTML = value
使用从给定字符串解析的节点替换该元素。
在 XML 文档的情况下,如果给定字符串格式不正确,则抛出 "SyntaxError
"
DOMException
。
如果元素的父节点是Document
,则抛出 "NoModificationAllowedError
" DOMException
。
此属性的设置器不会对潜在危险的元素和属性(如script
或 事件处理程序内容属性)进行消毒。
Element
的
outerHTML
获取器
步骤如下:
令 compliantString 为调用 获取受信任类型合规字符串
算法的结果,参数为 TrustedHTML
,
this 的 相关全局对象、给定值、"Element outerHTML
" 和
"script
"。
如果 parent 为 null,则返回。即使继续执行其余步骤,也无法获得对创建的节点的引用。
如果 parent 是 Document
,则抛出
"NoModificationAllowedError
" DOMException
。
如果 parent 是 DocumentFragment
,
则将 parent 设置为
调用 创建元素 的结果,
参数为 this 的
节点文档、body
和
HTML 命名空间。
令 fragment 为调用 片段解析算法步骤 的结果,参数为 parent 和 compliantString。
insertAdjacentHTML()
方法insertAdjacentHTML()
方法在DOM Parsing and Serialization 问题跟踪器中存在一些未解决的问题,记录了规范中的各种问题。
element.insertAdjacentHTML(position, string)
将string解析为 HTML 或 XML,并将生成的节点插入树中由 position 参数指定的位置,具体如下:
beforebegin
"afterbegin
"beforeend
"afterend
"如果参数值无效(例如,在 XML 文档中,
如果给定的字符串格式不正确),则抛出 "SyntaxError
" DOMException
。
如果给定位置不可行(例如在
Document
的根元素之后插入元素),则抛出
"NoModificationAllowedError
" DOMException
。
此方法不会对潜在危险的元素和属性(如script
或 事件处理程序内容属性)进行消毒。
Element
的
insertAdjacentHTML(position,
string)
方法步骤如下:
令 compliantString 为调用 获取受信任类型合规字符串 算法的结果,参数为 TrustedHTML
,
this 的 相关全局对象、string、"Element insertAdjacentHTML
"
和 "script
"。
令 context 为 null。
使用以下列表中的第一个匹配项:
beforebegin
" 的ASCII
大小写不敏感匹配afterend
" 的ASCII
大小写不敏感匹配如果 context 为 null 或 Document
,则抛出
"NoModificationAllowedError
" DOMException
。
afterbegin
" 的ASCII
大小写不敏感匹配beforeend
" 的ASCII
大小写不敏感匹配如果 context 不是 Element
或满足以下所有条件:
令 fragment 为调用 片段解析算法步骤 的结果,参数为 context 和 compliantString。
beforebegin
" 的ASCII
大小写不敏感匹配afterend
" 的ASCII
大小写不敏感匹配afterbegin
" 的ASCII
大小写不敏感匹配beforeend
" 的ASCII
大小写不敏感匹配与其他直接Node
操作
API(与innerHTML
不同)一样,
insertAdjacentHTML()
不包含任何特殊的
template
元素处理。在大多数情况下,您将希望使用
templateEl.content.insertAdjacentHTML()
,
而不是直接操作template
元素的子节点。
createContextualFragment()
方法createContextualFragment()
方法在DOM Parsing and Serialization 问题跟踪器中存在一些未解决的问题,记录了规范中的各种问题。
docFragment = range.createContextualFragment(string)
返回一个使用range的起始节点作为解析fragment的上下文,从标记字符串string创建的DocumentFragment
。
此方法不会对潜在危险的元素和属性(如script
或 事件处理程序内容属性)进行消毒。
partial interface Range {
[CEReactions , NewObject ] DocumentFragment
createContextualFragment ((TrustedHTML
or DOMString ) string );
};
Range
的
createContextualFragment(string)
方法步骤如下:
令 compliantString 为调用 获取受信任类型合规字符串 算法的结果,参数为 TrustedHTML
、
this 的 相关全局对象、string 和
"RangecreateContextualFragment"
。
令 element 为 null。
如果 element 为 null 或满足以下所有条件:
令 fragment node 为调用 片段解析算法步骤 的结果,参数为 element 和 compliantString。
返回 fragment node。
setTimeout()
和 setInterval()
方法允许作者调度基于定时器的回调函数。
id = self.setTimeout(handler [, timeout [, ...arguments ] ])
在所有当前引擎中支持。
调度一个超时,在 timeout 毫秒后运行 handler。任何 arguments 直接传递给 handler。
id = self.setTimeout(code [, timeout ])
调度一个超时,在 timeout 毫秒后编译并运行 code。
self.clearTimeout(id)
在所有当前引擎中支持。
取消通过 setTimeout()
或 setInterval()
设置的超时,标识符为
id。
id = self.setInterval(handler [, timeout [, ...arguments ] ])
在所有当前引擎中支持。
调度一个超时,每 timeout 毫秒运行一次 handler。任何 arguments 直接传递给 handler。
id = self.setInterval(code [, timeout ])
调度一个超时,每 timeout 毫秒编译并运行 code。
self.clearInterval(id)
在所有当前引擎中支持。
取消通过 setInterval()
或 setTimeout()
设置的超时,标识符为 id。
定时器可以嵌套;然而,在五个嵌套的定时器之后,间隔被强制设置为至少四毫秒。
此 API 不保证定时器会精确按计划运行。由于 CPU 负载、其他任务等原因导致的延迟是可以预期的。
实现 WindowOrWorkerGlobalScope
混合体的对象拥有一个setTimeout 和 setInterval ID 映射,该映射是一个有序映射,初始为空。此映射中的每个键是一个正整数,对应于 setTimeout()
或 setInterval()
调用的返回值。每个值是一个唯一内部值,对应于对象的活动定时器映射中的键。
setTimeout(handler, timeout,
...arguments)
方法步骤是根据定时器初始化步骤的运行结果返回,
其中 this
是handler、timeout、arguments 和 false。
setInterval(handler, timeout,
...arguments)
方法步骤是根据定时器初始化步骤的运行结果返回,
其中 this
是handler、timeout、arguments 和 true。
clearTimeout(id)
和 clearInterval(id)
方法的步骤是移除
此对象的 setTimeout 和
setInterval ID 映射[id]。
由于 clearTimeout()
和 clearInterval()
从同一个映射中清除条目,因此可以使用任一方法来清除由
setTimeout()
或 setInterval()
创建的定时器。
要执行 定时器初始化步骤,给定一个 WindowOrWorkerGlobalScope
对象、一个字符串或 Function
或 TrustedScript
、handler、一个数字
timeout、一个列表 arguments、布尔值 repeat,并可选地(且仅在 repeat 为 true 时)给出数字
previousId,执行以下步骤。这些步骤返回一个数字。
令 thisArg 为 global,如果它是 WorkerGlobalScope
对象;否则,令
thisArg
为与 global 对应的 WindowProxy
。
如果给定了 previousId,则令 id 为 previousId;否则,令 id 为一个 实现定义的 大于零的整数,并且该整数在 global 的 setTimeout 和 setInterval ID 映射中不存在。
如果 周围代理 的 事件循环 的 当前运行任务 是由此算法创建的任务,则令 nesting level 为 任务 的 定时器嵌套级别;否则,令 nesting level 为零。
任务的 定时器嵌套级别 用于嵌套调用 setTimeout()
,以及由 setInterval()
创建的重复定时器。(或者,实际上,对于这两者的任何组合。)换句话说,它表示该算法的嵌套调用,而不是某个特定方法的嵌套调用。
如果 timeout 小于 0,则将 timeout 设置为 0。
如果 nesting level 大于 5,并且 timeout 小于 4,则将 timeout 设置为 4。
令 realm 为 global 的 相关领域。
令 initiating script 为 活动脚本。
令 uniqueHandle 为 null。
令 task 为一个 任务,执行以下子步骤:
如果 id 不在 global 的 setTimeout 和 setInterval ID 映射中 存在,则中止这些步骤。
如果 global 的 setTimeout 和 setInterval ID 映射[id] 不等于 uniqueHandle,则中止这些步骤。
这是为了适应 ID 已被 clearTimeout()
或 clearInterval()
调用清除,并且随后被 setTimeout()
或 setInterval()
调用重用的情况。
记录定时器处理程序的时间信息,给定 handler、global 的 相关设置对象 和 repeat。
如果 handler 是一个 Function
,则
调用
handler,给定 arguments 和 "
report
",并将 回调的 this 值 设置为
thisArg。
否则:
如果未给定 previousId:
如果global是Window
对象,则将globalName设置为"Window
";否则为"Worker
"。
令 methodName 为 "setInterval
",如果 repeat 为 true;否则为
"setTimeout
"。
令 sink 为 globalName、U+0020 空格和 methodName 的连接。
将handler设置为调用获取受信任类型兼容字符串算法的结果,
参数为TrustedScript
、
global、
handler、sink以及"script
"。
断言:handler 是一个字符串。
执行 确保 CSP 不阻止字符串编译(realm, « », handler, handler, timer, « », handler)。如果抛出异常,捕获它,为 global 报告,并中止这些步骤。
令 settings object 为 global 的 相关设置对象。
令 fetch options 为 默认经典脚本获取选项。
令 base URL 为 settings object 的 API 基础 URL。
如果 initiating script 不为 null,则:
将 fetch options 设置为 脚本获取选项,其 加密随机数 为 initiating script 的 获取选项
的
加密随机数,完整性元数据为空字符串,解析器元数据为 "非解析器插入
",凭证模式 为 initiating script 的
获取选项
的 凭证模式,引用者策略 为 initiating
script
的
获取选项 的 引用者策略,获取优先级 为 "自动
"。
将 base URL 设置为 initiating script 的 基础 URL。
这些步骤确保了 setTimeout()
和
setInterval()
执行的字符串编译与 eval()
执行的字符串编译行为一致。也就是说,通过 import()
获取的 模块脚本 在两种上下文中将表现相同。
令 script 为 创建经典脚本的结果,给定 handler、settings object、base URL 和 fetch options。
运行经典脚本 script。
如果 id 不在 global 的 setTimeout 和 setInterval ID 映射中 存在,则中止这些步骤。
如果 global 的 setTimeout 和 setInterval ID 映射[id] 不等于 uniqueHandle,则中止这些步骤。
此 ID 可能已通过 handler 中的作者代码调用 clearTimeout()
或 clearInterval()
被移除。检查
uniqueHandle 是否不同,以防该 ID 在被清除后,被后续的 setTimeout()
或 setInterval()
调用重用。
如果 repeat 为 true,则重新执行 定时器初始化步骤,给定 global、handler、timeout、arguments、true 和 id。
否则,移除 global 的 setTimeout 和 setInterval ID 映射[id]。
递增 nesting level。
将 task 的 定时器嵌套级别 设置为 nesting level。
令 completionStep 为一个算法步骤,它在全局任务队列中排队一个全局任务,给定 global 来运行 task。
将 uniqueHandle 设置为 运行超时后步骤 的结果,给定
global、"setTimeout/setInterval
"、timeout 和 completionStep。
设置 global 的 setTimeout 和 setInterval ID 映射[id] 为 uniqueHandle。
返回 id。
参数转换按 Web IDL 的定义进行(例如,对作为第一个参数传递的对象调用 toString()
方法),
在调用此算法之前,算法在 Web IDL 中定义。
例如,以下相当愚蠢的代码将导致日志包含"ONE TWO
":
var log = '' ;
function logger( s) { log += s + ' ' ; }
setTimeout({ toString: function () {
setTimeout( "logger('ONE')" , 100 );
return "logger('TWO')" ;
} }, 100 );
要在没有任何延迟的情况下连续运行几个毫秒的任务,同时仍然将控制权交还给浏览器,以避免阻塞用户界面(并避免浏览器因占用CPU资源而终止脚本),只需在执行工作之前排队下一个定时器:
function doExpensiveWork() {
var done = false ;
// ...
// this part of the function takes up to five milliseconds
// set done to true if we're done
// ...
return done;
}
function rescheduleWork() {
var id = setTimeout( rescheduleWork, 0 ); // preschedule next iteration
if ( doExpensiveWork())
clearTimeout( id); // clear the timeout if we don't need it
}
function scheduleWork() {
setTimeout( rescheduleWork, 0 );
}
scheduleWork(); // queues a task to do lots of work
实现了WindowOrWorkerGlobalScope
混入的对象拥有一个活动计时器映射,这是一个有序映射,最初为空。此映射中的每个键是一个唯一的内部值,表示一个计时器,每个值是一个DOMHighResTimeStamp
,表示该计时器的到期时间。
要在超时后运行步骤,给定一个WindowOrWorkerGlobalScope
的global,一个字符串orderingIdentifier,一个数字milliseconds,以及一组步骤completionSteps,执行以下步骤。它们返回一个唯一的内部值。
让timerKey成为一个新的唯一的内部值。
让startTime成为给定global的当前高分辨率时间。
并行执行以下步骤:
如果global是一个Window
对象,等待直到global的关联的Document
在接下来的milliseconds毫秒内(不一定是连续的)完全激活。
否则,global是一个WorkerGlobalScope
对象;等待milliseconds毫秒,且此期间worker未被暂停(不一定是连续的)。
等待所有在相同global和orderingIdentifier的上下文中,比当前算法启动得更早且milliseconds小于或等于当前值的算法执行完毕。
可选地,再等待一个实现定义的时间长度。
这允许用户代理根据需要延长超时时间,以优化设备的电源使用。例如,一些处理器有低功耗模式,在这种模式下,计时器的精度会降低;在这些平台上,用户代理可以减缓计时器的执行时间,以适应这种时间表,而不要求处理器使用功耗更高的精确模式。
执行completionSteps。
返回timerKey。
在超时后运行步骤
旨在供其他规范使用,这些规范希望在开发人员指定的超时后执行开发人员提供的代码,类似于setTimeout()
的方式。(请注意,它没有setTimeout()
的嵌套和限制行为。)
这些规范可以选择一个orderingIdentifier,以确保在它们自己的规范超时内的顺序,同时不限制与其他规范超时的顺序。
支持所有当前的引擎。
queueMicrotask(callback)
方法必须
排入一个微任务以调用
callback,使用 « » 和 "report
"。
queueMicrotask()
方法允许开发者在微任务队列中调度回调。这允许他们的代码在JavaScript 执行上下文堆栈下次为空时运行,这发生在所有当前执行的同步 JavaScript
都已完成时。与使用例如setTimeout(f, 0)
的情况不同,这不会将控制权交回事件循环。
开发者应该意识到,调度大量微任务与运行大量同步代码具有相同的性能缺点。两者都会阻止浏览器执行自己的工作,如渲染。在许多情况下,requestAnimationFrame()
或requestIdleCallback()
是更好的选择。特别是,如果目标是在下一个渲染周期之前运行代码,那就是requestAnimationFrame()
的目的。
正如以下示例所示,关于queueMicrotask()
的最佳思考方式是将其视为一种重新安排同步代码的机制,有效地将排队的代码放在当前执行的同步
JavaScript 完成后的立即位置。
使用queueMicrotask()
的最常见原因是创建一致的顺序,即使在信息可同步获取的情况下,也不会引入不必要的延迟。
例如,考虑一个自定义元素触发了一个load
事件,同时维护一个先前加载数据的内部缓存。一个简单的实现可能如下所示:
MyElement. prototype. loadData = function ( url) {
if ( this . _cache[ url]) {
this . _setData( this . _cache[ url]);
this . dispatchEvent( new Event( "load" ));
} else {
fetch( url). then( res => res. arrayBuffer()). then( data => {
this . _cache[ url] = data;
this . _setData( data);
this . dispatchEvent( new Event( "load" ));
});
}
};
然而,这种简单的实现是有问题的,因为它会导致用户体验到不一致的行为。例如,像下面这样的代码
element. addEventListener( "load" , () => console. log( "loaded" ));
console. log( "1" );
element. loadData();
console. log( "2" );
有时会记录 "1, 2, loaded"(如果数据需要获取),而有时会记录 "1, loaded, 2"(如果数据已经缓存)。同样,在调用 loadData()
之后,数据是否已经设置到元素上也是不一致的。
为了获得一致的顺序,可以使用 queueMicrotask()
:
MyElement. prototype. loadData = function ( url) {
if ( this . _cache[ url]) {
queueMicrotask(() => {
this . _setData( this . _cache[ url]);
this . dispatchEvent( new Event( "load" ));
});
} else {
fetch( url). then( res => res. arrayBuffer()). then( data => {
this . _cache[ url] = data;
this . _setData( data);
this . dispatchEvent( new Event( "load" ));
});
}
};
通过实质上将排队的代码重新安排在 JavaScript 执行上下文栈 清空之后,这确保了元素状态的顺序和更新的一致性。
queueMicrotask()
的另一个有趣用法是允许多个调用者进行无协调的“批处理”工作。例如,考虑一个库函数,它希望尽快将数据发送到某个地方,但如果可以轻松避免多次网络请求,它又不想这样做。平衡这一点的一种方法如下:
const queuedToSend = [];
function sendData( data) {
queuedToSend. push( data);
if ( queuedToSend. length === 1 ) {
queueMicrotask(() => {
const stringToSend = JSON. stringify( queuedToSend);
queuedToSend. length = 0 ;
fetch( "/endpoint" , stringToSend);
});
}
}
采用这种架构,在当前执行的同步 JavaScript 中对 sendData()
的多次连续调用将被批处理成一次 fetch()
调用,但没有中间的事件循环任务会抢先执行该 fetch(这在使用 setTimeout()
的类似代码中会发生)。
window.alert(message)
在所有当前引擎中均支持。
显示一个带有给定消息的模态警告框,并等待用户关闭它。
result = window.confirm(message)
在所有当前引擎中均支持。
显示一个带有给定消息的模态确定/取消提示,等待用户关闭它,并在用户点击确定时返回 true,在用户点击取消时返回 false。
result = window.prompt(message [, default])
在所有当前引擎中均支持。
显示一个带有给定消息的模态文本输入提示,等待用户关闭它,并返回用户输入的值。如果用户取消提示,则返回 null。如果提供了第二个参数,则使用给定的值作为默认值。
依赖于任务或微任务的逻辑,例如媒体元素 加载其媒体数据,在调用这些方法时会被暂停。
alert()
和 alert(message)
方法步骤如下:
如果我们无法显示简单对话框,则 返回。
如果该方法是在没有参数的情况下调用的,则令 message 为空字符串;否则,令 message 为该方法的第一个 参数。
将 message 设置为通过给定 message 进行 标准化换行符 的结果。
将 message 设置为通过给定 message 进行 可选地截断 的结果。
向用户显示 message,将 U+000A LF 视为换行符。
调用 WebDriver BiDi
用户提示已打开,使用 此对象、
"alert
" 和 message。
在等待用户确认消息时,可选地暂停。
调用 WebDriver BiDi 用户提示已关闭,使用 此对象 和 true。
由于历史原因,该方法使用了两个重载,而不是使用可选参数。这一实际影响是 alert(undefined)
被视为 alert("undefined")
,但
alert()
被视为
alert("")
。
confirm(message)
方法步骤如下:
如果我们无法显示简单对话框,则 返回 false。
将 message 设置为通过给定 message 进行 标准化换行符 的结果。
将 message 设置为通过给定 message 进行 可选地截断 的结果。
向用户显示 message,将 U+000A LF 视为换行符,并要求用户作出肯定或否定的响应。
调用 WebDriver BiDi
用户提示已打开,使用 此对象、
"confirm
" 和 message。
暂停,直到用户作出肯定或否定的响应。
调用 WebDriver BiDi 用户提示已关闭,使用 此对象, 如果用户作出了肯定响应,则为 true,否则为 false。
如果用户作出了肯定响应,返回 true;否则,用户作出了否定响应: 返回 false。
prompt(message,
default)
方法步骤如下:
如果我们无法显示简单对话框,则 返回 null。
将 message 设置为通过给定 message 进行 标准化换行符 的结果。
将 message 设置为通过给定 message 进行 可选地截断 的结果。
将 default 设置为通过给定 default 进行 可选地截断 的结果。
向用户显示 message,将 U+000A LF 视为换行符,并要求用户作出字符串值的响应或中止。响应必须默认设置为由 default 给定的值。
调用 WebDriver BiDi
用户提示已打开,使用 此对象、
"prompt
"、message 和 default。
暂停,等待用户的响应。
如果用户中止,则令 result 为 null,否则令其为用户作出的响应字符串。
调用 WebDriver BiDi 用户提示已关闭,使用 此对象, 如果 result 为 null,则为 false,否则为 true,和 result。
返回 result。
对于 可选地截断简单对话框字符串 s,返回 s 本身或从 s 派生的更短的字符串。用户代理不应提供显示 s 省略部分的用户界面,因为这使得恶意用户很容易创建类似“重要的安全警告!点击‘显示更多’以查看详细信息!”的对话框。
例如,用户代理可能只想显示消息的前 100 个字符。或者,用户代理可能用“……”替换字符串的中间部分。这些类型的修改在限制不自然的大而可信的系统对话框的滥用潜力方面可能很有用。
我们在以下算法返回 true 时,无法显示简单对话框,针对 Window
的 window:
如果 window 的 相关设置对象 的 源 和 window 的 相关 设置对象 的 顶级源 不为 同 源域,则返回 true。
可选地,返回 true。(例如,用户代理可能会给用户提供忽略所有模态对话框的选项,因此每当调用该方法时将在此步骤中止。)
返回 false。
在所有当前引擎中均支持。
window.print()
提示用户打印页面。
print()
方法步骤如下:
令 document 为 此对象 的 关联的 Document
。
如果 document 不是完全激活的,则返回。
如果 document 的 卸载 计数器大于 0,则 返回。
否则,设置 document 的 加载后打印标志。
每当用户要求获取文档的实体形式(例如打印的副本)或实体形式的表示(例如 PDF 副本)时,用户代理也应运行 打印步骤。
Document
document 的 打印步骤
如下:
用户代理可以向用户显示消息或返回(或两者兼而有之)。
例如,信息亭浏览器可以静默忽略任何对 print()
方法的调用。
例如,移动设备上的浏览器可以检测到附近没有打印机,并在继续提供“保存为 PDF”选项之前显示一条消息。
如果 document 的 活动沙箱标志集 设置了 沙箱化的模态标志,则返回。
如果打印对话框被 Document
的沙箱阻止,
则不会触发 beforeprint
或 afterprint
事件。
用户代理必须触发一个事件,名为 beforeprint
,
在 相关全局对象 以及其中的任何
子导航中。
仅在子导航中触发似乎不正确,可能需要对某些任务进行排队。请参阅 问题 #5096。
beforeprint
事件可用于
注释打印的副本,例如添加文档打印的时间。
用户代理应为用户提供获取 document 的实体形式(或实体形式的表示)的机会。用户代理可以等待用户接受或拒绝后再返回;如果是这样,用户代理必须在方法等待时暂停。即使 用户代理在此时不等待,用户代理也必须在算法的此时点使用相关文档的状态,如果最终创建了备用形式。
用户代理必须触发一个事件,名为 afterprint
,
在 相关全局对象
以及其中的任何
子导航中。
仅在子导航中触发似乎不正确,可能需要对某些任务进行排队。请参阅 问题 #5096。
afterprint
事件可用于
恢复在早期事件中添加的注释,以及显示打印后的用户界面。例如,如果一个页面正在引导用户完成申请住房贷款的步骤,脚本可以在打印表单或其他内容后自动进入下一步。
Navigator
对象在所有当前引擎中均支持。
Navigator
的实例表示用户代理(客户端)的身份和状态。它们还作为一个通用的全局对象,位于本规范和其他规范中的各种 API 之下。
[Exposed =Window ]
interface Navigator {
// objects implementing this interface also implement the interfaces given below
};
Navigator includes NavigatorID ;
Navigator includes NavigatorLanguage ;
Navigator includes NavigatorOnLine ;
Navigator includes NavigatorContentUtils ;
Navigator includes NavigatorCookies ;
Navigator includes NavigatorPlugins ;
Navigator includes NavigatorConcurrentHardware ;
这些接口混入是单独定义的,以便WorkerNavigator
可以重用Navigator
接口的部分内容。
每个Window
都有一个关联的Navigator
,这是一个Navigator
对象。在创建Window
对象时,其关联的Navigator
必须设置为在Window
对象的相关领域中创建的新Navigator
对象。
在所有当前引擎中均支持。
navigator
和clientInformation
的
getter 步骤是返回this的关联的Navigator
。
interface mixin NavigatorID {
readonly attribute DOMString appCodeName ; // constant "Mozilla"
readonly attribute DOMString appName ; // constant "Netscape"
readonly attribute DOMString appVersion ;
readonly attribute DOMString platform ;
readonly attribute DOMString product ; // constant "Gecko"
[Exposed =Window ] readonly attribute DOMString productSub ;
readonly attribute DOMString userAgent ;
[Exposed =Window ] readonly attribute DOMString vendor ;
[Exposed =Window ] readonly attribute DOMString vendorSub ; // constant ""
};
在某些情况下,尽管整个行业都在努力,网页浏览器仍然存在一些缺陷和限制,网页作者不得不采取措施来解决这些问题。
本节定义了一组属性,脚本可以使用这些属性来确定正在使用的用户代理类型,以便绕过这些问题。
用户代理具有 navigator 兼容模式,其值可以是 Chrome、Gecko 或 WebKit。
navigator 兼容模式 将 NavigatorID
混入限制为已知与现有网页内容兼容的属性值组合,以及 taintEnabled()
和 oscpu
的存在与否。
客户端检测应始终仅限于检测已知的当前版本;对于未来版本和未知版本,应始终假设它们完全符合标准。
self.navigator.appCodeName
返回字符串 "Mozilla
"。
self.navigator.appName
返回字符串 "Netscape
"。
self.navigator.appVersion
返回浏览器的版本。
self.navigator.platform
返回平台名称。
self.navigator.product
返回字符串 "Gecko
"。
window.navigator.productSub
返回字符串 "20030107
" 或 "20100101
"。
self.navigator.userAgent
在所有当前引擎中均支持。
返回完整的 `User-Agent
` 头信息。
window.navigator.vendor
返回空字符串,或字符串 "Apple Computer, Inc.
",或字符串 "Google Inc.
"。
window.navigator.vendorSub
返回空字符串。
appCodeName
必须返回字符串 "Mozilla
"。
appName
必须返回字符串 "Netscape
"。
appVersion
必须返回以 "5.0 (
" 开头的适当字符串,如下所示:
让 trail 为 默认
`User-Agent
` 值 中在 "Mozilla/
" 前缀之后的子字符串。
返回 trail。
如果 trail 以 "5.0 (Windows
" 开头,则返回 "5.0 (Windows)
"。
否则,返回 trail 的前缀部分,直到但不包括第一个 U+003B
(;) 为止,并连接字符 U+0029 右括号。例如,"5.0 (Macintosh)
",
"5.0 (Android 10)
" 或 "5.0 (X11)
"。
platform
必须返回表示浏览器正在执行的平台的字符串(例如 "MacIntel
","Win32
",
"Linux x86_64
","Linux armv81
")或出于隐私和
兼容性考虑,在其他平台上常见的字符串。
product
必须返回字符串 "Gecko
"。
productSub
必须返回以下列表中的适当字符串:
字符串 "20030107
"。
字符串 "20100101
"。
userAgent
必须返回 默认
`User-Agent
` 值。
vendor
必须返回以下列表中的适当字符串:
字符串 "Google Inc.
"。
空字符串。
字符串 "Apple Computer, Inc.
"。
vendorSub
必须返回空字符串。
如果 navigator 兼容模式 是 Gecko,则用户代理还必须支持以下部分接口:
partial interface mixin NavigatorID {
[Exposed =Window ] boolean taintEnabled (); // constant false
[Exposed =Window ] readonly attribute DOMString oscpu ;
};
taintEnabled()
方法必须返回 false。
oscpu
属性的 getter 必须返回
空字符串或表示浏览器正在执行的平台的字符串,例如 "Windows NT 10.0; Win64; x64
","Linux
x86_64
"。
该 API 中任何因用户而异的信息都可以用于对用户进行分析。事实上,如果有足够多的此类信息,则可以唯一地识别用户。因此,强烈建议用户代理实现者尽可能少地在该 API 中包含信息。
interface mixin NavigatorLanguage {
readonly attribute DOMString language ;
readonly attribute FrozenArray <DOMString > languages ;
};
self.navigator.language
在所有当前引擎中均支持。
在所有当前引擎中均支持。
返回一个表示用户首选语言的语言标签。
self.navigator.languages
在所有当前引擎中均支持。
返回一个表示用户首选语言的语言标签数组,最优先的语言排在最前面。
最优先的语言是由 navigator.language
返回的语言。
当用户代理对用户的首选语言的理解发生变化时,会在 languagechange
事件在 Window
或 WorkerGlobalScope
对象上触发。
language
languages
必须返回一个冻结数组, 该数组包含一个或多个有效的 BCP 47 语言标签,表示合理的语言或用户的首选语言,并按首选顺序排列,最优先的语言排在最前面。必须返回同一个对象,直到用户代理需要返回不同的值或不同顺序的值为止。[BCP47]
每当用户代理需要让某个 navigator.languages
属性的 Window
或 WorkerGlobalScope
对象 global 返回一组新的语言标签时,用户代理必须在 DOM 操作任务源 上排队一个全局任务,然后触发一个事件名为 languagechange
在 global 上,并等待该任务开始执行后再实际返回新值。
为了确定一个合理的语言,用户代理应牢记以下几点:
en-US
" 值;如果所有服务用户都使用相同的值,则可以减少相互之间的区别可能性。
为了避免引入更多的指纹识别向量,用户代理应使用与此函数中定义的 API 相同的列表,用于 HTTP `
Accept-Language
`
头。
interface mixin NavigatorOnLine {
readonly attribute boolean onLine ;
};
self.navigator.onLine
在所有当前引擎中均支持。
在所有当前引擎中均支持。
如果用户代理确定离线(断开与网络的连接),则返回false。否则返回true,表示用户代理可能在线。
当用户代理在用户点击链接或脚本请求远程页面时不会联系网络(或知道此类尝试会失败)时,onLine
属性必须返回false,否则返回true。
当某个Window
或 WorkerGlobalScope
对象global的navigator.onLine
属性的值从true变为false时,用户代理必须在网络任务源
中为global排队一个全局任务,以触发名为offline
的事件。
另一方面,当某个Window
或 WorkerGlobalScope
对象global的navigator.onLine
属性的值从false变为true时,用户代理必须在网络任务源
中为global排队一个全局任务,以触发名为online
的事件。
此属性本质上是不可靠的。计算机可以连接到网络但没有互联网访问。
在此示例中,当浏览器上线和离线时,会更新指示器。
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< title > Online status</ title >
< script >
function updateIndicator() {
document. getElementById( 'indicator' ). textContent = navigator. onLine ? 'online' : 'offline' ;
}
</ script >
</ head >
< body onload = "updateIndicator()" ononline = "updateIndicator()" onoffline = "updateIndicator()" >
< p > The network is: < span id = "indicator" > (state unknown)</ span >
</ body >
</ html >
registerProtocolHandler()
方法Navigator/registerProtocolHandler
interface mixin NavigatorContentUtils {
[SecureContext ] undefined registerProtocolHandler (DOMString scheme , USVString url );
[SecureContext ] undefined unregisterProtocolHandler (DOMString scheme , USVString url );
};
window.navigator.registerProtocolHandler(scheme, url)
在url中为scheme注册一个处理程序。例如,在线电话消息服务可以将自己注册为sms:
协议的处理程序,以便当用户点击这样的链接时,可以选择使用该网站。[SMS]
字符串 "%s
" 在url中用作放置要处理内容的 URL 的占位符。
如果用户代理阻止注册(例如,尝试注册 "http
" 处理程序时),将抛出"SecurityError
" DOMException
。
如果url中缺少 "%s
" 字符串,将抛出"SyntaxError
" DOMException
。
window.navigator.unregisterProtocolHandler(scheme, url)
Navigator/unregisterProtocolHandler
仅在一个引擎中支持。
注销给定参数的处理程序。
如果用户代理阻止注销(例如使用无效方案),将抛出"SecurityError
" DOMException
。
如果url中缺少 "%s
" 字符串,将抛出"SyntaxError
" DOMException
。
registerProtocolHandler(scheme,
url)
方法步骤如下:
让(normalizedScheme, normalizedURLString)成为运行规范化协议处理程序参数的结果,使用scheme,url,以及 this的 相关设置对象。
并行:为normalizedScheme和normalizedURLString注册协议处理程序。在所描述的约束内,用户代理可以执行任何操作。例如,用户代理可以提示用户,并提供用户将该站点添加到处理程序短名单或将其设为默认的机会,或取消请求。用户代理也可以静默收集信息,仅在与用户相关时提供这些信息。
用户代理应记录已注册处理程序的网站(即使用户已拒绝此类注册),以便用户不会反复收到相同的请求。
如果registerProtocolHandler()
自动化模式的
this的相关全局对象的
关联的Document
不是 "none
",用户代理应首先验证它是否处于自动化上下文中(参见
WebDriver
的安全性考虑)。然后,用户代理应绕过上述的信息通信和用户同意收集,直接根据url。
autoAccept
"模拟用户查看了注册详情并接受了请求。
autoReject
"模拟用户查看了注册详情并拒绝了请求。
当用户代理使用该处理程序处理一个URLinputURL时:
设置用户名给定inputURL和空字符串。
设置密码给定inputURL和空字符串。
令inputURLString为inputURL的序列化结果。
令encodedURL为运行UTF-8 百分号编码 inputURLString的结果,使用组件百分号编码集。
令handlerURLString为normalizedURLString。
用encodedURL替换handlerURLString中首次出现的"%s
"。
令resultURL为解析handlerURLString的结果。
如果用户访问了https://example.com/
站点,并执行了以下调用:
navigator. registerProtocolHandler( 'web+soup' , 'soup?url=%s' )
...然后,在访问https://www.example.net/
期间点击了一个类似的链接:
< a href = "web+soup:chicken-kïwi" > Download our Chicken Kïwi soup!</ a >
...然后 UA 可能会导航到以下 URL:
https://example.com/soup?url=web+soup:chicken-k%C3%AFwi
然后该站点可以执行其处理过程(合成并将其运送给用户,或其他任何操作)。
此处未定义何时使用该处理程序。在某种程度上,跨文档导航的处理模型定义了一些相关的情况,但通常情况下,用户代理可以在其通常将方案交给本机插件或辅助应用程序时使用此信息。
unregisterProtocolHandler(scheme,
url)
方法步骤如下:
令(normalizedScheme, normalizedURLString)成为运行规范化协议处理程序参数的结果,使用 scheme,url,以及 this的 相关设置对象。
并行:注销由normalizedScheme和normalizedURLString描述的处理程序。
要规范化协议处理程序参数,给定字符串scheme、字符串url和环境设置对象environment,请执行以下步骤:
将scheme设置为scheme,转换为 ASCII 小写。
如果scheme既不是安全列方案,也不是以
"web+
" 开头并后跟一个或多个ASCII
小写字母的字符串,则抛出"SecurityError
" DOMException
。
这意味着在scheme中包含冒号(如 "mailto:
")将抛出异常。
以下方案是安全列方案:
bitcoin
ftp
ftps
geo
im
irc
ircs
magnet
mailto
matrix
mms
news
nntp
openpgp4fpr
sftp
sip
sms
smsto
ssh
tel
urn
webcal
wtai
xmpp
此列表可以更改。如果有应添加的方案,请提供反馈。
如果url不包含 "%s
",则抛出
"SyntaxError
" DOMException
。
让urlRecord成为编码解析 URL得到的结果,使用 url,相对于environment。
如果urlRecord失败,则抛出"SyntaxError
" DOMException
。
如果%s
占位符在URL的主机或端口中,这是强制性情况。
如果urlRecord的方案不是
HTTP(S)方案或urlRecord的源与
environment的同源,则抛出
"SecurityError
" DOMException
。
断言:根据URL是否潜在可信?,urlRecord的结果为"Potentially Trustworthy
"。
由于规范化协议处理程序参数在 安全上下文中运行, 这由同源条件隐含。
返回(scheme, urlRecord)。
序列化的urlRecord根据定义不会是一个有效的 URL 字符串,因为它包含
"%s
" 字符串,而这在URL中不是一个有效组件。
自定义协议处理程序可能会引发一些问题,特别是隐私问题。
劫持所有网页使用。用户代理不应允许将其正常操作中关键的协议(例如HTTP(S) 协议)重定向到第三方网站。这将使用户的活动被轻易跟踪,并可能导致在安全连接中的用户信息被收集。
劫持默认设置。强烈建议用户代理不要自动更改任何默认设置,因为这可能会导致用户将数据发送到用户未预料的远程主机。新注册的处理程序不应自动导致这些站点被使用。
注册垃圾信息。用户代理应考虑到站点可能会尝试注册大量处理程序,可能来自多个域(例如,通过重定向到一系列不同域的页面,每个页面注册一个web+spam:
处理程序——类似的滥用其他浏览器功能的做法已经被色情网站使用多年)。用户代理应优雅地处理此类恶意尝试,保护用户。
恶意处理程序元数据。用户代理应防止针对接口中嵌入的字符串的典型攻击,例如确保此类字符串中的标记或转义字符不会被执行,正确处理空字节,防止过长的字符串导致崩溃或缓冲区溢出等。
泄露私人数据。网页作者可能会引用使用被认为是私人数据的 URL 的自定义协议处理程序。他们可能期望用户选择的处理程序指向组织内部的页面,从而确保敏感数据不会暴露给第三方。然而,用户可能已经注册了一个指向外部站点的处理程序,从而导致数据泄露给第三方。开发人员可能需要考虑允许管理员在某些子域、内容类型或协议上禁用自定义处理程序。
界面干扰。用户代理应准备好处理有意提供给方法的长参数。例如,如果用户界面包含一个“接受”按钮和一个“拒绝”按钮,并且“接受”按钮中包含处理程序的名称,重要的是长名称不会导致“拒绝”按钮被推到屏幕外。
每个Document
都有一个registerProtocolHandler()
自动化模式。默认值为"none
",但它也可以是"autoAccept
"或"autoReject
"。
为了用户代理自动化和网站测试的目的,本标准定义了设置 RPH 注册模式WebDriver 扩展命令。它指示用户代理将Document
置于一种模式,在这种模式下,它将自动模拟用户接受或拒绝注册确认提示对话框。
HTTP 方法 | URI 模板 |
---|---|
`POST `
|
/session/{session id}/custom-handlers/set-mode
|
远程结束步骤如下:
如果parameters不是 JSON 对象,则返回WebDriver 错误,错误码为WebDriver 错误代码中的无效参数。
将mode设置为从parameters中获取名为"mode
"的属性的结果。
如果mode不是"autoAccept
",
"autoReject
",
或"none
",
则返回WebDriver 错误,错误码为WebDriver
错误代码中的无效参数。
将document的registerProtocolHandler()
自动化模式设置为mode。
返回成功并将数据设置为 null。
interface mixin NavigatorCookies {
readonly attribute boolean cookieEnabled ;
};
window.navigator.cookieEnabled
支持所有当前引擎。
如果设置 Cookie 的操作会被忽略,则返回 false,否则返回 true。
当用户代理试图根据HTTP 状态管理机制处理 Cookie 时,cookieEnabled
属性必须返回 true;如果忽略
Cookie 更改请求,则返回 false。[COOKIES]
window.navigator.pdfViewerEnabled
如果用户代理支持在内联查看 PDF 文件时返回 true,否则返回 false。在后者的情况下,PDF 文件将由外部软件处理。
interface mixin NavigatorPlugins {
[SameObject ] readonly attribute PluginArray plugins ;
[SameObject ] readonly attribute MimeTypeArray mimeTypes ;
boolean javaEnabled ();
readonly attribute boolean pdfViewerEnabled ;
};
[Exposed =Window ,
LegacyUnenumerableNamedProperties ]
interface PluginArray {
undefined refresh ();
readonly attribute unsigned long length ;
getter Plugin ? item (unsigned long index );
getter Plugin ? namedItem (DOMString name );
};
[Exposed =Window ,
LegacyUnenumerableNamedProperties ]
interface MimeTypeArray {
readonly attribute unsigned long length ;
getter MimeType ? item (unsigned long index );
getter MimeType ? namedItem (DOMString name );
};
[Exposed =Window ,
LegacyUnenumerableNamedProperties ]
interface Plugin {
readonly attribute DOMString name ;
readonly attribute DOMString description ;
readonly attribute DOMString filename ;
readonly attribute unsigned long length ;
getter MimeType ? item (unsigned long index );
getter MimeType ? namedItem (DOMString name );
};
[Exposed =Window ]
interface MimeType {
readonly attribute DOMString type ;
readonly attribute DOMString description ;
readonly attribute DOMString suffixes ;
readonly attribute Plugin enabledPlugin ;
};
尽管如今可以通过 navigator.pdfViewerEnabled
来检测 PDF 查看器的支持,但由于历史原因,有许多复杂且交织的接口提供相同的功能,而遗留代码依赖于这些接口。本节指定了简单的现代变体和复杂的历史变体。
每个用户代理都有一个 支持 PDF 查看器 的布尔值,其值是实现定义的(可能会根据用户偏好有所不同)。
该值还会影响导航处理模型。
每个 Window
对象都有一个 PDF 查看器插件对象 列表。如果用户代理的 支持 PDF 查看器
为 false,则该列表为空。否则,它是一个包含五个 Plugin
对象的列表,这些对象的 名称 分别为:
PDF Viewer
"Chrome PDF Viewer
"Chromium PDF Viewer
"Microsoft Edge PDF Viewer
"WebKit built-in PDF
"上述列表的值构成了 PDF 查看器插件名称 列表。
这些名称是基于网站历史搜索证据选择的,因此是用户代理为了保持与现有内容的兼容性而需要公开的名称。它们按字母顺序排列。然后将 "PDF Viewer
" 名称插入到第 0
个位置,以便 enabledPlugin
获取器可以指向一个通用的插件名称。
每个 Window
对象都有一个 PDF 查看器 mime 类型对象 列表。如果用户代理的 支持 PDF
查看器
为 false,则该列表为空。否则,它是一个包含两个 MimeType
对象的列表,这些对象的 类型 分别为:
application/pdf
"text/pdf
"上述列表的值构成了 PDF 查看器 mime 类型 列表。
每个 NavigatorPlugins
对象都有一个 插件数组,这是一个新的 PluginArray
,以及一个
mime 类型数组,这是一个新的 MimeTypeArray
。
该 NavigatorPlugins
混入的 plugins
获取器步骤是返回 此对象的 插件数组。
该 NavigatorPlugins
混入的 mimeTypes
获取器步骤是返回 此对象的 mime 类型数组。
该 NavigatorPlugins
混入的 javaEnabled()
方法步骤是返回 false。
在所有当前引擎中受支持。
该 NavigatorPlugins
混入的 pdfViewerEnabled
获取器步骤是返回用户代理的 支持 PDF
查看器
的状态。
该 PluginArray
接口 支持命名属性。如果用户代理的
支持 PDF
查看器
状态为 true,那么它们就是 PDF
查看器插件名称。否则,它们为空列表。
该 PluginArray
接口的 namedItem(name)
方法步骤如下:
该 PluginArray
接口 支持索引属性。支持的属性索引 是此对象的相关全局对象的 PDF
查看器插件对象的索引。
该 PluginArray
接口的 item(index)
方法步骤如下:
将 plugins 设为 此对象的 相关全局对象 的PDF 查看器插件对象。
如果 index 小于 plugins 的 大小,则返回 plugins[index]。
返回 null。
该 PluginArray
接口的 length
获取器步骤是返回此对象的相关全局对象的 PDF 查看器插件对象的大小。
该 PluginArray
接口的 refresh()
方法步骤是没有操作。
该 MimeTypeArray
接口 支持命名属性。如果用户代理的
支持 PDF
查看器
为 true,那么它们就是 PDF 查看器 mime
类型。否则,它们为空列表。
该 MimeTypeArray
接口的 namedItem(name)
方法步骤如下:
对于每个 MimeType
mime
类型 ,在 此对象的 相关全局对象 的 PDF 查看器 mime 类型对象 列
表中:如果 mime 类型 的 类型 是 name,则返回 mime 类型。
返回 null。
该 MimeTypeArray
接口 支持索引属性。支持的属性索引 是此对象的相关全局对象的 PDF 查看器 mime
类型对象的索引。
该 MimeTypeArray
接口的 item(index)
方法步骤如下:
将 mime 类型列表 设为 此对象的 相关全局对象 的PDF 查看器 mime 类型对象。
如果index小于mimeTypes的大小,则返回mimeTypes[index]。
返回 null。
该 MimeTypeArray
接口的 length
获取器步骤是返回此对象的相关全局对象的 PDF 查看器 mime 类型对象的大小。
每个 Plugin
对象都有一个
名称,该名称在创建对象时设置。
该 Plugin
接口的
name
获取器步骤是返回 此对象的
名称。
该 Plugin
接口的
description
获取器步骤是返回"Portable Document Format
"。
该 Plugin
接口的
filename
获取器步骤是返回"internal-pdf-viewer
"。
该 Plugin
接口 支持命名属性。如果用户代理的
支持 PDF
查看器
状态为 true,那么它们就是 PDF 查看器 mime
类型。否则,它们为空列表。
该 Plugin
接口的
namedItem(name)
方法步骤如下:
对于每个 MimeType
mime
类型 ,在 此对象的 相关全局对象 的 PDF 查看器 mime 类型对象 列表中:如果 mime 类型 的
类型
是
name,则返回 mime 类型。
返回 null。
该 Plugin
接口 支持索引属性。支持的属性索引 是此对象的相关全局对象的 PDF 查看器 mime
类型对象的索引。
该 Plugin
接口的
item(index)
方法步骤如下:
将 mime 类型列表 设为 此对象的 相关全局对象 的PDF 查看器 mime 类型对象。
如果index小于mimeType的大小,则返回mimeTypes[index]。
返回 null。
该 Plugin
接口的
length
获取器步骤是返回此对象的相关全局对象的 PDF 查看器 mime 类型对象的大小。
每个 MimeType
对象都有一个
类型,该类型在创建对象时设置。
该 MimeType
接口的
type
获取器步骤是返回
此对象的
类型。
该 MimeType
接口的
description
获取器步骤是返回"Portable Document Format
"。
该 MimeType
接口的
suffixes
获取器步骤是返回
"pdf
"。
该 MimeType
接口的
enabledPlugin
获取器步骤是返回此对象的相关全局对象的 PDF 查看器插件对象[0](即通用的 "PDF Viewer
" 对象)。
支持所有当前的浏览器引擎。
[Exposed =(Window ,Worker ), Serializable , Transferable ]
interface ImageBitmap {
readonly attribute unsigned long width ;
readonly attribute unsigned long height ;
undefined close ();
};
typedef (CanvasImageSource or
Blob or
ImageData ) ImageBitmapSource ;
enum ImageOrientation { " from-image " , " flipY " };
enum PremultiplyAlpha { " none " , " premultiply " , " default " };
enum ColorSpaceConversion { " none " , " default " };
enum ResizeQuality { " pixelated " , " low " , " medium " , " high " };
dictionary ImageBitmapOptions {
ImageOrientation imageOrientation = "from-image";
PremultiplyAlpha premultiplyAlpha = "default";
ColorSpaceConversion colorSpaceConversion = "default";
[EnforceRange ] unsigned long resizeWidth ;
[EnforceRange ] unsigned long resizeHeight ;
ResizeQuality resizeQuality = "low";
};
一个ImageBitmap
对象表示一个位图图像,可以无延迟地绘制到画布上。
对于什么是无延迟的确切判断由实现者决定,但通常情况下,如果使用位图需要网络I/O,甚至本地磁盘I/O,那么延迟可能是不合适的;而如果它只需要从GPU或系统RAM进行阻塞读取,那么延迟可能是可以接受的。
promise = self.createImageBitmap(image [, options ])
支持所有当前的浏览器引擎。
promise = self.createImageBitmap(image, sx, sy, sw, sh [, options ])
接受image,它可以是img
元素,一个SVG image
元素,一个video
元素,一个canvas
元素,一个Blob
对象,一个ImageData
对象,或另一个ImageBitmap
对象,并返回一个promise,当创建新的ImageBitmap
时,promise被解析。
如果无法构造ImageBitmap
对象,例如因为提供的image数据实际上不是图像,那么promise将被拒绝。
如果提供了sx、sy、sw和sh参数,源图像将被裁剪到指定的像素,原始图像中缺少的任何像素将被替换为透明黑色。这些坐标在源图像的像素坐标空间中,而不是在CSS像素中。
如果提供了options,则ImageBitmap
对象的位图数据将根据options进行修改。例如,如果premultiplyAlpha
选项设置为"premultiply
",则位图数据的颜色通道将被与其alpha通道相乘。
如果源图像处于无效状态(例如,img
元素未成功加载,ImageBitmap
对象的[[Detached]]内部槽值为true,或ImageData
对象的data
属性值的[[ViewedArrayBuffer]]内部槽被分离,或者Blob
的数据无法解释为位图图像),则promise将被拒绝,并引发"InvalidStateError
"DOMException
。
如果脚本不允许访问源图像的数据(例如,video
跨CORS跨源,或canvas
由来自其他源的worker脚本绘制),则promise将被拒绝,并引发"SecurityError
"DOMException
。
imageBitmap.close()
支持所有当前的浏览器引擎。
释放imageBitmap的底层位图数据。
imageBitmap.width
支持所有当前的浏览器引擎。
imageBitmap.height
支持所有当前的浏览器引擎。
一个ImageBitmap
对象,其[[Detached]]内部槽值为false,总是有相关的位图数据,具有宽度和高度。然而,这些数据可能会被破坏。如果一个ImageBitmap
对象的媒体数据可以无错误地解码,那么它被认为是完全可解码的。
一个ImageBitmap
对象的位图有一个origin-clean标志,指示该位图是否被来自不同来源的内容污染。该标志最初设置为true,并可能在createImageBitmap()
的步骤中更改为false。
它们的序列化步骤,给定value和serialized,如下:
如果value的origin-clean标志未设置,则抛出"DataCloneError
"DOMException
。
将serialized的[[BitmapData]]设置为value的位图数据的副本。
它们的反序列化步骤,给定serialized、value和targetRealm,如下:
将value的位图数据设置为serialized的[[BitmapData]]。
它们的传输步骤,给定value和dataHolder,如下:
如果value的origin-clean标志未设置,则抛出"DataCloneError
"DOMException
。
将dataHolder的[[BitmapData]]设置为value的位图数据。
取消设置value的位图数据。
它们的传输接收步骤,给定dataHolder和value,如下:
将value的位图数据设置为dataHolder的[[BitmapData]]。
createImageBitmap(image, options)
和createImageBitmap(image sx, sy, sw, sh, options)
方法,在调用时,必须执行以下步骤:
如果给出了sw或sh并且为0,则返回一个被拒绝的promise,并带有RangeError
。
如果options的resizeWidth
或options的resizeHeight
之一存在且为0,则返回一个被拒绝的promise,并带有"InvalidStateError
"DOMException
。
检查image参数的可用性。如果抛出异常或返回bad,则返回一个被拒绝的promise,并带有"InvalidStateError
"DOMException
。
设定p为一个新的promise。
设定imageBitmap为一个新的ImageBitmap
对象。
根据image进行切换:
img
image
如果image的媒体数据没有自然尺寸(例如,它是一个没有指定内容大小的矢量图形),并且options的resizeWidth
或options的resizeHeight
未存在,则返回一个被拒绝的promise,并带有"InvalidStateError
"DOMException
。
如果image的媒体数据没有自然尺寸(例如,它是一个没有指定内容大小的矢量图形),则应将其渲染为resizeWidth
和resizeHeight
选项指定大小的位图。
将imageBitmap的位图数据设定为image的媒体数据的副本,裁剪到源矩形并格式化。如果这是一个动画图像,imageBitmap的位图数据只能从动画的默认图像(格式定义在不支持或禁用动画时使用的图像)中获取,或者,如果没有这样的图像,则取动画的第一帧。
如果image不是origin-clean,则将imageBitmap位图的origin-clean标志设置为false。
并行执行此步骤:
使用imageBitmap解析p。
video
如果image的networkState
属性为NETWORK_EMPTY
,则返回一个被拒绝的promise,并带有"InvalidStateError
"DOMException
。
将imageBitmap的位图数据设定为在当前播放位置的帧的副本,在媒体资源的自然宽度和自然高度(即在应用了任何纵横比修正后),裁剪到源矩形并格式化。
如果image不是origin-clean,则将imageBitmap位图的origin-clean标志设置为false。
并行执行此步骤:
使用imageBitmap解析p。
canvas
将imageBitmap的位图数据设定为image的位图数据的副本,裁剪到源矩形并格式化。
将imageBitmap位图的origin-clean标志设置为与image位图的 origin-clean标志相同的值。
并行执行此步骤:
使用imageBitmap解析p。
Blob
并行执行这些步骤:
将imageData设定为读取image数据的结果。如果在读取对象时发生错误,则使用"InvalidStateError
"DOMException
拒绝p并中止这些步骤。
应用图像嗅探规则来确定imageData的文件格式,image的MIME类型(如image的type
属性所示)给出官方类型。
如果imageData不在支持的图像文件格式中(例如,它根本不是图像),或如果imageData在某种致命方式上损坏,以至于无法获取图像尺寸(例如,一个没有自然大小的矢量图形),则使用"InvalidStateError
"DOMException
拒绝p并中止这些步骤。
将imageBitmap的位图数据设定为imageData,裁剪到源矩形并格式化。如果这是一个动画图像,imageBitmap的位图数据必须仅取自动画的默认图像(格式定义在不支持或禁用动画时使用的图像),或者,如果没有这样的图像,则取动画的第一帧。
使用imageBitmap解析p。
ImageData
设定buffer为image的data
属性值的[[ViewedArrayBuffer]]内部槽。
如果IsDetachedBuffer(buffer)为true,则返回一个被拒绝的promise,并带有"InvalidStateError
"DOMException
。
将imageBitmap的位图数据设定为image的图像数据,裁剪到源矩形并格式化。
并行执行此步骤:
使用imageBitmap解析p。
ImageBitmap
将imageBitmap的位图数据设定为image的位图数据的副本,裁剪到源矩形并格式化。
将imageBitmap位图的origin-clean标志设置为与image位图的origin-clean标志相同的值。
并行执行此步骤:
使用imageBitmap解析p。
VideoFrame
将imageBitmap的位图数据设定为image的可见像素数据的副本,裁剪到源矩形并格式化。
并行执行此步骤:
使用imageBitmap解析p。
返回p。
当上述步骤要求用户代理将位图数据裁剪到源矩形并格式化时,用户代理必须执行以下步骤:
将input设定为正在转换的位图数据。
如果指定了sx、sy、sw和sh,则将sourceRectangle设定为一个矩形,其四个角分别是(sx, sy), (sx+sw, sy), (sx+sw, sy+sh), (sx, sy+sh)。否则,将sourceRectangle设定为一个矩形,其四个角分别是(0, 0), (width of input, 0), (width of input, height of input), (0, height of input)。
如果sw或sh为负值,则该矩形的左上角将位于sx、sy点的左侧或上方。
设定outputWidth如下:
resizeWidth
成员的options被指定
resizeWidth
成员的值
resizeWidth
成员的options未指定,但resizeHeight
成员被指定
resizeHeight
成员的值,除以sourceRectangle的高度,并向上取整至最接近的整数
resizeWidth
和resizeHeight
都未指定
设定outputHeight如下:
resizeHeight
成员的options被指定
resizeHeight
成员的值
resizeHeight
成员的options未指定,但resizeWidth
成员被指定
resizeWidth
成员的值,除以sourceRectangle的宽度,并向上取整至最接近的整数
resizeWidth
和resizeHeight
都未指定
将input放置在一个无限的透明黑色网格平面上,使其左上角位于平面的原点,x坐标向右增加,y坐标向下增加,并且每个像素在input图像数据中占据平面网格上的一个单元格。
将output设定为由sourceRectangle表示的平面上的矩形。
将output缩放到outputWidth和outputHeight指定的大小。用户代理应使用resizeQuality
选项的值来指导缩放算法的选择。
如果imageOrientation
成员的options值为"flipY
",则必须垂直翻转output,无视源图像的任何图像方向元数据(如EXIF元数据),如果有的话。[EXIF]
如果值为"from-image
",则不需要额外的步骤。
曾经有一个"none
"枚举值。它被重命名为"from-image
"。将来,"none
"将被添加回来,并具有不同的含义。
如果image是img
元素或Blob
对象,则将val设定为colorSpaceConversion
成员的options的值,然后执行这些子步骤:
如果val为"default
",颜色空间转换行为是实现特定的,并应根据实现用来将图像绘制到画布上的默认颜色空间来选择。
如果val为"none
",output必须在不执行任何颜色空间转换的情况下解码。这意味着图像解码算法必须忽略嵌入源数据中的颜色配置文件元数据以及显示设备的颜色配置文件。
将val设定为premultiplyAlpha
成员的options的值,然后执行这些子步骤:
返回output。
close()
方法的步骤如下:
将this的[[Detached]]内部槽值设为true。
width
获取器的步骤如下:
如果this的[[Detached]]内部槽的值为true,则返回0。
height
获取器的步骤如下:
如果this的[[Detached]]内部槽的值为true,则返回0。
ResizeQuality
枚举用于表示在缩放图像时对插值质量的偏好。
"pixelated
"
值表示优先考虑尽可能多地保留原始图像的像素化,在目标尺寸不是原始尺寸的整数倍时,通过必要的小幅平滑来避免图像失真。
要实现 "pixelated
",对于每个轴,首先确定其自然尺寸的整数倍,使其最接近目标尺寸且大于零。使用最近邻缩放到此整数倍大小,然后使用双线性插值将其缩放到目标尺寸。
"low
"
值表示对低级图像插值质量的偏好。低质量图像插值可能比更高的设置在计算上更有效。
"medium
" 值表示对中等级图像插值质量的偏好。
"high
"
值表示对高级图像插值质量的偏好。高质量图像插值可能比较低的设置在计算上更昂贵。
双线性缩放是一种相对较快的低质量图像平滑算法的示例。双三次或Lanczos缩放是生成更高质量输出的图像缩放算法示例。本规范不强制要求使用特定的插值算法,除非是上文描述的 "像素化
"。
使用这个API,可以预先剪裁和准备一个精灵图:
var sprites = {};
function loadMySprites() {
var image = new Image();
image. src = 'mysprites.png' ;
var resolver;
var promise = new Promise( function ( arg) { resolver = arg });
image. onload = function () {
resolver( Promise. all([
createImageBitmap( image, 0 , 0 , 40 , 40 ). then( function ( image) { sprites. person = image }),
createImageBitmap( image, 40 , 0 , 40 , 40 ). then( function ( image) { sprites. grass = image }),
createImageBitmap( image, 80 , 0 , 40 , 40 ). then( function ( image) { sprites. tree = image }),
createImageBitmap( image, 0 , 40 , 40 , 40 ). then( function ( image) { sprites. hut = image }),
createImageBitmap( image, 40 , 40 , 40 , 40 ). then( function ( image) { sprites. apple = image }),
createImageBitmap( image, 80 , 40 , 40 , 40 ). then( function ( image) { sprites. snake = image })
]));
};
return promise;
}
function runDemo() {
var canvas = document. querySelector( 'canvas#demo' );
var context = canvas. getContext( '2d' );
context. drawImage( sprites. tree, 30 , 10 );
context. drawImage( sprites. snake, 70 , 10 );
}
loadMySprites(). then( runDemo);
一些对象包含AnimationFrameProvider
接口混入。
callback FrameRequestCallback = undefined (DOMHighResTimeStamp time );
interface mixin AnimationFrameProvider {
unsigned long requestAnimationFrame (FrameRequestCallback callback );
undefined cancelAnimationFrame (unsigned long handle );
};
Window includes AnimationFrameProvider ;
DedicatedWorkerGlobalScope includes AnimationFrameProvider ;
每个AnimationFrameProvider
对象还有一个目标对象,用于存储提供者的内部状态。其定义如下:
AnimationFrameProvider
是一个Window
Window
的关联的Document
AnimationFrameProvider
是一个DedicatedWorkerGlobalScope
DedicatedWorkerGlobalScope
每个目标对象都有一个动画帧回调映射,它是一个有序映射,初始为空;还有一个动画帧回调标识符,它是一个数字,初始值为零。
当满足以下任一条件时,AnimationFrameProvider
provider
被视为受支持:
所有现有引擎均支持。
requestAnimationFrame(callback)
方法的步骤如下:
如果this不受支持,则抛出一个"NotSupportedError
"DOMException
。
将target的动画帧回调标识符增加1,并将其结果设为handle。
让callbacks成为target的动画帧回调映射。
设置callbacks[handle]为callback。
返回handle。
所有现有引擎均支持。
cancelAnimationFrame(handle)
方法的步骤如下:
如果this不受支持,则抛出一个"NotSupportedError
"DOMException
。
移除callbacks[handle]。
要运行动画帧回调,对于target对象target,使用时间戳now:
在工作线程中,requestAnimationFrame()
可以与从canvas
元素传输的OffscreenCanvas
一起使用。首先,在文档中,将控制权转移到工作线程:
const offscreenCanvas = document. getElementById( "c" ). transferControlToOffscreen();
worker. postMessage( offscreenCanvas, [ offscreenCanvas]);
然后,在 worker 中,以下代码将绘制一个从左到右移动的矩形:
let ctx, pos = 0 ;
function draw( dt) {
ctx. clearRect( 0 , 0 , 100 , 100 );
ctx. fillRect( pos, 0 , 10 , 10 );
pos += 10 * dt;
requestAnimationFrame( draw);
}
self. onmessage = function ( ev) {
const transferredCanvas = ev. data;
ctx = transferredCanvas. getContext( "2d" );
draw();
};
WebSocket
接口曾在此定义。现在它在WebSockets中定义。[WEBSOCKETS]
MessageEvent
接口在所有当前引擎中支持。
在 服务器发送事件中、跨文档消息传递中、
通道消息传递中、
广播频道中,以及
WebSockets中使用
MessageEvent
接口用于它们的message
事件:[WEBSOCKETS]
[Exposed =(Window ,Worker ,AudioWorklet )]
interface MessageEvent : Event {
constructor (DOMString type , optional MessageEventInit eventInitDict = {});
readonly attribute any data ;
readonly attribute USVString origin ;
readonly attribute DOMString lastEventId ;
readonly attribute MessageEventSource ? source ;
readonly attribute FrozenArray <MessagePort > ports ;
undefined initMessageEvent (DOMString type , optional boolean bubbles = false , optional boolean cancelable = false , optional any data = null , optional USVString origin = "", optional DOMString lastEventId = "", optional MessageEventSource ? source = null , optional sequence <MessagePort > ports = []);
};
dictionary MessageEventInit : EventInit {
any data = null ;
USVString origin = "";
DOMString lastEventId = "";
MessageEventSource ? source = null ;
sequence <MessagePort > ports = [];
};
typedef (WindowProxy or MessagePort or ServiceWorker ) MessageEventSource ;
event.data
在所有当前引擎中支持。
返回消息的数据。
event.origin
在所有当前引擎中支持。
event.lastEventId
在所有当前引擎中支持。
返回最后事件 ID 字符串, 对于服务器发送事件。
event.source
在所有当前引擎中支持。
返回消息源的WindowProxy
,
对于跨文档消息传递;在connect
事件中
SharedWorkerGlobalScope
对象中被附加的MessagePort
。
event.ports
在所有当前引擎中支持。
返回与消息一起发送的MessagePort
数组,适用于跨文档消息传递和通道消息传递。
data
属性必须返回其初始化的值。它表示正在发送的消息。
origin
属性必须返回其
初始化的值。它表示,在服务器发送事件和跨文档消息传递中,
发送消息的文档的来源
(通常是文档的方案、主机名和端口,但不包括其路径或片段)。
lastEventId
属性必须返回其
初始化的值。它表示,在服务器发送事件中,事件源的最后事件 ID 字符串。
source
属性必须返回其
初始化的值。它表示,在跨文档消息传递中,
WindowProxy
的浏览上下文,
来自其发送消息的Window
对象;在connect
事件中使用共享worker,
新连接的MessagePort
。
ports
属性必须返回其初始化的值。它表示,在跨文档消息传递和通道消息传递中,发送的MessagePort
数组。
initMessageEvent(type, bubbles,
cancelable, data, origin, lastEventId,
source, ports)
方法必须以类似命名的方式初始化事件
initEvent()
方法。
[DOM]
各种 API(例如,WebSocket
、
EventSource
)
使用
MessageEvent
接口用于它们的message
事件
而不使用MessagePort
API。
在所有当前引擎中支持。
本节为非规范性内容。
为了使服务器能够通过 HTTP 或使用专用的服务器推送协议向网页推送数据,本规范引入了EventSource
接口。
使用此 API 包括创建一个EventSource
对象并注册一个事件监听器。
var source = new EventSource( 'updates.cgi' );
source. onmessage = function ( event) {
alert( event. data);
};
在服务器端,脚本(在此例中为 "updates.cgi
")以以下形式发送消息,MIME 类型为text/event-stream
:
data: 这是第一条消息。 data: 这是第二条消息, data: 它有两行。 data: 这是第三条消息。
作者可以使用不同的事件类型来区分事件。以下是一个包含 "add" 和 "remove" 两种事件类型的流:
event: add data: 73857293 event: remove data: 2153 event: add data: 113411
处理这种流的脚本如下(其中addHandler
和removeHandler
是接受一个参数的函数,即事件):
var source = new EventSource( 'updates.cgi' );
source. addEventListener( 'add' , addHandler, false );
source. addEventListener( 'remove' , removeHandler, false );
默认的事件类型是 "message"。
事件流始终以 UTF-8 解码。无法指定其他字符编码。
事件流请求可以像普通 HTTP 请求一样使用 HTTP 301 和 307 重定向进行重定向。如果连接关闭,客户端将重新连接;可以通过使用 HTTP 204 无内容响应代码来告知客户端停止重新连接。
使用此 API 而不是使用XMLHttpRequest
或iframe
来模拟它,使用户代理能够在用户代理实现者和网络运营商能够预先协调的情况下更好地利用网络资源。除此之外,这还可以显著节省便携式设备的电池寿命。这在下面的无连接推送部分中进一步讨论。
EventSource
接口在所有当前引擎中支持。
[Exposed =(Window ,Worker )]
interface EventSource : EventTarget {
constructor (USVString url , optional EventSourceInit eventSourceInitDict = {});
readonly attribute USVString url ;
readonly attribute boolean withCredentials ;
// ready state
const unsigned short CONNECTING = 0;
const unsigned short OPEN = 1;
const unsigned short CLOSED = 2;
readonly attribute unsigned short readyState ;
// networking
attribute EventHandler onopen ;
attribute EventHandler onmessage ;
attribute EventHandler onerror ;
undefined close ();
};
dictionary EventSourceInit {
boolean withCredentials = false ;
};
每个 EventSource
对象都与以下内容相关联:
一个 url(一个 URL 记录)。在构造期间设置。
一个 请求。这最初必须为 null。
一个以毫秒为单位的 重新连接时间。它最初必须是实现定义的值,可能在几秒钟的范围内。
一个 最后事件 ID 字符串。它最初必须为空字符串。
除了 url 之外,这些目前并未在
EventSource
对象上公开。
source = new EventSource(
url [, { withCredentials:
true } ])
在所有当前引擎中支持。
创建一个新的 EventSource
对象。
url 是一个字符串,提供了将提供事件流的 URL。
将 withCredentials
设置为 true
将把连接请求的凭证模式设置为 url 为 "include
"。
source.close()
在所有当前引擎中支持。
中止为此 EventSource
对象启动的fetch 算法的任何实例,并将 readyState
属性设置为 CLOSED
。
source.url
在所有当前引擎中支持。
返回提供事件流的 URL。
source.withCredentials
在所有当前引擎中支持。
如果连接请求的凭证模式
设置为 "include
",则返回 true,否则返回 false。
source.readyState
在所有当前引擎中支持。
返回此 EventSource
对象连接的状态。它可以具有以下描述的值。
EventSource(url, eventSourceInitDict)
构造函数在调用时必须执行以下步骤:
令 ev 为一个新的 EventSource
对象。
令 settings 为 ev 的 相关设置对象。
令 urlRecord 为在给定 url 的情况下编码解析 URL 的结果, 相对于 settings。
如果 urlRecord 失败,则抛出 "SyntaxError
"
DOMException
。
将 ev 的 url 设置为 urlRecord。
令 corsAttributeState 为 Anonymous。
如果 eventSourceInitDict 的 withCredentials
成员的值为 true,则将
corsAttributeState 设置为 Use
Credentials 并将 ev 的 withCredentials
属性设置为 true。
令 request 为 创建一个潜在的 CORS 请求的结果, 给定 urlRecord、空字符串和 corsAttributeState。
将 request 的 客户端 设置为 settings。
用户代理可以在 request 的头列表中
设置 (`Accept
`,
`text/event-stream
`)。
将 request 的缓存模式
设置为
"no-store
"。
将 request 的发起者类型设置为 "other
"。
将 ev 的 request 设置为 request。
给定 response res,令 processEventSourceEndOfBody 进行以下步骤:如果 res 不是网络错误, 则重新建立连接。
获取 request,并将 processResponseEndOfBody 设置为 processEventSourceEndOfBody,将 processResponse 设置为以下步骤,给定 response res:
返回 ev。
url
属性的 getter 必须返回此 EventSource
对象的url 的序列化结果。
withCredentials
属性必须返回其
最后初始化的值。当对象被创建时,它必须初始化为
false。
readyState
属性表示连接的状态。它可以具有以下值:
CONNECTING
(数值 0)OPEN
(数值
1)CLOSED
(数值 2)close()
方法。当对象被创建时,其 readyState
必须
设置为 CONNECTING
(0)。下文中处理连接的规则定义了值何时更改。
close()
方法必须中止为此 EventSource
对象启动的fetch 算法的任何实例,并且必须将 readyState
属性设置为 CLOSED
。
以下是 事件处理程序(及其对应的
事件处理程序事件类型),所有实现
EventSource
接口的对象都必须支持,作为 事件处理程序 IDL 属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onopen
在所有当前引擎中支持。 Firefox6+Safari5+Chrome6+
Opera12+Edge79+ Edge (旧版)?Internet Explorer不支持 Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
open
|
onmessage
在所有当前引擎中支持。 Firefox6+Safari5+Chrome6+
Opera12+Edge79+ Edge (旧版)?Internet Explorer不支持 Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
message
|
onerror
在所有当前引擎中支持。 Firefox6+Safari5+Chrome6+
Opera12+Edge79+ Edge (旧版)?Internet Explorer不支持 Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
error
|
当用户代理需要宣布连接时,用户代理必须排队一个任务,如果readyState
属性被设置为CLOSED
以外的值,
则将readyState
属性设置为OPEN
并触发一个名为open
的事件,
在EventSource
对象上。
当用户代理需要重新建立连接时,用户代理必须运行以下步骤。这些步骤是在并行运行的,而不是作为任务的一部分运行的。(当然,它排队的任务是像普通任务一样运行的,而不是它们自己并行运行的。)
排队一个任务 以运行以下步骤:
如果readyState
属性被设置为CLOSED
,
则中止任务。
将readyState
属性设置为CONNECTING
。
触发一个事件
名为error
在EventSource
对象上。
等待与事件源的重连时间相等的延迟。
可选地,再等待一些时间。特别是,如果上次尝试失败,那么用户代理可能会引入指数级的回退延迟,以避免可能已经超载的服务器过载。或者,如果操作系统报告没有网络连接,用户代理可能会等待操作系统宣布网络连接已恢复,然后再重试。
等待上述任务运行完毕(如果尚未运行)。
排队一个任务 以运行以下步骤:
如果EventSource
对象的readyState
属性未设置为CONNECTING
,
则返回。
令request为EventSource
对象的request。
如果EventSource
对象的最后事件 ID 字符串不是空字符串,则:
令lastEventIDValue为EventSource
对象的最后事件 ID 字符串,编码为 UTF-8。
设置
(`Last-Event-ID
`,
lastEventIDValue)在request的头列表中。
获取request并按本节前面描述的方式处理由此获得的响应(如果有)。
当用户代理需要连接失败时,用户代理必须排队一个任务,如果readyState
属性被设置为CLOSED
以外的值,
则将readyState
属性设置为CLOSED
并触发一个事件名为error
在EventSource
对象上。
一旦用户代理连接失败,
它将不会尝试重新连接。
任务源
为EventSource
对象排队的任务是远程事件任务源。
Last-Event-ID
`
请求头Last-Event-ID
` HTTP 请求头在用户代理重新建立连接时,向服务器报告一个EventSource
对象的最后事件
ID 字符串。
参见 whatwg/html issue #7363 以更好地定义值空间。它本质上是任何 UTF-8 编码的字符串,不包含 U+0000 NULL、U+000A LF 或 U+000D CR。
此事件流格式的MIME 类型为text/event-stream
。
事件流格式如以下 ABNF 的stream
生成所描述,其字符集为 Unicode。[ABNF]
stream = [ bom ] * event
event = * ( comment / field ) end-of-line
comment = colon * any-char end-of-line
field = 1* name-char [ colon [ space ] * any-char ] end-of-line
end-of-line = ( cr lf / cr / lf )
; characters
lf = %x000A ; U+000A LINE FEED (LF)
cr = %x000D ; U+000D CARRIAGE RETURN (CR)
space = %x0020 ; U+0020 SPACE
colon = %x003A ; U+003A COLON (:)
bom = %xFEFF ; U+FEFF BYTE ORDER MARK
name-char = %x0000-0009 / %x000B-000C / %x000E-0039 / %x003B-10FFFF
; a scalar value other than U+000A LINE FEED (LF), U+000D CARRIAGE RETURN (CR), or U+003A COLON (:)
any-char = %x0000-0009 / %x000B-000C / %x000E-10FFFF
; a scalar value other than U+000A LINE FEED (LF) or U+000D CARRIAGE RETURN (CR)
此格式的事件流必须始终以 UTF-8 编码。[ENCODING]
行必须由 U+000D 回车符 (CR) 和 U+000A 换行符 (LF) 字符对、单个 U+000A 换行符 (LF) 字符或单个 U+000D 回车符 (CR) 字符分隔。
由于为此类资源建立的与远程服务器的连接预计将是长期存在的,用户代理应该确保使用适当的缓冲方式。特别是,虽然使用以单个 U+000A 换行符 (LF) 字符结束的行缓冲是安全的,但使用块缓冲或使用不同预期行结尾的行缓冲可能会导致事件分发的延迟。
流必须使用 UTF-8 解码算法进行解码。
UTF-8 解码 算法会移除一个前置的 UTF-8 字节顺序标记 (BOM),如果有的话。
然后必须逐行解析流,其中行结束符可以是 U+000D 回车符 U+000A 换行符 (CRLF) 字符对、单个 U+000A 换行符 (LF) 字符(不以 U+000D 回车符 (CR) 字符为前缀),或单个 U+000D 回车符 (CR) 字符(不以 U+000A 换行符 (LF) 字符为后缀)。
当解析流时,必须与之关联一个data缓冲区、一个event type缓冲区和一个last event ID缓冲区。它们必须初始化为空字符串。
行必须按照接收的顺序按以下方式处理:
分发事件,如下文所述。
忽略此行。
收集该行中第一个 U+003A 冒号字符 (:) 之前的字符,并将其作为field。
收集第一个 U+003A 冒号字符 (:) 之后的字符,并将其作为value。如果value以 U+0020 空格字符开头,将其从value中移除。
处理字段,如以下步骤所述,使用field作为字段名称,使用value作为字段值。
处理字段,如以下步骤所述,使用整个行作为字段名称,并使用空字符串作为字段值。
一旦文件末尾到达,任何未处理的数据都必须被丢弃。(如果文件在事件的中间结束,即在最后一个空行之前,则不分发未完成的事件。)
给定字段名称和字段值,处理字段的步骤取决于字段名称,如以下列表所示。字段名称必须逐字比较,不进行大小写折叠。
将event type缓冲区设置为字段值。
将字段值附加到data缓冲区,然后在data缓冲区中附加一个单一的 U+000A 换行符 (LF) 字符。
如果字段值不包含 U+0000 NULL,则将last event ID缓冲区设置为字段值。否则,忽略此字段。
如果字段值仅包含ASCII 数字,则将字段值解释为一个以十进制表示的整数,并将事件流的重新连接时间设置为该整数。 否则,忽略此字段。
忽略该字段。
当用户代理需要分发事件时,用户代理必须使用适当的步骤处理data缓冲区、event type缓冲区和last event ID缓冲区。
对于网络浏览器,分发事件的适当步骤如下:
将事件源的最后事件 ID 字符串设置为last event ID缓冲区的值。缓冲区不会被重置,因此事件源的最后事件 ID 字符串将保持为此值,直到下一次由服务器设置为止。
如果data缓冲区为空字符串,将data缓冲区和event type缓冲区设置为空字符串并返回。
如果data缓冲区的最后一个字符是 U+000A 换行符 (LF) 字符,则从data缓冲区中删除最后一个字符。
让event成为创建一个事件的结果,使用MessageEvent
,在事件源的相关领域中。
将event的type
属性初始化为message
,其data
属性初始化为data,其origin
属性初始化为事件流最终
URL(即重定向后的 URL)的序列化,其lastEventId
属性初始化为事件源的最后事件 ID 字符串。
如果event type缓冲区的值不是空字符串,则将新创建的事件的类型更改为与event type缓冲区的值相等。
将data缓冲区和event type缓冲区设置为空字符串。
排队一个任务,如果readyState
属性设置为除CLOSED
以外的值,分发刚创建的事件到EventSource
对象。
如果事件没有 "id" 字段,但之前的事件确实将事件源的最后事件 ID 字符串设置了,那么事件的lastEventId
字段将被设置为最后看到的
"id" 字段的值。
对于其他用户代理,分发事件的适当步骤取决于实现,但至少它们必须在返回之前将data和event type缓冲区设置为空字符串。
以下事件流,一旦后面跟着一个空行:
data: YHOO data: +2 data: 10
...将导致一个带有接口为message
的事件被分发到EventSource
对象。事件的data
属性将包含字符串"YHOO\n+2\n10
"(其中"\n
"表示换行符)。
这可以如下使用:
var stocks = new EventSource( "https://stocks.example.com/ticker.php" );
stocks. onmessage = function ( event) {
var data = event. data. split( '\n' );
updateStocks( data[ 0 ], data[ 1 ], data[ 2 ]);
};
...其中updateStocks()
是一个定义为以下的函数:
function updateStocks( symbol, delta, value) { ... }
...或类似的函数。
以下流包含四个块。第一个块只有一个注释,不会触发任何事件。第二个块有两个字段,分别名为 "data" 和 "id";将为此块触发一个事件,数据为 "first event",然后将最后事件 ID 设置为
"1",以便如果连接在此块与下一个块之间中断,服务器将发送一个带有值为 "Last-Event-ID
"
的标头,值为 "1
"。第三个块触发一个数据为 "second event" 的事件,并且有一个 "id" 字段,这次没有值,这会将最后事件 ID
重置为空字符串(这意味着在尝试重新连接时将不会发送
"Last-Event-ID
"
标头)。最后,最后一个块仅触发一个数据为 " third event"(带有一个前置空格字符)的事件。请注意,最后一个块仍然必须以空行结尾,流的结束不足以触发最后一个事件。
: test stream data: first event id: 1 data:second event id data: third event
以下流触发两个事件:
data data data data:
第一个块触发的数据为一个空字符串的事件,如果最后一个块后面跟着一个空行,它也会这样做。中间块触发的数据为一个单一换行符字符的事件。最后一个块被丢弃,因为它后面没有跟着空行。
以下流触发两个相同的事件:
data:test data: test
这是因为冒号后的空格(如果存在)会被忽略。
已知旧版代理服务器在某些情况下会在短暂超时后断开 HTTP 连接。为了防止此类代理服务器的影响,作者可以每隔 15 秒左右包含一行注释(以 ':' 字符开头)。
希望将事件源连接与其他连接或之前提供的特定文档相关联的作者可能会发现,依赖 IP 地址不起作用,因为单个客户端可能有多个 IP 地址(由于有多个代理服务器),并且单个 IP 地址可能有多个客户端(由于共享代理服务器)。最好在提供文档时包含一个唯一标识符,然后在建立连接时将该标识符作为 URL 的一部分传递。
作者还需注意,HTTP 分块传输可能会对该协议的可靠性产生意想不到的负面影响,特别是在分块传输由不了解时间要求的不同层执行时。如果这是个问题,可以在提供事件流时禁用分块传输。
支持 HTTP 每服务器连接限制的客户端在从站点打开多个页面时,可能会遇到问题,如果每个页面都有一个指向同一域的EventSource
。作者可以通过使用每个连接唯一的域名,或允许用户在每个页面上启用或禁用EventSource
功能,或通过使用共享worker共享单个EventSource
对象来避免这种情况。
在受控环境中运行的用户代理(例如与特定运营商绑定的移动设备上的浏览器)可能会将连接的管理卸载到网络上的代理服务器。在这种情况下,为了符合规范,用户代理被视为包括手持设备软件和网络代理。
例如,移动设备上的浏览器在建立连接后,可能会检测到它在支持的网络上,并请求网络上的代理服务器接管连接的管理。这种情况下的时间线可能如下:
EventSource
构造函数中指定的资源。EventSource
构造函数中指定的资源(可能包括一个`Last-Event-ID
`
HTTP 头等)。这可以减少总数据使用量,从而节省大量电量。
除了实现现有的 API 和text/event-stream
线路格式之外,如上所述,也可以支持其他适用规范定义的事件帧格式。本规范未定义它们的解析或处理方式。
当 EventSource
对象的 readyState
为 CONNECTING
时,并且该对象已注册了一个或多个 open
、message
或
error
事件的事件监听器时,必须从 Window
或
WorkerGlobalScope
对象到 EventSource
对象本身有一个强引用。
当 EventSource
对象的 readyState
为 OPEN
时,并且该对象已注册了一个或多个 message
或
error
事件的事件监听器时,必须从
Window
或 WorkerGlobalScope
对象到 EventSource
对象本身有一个强引用。
当 EventSource
对象在 远程事件任务来源
上排队有任务时,必须从
Window
或
WorkerGlobalScope
对象到 EventSource
对象有一个强引用。
如果用户代理要 强制关闭 一个 EventSource
对象(当
Document
对象永久消失时会发生这种情况),用户代理必须中止为此 EventSource
对象启动的任何
fetch 算法的实例,并且必须将 readyState
属性设置为 CLOSED
。
如果一个 EventSource
对象在其连接仍然打开时被垃圾回收,则用户代理必须中止由该 EventSource
打开的
fetch 算法的任何实例。
本节为非规范性内容。
强烈建议用户代理在其开发控制台中提供有关 EventSource
对象及其相关网络连接的详细诊断信息,以帮助作者调试使用此 API 的代码。
例如,用户代理可以有一个面板,显示页面创建的所有 EventSource
对象,每个对象列出构造函数的参数、是否存在网络错误、连接的 CORS 状态以及客户端发送和从服务器接收的头信息以导致该状态、收到的消息以及它们是如何被解析的,等等。
特别鼓励在开发控制台中报告详细信息,尤其是在触发 error
事件时,因为事件本身几乎无法提供任何信息。
所有当前引擎都支持。
出于安全和隐私原因,Web 浏览器阻止不同域中的文档相互影响;即,跨站脚本是被禁止的。
虽然这是一个重要的安全功能,但它阻止了来自不同域的页面在非敌对情况下进行通信。本节引入了一种消息传递系统,允许文档之间无论其来源域如何进行通信,同时设计上避免了跨站脚本攻击的发生。
postMessage()
API 可以被用作追踪向量。
本节为非规范内容。
例如,如果文档 A 包含一个包含文档 B 的 iframe
元素,并且文档 A 中的脚本调用了文档 B 的 postMessage()
,则会在文档
B 的 Window
对象上触发一个消息事件,该事件标记为来自文档 A 的 Window
对象。文档 A
中的脚本可能看起来像这样:
var o = document. getElementsByTagName( 'iframe' )[ 0 ];
o. contentWindow. postMessage( 'Hello world' , 'https://b.example.org/' );
要注册一个处理传入事件的事件处理程序,脚本可以使用 addEventListener()
(或类似机制)。例如,文档 B 中的脚本可能看起来像这样:
window. addEventListener( 'message' , receiver, false );
function receiver( e) {
if ( e. origin == 'https://example.com' ) {
if ( e. data == 'Hello world' ) {
e. source. postMessage( 'Hello' , e. origin);
} else {
alert( e. data);
}
}
}
该脚本首先检查域是否是预期的域,然后查看消息内容,决定是将其显示给用户,还是通过发送消息回最初发送消息的文档来响应。
使用此 API 需要格外小心,以防止用户受到恶意实体的攻击,这些实体可能会滥用站点为他们自己的目的服务。
作者应检查 origin
属性,以确保仅接受来自他们预期接收消息的域的消息。否则,作者消息处理代码中的错误可能会被恶意网站利用。
此外,即使在检查了 origin
属性之后,作者还应检查相关数据是否符合预期格式。否则,如果事件的来源已通过跨站脚本漏洞被攻击,使用 postMessage()
方法发送的未检查信息的进一步处理可能会导致攻击传播到接收方。
对于包含任何机密信息的消息,作者不应在消息中的 targetOrigin 参数中使用通配符 (*),否则无法保证消息仅传递给预期的接收者。
接受来自任何来源的消息的作者,建议考虑拒绝服务攻击的风险。攻击者可能会发送大量消息;如果接收页面为每条此类消息执行昂贵的计算或导致网络流量的发送,攻击者的消息可能会转化为拒绝服务攻击。建议作者采用速率限制(仅接受每分钟一定数量的消息)来使此类攻击变得不切实际。
此 API 的完整性基于以下事实:一个 源
的脚本无法向其他源(非 同源)的对象发送任意事件(使用
dispatchEvent()
或其他方式)。
实现者被强烈建议在实现此功能时格外小心。它允许作者将信息从一个域传输到另一个域,而出于安全原因通常是不允许的。这也要求用户代理小心地允许访问某些属性而不允许访问其他属性。
还建议用户代理考虑限制不同 源 之间的消息流量,以保护不太成熟的站点免受拒绝服务攻击。
window.postMessage(message [, options ])
Support in all current engines.
向指定的窗口发送消息。消息可以是结构化对象,例如嵌套对象和数组,可以包含 JavaScript 值(字符串、数字、Date
对象等),
还可以包含某些数据对象,如 File
、
Blob
、
FileList
和 ArrayBuffer
对象。
列在 options 的 transfer
成员
中的对象是被转移的,而不是仅仅被克隆,这意味着它们在发送方将不再可用。
可以使用 options 的 targetOrigin
成员指定目标源。
如果未提供,则默认为 "/
"。此默认值仅将消息限制为同源目标。
如果目标窗口的源与指定的目标源不匹配,则为了避免信息泄露,消息将被丢弃。要将消息发送到目标,无论源是什么,请将目标源设置为 "*
"。
如果 transfer 数组包含重复对象,或者 message 无法克隆,则抛出 "DataCloneError
" DOMException
。
window.postMessage(message, targetOrigin [, transfer ])
这是 postMessage()
的另一种版本,其中目标源作为参数指定。调用 window.postMessage(message, target, transfer)
等价于 window.postMessage(message, {targetOrigin,
transfer})
。
当向刚刚导航到新 文档
的 浏览上下文的 窗口
发送消息时,可能会导致消息未能传达到其预期的接收者:目标
浏览上下文中的脚本必须有时间设置接收消息的监听器。因此,例如,在将消息发送到新创建的子
iframe
的
窗口
的情况下,建议作者让子 文档
向父级发送消息以宣布其准备好接收消息,并让父级在开始发送消息之前等待此消息。
给定 targetWindow、message 和 options,窗口发送消息步骤如下:
令 targetRealm 为 targetWindow 的 领域。
令 incumbentSettings 为 现任设置对象。
令 targetOrigin 为 options["targetOrigin
"]。
如果 targetOrigin 是单个 U+002F 斜杠字符(/),则将 targetOrigin 设置为 incumbentSettings 的 源。
否则,如果 targetOrigin 不是单个 U+002A 星号字符(*),则:
令 parsedURL 为在 targetOrigin 上运行 URL 解析器 的结果。
如果 parsedURL 失败,则抛出 "SyntaxError
"
DOMException
。
将 targetOrigin 设置为 parsedURL 的 源。
令 transfer 为 options["transfer
"]。
令 serializeWithTransferResult 为 StructuredSerializeWithTransfer(message, transfer)。重新抛出任何异常。
在给定的 targetWindow 上,在 已发送消息任务源 上队列一个全局任务,以执行以下步骤:
如果 targetOrigin 参数不是单个字面 U+002A 星号字符 (*),并且 targetWindow 的 关联的
Document
的 源 不是与
targetOrigin 同源,则返回。
令 source 为与 incumbentSettings 的 全局对象(一个 Window
对象)对应的 WindowProxy
对象。
令 deserializeRecord 为 StructuredDeserializeWithTransfer(serializeWithTransferResult, targetRealm)。
如果这引发异常,捕获它,触发一个名为messageerror
的事件在 targetWindow 上,使用 MessageEvent
,其
origin
属性初始化为 origin,并且 source
属性初始化为 source,然后返回。
令 messageClone 为 deserializeRecord.[[Deserialized]]。
令 newPorts 为一个新 冻结数组,包含
deserializeRecord.[[TransferredValues]] 中的所有 MessagePort
对象(如果有),保持它们的相对顺序。
触发一个名为message
的事件在
targetWindow 上,使用 MessageEvent
,其
origin
属性初始化为 origin,source
属性初始化为 source,data
属性初始化为 messageClone,并且 ports
属性初始化为 newPorts。
Window
接口的 postMessage(message, options)
方法步骤是给定
this,message 和 options 运行 窗口发送消息步骤。
Window
接口的 postMessage(message, targetOrigin,
transfer)
方法步骤是给定 this,message 和 «[ "targetOrigin
"
→
targetOrigin, "transfer
"
→ transfer ]» 运行 窗口发送消息步骤。
在所有当前引擎中支持。
Channel_Messaging_API/Using_channel_messaging
在所有当前引擎中支持。
本节为非规范性内容。
为了使独立的代码片段(例如,在不同的浏览上下文中运行)能够直接通信,作者可以使用通道消息传递。
此机制中的通信通道实现为双向管道,每端都有一个端口。发送到一个端口的消息会在另一个端口接收,反之亦然。消息作为 DOM 事件传递,不会中断或阻塞正在运行的任务。
要创建一个连接(两个“纠缠”的端口),调用 MessageChannel()
构造函数:
var channel = new MessageChannel();
其中一个端口作为本地端口保留,另一个端口发送给远程代码,例如使用postMessage()
发送:
otherWindow. postMessage( 'hello' , 'https://example.com' , [ channel. port2]);
要发送消息,可以使用端口上的postMessage()
方法:
channel. port1. postMessage( 'hello' );
要接收消息,可以监听message
事件:
channel. port1. onmessage = handleMessage;
function handleMessage( event) {
// message is in event.data
// ...
}
通过端口发送的数据可以是结构化数据;例如,这里通过MessagePort
传递了一个字符串数组:
port1. postMessage([ 'hello' , 'world' ]);
本节为非规范性内容。
在此示例中,两个 JavaScript 库通过MessagePort
连接在一起。这允许这些库以后可以在不同的框架中或Worker
对象中托管,而无需对 API 进行任何更改。
< script src = "contacts.js" ></ script > <!-- exposes a contacts object -->
< script src = "compose-mail.js" ></ script > <!-- exposes a composer object -->
< script >
var channel = new MessageChannel();
composer. addContactsProvider( channel. port1);
contacts. registerConsumer( channel. port2);
</ script >
以下是 "addContactsProvider()" 函数实现可能的样子:
function addContactsProvider( port) {
port. onmessage = function ( event) {
switch ( event. data. messageType) {
case 'search-result' : handleSearchResult( event. data. results); break ;
case 'search-done' : handleSearchDone(); break ;
case 'search-error' : handleSearchError( event. data. message); break ;
// ...
}
};
};
或者,它可以实现如下:
function addContactsProvider( port) {
port. addEventListener( 'message' , function ( event) {
if ( event. data. messageType == 'search-result' )
handleSearchResult( event. data. results);
});
port. addEventListener( 'message' , function ( event) {
if ( event. data. messageType == 'search-done' )
handleSearchDone();
});
port. addEventListener( 'message' , function ( event) {
if ( event. data. messageType == 'search-error' )
handleSearchError( event. data. message);
});
// ...
port. start();
};
关键的区别在于,当使用 addEventListener()
时,必须同时调用 start()
方法。而使用 onmessage
时,调用 start()
是隐含的。
无论是显式调用 start()
方法,还是通过设置 onmessage
隐式调用,都会启动消息流:消息端口上发布的消息最初是暂停的,以防止在脚本有机会设置其处理程序之前消息被丢弃。
本节为非规范性内容。
端口可以被视为向系统中其他参与者暴露有限能力(在对象能力模型意义上)的一种方式。这可以是一个弱能力系统,其中端口仅作为特定来源内的方便模型,或者是一个强能力模型,其中端口由一个来源provider提供,作为另一个来源consumer影响或获取provider信息的唯一机制。
例如,考虑一种情况,一个社交网站在一个iframe
中嵌入了用户的电子邮件联系人提供者(来自第二个来源的地址簿网站),并在另一个iframe
中嵌入了一个游戏(来自第三个来源)。外部社交网站和第二个iframe
中的游戏无法访问第一个iframe
内的任何内容;它们只能:
使用window.postMessage()
API向iframe
中的窗口
发送消息
事件。
联系人提供者可以使用这些方法,尤其是第三个方法,来提供一个API,以便其他来源可以访问用户的地址簿。例如,它可以响应一条消息"add-contact Guillaume Tell
<tell@pomme.example.net>
",通过将给定的人和电子邮件地址添加到用户的地址簿。
为了避免任何网站能够操纵用户的联系人,联系人提供者可能只允许某些受信任的网站(如社交网站)这样做。
现在假设游戏想要将联系人添加到用户的地址簿,并且社交网站愿意代表它这样做,基本上是在“共享”联系人提供者与社交网站的信任。有几种方法可以做到这一点;最简单的方法是,它可以在游戏站点和联系人站点之间代理消息。但是,这种解决方案有一些困难:它要求社交网站完全信任游戏站点不会滥用这种特权,或者要求社交网站验证每个请求,以确保它不允许某些请求(例如添加多个联系人、读取联系人或删除联系人);如果多个游戏同时尝试与联系人提供者交互,则还需要一些额外的复杂性。
然而,使用消息通道和MessagePort
对象,所有这些问题都可以消除。当游戏告诉社交网站它想要添加联系人时,社交网站可以向联系人提供者请求,不是让它添加联系人,而是请求添加一个联系人的能力。然后,联系人提供者创建一对MessagePort
对象,并将其中一个发送回社交网站,社交网站将其转发给游戏。游戏和联系人提供者之间然后建立了直接连接,并且联系人提供者知道只接受一个“添加联系人”请求,其他请求一律不受理。换句话说,游戏已经被授予了添加一个联系人的能力。
本节为非规范性内容。
延续上一节的示例,特别考虑联系人提供者。虽然最初的实现可能仅仅在服务的iframe
中使用XMLHttpRequest
对象,但服务的演变可能会转向使用带有单个WebSocket
连接的共享worker。
如果最初的设计使用了MessagePort
对象来授予能力,或者仅仅是为了允许多个同时独立的会话,那么服务实现可以从每个iframe
中的XMLHttpRequest
模型切换到共享的WebSocket
模型,而无需更改
API:服务提供者端的端口可以全部转发到共享worker,而不会对 API 的用户产生丝毫影响。
所有当前引擎均支持。
[Exposed =(Window ,Worker )]
interface MessageChannel {
constructor ();
readonly attribute MessagePort port1 ;
readonly attribute MessagePort port2 ;
};
channel = new MessageChannel()
所有当前引擎均支持。
返回一个新的 MessageChannel
对象,其中包含两个新的 MessagePort
对象。
channel.port1
所有当前引擎均支持。
返回第一个 MessagePort
对象。
channel.port2
所有当前引擎均支持。
返回第二个 MessagePort
对象。
一个 MessageChannel
对象具有一个关联的端口 1和一个关联的
端口 2,它们都是 MessagePort
对象。
new MessageChannel()
构造函数的步骤是:
将 this
的
端口 1 设置为 新的
MessagePort
,
该对象位于 相关领域。
将 this
的
端口
2 设置为 新的
MessagePort
,
该对象位于 相关领域。
port1
的 getter 步骤是返回
this 的 端口 1。
port2
的 getter 步骤是返回
this 的 端口 2。
所有当前引擎均支持。
每个通道都有两个消息端口。通过一个端口发送的数据会在另一个端口接收,反之亦然。
[Exposed =(Window ,Worker ,AudioWorklet ), Transferable ]
interface MessagePort : EventTarget {
undefined postMessage (any message , sequence <object > transfer );
undefined postMessage (any message , optional StructuredSerializeOptions options = {});
undefined start ();
undefined close ();
// event handlers
attribute EventHandler onmessage ;
attribute EventHandler onmessageerror ;
attribute EventHandler onclose ;
};
dictionary StructuredSerializeOptions {
sequence <object > transfer = [];
};
port.postMessage(message [, transfer])
所有当前引擎均支持。
port.postMessage(message [, { transfer }])
通过通道发送消息。列在 transfer 中的对象会被转移,而不仅仅是克隆,这意味着它们在发送方不再可用。
如果 transfer 包含重复的对象或 port,或者 message 无法克隆,则抛出 "DataCloneError
" DOMException
。
port.start()
所有当前引擎均支持。
开始分派端口上收到的消息。
port.close()
所有当前引擎均支持。
断开端口连接,使其不再活动。
每个 MessagePort
对象都可以与另一个对象纠缠(对称关系)。
每个 MessagePort
对象还有一个称为 任务源 的
端口消息队列,初始为空。端口消息队列可以启用或禁用,初始为禁用状态。一旦启用,端口就不能再禁用(尽管队列中的消息可以转移到另一个队列或完全删除,效果基本相同)。MessagePort
还有一个 已传输 标志,初始值必须为 false。
当端口的 端口消息队列
启用时,事件循环 必须将其用作其 任务源 之一。当端口的 相关全局对象 是一个
Window
时,所有排队在其 端口消息队列 中的 任务 必须与端口的 相关全局对象 的
关联
Document
相关联。
如果文档是 完全激活的,但事件侦听器都是在非 完全激活的 文档上下文中创建的,那么消息不会被接收,除非直到这些文档再次变为 完全激活的。
每个 事件循环 都有一个称为 未传输端口消息队列 的 任务源。这是一个虚拟的 任务源:它必须表现得好像包含了每个 端口消息队列 中的 任务,其 已传输 标志为 false,端口消息队列已启用,且其 相关代理 的 事件循环 是该 事件循环,按它们添加到各自的 任务源 的顺序排列。当一个 任务 将从 未传输端口消息队列 中移除时,它必须从其 端口消息队列 中移除。
当 MessagePort
的 已传输 标志为 false
时,为事件循环的目的,其 端口消息队列
必须被忽略。(此时会使用 未传输端口消息队列。)
当端口、其双胞胎或从中克隆的对象被转移或曾经被转移时,已传输
标志被设置为 true。当 MessagePort
的 已传输 标志为 true 时,其 端口消息队列 作为一流的 任务源 运行,不受任何 未传输端口消息队列 的影响。
当用户代理要 纠缠 两个 MessagePort
对象时,必须执行以下步骤:
如果其中一个端口已经被纠缠,则解开它与其纠缠的端口。
如果这两个先前纠缠的端口是一个 MessageChannel
对象的两个端口,那么该 MessageChannel
对象不再表示实际的通道:该对象中的两个端口不再纠缠。
将要纠缠的两个端口关联起来,使它们成为新通道的两个部分。(没有表示该通道的 MessageChannel
对象。)
两个已通过此步骤的端口 A 和 B 现在被认为是纠缠的;一个与另一个纠缠,反之亦然。
虽然本规范将此过程描述为瞬间完成,但实现更可能通过消息传递来实现这一点。与所有算法一样,关键在于最终结果在黑箱意义上与规范中描述的结果不可区分。
给定发起解开的 MessagePort
initiatorPort,解开步骤如下:
让 otherPort 成为 initiatorPort 纠缠的 MessagePort
。
断言:otherPort 存在。
解开 initiatorPort 和 otherPort,使它们不再纠缠或彼此关联。
即使端口未被显式关闭,也会触发 close
事件。以下情况会触发此事件:
close()
方法;文档
被 销毁;或MessagePort
被
垃圾回收。
我们仅在 otherPort 上调度此事件,因为 initiatorPort 显式触发了关闭,它的 文档
不再存在,或已被垃圾回收,如上所述。
MessagePort
对象是
可转移对象。它们的 转移步骤,给定 value 和
dataHolder,如下:
将 value 的 已传输 标志设置为 true。
将 dataHolder 的 [[PortMessageQueue]] 设置为 value 的 端口消息队列。
如果 value 与另一个端口 remotePort 纠缠,则:
将 remotePort 的 已传输 标志设置为 true。
将 dataHolder 的 [[RemotePort]] 设置为 remotePort。
否则,将 dataHolder 的 [[RemotePort]] 设置为 null。
它们的 接收步骤,给定 dataHolder 和 value,如下:
将 value 的 已传输 标志设置为 true。
将所有将在 dataHolder 的 [[PortMessageQueue]] 中触发 message
事件的 任务 移动到 value 的
端口消息队列
中(如果有),将
value 的 端口消息队列
保持在其初始禁用状态,并且如果 value 的 相关全局对象
是一个 Window
,则将移动的 任务 与 value 的 相关全局对象
的 关联
Document
相关联。
如果 dataHolder 的 [[RemotePort]] 不为 null,则 纠缠 dataHolder 的 [[RemotePort]] 和 value。(这将解开 dataHolder 的 [[RemotePort]] 与最初转移的端口的纠缠。)
给定 sourcePort、targetPort、message 和 options 的 消息端口消息发送步骤如下:
让 transfer 成为 options["transfer
"]。
如果 transfer 包含 sourcePort,则抛出 "DataCloneError
" DOMException
。
让 doomed 为 false。
如果 targetPort 不为 null 并且 transfer 包含 targetPort,则将 doomed 设置为 true,并选择性地向开发者控制台报告目标端口发送给自身,导致通信通道丢失。
让 serializeWithTransferResult 成为 StructuredSerializeWithTransfer(message, transfer) 的结果。重新抛出任何异常。
如果 targetPort 为 null,或 doomed 为 true,则返回。
添加一个运行以下步骤的 任务 到 targetPort 的 端口消息队列 中:
让 finalTargetPort 成为 MessagePort
,任务现在位于其
端口消息队列 中。
如果 targetPort 本身被转移并因此所有任务随之移动,这可能与 targetPort 不同。
让 targetRealm 成为 finalTargetPort 的 相关领域。
让 deserializeRecord 成为 StructuredDeserializeWithTransfer(serializeWithTransferResult, targetRealm) 的结果。
如果这抛出异常,捕获它,触发 一个名为 messageerror
的事件在 finalTargetPort 上,使用 MessageEvent
,然后返回。
让 messageClone 成为 deserializeRecord.[[Deserialized]]。
让 newPorts 成为一个新的 冻结数组,由
deserializeRecord.[[TransferredValues]] 中的所有 MessagePort
对象组成(如果有),保持它们的相对顺序。
触发 一个名为 message
的事件在
finalTargetPort 上,使用 MessageEvent
,将
data
属性初始化为 messageClone,将 ports
属性初始化为 newPorts。
给定 message 和 transfer 的 postMessage(message, transfer)
方法步骤如下:
让 targetPort 成为 此 与之纠缠的端口,如果有;否则为 null。
让 options 成为 «[ "transfer
"
→ transfer ]»。
运行 消息端口消息发送步骤,提供 此、targetPort、message 和 options。
给定 sourcePort、targetPort、message 和 options 的 postMessage(message, options)
方法步骤如下:
让 targetPort 成为 此 与之纠缠的端口,如果有;否则为 null。
运行 消息端口消息发送步骤,提供 此、targetPort、message 和 options。
给定 sourcePort 的 start()
方法步骤是启用 此 的 端口消息队列,如果它尚未启用。
给定 sourcePort 的 close()
方法步骤如下:
将 此 的 [[Detached]] 内部插槽值设置为 true。
以下是 事件处理程序(及其对应的 事件处理程序事件类型)必须由所有实现 MessagePort
接口的
对象支持,作为 事件处理程序 IDL
属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onmessage
所有当前引擎均支持。 Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11.5+ |
message
|
onmessageerror
MessagePort/messageerror_event 所有当前引擎均支持。 Firefox57+Safari16.4+Chrome60+
Opera?Edge79+ Edge (旧版)18Internet Explorer不支持 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+ |
messageerror
|
onclose |
close |
第一次将 MessagePort
对象的 onmessage
IDL 属性设置时,端口的 端口消息队列 必须启用,仿佛已调用 start()
方法。
当一个 MessagePort
对象 o 被垃圾回收时,如果 o 是纠缠的,那么用户代理必须 解开纠缠
o。
当一个 MessagePort
对象 o 是纠缠的,并且注册了 message
或 messageerror
事件监听器时,用户代理必须表现得好像 o 的纠缠 MessagePort
对象对 o 有一个强引用。
此外,当 MessagePort
对象仍然存在一个由 任务
引用的事件在
任务队列 中,且该事件将要在该 MessagePort
对象上分发,或当 MessagePort
对象的 端口消息队列
已启用且不为空时,该对象不得被垃圾回收。
因此,消息端口可以被接收、分配一个事件监听器,然后被遗忘,只要该事件监听器可以接收消息,通道将被维持。
当然,如果这种情况发生在通道的两侧,那么两个端口都可能被垃圾回收,因为它们不会从活动代码中可达,尽管它们对彼此有强引用。然而,如果一个消息端口有待处理的消息,它不会被垃圾回收。
强烈建议作者明确关闭 MessagePort
对象以解开它们的纠缠,以便它们的资源可以被回收。创建许多 MessagePort
对象并在不关闭它们的情况下将其丢弃,可能导致高瞬时内存使用,因为垃圾回收不一定及时执行,尤其是对于 MessagePort
,垃圾回收可能涉及跨进程协调。
在所有当前引擎中均受支持。
在所有当前引擎中均受支持。
由同一用户在同一用户代理中打开但在不同不相关 浏览上下文 中的同一 来源 页面,有时需要互相发送通知,例如“嘿,用户在这里登录了,请重新检查您的凭据”。
对于复杂的情况,例如管理共享状态的锁定,管理服务器和多个本地客户端之间的资源同步,共享一个与远程主机的 WebSocket
连接,等等,共享
workers 是最合适的解决方案。
但对于简单的情况,如果使用共享 worker 会显得过于繁重,作者可以使用本节描述的简单基于通道的广播机制。
[Exposed =(Window ,Worker )]
interface BroadcastChannel : EventTarget {
constructor (DOMString name );
readonly attribute DOMString name ;
undefined postMessage (any message );
undefined close ();
attribute EventHandler onmessage ;
attribute EventHandler onmessageerror ;
};
broadcastChannel = new BroadcastChannel(name)
BroadcastChannel/BroadcastChannel
在所有当前引擎中均受支持。
返回一个新的 BroadcastChannel
对象,通过该对象可以发送和接收给定通道名称的消息。
broadcastChannel.name
在所有当前引擎中均受支持。
返回通道名称(在构造函数中传递)。
broadcastChannel.postMessage(message)
在所有当前引擎中均受支持。
将给定消息发送到为此通道设置的其他 BroadcastChannel
对象。消息可以是结构化对象,例如嵌套的对象和数组。
broadcastChannel.close()
在所有当前引擎中均受支持。
关闭 BroadcastChannel
对象,使其可以被垃圾回收。
一个 BroadcastChannel
对象有一个 通道名称 和一个 关闭标志。
new BroadcastChannel(name)
构造函数步骤如下:
当一个 BroadcastChannel
对象的 关闭标志 为 false 且有一个为 message
或 messageerror
事件注册的事件监听器时,必须有一个从
BroadcastChannel
对象的 相关全局对象 到
BroadcastChannel
对象本身的强引用。
close()
方法步骤是将
此对象 的 关闭标志 设置为 true。
强烈建议作者在不再需要 BroadcastChannel
对象时明确关闭它们,以便可以进行垃圾回收。创建许多
BroadcastChannel
对象并在为其留有事件监听器的情况下丢弃它们而不关闭它们,可能导致表面上的内存泄漏,因为这些对象在拥有事件监听器期间将继续存在(或直到其页面或 worker 被关闭)。
以下是 事件处理程序(及其对应的 事件处理程序事件类型),所有实现
BroadcastChannel
接口的对象必须支持这些,
作为 事件处理程序 IDL 属性。
事件处理程序 | 事件处理程序事件类型 |
---|---|
onmessage
BroadcastChannel/message_event 在所有当前引擎中均受支持。 Firefox38+Safari15.4+Chrome54+
Opera?Edge79+ Edge (旧版)?Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
message
|
onmessageerror
BroadcastChannel/messageerror_event 在所有当前引擎中均受支持。 Firefox57+Safari15.4+Chrome60+
Opera?Edge79+ Edge (旧版)?Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+ |
messageerror
|
假设某页面希望知道用户何时注销,即使用户是在同一网站的另一个标签页中注销的:
var authChannel = new BroadcastChannel( 'auth' );
authChannel. onmessage = function ( event) {
if ( event. data == 'logout' )
showLogout();
}
function logoutRequested() {
// called when the user asks us to log them out
doLogout();
showLogout();
authChannel. postMessage( 'logout' );
}
function doLogout() {
// actually log the user out (e.g. clearing cookies)
// ...
}
function showLogout() {
// update the UI to indicate we're logged out
// ...
}
所有当前引擎都支持。
本节是非规范性的。
本规范定义了一个API,用于在后台独立于任何用户界面脚本运行脚本。
这允许运行不会被响应点击或其他用户交互的脚本中断的长时间运行的脚本,并允许执行长时间任务而不需要让出以保持页面响应。
Worker(在本文中称为这些后台脚本)相对来说是重量级的,并不打算大规模使用。例如,为四百万像素的图像中的每个像素启动一个Worker是不合适的。下面的示例展示了一些Worker的适当用途。
通常,Worker被期望是长期存在的,具有较高的启动性能成本和较高的每实例内存成本。
本节是非规范性的。
Worker可以用于各种用途。以下小节展示了这些用途的各种示例。
本节是非规范性的。
Worker最简单的用途是执行计算密集型任务而不打断用户界面。
在此示例中,主文档生成一个Worker来(简单地)计算素数,并逐步显示最近找到的素数。
主页如下:
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< title > Worker example: One-core computation</ title >
</ head >
< body >
< p > The highest prime number discovered so far is: < output id = "result" ></ output ></ p >
< script >
var worker = new Worker( 'worker.js' );
worker. onmessage = function ( event) {
document. getElementById( 'result' ). textContent = event. data;
};
</ script >
</ body >
</ html >
调用 Worker()
构造函数会创建一个 worker,并返回一个表示该 worker 的
Worker
对象,该对象用于与 worker 通信。
该对象的 onmessage
事件处理程序允许代码从 worker 接收消息。
worker 本身如下:
var n = 1 ;
search: while ( true ) {
n += 1 ;
for ( var i = 2 ; i <= Math. sqrt( n); i += 1 )
if ( n % i == 0 )
continue search;
// found a prime!
postMessage( n);
}
这段代码的大部分只是一个未经优化的素数搜索。使用 postMessage()
方法在找到素数时将消息发送回页面。
本节是非规范性的。
到目前为止,我们的所有示例都展示了运行 经典脚本 的
workers。workers
还可以使用 模块脚本
来实例化,模块脚本具有通常的优点:能够使用 JavaScript 的
import
语句导入其他模块;默认启用严格模式;顶级声明不会污染 worker 的全局作用域。
由于 import
语句是可用的,importScripts()
方法在模块 workers 内将自动失效。
在此示例中,主文档使用 worker 在主线程外进行图像处理。它从另一个模块导入所使用的滤镜。
主页如下:
<!DOCTYPE html>
< html lang = "en" >
< meta charset = "utf-8" >
< title > Worker example: image decoding</ title >
< p >
< label >
Type an image URL to decode
< input type = "url" id = "image-url" list = "image-list" >
< datalist id = "image-list" >
< option value = "https://html.spec.whatwg.org/images/drawImage.png" >
< option value = "https://html.spec.whatwg.org/images/robots.jpeg" >
< option value = "https://html.spec.whatwg.org/images/arcTo2.png" >
</ datalist >
</ label >
</ p >
< p >
< label >
Choose a filter to apply
< select id = "filter" >
< option value = "none" > none</ option >
< option value = "grayscale" > grayscale</ option >
< option value = "brighten" > brighten by 20%</ option >
</ select >
</ label >
</ p >
< div id = "output" ></ div >
< script type = "module" >
const worker = new Worker( "worker.js" , { type: "module" });
worker. onmessage = receiveFromWorker;
const url = document. querySelector( "#image-url" );
const filter = document. querySelector( "#filter" );
const output = document. querySelector( "#output" );
url. oninput = updateImage;
filter. oninput = sendToWorker;
let imageData, context;
function updateImage() {
const img = new Image();
img. src = url. value;
img. onload = () => {
const canvas = document. createElement( "canvas" );
canvas. width = img. width;
canvas. height = img. height;
context = canvas. getContext( "2d" );
context. drawImage( img, 0 , 0 );
imageData = context. getImageData( 0 , 0 , canvas. width, canvas. height);
sendToWorker();
output. replaceChildren( canvas);
};
}
function sendToWorker() {
worker. postMessage({ imageData, filter: filter. value });
}
function receiveFromWorker( e) {
context. putImageData( e. data, 0 , 0 );
}
</ script >
worker 文件如下:
import * as filters from "./filters.js" ;
self. onmessage = e => {
const { imageData, filter } = e. data;
filters[ filter]( imageData);
self. postMessage( imageData, [ imageData. data. buffer]);
};
它会导入文件 filters.js
:
export function none() {}
export function grayscale({ data: d }) {
for ( let i = 0 ; i < d. length; i += 4 ) {
const [ r, g, b] = [ d[ i], d[ i + 1 ], d[ i + 2 ]];
// CIE luminance for the RGB
// The human eye is bad at seeing red and blue, so we de-emphasize them.
d[ i] = d[ i + 1 ] = d[ i + 2 ] = 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
};
export function brighten({ data: d }) {
for ( let i = 0 ; i < d. length; ++ i) {
d[ i] *= 1.2 ;
}
};
所有当前引擎都支持。
本节是非规范性的。
本节通过一个 Hello World 示例介绍了 shared workers。由于每个 worker 可以有多个连接,因此 shared workers 使用略有不同的 API。
第一个示例展示了如何连接到 worker,以及 worker 如何在连接到页面时将消息发送回页面。接收到的消息将显示在日志中。
以下是 HTML 页面:
<!DOCTYPE HTML>
< html lang = "en" >
< meta charset = "utf-8" >
< title > Shared workers: demo 1</ title >
< pre id = "log" > Log:</ pre >
< script >
var worker = new SharedWorker( 'test.js' );
var log = document. getElementById( 'log' );
worker. port. onmessage = function ( e) { // note: not worker.onmessage!
log. textContent += '\n' + e. data;
}
</ script >
以下是 JavaScript worker:
onconnect = function ( e) {
var port = e. ports[ 0 ];
port. postMessage( 'Hello World!' );
}
第二个示例通过改变两件事扩展了第一个示例:首先,消息是通过 addEventListener()
接收的,而不是通过 事件处理程序 IDL 属性;其次,消息会发送到 worker,从而导致
worker 返回另一条消息。接收到的消息同样显示在日志中。
以下是 HTML 页面:
<!DOCTYPE HTML>
< html lang = "en" >
< meta charset = "utf-8" >
< title > Shared workers: demo 2</ title >
< pre id = "log" > Log:</ pre >
< script >
var worker = new SharedWorker( 'test.js' );
var log = document. getElementById( 'log' );
worker. port. addEventListener( 'message' , function ( e) {
log. textContent += '\n' + e. data;
}, false );
worker. port. start(); // note: need this when using addEventListener
worker. port. postMessage( 'ping' );
</ script >
以下是 JavaScript worker:
onconnect = function ( e) {
var port = e. ports[ 0 ];
port. postMessage( 'Hello World!' );
port. onmessage = function ( e) {
port. postMessage( 'pong' ); // not e.ports[0].postMessage!
// e.target.postMessage('pong'); would work also
}
}
最后,示例进行了扩展,以展示如何让两个页面连接到同一个 worker;在这种情况下,第二个页面仅仅是第一个页面中的一个 iframe
,但同样的原理也适用于在一个单独的
顶级可遍历页面中的完全独立的页面。
以下是外部 HTML 页面:
<!DOCTYPE HTML>
< html lang = "en" >
< meta charset = "utf-8" >
< title > Shared workers: demo 3</ title >
< pre id = "log" > Log:</ pre >
< script >
var worker = new SharedWorker( 'test.js' );
var log = document. getElementById( 'log' );
worker. port. addEventListener( 'message' , function ( e) {
log. textContent += '\n' + e. data;
}, false );
worker. port. start();
worker. port. postMessage( 'ping' );
</ script >
< iframe src = "inner.html" ></ iframe >
以下是内部 HTML 页面:
<!DOCTYPE HTML>
< html lang = "en" >
< meta charset = "utf-8" >
< title > Shared workers: demo 3 inner frame</ title >
< pre id = log > Inner log:</ pre >
< script >
var worker = new SharedWorker( 'test.js' );
var log = document. getElementById( 'log' );
worker. port. onmessage = function ( e) {
log. textContent += '\n' + e. data;
}
</ script >
以下是 JavaScript worker:
var count = 0 ;
onconnect = function ( e) {
count += 1 ;
var port = e. ports[ 0 ];
port. postMessage( 'Hello World! You are connection #' + count);
port. onmessage = function ( e) {
port. postMessage( 'pong' );
}
}
本节是非规范性的。
在此示例中,可以打开多个窗口(视图),所有窗口都在查看同一张地图。所有窗口共享相同的地图信息,并由一个 worker 协调所有视图。每个视图可以独立移动,但如果它们在地图上设置任何数据,所有视图都会更新。
主页面并不特别有趣,它只是提供了一种打开视图的方法:
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< title > Workers example: Multiviewer</ title >
< script >
function openViewer() {
window. open( 'viewer.html' );
}
</ script >
</ head >
< body >
< p >< button type = button onclick = "openViewer()" > Open a new
viewer</ button ></ p >
< p > Each viewer opens in a new window. You can have as many viewers
as you like, they all view the same data.</ p >
</ body >
</ html >
视图部分更为复杂:
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< title > Workers example: Multiviewer viewer</ title >
< script >
var worker = new SharedWorker( 'worker.js' , 'core' );
// CONFIGURATION
function configure( event) {
if ( event. data. substr( 0 , 4 ) != 'cfg ' ) return ;
var name = event. data. substr( 4 ). split( ' ' , 1 )[ 0 ];
// update display to mention our name is name
document. getElementsByTagName( 'h1' )[ 0 ]. textContent += ' ' + name;
// no longer need this listener
worker. port. removeEventListener( 'message' , configure, false );
}
worker. port. addEventListener( 'message' , configure, false );
// MAP
function paintMap( event) {
if ( event. data. substr( 0 , 4 ) != 'map ' ) return ;
var data = event. data. substr( 4 ). split( ',' );
// display tiles data[0] .. data[8]
var canvas = document. getElementById( 'map' );
var context = canvas. getContext( '2d' );
for ( var y = 0 ; y < 3 ; y += 1 ) {
for ( var x = 0 ; x < 3 ; x += 1 ) {
var tile = data[ y * 3 + x];
if ( tile == '0' )
context. fillStyle = 'green' ;
else
context. fillStyle = 'maroon' ;
context. fillRect( x * 50 , y * 50 , 50 , 50 );
}
}
}
worker. port. addEventListener( 'message' , paintMap, false );
// PUBLIC CHAT
function updatePublicChat( event) {
if ( event. data. substr( 0 , 4 ) != 'txt ' ) return ;
var name = event. data. substr( 4 ). split( ' ' , 1 )[ 0 ];
var message = event. data. substr( 4 + name. length + 1 );
// display "<name> message" in public chat
var public = document. getElementById( 'public' );
var p = document. createElement( 'p' );
var n = document. createElement( 'button' );
n. textContent = '<' + name + '> ' ;
n. onclick = function () { worker. port. postMessage( 'msg ' + name); };
p. appendChild( n);
var m = document. createElement( 'span' );
m. textContent = message;
p. appendChild( m);
public. appendChild( p);
}
worker. port. addEventListener( 'message' , updatePublicChat, false );
// PRIVATE CHAT
function startPrivateChat( event) {
if ( event. data. substr( 0 , 4 ) != 'msg ' ) return ;
var name = event. data. substr( 4 ). split( ' ' , 1 )[ 0 ];
var port = event. ports[ 0 ];
// display a private chat UI
var ul = document. getElementById( 'private' );
var li = document. createElement( 'li' );
var h3 = document. createElement( 'h3' );
h3. textContent = 'Private chat with ' + name;
li. appendChild( h3);
var div = document. createElement( 'div' );
var addMessage = function ( name, message) {
var p = document. createElement( 'p' );
var n = document. createElement( 'strong' );
n. textContent = '<' + name + '> ' ;
p. appendChild( n);
var t = document. createElement( 'span' );
t. textContent = message;
p. appendChild( t);
div. appendChild( p);
};
port. onmessage = function ( event) {
addMessage( name, event. data);
};
li. appendChild( div);
var form = document. createElement( 'form' );
var p = document. createElement( 'p' );
var input = document. createElement( 'input' );
input. size = 50 ;
p. appendChild( input);
p. appendChild( document. createTextNode( ' ' ));
var button = document. createElement( 'button' );
button. textContent = 'Post' ;
p. appendChild( button);
form. onsubmit = function () {
port. postMessage( input. value);
addMessage( 'me' , input. value);
input. value = '' ;
return false ;
};
form. appendChild( p);
li. appendChild( form);
ul. appendChild( li);
}
worker. port. addEventListener( 'message' , startPrivateChat, false );
worker. port. start();
</ script >
</ head >
< body >
< h1 > Viewer</ h1 >
< h2 > Map</ h2 >
< p >< canvas id = "map" height = 150 width = 150 ></ canvas ></ p >
< p >
< button type = button onclick = "worker.port.postMessage('mov left')" > Left</ button >
< button type = button onclick = "worker.port.postMessage('mov up')" > Up</ button >
< button type = button onclick = "worker.port.postMessage('mov down')" > Down</ button >
< button type = button onclick = "worker.port.postMessage('mov right')" > Right</ button >
< button type = button onclick = "worker.port.postMessage('set 0')" > Set 0</ button >
< button type = button onclick = "worker.port.postMessage('set 1')" > Set 1</ button >
</ p >
< h2 > Public Chat</ h2 >
< div id = "public" ></ div >
< form onsubmit = "worker.port.postMessage('txt ' + message.value); message.value = ''; return false;" >
< p >
< input type = "text" name = "message" size = "50" >
< button > Post</ button >
</ p >
</ form >
< h2 > Private Chat</ h2 >
< ul id = "private" ></ ul >
</ body >
</ html >
关于视图的编写方式,有几个关键点值得注意。
多个监听器。代码在此处附加了多个事件监听器,而不是使用单一的消息处理函数。每个监听器都会快速检查消息是否与之相关。在这个示例中,这没有太大区别,但如果多个作者想要使用单一端口与 worker 进行通信,这种方法允许代码独立工作,而不需要对单一事件处理函数进行修改。
以这种方式注册事件监听器还允许在完成后注销特定的监听器,正如在此示例中的 configure()
方法中所做的那样。
最后是 worker:
var nextName = 0 ;
function getNextName() {
// this could use more friendly names
// but for now just return a number
return nextName++ ;
}
var map = [
[ 0 , 0 , 0 , 0 , 0 , 0 , 0 ],
[ 1 , 1 , 0 , 1 , 0 , 1 , 1 ],
[ 0 , 1 , 0 , 1 , 0 , 0 , 0 ],
[ 0 , 1 , 0 , 1 , 0 , 1 , 1 ],
[ 0 , 0 , 0 , 1 , 0 , 0 , 0 ],
[ 1 , 0 , 0 , 1 , 1 , 1 , 1 ],
[ 1 , 1 , 0 , 1 , 1 , 0 , 1 ],
];
function wrapX( x) {
if ( x < 0 ) return wrapX( x + map[ 0 ]. length);
if ( x >= map[ 0 ]. length) return wrapX( x - map[ 0 ]. length);
return x;
}
function wrapY( y) {
if ( y < 0 ) return wrapY( y + map. length);
if ( y >= map[ 0 ]. length) return wrapY( y - map. length);
return y;
}
function wrap( val, min, max) {
if ( val < min)
return val + ( max- min) + 1 ;
if ( val > max)
return val - ( max- min) - 1 ;
return val;
}
function sendMapData( viewer) {
var data = '' ;
for ( var y = viewer. y- 1 ; y <= viewer. y+ 1 ; y += 1 ) {
for ( var x = viewer. x- 1 ; x <= viewer. x+ 1 ; x += 1 ) {
if ( data != '' )
data += ',' ;
data += map[ wrap( y, 0 , map[ 0 ]. length- 1 )][ wrap( x, 0 , map. length- 1 )];
}
}
viewer. port. postMessage( 'map ' + data);
}
var viewers = {};
onconnect = function ( event) {
var name = getNextName();
event. ports[ 0 ]. _data = { port: event. ports[ 0 ], name: name, x: 0 , y: 0 , };
viewers[ name] = event. ports[ 0 ]. _data;
event. ports[ 0 ]. postMessage( 'cfg ' + name);
event. ports[ 0 ]. onmessage = getMessage;
sendMapData( event. ports[ 0 ]. _data);
};
function getMessage( event) {
switch ( event. data. substr( 0 , 4 )) {
case 'mov ' :
var direction = event. data. substr( 4 );
var dx = 0 ;
var dy = 0 ;
switch ( direction) {
case 'up' : dy = - 1 ; break ;
case 'down' : dy = 1 ; break ;
case 'left' : dx = - 1 ; break ;
case 'right' : dx = 1 ; break ;
}
event. target. _data. x = wrapX( event. target. _data. x + dx);
event. target. _data. y = wrapY( event. target. _data. y + dy);
sendMapData( event. target. _data);
break ;
case 'set ' :
var value = event. data. substr( 4 );
map[ event. target. _data. y][ event. target. _data. x] = value;
for ( var viewer in viewers)
sendMapData( viewers[ viewer]);
break ;
case 'txt ' :
var name = event. target. _data. name;
var message = event. data. substr( 4 );
for ( var viewer in viewers)
viewers[ viewer]. port. postMessage( 'txt ' + name + ' ' + message);
break ;
case 'msg ' :
var party1 = event. target. _data;
var party2 = viewers[ event. data. substr( 4 ). split( ' ' , 1 )[ 0 ]];
if ( party2) {
var channel = new MessageChannel();
party1. port. postMessage( 'msg ' + party2. name, [ channel. port1]);
party2. port. postMessage( 'msg ' + party1. name, [ channel. port2]);
}
break ;
}
}
连接多个页面。脚本使用 onconnect
事件监听器来监听多个连接。
直接通道。当 worker 从一个视图接收到名为“msg”的消息并指定另一个视图时,它会在两个视图之间建立直接连接,这样两个视图就可以直接通信,而无需 worker 代理所有消息。
本节是非规范性的。
随着多核 CPU 的普及,获得更好性能的一种方法是将计算密集型任务拆分给多个 workers。在此示例中,一个需要对 1 到 10,000,000 之间的每个数字执行的计算密集型任务被分配给十个子 workers。
主页面如下,仅用于报告结果:
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< title > Worker example: Multicore computation</ title >
</ head >
< body >
< p > Result: < output id = "result" ></ output ></ p >
< script >
var worker = new Worker( 'worker.js' );
worker. onmessage = function ( event) {
document. getElementById( 'result' ). textContent = event. data;
};
</ script >
</ body >
</ html >
worker 本身如下:
// settings
var num_workers = 10 ;
var items_per_worker = 1000000 ;
// start the workers
var result = 0 ;
var pending_workers = num_workers;
for ( var i = 0 ; i < num_workers; i += 1 ) {
var worker = new Worker( 'core.js' );
worker. postMessage( i * items_per_worker);
worker. postMessage(( i+ 1 ) * items_per_worker);
worker. onmessage = storeResult;
}
// handle the results
function storeResult( event) {
result += 1 * event. data;
pending_workers -= 1 ;
if ( pending_workers <= 0 )
postMessage( result); // finished!
}
它包括一个用于启动子 workers 的循环,然后是一个等待所有子 workers 响应的处理程序。
子 workers 的实现如下:
var start;
onmessage = getStart;
function getStart( event) {
start = 1 * event. data;
onmessage = getEnd;
}
var end;
function getEnd( event) {
end = 1 * event. data;
onmessage = null ;
work();
}
function work() {
var result = 0 ;
for ( var i = start; i < end; i += 1 ) {
// perform some complex calculation here
result += 1 ;
}
postMessage( result);
close();
}
它们在两个事件中接收两个数字,然后对指定范围内的数字执行计算,并将结果报告回父 worker。
本节是非规范性的。
假设有一个加密库可用,它提供以下三个任务:
该库本身如下:
function handleMessage( e) {
if ( e. data == "genkeys" )
genkeys( e. ports[ 0 ]);
else if ( e. data == "encrypt" )
encrypt( e. ports[ 0 ]);
else if ( e. data == "decrypt" )
decrypt( e. ports[ 0 ]);
}
function genkeys( p) {
var keys = _generateKeyPair();
p. postMessage( keys[ 0 ]);
p. postMessage( keys[ 1 ]);
}
function encrypt( p) {
var key, state = 0 ;
p. onmessage = function ( e) {
if ( state == 0 ) {
key = e. data;
state = 1 ;
} else {
p. postMessage( _encrypt( key, e. data));
}
};
}
function decrypt( p) {
var key, state = 0 ;
p. onmessage = function ( e) {
if ( state == 0 ) {
key = e. data;
state = 1 ;
} else {
p. postMessage( _decrypt( key, e. data));
}
};
}
// support being used as a shared worker as well as a dedicated worker
if ( 'onmessage' in this ) // dedicated worker
onmessage = handleMessage;
else // shared worker
onconnect = function ( e) { e. port. onmessage = handleMessage; }
// the "crypto" functions:
function _generateKeyPair() {
return [ Math. random(), Math. random()];
}
function _encrypt( k, s) {
return 'encrypted-' + k + ' ' + s;
}
function _decrypt( k, s) {
return s. substr( s. indexOf( ' ' ) + 1 );
}
请注意,这里的加密函数只是占位符,并不执行实际的加密操作。
该库可以如下使用:
<!DOCTYPE HTML>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< title > Worker example: Crypto library</ title >
< script >
const cryptoLib = new Worker( 'libcrypto-v1.js' ); // or could use 'libcrypto-v2.js'
function startConversation( source, message) {
const messageChannel = new MessageChannel();
source. postMessage( message, [ messageChannel. port2]);
return messageChannel. port1;
}
function getKeys() {
let state = 0 ;
startConversation( cryptoLib, "genkeys" ). onmessage = function ( e) {
if ( state === 0 )
document. getElementById( 'public' ). value = e. data;
else if ( state === 1 )
document. getElementById( 'private' ). value = e. data;
state += 1 ;
};
}
function enc() {
const port = startConversation( cryptoLib, "encrypt" );
port. postMessage( document. getElementById( 'public' ). value);
port. postMessage( document. getElementById( 'input' ). value);
port. onmessage = function ( e) {
document. getElementById( 'input' ). value = e. data;
port. close();
};
}
function dec() {
const port = startConversation( cryptoLib, "decrypt" );
port. postMessage( document. getElementById( 'private' ). value);
port. postMessage( document. getElementById( 'input' ). value);
port. onmessage = function ( e) {
document. getElementById( 'input' ). value = e. data;
port. close();
};
}
</ script >
< style >
textarea { display : block ; }
</ style >
</ head >
< body onload = "getKeys()" >
< fieldset >
< legend > Keys</ legend >
< p >< label > Public Key: < textarea id = "public" ></ textarea ></ label ></ p >
< p >< label > Private Key: < textarea id = "private" ></ textarea ></ label ></ p >
</ fieldset >
< p >< label > Input: < textarea id = "input" ></ textarea ></ label ></ p >
< p >< button onclick = "enc()" > Encrypt</ button > < button onclick = "dec()" > Decrypt</ button ></ p >
</ body >
</ html >
不过,API 的后续版本可能希望将所有加密工作卸载到子 workers 上。可以按如下方式完成:
function handleMessage( e) {
if ( e. data == "genkeys" )
genkeys( e. ports[ 0 ]);
else if ( e. data == "encrypt" )
encrypt( e. ports[ 0 ]);
else if ( e. data == "decrypt" )
decrypt( e. ports[ 0 ]);
}
function genkeys( p) {
var generator = new Worker( 'libcrypto-v2-generator.js' );
generator. postMessage( '' , [ p]);
}
function encrypt( p) {
p. onmessage = function ( e) {
var key = e. data;
var encryptor = new Worker( 'libcrypto-v2-encryptor.js' );
encryptor. postMessage( key, [ p]);
};
}
function encrypt( p) {
p. onmessage = function ( e) {
var key = e. data;
var decryptor = new Worker( 'libcrypto-v2-decryptor.js' );
decryptor. postMessage( key, [ p]);
};
}
// support being used as a shared worker as well as a dedicated worker
if ( 'onmessage' in this ) // dedicated worker
onmessage = handleMessage;
else // shared worker
onconnect = function ( e) { e. ports[ 0 ]. onmessage = handleMessage };
小型子 workers 的代码如下。
用于生成密钥对:
onmessage = function ( e) {
var k = _generateKeyPair();
e. ports[ 0 ]. postMessage( k[ 0 ]);
e. ports[ 0 ]. postMessage( k[ 1 ]);
close();
}
function _generateKeyPair() {
return [ Math. random(), Math. random()];
}
用于加密:
onmessage = function ( e) {
var key = e. data;
e. ports[ 0 ]. onmessage = function ( e) {
var s = e. data;
postMessage( _encrypt( key, s));
}
}
function _encrypt( k, s) {
return 'encrypted-' + k + ' ' + s;
}
用于解密:
onmessage = function ( e) {
var key = e. data;
e. ports[ 0 ]. onmessage = function ( e) {
var s = e. data;
postMessage( _decrypt( key, s));
}
}
function _decrypt( k, s) {
return s. substr( s. indexOf( ' ' ) + 1 );
}
请注意,API 的用户甚至不必知道这些操作正在发生——API 没有改变;该库可以将任务委托给子 workers,而无需更改其 API,即使它是通过消息通道接收数据的。
本节是非规范性的。
创建一个 worker 需要一个指向 JavaScript 文件的 URL。Worker()
构造函数以该文件的 URL 作为其唯一参数被调用;然后创建并返回一个 worker:
var worker = new Worker( 'helper.js' );
如果你希望你的 worker 脚本被解释为 模块脚本 而不是默认的 经典脚本,你需要使用稍微不同的签名:
var worker = new Worker( 'helper.mjs' , { type: "module" });
本节是非规范性的。
专用 workers 在后台使用 MessagePort
对象,因此支持所有相同的功能,例如发送结构化数据、传输二进制数据和传输其他端口。
要从专用 worker 接收消息,请在 onmessage
事件处理程序 IDL 属性上使用 Worker
对象:
worker. onmessage = function ( event) { ... };
你还可以使用 addEventListener()
方法。
专用 workers 使用的隐式 MessagePort
在创建时隐式启用其 端口消息队列,因此在
Worker
接口上没有相当于 MessagePort
接口的 start()
方法。
要发送数据到 worker,请使用 postMessage()
方法。可以通过此通信通道发送结构化数据。要高效传输 ArrayBuffer
对象(通过转移它们而不是克隆它们),将它们列在第二个参数中的数组中。
worker. postMessage({
operation: 'find-edges' ,
input: buffer, // an ArrayBuffer object
threshold: 0.6 ,
}, [ buffer]);
要在 worker 内部接收消息,请使用 onmessage
事件处理程序 IDL 属性。
onmessage = function ( event) { ... };
你同样还可以使用 addEventListener()
方法。
在这两种情况下,数据都通过事件对象的 data
属性提供。
要发送消息回去,你仍然使用 postMessage()
。它以相同的方式支持结构化数据。
postMessage( event. data. input, [ event. data. input]); // transfer the buffer back
所有当前引擎都支持。
本节是非规范性的。
Shared workers 是通过用于创建它的脚本的 URL 来标识的,选项上可以加上一个显式名称。该名称允许启动特定 shared worker 的多个实例。
Shared workers 由 来源 进行范围限定。两个使用相同名称的不同站点不会发生冲突。然而,如果一个页面尝试使用与同一站点的另一个页面相同的 shared worker 名称,但使用不同的脚本 URL,则会失败。
创建 shared workers 是通过 SharedWorker()
构造函数完成的。此构造函数将要使用的脚本的 URL 作为第一个参数,worker 的名称(如果有)作为第二个参数。
var worker = new SharedWorker( 'service.js' );
与 shared workers 通信是通过显式的 MessagePort
对象进行的。由
SharedWorker()
构造函数返回的对象在其 port
属性中持有一个对端口的引用。
worker. port. onmessage = function ( event) { ... };
worker. port. postMessage( 'some message' );
worker. port. postMessage({ foo: 'structured' , bar: [ 'data' , 'also' , 'possible' ]});
在 shared worker 内部,worker 的新客户端通过 connect
事件宣布。新客户端的端口通过事件对象的 source
属性获得。
onconnect = function ( event) {
var newPort = event. source;
// set up a listener
newPort. onmessage = function ( event) { ... };
// send a message back to the port
newPort. postMessage( 'ready!' ); // can also send structured data, of course
};
本标准定义了两种类型的 workers:专用 workers 和 shared workers。专用 workers 一旦创建,就会与其创建者关联,但可以使用消息端口从专用 worker 与多个其他浏览上下文或 workers 通信。另一方面,shared workers 是有名称的,一旦创建,运行在同一 来源 的任何脚本都可以获取到该 worker 的引用并与之通信。Service Workers 定义了第三种类型。[SW]
全局作用域是 worker 的“内部”。
WorkerGlobalScope
公共接口所有当前引擎都支持。
[Exposed =Worker ]
interface WorkerGlobalScope : EventTarget {
readonly attribute WorkerGlobalScope self ;
readonly attribute WorkerLocation location ;
readonly attribute WorkerNavigator navigator ;
undefined importScripts ((TrustedScriptURL
or USVString )... urls );
attribute OnErrorEventHandler onerror ;
attribute EventHandler onlanguagechange ;
attribute EventHandler onoffline ;
attribute EventHandler ononline ;
attribute EventHandler onrejectionhandled ;
attribute EventHandler onunhandledrejection ;
};
WorkerGlobalScope
作为特定类型的 worker 全局作用域对象的基类,包括 DedicatedWorkerGlobalScope
、SharedWorkerGlobalScope
和 ServiceWorkerGlobalScope
。
一个 WorkerGlobalScope
对象有一个关联的 所有者集(一组
Document
和 WorkerGlobalScope
对象)。它最初是空的,在创建或获取 worker 时填充。
这是一个 集合,而不是单个所有者,以适应 SharedWorkerGlobalScope
对象。
一个 WorkerGlobalScope
对象有一个关联的 类型("classic
" 或 "module
")。它在创建时设置。
一个 WorkerGlobalScope
对象有一个关联的 url(null
或
URL)。它最初为 null。
一个 WorkerGlobalScope
对象有一个关联的 名称(一个字符串)。它在创建时设置。
对于每个 WorkerGlobalScope
子类,名称可以有不同的语义。对于 DedicatedWorkerGlobalScope
实例,它只是一个由开发者提供的名称,主要用于调试目的。对于 SharedWorkerGlobalScope
实例,它允许通过 SharedWorker()
构造函数获取到公共 shared worker 的引用。对于 ServiceWorkerGlobalScope
对象,它没有意义(因此在 JavaScript API 中根本不暴露)。
一个 WorkerGlobalScope
对象有一个关联的 策略容器(一个 策略容器)。它最初是一个新的 策略容器。
一个 WorkerGlobalScope
对象有一个关联的 嵌入器策略(一个 嵌入器策略)。
一个 WorkerGlobalScope
对象有一个关联的 模块映射。它是一个 模块映射,最初为空。
一个 WorkerGlobalScope
对象有一个关联的 跨来源隔离能力 布尔值。它最初为 false。
workerGlobal.self
所有当前引擎都支持。
workerGlobal.location
所有当前引擎都支持。
WorkerLocation
对象。workerGlobal.navigator
所有当前引擎都支持。
WorkerNavigator
对象。workerGlobal.importScripts(...urls)
WorkerGlobalScope/importScripts
所有当前引擎都支持。
self
属性必须返回 WorkerGlobalScope
对象本身。
location
属性必须返回 WorkerLocation
对象,其关联的 WorkerGlobalScope
对象 是 WorkerGlobalScope
对象。
虽然 WorkerLocation
对象在 WorkerGlobalScope
对象之后创建,但这并不成问题,因为从脚本中无法观察到这一点。
以下是必须支持的 事件处理程序(及其对应的
事件处理程序事件类型),它们作为 事件处理程序 IDL 属性,由实现 WorkerGlobalScope
接口的对象支持:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onerror
所有当前引擎都支持。 Firefox3.5+Safari4+Chrome4+
Opera11.5+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android? |
error
|
onlanguagechange
WorkerGlobalScope/languagechange_event 所有当前引擎都支持。 Firefox74+Safari4+Chrome4+
Opera11.5+Edge79+ Edge (旧版)?Internet Explorer不支持 Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
languagechange
|
onoffline
WorkerGlobalScope/offline_event Firefox29+Safari8+Chrome不支持
Opera?Edge不支持 Edge (旧版)?Internet Explorer不支持 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
offline
|
ononline
WorkerGlobalScope/online_event Firefox29+Safari8+Chrome不支持
Opera?Edge不支持 Edge (旧版)?Internet Explorer不支持 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
online
|
onrejectionhandled |
rejectionhandled
|
onunhandledrejection |
unhandledrejection
|
DedicatedWorkerGlobalScope
接口当前所有引擎均支持。
[Global =(Worker ,DedicatedWorker ),Exposed =DedicatedWorker ]
interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
[Replaceable ] readonly attribute DOMString name ;
undefined postMessage (any message , sequence <object > transfer );
undefined postMessage (any message , optional StructuredSerializeOptions options = {});
undefined close ();
attribute EventHandler onmessage ;
attribute EventHandler onmessageerror ;
};
DedicatedWorkerGlobalScope
对象的行为类似于它们有一个与之关联的隐式MessagePort
。该端口是
worker 创建时设置的通道的一部分,但未公开。在DedicatedWorkerGlobalScope
对象之前,此对象绝不能被垃圾回收。
该端口收到的所有消息必须立即重新定向到DedicatedWorkerGlobalScope
对象。
dedicatedWorkerGlobal.name
DedicatedWorkerGlobalScope/name
当前所有引擎均支持。
dedicatedWorkerGlobal.postMessage(message [, transfer ])
DedicatedWorkerGlobalScope/postMessage
当前所有引擎均支持。
dedicatedWorkerGlobal.postMessage(message [, { transfer } ])
克隆message并将其传输到与dedicatedWorkerGlobal关联的Worker
对象。transfer可以作为要传输而不是克隆的对象列表传递。
dedicatedWorkerGlobal.close()
DedicatedWorkerGlobalScope/close
当前所有引擎均支持。
终止dedicatedWorkerGlobal。
name
获取步骤是返回this的name。
它的值表示使用Worker
构造函数赋予 worker 的名称,主要用于调试。
postMessage(message,
transfer)
和postMessage(message,
options)
方法在DedicatedWorkerGlobalScope
对象上执行时,
其行为类似于它们立即调用端口上的postMessage(message, transfer)
和postMessage(message,
options)
,并返回相同的返回值。
要关闭一个 worker,给定一个workerGlobal,执行以下步骤:
丢弃已添加到workerGlobal的tasks的任何relevant agent的event loop的task queues。
将workerGlobal的closing 标志设置为 true。(这将阻止进一步的任务排队。)
close()
方法的步骤是给定关闭一个 worker,给定this。
以下是必须由实现DedicatedWorkerGlobalScope
接口的对象支持的事件处理程序(及其对应的事件处理程序事件类型),作为事件处理程序IDL属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onmessage
DedicatedWorkerGlobalScope/message_event 当前所有引擎均支持。 Firefox3.5+Safari
4+Chrome4+
Opera10.6+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android11.5+ |
message
|
onmessageerror
DedicatedWorkerGlobalScope/messageerror_event 当前所有引擎均支持。 Firefox57+Safari16.4+Chrome60+
Opera?Edge79+ Edge (旧版)18Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+ |
messageerror
|
SharedWorkerGlobalScope
接口
当前所有引擎均支持。
[Global =(Worker ,SharedWorker ),Exposed =SharedWorker ]
interface SharedWorkerGlobalScope : WorkerGlobalScope {
[Replaceable ] readonly attribute DOMString name ;
undefined close ();
attribute EventHandler onconnect ;
};
SharedWorkerGlobalScope
对象具有关联的构造源、构造URL和凭据。它们在SharedWorkerGlobalScope
对象创建时,在运行worker算法中初始化。
Shared workers通过connect
事件在其SharedWorkerGlobalScope
对象上接收消息端口,针对每个连接。
sharedWorkerGlobal.name
当前所有引擎均支持。
返回sharedWorkerGlobal的name,即赋予SharedWorker
构造函数的值。多个SharedWorker
对象可以通过重用相同的名称对应于同一个 shared worker(及SharedWorkerGlobalScope
)。
sharedWorkerGlobal.close()
当前所有引擎均支持。
终止sharedWorkerGlobal。
name
获取步骤是返回this的name。它的值表示可以使用SharedWorker
构造函数获取对worker的引用的名称。
close()
方法的步骤是给定关闭一个worker,给定this。
以下是必须由实现SharedWorkerGlobalScope
接口的对象支持的事件处理程序(及其对应的事件处理程序事件类型),作为事件处理程序IDL属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onconnect
SharedWorkerGlobalScope/connect_event 当前所有引擎均支持。 Firefox29+Safari16+Chrome4+
Opera10.6+Edge79+ Edge (旧版)?Internet ExplorerNo Firefox Android?Safari iOS16+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
connect
|
worker事件循环的任务队列仅包含事件、回调和网络活动作为任务。这些worker事件循环由运行worker算法创建。
每个WorkerGlobalScope
对象都有一个关闭标志,最初必须为false,但可以通过以下处理模型部分中的算法将其设置为true。
一旦WorkerGlobalScope
的关闭标志设置为true,事件循环的任务队列必须丢弃任何将添加到其中的进一步任务(除非另有规定,否则已经在队列中的任务不受影响)。实际上,一旦关闭标志为true,计时器停止触发,所有待处理的后台操作通知将被丢弃,等等。
Workers通过消息通道及其MessagePort
对象与其他workers和Window
进行通信。
每个WorkerGlobalScope
对象worker
global scope有一个worker的端口列表,该列表由与另一个端口纠缠并且只有一个端口由worker global scope拥有的所有MessagePort
对象组成。在专用worker的情况下,此列表包括隐式MessagePort
。
在创建或获取worker时,给定一个环境设置对象o,要添加的相关所有者取决于o指定的全局对象的类型。如果o的全局对象是WorkerGlobalScope
对象(即,如果我们正在创建嵌套的专用worker),则相关所有者是该全局对象。否则,o的全局对象是Window
对象,相关所有者是该Window
的关联Document
。
如果WorkerGlobalScope
的所有者集不是空,或者:
WorkerGlobalScope
对象是SharedWorkerGlobalScope
对象(即,worker是共享worker),并且,
该定义的第二部分允许共享worker在页面加载期间存活短暂时间,以防该页面将再次联系共享worker。用户代理可以利用这一点,在用户在同一站点内从页面导航到页面时,避免重新启动站点使用的共享worker的成本。
当一个 worker 的任何所有者是Document
对象(且这些对象是完全活跃的)或active
needed workers,则该 worker 被称为active needed worker。
如果worker是活动需要的worker,并且它有未完成的计时器、数据库事务或网络连接,或者其worker的端口列表不为空,或者其WorkerGlobalScope
实际上是SharedWorkerGlobalScope
对象(即,worker是共享worker),则该worker被称为受保护的worker。
如果worker不是活动需要的worker,但它是一个允许的worker,则该worker被称为可挂起的worker。
当用户代理需要为带有Worker
或SharedWorker
对象worker的脚本运行一个worker时,URL url,环境设置对象
outside settings,MessagePort
outside port,以及WorkerOptions
字典options,它必须执行以下步骤。
如果worker是SharedWorker
对象,则让is
shared为true,否则为false。
给定outside settings,将owner设为相关所有者。
将unsafeWorkerCreationTime设为不安全的共享当前时间。
将agent设为给定outside settings和is shared时获取专用/共享worker代理的结果。在该代理中运行以下步骤。
将realm execution context设为创建新领域的结果,给定agent和以下自定义内容:
对于全局对象,如果is shared为true,则创建一个新的SharedWorkerGlobalScope
对象。否则,创建一个新的DedicatedWorkerGlobalScope
对象。
将worker global scope设为realm execution context的Realm组件的全局对象。
这是在上一步中创建的DedicatedWorkerGlobalScope
或SharedWorkerGlobalScope
对象。
用realm execution context、outside settings和unsafeWorkerCreationTime来设置worker环境设置对象,并将结果设为inside settings。
将worker global scope的name设置为options的name
成员的值。
如果is shared为true,则执行以下操作:
如果is
shared为true,则将destination设为"sharedworker
",否则设为"worker
"。
根据options的type
成员的值来获取script:
classic
"module
"credentials
成员的值、inside
settings,以及如下定义的onComplete和performFetch。在两种情况下,将performFetch设为以下执行获取挂钩,给定request、isTopLevel和processCustomFetchResponse:
如果isTopLevel为false,fetch request并将processResponseConsumeBody设置为processCustomFetchResponse,并中止这些步骤。
Fetch request,将processResponseConsumeBody设置为以下步骤,给定response response和null、失败,或字节序列 bodyBytes:
初始化worker global scope的策略容器,给定worker global scope、response和inside settings。
如果在worker global scope上执行运行CSP初始化算法时返回"Blocked
",则将response设置为网络错误。[CSP]
如果worker global scope的嵌入者策略的值与跨源隔离兼容,并且is
shared为true,则将agent的代理集群的跨源隔离模式设置为"逻辑
"或"具体
"。选择的模式是实现定义。
这实际上应该在创建代理集群时设置,这需要重新设计本节。
如果检查全局对象的嵌入者策略与worker global scope、outside settings和response的结果为false,则将response设置为网络错误。
如果agent的代理集群的跨源隔离模式为"具体
",则将worker
global scope的跨源隔离能力设置为true。
如果is shared为false,且owner的跨源隔离能力为false,则将worker global scope的跨源隔离能力设置为false。
如果is shared为false,且response的url的scheme为"data
",则将worker global
scope的跨源隔离能力设置为false。
这是目前的保守默认设置,我们还在研究如何在权限策略的上下文中处理一般的workers,特别是data:
URL workers(它们与其所有者是跨源的)。有关更多详情,请参阅w3c/webappsec-permissions-policy
issue #207。
使用response和bodyBytes运行processCustomFetchResponse。
在两种情况下,给定script的onComplete为以下步骤:
如果script为null,或者script的要重新抛出的错误非空,则:
将worker与worker global scope关联。
将inside port设为inside settings的realm中新建的MessagePort
对象。
将inside port与worker global scope关联。
缠结outside port和inside port。
创建一个新的WorkerLocation
对象,并将其与worker
global scope关联。
关闭孤立worker:开始监控worker,以便在它不再是受保护的worker后不久,且不晚于它不再是允许的worker,将worker global scope的关闭标志设置为true。
暂停worker:开始监控worker,使得每当worker global scope的关闭标志为false且worker是可暂停的worker时,用户代理会暂停该worker中的脚本执行,直到关闭标志切换为true或worker不再是可暂停的worker为止。
设置inside settings的执行准备就绪标志。
启用outside port的端口消息队列。
如果is shared为false,则启用worker隐式端口的端口消息队列。
如果is shared为true,则在worker global scope上使用MessageEvent
排队一个全局任务,给定worker
global scope,以触发一个名为connect
的事件,data
属性初始化为空字符串,ports
属性初始化为包含inside
port的新冻结数组,source
属性初始化为inside
port。
启用与worker global scope的相关设置对象关联的ServiceWorkerContainer
对象的客户端消息队列。
事件循环:运行由inside settings指定的负责的事件循环,直到它被销毁。
由事件循环运行的任务可能会通过提前中止,这是通过下面定义的终止worker算法实现的。
worker处理模型将在此步骤上保持不变,直到事件循环被销毁,这是在事件循环处理模型中描述的关闭标志设置为true之后发生的。
解开所有worker的端口列表中的端口。
当用户代理需要终止一个worker时,它必须与worker的主循环(即上面定义的"运行一个worker"处理模型)并行地执行以下步骤:
将worker的WorkerGlobalScope
对象的关闭标志设置为true。
如果在WorkerGlobalScope
对象的相关代理的事件循环的任务队列中排队了任何任务,则丢弃它们而不处理它们。
如果worker的WorkerGlobalScope
对象实际上是DedicatedWorkerGlobalScope
对象(即worker是专用worker),则清空worker的隐式端口缠结的端口的端口消息队列。
当worker不再是活动需要的worker,且在其关闭标志设置为true后仍继续执行时,用户代理可以调用终止worker算法。
每当在 worker 的脚本之一中发生未捕获的运行时脚本错误时,如果该错误不是在处理先前的脚本错误时发生的,用户代理将报告该错误,针对 worker 的 WorkerGlobalScope
对象。
AbstractWorker
混合
interface mixin AbstractWorker {
attribute EventHandler onerror ;
};
以下是实现AbstractWorker
接口的对象必须支持的事件处理程序(及其对应的事件处理程序事件类型),作为事件处理程序IDL属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onerror
支持所有当前引擎。 Firefox44+Safari11.1+Chrome40+
Opera?Edge79+ Edge (旧版)17+Internet Explorer不支持 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? 支持所有当前引擎。 Firefox29+Safari16+Chrome5+
Opera10.6+Edge79+ Edge (旧版)?Internet Explorer不支持 Firefox Android33+Safari iOS16+Chrome Android不支持WebView Android?Samsung Internet4.0–5.0Opera Android11–14 支持所有当前引擎。 Firefox3.5+Safari4+Chrome4+
Opera10.6+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+ |
error
|
要设置一个Worker环境设置对象,需要给定一个JavaScript执行上下文execution context,一个环境设置对象outside settings,以及一个数字unsafeWorkerCreationTime:
让inherited origin成为outside settings的来源。
让realm成为execution context的Realm组件的值。
让worker global scope成为realm的全局对象。
让settings object成为一个新的环境设置对象,其算法定义如下:
返回execution context。
返回worker global scope的模块映射。
返回worker global scope的url。
如果worker global scope的url的scheme是"data
",则返回一个唯一的不透明来源,否则返回inherited origin。
返回worker global scope的策略容器。
返回worker global scope的跨源隔离能力。
返回使用worker global scope的跨源隔离能力对unsafeWorkerCreationTime进行粗化的结果。
设置settings object的id为一个新的唯一不透明字符串,创建URL为worker global scope的url,顶级创建URL为null,目标浏览上下文为null,活动的service worker为null。
如果worker global scope是一个DedicatedWorkerGlobalScope
对象,
则将settings object的顶级来源设置为outside
settings的顶级来源。
否则,将settings object的顶级来源设置为实现定义的值。
请参阅客户端存储分区以了解有关正确定义此内容的最新信息。
将realm的[[HostDefined]]字段设置为settings object。
返回settings object。
Worker
接口
在所有当前引擎中均支持。
[Exposed =(Window ,DedicatedWorker ,SharedWorker )]
interface Worker : EventTarget {
constructor ((TrustedScriptURL
or USVString ) scriptURL , optional WorkerOptions options = {});
undefined terminate ();
undefined postMessage (any message , sequence <object > transfer );
undefined postMessage (any message , optional StructuredSerializeOptions options = {});
attribute EventHandler onmessage ;
attribute EventHandler onmessageerror ;
};
dictionary WorkerOptions {
WorkerType type = "classic";
RequestCredentials credentials = "same-origin"; // credentials is only used if type is "module"
DOMString name = "";
};
enum WorkerType { "classic" , "module" };
Worker includes AbstractWorker ;
worker = new Worker(scriptURL [, options ])
在所有当前引擎中均支持。
返回一个新的Worker
对象。scriptURL将被获取并在后台执行,创建一个新的全局环境,worker表示通信通道。options可以用来通过name
选项定义该全局环境的名称,主要用于调试目的。它还可以确保这个新的全局环境支持
JavaScript
模块(指定type: "module"
),如果指定了该选项,还可以通过credentials
选项指定如何获取scriptURL。
worker.terminate()
在所有当前引擎中均支持。
worker.postMessage(message [, transfer ])
在所有当前引擎中均支持。
worker.postMessage(message [, { transfer } ])
克隆message并将其传输 到worker的全局环境。transfer可以作为一组对象传递,这些对象将被传输而不是克隆。
当调用terminate()
方法时,必须在与其关联的 worker 上运行terminate a worker算法。
Worker
对象表现得好像它们有一个隐含的MessagePort
与它们关联。此端口是创建
worker 时设置的通道的一部分,但未公开。在Worker
对象之前,此对象不得被垃圾回收。
该端口收到的所有消息必须立即重新定向到Worker
对象。
Worker
对象上的postMessage(message, transfer)
和postMessage(message,
options)
方法的行为与调用端口上的相应postMessage(message, transfer)
和postMessage(message,
options)
方法,并返回相同的返回值。
postMessage()
方法的第一个参数可以是结构化数据:
worker. postMessage({ opcode: 'activate' , device: 1938 , parameters: [ 23 , 102 ]});
以下是实现Worker
接口的对象必须支持的事件处理程序(及其对应的事件处理程序事件类型),作为事件处理程序 IDL 属性:
事件处理程序 | 事件处理程序事件类型 |
---|---|
onmessage |
message
|
onmessageerror |
messageerror
|
当调用Worker(scriptURL,
options)
构造函数时,用户代理必须执行以下步骤:
将compliantScriptURL设置为使用TrustedScriptURL
、this的相关全局对象、scriptURL、“Worker constructor
”和“script
”调用获取 Trusted Type 合规字符串算法的结果。
将outside settings设置为当前设置对象。
将worker URL设置为相对outside settings对compliantScriptURL执行编码-解析 URL的结果。
可以使用任何同源
URL(包括blob:
URL)。也可以使用data:
URL,但它们会创建具有不透明来源的 worker。
如果worker URL为失败,则
抛出“SyntaxError
”DOMException
。
创建一个新的Worker
对象并将其设置为worker。
创建一个新的outside port,该outside port是outside settings的realm中的一个新的MessagePort
。
将outside port与worker关联。
并行运行此步骤:
根据worker、worker URL、outside settings、outside port和options执行运行 worker。
返回worker。
SharedWorker
接口在所有当前引擎中均受支持。
[Exposed =Window ]
interface SharedWorker : EventTarget {
constructor ((TrustedScriptURL
or USVString ) scriptURL , optional (DOMString or WorkerOptions ) options = {});
readonly attribute MessagePort port ;
};
SharedWorker includes AbstractWorker ;
sharedWorker = new SharedWorker(scriptURL [, name ])
在所有当前引擎中均受支持。
返回一个新的 SharedWorker
对象。scriptURL 将在后台被获取并执行,创建一个新的全局环境,sharedWorker 代表了该全局环境的通信通道。name
可用于定义该全局环境的
name。
sharedWorker = new SharedWorker(scriptURL [, options ])
返回一个新的 SharedWorker
对象。scriptURL 将在后台被获取并执行,创建一个新的全局环境,sharedWorker 代表了该全局环境的通信通道。options 可用于通过
name
选项定义该全局环境的 name。它还可以确保这个新的全局环境支持
JavaScript 模块(指定 type: "module"
),如果指定了这一选项,还可以通过 credentials
选项来指定如何获取
scriptURL。请注意,尝试使用 options 中的 type
或 credentials
值与现有共享
worker
不匹配的情况下构建共享 worker,将导致返回的 sharedWorker 触发错误事件,并且不会连接到现有的共享 worker。
sharedWorker.port
在所有当前引擎中均受支持。
返回 sharedWorker 的 MessagePort
对象,该对象可用于与全局环境进行通信。
The port
属性必须返回由对象的构造函数分配的值。它代表与共享 worker 进行通信的 MessagePort
。
用户代理有一个关联的 共享 worker 管理器,它是 启动一个新的并行队列 的结果。
为了简化,每个用户代理都有一个 共享 worker 管理器。实现可以为每个 origin 使用一个管理器;这在可观察上是没有区别的,并且可以实现更多的并发性。
当 SharedWorker(script
URL, options)
构造函数被调用时:
令 compliantScriptURL 为调用 获取可信类型兼容字符串 算法的结果,参数为 TrustedScriptURL
,this 的 相关全局对象,scriptURL,"SharedWorker constructor
"
和 "script
"。
如果 options 是一个 DOMString
,则将
options 设置为一个新的 WorkerOptions
字典,其中 name
成员设置为 options 的值,其他成员设置为默认值。
令 outside settings 为 当前设置对象。
令 urlRecord 为 编码解析 URL 的结果,参数为 compliantScriptURL,相对于 outside settings。
任何 同源
URL(包括 blob:
URL)都可以使用。data:
URL 也可以使用,但它们会创建一个具有 不透明 origin 的 worker。
如果 urlRecord 失败,则抛出 "SyntaxError
" DOMException
。
令 worker 为一个新的 SharedWorker
对象。
令 outside port 为 新建 的 MessagePort
,位于
outside settings 的 realm 中。
将 outside port 分配给 worker 的 port
属性。
令 callerIsSecureContext 为 true,如果 outside settings 是 安全上下文;否则为 false。
令 outside storage key 为运行 为非存储目的获取存储密钥 的结果,参数为 outside settings。
令 worker global scope 为 null。
对每个
scope 进行迭代,在所有 SharedWorkerGlobalScope
对象的列表中:
令 worker storage key 为运行 为非存储目的获取存储密钥 的结果,参数为 scope 的 相关设置对象。
如果以下所有条件都为真:
name
成员的值,
那么:
将 worker global scope 设置为 scope。
跳出循环。
data:
URL 会创建一个具有 不透明 origin 的
worker。构造函数
origin
和构造函数 URL
都会进行比较,因此可以在同一个 origin 中使用相同的 data:
URL 访问相同的 SharedWorkerGlobalScope
对象,但不能用于绕过 同源
限制。
如果 worker global scope 不为 null,但用户代理已配置为禁止由 worker global scope 表示的 worker 与由 script 其 设置对象 是 outside settings 之间的通信,则将 worker global scope 设置为 null。
例如,用户代理可以有一个开发模式,该模式将特定的 顶级可遍历对象 与所有其他页面隔离,并且该开发模式下的 script 可能会被阻止连接到在普通浏览器模式下运行的共享 worker。
如果 worker global scope 不为 null,则执行以下子步骤:
令 settings object 为 worker global scope 的 相关设置对象。
令 workerIsSecureContext 为 true,如果 settings object 是 安全上下文;否则为 false。
如果 workerIsSecureContext 不等于 callerIsSecureContext,则 排队一个任务,触发一个名为 error
的事件,在 worker 上,终止这些步骤。[SECURE-CONTEXTS]
将 worker 与 worker global scope 关联。
令 inside port 为 新建 的 MessagePort
,位于
settings object 的 realm
中。
纠缠 outside port 和 inside port。
排队一个任务,使用
DOM 操作任务源,触发一个名为 connect
的事件,在 worker global scope 上,使用 MessageEvent
,data
属性初始化为空字符串,ports
属性初始化为一个新的 冻结数组,仅包含 inside port,以及 source
属性初始化为 inside port。
将 相关的要添加的所有者 给定 outside settings,添加 到 worker global scope 的所有者集合中。
否则,并行,运行一个 worker,给定 worker,urlRecord,outside settings,outside port 和 options。
返回 worker。
interface mixin NavigatorConcurrentHardware {
readonly attribute unsigned long long hardwareConcurrency ;
};
self.navigator.hardwareConcurrency
返回可能供用户代理使用的逻辑处理器数量。
navigator.hardwareConcurrency
属性的 getter 必须返回一个在 1
到可能供用户代理使用的逻辑处理器数量之间的数字。如果无法确定,则 getter 必须返回 1。
用户代理应该倾向于公开可用的逻辑处理器数量,仅在存在用户代理特定限制(例如对可以创建的 worker 数量的限制)或用户代理希望限制指纹识别可能性的情况下才使用较低的值。
importScripts(...urls)
方法的步骤如下:
令 urlStrings 为 « »。
对 urls 中的每个 url:
追加 调用 获取可信类型兼容字符串 算法的结果,将 TrustedScriptURL
、this 的 相关全局对象、url、"Worker importScripts
"
和 "script
" 追加到 urlStrings 中。
给定 将脚本导入到工作线程全局范围,给定 this 和 urlStrings。
要将脚本导入到工作线程全局范围,给定 WorkerGlobalScope
对象 worker global scope、一个 列表 的 标量值字符串
urls,以及可选的 执行抓取钩子 performFetch:
令 settings object 为 当前设置对象。
如果 urls 为空,则返回。
令 urlRecords 为 « »。
对于 urls 中的每个 url:
令 urlRecord 为 编码-解析URL 的结果,给定 url,相对于 settings object。
如果 urlRecord 失败,则抛出 "SyntaxError
" DOMException
。
将 urlRecord 追加到 urlRecords 中。
对于 urlRecords 中的每个 urlRecord:
Service Workers 是一个运行此算法的规范示例,它使用了自己的执行抓取钩子。[SW]
WorkerNavigator
接口支持所有当前引擎。
是 navigator
WorkerGlobalScope
接口的属性,必须返回 WorkerNavigator
接口的一个实例,该实例表示用户代理(客户端)的身份和状态:
[Exposed =Worker ]
interface WorkerNavigator {};
WorkerNavigator includes NavigatorID ;
WorkerNavigator includes NavigatorLanguage ;
WorkerNavigator includes NavigatorOnLine ;
WorkerNavigator includes NavigatorConcurrentHardware ;
WorkerLocation
接口支持所有当前引擎。
支持所有当前引擎。
[Exposed =Worker ]
interface WorkerLocation {
stringifier readonly attribute USVString href ;
readonly attribute USVString origin ;
readonly attribute USVString protocol ;
readonly attribute USVString host ;
readonly attribute USVString hostname ;
readonly attribute USVString port ;
readonly attribute USVString pathname ;
readonly attribute USVString search ;
readonly attribute USVString hash ;
};
一个 WorkerLocation
对象有一个关联的 WorkerGlobalScope
对象(一个 WorkerGlobalScope
对象)。
在所有当前引擎中都支持。
href
的
getter 步骤是返回 this 的 WorkerGlobalScope
对象 的 url,并进行 序列化。
在所有当前引擎中都支持。
origin
的 getter 步骤是返回 origin 的序列化,其为 this 的 WorkerGlobalScope
对象 的 url 的 origin。
在所有当前引擎中都支持。
protocol
的 getter 步骤是返回 this 的 WorkerGlobalScope
对象 的
url 的 scheme,后跟 ":
"。
在所有当前引擎中都支持。
host
的
getter 步骤是:
让 url 为 this 的 WorkerGlobalScope
对象 的
url。
如果 url 的 host 为空,则返回空字符串。
在所有当前引擎中都支持。
hostname
的 getter 步骤是:
让 host 为 this 的 WorkerGlobalScope
对象 的
url 的 host。
如果 host 为空,则返回空字符串。
返回 host,并进行 序列化。
在所有当前引擎中都支持。
port
的
getter 步骤是:
让 port 为 this 的 WorkerGlobalScope
对象 的
url 的 port。
如果 port 为空,则返回空字符串。
返回 port,并进行 序列化。
在所有当前引擎中都支持。
pathname
的 getter 步骤是返回 URL 路径序列化 的结果,作用于 this 的 WorkerGlobalScope
对象 的 url。
在所有当前引擎中都支持。
search
的 getter 步骤是:
让 query 为 this 的 WorkerGlobalScope
对象 的
url 的 query。
如果 query 为空或为空字符串,则返回空字符串。
返回 "?
",后跟 query。
在所有当前引擎中都支持。
hash
的
getter 步骤是:
让 fragment 为 this 的 WorkerGlobalScope
对象 的
url 的 fragment。
如果 fragment 为空或为空字符串,则返回空字符串。
返回 "#
",后跟 fragment。
本节为非规范性内容。
Worklet 是一种规范基础设施,可以用于在主 JavaScript 执行环境之外运行脚本,而不需要特定的实现模型。
此处指定的 worklet 基础设施不能直接被 Web 开发者使用。相反,其他规范在其基础上构建了可以直接使用的 worklet 类型,专门用于在浏览器实现管道的特定部分运行。
本节为非规范性内容。
允许在渲染或实现管道的其他敏感部分(例如音频输出)添加扩展点是困难的。如果扩展点可以完全访问 Window
上的
API,引擎将不得不放弃先前对这些阶段中可能发生的事情的假设。例如,在布局阶段,渲染引擎假设不会修改 DOM。
此外,在 Window
环境中定义扩展点将限制用户代理在与 Window
对象相同的线程中执行工作。(除非实现了复杂的高开销基础设施,以允许线程安全的 API 以及线程连接保证。)
Worklet 的设计旨在允许扩展点,同时保留用户代理当前依赖的保证。这是通过基于 WorkletGlobalScope
子类的新全局环境实现的。
Worklet 类似于 Web Workers。但是,它们具有以下特点:
与线程无关。也就是说,它们并非设计为在专用独立线程上运行,如每个 worker 那样。实现可以选择在任何地方运行 worklet(包括主线程上)。
能够创建全局范围的多个重复实例,以实现并行处理。
不使用基于事件的 API。相反,类会在全局范围内注册,其方法由用户代理调用。
全局范围的 API 表面较少。
由于 worklet 具有相对较高的开销,因此应谨慎使用。由于这一点,预计一个给定的 WorkletGlobalScope
将被多个独立的脚本共享。(这类似于一个 Window
在多个独立脚本之间共享。)
Worklet 是一种通用技术,可以服务于不同的用例。一些 worklet,如 CSS Painting API 中定义的 worklet,提供了扩展点,旨在进行无状态、幂等和短期运行的计算,这些计算在接下来的几个部分中有特殊的考虑。其他如 Web Audio API 中定义的 worklet,则用于有状态、长期运行的操作。[CSSPAINT] [WEBAUDIO]
某些使用 worklet 的规范旨在允许用户代理通过多线程并行处理工作,或根据需要在线程之间移动工作。在这些规范中,用户代理可能会以 实现定义 的顺序调用 Web 开发者提供的类的方法。
因此,为防止互操作性问题,作者在此类 WorkletGlobalScope
上注册类时,应确保其代码的幂等性。也就是说,类中的方法或方法集在给定特定输入的情况下应产生相同的输出。
本规范使用以下技术来鼓励作者编写幂等的代码:
不可访问全局对象(即,在 WorkletGlobalScope
上没有类似于 self
的对应物)。
虽然这在最初指定 worklet 时是预期的,但 globalThis
的引入使这一点不再成立。有关更多讨论,请参阅 issue #6059。
代码作为 模块脚本
加载,这使得代码在严格模式下执行,并且没有共享的 this
引用全局代理。
这些限制共同帮助防止两个不同的脚本使用 全局对象 的属性共享状态。
此外,使用 worklet 并打算允许 实现定义 行为的规范必须遵守以下规则:
它们必须要求用户代理为每个 WorkletGlobalScope
实例至少提供两个 Worklet
,并随机分配类中的一个方法或一组方法给某个特定的
WorkletGlobalScope
实例。这些规范可以在内存受限的情况下提供退出选项。
这些规范必须允许用户代理在任何时间创建和销毁其 WorkletGlobalScope
子类的实例。
某些使用 worklet 的规范可以根据用户代理的状态在 Web 开发者提供的类上调用方法。为了增加线程之间的并发性,用户代理可能会基于潜在的未来状态推测性地调用某个方法。
在这些规范中,用户代理可能会随时调用这些方法,并且使用任何参数,而不仅限于与当前用户代理状态相对应的参数。这种推测性评估的结果不会立即显示,但可以缓存以供用户代理状态与推测状态匹配时使用。这可以增加用户代理与 worklet 线程之间的并发性。
因此,为防止用户代理之间的互操作性风险,在此类 WorkletGlobalScope
上注册类的作者应使其代码无状态。也就是说,调用方法的唯一效果应该是其结果,而不应有任何更新可变状态等副作用。
与鼓励 代码幂等性 的相同技术也鼓励作者编写无状态代码。
本节为非规范性内容。
在这些示例中,我们将使用一个虚拟的 worklet。Window
对象提供了两个
Worklet
实例,每个实例都在其自己的 FakeWorkletGlobalScope
集合中运行代码:
partial interface Window {
[SameObject , SecureContext ] readonly attribute Worklet fakeWorklet1 ;
[SameObject , SecureContext ] readonly attribute Worklet fakeWorklet2 ;
};
每个 Window
都有两个 Worklet
实例,分别是 fake
worklet 1 和 fake worklet 2。这两个实例的 worklet
全局范围类型 都设置为 FakeWorkletGlobalScope
,其
worklet
目标类型 设置为 "fakeworklet
"。用户代理应为每个 worklet 创建至少两个 FakeWorkletGlobalScope
实例。
"fakeworklet
" 实际上不是 Fetch
所规定的有效目标。但这说明了真正的 worklet 通常会有其专属的 worklet 类型特定目标。[FETCH]
fakeWorklet1
的 getter 步骤是返回 this 的 fake worklet 1。
fakeWorklet2
的 getter 步骤是返回 this 的
fake worklet 2。
[Global =(Worklet ,FakeWorklet ),
Exposed =FakeWorklet ,
SecureContext ]
interface FakeWorkletGlobalScope : WorkletGlobalScope {
undefined registerFake (DOMString type , Function classConstructor );
};
每个 FakeWorkletGlobalScope
都有一个 已注册类构造函数映射,这是一个 有序映射,初始为空。
registerFake(type, classConstructor)
方法的步骤是将 this 的
已注册类构造函数映射[type] 设置为
classConstructor。
本节为非规范性内容。
要将脚本加载到 fake worklet 1,Web 开发者可以编写:
window. fakeWorklet1. addModule( 'script1.mjs' );
window. fakeWorklet1. addModule( 'script2.mjs' );
请注意,哪个脚本先完成获取并运行取决于网络时序:可能是 script1.mjs
,也可能是 script2.mjs
。对于打算在 worklet
中加载的精心编写的脚本,如果它们遵循关于准备 推测性评估 的建议,这通常不会有什么影响。
如果 Web 开发者希望在脚本成功运行并加载到某些 worklet 之后才执行任务,他们可以编写:
Promise. all([
window. fakeWorklet1. addModule( 'script1.mjs' ),
window. fakeWorklet2. addModule( 'script2.mjs' )
]). then(() => {
// Do something which relies on those scripts being loaded.
});
关于脚本加载的另一个重要点是,加载的脚本可以在每个 WorkletGlobalScope
中运行多个 Worklet
,如
代码幂等性 部分中讨论的那样。特别是上述 fake worklet
1
和 fake worklet
2
的规范要求这一点。所以,考虑如下场景:
// script.mjs
console. log( "Hello from a FakeWorkletGlobalScope!" );
// app.mjs
window. fakeWorklet1. addModule( "script.mjs" );
这可能会导致用户代理的控制台输出如下内容:
[fakeWorklet1#1] Hello from a FakeWorkletGlobalScope!
[fakeWorklet1#4] Hello from a FakeWorkletGlobalScope!
[fakeWorklet1#2] Hello from a FakeWorkletGlobalScope!
[fakeWorklet1#3] Hello from a FakeWorkletGlobalScope!
如果用户代理在某个时间点决定终止并重启第三个 FakeWorkletGlobalScope
实例,控制台会再次打印 [fakeWorklet1#3] Hello from a FakeWorkletGlobalScope!
。
本节为非规范性内容。
假设我们虚拟的 worklet 的一个预期用途是允许 Web 开发者自定义布尔值求反的高度复杂过程。他们可能会这样注册他们的自定义:
// script.mjs
registerFake( 'negation-processor' , class {
process( arg) {
return ! arg;
}
});
// app.mjs
window. fakeWorklet1. addModule( "script.mjs" );
为了使用此类已注册的类,虚拟 worklet 的规范可以定义一个 查找 true 的相反值 算法,给定一个 Worklet
worklet:
可选地,为 worklet 创建一个 worklet 全局范围。
让 classConstructor 成为 workletGlobalScope 的 已注册类构造函数映射["negation-processor
"]。
让 classInstance 成为 构造 classConstructor 的结果,无需参数。
让 function 成为 获取(classInstance,
"process
") 的结果。重新抛出任何异常。
返回调用
callback的结果,使用 « true » 和 "rethrow
",并将 回调此值 设置为
classInstance。
另一种或许更好的规范架构是在注册时,将 "process
" 属性提取出来并转换为 Function
,作为
registerFake()
方法步骤的一部分。
WorkletGlobalScope
的子类用于创建在特定 Worklet
中加载的代码可以执行的 全局对象。
[Exposed =Worklet , SecureContext ]
interface WorkletGlobalScope {};
其他规范旨在继承 WorkletGlobalScope
,增加注册类的
API 以及其他特定于其 worklet 类型的 API。
每个 WorkletGlobalScope
都有一个关联的 模块映射。它是一个 模块映射,最初为空。
本节为非规范性内容。
每个 WorkletGlobalScope
都包含在其自己的 worklet
代理 中,该代理具有其对应的 事件循环。然而,实际上,这些代理和事件循环的实现预计会与大多数其他代理有所不同。
为每个 WorkletGlobalScope
实例存在一个 worklet
代理,因为理论上,一个实现可以为每个 WorkletGlobalScope
实例使用一个单独的线程,允许这种级别的并行性最好通过代理来完成。然而,由于它们的 [[CanBlock]] 值为 false,因此没有要求代理和线程是 1:1 的关系。这使得实现有自由可以在任何线程上执行加载到
worklet
中的脚本,包括运行来自其他具有 false 的 [[CanBlock]] 的代理代码的线程,例如类似源窗口代理("主线程")的线程。这与 专用worker代理 相反,其 [[CanBlock]] 值为 true
实际上要求它们获得一个专用的操作系统线程。
Worklet 事件循环
也是有些特殊的。它们仅用于与 addModule()
相关联的 任务,用户代理调用作者定义方法的任务,以及 微任务。因此,即使 事件循环处理模型
规定所有事件循环都要持续运行,实现可以使用更简单的策略来实现可观察的等效结果,该策略只是 调用 作者提供的方法,然后依赖于该过程 执行微任务检查点。
要为 Worklet
worklet 创建一个 worklet 全局范围:
令 outsideSettings 为 worklet 的 相关设置对象。
令 agent 为根据 outsideSettings 获取的 worklet 代理。在该代理中运行这些步骤的其余部分。
令 realmExecutionContext 为根据 agent 和以下自定义创建的新领域的结果:
对于全局对象,创建一个由 worklet 的 worklet 全局范围类型 给定的新对象。
令 workletGlobalScope 为 realmExecutionContext 的领域组件的 全局对象。
令 insideSettings 为根据 realmExecutionContext 和 outsideSettings 设置的 worklet 环境设置对象的结果。
令 runNextAddedModule 为以下步骤:
如果 pendingAddedModules 不为空,则:
令 moduleURL 为从 pendingAddedModules 出队的结果。
给定 moduleURL,insideSettings,worklet 的 worklet 目标类型,什么是凭证模式?,insideSettings,worklet 的 模块响应映射,并在给定 script 时执行以下步骤,获取 worklet 脚本图:
这实际上不会执行网络请求,因为它只会重用 worklet 的 模块响应映射 中的 响应。这一步的主要目的是从 workletGlobalScope 特定的 模块脚本中创建一个新的 响应。
将 workletGlobalScope 附加到
outsideSettings 的 全局对象的 关联
Document
的 worklet 全局范围 中。
运行 insideSettings 指定的 负责的事件循环。
运行 runNextAddedModule。
要 终止一个 worklet 全局范围,给定一个 WorkletGlobalScope
workletGlobalScope:
等待 eventLoop 完成 当前运行的任务。
如果前一步骤在 实现定义的时间段内未完成,则 中止 worklet 中当前运行的脚本。
销毁 eventLoop。
从包含 workletGlobalScope 的 Worklet
的
全局范围中 移除 workletGlobalScope。
从包含 workletGlobalScope 的 Document
的
worklet 全局范围中 移除 workletGlobalScope。
要设置一个 Worklet 环境设置对象,给定一个JavaScript 执行上下文executionContext和一个环境设置对象outsideSettings:
令origin为一个唯一的不透明的来源。
令inheritedAPIBaseURL为outsideSettings的API 基础 URL。
令inheritedPolicyContainer为outsideSettings的策略容器的克隆。
令realm为executionContext的领域组件的值。
令workletGlobalScope为realm的全局对象。
令settingsObject为一个新的环境设置对象,其算法定义如下:
返回executionContext。
返回workletGlobalScope的模块映射。
返回inheritedAPIBaseURL。
与从单一资源派生的其他全局对象或工人不同,Worklet 没有主要资源;相反,多个脚本,每个脚本都有自己的 URL,通过 worklet.addModule()
加载到全局范围中。因此,这个
API 基础
URL与其他全局对象的 URL 有所不同。然而,目前这并不重要,因为没有可用的 Worklet 代码的 API 使用 API 基础
URL。
返回origin。
返回inheritedPolicyContainer。
返回 TODO。
将settingsObject的id设置为新的唯一不透明字符串,将创建 URL设置为inheritedAPIBaseURL,将顶级创建 URL设置为 null,将顶级来源设置为outsideSettings的顶级来源,将目标浏览上下文设置为 null,并将活动服务worker设置为 null。
将realm的 [[HostDefined]] 字段设置为settingsObject。
返回settingsObject。
Worklet
类支持所有当前引擎。
Worklet
类提供了将模块脚本添加到其关联的 WorkletGlobalScope
的能力。然后用户代理可以在 WorkletGlobalScope
上创建注册的类并调用其方法。
[Exposed =Window , SecureContext ]
interface Worklet {
[NewObject ] Promise <undefined > addModule (USVString moduleURL , optional WorkletOptions options = {});
};
dictionary WorkletOptions {
RequestCredentials credentials = "same-origin";
};
创建 Worklet
实例的规范必须为给定实例指定以下内容:
它的 worklet 全局范围类型,它必须是一个从 WorkletGlobalScope
继承的 Web IDL 类型;并且
它的 worklet 目标类型,它必须是一个 目标,并且在获取脚本时使用。
await worklet.addModule(moduleURL[, { credentials }])
支持所有当前引擎。
加载并执行由 moduleURL 提供的 模块脚本 到所有 worklet 的 全局范围 中。它还可以根据 worklet 类型在此过程中创建额外的全局范围。返回的 promise 将在脚本成功加载并在所有全局范围中运行后完成。
credentials
选项可以设置为 凭据模式,以修改脚本获取过程。默认值为 "same-origin
"。
在 获取脚本或其依赖项时的任何失败都将导致返回的 promise 被 "AbortError
" DOMException
拒绝。解析脚本或其依赖项中的任何错误将导致返回的 promise 被解析时生成的异常拒绝。
Worklet
有一个 列表,其中包含 全局范围 的实例,这些实例包含 Worklet
的 worklet
全局范围类型。它最初是空的。
Worklet
有一个 添加的模块列表,它是一个 列表,包含 URL,最初是空的。对该列表的访问应是线程安全的。
Worklet
有一个 模块响应映射,它是一个 有序映射,从 URL 到
"fetching
" 或包含 响应 以及代表响应主体的 字节序列 的 元组,这映射最初是空的,并且访问它应是线程安全的。
添加的模块列表 和 模块响应映射 的存在是为了确保在不同时间创建的 WorkletGlobalScope
运行基于相同源文本的等效 模块脚本。这允许透明地创建额外的 WorkletGlobalScope
给作者。
实际上,用户代理不需要使用线程安全的编程技术来实现这些数据结构和查询它们的算法。相反,当调用 addModule()
时,用户代理可以在主线程上获取模块图,并将获取到的源文本(即 模块响应映射 中包含的重要数据)发送到每个具有 WorkletGlobalScope
的线程。
然后,当用户代理为给定的 Worklet
创建一个新的 WorkletGlobalScope
时,它可以简单地将从主线程获取的源文本映射和入口点列表发送到包含新 WorkletGlobalScope
的线程。
addModule(moduleURL, options)
方法步骤如下:
让 outsideSettings 成为 相关设置对象。
让 moduleURLRecord 成为 编码解析 URL 的结果,给定 moduleURL,相对于 outsideSettings。
如果 moduleURLRecord 失败,则返回 被拒绝的
promise,并带有 "SyntaxError
" DOMException
。
让 promise 成为一个新的 promise。
并行运行以下步骤:
在继续之前,等待 创建过程的所有步骤——包括在 worklet 代理 内进行的步骤——完成。
让 addedSuccessfully 为 false。
对于每个 workletGlobalScope,在 this 的 全局范围
上,队列一个全局任务,在
网络任务源 上,给定
workletGlobalScope,获取 worklet 脚本图,给定
moduleURLRecord,outsideSettings,this 的 worklet
目标类型,options["credentials
"],workletGlobalScope
的 相关设置对象,this
的
模块响应映射,以及给定 script 的以下步骤:
只有第一个获取实际上会执行网络请求;其他 WorkletGlobalScope
将重用来自 响应 的 this 的 模块响应映射。
如果 script 为 null,则:
队列一个全局任务 在 网络任务源 上,给定 this 的 相关全局对象 以执行以下步骤:
如果 pendingTasks 不是 -1,则:
将 pendingTasks 设置为 -1。
用 "AbortError
" DOMException
拒绝 promise。
中止这些步骤。
如果 script 的 重抛错误 不是 null,则:
如果 addedSuccessfully 为 false,则:
运行模块脚本,给定 script。
队列一个全局任务 在 网络任务源 上,给定 this 的 相关全局对象 以执行以下步骤:
如果 pendingTasks 不是 -1,则:
将 pendingTasks 设置为 pendingTasks - 1。
如果 pendingTasks 为 0,则解决 promise。
返回 promise。
Worklet
的生命周期没有特殊考虑;它与其所属的对象(如 Window
)的生命周期相绑定。
每个 Document
都有一个 worklet 全局作用域,这是一个 有序集合,包含了 WorkletGlobalScope
,初始时为空。
WorkletGlobalScope
的生命周期至少与包含它的 Document
的生命周期相绑定。特别是,销毁
Document
会 终止 对应的
WorkletGlobalScope
,并允许其被垃圾回收。
此外,除非对应的 worklet 类型的规范另有说明,用户代理可以随时 终止 给定的 WorkletGlobalScope
。例如,如果
worklet 代理的 事件循环
没有排队的 任务,或者用户代理没有任何计划使用
worklet 的操作,或者用户代理检测到异常操作(如无限循环或超出时间限制的回调),它们可能会终止 worklet。
最后,特定 worklet 类型的规范可以提供有关何时 创建 给定 worklet 类型的 WorkletGlobalScope
的更多详细信息。例如,它们可能会在调用 worklet 代码的特定过程中创建这些作用域,正如 示例
中所示。
支持所有当前引擎。
本节为非规范性内容。
本规范引入了两种与 HTTP 会话 Cookie 类似的机制,用于在客户端存储名称-值对。[COOKIES]
第一种机制设计用于用户进行单次交易的场景,但用户可能会同时在不同窗口中进行多次交易。
Cookie 并不能很好地处理这种情况。例如,用户可能在两个不同的窗口中使用同一个网站购买机票。如果网站使用 Cookie 来跟踪用户正在购买的机票,那么当用户在两个窗口中点击页面时,当前正在购买的机票可能会从一个窗口“泄漏”到另一个窗口,可能导致用户在不经意间购买同一航班的两张机票。
为了解决这个问题,本规范引入了 sessionStorage
获取器。网站可以将数据添加到会话存储中,该数据将在同一窗口中打开的同一站点的任何页面中可访问。
例如,页面上可能有一个复选框,用户勾选它表示他们想要保险:
< label >
< input type = "checkbox" onchange = "sessionStorage.insurance = checked ? 'true' : ''" >
I want insurance on this trip.
</ label >
后续页面可以通过脚本检查用户是否勾选了复选框:
if ( sessionStorage. insurance) { ... }
如果用户在该站点上打开了多个窗口,每个窗口都会有自己的会话存储对象的独立副本。
第二种存储机制设计用于跨多个窗口的存储,并且超出了当前会话的范围。特别是,Web 应用程序可能希望在客户端存储大量用户数据,例如整个用户撰写的文档或用户的邮箱,以提高性能。
再次说明,Cookie 不能很好地处理这种情况,因为它们会随每个请求一起发送。
localStorage
获取器用于访问页面的本地存储区域。
example.com 上的站点可以通过在页面底部放置以下内容来显示用户加载其页面的次数:
< p >
You have viewed this page
< span id = "count" > an untold number of</ span >
time(s).
</ p >
< script >
if ( ! localStorage. pageLoadCount)
localStorage. pageLoadCount = 0 ;
localStorage. pageLoadCount = parseInt( localStorage. pageLoadCount) + 1 ;
document. getElementById( 'count' ). textContent = localStorage. pageLoadCount;
</ script >
每个站点都有其自己的独立存储区域。
localStorage
获取器提供了对共享状态的访问。本规范未定义在多进程用户代理中的与其他代理集群的交互,作者应假设没有锁机制。例如,站点可能尝试读取一个键的值,递增其值,然后将其写回,使用新值作为会话的唯一标识符;如果站点在两个不同的浏览器窗口中同时执行此操作,可能最终会为两个会话使用相同的“唯一”标识符,可能导致灾难性的后果。
支持所有当前引擎。
Storage
接口[Exposed =Window ]
interface Storage {
readonly attribute unsigned long length ;
DOMString ? key (unsigned long index );
getter DOMString ? getItem (DOMString key );
setter undefined setItem (DOMString key , DOMString value );
deleter undefined removeItem (DOMString key );
undefined clear ();
};
storage.length
支持所有当前引擎。
返回键/值对的数量。
storage.key (n)
支持所有当前引擎。
返回第 n 个键的名称,如果 n 大于或等于键/值对的数量,则返回 null。
value = storage.getItem (key)
支持所有当前引擎。
value = storage[key]
返回与给定 key 关联的当前值,如果给定 key 不存在,则返回 null。
storage.setItem (key, value)
支持所有当前引擎。
storage[key] = value
将由 key 标识的键的值设置为 value,如果之前没有为 key 存在键/值对,则创建一个新的键/值对。
如果无法设置新值,则抛出 "QuotaExceededError
" DOMException
异常。(设置可能会失败,例如,如果用户已禁用该站点的存储,或者已超出配额。)
storage.removeItem (key)
支持所有当前引擎。
delete
storage[key]
删除具有给定 key 的键/值对,如果存在具有给定 key 的键/值对。
storage.clear()
支持所有当前引擎。
删除所有键/值对(如果有的话)。
Storage
对象具有以下关联项:
local
" 或 "session
"。
要对 Storage
对象
storage 进行重新排序,请按 storage 的 map 的 entries 以 实现定义
的方式重新排序。
虽然不幸,但迭代顺序未定义,并且在大多数变更时可能会更改。
要对 Storage
对象
storage 进行广播,给定 key、oldValue 和
newValue,请按以下步骤操作:
让 thisDocument 成为 storage 的 相关全局对象 的 关联
Document
。
让 url 成为 thisDocument 的 URL。
让 remoteStorages 成为所有 Storage
对象,排除以下情况:
并且,如果 type 是
"session
",则其 相关设置对象 的 关联
Document
的 节点可导航
的
可遍历导航 与 thisDocument 的
节点可导航 的 可遍历导航 相同。
对于每个 remoteStorage 中的 remoteStorages,在
remoteStorage 的 相关全局对象 上 排队一个全局任务
在 DOM
操作任务源
中,给定 remoteStorage 的 相关全局对象,使用 StorageEvent
,将
key
初始化为 key,oldValue
初始化为 oldValue,newValue
初始化为 newValue,url
初始化为 url,以及 storageArea
初始化为 remoteStorage。
Document
对象关联的结果 任务 不一定是 完全活动的,但在 事件循环 中,该对象上的事件在 Document
再次变为 完全活动 之前将被忽略。
length
获取步骤是返回
this 的
map 的 大小。
key(index)
方法的步骤为:
支持的属性名称在 Storage
对象
storage 上是运行 获取键 的结果。
getItem(key)
方法的步骤为:
setItem(key, value)
方法的步骤为:
让 oldValue 为 null。
让 reorder 为 true。
如果 value 无法存储,则抛出 "QuotaExceededError
" DOMException
异常。
removeItem(key)
方法的步骤为:
clear()
方法的步骤为:
sessionStorage
获取器interface mixin WindowSessionStorage {
readonly attribute Storage sessionStorage ;
};
Window includes WindowSessionStorage ;
window.sessionStorage
支持所有当前引擎。
返回与该 window 的源关联的 Storage
对象的会话存储区域。
如果 Document
的
源
是
不透明的源
或者请求违反了某项策略决定(例如,如果用户代理被配置为不允许页面持久化数据),则抛出
"SecurityError
" DOMException
。
Document
对象有一个关联的 会话存储持有者,它可以为 null 或一个 Storage
对象。它最初为 null。
sessionStorage
获取器的步骤如下:
如果 this 的 关联 Document
的 会话存储持有者 非
null,则返回
this 的 关联 Document
的 会话存储持有者。
让 map 成为使用 this 的 相关设置对象 和
"sessionStorage
" 运行 获取会话存储瓶映射 的结果。
如果 map 失败,则抛出 "SecurityError
" DOMException
。
将 this 的 关联 Document
的 会话存储持有者 设置为
storage。
返回 storage。
在创建一个新的辅助浏览上下文和文档后,会话存储将被复制。
localStorage
获取器interface mixin WindowLocalStorage {
readonly attribute Storage localStorage ;
};
Window includes WindowLocalStorage ;
window.localStorage
支持所有当前引擎。
返回与 window 的源关联的 Storage
对象的本地存储区域。
如果 Document
的 源 是
不透明的源
或者请求违反了某项策略决定(例如,如果用户代理被配置为不允许页面持久化数据),则抛出
"SecurityError
" DOMException
。
Document
对象有一个关联的 本地存储持有者,它可以为 null 或一个 Storage
对象。它最初为
null。
localStorage
获取器的步骤如下:
如果 this 的 关联 Document
的 本地存储持有者 非 null,则返回
this 的 关联 Document
的 本地存储持有者。
如果 map 失败,则抛出 "SecurityError
" DOMException
。
将 this 的 关联 Document
的 本地存储持有者 设置为
storage。
返回 storage。
StorageEvent
接口支持所有当前引擎。
[Exposed =Window ]
interface StorageEvent : Event {
constructor (DOMString type , optional StorageEventInit eventInitDict = {});
readonly attribute DOMString ? key ;
readonly attribute DOMString ? oldValue ;
readonly attribute DOMString ? newValue ;
readonly attribute USVString url ;
readonly attribute Storage ? storageArea ;
undefined initStorageEvent (DOMString type , optional boolean bubbles = false , optional boolean cancelable = false , optional DOMString ? key = null , optional DOMString ? oldValue = null , optional DOMString ? newValue = null , optional USVString url = "", optional Storage ? storageArea = null );
};
dictionary StorageEventInit : EventInit {
DOMString ? key = null ;
DOMString ? oldValue = null ;
DOMString ? newValue = null ;
USVString url = "";
Storage ? storageArea = null ;
};
event.key
返回正在更改的存储项的键。
event.oldValue
返回值正在更改的存储项的键的旧值。
event.newValue
返回值正在更改的存储项的键的新值。
event.url
返回存储项已更改的文档的URL。
event.storageArea
返回受影响的Storage
对象。
key
,oldValue
,newValue
,url
,和storageArea
属性必须返回它们初始化时的值。
initStorageEvent(type, bubbles, cancelable, key, oldValue, newValue, url, storageArea)
方法必须以类似于initEvent()
方法的方式初始化事件。[DOM]
第三方广告商(或任何能够将内容分发到多个网站的实体)可以使用存储在其本地存储区域中的唯一标识符来跨多个会话追踪用户,从而建立用户兴趣的档案,以便进行高度定向的广告投放。与能够识别用户真实身份的网站(例如需要认证凭据的电子商务网站)相结合,这可能会让压制性团体比在纯匿名的网页浏览环境中更准确地定位个人。
有许多技术可以用来减轻用户追踪的风险:
用户代理可以限制访问 localStorage
对象的脚本,仅限于源自 顶层文档的域。例如,拒绝访问其他域的页面中运行在 iframe
中的
API。
用户代理可以(可能通过用户配置的方式)在一段时间后自动删除存储的数据。
例如,用户代理可以被配置为将第三方本地存储区域视为仅限会话存储,在用户关闭所有能够访问该存储的可导航元素后删除数据。
这可以限制网站追踪用户的能力,因为网站只能在用户通过自身进行身份验证(例如通过购买或登录服务)时跨多个会话追踪用户。
然而,这也降低了 API 作为长期存储机制的实用性。如果用户不完全理解数据过期的含义,也可能使用户的数据面临风险。
如果用户尝试通过清除 Cookie 来保护隐私,但没有同时清除本地存储区域中的数据,网站可以通过将这两项功能作为彼此的冗余备份来破坏这些尝试。用户代理应以帮助用户理解这一可能性的方式呈现清除这些存储的界面,并使其能够同时删除所有持久性存储功能中的数据。[COOKIES]
用户代理可以允许站点在不受限制的情况下访问会话存储区域,但要求用户授权访问本地存储区域。
用户代理可以记录导致数据存储的第三方来源的来源。
如果这些信息用于呈现当前持久性存储中的数据视图,用户将能够对持久性存储中的哪些部分进行裁剪做出明智的决定。结合阻止列表(“删除此数据并防止此域名再次存储数据”),用户可以将持久性存储的使用限制为他们信任的站点。
用户代理可以允许用户共享其持久存储域的阻止列表。
这将允许社区共同行动来保护他们的隐私。
虽然这些建议可以防止API被轻易用于用户追踪,但它们并不能完全阻止这种行为。在单一域名内,网站仍然可以在会话期间追踪用户,并且可以将所有这些信息与任何身份信息(如姓名、信用卡号码、地址)一起传递给第三方。如果第三方与多个网站合作获取这些信息,仍然可以创建一个用户档案。
然而,用户追踪在某种程度上是可能的,即使没有用户代理的任何合作,例如通过在 URL 中使用会话标识符,这种技术已经广泛用于无害的目的,但很容易被重新利用来进行用户追踪(甚至是事后追踪)。然后可以将这些信息与其他网站共享,使用访问者的IP地址和其他用户特定的数据(如用户代理头和配置设置)将独立的会话合并成连贯的用户档案。
用户代理应将持久存储的数据视为可能敏感的;例如,电子邮件、日历预约、健康记录或其他机密文件都有可能存储在此机制中。
为此,用户代理应确保在删除数据时,数据能够从底层存储中及时删除。
由于存在 DNS 欺骗攻击的可能性,不能保证声称来自某个域的主机确实来自该域。为减轻这种风险,页面可以使用 TLS。使用 TLS 的页面可以确保只有用户、代表用户工作的软件,以及其他使用 TLS 且拥有证明它们来自同一域的证书的页面,能够访问它们的存储区域。
共享同一主机名的不同作者,例如在已关闭的 geocities.com
上托管内容的用户,都会共享一个本地存储对象。没有功能可以按路径名限制访问。因此,共享主机的作者被敦促避免使用这些功能,因为其他作者很容易读取和覆盖这些数据。
即使提供了路径限制功能,通常的 DOM 脚本安全模型也能轻易绕过这种保护,从任何路径访问数据。
在实现这些持久存储功能时,主要的风险有两个:让恶意网站读取其他域的信息,以及让恶意网站写入其他域的数据。
允许第三方网站读取不应从其域读取的数据会导致信息泄漏。例如,一个域的用户购物愿望清单可能被另一个域用于定向广告;或者一个用户在文字处理网站上存储的进行中的机密文件可能被竞争公司的网站查看。
允许第三方网站将数据写入其他域的持久存储可能导致信息欺骗,这同样危险。例如,恶意网站可能向用户的愿望清单中添加项目;或者恶意网站可能将用户的会话标识符设置为已知 ID,然后利用该 ID 跟踪用户在受害网站上的操作。
因此,严格遵循本规范中描述的源模型对于用户安全至关重要。
本节仅描述标记为 HTML MIME 类型 的资源的规则。XML 资源的规则将在下方名为 "XML 语法" 的部分中讨论。
本节仅适用于文档、创作工具和标记生成器。特别地,它不适用于一致性检查器;一致性检查器必须使用下一节(“解析 HTML 文档”)中给出的要求。
文档必须由以下部分按给定顺序组成:
html
元素 的形式出现。上面提到的各种内容类型将在接下来的几节中进行描述。
此外,还有一些关于如何序列化 字符编码声明 的限制,如该主题的章节中所讨论的。
在 html
元素之前的 ASCII
空白符,在 html
元素的开始以及 head
元素之前的 ASCII 空白符将在文档解析时被删除;html
元素之后的
ASCII
空白符将被解析为如果它们位于 body
元素的末尾。因此,围绕文档元素的 ASCII 空白符 并不会被原样保存。
建议在 DOCTYPE 之后、在文档元素之前的任何注释之后、html
元素的开始标签之后(如果它未被 省略),以及
html
元素内的任何注释之后、在 head
元素之前插入换行符。
HTML 语法中的许多字符串(例如元素及其属性的名称)是大小写不敏感的,但仅限于 ASCII 大写字母 和 ASCII 小写字母。为了方便起见,在本节中,这只是被简单地称为“大小写不敏感”。
DOCTYPE 是一个必需的前言。
由于历史原因,DOCTYPE 是必需的。如果省略,浏览器往往会使用与某些规范不兼容的不同渲染模式。在文档中包含 DOCTYPE 可确保浏览器尽最大努力遵循相关规范。
DOCTYPE 必须按以下顺序由以下组件组成:
<!DOCTYPE
" ASCII
大小写不敏感 匹配的字符串。html
" ASCII
大小写不敏感 匹配的字符串。换句话说,<!DOCTYPE html>
,大小写不敏感。
对于无法输出带有简短 DOCTYPE "<!DOCTYPE html>
" 的 HTML 标记的 HTML 生成器,可以在 DOCTYPE 中插入一个 DOCTYPE 旧版字符串(在上面定义的位置)。该字符串必须由以下内容组成:
SYSTEM
" ASCII
大小写不敏感 匹配的字符串。about:legacy-compat
"。
换句话说,<!DOCTYPE html SYSTEM "about:legacy-compat">
或
<!DOCTYPE html SYSTEM 'about:legacy-compat'>
,引号中的部分大小写敏感。
除非文档是由无法输出较短字符串的系统生成的,否则不应使用 DOCTYPE 旧版字符串。
有六种不同类型的元素:空元素、template
元素、原始文本元素、可转义的原始文本元素、外部元素和普通元素。
area
、base
、br
、col
、embed
、hr
、img
、input
、link
、meta
、source
、track
、wbr
template
元素template
script
、style
textarea
、title
标签 用于在标记中分隔元素的开始和结束。原始文本、可转义的原始文本 和 普通 元素有一个开始标签,表示它们的开始,并且有一个结束标签,表示它们的结束。某些普通元素的开始和结束标签可以省略,如在下面的“可选标签”部分所述。那些不能省略的标签不应省略。空元素 只有一个开始标签;对于空元素,不得指定结束标签。外部元素必须要么有一个开始标签和一个结束标签,要么有一个标记为自闭合的开始标签,在这种情况下它们不得有结束标签。
元素的内容必须放在开始标签(某些情况下可能会被隐含)之后和结束标签(同样地,某些情况下可能会被隐含)之前。每个元素允许的具体内容取决于该元素的内容模型,如本规范前面所述。元素不得包含内容模型不允许的内容。但是,除了这些内容模型对内容施加的限制之外,五种类型的元素还有额外的语法要求。
空元素不能有任何内容(因为没有结束标签,所以无法在开始标签和结束标签之间放置内容)。
template
元素可以有模板内容,但这些模板内容不是template
元素本身的子元素。相反,它们存储在一个DocumentFragment
中,并与另一个不带浏览上下文的Document
关联,以避免template
内容干扰主Document
。template 内容的标记放置在template
元素的开始标签之后和template
元素的结束标签之前(与其他元素一样),可以包含任何文本、字符引用、元素和注释,但文本不得包含字符 U+003C
小于号(<)或模糊的符号。
可转义的原始文本元素可以包含文本和字符引用,但文本不得包含模糊的符号。下面还描述了进一步的限制。
外部元素的开始标签被标记为自闭合的,不能有任何内容(因为同样地,没有结束标签,无法在开始标签和结束标签之间放置内容)。外部元素的开始标签未标记为自闭合的可以包含文本、字符引用、CDATA 区段、其他元素和注释,但文本不得包含字符 U+003C 小于号(<)或模糊的符号。
HTML 语法不支持命名空间声明,即使在外部元素中也是如此。
例如,考虑以下 HTML 片段:
< p >
< svg >
< metadata >
<!-- this is invalid -->
< cdr:license xmlns:cdr = "https://www.example.com/cdr/metadata" name = "MIT" />
</ metadata >
</ svg >
</ p >
最内部的元素cdr:license
实际上位于 SVG 命名空间中,因为"xmlns:cdr
"属性没有任何作用(与 XML
中不同)。事实上,正如上述片段中的注释所说,该片段实际上是不符合规范的。这是因为SVG 2在 SVG 命名空间中没有定义任何名为"cdr:license
"的元素。
普通元素可以包含文本、字符引用、其他元素和注释,但文本不得包含字符 U+003C 小于号(<)或模糊的符号。一些普通元素在其允许包含的内容方面还具有进一步的限制,这些限制超出了内容模型施加的限制以及本段中描述的限制。此类限制将在下文中描述。
标签包含一个标签名,用于指定元素的名称。所有 HTML 元素的名称都只使用ASCII 字母数字字符。在 HTML 语法中,标签名(即使是外部元素的标签名)可以使用任意大小写字母的组合编写,转换为全小写字母后与元素的标签名匹配;标签名不区分大小写。
起始标签必须具有以下格式:
结束标签必须具有以下格式:
属性在元素的起始标签中表达。
属性有一个名称和一个值。属性名称必须由一个或多个字符组成,且这些字符不能是控制字符、U+0020 空格、U+0022(")、U+0027(')、U+003E(>)、U+002F(/)、U+003D(=)以及非字符。在HTML语法中,属性名称,即使是外部元素的属性名称,也可以用任何大小写字母的组合书写。
属性值是文本和字符引用的混合体,但还有限制,即文本不能包含模糊的 & 符号。
属性可以通过四种不同的方式指定:
仅有属性名称。值隐含为空字符串。
在以下示例中,disabled
属性使用了空属性语法:
< input disabled >
如果使用空属性语法的属性后面需要跟另一个属性,则必须有ASCII 空白字符将二者分开。
属性名称,然后是零个或多个ASCII 空白字符,然后是一个 U+003D 等号字符(=),再接着是零个或多个ASCII 空白字符,最后是属性值,该属性值除了必须符合上述属性值的要求外,还不能包含任何字面ASCII 空白字符、U+0022 双引号字符(")、U+0027 撇号字符(')、U+003D 等号字符(=)、U+003C 小于号字符(<)、U+003E 大于号字符(>)、或 U+0060 重音符号字符(`),并且不能为空字符串。
在以下示例中,value
属性使用了未引用的属性值语法:
< input value = yes >
如果使用未引用的属性语法的属性后面要跟另一个属性或可选的 U+002F 斜杠字符(/)(如在上述起始标签语法的第6步中所允许的),则必须有ASCII 空白字符将二者分开。
属性名称,然后是零个或多个ASCII 空白字符,然后是一个 U+003D 等号字符(=),再接着是零个或多个ASCII 空白字符,然后是一个 U+0027 撇号字符('),接着是属性值,除了必须符合上述属性值的要求外,还不能包含任何字面 U+0027 撇号字符('),最后由第二个 U+0027 撇号字符(')关闭。
在以下示例中,type
属性使用了单引号属性值语法:
< input type = 'checkbox' >
如果使用单引号属性语法的属性后面要跟另一个属性,则必须有ASCII 空白字符 将二者分开。
属性名称,然后是零个或多个ASCII 空白字符,然后是一个 U+003D 等号字符(=),再接着是零个或多个ASCII 空白字符,然后是一个 U+0022 双引号字符("),接着是属性值,除了必须符合上述属性值的要求外,还不能包含任何字面 U+0022 双引号字符("),最后由第二个 U+0022 双引号字符(")关闭。
在以下示例中,name
属性使用了双引号属性值语法:
< input name = "be evil" >
如果使用双引号属性语法的属性后面要跟另一个属性,则必须有ASCII 空白字符将二者分开。
在同一个起始标签中,不得有两个或多个属性的名称在ASCII大小写不敏感匹配时相同。
当一个外部元素具有以下表格中的本地名称和命名空间的属性时,该属性必须使用表格中相应行的第三个单元格中的名称书写。
本地名称 | 命名空间 | 属性名称 |
---|---|---|
actuate |
XLink 命名空间 | xlink:actuate |
arcrole |
XLink 命名空间 | xlink:arcrole |
href |
XLink 命名空间 | xlink:href |
role |
XLink 命名空间 | xlink:role |
show |
XLink 命名空间 | xlink:show |
title |
XLink 命名空间 | xlink:title |
type |
XLink 命名空间 | xlink:type |
lang |
XML 命名空间 | xml:lang |
space |
XML 命名空间 | xml:space |
xmlns |
XMLNS 命名空间 | xmlns |
xlink |
XMLNS 命名空间 | xmlns:xlink |
在HTML 语法中不能表达其他命名空间的属性。
上述表格中的属性是否符合规范由其他规范定义(例如SVG 2和MathML);本节仅描述这些属性在HTML语法中的序列化规则。
某些标签可以被省略。
在下述情形中省略元素的起始标签并不意味着该元素不存在;它被隐式表示,但仍然存在。例如,一个HTML文档总是有一个根html
元素,即使字符串<html>
在标记中未出现。
如果html
元素内部的第一个内容不是注释,那么可以省略html
元素的起始标签。
例如,在以下情况下可以删除"<html>
"标签:
<!DOCTYPE HTML>
< html >
< head >
< title > Hello</ title >
</ head >
< body >
< p > Welcome to this example.</ p >
</ body >
</ html >
这样做会使文档看起来像这样:
<!DOCTYPE HTML>
< head >
< title > Hello</ title >
</ head >
< body >
< p > Welcome to this example.</ p >
</ body >
</ html >
这将产生完全相同的DOM。特别注意,解析器会忽略围绕文档元素的空白字符。以下示例也会生成完全相同的DOM:
<!DOCTYPE HTML> < head >
< title > Hello</ title >
</ head >
< body >
< p > Welcome to this example.</ p >
</ body >
</ html >
然而,在下面的示例中,删除开始标签会将注释移到html
元素之前:
<!DOCTYPE HTML>
< html >
<!-- where is this comment in the DOM? -->
< head >
< title > Hello</ title >
</ head >
< body >
< p > Welcome to this example.</ p >
</ body >
</ html >
删除标签后,文档实际上变成了如下所示:
<!DOCTYPE HTML>
<!-- where is this comment in the DOM? -->
< html >
< head >
< title > Hello</ title >
</ head >
< body >
< p > Welcome to this example.</ p >
</ body >
</ html >
这就是为什么标签只能在后面没有注释的情况下删除的原因:如果在有注释的情况下删除标签,会改变文档解析后的树结构。当然,如果注释的位置无关紧要,那么标签可以被省略,就好像注释一开始就被移到起始标签之前一样。
一个 html
元素的结束标签可以省略,如果 html
元素后面没有紧跟着注释。
一个 head
元素的开始标签可以省略,如果该元素为空,或者
head
元素内的第一个内容是元素。
一个 head
元素的结束标签可以省略,如果 head
元素后面没有紧跟着ASCII空白字符或注释。
一个 body
元素的开始标签可以省略,如果该元素为空,或者
body
元素内的第一个内容不是ASCII空白字符或注释,除非 body
元素内的第一个内容是
meta
、noscript
、link
、script
、style
或template
元素。
一个 body
元素的结束标签可以省略,如果 body
元素后面没有紧跟着注释。
注意,在上面的示例中,head
元素的开始和结束标签,以及 body
元素的开始标签,不能省略,因为它们被空白字符包围:
<!DOCTYPE HTML>
< html >
< head >
< title > Hello</ title >
</ head >
< body >
< p > Welcome to this example.</ p >
</ body >
</ html >
(body
和
html
元素的结束标签可以毫无问题地省略;在这些标签之后的任何空白字符都会被解析到 body
元素中。)
然而,通常情况下,空白字符并不是问题。如果我们首先删除我们不关心的空白字符:
<!DOCTYPE HTML> < html >< head >< title > Hello</ title ></ head >< body >< p > Welcome to this example.</ p ></ body ></ html >
然后我们可以省略一些标签而不影响 DOM:
<!DOCTYPE HTML> < title > Hello</ title >< p > Welcome to this example.</ p >
此时,我们也可以添加一些空白字符回去:
<!DOCTYPE HTML>
< title > Hello</ title >
< p > Welcome to this example.</ p >
这相当于这个文档,其中省略的标签显示在解析器隐含的位置;唯一由此产生的空白文本节点是 head
元素末尾的换行符:
<!DOCTYPE HTML>
< html >< head > < title > Hello</ title >
</ head >< body > < p > Welcome to this example.</ p > </ body ></ html >
一个 li
元素的结束标签可以省略,如果 li
元素后面紧跟着另一个
li
元素,或者父元素中没有更多内容。
一个 dt
元素的结束标签可以省略,如果 dt
元素后面紧跟着另一个
dt
元素或一个
dd
元素。
一个 dd
元素的结束标签可以省略,如果 dd
元素后面紧跟着另一个
dd
元素或一个
dt
元素,或者父元素中没有更多内容。
一个 p
元素的结束标签可以省略,如果p
元素紧接着的是address
、article
、aside
、blockquote
、details
、dialog
、div
、dl
、fieldset
、figcaption
、figure
、footer
、form
、h1
、h2
、h3
、h4
、h5
、h6
、header
、hgroup
、hr
、main
、menu
、nav
、ol
、p
、pre
、search
、section
、table
或ul
元素,或者父元素中不再有其他内容,且父元素是一个不是a
、audio
、del
、ins
、map
、noscript
或video
的HTML 元素,或不是自主自定义元素。
因此我们可以进一步简化前面的示例:
<!DOCTYPE HTML> < title > Hello</ title >< p > Welcome to this example.
一个 rt
元素的结束标签可以省略,如果 rt
元素后面紧跟着另一个
rt
或 rp
元素,或者父元素中没有更多内容。
一个 rp
元素的结束标签可以省略,如果 rp
元素后面紧跟着一个
rt
或 rp
元素,或者父元素中没有更多内容。
一个 optgroup
元素的结束标签可以省略,如果 optgroup
元素后面紧跟着另一个 optgroup
元素,如果它后面紧跟着一个 hr
元素,或者父元素中没有更多内容。
一个 option
元素的结束标签可以省略,如果 option
元素后面紧跟着另一个 option
元素,如果它后面紧跟着一个 optgroup
元素,如果它后面紧跟着一个 hr
元素,或者父元素中没有更多内容。
一个 colgroup
元素的开始标签可以省略,如果 colgroup
元素内的第一个内容是 col
元素,并且该元素前面没有紧跟着另一个 colgroup
元素,其结束标签已被省略。(如果该元素为空,则不能省略。)
一个 colgroup
元素的结束标签可以省略,如果 colgroup
元素后面没有紧跟着ASCII空白字符或注释。
一个 caption
元素的结束标签可以省略,如果 caption
元素后面没有紧跟着ASCII空白字符或注释。
一个 thead
元素的结束标签可以省略,如果 thead
元素后面紧跟着一个 tbody
或 tfoot
元素。
一个 tbody
元素的开始标签可以省略,如果 tbody
元素内的第一个内容是 tr
元素,并且该元素前面没有紧跟着一个 tbody
、thead
或tfoot
元素,其结束标签已被省略。(如果该元素为空,则不能省略。)
一个 tbody
元素的结束标签可以省略,如果 tbody
元素后面紧跟着一个 tbody
或
tfoot
元素,或者父元素中没有更多内容。
一个 tfoot
元素的结束标签可以省略,如果父元素中没有更多内容。
一个 tr
元素的结束标签可以省略,如果 tr
元素后面紧跟着另一个
tr
元素,或者父元素中没有更多内容。
一个 td
元素的结束标签可以省略,如果 td
元素后面紧跟着一个
td
或 th
元素,或者父元素中没有更多内容。
一个 th
元素的结束标签可以省略,如果 th
元素后面紧跟着一个
td
或 th
元素,或者父元素中没有更多内容。
省略所有这些与表格相关的标签可以使表格标记简洁得多。
看这个例子:
< table >
< caption > 37547 TEE Electric Powered Rail Car Train Functions (Abbreviated)</ caption >
< colgroup >< col >< col >< col ></ colgroup >
< thead >
< tr >
< th > Function</ th >
< th > Control Unit</ th >
< th > Central Station</ th >
</ tr >
</ thead >
< tbody >
< tr >
< td > Headlights</ td >
< td > ✔</ td >
< td > ✔</ td >
</ tr >
< tr >
< td > Interior Lights</ td >
< td > ✔</ td >
< td > ✔</ td >
</ tr >
< tr >
< td > Electric locomotive operating sounds</ td >
< td > ✔</ td >
< td > ✔</ td >
</ tr >
< tr >
< td > Engineer's cab lighting</ td >
< td ></ td >
< td > ✔</ td >
</ tr >
< tr >
< td > Station Announcements - Swiss</ td >
< td ></ td >
< td > ✔</ td >
</ tr >
</ tbody >
</ table >
完全相同的表格,除了空白字符的差异之外,可以标记如下:
< table >
< caption > 37547 TEE Electric Powered Rail Car Train Functions (Abbreviated)
< colgroup >< col >< col >< col >
< thead >
< tr >
< th > Function
< th > Control Unit
< th > Central Station
< tbody >
< tr >
< td > Headlights
< td > ✔
< td > ✔
< tr >
< td > Interior Lights
< td > ✔
< td > ✔
< tr >
< td > Electric locomotive operating sounds
< td > ✔
< td > ✔
< tr >
< td > Engineer's cab lighting
< td >
< td > ✔
< tr >
< td > Station Announcements - Swiss
< td >
< td > ✔
</ table >
由于单元格占用的空间更少,因此可以通过将每一行放在一行上来使其更加简洁:
< table >
< caption > 37547 TEE Electric Powered Rail Car Train Functions (Abbreviated)
< colgroup >< col >< col >< col >
< thead >
< tr > < th > Function < th > Control Unit < th > Central Station
< tbody >
< tr > < td > Headlights < td > ✔ < td > ✔
< tr > < td > Interior Lights < td > ✔ < td > ✔
< tr > < td > Electric locomotive operating sounds < td > ✔ < td > ✔
< tr > < td > Engineer's cab lighting < td > < td > ✔
< tr > < td > Station Announcements - Swiss < td > < td > ✔
</ table >
这些表格在 DOM 层级上的唯一区别在于(无论如何在语义上都是中性的)空白字符的精确位置。
然而,如果一个开始标签有任何属性,则绝不能省略它。
回到之前的示例,移除所有空白字符,然后移除所有可选标签:
<!DOCTYPE HTML> < title > Hello</ title >< p > Welcome to this example.
如果此示例中的 body
元素必须有一个 class
属性,并且 html
元素必须有一个 lang
属性,那么标记必须变成:
<!DOCTYPE HTML> < html lang = "en" >< title > Hello</ title >< body class = "demo" >< p > Welcome to this example.
本节假设文档是符合规范的,特别是没有内容模型的违规行为。在不符合本规范中描述的内容模型的文档中,以本节描述的方式省略标签,可能会导致意外的 DOM 差异(这是内容模型设计要避免的一部分原因)。
由于历史原因,某些元素除了其内容模型规定的限制外,还有额外的限制。
一个 table
元素不得包含 tr
元素,尽管根据本规范中描述的内容模型,这些元素在 table
元素内部在技术上是被允许的。(如果在标记中将一个 tr
元素放在
table
中,它实际上会在其前面隐含一个 tbody
开始标签。)
一个单独的换行符可以紧接在
pre
和
textarea
元素的开始标签之后放置。这不会影响元素的处理。如果元素的内容本身以换行符开头,那么必须包括原本可选的换行符(因为否则内容中的首个换行符会被视为可选换行符,并被忽略)。
原始文本和可转义原始文本元素中的文本不得包含字符串“</
”(U+003C
小于号,U+002F 斜杠)后跟与元素标签名称不区分大小写匹配的字符,后面紧跟 U+0009 字符制表符(tab)、U+000A 换行符(LF)、U+000C 进纸符(FF)、U+000D 回车符(CR)、U+0020
空格、U+003E 大于号(>)或 U+002F 斜杠(/)中的一个。
文本 允许出现在元素、属性值和注释中。基于文本的位置,关于文本允许和不允许的内容有额外的限制,如其他部分所述。
HTML中的换行符可以表示为U+000D回车符(CR)字符、U+000A换行符(LF)字符,或按顺序出现的U+000D回车符(CR)、U+000A换行符(LF)字符对。
在允许使用字符引用的地方,U+000A换行符(LF)字符的字符引用(但不是U+000D回车符(CR)字符)也代表一个换行符。
在其他部分描述的某些情况下,文本可以与字符引用混合使用。这些字符引用可以用于转义在文本中不能合法包含的字符。
字符引用必须以U+0026 &符号字符(&)开头。接下来有三种可能的字符引用类型:
上述数字字符引用形式可以引用任何代码点,但排除U+000D CR、非字符和除ASCII空白以外的控制字符。
一个模糊的&符号是指后跟一个或多个ASCII字母数字,再跟一个U+003B分号字符(;)的U+0026 &符号字符(&),但这些字符不与命名字符引用部分中的任何名称匹配。
CDATA 部分必须由以下组件按顺序组成:
<![CDATA[
”。]]>
”。]]>
”。CDATA 部分只能用于外部内容(MathML 或 SVG)。在此示例中,CDATA 部分用于转义MathML
ms
元素的内容:
< p > You can add a string to a number, but this stringifies the number:</ p >
< math >
< ms > <![CDATA[x<y]]> </ ms >
< mo > +</ mo >
< mn > 3</ mn >
< mo > =</ mo >
< ms > <![CDATA[x<y3]]> </ ms >
</ math >
注释必须具有以下格式:
<!--
”。>
”开头,也不得以字符串“->
”开头,不得包含字符串“<!--
”、“-->
”或“--!>
”,并且不得以字符串“<!-
”结尾。
-->
”。文本可以以字符串“<!
”结尾,例如<!--My favorite operators are > and <!-->
。
本节仅适用于用户代理、数据挖掘工具和符合性检查器。
解析 XML 文档为 DOM 树的规则在下一节中讨论,标题为“XML 语法”。
用户代理必须使用本节描述的解析规则来从text/html
资源生成
DOM 树。这些规则共同定义了所谓的HTML 解析器。
虽然本规范中描述的 HTML 语法与 SGML 和 XML 有很大相似之处,但它是一种具有自己解析规则的独立语言。
HTML 的一些早期版本(特别是从 HTML2 到 HTML4)基于 SGML 并使用 SGML 解析规则。然而,很少有(如果有的话)网络浏览器曾经实现过对 HTML 文档的真正 SGML 解析;历史上,严格处理 HTML 作为 SGML 应用程序的唯一用户代理是验证器。由此产生的混乱——验证器声称文档有一种表示方式,而广泛部署的网络浏览器则以互操作的方式实现了另一种表示方式——浪费了几十年的生产力。因此,这个版本的 HTML 回归到非 SGML 基础。
建议有兴趣在其创作管道中使用 SGML 工具的作者使用 XML 工具和 HTML 的 XML 序列化。
对于符合性检查器,如果确定资源采用的是HTML 语法,那么它就是一个HTML 文档。
正如术语部分所述,未明确指定命名空间的元素类型引用总是指HTML
命名空间中的元素。例如,如果规范中提到“menu
元素”,那么这就是一个本地名称为“menu
”的元素,命名空间为“http://www.w3.org/1999/xhtml
”,接口为HTMLMenuElement
。在可能的情况下,对这些元素的引用都链接到了它们的定义。
HTML 解析过程的输入由一串代码点组成,这些代码点首先经过标记化阶段,然后进入树构建阶段。输出是一个文档
对象。
不支持脚本的实现实际上不需要创建一个 DOM 文档
对象,但在这种情况下,DOM
树仍然作为规范其余部分的模型使用。
在常见情况下,标记化阶段处理的数据来自网络,但它也可以来自在用户代理中运行的脚本,例如使用document.write()
API。
标记化阶段和树构建阶段只有一组状态,但树构建阶段是可重入的,这意味着当树构建阶段处理一个标记时,标记器可能会恢复,导致在第一个标记的处理完成之前发出并处理更多的标记。
在以下示例中,树构建阶段将在处理“script”结束标签标记时被调用来处理一个“p”开始标签标记:
...
< script >
document. write( '<p>' );
</ script >
...
为了处理这些情况,解析器有一个脚本嵌套级别,其初始值必须设为零,以及一个解析器暂停标志,其初始值必须设为 false。
本规范定义了HTML文档的解析规则,无论其语法是否正确。解析算法中的某些点被称为解析错误。解析错误的处理是明确的(即本规范中描述的处理规则),但用户代理在解析HTML文档时,可以在遇到的第一个他们不想应用本规范中描述的规则的解析错误时中止解析器。
如果文档中存在一个或多个解析错误情况,符合性检查器必须至少报告一个解析错误情况;如果文档中不存在解析错误情况,则不得报告任何解析错误情况。如果文档中存在多个解析错误情况,符合性检查器可以报告多个解析错误情况。
解析错误只是HTML语法上的错误。除了检查解析错误外,符合性检查器还将验证文档是否遵守本规范中描述的所有其他符合性要求。
某些解析错误有专门的代码,在报告中应由符合性检查器使用。
下表中的错误描述是非规范性的。
代码 | 描述 |
---|---|
abrupt-closing-of-empty-comment |
当解析器遇到一个由U+003E(>)码点(即 |
abrupt-doctype-public-identifier |
当解析器在DOCTYPE公共标识符中遇到U+003E(>)码点时(例如 |
abrupt-doctype-system-identifier |
当解析器在DOCTYPE系统标识符中遇到U+003E(>)码点时(例如 |
absence-of-digits-in-numeric-character-reference |
当解析器遇到不包含任何数字的数字字符引用时(例如 |
cdata-in-html-content |
当解析器在非外部内容(SVG或MathML)中遇到CDATA部分时,会发生此错误。解析器将这些CDATA部分(包括前导的" |
character-reference-outside-unicode-range |
当解析器遇到引用超出有效Unicode范围的字符引用时,会发生此错误。解析器将此类字符引用解析为U+FFFD替换字符。 |
control-character-in-input-stream |
当输入流包含不是ASCII空白或U+0000 NULL的控制码点时,会发生此错误。这些码点按原样解析,并且通常在解析规则不适用其他限制时,会直接进入DOM。 |
control-character-reference |
当解析器遇到引用了不是ASCII空白或U+000D回车符的字符引用的控制码点时,会发生此错误。解析器按原样解析此类字符引用,除了C1控制引用根据数字字符引用结束状态替换。 |
duplicate- attribute |
当解析器在标记中遇到具有相同名称的属性时,会发生此错误。解析器忽略所有此类属性的重复出现。 |
end-tag-with-attributes | |
end-tag-with-trailing-solidus |
当解析器遇到在关闭U+003E(>)码点之前带有U+002F(/)的结束标签时(例如 |
eof-before-tag-name |
当解析器在应出现标记名称的位置遇到输入流的结束时,会发生此错误。在这种情况下,解析器将开始标签的开始(即 |
eof-in-cdata | |
eof-in-comment | |
eof-in-doctype |
当解析器在DOCTYPE中遇到输入流的结束时,会发生此错误。在这种情况下,如果DOCTYPE正确地作为文档前言放置,解析器将 |
eof-in-script-html-comment-like-text |
当解析器在输入流中遇到类似于HTML注释的文本时,会发生此错误,而这些文本位于 在 |
eof-in-tag | |
incorrectly-closed-comment | |
incorrectly-opened-comment |
当解析器遇到" 此错误的一个可能原因是在HTML中使用了XML标记声明(例如 |
invalid-character-sequence-after-doctype-name |
当解析器在码点序列中遇到除" |
invalid-first-character-of-tag-name |
当解析器在预期开始标签名称的第一个码点或结束标签名称的第一个码点处遇到不是ASCII字母的码点时,会发生此错误。如果预期是开始标签,则该码点和前面的U+003C(<)被视为文本内容,所有后续内容被视为标记。如果预期是结束标签,则该码点和所有后续内容直到U+003E(>)码点(如果存在)或输入流的结束,都会被视为注释。 |
missing-attribute-value |
当解析器在应出现属性值的位置遇到U+003E(>)码点时(例如 |
missing-doctype-name |
当解析器遇到缺少名称的DOCTYPE时(例如 |
missing-doctype-public-identifier |
当解析器在应出现DOCTYPE公共标识符的地方遇到U+003E(>)码点时(例如 |
missing-doctype-system-identifier |
当解析器在应出现DOCTYPE系统标识符的地方遇到U+003E(>)码点时(例如 |
missing-end-tag-name |
当解析器在应出现结束标签名称的位置遇到U+003E(>)码点时,即 |
missing-quote-before-doctype-public-identifier |
当解析器遇到前面没有引号的DOCTYPE公共标识符时(例如 |
missing-quote-before-doctype-system-identifier |
当解析器遇到前面没有引号的DOCTYPE系统标识符时(例如 |
missing-semicolon-after-character-reference |
当解析器遇到未以U+003B(;)码点终止的字符引用时,会发生此错误。通常,解析器的行为是字符引用由U+003B(;)码点终止;然而,在某些模糊情况下,解析器会将后续的码点包括在字符引用中。
例如, |
missing-whitespace-after-doctype-public-keyword |
当解析器遇到其" |
missing-whitespace-after-doctype-system-keyword |
当解析器遇到其" |
missing-whitespace-before-doctype-name |
当解析器遇到其" |
missing-whitespace-between-attributes |
当解析器遇到未被属性值分隔的ASCII空白(例如 |
missing-whitespace-between-doctype-public-and-system-identifiers |
当解析器遇到其公共和系统标识符之间没有ASCII空白的DOCTYPE时,会发生此错误。在这种情况下,解析器的行为就像存在ASCII空白一样。 |
nested-comment |
当解析器遇到嵌套的注释时(例如 |
noncharacter-character-reference | |
noncharacter-in-input-stream | |
non-void-html-element-start-tag-with-trailing-solidus |
当解析器遇到一个开始标签,其元素不在空元素列表中,也不是外部内容(即不是SVG或MathML元素)的一部分,且在关闭的U+003E(>)码点之前带有U+002F(/)码点时,会发生此错误。解析器的行为就像U+002F(/)不存在一样。 开始标签名称中的尾随U+002F(/)只能在外部内容中用于指定自闭合标签。(HTML中不存在自闭合标签。)它也允许用于空元素,但在这种情况下没有任何效果。 |
null-character-reference |
当解析器遇到引用U+0000 NULL字符引用的数字码点时,会发生此错误。解析器将此类字符引用解析为U+FFFD替换字符。 |
surrogate-character-reference | |
surrogate-in-input-stream |
当输入流包含代理时,会发生此错误。此类码点按原样解析,并且通常在解析规则不适用其他限制时,会直接进入DOM。 代理只能通过脚本API(如 |
unexpected-character-after-doctype-system-identifier |
当解析器在DOCTYPE系统标识符之后遇到除ASCII空白或关闭的U+003E(>)之外的任何码点时,会发生此错误。解析器会忽略这些码点。 |
unexpected-character-in-attribute-name |
当解析器在属性名称中遇到U+0022(")、U+0027(')或U+003C(<)码点时,会发生此错误。解析器将此类码点包括在属性名称中。 触发此错误的码点通常是另一个语法结构的一部分,可能是属性名称周围的拼写错误的标志。 |
unexpected-character-in-unquoted-attribute-value |
当解析器在未引用的属性值中遇到U+0022(")、U+0027(')、U+003C(<)、U+003D(=)或U+0060(`)码点时,会发生此错误。解析器将此类码点包括在属性值中。 触发此错误的码点通常是另一个语法结构的一部分,可能是属性值周围的拼写错误的标志。 U+0060(`)在触发此错误的码点列表中,因为某些旧版用户代理将其视为引号。 例如,考虑以下标记:
由于U+0027(')码点放错了位置,解析器将" |
unexpected-equals-sign-before-attribute-name |
当解析器在属性名称之前遇到U+003D(=)码点时,会发生此错误。在这种情况下,解析器将U+003D(=)视为属性名称的第一个码点。 此错误的常见原因是忘记了属性名称。 |
unexpected-null-character |
当解析器在某些位置的输入流中遇到U+0000 NULL码点时,会发生此错误。通常,此类码点要么被忽略,要么出于安全原因被替换为U+FFFD替换字符。 |
unexpected-question-mark-instead-of-tag-name |
当解析器在应出现开始标签名称的第一个码点的位置遇到U+003F(?)码点时,会发生此错误。U+003F(?)和所有后续内容直到U+003E(>)码点(如果存在)或输入流的结束,将被视为注释。 例如,考虑以下标记:
这将被解析为:
此错误的常见原因是在HTML中使用XML处理指令(例如 |
unexpected-solidus-in-tag |
当解析器在标记中遇到不是引用属性值的一部分且未紧跟U+003E(>)码点之后的U+002F(/)码点时(例如 |
unknown-named-character-reference |
进入标记化阶段的代码点流最初将由用户代理视为字节流(通常通过网络或从本地文件系统传输)。这些字节根据特定的字符编码对实际字符进行编码,用户代理使用该编码将字节解码为字符。
对于XML文档,要求用户代理使用的确定字符编码的算法由XML定义。本节不适用于XML文档。[XML]
通常,下面定义的编码嗅探算法用于确定字符编码。
给定一个字符编码,输入字节流中的字节必须通过将输入字节流和字符编码传递给解码器来转换为标记化器的输入流中的字符。
前导字节顺序标记(BOM)会导致字符编码参数被忽略,并且BOM本身将被跳过。
原始字节流中不符合编码标准的字节或字节序列(例如UTF-8输入字节流中的无效UTF-8字节序列)是符合性检查器应该报告的错误。[ENCODING]
解码器算法描述了如何处理无效输入;出于安全原因,必须严格遵循这些规则。处理无效字节序列的差异可能导致包括脚本注入漏洞(“XSS”)在内的各种问题。
当HTML解析器解码输入字节流时,它使用字符编码和置信度。置信度可以是暂定的、确定的或无关紧要的。使用的编码以及该编码的置信度是暂定的还是确定的,在解析期间用于确定是否更改编码。如果不需要编码,例如因为解析器在Unicode流上操作且根本不需要使用字符编码,则置信度是无关紧要的。
某些算法通过将字符直接添加到输入流中,而不是将字节添加到输入字节流中,来向解析器提供数据。
当HTML解析器要在具有已知确定编码的输入字节流上操作时,字符编码就是该编码,并且置信度是确定的。
在某些情况下,在解析文档之前明确确定编码可能是不切实际的。出于这个原因,本规范提供了具有可选预扫描的两次通过机制。允许实现如下所述,在开始解析文档之前,将简化的解析算法应用于他们所拥有的字节。然后,启动真正的解析器,使用从预解析和其他带外元数据派生的暂定编码。如果在加载文档时,用户代理发现了与该信息冲突的字符编码声明,则可以重新调用解析器,以实际编码重新解析文档。
用户代理必须使用以下算法,即编码嗅探算法,在第一次传递中确定解码文档时要使用的字符编码。该算法将用户代理可用的任何带外元数据(例如文档的Content-Type元数据)和目前可用的所有字节作为输入,并返回一个字符编码和置信度,这个置信度可以是暂定的或确定的。
如果BOM嗅探的结果是编码,则返回该编码,并将置信度设置为确定的。
如果用户明确指示用户代理用特定编码覆盖文档的字符编码,则可以选择返回该编码,并将置信度设置为确定的。
通常,用户代理会跨会话记住此类用户请求,并且在某些情况下也将它们应用于iframe
中的文档。
用户代理可以等待更多资源字节可用,在此步骤或此算法中的任何后续步骤中。例如,用户代理可能会等待500毫秒或1024个字节,以先到者为准。通常,预解析源以找到编码可以提高性能,因为它减少了在找到编码信息时丢弃解析时使用的数据结构的需求。然而,如果用户代理等待时间过长以获取数据来确定编码,则延迟的成本可能超过预解析带来的性能提升。
字符编码声明的创作符合性要求将它们限制为只能出现在前1024个字节中。因此,鼓励用户代理在前1024个字节上使用下面的预扫描算法(按照这些步骤调用),但不要延迟超出此范围。
如果传输层指定了字符编码,并且该编码受到支持,则返回该编码,并将置信度设置为确定的。
可选择预扫描字节流以确定其编码,终止条件为用户代理认为继续扫描字节将不再有效。鼓励用户代理仅预扫描前1024个字节。用户代理可以认为扫描任何字节都无效,在这种情况下,这些子步骤将完全跳过。
上述算法返回字符编码或失败。如果它返回字符编码,则返回相同的编码,并将置信度设置为暂定的。
否则,如果用户代理有关于该页面可能编码的信息,例如基于上次访问页面时的编码,则返回该编码,并将置信度设置为暂定的。
用户代理可以尝试通过对数据流应用频率分析或其他算法自动检测字符编码。此类算法可以使用有关资源的其他信息,而不仅仅是资源的内容,包括资源的地址。如果自动检测成功确定字符编码,并且该编码是受支持的编码,则返回该编码,并将置信度设置为暂定的。[UNIVCHARDET]
通常不鼓励用户代理尝试对通过网络获取的资源进行自动检测编码,因为这样做涉及固有的不互通启发式方法。基于HTML文档的前言尝试检测编码特别棘手,因为HTML标记通常仅使用ASCII字符,而HTML文档通常以大量标记开始,而不是文本内容。
UTF-8编码具有高度可检测的位模式。包含值大于0x7F的字节且与UTF-8模式匹配的本地文件系统中的文件很可能是UTF-8,而包含不匹配字节序列的文档则很可能不是。当用户代理可以检查整个文件,而不仅仅是前言时,专门检测UTF-8特别有效。[PPUTF8] [UTF8DET]
否则,返回一个实现定义的或用户指定的默认字符编码,置信度为暂定的。
在受控环境中或可以规定文档编码的环境中(例如,旨在专用新网络中使用的用户代理),建议使用全面的UTF-8
编码。
在其他环境中,默认编码通常依赖于用户的区域设置(用户可能经常访问的页面的语言的近似值,从而通常是编码)。以下表格给出了基于用户区域设置的建议默认值,以与旧版内容兼容。区域设置通过BCP 47语言标签标识。 [BCP47] [ENCODING]
本地语言 | 建议的默认编码 | |
---|---|---|
ar | 阿拉伯语 | windows-1256 |
az | 阿塞拜疆语 | windows-1254 |
ba | 巴什基尔语 | windows-1251 |
be | 白俄罗斯语 | windows-1251 |
bg | 保加利亚语 | windows-1251 |
cs | 捷克语 | windows-1250 |
el | 希腊语 | ISO-8859-7 |
et | 爱沙尼亚语 | windows-1257 |
fa | 波斯语 | windows-1256 |
he | 希伯来语 | windows-1255 |
hr | 克罗地亚语 | windows-1250 |
hu | 匈牙利语 | ISO-8859-2 |
ja | 日语 | Shift_JIS |
kk | 哈萨克语 | windows-1251 |
ko | 韩语 | EUC-KR |
ku | 库尔德语 | windows-1254 |
ky | 吉尔吉斯语 | windows-1251 |
lt | 立陶宛语 | windows-1257 |
lv | 拉脱维亚语 | windows-1257 |
mk | 马其顿语 | windows-1251 |
pl | 波兰语 | ISO-8859-2 |
ru | 俄语 | windows-1251 |
sah | 雅库特语 | windows-1251 |
sk | 斯洛伐克语 | windows-1250 |
sl | 斯洛文尼亚语 | ISO-8859-2 |
sr | 塞尔维亚语 | windows-1251 |
tg | 塔吉克语 | windows-1251 |
th | 泰语 | windows-874 |
tr | 土耳其语 | windows-1254 |
tt | 鞑靼语 | windows-1251 |
uk | 乌克兰语 | windows-1251 |
vi | 越南语 | windows-1258 |
zh-Hans, zh-CN, zh-SG | 简体中文 | GBK |
zh-Hant, zh-HK, zh-MO, zh-TW | 繁体中文 | Big5 |
所有其他语言环境 | windows-1252 |
此表内容源自Windows、Chrome和Firefox的默认设置交集。
文档的字符编码必须立即设置为从该算法返回的值,同时用户代理使用返回的值选择用于输入字节流的解码器。
当算法要求用户代理预扫描字节流以确定其编码时,给定一些定义的end condition,它必须运行以下步骤。如果在这些步骤中的任何一点(包括此算法调用的获取属性算法实例期间)用户代理要么耗尽字节(即下面的第一个步骤中创建的position指针超出目前获得的字节流的末尾),要么到达其end condition,则中止预扫描字节流以确定其编码算法,并返回结果获取XML编码,应用于与预扫描字节流以确定其编码算法应用于相同的字节。否则,这些步骤将返回一个字符编码。
设fallback encoding为null。
设position为指向输入字节流中一个字节的指针,最初指向第一个字节。
预扫描UTF-16 XML声明:如果position指向:
返回UTF-16LE。
返回UTF-16BE。
出于历史原因,前缀比XML附录F中的前缀多两个字节,并且不检查编码名称。
循环:如果position指向:
<!--
`)开头的一系列字节将position指针前移,使其指向前面有两个0x2D字节并位于找到的0x3C字节之后的第一个0x3E字节(即在ASCII'-->'序列的末尾)。(这两个0x2D字节可以与'<!--'序列中的相同。)
将position指针前移,使其指向下一个0x09, 0x0A, 0x0C, 0x0D, 0x20或0x2F字节(与上面匹配的字符序列中的那个字节)。
设attribute list为空字符串列表。
设got pragma为false。
设need pragma为null。
设charset为null值(在此算法中,这与未识别的编码或空字符串不同)。
属性:获取属性及其值。如果没有获取到属性,则跳转到下面的处理步骤。
如果属性名称已经在attribute list中,则返回属性步骤。
将属性名称添加到attribute list中。
运行以下列表中的相应步骤(如果适用):
http-equiv
"如果属性值是"content-type
",则将got pragma设置为true。
content
"应用从meta
元素中提取字符编码的算法,将属性值作为解析的字符串。如果返回了一个字符编码,并且charset仍设置为null,则将charset设置为返回的编码,并将need
pragma设置为true。
charset
"将charset设为获取编码的结果,取自属性值,并将need pragma设置为false。
返回属性步骤。
处理:如果need pragma为null,则跳转到下面标记为下一字节的步骤。
如果need pragma为true但got pragma为false,则跳转到下面标记为下一字节的步骤。
如果charset为失败,则跳转到下面标记为下一字节的步骤。
如果charset是UTF-16BE/LE,则将charset设置为UTF-8。
如果charset是x-user-defined,则将charset设置为windows-1252。
返回charset。
将position指针前移,使其指向下一个0x09(HT)、0x0A(LF)、0x0C(FF)、0x0D(CR)、0x20(SP)或0x3E(>)字节。
反复获取属性直到找不到更多属性,然后跳转到下面标记为下一字节的步骤。
<!
`)</
`)<?
`)将position指针前移,使其指向找到的0x3C字节之后的第一个0x3E字节(>)。
对该字节不做任何处理。
当预扫描字节流以确定其编码算法要求获取属性时,它的含义如下:
如果position处的字节是0x09(HT)、0x0A(LF)、0x0C(FF)、0x0D(CR)、0x20(SP)或0x2F(/)之一,则将position前移到下一个字节并重新执行此步骤。
如果position处的字节是0x3E(>),则中止获取属性算法。不存在属性。
否则,position处的字节是属性名称的开始。设attribute name和attribute value为空字符串。
按如下方式处理position处的字节:
将position前移到下一个字节并返回到上一步骤。
空格:如果position处的字节是0x09(HT)、0x0A(LF)、0x0C(FF)、0x0D(CR)或0x20(SP)之一,则将position前移到下一个字节,然后重复此步骤。
如果position处的字节不是0x3D(=),则中止获取属性算法。属性的名称为attribute name的值,其值为空字符串。
将position移过0x3D(=)字节。
值:如果position处的字节是0x09(HT)、0x0A(LF)、0x0C(FF)、0x0D(CR)或0x20(SP)之一,则将position前移到下一个字节,然后重复此步骤。
按如下方式处理position处的字节:
按如下方式处理position处的字节:
将position前移到下一个字节并返回到上一步骤。
当预扫描字节流以确定其编码算法在未返回编码的情况下被中止时,获取XML编码的含义如下。
即使在text/html
中查找类似XML声明的语法也是为了兼容现有内容。
令 encodingPosition 为指向流开始的指针。
如果 encodingPosition 没有指向字节序列 0x3C, 0x3F, 0x78, 0x6D, 0x6C (`<?xml
`),则返回失败。
令 xmlDeclarationEnd 为输入字节流中下一个为 0x3E (>) 的字节指针。如果没有这样的字节,则返回失败。
将 encodingPosition 设置为在当前 encodingPosition 处或之后的字节子序列 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69,
0x6E, 0x67 (`encoding
`) 的第一次出现的位置。如果没有这样的序列,则返回失败。
将 encodingPosition 前移超过字节 0x67 (g)。
当 encodingPosition 处的字节小于或等于 0x20(即它是 ASCII 空格或控制字符)时,将 encodingPosition 前移到下一个字节。
如果 encodingPosition 处的字节不是 0x3D (=),则返回失败。
将 encodingPosition 前移到下一个字节。
当 encodingPosition 处的字节小于或等于 0x20(即它是 ASCII 空格或控制字符)时,将 encodingPosition 前移到下一个字节。
令 quoteMark 为 encodingPosition 处的字节。
如果 quoteMark 不是 0x22 (") 或 0x27 ('),则返回失败。
将 encodingPosition 前移到下一个字节。
令 encodingEndPosition 为从 encodingPosition 开始到下一个 quoteMark 出现的位置。如果 quoteMark 不再出现,则返回失败。
令 potentialEncoding 为介于 encodingPosition(包含)和 encodingEndPosition(不包含)之间的字节序列。
如果 potentialEncoding 包含一个或多个字节,其字节值为 0x20 或以下,则返回失败。
如果 encoding 是 UTF-16BE/LE,则将其更改为 UTF-8。
返回 encoding。
为了互操作性,用户代理不应使用返回与上述描述的结果不同的预扫描算法。(但是,如果你这样做,请至少通知我们,这样我们可以改进此算法,造福所有人……)
用户代理必须支持在编码中定义的编码,包括但不限于UTF-8、ISO-8859-2、ISO-8859-7、ISO-8859-8、windows-874、windows-1250、windows-1251、windows-1252、windows-1254、windows-1255、windows-1256、windows-1257、windows-1258、GBK、Big5、ISO-2022-JP、Shift_JIS、EUC-KR、UTF-16BE、UTF-16LE、UTF-16BE/LE,以及x-user-defined。用户代理不得支持其他编码。
上述规定禁止支持例如CESU-8、UTF-7、BOCU-1、SCSU、EBCDIC和UTF-32等编码。本规范不尝试在其算法中支持被禁止的编码;支持和使用被禁止的编码将导致意外行为。[CESU8] [UTF7] [BOCU1] [SCSU]
当解析器要求用户代理更改编码时,它必须执行以下步骤。这可能发生在编码嗅探算法未能找到字符编码,或找到的字符编码并非文件的实际编码时。
如果已经用于解释输入流的编码是UTF-16BE/LE,则将置信度设置为确定并返回。新编码被忽略;如果它不是相同的编码,那么它显然是错误的。
如果新编码是UTF-16BE/LE,则将其更改为UTF-8。
如果新编码是x-user-defined,则将其更改为windows-1252。
如果新编码与已经用于解释输入流的编码相同或等效,则将置信度设置为确定并返回。当文件中找到的编码信息与编码嗅探算法确定的编码匹配时,以及在解析器的第二次通过中,如果第一次通过发现上述编码嗅探算法未能找到正确的编码时,会发生这种情况。
如果所有字节到当前解码器转换的最后一个字节在当前编码和新编码中的Unicode解释相同,并且如果用户代理支持动态更改转换器,那么用户代理可以动态更改为新编码的转换器。将文档的字符编码和用于转换输入流的编码设置为新编码,将置信度设置为确定,并返回。
否则,重新启动导航
算法,将historyHandling设置为"替换
",其他输入保持不变,但这次跳过编码嗅探算法,而只是将编码设置为新编码,并将置信度设置为确定。只要可能,这应该在不实际联系网络层的情况下完成(字节应该从内存中重新解析),即使例如文档被标记为不可缓存。如果这不可能,并且联系网络层将涉及重复使用非GET
方法的请求,那么应将置信度设置为确定并忽略新编码。资源将被误解。用户代理可以通知用户这种情况,以帮助应用程序开发。
此算法仅在在meta
元素上找到新编码声明时调用。
输入流由在输入字节流解码时或通过直接操作输入流的各种API推送到其中的字符组成。
任何代理的出现都是输入流中的代理的解析错误。任何非字符的出现都是输入流中的非字符的解析错误,任何控制字符的出现(除了ASCII空白字符和U+0000 NULL字符)都是输入流中的控制字符的解析错误。
U+0000 NULL字符的处理方式根据字符的位置有所不同,并在解析的后期阶段发生。它们要么被忽略,要么由于安全原因被替换为U+FFFD替换字符。这种处理必然会分布在标记化阶段和树构建阶段。
在标记化阶段之前,必须通过规范化换行符来预处理输入流。因此,HTML DOM中的换行符由U+000A LF字符表示,标记化阶段的输入中不会出现U+000D CR字符。
下一个输入字符是输入流中尚未被本节要求消耗或显式忽略的第一个字符。最初,下一个输入字符是输入中的第一个字符。当前输入字符是最后一个被消耗的字符。
插入点是使用document.write()
插入的内容实际插入的位置(就在一个字符之前或输入流的末尾之前)。插入点相对于它之后的字符的位置,它不是输入流中的绝对偏移。最初,插入点是未定义的。
下表中的"EOF"字符是表示输入流结束的概念性字符。如果解析器是脚本创建的解析器,则当document.close()
方法消耗一个显式"EOF"字符时,输入流就会结束。否则,"EOF"字符并不是流中的真实字符,而是没有任何后续字符的标志。
插入模式是一个控制树构建阶段主要操作的状态变量。
最初,插入模式是"初始"。它可以在解析过程中更改为"html之前"、"head之前"、"在head中"、"在head noscript中"、"head之后"、"在body中"、"在文本中"、"在table中"、"在table文本中"、"在caption中"、"在列组中"、"在table body中"、"在行中"、"在单元格中"、"在select中"、"在table中的select中"、"在模板中"、"在body之后"、"在frameset中"、"在frameset之后"、"在body之后的之后",以及"在frameset之后的之后",如树构建阶段所述。插入模式影响标记的处理方式以及是否支持CDATA段。
其中的几个模式,特别是"在head中"、"在body中"、"在table中"和"在select中",是特殊的,因为在某些时候其他模式会让位于它们。当下面的算法说明用户代理应当"使用m插入模式的规则"做某事时,其中m是这些模式之一,用户代理必须使用m 插入模式部分中描述的规则,但必须保持插入模式不变,除非m中的规则自行切换到新的插入模式。
当插入模式切换到"文本"或"在table文本中"时,还会设置原始插入模式。树构建阶段将返回此插入模式。
类似地,为了解析嵌套的模板
元素,使用了一个模板插入模式栈。它最初是空的。当前模板插入模式是最近添加到模板插入模式栈中的插入模式。下面各节中的算法将推入插入模式到这个栈中,这意味着要将指定的插入模式添加到栈中,并从栈中弹出插入模式,这意味着必须从栈中移除最近添加的插入模式。
当以下步骤要求UA适当地重置插入模式时,这意味着UA必须按照以下步骤进行:
设last为false。
设node为开放元素栈中的最后一个节点。
循环:如果node是开放元素栈中的第 一个节点,则将last设置为true,并且如果解析器是作为HTML片段解析算法的一部分创建的(片段情况),则将node设置为传递给该算法的上下文元素。
如果node是select
元素,则运行这些子步骤:
如果node是tbody
、thead
或tfoot
元素,则将插入模式切换到"在table
body中"并返回。
如果node是frameset
元素,则将插入模式切换到"在frameset中"并返回。(片段情况)
如果node是html
元素,则运行这些子步骤:
现在将node设为开放元素栈中node之前的节点。
返回到标记为循环的步骤。
最初,打开元素栈是空的。栈向下增长;栈顶的节点是第一个添加到栈中的节点,而栈底的节点是栈中最近添加的节点(尽管在处理嵌套错误标签的过程中栈会以随机访问的方式操作)。
"html之前"的插入模式会创建html
文档元素,然后将其添加到栈中。
在片段情况下,打开元素栈初始化为包含作为该算法一部分创建的html
元素。(片段情况跳过了"html之前"插入模式。)
无论html
节点如何创建,它都是栈顶的节点。只有当解析器完成时,它才会从栈中弹出。
当前节点是这个打开元素栈中的栈底节点。
调整后的当前节点是如果解析器是作为HTML片段解析算法的一部分创建的,并且打开元素栈中只有一个元素(片段情况),那么调整后的当前节点是上下文元素;否则,调整后的当前节点就是当前节点。
当当前节点从打开元素栈中移除时,处理内部资源链接给定当前节点的节点文档。
在打开元素栈中的元素分为以下几类:
以下元素具有不同级别的特殊解析规则:HTML的address
、applet
、area
、article
、aside
、base
、basefont
、bgsound
、blockquote
、body
、br
、button
、caption
、center
、col
、colgroup
、dd
、details
、dir
、div
、dl
、dt
、embed
、fieldset
、figcaption
、figure
、footer
、form
、frame
、frameset
、h1
、h2
、h3
、h4
、h5
、h6
、head
、header
、hgroup
、hr
、html
、iframe
、img
、input
、keygen
、li
、link
、listing
、main
、marquee
、menu
、meta
、nav
、noembed
、noframes
、noscript
、object
、ol
、p
、param
、plaintext
、pre
、script
、search
、section
、select
、source
、style
、summary
、table
、tbody
、td
、template
、textarea
、tfoot
、th
、thead
、title
、tr
、track
、ul
、wbr
、xmp
;MathMLmi
、MathMLmo
、MathMLmn
、MathMLms
、MathMLmtext
和MathMLannotation-xml
;以及SVGforeignObject
、SVGdesc
和SVGtitle
。
一个image
起始标签标记由树构建器处理,但它不在此列表中,因为它不是一个元素;它被转换为一个img
元素。
以下HTML元素是那些最终出现在活动格式化元素列表中的元素:a
、b
、big
、code
、em
、font
、i
、nobr
、s
、small
、strike
、strong
、tt
和u
。
在解析HTML文档时找到的所有其他元素。
通常,特殊元素具有特定处理开始和结束标签标记的规则,而普通元素的标记则适用于“任何其他开始标签”和“任何其他结束标签”条款,并且树构建器的某些部分会检查打开元素栈中的特定元素是否属于特殊类别。然而,一些元素(例如option
元素)虽然其开始或结束标签标记被特定处理,但仍然不属于特殊类别,因此它们在其他地方仍然遵循普通处理。
打开元素栈被称为在特定范围内具有一个元素target node,当以下算法在匹配状态终止时,它包括一个元素类型list:
将node初始化为当前节点(栈底的节点)。
如果node是目标节点,则在匹配状态下终止。
否则,如果node是list中的元素类型之一,则在失败状态下终止。
否则,将node设置为打开元素栈中的上一个条目,并返回步骤2。(这永远不会失败,因为如果到达栈顶——一个html
元素——循环总会在前一步终止。)
打开元素栈被称为具有特定范围内的某个元素,当它具有该特定范围内的元素,包括以下元素类型:
applet
caption
html
table
td
th
marquee
object
template
mi
mo
mn
ms
mtext
annotation-xml
foreignObject
desc
title
打开元素栈被称为具有特定列表项范围内的某个元素,当它具有该特定范围内的元素,包括以下元素类型:
打开元素栈被称为具有特定按钮范围内的某个元素,当它具有该特定范围内的元素,包括以下元素类型:
打开元素栈被称为具有特定表格范围内的某个元素,当它具有该特定范围内的元素,包括以下元素类型:
打开元素栈被称为具有特定选择范围内的某个元素,当它具有该特定范围内的元素,包括所有元素类型除外以下:
如果在任何时候打开元素栈中的任何元素被移动到文档树中的新位置或从中移除,什么也不会发生。特别是,栈在这种情况下不会发生变化。这可能会导致,除了其他奇怪的效果之外,内容被附加到已不再存在于DOM中的节点上。
在某些情况下(即在关闭嵌套错误的格式化元素时),栈以随机访问的方式操作。
最初,活动格式化元素列表为空。该列表用于处理格式化元素标签的嵌套错误。
该列表包含格式化类别中的元素和标记。标记是在进入applet
、object
、marquee
、template
、td
、th
和caption
元素时插入的,用于防止格式化“泄漏”到这些元素中。
此外,活动格式化元素列表中的每个元素都与创建它的令牌相关联,因此如果有必要,可以为该令牌创建更多元素。
当以下步骤要求UA将元素推入活动格式化元素列表时,UA必须执行以下步骤:
如果在最后一个标记之后(如果有)或列表中(如果没有标记)已经有三个具有与element相同的标签名、命名空间和属性的元素,则删除活动格式化元素列表中最早的该类元素。为此,属性必须在元素由解析器创建时进行比较;如果它们的所有解析属性都可以配对,并且每对中的两个属性具有相同的名称、命名空间和值(属性的顺序无关紧要),则两个元素具有相同的属性。
这是诺亚方舟条款,只是每个家族是三个而不是两个。
将element添加到活动格式化元素列表中。
当以下步骤要求UA重构活动格式化元素时,UA必须执行以下步骤:
如果活动格式化元素列表中没有条目,则无内容重构;停止执行该算法。
如果活动格式化元素列表中的最后一个(最近添加的)条目是一个标记,或如果它是打开元素栈中的一个元素,则无内容重构;停止执行该算法。
令entry为活动格式化元素列表中的最后一个(最近添加的)元素。
倒带:如果活动格式化元素列表中没有在entry之前的条目,则跳到标记为创建的步骤。
将entry设置为活动格式化元素列表中entry之前的一个条目。
前进:将entry设置为活动格式化元素列表中entry之后的一个元素。
创建:插入一个HTML元素,为创建元素entry的令牌获得new element。
用new element的条目替换活动格式化元素列表中的entry条目。
如果活动格式化元素列表中new element的条目不是列表中的最后一个条目,则返回到标记为前进的步骤。
这将重新打开所有尚未显式关闭的当前正文、单元格或标题(以最年轻的为准)中打开的格式化元素。
按照本规范的编写方式,活动格式化元素列表总是按照时间顺序排列,最早添加的元素在前,最近添加的元素在后(当然,除非正在执行上述算法的第7至第10步)。
当以下步骤要求UA清除直到最后一个标记的活动格式化元素列表时,UA必须执行以下步骤:
最初,head
元素指针和form
元素指针均为null。
一旦解析了一个head
元素(无论是隐式还是显式),head
元素指针就会指向该节点。
form
元素指针指向最后一个被打开且尚未看到其结束标签的form
元素。由于历史原因,它用于在严重错误的标记情况下将表单控件与表单关联。在template
元素内被忽略。
脚本标志在创建解析器时,如果脚本已启用,则设置为“enabled”,否则设置为“disabled”。
即使在作为HTML片段解析算法的一部分创建解析器时,脚本标志也可以启用,尽管在这种情况下script
元素不会执行。
frameset-ok 标志在创建解析器时设置为“ok”。在看到某些标记后,它会被设置为“not ok”。
实现必须表现得像是使用了以下状态机来对HTML进行标记化。状态机必须从数据状态开始。大多数状态消耗单个字符,这可能会产生各种副作用,并且要么将状态机切换到一个新状态以重新消耗当前输入字符,要么将其切换到新状态以消耗下一个字符,或者保持在相同状态以消耗下一个字符。一些状态有更复杂的行为,可以在切换到另一个状态之前消耗多个字符。在某些情况下,标记化器的状态也会被树构建阶段改变。
当一个状态指示要在指定状态下重新消耗一个匹配的字符时,这意味着切换到该状态,但在尝试消耗下一个输入字符时,提供当前输入字符代替。
某些状态的确切行为取决于插入模式和开放元素堆栈。某些状态还使用temporary buffer来跟踪进度,字符引用状态使用return state返回到调用它的状态。
标记化步骤的输出是一系列零个或多个以下标记:DOCTYPE、开始标签、结束标签、注释、字符、文件结束标记。DOCTYPE标记具有名称、公共标识符、系统标识符和强制怪异模式标志。当创建DOCTYPE标记时,其名称、公共标识符和系统标识符必须标记为丢失(这与空字符串是不同的状态),并且强制怪异模式标志必须设置为关闭(另一状态为开启)。开始和结束标签标记具有标签名称、自关闭标志和一个属性列表,其中每个属性都有一个名称和一个值。当创建开始或结束标签标记时,其自关闭标志必须未设置(另一状态是设置),并且其属性列表必须为空。注释和字符标记具有数据。
当标记被发出时,必须立即由树构建阶段处理。树构建阶段可以影响标记化阶段的状态,并且可以将其他字符插入流中。(例如,script
元素可能会导致脚本执行,并使用动态标记插入API将字符插入正在标记化的流中。)
创建标记和发出标记是不同的操作。标记可能会被创建但隐式放弃(从未发出),例如如果文件在处理字符时意外结束,这些字符正被解析为一个开始标签标记。
当发出带有自关闭标志的开始标签标记时,如果在树构建阶段处理时该标志未被确认,那就是一个非空HTML元素的开始标签带有尾随斜杠的解析错误。
当发出带有属性的结束标签标记时,那就是一个带有属性的结束标签的解析错误。
当发出带有自关闭标志的结束标签标记时,那就是一个带有尾随斜杠的结束标签的解析错误。
合适的结束标签标记是指其标签名称与从此标记化器发出的最后一个开始标签的标签名称相匹配的结束标签标记(如果有的话)。如果从此标记化器发出的没有开始标签,那么就没有合适的结束标签标记。
字符引用被称为作为属性的一部分消耗,如果返回状态是属性值(双引号)状态、属性值(单引号)状态或属性值(无引号)状态。
当某个状态指示刷新作为字符引用消耗的代码点时,这意味着对于临时缓冲区中的每个代码点(按它们添加到缓冲区的顺序),用户代理必须将缓冲区中的代码点追加到当前属性的值中,如果字符引用是作为属性的一部分消耗的,否则将代码点作为字符标记发出。
在标记化器的每一步之前,用户代理必须首先检查解析器暂停标志。如果它为true,那么标记化器必须中止任何嵌套的标记化器调用的处理,将控制权交还给调用者。
标记化器状态机由以下小节中定义的状态组成。
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
script
”,则切换到脚本数据双重转义状态。否则,切换到脚本数据转义状态。将当前输入字符作为字符令牌发出。消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
script
”,则切换到脚本数据转义状态。否则,切换到脚本数据双重转义状态。将当前输入字符作为字符令牌发出。消耗下一个输入字符:
消耗下一个输入字符:
当用户代理离开属性名称状态(如果合适,在发出标签令牌之前),必须将完整的属性名称与同一令牌上的其他属性进行比较;如果令牌上已经有一个具有完全相同名称的属性,那么这就是一个重复属性 解析错误,并且必须从令牌中删除新属性。
如果属性以这种方式从令牌中删除,则解析器不会在后续使用它及其关联的值(如果有的话),因此它们实际上被丢弃。然而,这种方式删除属性并不会改变它作为“当前属性”的状态,针对标记化器来说。
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗 下一个输入字符:
如果接下来的几个字符是:
消耗 下一个输入字符:
消耗下一个输入字符:
消费 下一个输入字符:
消费 下一个输入字符:
消费 下一个输入字符:
消费 下一个输入字符:
消费 下一个输入字符:
消费 下一个输入字符:
消费 下一个输入字符:
消费 下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
如果从当前输入字符开始的六个字符是 ASCII 不区分大小写匹配单词 "PUBLIC",则消耗这些字符 并切换到DOCTYPE 公共关键字之后状态。
否则,如果从当前输入字符开始的六个字符是 ASCII 不区分大小写匹配单词 "SYSTEM",则消耗这些 字符并切换到DOCTYPE 系统关键字之后状态。
否则,这是一个DOCTYPE 名称之后的无效字符序列 解析 错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 开。重新消费进入伪 DOCTYPE 状态。
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
U+0000 NULL 字符在树构建阶段处理,作为 在外来内容中插入模式的一部分,这是 CDATA 段可以出现的唯一位置。
消耗下一个输入字符:
消耗下一个输入字符:
将临时缓冲区设置为空字符串。将 U+0026 AMPERSAND (&) 字符附加到 临时缓冲区中。消耗下一个输入字符:
消耗尽可能多的字符,这些消耗的字符是命名字符引用表第一列中的标识符之一。每次消耗时,将字符附加到临时缓冲区中。
如果字符引用是作为属性的一部分消耗的,并且最后一个匹配的字符不是 U+003B 分号字符 (;),并且下一个输入字符是 U+003D 等号字符 (=) 或ASCII 字母数字,那么出于历史原因,刷新作为字符引用消耗的代码点并切换到返回状态。
否则:
如果最后一个匹配的字符不是 U+003B 分号字符 (;),那么这是一个缺少字符引用之后的分号 解析错误。
将临时缓冲区设置为空字符串。将一个或两个与字符引用名称(如命名字符引用表第二列所示的字符引用名称相对应的字符附加到临时缓冲区中。
如果标记(不在属性中)包含字符串I'm ¬it; I
tell you
,字符引用将解析为"not",如I'm ¬it;
I tell you
(这是解析错误)。但如果标记为I'm
∉ I tell you
,字符引用将解析为"notin;",结果为I'm ∉ I tell you
(没有解析错误)。
然而,如果标记在属性中包含字符串I'm ¬it; I tell you
,则不会解析字符引用,字符串保持不变(且无解析错误)。
消耗下一个输入字符:
将 字符引用代码 设置为 0。
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
消耗下一个输入字符:
检查 字符引用代码:
如果该数字大于 0x10FFFF,那么这是一个超出 Unicode 范围的字符引用 解析错误。将 字符引用代码 设置为 0xFFFD。
如果该数字是 0x0D,或者是一个控制字符,但不是ASCII 空白字符,那么这是一个控制字符引用 解析错误。如果该数字是下表第一列中的数字,则找到该数字在第一列中的行,并将 字符引用代码 设置为该行第二列中的数字。
数字 | 代码点 | |
---|---|---|
0x80 | 0x20AC | 欧元符号 (€) |
0x82 | 0x201A | 单低 9 引号 (‚) |
0x83 | 0x0192 | 拉丁文小写字母 F 带钩 (ƒ) |
0x84 | 0x201E | 双低 9 引号 („) |
0x85 | 0x2026 | 省略号 (…) |
0x86 | 0x2020 | 匕首 (†) |
0x87 | 0x2021 | 双匕首 (‡) |
0x88 | 0x02C6 | 变音符号 (ˆ) |
0x89 | 0x2030 | 每千符号 (‰) |
0x8A | 0x0160 | 拉丁文大写字母 S 带抑扬符 (Š) |
0x8B | 0x2039 | 单左引号 (‹) |
0x8C | 0x0152 | 拉丁文大写连字 OE (Œ) |
0x8E | 0x017D | 拉丁文大写字母 Z 带抑扬符 (Ž) |
0x91 | 0x2018 | 左单引号 (‘) |
0x92 | 0x2019 | 右单引号 (’) |
0x93 | 0x201C | 左双引号 (“) |
0x94 | 0x201D | 右双引号 (”) |
0x95 | 0x2022 | 项目符号 (•) |
0x96 | 0x2013 | 短破折号 (–) |
0x97 | 0x2014 | 长破折号 (—) |
0x98 | 0x02DC | 小波浪号 (˜) |
0x99 | 0x2122 | 商标符号 (™) |
0x9A | 0x0161 | 拉丁文小写字母 S 带抑扬符 (š) |
0x9B | 0x203A | 单右引号 (›) |
0x9C | 0x0153 | 拉丁文小写连字 OE (œ) |
0x9E | 0x017E | 拉丁文小写字母 Z 带抑扬符 (ž) |
0x9F | 0x0178 | 拉丁文大写字母 Y 带分音符 (Ÿ) |
将 临时缓冲区设置为空字符串。将一个等于字符引用代码的代码点附加到临时缓冲区中。刷新作为字符引用消耗的代码点。切换到返回状态。
树构建阶段的输入是一系列来自标记化阶段的标记。当解析器创建时,树构建阶段与 DOM
文档
对象关联。该阶段的“输出”包括动态修改或扩展该文档的
DOM 树。
本规范未定义交互式用户代理何时必须呈现
文档
以便用户可以使用,或何时必须开始接受用户输入。
当每个标记从标记器发出时,用户代理必须遵循以下列表中的适当步骤,该列表称为 树构建分发器:
annotation-xml
元素,且标记是标签名为“svg”的起始标记下一个标记是即将由树构建分发器处理的标记(即使标记随后只是被忽略)。
如果节点是以下元素之一,则该节点是MathML 文本集成点:
mi
元素mo
元素mn
元素ms
元素mtext
元素如果节点是以下元素之一,则该节点是HTML 集成点:
annotation-xml
元素,其起始标记具有一个名为“encoding”的属性,该属性的值与字符串“text/html
”进行ASCII 不区分大小写匹配annotation-xml
元素,其起始标记具有一个名为“encoding”的属性,该属性的值与字符串“application/xhtml+xml
”进行ASCII 不区分大小写匹配foreignObject
元素desc
元素title
元素如果问题中的节点是上下文元素传递到HTML 片段解析算法,则该元素的起始标记是该HTML 片段解析算法期间创建的“伪造”标记。
以下提到的所有标签名称并非本规范中的合规标签名称;许多标签名被包括在内是为了处理遗留内容。它们仍然构成实现要求遵循的算法的一部分,以声称符合规范。
下面描述的算法对生成的 DOM 树的深度、标签名称、属性名称、属性值、文本
节点等的长度没有限制。虽然鼓励实现者避免任意限制,但也认识到实际问题可能会迫使用户代理施加嵌套深度约束。
当解析器正在处理标记时,它可以启用或禁用寄养父母。这会影响以下算法。
使用特定覆盖目标(可选)插入节点的适当位置是运行以下步骤返回的元素中的位置:
如果指定了覆盖目标,则将target设为覆盖目标。
否则,将target设为当前节点。
使用以下列表中第一个匹配步骤确定adjusted insertion location:
table
、tbody
、tfoot
、thead
或tr
元素
当内容在表格中嵌套错误时,会发生寄养父母。
运行以下子步骤:
如果有last template且没有last table,或者有last table,但在打开元素栈中last template低于(最近添加)last table,则将adjusted insertion location设为last template的template 内容的最后一个子元素(如果有)之后,并中止这些步骤。
如果没有last table,则将adjusted insertion location设为打开元素栈中的第一个元素(html
元素)内的最后一个子元素之后,并中止这些步骤。(片段情况)
如果last table有一个父节点,则将adjusted insertion location设为last table的父节点内,紧接在last table之前,并中止这些步骤。
将previous element设为打开元素栈中紧挨last table上方的元素。
将adjusted insertion location设为previous element内的最后一个子元素之后。
这些步骤部分是因为元素(特别是table
元素)可能已被脚本在
DOM 中移动,或者在元素被解析器插入后,已完全从 DOM 中删除。
将adjusted insertion location设为target内的最后一个子元素之后。
如果adjusted insertion location在template
元素内,则将其改为template
元素的template
内容中的最后一个子元素之后。
返回adjusted insertion location。
当以下步骤要求 UA 为特定given namespace和特定intended parent中的标记创建一个元素时,UA 必须运行以下步骤:
如果活动推测性 HTML 解析器不为空,则返回创建推测性模拟元素的结果,给定given namespace、标记的标签名称和标记的属性。
否则,选择性地创建推测性模拟元素,给定given namespace、标记的标签名称和标记的属性。
结果不被使用。此步骤允许从非推测性解析中启动推测性获取。在此时获取仍然是推测性的,因为,例如,在元素插入时,intended parent可能已经从文档中移除。
将document设为intended parent的节点文档。
将local name设为标记的标签名称。
如果该标记存在"is
"属性,将is设为该属性的值,否则为
null。
将definition设为查找自定义元素定义的结果,给定document、given namespace、local name和is。
如果definition不为空且解析器不是作为HTML 片段解析算法的一部分创建的,则设will execute script为 true。否则,设为 false。
如果will execute script为 true,则:
将element设为创建元素的结果,给定document、localName、given namespace、null 和is。如果will execute script为 true,则设置synchronous custom elements flag;否则,保持未设置。
这将导致运行自定义元素构造函数,如果will execute script为 true。然而,由于我们递增了动态标记插入计数器,这不会导致新字符插入到标记化器,或文档被摧毁。
追加给定标记中的每个属性到element。
这可以排队自定义元素回调反应以触发attributeChangedCallback
,可能会立即运行(在下一步中)。
虽然is
属性决定了创建自定义内置元素,但它在相关的自定义元素构造函数执行期间不可见;它与所有其他属性一起在此步骤中追加。
如果will execute script为 true,则:
如果element具有xmlns
属性在XMLNS
命名空间中,其值与元素的命名空间不完全相同,则这是一个解析错误。类似地,如果element具有xmlns:xlink
属性在XMLNS
命名空间中,其值与XLink
命名空间不相符,则这是一个解析错误。
如果element是与表单相关的元素,而不是与表单相关的自定义元素,且form
元素指针不为 null,打开元素堆栈上没有template
元素,element既不列出,也没有form
属性,并且intended
parent与form
元素指针指向的元素位于同一树中,那么将element与该form
元素关联,并设置element的解析器插入标志。
返回element。
为了用元素element在调整后的插入位置插入一个元素:
将adjusted insertion location设为适当的插入节点位置。
如果无法在adjusted insertion location插入element,则中止这些步骤。
如果解析器不是作为HTML 片段解析算法的一部分创建的,则将一个新的元素队列推入element的相关代理的自定义元素反应栈。
在adjusted insertion location插入element。
如果解析器不是作为HTML 片段解析算法的一部分创建的,则从element的相关代理的自定义元素反应栈中弹出元素队列,并调用该队列中的自定义元素反应。
如果adjusted insertion location无法接受更多元素,例如,因为它是文档
,它已经有了一个元素子节点,则element将被丢弃。
当以下步骤要求用户代理为给定命名空间中的标记并使用布尔onlyAddToElementStack插入外来元素时,用户代理必须执行以下步骤:
将adjusted insertion location设为适当的插入节点位置。
将element设为为标记创建元素的结果,在给定的命名空间中,预定父节点为adjusted insertion location所在的元素。
如果onlyAddToElementStack为 false,则使用element运行在调整后的插入位置插入元素。
返回element。
当以下步骤要求用户代理为标记插入 HTML 元素时,用户代理必须插入外来元素,使用HTML 命名空间和 false。
当以下步骤要求用户代理为标记调整 MathML
属性时,如果标记有名为definitionurl
的属性,则将其名称更改为definitionURL
(注意大小写差异)。
当以下步骤要求用户代理为标记调整 SVG 属性时,对于标记上每个属性,其属性名称是以下表第一列中的之一,则将属性的名称更改为对应的第二列中的名称。(这修复了 SVG 属性不是全小写的问题。)
令牌上的属性名称 | 元素上的属性名称 |
---|---|
attributename |
attributeName
|
attributetype |
attributeType
|
basefrequency |
baseFrequency
|
baseprofile |
baseProfile
|
calcmode |
calcMode
|
clippathunits |
clipPathUnits
|
diffuseconstant |
diffuseConstant
|
edgemode |
edgeMode
|
filterunits |
filterUnits
|
glyphref |
glyphRef
|
gradienttransform |
gradientTransform
|
gradientunits |
gradientUnits
|
kernelmatrix |
kernelMatrix
|
kernelunitlength |
kernelUnitLength
|
keypoints |
keyPoints
|
keysplines |
keySplines
|
keytimes |
keyTimes
|
lengthadjust |
lengthAdjust
|
limitingconeangle |
limitingConeAngle
|
markerheight |
markerHeight
|
markerunits |
markerUnits
|
markerwidth |
markerWidth
|
maskcontentunits |
maskContentUnits
|
maskunits |
maskUnits
|
numoctaves |
numOctaves
|
pathlength |
pathLength
|
patterncontentunits |
patternContentUnits
|
patterntransform |
patternTransform
|
patternunits |
patternUnits
|
pointsatx |
pointsAtX
|
pointsaty |
pointsAtY
|
pointsatz |
pointsAtZ
|
preservealpha |
preserveAlpha
|
preserveaspectratio |
preserveAspectRatio
|
primitiveunits |
primitiveUnits
|
refx |
refX
|
refy |
refY
|
repeatcount |
repeatCount
|
repeatdur |
repeatDur
|
requiredextensions |
requiredExtensions
|
requiredfeatures |
requiredFeatures
|
specularconstant |
specularConstant
|
specularexponent |
specularExponent
|
spreadmethod |
spreadMethod
|
startoffset |
startOffset
|
stddeviation |
stdDeviation
|
stitchtiles |
stitchTiles
|
surfacescale |
surfaceScale
|
systemlanguage |
systemLanguage
|
tablevalues |
tableValues
|
targetx |
targetX
|
targety |
targetY
|
textlength |
textLength
|
viewbox |
viewBox
|
viewtarget |
viewTarget
|
xchannelselector |
xChannelSelector
|
ychannelselector |
yChannelSelector
|
zoomandpan |
zoomAndPan
|
当以下步骤要求用户代理为令牌调整外部属性时,如果令牌上的任何属性与下表第一列中的字符串匹配,则将该属性设为命名空间属性,前缀为相应单元格中的字符串,本地名称为相应单元格中的字符串,命名空间为相应单元格中的命名空间。(这修复了命名空间属性的使用,特别是lang
属性在XML
命名空间中的使用问题。)
属性名称 | 前缀 | 本地名称 | 命名空间 |
---|---|---|---|
xlink:actuate |
xlink |
actuate |
XLink 命名空间 |
xlink:arcrole |
xlink |
arcrole |
XLink 命名空间 |
xlink:href |
xlink |
href |
XLink 命名空间 |
xlink:role |
xlink |
role |
XLink 命名空间 |
xlink:show |
xlink |
show |
XLink 命名空间 |
xlink:title |
xlink |
title |
XLink 命名空间 |
xlink:type |
xlink |
type |
XLink 命名空间 |
xml:lang |
xml |
lang |
XML 命名空间 |
xml:space |
xml |
space |
XML 命名空间 |
xmlns |
(无) | xmlns |
XMLNS 命名空间 |
xmlns:xlink |
xmlns |
xlink |
XMLNS 命名空间 |
当以下步骤要求用户代理在处理令牌时插入一个字符时,用户代理必须运行以下步骤:
让data为传递给算法的字符,或者,如果没有明确指定字符,则为正在处理的字符令牌的字符。
让adjusted insertion location为插入节点的适当位置。
如果adjusted insertion location位于Document
节点中,则返回。
如果在adjusted insertion
location之前立即有一个Text
节点,则将data附加到该Text
节点的data。
否则,创建一个新的Text
节点,其data为
data,其节点文档
与adjusted insertion location所在的元素的节点文档相同,并将新创建的节点插入到adjusted insertion location中。
以下是解析器的一些示例输入及其对应的Text
节点数量,假设用户代理执行脚本。
输入 | Text
节点数量
|
---|---|
|
文档中有一个Text
节点,包含"AB"。
|
|
三个Text
节点;脚本前的"A"、脚本内容以及脚本后的"BC"(解析器会附加到由脚本创建的
Text
节点)。
|
|
文档中有两个相邻的Text
节点,包含"A"和"BC"。
|
|
表格之前有一个Text
节点,包含"ABCD"。(这是由寄养父母引起的。)
|
|
表格之前有一个Text
节点,包含"A B C" (A-空格-B-空格-C)。(这是由寄养父母引起的。)
|
|
表格之前有一个Text
节点,包含"A BC" (A-空格-B-C),表格内有一个Text
节点(作为
tbody
的子节点),包含单个空格字符。(由非字符标记将空格字符与非空格字符分隔开,即使这些其他标记随后被忽略,也不会受到寄养父母的影响。)
|
当以下步骤要求用户代理在处理注释令牌时插入一个注释时,可以选择使用显式插入位置position,用户代理必须运行以下步骤:
让data为正在处理的注释令牌中的数据。
如果指定了position,则让adjusted insertion location为position。否则,让adjusted insertion location为插入节点的适当位置。
创建一个Comment
节点,其data
属性设置为
data,其节点文档
与adjusted insertion location所在节点的文档相同。
将新创建的节点插入到adjusted insertion location中。
通用原始文本元素解析算法和 通用 RCDATA 元素 解析算法包括以下步骤。这些算法总是在响应开始标签令牌时被调用。
如果调用的算法是通用原始文本 元素解析 算法,则将标记化器切换到RAWTEXT 状态;否则,调用的算法是通用 RCDATA 元素 解析算法,将标记化器切换到 RCDATA 状态。
当以下步骤要求 UA 生成隐含结束标签时,如果当前节点是 dd
元素、dt
元素、li
元素、optgroup
元素、option
元素、p
元素、rb
元素、rp
元素、rt
元素或 rtc
元素,UA 必须从当前节点中将其弹出打开元素的堆栈。
如果某个步骤要求 UA 生成隐含结束标签但列出了要从该过程排除的元素,则 UA 必须执行上述步骤,仿佛该元素不在上述列表中。
当以下步骤要求 UA 彻底生成所有隐含结束标签时,如果当前节点是 caption
元素、colgroup
元素、dd
元素、dt
元素、li
元素、optgroup
元素、option
元素、p
元素、rb
元素、rp
元素、rt
元素、rtc
元素、tbody
元素、td
元素、tfoot
元素、th
元素、thead
元素或 tr
元素,UA 必须从当前节点中将其弹出打开元素的堆栈。
Document
对象有一个关联的解析器不能改变模式标志(布尔值)。最初为 false。
当用户代理应用 "initial" 插入 模式 的规则时,用户代理必须按如下方式处理该令牌:
忽略该令牌。
如果 DOCTYPE 令牌的名称不是 "html
",或者令牌的公共标识符不存在,或者令牌的系统标识符既不存在也不是 "about:legacy-compat
",
那么会发生解析错误。
将一个 DocumentType
节点附加到 Document
节点上,其 名称 设置为
DOCTYPE 令牌中给定的名称,或者如果名称不存在,则设置为空字符串;其 公共
ID 设置为 DOCTYPE 令牌中给定的公共标识符,或者如果公共标识符不存在,则设置为空字符串;其 系统
ID 设置为 DOCTYPE 令牌中给定的系统标识符,或者如果系统标识符不存在,则设置为空字符串。
这也确保 DocumentType
节点作为
doctype
属性的值返回给
Document
对象。
然后,如果文档不是 一个 iframe
srcdoc
文档,并且 解析器不能
改变模式标志 为 false,并且 DOCTYPE 令牌符合以下列表中的条件之一,那么将 Document
设置为 quirks
模式:
html
"。 -//W3O//DTD W3 HTML Strict 3.0//EN//
" -/W3C/DTD HTML 4.0 Transitional/EN
" HTML
" http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd
"
+//Silmaril//dtd html Pro v0r11 19970101//
" 开头 -//AS//DTD HTML 3.0 asWedit + extensions//
" 开头 -//AdvaSoft Ltd//DTD HTML 3.0 asWedit + extensions//
" 开头 -//IETF//DTD HTML 2.0 Level 1//
" 开头 -//IETF//DTD HTML 2.0 Level 2//
" 开头 -//IETF//DTD HTML 2.0 Strict Level 1//
" 开头 -//IETF//DTD HTML 2.0 Strict Level 2//
" 开头 -//IETF//DTD HTML 2.0 Strict//
" 开头 -//IETF//DTD HTML 2.0//
" 开头 -//IETF//DTD HTML 2.1E//
" 开头 -//IETF//DTD HTML 3.0//
" 开头 -//IETF//DTD HTML 3.2 Final//
" 开头 -//IETF//DTD HTML 3.2//
" 开头 -//IETF//DTD HTML 3//
" 开头 -//IETF//DTD HTML Level 0//
" 开头 -//IETF//DTD HTML Level 1//
" 开头 -//IETF//DTD HTML Level 2//
" 开头 -//IETF//DTD HTML Level 3//
" 开头 -//IETF//DTD HTML Strict Level 0//
" 开头 -//IETF//DTD HTML Strict Level 1//
" 开头 -//IETF//DTD HTML Strict Level 2//
" 开头 -//IETF//DTD HTML Strict Level 3//
" 开头 -//IETF//DTD HTML Strict//
" 开头 -//IETF//DTD HTML//
" 开头 -//Metrius//DTD Metrius Presentational//
" 开头 -//Microsoft//DTD Internet Explorer 2.0 HTML Strict//
" 开头 -//Microsoft//DTD Internet Explorer 2.0 HTML//
" 开头 -//Microsoft//DTD Internet Explorer 2.0 Tables//
" 开头 -//Microsoft//DTD Internet Explorer 3.0 HTML Strict//
" 开头 -//Microsoft//DTD Internet Explorer 3.0 HTML//
" 开头 -//Microsoft//DTD Internet Explorer 3.0 Tables//
" 开头 -//Netscape Comm. Corp.//DTD HTML//
" 开头 -//Netscape Comm. Corp.//DTD Strict HTML//
" 开头 -//O'Reilly and Associates//DTD HTML 2.0//
" 开头 -//O'Reilly and Associates//DTD HTML Extended 1.0//
" 开头 -//O'Reilly and Associates//DTD HTML Extended Relaxed 1.0//
" 开头 -//SQ//DTD HTML 2.0 HoTMetaL + extensions//
" 开头 -//SoftQuad Software//DTD HoTMetaL PRO 6.0::19990601::extensions to HTML 4.0//
" 开头
-//SoftQuad//DTD HoTMetaL PRO 4.0::19971010::extensions to HTML 4.0//
" 开头 -//Spyglass//DTD HTML 2.0 Extended//
" 开头 -//Sun Microsystems Corp.//DTD HotJava HTML//
" 开头 -//Sun Microsystems Corp.//DTD HotJava Strict HTML//
" 开头 -//W3C//DTD HTML 3 1995-03-24//
" 开头 -//W3C//DTD HTML 3.2 Draft//
" 开头 -//W3C//DTD HTML 3.2 Final//
" 开头 -//W3C//DTD HTML 3.2//
" 开头 -//W3C//DTD HTML 3.2S Draft//
" 开头 -//W3C//DTD HTML 4.0 Frameset//
" 开头 -//W3C//DTD HTML 4.0 Transitional//
" 开头 -//W3C//DTD HTML Experimental 19960712//
" 开头 -//W3C//DTD HTML Experimental 970421//
" 开头 -//W3C//DTD W3 HTML//
" 开头 -//W3O//DTD W3 HTML 3.0//
" 开头 -//WebTechs//DTD Mozilla HTML 2.0//
" 开头 -//WebTechs//DTD Mozilla HTML//
" 开头 -//W3C//DTD HTML 4.01 Frameset//
" 开头 -//W3C//DTD HTML 4.01 Transitional//
" 开头 否则,如果文档不是 一个 iframe
srcdoc
文档,并且 解析器不能改变
模式标志 为 false,并且 DOCTYPE 令牌符合以下列表中的条件之一,那么将 Document
设置为 有限的
quirks 模式:
-//W3C//DTD XHTML 1.0 Frameset//
" 开头 -//W3C//DTD XHTML 1.0 Transitional//
" 开头 -//W3C//DTD HTML 4.01 Frameset//
" 开头 -//W3C//DTD HTML 4.01 Transitional//
" 开头 系统标识符和公共标识符字符串必须以ASCII 大小写不敏感的方式与上面列表中给定的值进行比较。对于上述条件,值为空字符串的系统标识符不被视为不存在。
然后,将 插入模式 切换为 "before html"。
如果文档不是 一个 iframe
srcdoc
文档,那么这是一个 解析
错误;如果 解析器不能改变模式标志
为 false,则将
Document
设置为 quirks
模式。
无论如何,将 插入模式 切换为 "before html",然后重新处理该令牌。
当用户代理应用 "before html" 插入 模式 的规则时,用户代理必须按如下方式处理该令牌:
解析 错误。忽略该令牌。
忽略该令牌。
为令牌创建一个元素
在
HTML
命名空间中,以 Document
作为预期父节点。将其附加到 Document
对象中。将
此元素放入 打开元素的堆栈中。
将 插入模式 切换为 "before head"。
按照以下 "其他任何情况" 条目中描述的方式操作。
解析 错误。忽略该令牌。
创建一个 html
元素,其 节点文档
是 Document
对象。将其附加到 Document
对象中。将此元素放入 打开元素的堆栈中。
将 插入模式 切换为 "before head",然后重新处理该令牌。
文档元素
可能会从 Document
对象中移除,例如通过脚本;在这种情况下,不会发生任何特殊情况,内容将继续按照下一节所述附加到节点中。
当用户代理应用 "before head" 插入 模式 的规则时,用户代理必须按如下方式处理该令牌:
忽略该令牌。
解析 错误。忽略该令牌。
按照以下 "其他任何情况" 条目中描述的方式操作。
解析 错误。忽略该令牌。
为没有属性的 "head" 开始标签令牌插入一个 HTML 元素。
重新处理当前令牌。
当用户代理应用 "in head" 插入模式 的规则时,用户代理必须按如下方式处理该令牌:
解析错误。忽略该令牌。
为该令牌插入一个 HTML 元素。立即将 当前节点 从 打开元素的堆栈 中弹出。
确认该令牌的 自闭合标志,如果已设置。
为该令牌插入一个 HTML 元素。立即将 当前节点 从 打开元素的堆栈 中弹出。
确认该令牌的 自闭合标志,如果已设置。
如果 活动推测性 HTML 解析器 为 null,则:
如果该元素具有 charset
属性,并且从其值中获取编码
的操作得到一个 编码,并且 置信度 目前为 暂定,则 将编码更改为所得的编码。
否则,如果该元素具有 http-equiv
属性,且其值与字符串 "Content-Type
"
匹配(不区分大小写),并且该元素具有 content
属性,并且将 从
meta
元素提取字符编码的算法 应用于该属性的值,返回一个
编码,并且 置信度 目前为 暂定,则 将编码更改为提取的编码。
为了简化实现,推测性 HTML 解析器 不会推测性地应用字符编码声明。
遵循 通用 RCDATA 元素解析算法。
遵循 通用原始文本元素解析算法。
将 插入模式 切换为 "in head noscript"。
执行以下步骤:
将 adjusted insertion location 设为 适当的节点插入位置。
为该令牌创建一个元素 在 HTML 命名空间 中,并且目标父节点为 adjusted insertion location 中的元素。
将元素的 解析器文档
设置为 Document
,并将元素的 强制异步
设置为
false。
这可以确保,如果脚本是外部脚本,则脚本中的任何 document.write()
调用将会在行内执行,而不是像在大多数其他情况下那样将文档抹掉。它还可以防止脚本在看到结束标签之前执行。
如果解析器是作为 HTML 片段解析算法 的一部分创建的,则将 script
元素的 已经开始 设置为
true。
(片段情况)
如果解析器是通过 document.write()
或 document.writeln()
方法调用的,那么可以选择将 script
元素的 已经开始
设置为
true。(例如,用户代理可能会使用此条款来防止在网络条件较慢或页面加载时间较长的情况下,通过 document.write()
插入的跨域脚本的执行。)
在 adjusted insertion location 插入新创建的元素。
将分词器切换到 脚本数据状态。
将 当前节点(将是 head
元素)从 打开元素的堆栈 中弹出。
将 插入模式 切换为 "after head"。
按照以下 "其他任何情况" 条目中描述的方式操作。
将 template start tag 设为开始标签。
将 frameset-ok 标志 设置为 "不行"。
将 插入模式 切换为 "in template"。
将 "in template" 推入 模板插入模式堆栈 中,使其成为新的 当前模板插入模式。
将 adjusted insertion location 设为 适当的节点插入位置。
将 intended parent 设为 adjusted insertion location 中的元素。
将 document 设为 intended parent 的 节点文档。
如果以下任何一项为 false:
shadowrootmode
不处于 无
状态;否则:
让 declarative shadow host element 为 调整后的当前节点。
让 mode 为 template start tag 的 shadowrootmode
属性的值。
如果 template start tag 有 shadowrootclonable
属性,则让 clonable 为 true;否则为 false。
如果 template start tag 有 shadowrootserializable
属性,则让 serializable 为 true;否则为 false。
如果 template start tag 有 shadowrootdelegatesfocus
属性,则让 delegatesFocus 为 true;否则为 false。
如果 declarative shadow host element 是 Shadow 主机, 则使用 template 在调整后的插入位置插入一个元素。
否则:
附加一个
Shadow 根节点,使用
declarative shadow host element、mode、clonable、
serializable、delegatesFocus,以及 "named
"。
如果抛出异常,则捕获异常并:
在调整后的插入位置插入一个元素,使用 template。
用户代理可能会向开发者控制台报告错误。
返回。
让 shadow 为 declarative shadow host element 的 Shadow 根节点。
将 shadow 的 声明性 设置为 true。
将 shadow 的 可用于元素内部 设置为 true。
如果 打开元素的堆栈 中没有
template
元素,则这是一个 解析错误;忽略该令牌。
否则,执行以下步骤:
解析错误。忽略该令牌。
将 当前节点(将是 head
元素)从 打开元素的堆栈 中弹出。
重新处理该令牌。
当用户代理要应用“in head noscript”插入模式的规则时,用户代理必须按以下方式处理令牌:
解析错误。忽略该令牌。
按以下“其他情况”条目中的描述操作。
解析错误。忽略该令牌。
解析错误。
将当前节点(即noscript
元素)从打开元素的堆栈中弹出;新当前节点将是head
元素。
重新处理该令牌。
当用户代理要应用“after head”插入模式的规则时,用户代理必须按以下方式处理令牌:
插入字符。
插入注释。
解析错误。忽略该令牌。
插入HTML元素来处理该令牌。
将frameset-ok标志设置为“not ok”。
插入HTML元素来处理该令牌。
将插入模式切换为“in frameset”。
解析错误。
将head
元素指针指向的节点从打开元素的堆栈中移除。(此时它可能不是当前节点。)
head
元素指针此时不能为null。
按以下“其他情况”条目中的描述操作。
解析错误。忽略该令牌。
插入HTML元素来处理一个不带属性的“body”开始标签令牌。
重新处理当前令牌。
当用户代理要应用“in body”插入模式的规则时,用户代理必须按以下方式处理令牌:
解析错误。忽略该令牌。
重建活动格式化元素(如果有)。
重建活动格式化元素(如果有)。
将frameset-ok标志设置为“not ok”。
插入注释。
解析错误。忽略该令牌。
解析错误。
如果打开元素的堆栈中存在template
元素,则忽略该令牌。
否则,对于令牌上的每个属性,检查该属性是否已存在于打开元素的堆栈的顶部元素上。如果没有,则将该属性及其对应的值添加到该元素。
解析错误。
如果打开元素的堆栈上只有一个节点,如果打开元素的堆栈上的第二个元素不是body
元素,或者如果打开元素的堆栈中存在template
元素,则忽略该令牌。(片段情况或在堆栈中存在template
元素)
否则,将frameset-ok标志设置为“not
ok”;然后对于令牌上的每个属性,检查该属性是否已存在于打开元素的堆栈上的body
元素(第二个元素)上,如果没有,则将该属性及其对应的值添加到该元素。
解析错误。
如果打开元素的堆栈上只有一个节点,或者打开元素的堆栈上的第二个元素不是body
元素,则忽略该令牌。(片段情况或在堆栈中存在template
元素)
如果frameset-ok标志设置为“not ok”,则忽略该令牌。
否则,运行以下步骤:
如果模板插入模式的堆栈不为空,则使用“in template”插入模式的规则处理该令牌。
否则,按照以下步骤操作:
如果打开元素的堆栈中没有处于作用域内的body
元素,则这是一个解析错误;忽略该令牌。
否则,如果打开元素的堆栈中存在非dd
元素、dt
元素、li
元素、optgroup
元素、option
元素、p
元素、rb
元素、rp
元素、rt
元素、rtc
元素、tbody
元素、td
元素、tfoot
元素、th
元素、thead
元素、tr
元素、body
元素或html
元素的节点,则这是一个解析错误。
将插入模式切换为“after body”。
如果打开元素的堆栈中没有处于作用域内的body
元素,则这是一个解析错误;忽略该令牌。
否则,如果打开元素的堆栈中存在非dd
元素、dt
元素、li
元素、optgroup
元素、option
元素、p
元素、rb
元素、rp
元素、rt
元素、rtc
元素、tbody
元素、td
元素、tfoot
元素、th
元素、thead
元素、tr
元素、body
元素或html
元素的节点,则这是一个解析错误。
将插入模式切换为“after body”。
重新处理该令牌。
插入HTML元素来处理该令牌。
如果当前节点是标签名为“h1”、“h2”、“h3”、“h4”、“h5”或“h6”的HTML元素,则这是一个解析错误;从打开元素的堆栈中弹出当前节点。
插入HTML元素来处理该令牌。
插入HTML元素来处理该令牌。
如果下一个令牌是U+000A换行符(LF)字符令牌,则忽略该令牌并继续处理下一个令牌。(pre
块开头的换行符作为一种方便的编写方式被忽略。)
将frameset-ok标志设置为“not ok”。
如果form
元素指针不为null,且打开元素的堆栈中没有template
元素,则这是一个解析错误;忽略该令牌。
否则:
运行以下步骤:
运行以下步骤:
将frameset-ok标志设置为“not ok”。
初始化node为当前节点(堆栈的最底部节点)。
循环:如果node是dd
元素,则运行以下子步骤:
如果node是dt
元素,则运行以下子步骤:
否则,将node设置为打开元素的堆栈中的前一个条目,并返回到标记为循环的步骤。
完成:如果打开元素的堆栈在按钮作用域内有p
元素,则关闭p
元素。
最后,插入HTML元素来处理该令牌。
插入HTML元素来处理该令牌。
将标记器切换到PLAINTEXT状态。
一旦看到标签名为 "plaintext" 的开始标签,所有剩余的标记都将是字符标记(以及最终的文件结束标记),因为没有办法将标记器切换出PLAINTEXT状态。然而,由于树构建器保持其现有的插入模式,它可能会在处理这些字符标记时重建活动格式化元素。这意味着解析器可以将其他元素插入到plaintext
元素中。
如果打开元素的堆栈在作用域内有button
元素,则运行以下子步骤:
重建活动格式化元素(如果有)。
插入HTML元素来处理该令牌。
将frameset-ok标志设置为“not ok”。
如果 打开元素的堆栈中没有在作用域内的具有相同标签名的HTML元素,则这是一个解析错误;忽略该令牌。
否则,运行以下步骤:
如果打开元素的堆栈中没有在按钮作用域内的p
元素,则这是一个解析错误;插入一个无属性的“p”开始标签令牌对应的HTML元素。
如果打开元素的堆栈中没有在列表项作用域内的li
元素,则这是一个解析错误;忽略该令牌。
否则,运行以下步骤:
如果打开元素的堆栈中没有在作用域内的具有相同标签名的HTML元素,则这是一个解析错误;忽略该令牌。
否则,运行以下步骤:
如果打开元素的堆栈中没有在作用域内的HTML元素且其标签名为“h1”、“h2”、“h3”、“h4”、“h5”或“h6”中的一个,则这是一个解析错误;忽略该令牌。
否则,运行以下步骤:
深吸一口气,然后按照下面“任何其他结束标签”条目中的描述进行操作。
如果活动格式化元素列表包含一个a
元素,该元素位于列表的末尾和最后一个标记之间(如果列表中没有标记,则位于列表的开头),则这是一个解析错误;为该令牌运行收养机构算法,然后从活动格式化元素列表和打开元素的堆栈中移除该元素(如果收养机构算法尚未移除它(如果该元素不在表格作用域内,可能不会移除))。
在不符合标准的流<a href="a">a<table><a href="b">b</table>x
中,第一个a
元素将在看到第二个时关闭,并且“x”字符将在指向“b”的链接中,而不是指向“a”。尽管外部的a
元素不在表格作用域内(这意味着在表格开始时的常规</a>
结束标签不会关闭外部的a
元素)。结果是两个a
元素间接嵌套在彼此内部——当解析不符合标准的标记时,通常会导致不符合标准的DOM。
重建活动格式化元素,如果有的话。
重建活动格式化元素,如果有的话。
重建活动格式化元素,如果有的话。
如果打开元素的堆栈中具有在作用域内的nobr
元素,则这是一个解析错误;为该令牌运行收养机构算法,然后再次重建活动格式化元素,如果有的话。
为该令牌运行收养机构算法。
重建活动格式化元素,如果有的话。
将frameset-ok 标志设置为“not ok”。
如果打开元素的堆栈中没有具有相同标签名的元素在作用域内,则这是一个解析错误;忽略该令牌。
否则,运行以下步骤:
如果文档
未设置为怪异模式,并且打开元素的堆栈中具有p
元素在按钮作用域内,则关闭p
元素。
将frameset-ok 标志设置为“not ok”。
解析错误。删除该令牌的属性,并按下一个条目中的描述进行操作;即,按没有属性的“br”开始标签令牌而不是实际的结束标签令牌进行操作。
重建活动格式化元素,如果有的话。
为该令牌插入一个HTML元素。立即从当前节点中弹出元素堆栈中的打开元素。
确认令牌的自关闭标志,如果已设置。
将frameset-ok 标志设置为“not ok”。
重建活动格式化元素,如果有的话。
为该令牌插入一个HTML元素。立即从当前节点中弹出元素堆栈中的打开元素。
确认令牌的自关闭标志,如果已设置。
如果该令牌没有名为“type”的属性,或者如果有该属性,但其值与字符串“hidden
”不匹配,则将frameset-ok
标志设置为“not ok”。
为该令牌插入一个HTML元素。立即从当前节点中弹出元素堆栈中的打开元素。
确认令牌的自关闭标志,如果已设置。
如果打开元素的堆栈中具有p
元素在按钮作用域内,则关闭p
元素。
为该令牌插入一个HTML元素。立即从当前节点中弹出元素堆栈中的打开元素。
确认令牌的自关闭标志,如果已设置。
将frameset-ok 标志设置为“not ok”。
解析错误。将令牌的标签名更改为“img”并重新处理它。(别问。)
运行以下步骤:
如果下一个令牌是一个U+000A换行符(LF)字符令牌,则忽略该令牌并继续处理下一个。(在textarea
元素开头的换行符将被忽略,以方便作者。)
将令牌生成器切换到RCDATA状态。
将frameset-ok 标志设置为“not ok”。
如果打开元素的堆栈中具有p
元素在按钮作用域内,则关闭p
元素。
重建活动格式化元素,如果有的话。
将frameset-ok 标志设置为“not ok”。
遵循通用原始文本元素解析算法。
将frameset-ok 标志设置为“not ok”。
遵循通用原始文本元素解析算法。
遵循通用原始文本元素解析算法。
重建活动格式化元素,如果有的话。
将frameset-ok 标志设置为“not ok”。
如果插入模式为“表格内”、“标题内”、“表格体内”、“行内”或“单元格内”之一,则将插入模式切换为“表格中的选择”。否则,将插入模式切换为“选择内”。
如果当前节点是一个option
元素,则从当前节点中弹出元素堆栈中的打开元素。
重建活动格式化元素,如果有的话。
如果打开元素的堆栈中具有在作用域内的ruby
元素,则生成隐含的结束标签。如果当前节点现在不是ruby
元素,则这是一个解析错误。
如果打开元素的堆栈中具有在作用域内的ruby
元素,则生成隐含的结束标签,但不包括rtc
元素。如果当前节点现在不是rtc
元素或ruby
元素,则这是一个解析错误。
重建活动格式化元素,如果有的话。
调整该令牌的MathML属性。(这会修复MathML属性的大小写问题。)
调整该令牌的外部属性。(这会修复命名空间属性的使用,特别是XLink。)
为该令牌插入一个外部元素,并使用MathML命名空间和false。
如果令牌设置了自关闭标志,则从当前节点中弹出元素堆栈中的打开元素并确认令牌的自关闭标志。
重建活动格式化元素,如果有的话。
调整该令牌的SVG属性。(这会修复SVG属性的大小写问题。)
调整该令牌的外部属性。(这会修复命名空间属性的使用,特别是在SVG中的XLink。)
为该令牌插入一个外部元素,并使用SVG命名空间和false。
如果令牌设置了自关闭标志,则从当前节点中弹出元素堆栈中的打开元素并确认令牌的自关闭标志。
解析错误。忽略该令牌。
重建活动格式化元素,如果有的话。
运行以下步骤:
当上面的步骤说用户代理应该关闭p
元素时,这意味着用户代理必须运行以下步骤:
收养机构算法,其唯一参数为正在运行算法的令牌token,包含以下步骤:
将subject设为token的标签名。
如果当前节点是一个HTML元素,其标签名为subject,并且当前节点不在活动格式化元素列表中,则弹出当前节点,并返回。
将outerLoopCounter设为0。
在真时运行:
如果outerLoopCounter大于或等于8,则返回。
将outerLoopCounter加1。
将formattingElement设为活动格式化元素列表中从末尾到列表中最后一个标记之间的最后一个元素(如果有),否则从列表开头开始,且其标签名为subject。
如果没有这样的元素,则返回并按照上述“任何其他结束标签”条目中的描述进行操作。
将furthestBlock设为打开元素的堆栈中最上面的节点,该节点在堆栈中低于formattingElement,并且是属于特殊类别的元素。可能没有一个。
如果没有furthestBlock,则用户代理必须首先弹出打开元素的堆栈中的所有节点,从当前节点到包括formattingElement,然后从活动格式化元素列表中移除formattingElement,最后返回。
将commonAncestor设为formattingElement在打开元素的堆栈中上方的元素。
在活动格式化元素列表中,为formattingElement的位置做一个书签,相对于列表中的前后元素。
将node和lastNode设为furthestBlock。
将innerLoopCounter设为0。
在真时运行:
将innerLoopCounter加1。
将node设为打开元素的堆栈中node上方的元素,或者如果node不再在打开元素的堆栈中(例如,因为它被此算法移除),则为node在从堆栈中移除之前在打开元素的堆栈中上方的元素。
如果node是formattingElement,则中断。
如果innerLoopCounter大于3,并且node在活动格式化元素列表中,则从列表中移除node。
为创建node的令牌创建一个元素,使用HTML命名空间,并以commonAncestor作为预期的父元素;将活动格式化元素列表中node的条目替换为新元素的条目,将打开元素的堆栈中node的条目替换为新元素的条目,并将node设为新元素。
如果last node是furthestBlock,则将前述书签移至活动格式化元素列表中新node之后的位置。
将lastNode附加到node。
将lastNode设为node。
在适当的位置插入节点,但使用commonAncestor作为覆盖目标。
为创建formattingElement的令牌创建一个元素,使用HTML命名空间,并以furthestBlock作为预期的父元素。
将furthestBlock的所有子节点附加到上一步创建的元素中。
将新元素附加到furthestBlock。
从打开元素的堆栈中移除formattingElement,并将新元素插入到打开元素的堆栈中,位置位于furthestBlock之下。
该算法的名称“收养机构算法”源于它如何使元素更改父元素,这与处理错误嵌套内容的其他可能算法形成对比。
当用户代理应用“文本”插入模式的规则时,用户代理必须按以下方式处理令牌:
这永远不会是U+0000 NULL字符;标记器会将这些字符转换为U+FFFD替换字符。
解析错误。
如果活动推测性HTML解析器为空,并且JavaScript执行上下文堆栈为空,则执行微任务检查点。
让old insertion point与当前的插入点具有相同的值。将插入点设在下一个输入字符之前。
将解析器的脚本嵌套级别增加1。
如果活动推测性HTML解析器为空,则准备脚本元素script。这可能会导致某些脚本执行,从而可能导致新的字符被插入到标记器中,并可能导致标记器输出更多令牌,从而导致解析器的重新进入调用。
将解析器的脚本嵌套级别减少1。如果解析器的脚本嵌套级别为零,则将解析器暂停标志设置为false。
将插入点设置为old insertion point的值。(换句话说,将插入点恢复到其先前的值。这可能是“未定义”的值。)
在此阶段,如果挂起的解析阻塞脚本不为空,则:
将解析器暂停标志设置为true,并中止对任何嵌套调用标记器的处理,将控制权交回调用方。(当调用方返回到“外部”树构建阶段时,标记化将恢复。)
此特定解析器的树构建阶段正在重新进入调用,例如,通过调用document.write()
。
当挂起的解析阻塞脚本不为空时:
将script设为挂起的解析阻塞脚本。
将挂起的解析阻塞脚本设置为空。
启动推测性HTML解析器以处理该HTML解析器实例。
如果解析器的文档
有阻止脚本的样式表或script的准备好被解析器执行为false:旋转事件循环,直到解析器的文档
没有阻止脚本的样式表,并且script的准备好被解析器执行变为true。
如果此解析器已在此期间被中止,则返回。
如果例如在运行旋转事件循环算法期间,文档
被销毁,或在文档
上调用了document.open()
方法,这种情况可能会发生。
停止推测性HTML解析器以处理该HTML解析器实例。
将解析器的脚本嵌套级别增加1(在此步骤之前它应该为零,因此这将其设置为1)。
执行脚本元素script。
将插入点再次设为未定义。
当用户代理应用“在表格中”插入模式的规则时,用户代理必须按以下方式处理令牌:
table
、
tbody
、
template
、
tfoot
、
thead
,
或tr
元素
将pending table character tokens设为一个空的令牌列表。
解析错误。忽略该令牌。
将堆栈清除回表格上下文。(见下文。)
为该令牌插入一个HTML元素,然后将插入模式切换到“在标题中”。
将堆栈清除回表格上下文。(见下文。)
为该令牌插入一个HTML元素,然后将插入模式切换到“在列组中”。
将堆栈清除回表格上下文。(见下文。)
为一个没有属性的“colgroup”开始标签令牌插入一个HTML元素,然后将插入模式切换到“在列组中”。
重新处理当前令牌。
将堆栈清除回表格上下文。(见下文。)
为该令牌插入一个HTML元素,然后将插入模式切换到“在表格正文中”。
将堆栈清除回表格上下文。(见下文。)
为一个没有属性的“tbody”开始标签令牌插入一个HTML元素,然后将插入模式切换到“在表格正文中”。
重新处理当前令牌。
解析错误。
如果打开元素的堆栈中没有在表格范围内的table
元素,则忽略该令牌。
否则:
从该堆栈中弹出元素,直到弹出一个table
元素。
重新处理该令牌。
如果打开元素的堆栈中没有在表格范围内的table
元素,这是一个解析错误;忽略该令牌。
否则:
从该堆栈中弹出元素,直到弹出一个table
元素。
解析错误。忽略该令牌。
如果该令牌没有名为“type”的属性,或者如果有,但该属性的值与字符串“hidden
”不区分ASCII大小写匹配,则:按下面“其他任何情况”条目中描述的方式处理。
否则:
解析错误。
确认令牌的自关闭标志,如果已设置。
解析错误。
如果打开元素的堆栈中有一个template
元素,或者如果form
元素指针不为空,则忽略该令牌。
否则:
为该令牌插入一个HTML元素,并将form
元素指针指向创建的元素。
当上述步骤要求UA 将堆栈清除回表格上下文时,这意味着UA必须在当前节点不是table
、
template
,
或html
元素时,从打开元素的堆栈中弹出元素。
这是与在表格范围内具有元素步骤中使用的相同的元素列表。
当用户代理要应用“表格文本中”插入模式的规则时,用户代理必须按以下方式处理该令牌:
解析错误。忽略该令牌。
将字符令牌追加到待处理表格字符令牌列表中。
如果待处理表格字符令牌列表中的任何令牌是非ASCII空白字符的字符令牌,则这是一个解析错误:使用“表格中”插入模式的“其他任何情况”条目中的规则重新处理待处理表格字符令牌列表中的字符令牌。
当用户代理要应用“在标题中”插入模式的规则时,用户代理必须按以下方式处理该令牌:
如果开放元素栈中没有在表格范围内的caption
元素,则这是解析错误;忽略该令牌。(片段情况)
否则:
从此栈中弹出元素,直到弹出caption
元素为止。
如果开放元素栈中没有在表格范围内的caption
元素,则这是解析错误;忽略该令牌。(片段情况)
否则:
从此栈中弹出元素,直到弹出caption
元素为止。
重新处理该令牌。
解析错误。忽略该令牌。
当用户代理要应用“在列组中”插入模式的规则时,用户代理必须按以下方式处理该令牌:
插入字符。
插入注释。
解析错误。忽略该令牌。
为令牌插入一个 HTML 元素。立即将当前节点从开放元素栈中弹出。
确认令牌的自闭合标志,如果已设置。
解析错误。忽略该令牌。
如果当前节点不是colgroup
元素,则这是解析错误;忽略该令牌。
重新处理该令牌。
当用户代理要应用“在表格主体中”插入模式的规则时,用户代理必须按以下方式处理该令牌:
清除堆栈返回表格主体上下文。(见下文。)
为令牌插入一个 HTML 元素,然后将插入模式切换到“在行中”。
解析错误。
清除堆栈返回表格主体上下文。(见下文。)
为没有属性的“tr”起始标签令牌插入一个 HTML 元素,然后将插入模式切换到“在行中”。
重新处理当前令牌。
如果开放元素栈中没有在表格范围内的元素,其标签名与令牌相同,这是解析错误;忽略该令牌。
否则:
清除堆栈返回表格主体上下文。(见下文。)
如果开放元素栈中没有在表格范围内的tbody
、thead
或tfoot
元素,这是解析错误;忽略该令牌。
否则:
清除堆栈返回表格主体上下文。(见下文。)
重新处理令牌。
解析错误。忽略该令牌。
当上述步骤要求 UA 清除堆栈返回表格主体上下文时,意味着 UA 必须在当前节点不是tbody
、tfoot
、thead
、template
或html
元素时,从开放元素栈中弹出元素。
当用户代理要应用“在行中”插入模式的规则时,用户代理必须按以下方式处理该令牌:
清除堆栈返回表格行上下文。(见下文。)
为令牌插入一个 HTML 元素,然后将插入模式切换到“在单元格中”。
如果开放元素栈中没有在表格范围内的tr
元素,这是解析错误;忽略该令牌。
否则:
清除堆栈返回表格行上下文。(见下文。)
如果开放元素栈中没有在表格范围内的tr
元素,这是解析错误;忽略该令牌。
否则:
清除堆栈返回表格行上下文。(见下文。)
从开放元素栈中弹出当前节点(它将是一个tr
元素)。将插入模式切换到“在表格主体中”。
重新处理该令牌。
如果开放元素栈中没有在表格范围内的元素,该元素是一个标签名与令牌相同的HTML 元素,这是解析错误;忽略该令牌。
如果开放元素栈中没有在表格范围内的tr
元素,忽略该令牌。
否则:
清除堆栈返回表格行上下文。(见下文。)
从开放元素栈中弹出当前节点(它将是一个tr
元素)。将插入模式切换到“在表格主体中”。
重新处理该令牌。
解析错误。忽略该令牌。
当上述步骤要求 UA 清除堆栈返回表格行上下文时,意味着 UA 必须在当前节点不是tr
、template
或html
元素时,从开放元素栈中弹出元素。
当用户代理要应用“在单元格中”插入模式的规则时,用户代理必须按以下方式处理该令牌:
如果开放元素栈中没有在表格范围内的元素,该元素是一个标签名与令牌相同的HTML 元素,则这是解析错误;忽略该令牌。
否则:
现在,如果当前节点不是一个标签名与令牌相同的HTML 元素,则这是解析错误。
关闭单元格(见下文)并重新处理令牌。
解析错误。忽略该令牌。
如果开放元素栈中没有在表格范围内的元素,该元素是一个标签名与令牌相同的HTML 元素,则这是解析错误;忽略该令牌。
否则,关闭单元格(见下文)并重新处理该令牌。
上述步骤中提到的关闭单元格,意味着运行以下算法:
开放元素栈不能同时包含td
和th
元素在表格范围内,也不能在调用关闭单元格算法时既不包含这两者。
当用户代理要应用“在选择框中”插入模式的规则时,用户代理必须按以下方式处理该令牌:
解析错误。忽略该令牌。
插入注释。
解析错误。忽略该令牌。
如果当前节点是一个option
元素,则从开放元素栈中弹出该节点。
如果当前节点是一个option
元素,则从开放元素栈中弹出该节点。
如果当前节点是一个optgroup
元素,则从开放元素栈中弹出该节点。
为该令牌插入一个 HTML 元素。立即从开放元素栈中弹出当前节点。
确认该令牌的自闭合标志,如果已设置。
首先,如果当前节点是一个option
元素,并且在开放元素栈中紧接在其前面的节点是一个optgroup
元素,则从开放元素栈中弹出当前节点。
如果开放元素栈中没有在选择范围内的select
元素,这是一个解析错误;忽略该令牌。(片段情况)
否则:
解析错误。
如果开放元素栈中没有在选择范围内的select
元素,忽略该令牌。(片段情况)
否则:
它只是像结束标签一样处理。
解析错误。
如果开放元素栈中没有在选择范围内的select
元素,忽略该令牌。(片段情况)
否则:
重新处理该令牌。
解析错误。忽略该令牌。
当用户代理要应用“在表格中的选择框”插入模式的规则时,用户代理必须按以下方式处理该令牌:
解析错误。
重新处理该令牌。
解析错误。
如果开放元素栈中没有在表格范围内的HTML元素与该令牌的标签名相同,则忽略该令牌。
否则:
重新处理该令牌。
当用户代理要应用“在模板中”插入模式的规则时,用户代理必须按以下方式处理该令牌:
解析错误。忽略该令牌。
如果在开放元素栈上没有template
元素,则停止解析。(片段情况)
否则,这是一个解析错误。
重新处理该令牌。
当用户代理要应用“在主体之后”插入模式的规则时,用户代理必须按以下方式处理该令牌:
解析错误。忽略该令牌。
如果解析器是作为HTML片段解析算法的一部分创建的,这是一个解析错误;忽略该令牌。(片段情况)
停止解析。
当用户代理要应用“在框架集内”插入模式的规则时,用户代理必须按以下方式处理该令牌:
插入字符。
插入注释。
解析错误。忽略该令牌。
如果当前节点是根html
元素,则这是一个解析错误;忽略该令牌。(片段情况)
如果解析器不是作为HTML片段解析算法的一部分创建的(片段情况),并且当前节点不再是frameset
元素,则将插入模式切换为“在框架集之后”。
为该令牌插入一个HTML元素。立即将当前节点从开放元素栈中弹出。
确认令牌的自关闭标志(如果设置了该标志)。
停止解析。
解析错误。忽略该令牌。
当用户代理要应用“在框架集之后”插入模式的规则时,用户代理必须按以下方式处理该令牌:
插入字符。
插入注释。
解析错误。忽略该令牌。
停止解析。
解析错误。忽略该令牌。
当用户代理要应用“在主体之后之后”插入模式的规则时,用户代理必须按以下方式处理该令牌:
停止解析。
当用户代理要应用“在框架集之后之后”插入模式的规则时,用户代理必须按以下方式处理该令牌:
停止解析。
解析错误。忽略该令牌。
当用户代理要应用在外来内容中解析令牌的规则时,用户代理必须按以下方式处理该令牌:
将frameset-ok标志设置为“不可以”。
解析错误。忽略该令牌。
解析错误。
当当前节点不是MathML文本集成点、HTML集成点或HTML命名空间中的元素时,从开放元素堆栈中弹出元素。
根据HTML内容中与当前插入模式相应部分中给出的规则重新处理该令牌。
如果调整后的当前节点是MathML命名空间中的元素,调整MathML属性以适应令牌。(这修复了不是全小写的MathML属性的情况。)
如果调整后的当前节点是SVG命名空间中的元素,并且令牌的标签名是下表第一列中的某个名称,则将标签名更改为相应单元格中给出的名称。(这修复了不是全小写的SVG元素的情况。)
标签名 | 元素名 |
---|---|
altglyph |
altGlyph |
altglyphdef |
altGlyphDef |
altglyphitem |
altGlyphItem |
animatecolor |
animateColor |
animatemotion |
animateMotion |
animatetransform |
animateTransform |
clippath |
clipPath |
feblend |
feBlend |
fecolormatrix |
feColorMatrix |
fecomponenttransfer |
feComponentTransfer |
fecomposite |
feComposite |
feconvolvematrix |
feConvolveMatrix |
fediffuselighting |
feDiffuseLighting |
fedisplacementmap |
feDisplacementMap |
fedistantlight |
feDistantLight |
fedropshadow |
feDropShadow |
feflood |
feFlood |
fefunca |
feFuncA |
fefuncb |
feFuncB |
fefuncg |
feFuncG |
fefuncr |
feFuncR |
fegaussianblur |
feGaussianBlur |
feimage |
feImage |
femerge |
feMerge |
femergenode |
feMergeNode |
femorphology |
feMorphology |
feoffset |
feOffset |
fepointlight |
fePointLight |
fespecularlighting |
feSpecularLighting |
fespotlight |
feSpotLight |
fetile |
feTile |
feturbulence |
feTurbulence |
foreignobject |
foreignObject |
glyphref |
glyphRef |
lineargradient |
linearGradient |
radialgradient |
radialGradient |
textpath |
textPath |
如果调整后的当前节点是SVG命名空间中的元素,调整SVG属性以适应令牌。(这修复了不是全小写的SVG属性的情况。)
调整外来属性以适应令牌。(这修复了使用命名空间属性的问题,特别是在SVG中的XLink。)
为令牌插入一个外来元素,使用调整后的当前节点的命名空间并设置为false。
如果令牌的自闭合标志已设置,则运行以下列表中的相应步骤:
确认令牌的自闭合标志,然后按照下面“script”结束标签的步骤进行操作。
从开放元素堆栈中弹出当前节点并确认令牌的自闭合标志。
script
元素将old insertion point的值设置为当前插入点的值。将插入点设置为下一个输入字符之前。
将解析器的脚本嵌套级别增加1。将解析器暂停标志设置为true。
如果活动的推测性HTML解析器为null并且用户代理支持SVG,则根据SVG规则处理SVGscript
元素。[SVG]
即使这导致向令牌器插入新字符,由于解析器暂停标志为true,解析器也不会被重新进入地执行。
将解析器的脚本嵌套级别减少1。如果解析器的脚本嵌套级别为零,则将解析器暂停标志设置为false。
将插入点的值恢复为old insertion point的值。(换句话说,将插入点恢复到其以前的值。这个值可能是“未定义”的值。)
运行以下步骤:
将node初始化为当前节点(堆栈的最底部节点)。
如果node的标签名转换为ASCII小写后与令牌的标签名不同,则这是一个解析错误。
如果node的标签名转换为ASCII小写后与令牌的标签名相同,则从开放元素堆栈中弹出元素,直到node被弹出堆栈,然后返回。
将node设置为开放元素堆栈中的上一个条目。
如果node不是HTML命名空间中的元素,则返回到标记为循环的步骤。
否则,根据HTML内容中与当前插入模式相应部分中给出的规则处理令牌。
Document/DOMContentLoaded_event
所有当前引擎均支持。
一旦用户代理停止解析文档,用户代理必须执行以下步骤:
所有当前引擎均支持。
如果活动推测性HTML解析器不为null,则停止推测性HTML解析器并返回。
将插入点设置为未定义。
将当前文档准备状态更新为“interactive
”。
从开放元素堆栈中弹出所有节点。
当文档解析完成后将执行的脚本列表不为空时:
旋转事件循环,直到文档解析完成后将执行的脚本列表中的第一个script
的准备被解析器执行设置为true并且解析器的Document
没有阻止脚本的样式表。
执行脚本元素,该元素由文档解析完成后将执行的脚本列表中的第一个script
提供。
从文档解析完成后将执行的脚本列表中删除第一个script
元素(即从列表中移除第一个条目)。
在DOM操作任务源上排队一个全局任务,给定Document
的相关全局对象,以执行以下子步骤:
将当前文档准备状态更新为“complete
”。
调用WebDriver BiDi加载完成,使用Document
的浏览上下文,并使用新的WebDriver BiDi导航状态,其id为Document
的WebDriver
BiDi加载时导航ID,状态为“complete
”,并且url为Document
对象的URL。
将Document
对象的WebDriver
BiDi加载时导航ID设置为null。
触发一个页面过渡事件,名为pageshow
,目标为window,并设置为false。
Document
现在准备好执行加载后任务。
当用户代理要中止解析器时,必须执行以下步骤:
用户代理可以实现一种优化,如本节所述,在HTML解析器等待待定的解析阻塞脚本获取并执行时,或在正常解析期间,当为标记创建元素时,推测性地获取HTML标记中声明的资源。虽然这种优化没有详细定义,但有一些规则需要考虑以实现互操作性。
每个HTML解析器可以有一个活动的推测性HTML解析器,它最初为null。
推测性HTML解析器必须像普通的HTML解析器一样运作(例如,适用树构建规则),但有一些例外:
普通HTML解析器和文档本身的状态不得受到影响。
例如,普通HTML解析器的下一个输入字符或打开元素堆栈不受推测性HTML解析器的影响。
推测性解析的结果主要是一系列推测性获取。推测性获取哪种资源是实现定义的,但用户代理不得推测性获取在假设阻塞HTML解析器的脚本什么也不做的情况下普通HTML解析器不会获取的资源。
同样的标记可能会多次出现在推测性HTML解析器和普通HTML解析器中。预期重复的获取将通过尚未完全指定的缓存规则来防止。
针对推测性模拟元素element的推测性获取必须遵循以下规则:
是否应将其中的一些东西应用到文档“实际”上,即使它们是推测性地找到的?
如果推测性HTML解析器遇到以下元素之一,则应视为该元素已处理,以便其对后续推测性获取的影响。
base
元素。
meta
元素,其http-equiv
属性处于内容安全策略状态。meta
元素,其name
属性与"referrer
"进行ASCII大小写不敏感匹配。meta
元素,其name
属性与"viewport
"进行ASCII大小写不敏感匹配。(这可能会影响媒体查询列表是否匹配环境。)[CSSDEVICEADAPT]让url成为element如果正常处理时将获取的URL。如果没有这样的URL,或者它是空字符串,则什么也不做。否则,如果url已经在推测性获取URL列表中,则什么也不做。否则,像正常处理该元素一样获取url,并将url添加到推测性获取URL列表中。
每个Document
都有一个推测性获取URL列表,这是一个列表,最初为空。
要为HTML解析器实例parser启动推测性HTML解析器:
可以选择返回。
此步骤允许用户代理选择不进行推测性HTML解析。
如果parser的活动的推测性HTML解析器不为null,则为parser停止推测性HTML解析器。
这可能发生在document.write()
写入另一个阻塞解析的脚本时。为简化起见,本规范总是重新启动推测性解析,但用户代理可以实现更有效的策略,只要最终结果等效即可。
让speculativeParser成为一个新的推测性HTML解析器,其状态与parser相同。
让speculativeDoc成为parser的Document
的新同构表示,其中所有元素都为推测性模拟元素。让speculativeParser解析为speculativeDoc。
将parser的活动的推测性HTML解析器设置为speculativeParser。
要为HTML解析器实例parser停止推测性HTML解析器:
让speculativeParser成为parser的活动的推测性HTML解析器。
如果speculativeParser为null,则返回。
丢弃speculativeParser的输入流中的任何待处理内容,并丢弃将来可能添加的任何内容。
将parser的活动的推测性HTML解析器设置为null。
推测性HTML解析器将创建推测性模拟元素,而不是普通元素。树构建器通常对元素执行的DOM操作应在推测性模拟元素上适当工作。
要在给定namespace、tagName和attributes的情况下创建推测性模拟元素:
让element成为一个新的推测性模拟元素。
将element的命名空间设置为namespace。
将element的本地名称设置为tagName。
将element的属性列表设置为attributes。
可以选择为element执行推测性获取。
返回element。
当树构建器说要将元素插入到template
元素的template内容中时,如果这是一个推测性模拟元素,并且template
元素的template内容不是ShadowRoot节点,则不执行任何操作。非声明性影子根内推测找到的URLtemplate
元素本身可能是模板,不得推测性获取。
当应用程序将HTML解析器与XML流水线结合使用时,构建的DOM可能在某些细微方面与XML工具链不兼容。例如,XML工具链可能无法表示名称为xmlns
的属性,因为它们与XML语法中的命名空间冲突。还有一些数据是HTML解析器生成的,但不包含在DOM本身中。本节规定了处理这些问题的一些规则。
如果所使用的XML API不支持DOCTYPE,工具可以完全删除DOCTYPE。
如果XML API不支持无命名空间且名称为"xmlns
"的属性、名称以"xmlns:
"开头的属性或XMLNS命名空间中的属性,则工具可以删除这些属性。
工具可以在输出中注释任何为正确操作所需的命名空间声明。
如果所使用的XML API限制元素和属性的本地名称中的允许字符,那么工具可以通过将任何不支持的字符替换为大写字母U和字符的代码点(以十六进制表示)对应的六位数字来映射所有元素和属性的本地名称到一组允许的名称,使用数字0-9和大写字母A-F作为符号,按数字顺序排列。
例如,元素名称foo<bar
,它可以由HTML解析器输出,虽然它既不是合法的HTML元素名称,也不是格式良好的XML元素名称,但会被转换为fooU00003Cbar
,这是一个格式良好的XML元素名称(尽管它在HTML中仍然不合法)。
再比如,考虑属性xlink:href
。在MathML元素上使用时,它在被调整后,成为带有前缀"xlink
"和本地名称"href
"的属性。然而,在HTML元素上使用时,它成为没有前缀且本地名称为"xlink:href
"的属性,这不是一个有效的NCName,因此可能不会被XML
API接受。因此,它可能会被转换为"xlinkU00003Ahref
"。
这种转换生成的名称方便地不会与HTML解析器生成的任何属性发生冲突,因为这些属性要么是小写的,要么是在调整外部属性算法的表中列出的。
如果XML API限制注释中有两个连续的U+002D HYPHEN-MINUS字符(--),工具可以在任何此类冲突字符之间插入一个U+0020 SPACE字符。
如果XML API限制注释以U+002D HYPHEN-MINUS字符(-)结尾,工具可以在此类注释末尾插入一个U+0020 SPACE字符。
如果XML API限制字符数据、属性值或注释中的允许字符,工具可以将任何U+000C FORM FEED (FF)字符替换为U+0020 SPACE字符,并将任何其他非XML字符替换为U+FFFD REPLACEMENT CHARACTER。
如果工具无法传递带外信息,则工具可以删除以下信息:
本节允许的变更适用于HTML解析器规则应用之后。例如,<a::>
开始标签将由</a::>
结束标签关闭,而不会由</aU00003AU00003A>
结束标签关闭,即使用户代理使用上述规则生成一个名为aU00003AU00003A
的实际元素来处理该开始标签。
本节是非规范性的。
本节讨论了一些错误标记,并讨论了HTML解析器如何处理这些情况。
本节是非规范性的。
最常讨论的错误标记示例如下:
< p > 1< b > 2< i > 3</ b > 4</ i > 5</ p >
在解析这个标记时,到"3"为止是直截了当的。这时,DOM看起来像这样:
此时,打开元素堆栈中有五个元素:html
、body
、p
、b
和i
。活动格式化元素列表中只有两个:b
和i
。插入模式是"在正文中"。
在接收到标签名为"b"的结束标签标记时,调用了"领养机构算法"。这是一个简单的情况,其中formattingElement是b
元素,并且没有furthest
block。因此,打开元素堆栈只剩下三个元素:html
、body
和p
,而活动格式化元素列表中只有一个:i
。此时DOM树未修改。
下一个标记是字符"4",触发了活动格式化元素的重建,在本例中只有i
元素。因此,为"4"节点创建了一个新的i
元素。在接收到"i"的结束标签标记并插入"5"节点后,DOM如下所示:
本节是非规范性的。
与前一个类似的一个案例如下:
< b > 1< p > 2</ b > 3</ p >
在解析到"2"之前,解析过程很简单:
有趣的是,当解析到标签名为"b"的结束标签时。
在看到该标记之前,打开元素堆栈中有四个元素:html
、body
、b
和p
。活动格式化元素列表中只有一个:b
。插入模式是"在正文中"。
在接收到标签名为"b"的结束标签标记时,调用了"领养机构算法",与前一个例子类似。然而,在这种情况下,有一个furthest
block,即p
元素。因此,这次不会跳过领养机构算法。
common ancestor是body
元素。概念上的"书签"标记了b
在活动格式化元素列表中的位置,但由于该列表中只有一个元素,书签不会有太大作用。
随着算法的进行,node最终设置为格式化元素(b
),而last
node最终设置为furthest block(p
)。
last node被附加(移动)到common ancestor,使得DOM看起来如下:
b
元素从活动格式化元素列表和打开元素堆栈中删除,因此当解析"3"时,它将被附加到p
元素上:
本节是非规范性的。
出于历史原因,表格中的错误处理尤其奇怪。例如,考虑以下标记:
< table > < b > < tr >< td > aaa</ td ></ tr > bbb</ table > ccc
高亮的b
元素开始标签不允许直接放置在表格内,解析器通过将该元素放置在表格之前来处理这种情况。(这被称为寄养父母)。可以通过查看DOM树来观察这一点,正如在看到table
元素的开始标签之后的情形:
...然后在看到b
元素开始标签之后:
此时,打开元素堆栈中包含了元素html
、body
、table
和b
(尽管最终的DOM树不匹配);活动格式化元素列表中只有一个b
元素;插入模式为"在表格中"。
tr
开始标签会导致b
元素被从堆栈中弹出,并隐式推导出一个tbody
开始标签;然后tbody
和tr
元素以相当直接的方式处理,将解析器带入"在表格体内"和"在行内"插入模式,之后DOM如下所示:
此时,打开元素堆栈中包含了元素html
、body
、table
、tbody
和tr
;活动格式化元素列表中仍然有b
元素;插入模式为"在行内"。
td
元素开始标签标记,在树中放置一个td
元素后,在活动格式化元素列表中放置了一个标记(它还切换到了"在单元格中"插入模式)。
该标记意味着在看到"aaa"字符标记时,不会创建b
元素来保存生成的文本
节点:
结束标签以直接的方式处理;在处理完它们之后,打开元素堆栈中包含了元素html
、body
、table
和tbody
;活动格式化元素列表中仍然有b
元素("td"结束标签标记已删除标记);插入模式为"在表格体内"。
于是"bbb"字符标记出现了。这些字符标记触发了使用"在表格文本中"插入模式(原始插入模式设置为"在表格体内")。字符标记被收集,当下一个标记(table
元素结束标签)出现时,它们作为一个整体处理。由于它们不是全部空格,因此根据"在表格中"插入模式中的"其他任何内容"规则进行处理,但带有寄养父母。
当活动格式化元素被重建时,会创建一个b
元素并进行寄养,然后将"bbb"文本
节点附加到它上面:
打开元素堆栈中包含了元素html
、body
、table
、tbody
和新创建的b
(再次注意,这与结果树不匹配!);活动格式化元素列表中有新创建的b
元素;插入模式仍然是"在表格体内"。
如果这些字符标记只是ASCII空白符而不是"bbb",那么这些ASCII空白符将仅附加到tbody
元素中。
最后,通过"table"结束标签关闭table
。这会将打开元素堆栈中的所有节点弹出,直到包括table
元素,但不会影响活动格式化元素列表,因此表格后的"ccc"字符标记会导致在表格之后再次创建一个b
元素:
本节为非规范性内容。
考虑以下标记,在本例中,我们假设它是文档 URL 为
https://example.com/inner
的页面内容,该内容正在作为另一个文档中 https://example.com/outer
的一个 iframe
渲染:
< div id = a >
< script >
var div = document. getElementById( 'a' );
parent. document. body. appendChild( div);
</ script >
< script >
alert( document. URL);
</ script >
</ div >
< script >
alert( document. URL);
</ script >
在解析第一个 "script" 结束标签之前,结果相对简单:
然而,在解析该脚本之后,div
元素及其子元素 script
已经消失:
此时,它们位于前面提到的外部 Document
中。然而,开放元素栈 仍然包含 div
元素。
因此,当第二个 script
元素被解析时,它被插入到了外部 Document
对象中。
那些被解析到与创建解析器时不同 Document
的脚本不会执行,因此第一个 alert 并不会弹出。
一旦 div
元素的结束标签被解析,该 div
元素将从栈中弹出,因此下一个 script
元素位于内部 Document
中:
这个脚本会执行,结果是弹出一个显示 "https://example.com/inner" 的 alert。
本节为非规范性内容。
在上一节的示例基础上,考虑以下情况:第二个 script
元素是一个外部脚本(即具有 src
属性的脚本)。由于该元素在创建时不在解析器的 Document
中,因此该外部脚本甚至不会被下载。
在另一个场景中,一个带有 src
属性的 script
元素被正常解析到其解析器的 Document
中,但在外部脚本下载过程中,该元素被移动到另一个文档中,脚本会继续下载,但不会执行。
一般来说,在 Document
之间移动 script
元素被认为是一种不良做法。
本节为非规范性内容。
以下标记展示了嵌套的格式化元素(如 b
)是如何被收集并继续应用的,即使它们所在的元素已经关闭,但是多余的重复元素会被丢弃。
<!DOCTYPE html>
< p >< b class = x >< b class = x >< b >< b class = x >< b class = x >< b > X
< p > X
< p >< b >< b class = x >< b > X
< p ></ b ></ b ></ b ></ b ></ b ></ b > X
生成的DOM树如下:
html
html
请注意标记中的第二个 p
元素没有显式的 b
元素,但在生成的 DOM 中,每种格式化元素(在本例中为带有 class 属性的三个 b
元素和两个不带修饰的 b
元素)在元素的 "X" 之前最多会被重建三次。
另请注意,这意味着在最后一段中,只有六个 b
结束标签就足以完全清除 活动格式化元素列表,尽管到目前为止已经看到了九个 b
开始标签。
在以下算法中,如果一个元素的元素类型是void元素之一,或者是basefont
、bgsound
、frame
、keygen
或param
,则该元素序列化为空。
以下步骤构成了HTML片段序列化算法。该算法以DOM中的Element
、Document
或DocumentFragment
作为输入节点,并称之为node,输入一个布尔值serializableShadowRoots,以及一个sequence<ShadowRoot>
类型的shadowRoots,返回一个字符串。
此算法序列化的是被序列化节点的子节点,而不是节点本身。
如果node序列化为空,则返回空字符串。
令s为一个字符串,并将其初始化为空字符串。
如果node是template
元素,则将node替换为template
元素的模板内容(一个DocumentFragment
节点)。
如果current node是shadow host,则:
令shadow为current node的shadow root。
如果以下情况之一为真:
serializableShadowRoots为true且shadow的serializable为true;或
shadowRoots包含shadow,
那么:
附加"<template shadowrootmode="
"。
如果shadow的mode为"open
",则附加"open
"。否则,附加"closed
"。
附加""
"。
如果shadow的delegates
focus已设置,则附加" shadowrootdelegatesfocus=""
"。
如果shadow的serializable已设置,则附加" shadowrootserializable=""
"。
如果shadow的clonable已设置,则附加" shadowrootclonable=""
"。
附加">
"。
附加运行HTML片段序列化算法的值,其中传入shadow、serializableShadowRoots和shadowRoots(因此对该元素递归调用此算法)。
附加"</template>
"。
对于node的每个子节点,按树顺序执行以下步骤:
令current node为正在处理的子节点。
将下列列表中的适当字符串附加到s:
Element
如果current node是HTML命名空间、MathML命名空间或SVG命名空间中的元素,则令 tagname为current node的本地名称。否则,令tagname为current node的限定名称。
附加一个U+003C小于号字符(<),然后是tagname。
对于由HTML
解析器创建的HTML
元素或通过createElement()
创建的元素,tagname将为小写。
如果current node的is
值不为null,并且该元素的属性列表中没有is
属性,则附加字符串" is="
",然后附加current
node的is
值,按下面描述的方式转义,使用属性模式,然后附加一个U+0022引号字符(")。
对于元素具有的每个属性,附加一个U+0020空格字符、按下文描述的方式序列化的属性名称,一个U+003D等号字符(=),一个U+0022引号字符("),属性值,按下文描述的方式转义,使用属性模式,然后附加第二个U+0022引号字符(")。
属性的序列化名称应根据以下规则确定:
该属性的序列化名称是该属性的本地名称。
对于由HTML
元素上的属性,由HTML
解析器或通过setAttribute()
设置时,本地名称将为小写。
属性的序列化名称是字符串"xml:
",后跟属性的本地名称。
xmlns
属性的序列化名称是字符串"xmlns
"。
xmlns
属性的序列化名称是字符串"xmlns:
",后跟属性的本地名称。
属性的序列化名称是字符串"xlink:
",后跟属性的本地名称。
属性的序列化名称是属性的限定名称。
虽然属性的确切顺序是实现定义的,可能取决于属性在原始标记中的顺序等因素,但排序顺序必须是稳定的,以便连续调用此算法可以以相同的顺序序列化元素的属性。
附加一个U+003E大于号字符(>)。
如果current node序列化为空,则此时继续处理下一个子节点。
附加运行HTML片段序列化算法的值,其中传入current node、serializableShadowRoots和shadowRoots(因此对该节点递归调用此算法),然后附加一个U+003C小于号字符(<)、一个U+002F斜杠字符(/)、tagname,最后附加一个U+003E大于号字符(>)。
文本
节点
如果current node的父节点是style
、script
、xmp
、iframe
、noembed
、noframes
或plaintext
元素,或者如果current
node的父节点是noscript
元素,并且为该节点启用了脚本,则按字面附加current
node的数据。
否则,附加current node的数据,按下文描述的方式转义。
注释
节点
附加"<!--
"(U+003C小于号、U+0021感叹号、U+002D短横线、U+002D短横线),然后附加current node的数据的值,然后附加字面字符串"-->
"(U+002D短横线、U+002D短横线、U+003E大于号)。
处理指令
节点
附加"<?
"(U+003C小于号、U+003F问号),然后附加current node的target
IDL属性的值,附加一个U+0020空格字符,然后附加current node的数据的值,最后附加一个U+003E大于号字符(>)。
文档类型
节点
附加"<!DOCTYPE
"(U+003C小于号、U+0021感叹号、U+0044大写字母D、U+004F大写字母O、U+0043大写字母C、U+0054大写字母T、U+0059大写字母Y、U+0050大写字母P、U+0045大写字母E),附加一个空格(U+0020空格),然后附加current
node的名称的值,然后附加">
"(U+003E大于号)。
返回s。
该算法的输出如果使用HTML解析器进行解析,可能不会还原原始的树结构。甚至HTML解析器本身也可能生成在序列化-重新解析步骤中不回送的树结构,尽管这种情况通常是不符合规范的。
例如,如果将一个附加了textarea
元素的Comment
节点进行序列化,然后输出再重新解析,则注释会显示在文本控件中。类似地,如果由于DOM操作,一个元素包含了一个包含"-->
"的注释,则在解析序列化元素的结果时,注释会在该点被截断,剩余部分将被解释为标记。另一个例子是让一个script
元素包含一个带有"</script>
"文本节点的Text
节点,或者让一个包含ul
元素的p
元素存在(因为ul
元素的起始标签会暗示p
的结束标签)。
这可能会导致跨站脚本攻击。例如,一个页面允许用户输入一些字体族名称,然后通过DOM将它们插入到一个CSS style
块中,然后使用innerHTML
ID属性获取该style
元素的HTML序列化:如果用户输入"</style><script>attack</script>
"作为字体族名称,innerHTML
将返回标记,如果在不同的上下文中解析,则会包含一个script
节点,即使在原始DOM中不存在script
节点。
例如,考虑以下标记:
< form id = "outer" >< div ></ form >< form id = "inner" >< input >
这将解析为:
input
元素将与内层form
元素相关联。现在,如果此树结构被序列化并重新解析,<form id="inner">
起始标签将被忽略,因此input
元素将与外层form
元素相关联。
< html >< head ></ head >< body >< form id = "outer" >< div > < form id = "inner" > < input ></ form ></ div ></ form ></ body ></ html >
再举一个例子,考虑以下标记:
< a >< table >< a >
这将解析为:
即寄养的a
元素嵌套在一起。经过一次序列化-重新解析的循环后,a
元素和table
元素将成为兄弟元素,因为第二个<a>
起始标签将隐式关闭第一个a
元素。
< html >< head ></ head >< body >< a > < a > </ a >< table ></ table ></ a ></ body ></ html >
由于历史原因,即使初始的U+000A换行符(LF)字符在pre
、textarea
或listing
元素中可以是符合规范的,本文的算法也不会将该字符进行轮回转移。HTML解析器在解析过程中将删除该字符,但该算法不会序列化额外的U+000A换行符(LF)字符。
例如,考虑以下标记:
< pre >
Hello.</ pre >
当首次解析此文档时,pre
元素的子文本内容以一个换行符字符开头。在一次序列化-重新解析的循环后,pre
元素的子文本内容仅为"Hello.
"。
由于is
属性在标记创建定制内建元素中起到了特殊作用,它为解析HTML提供了一种机制来设置元素的is
值,因此在序列化过程中需要特别处理此属性。这确保了元素的is
值在序列化-解析循环中得以保留。
在通过解析器创建定制内建元素时,开发者直接使用is
属性;在这种情况下,序列化-解析循环可以正常工作。
< script >
window. SuperP = class extends HTMLParagraphElement {};
customElements. define( "super-p" , SuperP, { extends : "p" });
</ script >
< div id = "container" >< p is = "super-p" > Superb!</ p ></ div >
< script >
console. log( container. innerHTML); // <p is="super-p">
container. innerHTML = container. innerHTML;
console. log( container. innerHTML); // <p is="super-p">
console. assert( container. firstChild instanceof SuperP);
</ script >
但是,当通过其构造函数或通过createElement()
创建定制内建元素时,不会添加is
属性。相反,is
值(这是自定义元素机制使用的)被设置,而无需通过属性进行中介。
< script >
container. innerHTML = "" ;
const p = document. createElement( "p" , { is: "super-p" });
container. appendChild( p);
// The is attribute is not present in the DOM:
console. assert( ! p. hasAttribute( "is" ));
// But the element is still a super-p:
console. assert( p instanceof SuperP);
</ script >
为了确保序列化-解析循环仍然有效,序列化过程会显式地将元素的is
值作为is
属性写出:
< script >
console. log( container. innerHTML); // <p is="super-p">
container. innerHTML = container. innerHTML;
console. log( container. innerHTML); // <p is="super-p">
console. assert( container. firstChild instanceof SuperP);
</ script >
转义字符串(用于上述算法)包括以下步骤:
将任何出现的"&
"字符替换为字符串"&
"。
将任何出现的U+00A0不间断空格字符替换为字符串"
"。
如果在属性模式下调用了该算法,则将任何出现的""
"字符替换为字符串""
"。
如果该算法未在属性模式下调用,则将任何出现的"<
"字符替换为字符串"<
",并将任何出现的">
"字符替换为字符串">
"。
以下步骤构成了HTML片段解析算法。该算法接受一个元素
节点作为输入,该节点被称为context元素,用于为解析器提供上下文信息,还有一个字符串input用于解析,以及一个可选的布尔值allowDeclarativeShadowRoots(默认值为false)。该算法返回零个或多个节点的列表。
在解析器部分标记为片段情况的部分仅在解析器是为了执行此算法而创建时才会出现。此类标记仅出于信息目的对算法进行注释,并没有规范性的权重。如果描述为片段情况的条件即使在解析器不是为了处理此算法而创建的情况下也可能发生,那么这是规范中的错误。
如果上下文元素的节点文档处于怪异模式,则将文档
置于怪异模式。否则,如果上下文元素的节点文档处于有限怪异模式,则将文档
置于有限怪异模式。否则,将文档
保持在非怪异模式。
如果allowDeclarativeShadowRoots为true,则将文档
的允许声明性Shadow Root属性设置为true。
title
textarea
style
xmp
iframe
noembed
noframes
script
noscript
plaintext
出于性能原因,不报告错误并直接使用此规范中描述的实际状态机的实现可以使用纯文本状态代替上述列表中提到的RAWTEXT和脚本数据状态。除了解析错误规则之外,它们是等效的,因为在片段情况下没有适当的结束标签标记,但它们涉及的状态转换要少得多。
让root成为一个没有属性的新的html
元素。
将root元素附加到上面创建的文档
节点。
设置解析器的打开元素栈,使其只包含单个元素root。
解析器将在该算法的部分过程中引用上下文元素。
将解析器的form
元素指针设置为最接近上下文元素的节点,该节点是一个表单
元素(直接向上遍历祖先链,包括该元素本身,如果它是一个表单
元素),如果有的话。(如果没有这样的表单
元素,则form
元素指针保持其初始值null。)
启动解析器,并让它运行,直到它消耗了所有刚刚插入输入流中的字符。
按树顺序返回root的子节点。
此表列出了HTML支持的字符引用名称及其对应的代码点。前面的章节中有引用。
为了兼容旧版,许多代码点有多个字符引用名称,这是有意为之的。例如,有些字符引用同时存在带有和不带尾部分号的形式,或以不同的大小写形式出现。
名称 | 字符 | 字形 |
---|---|---|
Aacute; |
U+000C1 | Á |
Aacute |
U+000C1 | Á |
aacute; |
U+000E1 | á |
aacute |
U+000E1 | á |
Abreve; |
U+00102 | Ă |
abreve; |
U+00103 | ă |
ac; |
U+0223E | ∾ |
acd; |
U+0223F | ∿ |
acE; |
U+0223E U+00333 | ∾̳ |
Acirc; |
U+000C2 | Â |
Acirc |
U+000C2 | Â |
acirc; |
U+000E2 | â |
acirc |
U+000E2 | â |
acute; |
U+000B4 | ´ |
acute |
U+000B4 | ´ |
Acy; |
U+00410 | А |
acy; |
U+00430 | а |
AElig; |
U+000C6 | Æ |
AElig |
U+000C6 | Æ |
aelig; |
U+000E6 | æ |
aelig |
U+000E6 | æ |
af; |
U+02061 | |
Afr; |
U+1D504 | 𝔄 |
afr; |
U+1D51E | 𝔞 |
Agrave; |
U+000C0 | À |
Agrave |
U+000C0 | À |
agrave; |
U+000E0 | à |
agrave |
U+000E0 | à |
alefsym; |
U+02135 | ℵ |
aleph; |
U+02135 | ℵ |
Alpha; |
U+00391 | Α |
alpha; |
U+003B1 | α |
Amacr; |
U+00100 | Ā |
amacr; |
U+00101 | ā |
amalg; |
U+02A3F | ⨿ |
AMP; |
U+00026 | & |
AMP |
U+00026 | & |
amp; |
U+00026 | & |
amp |
U+00026 | & |
And; |
U+02A53 | ⩓ |
and; |
U+02227 | ∧ |
andand; |
U+02A55 | ⩕ |
andd; |
U+02A5C | ⩜ |
andslope; |
U+02A58 | ⩘ |
andv; |
U+02A5A | ⩚ |
ang; |
U+02220 | ∠ |
ange; |
U+029A4 | ⦤ |
angle; |
U+02220 | ∠ |
angmsd; |
U+02221 | ∡ |
angmsdaa; |
U+029A8 | ⦨ |
angmsdab; |
U+029A9 | ⦩ |
angmsdac; |
U+029AA | ⦪ |
angmsdad; |
U+029AB | ⦫ |
angmsdae; |
U+029AC | ⦬ |
angmsdaf; |
U+029AD | ⦭ |
angmsdag; |
U+029AE | ⦮ |
angmsdah; |
U+029AF | ⦯ |
angrt; |
U+0221F | ∟ |
angrtvb; |
U+022BE | ⊾ |
angrtvbd; |
U+0299D | ⦝ |
angsph; |
U+02222 | ∢ |
angst; |
U+000C5 | Å |
angzarr; |
U+0237C | ⍼ |
Aogon; |
U+00104 | Ą |
aogon; |
U+00105 | ą |
Aopf; |
U+1D538 | 𝔸 |
aopf; |
U+1D552 | 𝕒 |
ap; |
U+02248 | ≈ |
apacir; |
U+02A6F | ⩯ |
apE; |
U+02A70 | ⩰ |
ape; |
U+0224A | ≊ |
apid; |
U+0224B | ≋ |
apos; |
U+00027 | ' |
ApplyFunction; |
U+02061 | |
approx; |
U+02248 | ≈ |
approxeq; |
U+0224A | ≊ |
Aring; |
U+000C5 | Å |
Aring |
U+000C5 | Å |
aring; |
U+000E5 | å |
aring |
U+000E5 | å |
Ascr; |
U+1D49C | 𝒜 |
ascr; |
U+1D4B6 | 𝒶 |
Assign; |
U+02254 | ≔ |
ast; |
U+0002A | * |
asymp; |
U+02248 | ≈ |
asympeq; |
U+0224D | ≍ |
Atilde; |
U+000C3 | Ã |
Atilde |
U+000C3 | Ã |
atilde; |
U+000E3 | ã |
atilde |
U+000E3 | ã |
Auml; |
U+000C4 | Ä |
Auml |
U+000C4 | Ä |
auml; |
U+000E4 | ä |
auml |
U+000E4 | ä |
awconint; |
U+02233 | ∳ |
awint; |
U+02A11 | ⨑ |
backcong; |
U+0224C | ≌ |
backepsilon; |
U+003F6 | ϶ |
backprime; |
U+02035 | ‵ |
backsim; |
U+0223D | ∽ |
backsimeq; |
U+022CD | ⋍ |
Backslash; |
U+02216 | ∖ |
Barv; |
U+02AE7 | ⫧ |
barvee; |
U+022BD | ⊽ |
Barwed; |
U+02306 | ⌆ |
barwed; |
U+02305 | ⌅ |
barwedge; |
U+02305 | ⌅ |
bbrk; |
U+023B5 | ⎵ |
bbrktbrk; |
U+023B6 | ⎶ |
bcong; |
U+0224C | ≌ |
Bcy; |
U+00411 | Б |
bcy; |
U+00431 | б |
bdquo; |
U+0201E | „ |
becaus; |
U+02235 | ∵ |
Because; |
U+02235 | ∵ |
because; |
U+02235 | ∵ |
bemptyv; |
U+029B0 | ⦰ |
bepsi; |
U+003F6 | ϶ |
bernou; |
U+0212C | ℬ |
Bernoullis; |
U+0212C | ℬ |
Beta; |
U+00392 | Β |
beta; |
U+003B2 | β |
beth; |
U+02136 | ℶ |
between; |
U+0226C | ≬ |
Bfr; |
U+1D505 | 𝔅 |
bfr; |
U+1D51F | 𝔟 |
bigcap; |
U+022C2 | ⋂ |
bigcirc; |
U+025EF | ◯ |
bigcup; |
U+022C3 | ⋃ |
bigodot; |
U+02A00 | ⨀ |
bigoplus; |
U+02A01 | ⨁ |
bigotimes; |
U+02A02 | ⨂ |
bigsqcup; |
U+02A06 | ⨆ |
bigstar; |
U+02605 | ★ |
bigtriangledown; |
U+025BD | ▽ |
bigtriangleup; |
U+025B3 | △ |
biguplus; |
U+02A04 | ⨄ |
bigvee; |
U+022C1 | ⋁ |
bigwedge; |
U+022C0 | ⋀ |
bkarow; |
U+0290D | ⤍ |
blacklozenge; |
U+029EB | ⧫ |
blacksquare; |
U+025AA | ▪ |
blacktriangle; |
U+025B4 | ▴ |
blacktriangledown; |
U+025BE | ▾ |
blacktriangleleft; |
U+025C2 | ◂ |
blacktriangleright; |
U+025B8 | ▸ |
blank; |
U+02423 | ␣ |
blk12; |
U+02592 | ▒ |
blk14; |
U+02591 | ░ |
blk34; |
U+02593 | ▓ |
block; |
U+02588 | █ |
bne; |
U+0003D U+020E5 | =⃥ |
bnequiv; |
U+02261 U+020E5 | ≡⃥ |
bNot; |
U+02AED | ⫭ |
bnot; |
U+02310 | ⌐ |
Bopf; |
U+1D539 | 𝔹 |
bopf; |
U+1D553 | 𝕓 |
bot; |
U+022A5 | ⊥ |
bottom; |
U+022A5 | ⊥ |
bowtie; |
U+022C8 | ⋈ |
boxbox; |
U+029C9 | ⧉ |
boxDL; |
U+02557 | ╗ |
boxDl; |
U+02556 | ╖ |
boxdL; |
U+02555 | ╕ |
boxdl; |
U+02510 | ┐ |
boxDR; |
U+02554 | ╔ |
boxDr; |
U+02553 | ╓ |
boxdR; |
U+02552 | ╒ |
boxdr; |
U+0250C | ┌ |
boxH; |
U+02550 | ═ |
boxh; |
U+02500 | ─ |
boxHD; |
U+02566 | ╦ |
boxHd; |
U+02564 | ╤ |
boxhD; |
U+02565 | ╥ |
boxhd; |
U+0252C | ┬ |
boxHU; |
U+02569 | ╩ |
boxHu; |
U+02567 | ╧ |
boxhU; |
U+02568 | ╨ |
boxhu; |
U+02534 | ┴ |
boxminus; |
U+0229F | ⊟ |
boxplus; |
U+0229E | ⊞ |
boxtimes; |
U+022A0 | ⊠ |
boxUL; |
U+0255D | ╝ |
boxUl; |
U+0255C | ╜ |
boxuL; |
U+0255B | ╛ |
boxul; |
U+02518 | ┘ |
boxUR; |
U+0255A | ╚ |
boxUr; |
U+02559 | ╙ |
boxuR; |
U+02558 | ╘ |
boxur; |
U+02514 | └ |
boxV; |
U+02551 | ║ |
boxv; |
U+02502 | │ |
boxVH; |
U+0256C | ╬ |
boxVh; |
U+0256B | ╫ |
boxvH; |
U+0256A | ╪ |
boxvh; |
U+0253C | ┼ |
boxVL; |
U+02563 | ╣ |
boxVl; |
U+02562 | ╢ |
boxvL; |
U+02561 | ╡ |
boxvl; |
U+02524 | ┤ |
boxVR; |
U+02560 | ╠ |
boxVr; |
U+0255F | ╟ |
boxvR; |
U+0255E | ╞ |
boxvr; |
U+0251C | ├ |
bprime; |
U+02035 | ‵ |
Breve; |
U+002D8 | ˘ |
breve; |
U+002D8 | ˘ |
brvbar; |
U+000A6 | ¦ |
brvbar |
U+000A6 | ¦ |
Bscr; |
U+0212C | ℬ |
bscr; |
U+1D4B7 | 𝒷 |
bsemi; |
U+0204F | ⁏ |
bsim; |
U+0223D | ∽ |
bsime; |
U+022CD | ⋍ |
bsol; |
U+0005C | \ |
bsolb; |
U+029C5 | ⧅ |
bsolhsub; |
U+027C8 | ⟈ |
bull; |
U+02022 | • |
bullet; |
U+02022 | • |
bump; |
U+0224E | ≎ |
bumpE; |
U+02AAE | ⪮ |
bumpe; |
U+0224F | ≏ |
Bumpeq; |
U+0224E | ≎ |
bumpeq; |
U+0224F | ≏ |
Cacute; |
U+00106 | Ć |
cacute; |
U+00107 | ć |
Cap; |
U+022D2 | ⋒ |
cap; |
U+02229 | ∩ |
capand; |
U+02A44 | ⩄ |
capbrcup; |
U+02A49 | ⩉ |
capcap; |
U+02A4B | ⩋ |
capcup; |
U+02A47 | ⩇ |
capdot; |
U+02A40 | ⩀ |
CapitalDifferentialD; |
U+02145 | ⅅ |
caps; |
U+02229 U+0FE00 | ∩︀ |
caret; |
U+02041 | ⁁ |
caron; |
U+002C7 | ˇ |
Cayleys; |
U+0212D | ℭ |
ccaps; |
U+02A4D | ⩍ |
Ccaron; |
U+0010C | Č |
ccaron; |
U+0010D | č |
Ccedil; |
U+000C7 | Ç |
Ccedil |
U+000C7 | Ç |
ccedil; |
U+000E7 | ç |
ccedil |
U+000E7 | ç |
Ccirc; |
U+00108 | Ĉ |
ccirc; |
U+00109 | ĉ |
Cconint; |
U+02230 | ∰ |
ccups; |
U+02A4C | ⩌ |
ccupssm; |
U+02A50 | ⩐ |
Cdot; |
U+0010A | Ċ |
cdot; |
U+0010B | ċ |
cedil; |
U+000B8 | ¸ |
cedil |
U+000B8 | ¸ |
Cedilla; |
U+000B8 | ¸ |
cemptyv; |
U+029B2 | ⦲ |
cent; |
U+000A2 | ¢ |
cent |
U+000A2 | ¢ |
CenterDot; |
U+000B7 | · |
centerdot; |
U+000B7 | · |
Cfr; |
U+0212D | ℭ |
cfr; |
U+1D520 | 𝔠 |
CHcy; |
U+00427 | Ч |
chcy; |
U+00447 | ч |
check; |
U+02713 | ✓ |
checkmark; |
U+02713 | ✓ |
Chi; |
U+003A7 | Χ |
chi; |
U+003C7 | χ |
cir; |
U+025CB | ○ |
circ; |
U+002C6 | ˆ |
circeq; |
U+02257 | ≗ |
circlearrowleft; |
U+021BA | ↺ |
circlearrowright; |
U+021BB | ↻ |
circledast; |
U+0229B | ⊛ |
circledcirc; |
U+0229A | ⊚ |
circleddash; |
U+0229D | ⊝ |
CircleDot; |
U+02299 | ⊙ |
circledR; |
U+000AE | ® |
circledS; |
U+024C8 | Ⓢ |
CircleMinus; |
U+02296 | ⊖ |
CirclePlus; |
U+02295 | ⊕ |
CircleTimes; |
U+02297 | ⊗ |
cirE; |
U+029C3 | ⧃ |
cire; |
U+02257 | ≗ |
cirfnint; |
U+02A10 | ⨐ |
cirmid; |
U+02AEF | ⫯ |
cirscir; |
U+029C2 | ⧂ |
ClockwiseContourIntegral; |
U+02232 | ∲ |
CloseCurlyDoubleQuote; |
U+0201D | ” |
CloseCurlyQuote; |
U+02019 | ’ |
clubs; |
U+02663 | ♣ |
clubsuit; |
U+02663 | ♣ |
Colon; |
U+02237 | ∷ |
colon; |
U+0003A | : |
Colone; |
U+02A74 | ⩴ |
colone; |
U+02254 | ≔ |
coloneq; |
U+02254 | ≔ |
comma; |
U+0002C | , |
commat; |
U+00040 | @ |
comp; |
U+02201 | ∁ |
compfn; |
U+02218 | ∘ |
complement; |
U+02201 | ∁ |
complexes; |
U+02102 | ℂ |
cong; |
U+02245 | ≅ |
congdot; |
U+02A6D | ⩭ |
Congruent; |
U+02261 | ≡ |
Conint; |
U+0222F | ∯ |
conint; |
U+0222E | ∮ |
ContourIntegral; |
U+0222E | ∮ |
Copf; |
U+02102 | ℂ |
copf; |
U+1D554 | 𝕔 |
coprod; |
U+02210 | ∐ |
Coproduct; |
U+02210 | ∐ |
COPY; |
U+000A9 | © |
COPY |
U+000A9 | © |
copy; |
U+000A9 | © |
copy |
U+000A9 | © |
copysr; |
U+02117 | ℗ |
CounterClockwiseContourIntegral; |
U+02233 | ∳ |
crarr; |
U+021B5 | ↵ |
Cross; |
U+02A2F | ⨯ |
cross; |
U+02717 | ✗ |
Cscr; |
U+1D49E | 𝒞 |
cscr; |
U+1D4B8 | 𝒸 |
csub; |
U+02ACF | ⫏ |
csube; |
U+02AD1 | ⫑ |
csup; |
U+02AD0 | ⫐ |
csupe; |
U+02AD2 | ⫒ |
ctdot; |
U+022EF | ⋯ |
cudarrl; |
U+02938 | ⤸ |
cudarrr; |
U+02935 | ⤵ |
cuepr; |
U+022DE | ⋞ |
cuesc; |
U+022DF | ⋟ |
cularr; |
U+021B6 | ↶ |
cularrp; |
U+0293D | ⤽ |
Cup; |
U+022D3 | ⋓ |
cup; |
U+0222A | ∪ |
cupbrcap; |
U+02A48 | ⩈ |
CupCap; |
U+0224D | ≍ |
cupcap; |
U+02A46 | ⩆ |
cupcup; |
U+02A4A | ⩊ |
cupdot; |
U+0228D | ⊍ |
cupor; |
U+02A45 | ⩅ |
cups; |
U+0222A U+0FE00 | ∪︀ |
curarr; |
U+021B7 | ↷ |
curarrm; |
U+0293C | ⤼ |
curlyeqprec; |
U+022DE | ⋞ |
curlyeqsucc; |
U+022DF | ⋟ |
curlyvee; |
U+022CE | ⋎ |
curlywedge; |
U+022CF | ⋏ |
curren; |
U+000A4 | ¤ |
curren |
U+000A4 | ¤ |
curvearrowleft; |
U+021B6 | ↶ |
curvearrowright; |
U+021B7 | ↷ |
cuvee; |
U+022CE | ⋎ |
cuwed; |
U+022CF | ⋏ |
cwconint; |
U+02232 | ∲ |
cwint; |
U+02231 | ∱ |
cylcty; |
U+0232D | ⌭ |
Dagger; |
U+02021 | ‡ |
dagger; |
U+02020 | † |
daleth; |
U+02138 | ℸ |
Darr; |
U+021A1 | ↡ |
dArr; |
U+021D3 | ⇓ |
darr; |
U+02193 | ↓ |
dash; |
U+02010 | ‐ |
Dashv; |
U+02AE4 | ⫤ |
dashv; |
U+022A3 | ⊣ |
dbkarow; |
U+0290F | ⤏ |
dblac; |
U+002DD | ˝ |
Dcaron; |
U+0010E | Ď |
dcaron; |
U+0010F | ď |
Dcy; |
U+00414 | Д |
dcy; |
U+00434 | д |
DD; |
U+02145 | ⅅ |
dd; |
U+02146 | ⅆ |
ddagger; |
U+02021 | ‡ |
ddarr; |
U+021CA | ⇊ |
DDotrahd; |
U+02911 | ⤑ |
ddotseq; |
U+02A77 | ⩷ |
deg; |
U+000B0 | ° |
deg |
U+000B0 | ° |
Del; |
U+02207 | ∇ |
Delta; |
U+00394 | Δ |
delta; |
U+003B4 | δ |
demptyv; |
U+029B1 | ⦱ |
dfisht; |
U+0297F | ⥿ |
Dfr; |
U+1D507 | 𝔇 |
dfr; |
U+1D521 | 𝔡 |
dHar; |
U+02965 | ⥥ |
dharl; |
U+021C3 | ⇃ |
dharr; |
U+021C2 | ⇂ |
DiacriticalAcute; |
U+000B4 | ´ |
DiacriticalDot; |
U+002D9 | ˙ |
DiacriticalDoubleAcute; |
U+002DD | ˝ |
DiacriticalGrave; |
U+00060 | ` |
DiacriticalTilde; |
U+002DC | ˜ |
diam; |
U+022C4 | ⋄ |
Diamond; |
U+022C4 | ⋄ |
diamond; |
U+022C4 | ⋄ |
diamondsuit; |
U+02666 | ♦ |
diams; |
U+02666 | ♦ |
die; |
U+000A8 | ¨ |
DifferentialD; |
U+02146 | ⅆ |
digamma; |
U+003DD | ϝ |
disin; |
U+022F2 | ⋲ |
div; |
U+000F7 | ÷ |
divide; |
U+000F7 | ÷ |
divide |
U+000F7 | ÷ |
divideontimes; |
U+022C7 | ⋇ |
divonx; |
U+022C7 | ⋇ |
DJcy; |
U+00402 | Ђ |
djcy; |
U+00452 | ђ |
dlcorn; |
U+0231E | ⌞ |
dlcrop; |
U+0230D | ⌍ |
dollar; |
U+00024 | $ |
Dopf; |
U+1D53B | 𝔻 |
dopf; |
U+1D555 | 𝕕 |
Dot; |
U+000A8 | ¨ |
dot; |
U+002D9 | ˙ |
DotDot; |
U+020DC | ◌⃜ |
doteq; |
U+02250 | ≐ |
doteqdot; |
U+02251 | ≑ |
DotEqual; |
U+02250 | ≐ |
dotminus; |
U+02238 | ∸ |
dotplus; |
U+02214 | ∔ |
dotsquare; |
U+022A1 | ⊡ |
doublebarwedge; |
U+02306 | ⌆ |
DoubleContourIntegral; |
U+0222F | ∯ |
DoubleDot; |
U+000A8 | ¨ |
DoubleDownArrow; |
U+021D3 | ⇓ |
DoubleLeftArrow; |
U+021D0 | ⇐ |
DoubleLeftRightArrow; |
U+021D4 | ⇔ |
DoubleLeftTee; |
U+02AE4 | ⫤ |
DoubleLongLeftArrow; |
U+027F8 | ⟸ |
DoubleLongLeftRightArrow; |
U+027FA | ⟺ |
DoubleLongRightArrow; |
U+027F9 | ⟹ |
DoubleRightArrow; |
U+021D2 | ⇒ |
DoubleRightTee; |
U+022A8 | ⊨ |
DoubleUpArrow; |
U+021D1 | ⇑ |
DoubleUpDownArrow; |
U+021D5 | ⇕ |
DoubleVerticalBar; |
U+02225 | ∥ |
DownArrow; |
U+02193 | ↓ |
Downarrow; |
U+021D3 | ⇓ |
downarrow; |
U+02193 | ↓ |
DownArrowBar; |
U+02913 | ⤓ |
DownArrowUpArrow; |
U+021F5 | ⇵ |
DownBreve; |
U+00311 | ◌̑ |
downdownarrows; |
U+021CA | ⇊ |
downharpoonleft; |
U+021C3 | ⇃ |
downharpoonright; |
U+021C2 | ⇂ |
DownLeftRightVector; |
U+02950 | ⥐ |
DownLeftTeeVector; |
U+0295E | ⥞ |
DownLeftVector; |
U+021BD | ↽ |
DownLeftVectorBar; |
U+02956 | ⥖ |
DownRightTeeVector; |
U+0295F | ⥟ |
DownRightVector; |
U+021C1 | ⇁ |
DownRightVectorBar; |
U+02957 | ⥗ |
DownTee; |
U+022A4 | ⊤ |
DownTeeArrow; |
U+021A7 | ↧ |
drbkarow; |
U+02910 | ⤐ |
drcorn; |
U+0231F | ⌟ |
drcrop; |
U+0230C | ⌌ |
Dscr; |
U+1D49F | 𝒟 |
dscr; |
U+1D4B9 | 𝒹 |
DScy; |
U+00405 | Ѕ |
dscy; |
U+00455 | ѕ |
dsol; |
U+029F6 | ⧶ |
Dstrok; |
U+00110 | Đ |
dstrok; |
U+00111 | đ |
dtdot; |
U+022F1 | ⋱ |
dtri; |
U+025BF | ▿ |
dtrif; |
U+025BE | ▾ |
duarr; |
U+021F5 | ⇵ |
duhar; |
U+0296F | ⥯ |
dwangle; |
U+029A6 | ⦦ |
DZcy; |
U+0040F | Џ |
dzcy; |
U+0045F | џ |
dzigrarr; |
U+027FF | ⟿ |
Eacute; |
U+000C9 | É |
Eacute |
U+000C9 | É |
eacute; |
U+000E9 | é |
eacute |
U+000E9 | é |
easter; |
U+02A6E | ⩮ |
Ecaron; |
U+0011A | Ě |
ecaron; |
U+0011B | ě |
ecir; |
U+02256 | ≖ |
Ecirc; |
U+000CA | Ê |
Ecirc |
U+000CA | Ê |
ecirc; |
U+000EA | ê |
ecirc |
U+000EA | ê |
ecolon; |
U+02255 | ≕ |
Ecy; |
U+0042D | Э |
ecy; |
U+0044D | э |
eDDot; |
U+02A77 | ⩷ |
Edot; |
U+00116 | Ė |
eDot; |
U+02251 | ≑ |
edot; |
U+00117 | ė |
ee; |
U+02147 | ⅇ |
efDot; |
U+02252 | ≒ |
Efr; |
U+1D508 | 𝔈 |
efr; |
U+1D522 | 𝔢 |
eg; |
U+02A9A | ⪚ |
Egrave; |
U+000C8 | È |
Egrave |
U+000C8 | È |
egrave; |
U+000E8 | è |
egrave |
U+000E8 | è |
egs; |
U+02A96 | ⪖ |
egsdot; |
U+02A98 | ⪘ |
el; |
U+02A99 | ⪙ |
Element; |
U+02208 | ∈ |
elinters; |
U+023E7 | ⏧ |
ell; |
U+02113 | ℓ |
els; |
U+02A95 | ⪕ |
elsdot; |
U+02A97 | ⪗ |
Emacr; |
U+00112 | Ē |
emacr; |
U+00113 | ē |
empty; |
U+02205 | ∅ |
emptyset; |
U+02205 | ∅ |
EmptySmallSquare; |
U+025FB | ◻ |
emptyv; |
U+02205 | ∅ |
EmptyVerySmallSquare; |
U+025AB | ▫ |
emsp; |
U+02003 | |
emsp13; |
U+02004 | |
emsp14; |
U+02005 | |
ENG; |
U+0014A | Ŋ |
eng; |
U+0014B | ŋ |
ensp; |
U+02002 | |
Eogon; |
U+00118 | Ę |
eogon; |
U+00119 | ę |
Eopf; |
U+1D53C | 𝔼 |
eopf; |
U+1D556 | 𝕖 |
epar; |
U+022D5 | ⋕ |
eparsl; |
U+029E3 | ⧣ |
eplus; |
U+02A71 | ⩱ |
epsi; |
U+003B5 | ε |
Epsilon; |
U+00395 | Ε |
epsilon; |
U+003B5 | ε |
epsiv; |
U+003F5 | ϵ |
eqcirc; |
U+02256 | ≖ |
eqcolon; |
U+02255 | ≕ |
eqsim; |
U+02242 | ≂ |
eqslantgtr; |
U+02A96 | ⪖ |
eqslantless; |
U+02A95 | ⪕ |
Equal; |
U+02A75 | ⩵ |
equals; |
U+0003D | = |
EqualTilde; |
U+02242 | ≂ |
equest; |
U+0225F | ≟ |
Equilibrium; |
U+021CC | ⇌ |
equiv; |
U+02261 | ≡ |
equivDD; |
U+02A78 | ⩸ |
eqvparsl; |
U+029E5 | ⧥ |
erarr; |
U+02971 | ⥱ |
erDot; |
U+02253 | ≓ |
Escr; |
U+02130 | ℰ |
escr; |
U+0212F | ℯ |
esdot; |
U+02250 | ≐ |
Esim; |
U+02A73 | ⩳ |
esim; |
U+02242 | ≂ |
Eta; |
U+00397 | Η |
eta; |
U+003B7 | η |
ETH; |
U+000D0 | Ð |
ETH |
U+000D0 | Ð |
eth; |
U+000F0 | ð |
eth |
U+000F0 | ð |
Euml; |
U+000CB | Ë |
Euml |
U+000CB | Ë |
euml; |
U+000EB | ë |
euml |
U+000EB | ë |
euro; |
U+020AC | € |
excl; |
U+00021 | ! |
exist; |
U+02203 | ∃ |
Exists; |
U+02203 | ∃ |
expectation; |
U+02130 | ℰ |
ExponentialE; |
U+02147 | ⅇ |
exponentiale; |
U+02147 | ⅇ |
fallingdotseq; |
U+02252 | ≒ |
Fcy; |
U+00424 | Ф |
fcy; |
U+00444 | ф |
female; |
U+02640 | ♀ |
ffilig; |
U+0FB03 | ffi |
fflig; |
U+0FB00 | ff |
ffllig; |
U+0FB04 | ffl |
Ffr; |
U+1D509 | 𝔉 |
ffr; |
U+1D523 | 𝔣 |
filig; |
U+0FB01 | fi |
FilledSmallSquare; |
U+025FC | ◼ |
FilledVerySmallSquare; |
U+025AA | ▪ |
fjlig; |
U+00066 U+0006A | fj |
flat; |
U+0266D | ♭ |
fllig; |
U+0FB02 | fl |
fltns; |
U+025B1 | ▱ |
fnof; |
U+00192 | ƒ |
Fopf; |
U+1D53D | 𝔽 |
fopf; |
U+1D557 | 𝕗 |
ForAll; |
U+02200 | ∀ |
forall; |
U+02200 | ∀ |
fork; |
U+022D4 | ⋔ |
forkv; |
U+02AD9 | ⫙ |
Fouriertrf; |
U+02131 | ℱ |
fpartint; |
U+02A0D | ⨍ |
frac12; |
U+000BD | ½ |
frac12 |
U+000BD | ½ |
frac13; |
U+02153 | ⅓ |
frac14; |
U+000BC | ¼ |
frac14 |
U+000BC | ¼ |
frac15; |
U+02155 | ⅕ |
frac16; |
U+02159 | ⅙ |
frac18; |
U+0215B | ⅛ |
frac23; |
U+02154 | ⅔ |
frac25; |
U+02156 | ⅖ |
frac34; |
U+000BE | ¾ |
frac34 |
U+000BE | ¾ |
frac35; |
U+02157 | ⅗ |
frac38; |
U+0215C | ⅜ |
frac45; |
U+02158 | ⅘ |
frac56; |
U+0215A | ⅚ |
frac58; |
U+0215D | ⅝ |
frac78; |
U+0215E | ⅞ |
frasl; |
U+02044 | ⁄ |
frown; |
U+02322 | ⌢ |
Fscr; |
U+02131 | ℱ |
fscr; |
U+1D4BB | 𝒻 |
gacute; |
U+001F5 | ǵ |
Gamma; |
U+00393 | Γ |
gamma; |
U+003B3 | γ |
Gammad; |
U+003DC | Ϝ |
gammad; |
U+003DD | ϝ |
gap; |
U+02A86 | ⪆ |
Gbreve; |
U+0011E | Ğ |
gbreve; |
U+0011F | ğ |
Gcedil; |
U+00122 | Ģ |
Gcirc; |
U+0011C | Ĝ |
gcirc; |
U+0011D | ĝ |
Gcy; |
U+00413 | Г |
gcy; |
U+00433 | г |
Gdot; |
U+00120 | Ġ |
gdot; |
U+00121 | ġ |
gE; |
U+02267 | ≧ |
ge; |
U+02265 | ≥ |
gEl; |
U+02A8C | ⪌ |
gel; |
U+022DB | ⋛ |
geq; |
U+02265 | ≥ |
geqq; |
U+02267 | ≧ |
geqslant; |
U+02A7E | ⩾ |
ges; |
U+02A7E | ⩾ |
gescc; |
U+02AA9 | ⪩ |
gesdot; |
U+02A80 | ⪀ |
gesdoto; |
U+02A82 | ⪂ |
gesdotol; |
U+02A84 | ⪄ |
gesl; |
U+022DB U+0FE00 | ⋛︀ |
gesles; |
U+02A94 | ⪔ |
Gfr; |
U+1D50A | 𝔊 |
gfr; |
U+1D524 | 𝔤 |
Gg; |
U+022D9 | ⋙ |
gg; |
U+0226B | ≫ |
ggg; |
U+022D9 | ⋙ |
gimel; |
U+02137 | ℷ |
GJcy; |
U+00403 | Ѓ |
gjcy; |
U+00453 | ѓ |
gl; |
U+02277 | ≷ |
gla; |
U+02AA5 | ⪥ |
glE; |
U+02A92 | ⪒ |
glj; |
U+02AA4 | ⪤ |
gnap; |
U+02A8A | ⪊ |
gnapprox; |
U+02A8A | ⪊ |
gnE; |
U+02269 | ≩ |
gne; |
U+02A88 | ⪈ |
gneq; |
U+02A88 | ⪈ |
gneqq; |
U+02269 | ≩ |
gnsim; |
U+022E7 | ⋧ |
Gopf; |
U+1D53E | 𝔾 |
gopf; |
U+1D558 | 𝕘 |
grave; |
U+00060 | ` |
GreaterEqual; |
U+02265 | ≥ |
GreaterEqualLess; |
U+022DB | ⋛ |
GreaterFullEqual; |
U+02267 | ≧ |
GreaterGreater; |
U+02AA2 | ⪢ |
GreaterLess; |
U+02277 | ≷ |
GreaterSlantEqual; |
U+02A7E | ⩾ |
GreaterTilde; |
U+02273 | ≳ |
Gscr; |
U+1D4A2 | 𝒢 |
gscr; |
U+0210A | ℊ |
gsim; |
U+02273 | ≳ |
gsime; |
U+02A8E | ⪎ |
gsiml; |
U+02A90 | ⪐ |
GT; |
U+0003E | > |
GT |
U+0003E | > |
Gt; |
U+0226B | ≫ |
gt; |
U+0003E | > |
gt |
U+0003E | > |
gtcc; |
U+02AA7 | ⪧ |
gtcir; |
U+02A7A | ⩺ |
gtdot; |
U+022D7 | ⋗ |
gtlPar; |
U+02995 | ⦕ |
gtquest; |
U+02A7C | ⩼ |
gtrapprox; |
U+02A86 | ⪆ |
gtrarr; |
U+02978 | ⥸ |
gtrdot; |
U+022D7 | ⋗ |
gtreqless; |
U+022DB | ⋛ |
gtreqqless; |
U+02A8C | ⪌ |
gtrless; |
U+02277 | ≷ |
gtrsim; |
U+02273 | ≳ |
gvertneqq; |
U+02269 U+0FE00 | ≩︀ |
gvnE; |
U+02269 U+0FE00 | ≩︀ |
Hacek; |
U+002C7 | ˇ |
hairsp; |
U+0200A | |
half; |
U+000BD | ½ |
hamilt; |
U+0210B | ℋ |
HARDcy; |
U+0042A | Ъ |
hardcy; |
U+0044A | ъ |
hArr; |
U+021D4 | ⇔ |
harr; |
U+02194 | ↔ |
harrcir; |
U+02948 | ⥈ |
harrw; |
U+021AD | ↭ |
Hat; |
U+0005E | ^ |
hbar; |
U+0210F | ℏ |
Hcirc; |
U+00124 | Ĥ |
hcirc; |
U+00125 | ĥ |
hearts; |
U+02665 | ♥ |
heartsuit; |
U+02665 | ♥ |
hellip; |
U+02026 | … |
hercon; |
U+022B9 | ⊹ |
Hfr; |
U+0210C | ℌ |
hfr; |
U+1D525 | 𝔥 |
HilbertSpace; |
U+0210B | ℋ |
hksearow; |
U+02925 | ⤥ |
hkswarow; |
U+02926 | ⤦ |
hoarr; |
U+021FF | ⇿ |
homtht; |
U+0223B | ∻ |
hookleftarrow; |
U+021A9 | ↩ |
hookrightarrow; |
U+021AA | ↪ |
Hopf; |
U+0210D | ℍ |
hopf; |
U+1D559 | 𝕙 |
horbar; |
U+02015 | ― |
HorizontalLine; |
U+02500 | ─ |
Hscr; |
U+0210B | ℋ |
hscr; |
U+1D4BD | 𝒽 |
hslash; |
U+0210F | ℏ |
Hstrok; |
U+00126 | Ħ |
hstrok; |
U+00127 | ħ |
HumpDownHump; |
U+0224E | ≎ |
HumpEqual; |
U+0224F | ≏ |
hybull; |
U+02043 | ⁃ |
hyphen; |
U+02010 | ‐ |
Iacute; |
U+000CD | Í |
Iacute |
U+000CD | Í |
iacute; |
U+000ED | í |
iacute |
U+000ED | í |
ic; |
U+02063 | |
Icirc; |
U+000CE | Î |
Icirc |
U+000CE | Î |
icirc; |
U+000EE | î |
icirc |
U+000EE | î |
Icy; |
U+00418 | И |
icy; |
U+00438 | и |
Idot; |
U+00130 | İ |
IEcy; |
U+00415 | Е |
iecy; |
U+00435 | е |
iexcl; |
U+000A1 | ¡ |
iexcl |
U+000A1 | ¡ |
iff; |
U+021D4 | ⇔ |
Ifr; |
U+02111 | ℑ |
ifr; |
U+1D526 | 𝔦 |
Igrave; |
U+000CC | Ì |
Igrave |
U+000CC | Ì |
igrave; |
U+000EC | ì |
igrave |
U+000EC | ì |
ii; |
U+02148 | ⅈ |
iiiint; |
U+02A0C | ⨌ |
iiint; |
U+0222D | ∭ |
iinfin; |
U+029DC | ⧜ |
iiota; |
U+02129 | ℩ |
IJlig; |
U+00132 | IJ |
ijlig; |
U+00133 | ij |
Im; |
U+02111 | ℑ |
Imacr; |
U+0012A | Ī |
imacr; |
U+0012B | ī |
image; |
U+02111 | ℑ |
ImaginaryI; |
U+02148 | ⅈ |
imagline; |
U+02110 | ℐ |
imagpart; |
U+02111 | ℑ |
imath; |
U+00131 | ı |
imof; |
U+022B7 | ⊷ |
imped; |
U+001B5 | Ƶ |
Implies; |
U+021D2 | ⇒ |
in; |
U+02208 | ∈ |
incare; |
U+02105 | ℅ |
infin; |
U+0221E | ∞ |
infintie; |
U+029DD | ⧝ |
inodot; |
U+00131 | ı |
Int; |
U+0222C | ∬ |
int; |
U+0222B | ∫ |
intcal; |
U+022BA | ⊺ |
integers; |
U+02124 | ℤ |
Integral; |
U+0222B | ∫ |
intercal; |
U+022BA | ⊺ |
Intersection; |
U+022C2 | ⋂ |
intlarhk; |
U+02A17 | ⨗ |
intprod; |
U+02A3C | ⨼ |
InvisibleComma; |
U+02063 | |
InvisibleTimes; |
U+02062 | |
IOcy; |
U+00401 | Ё |
iocy; |
U+00451 | ё |
Iogon; |
U+0012E | Į |
iogon; |
U+0012F | į |
Iopf; |
U+1D540 | 𝕀 |
iopf; |
U+1D55A | 𝕚 |
Iota; |
U+00399 | Ι |
iota; |
U+003B9 | ι |
iprod; |
U+02A3C | ⨼ |
iquest; |
U+000BF | ¿ |
iquest |
U+000BF | ¿ |
Iscr; |
U+02110 | ℐ |
iscr; |
U+1D4BE | 𝒾 |
isin; |
U+02208 | ∈ |
isindot; |
U+022F5 | ⋵ |
isinE; |
U+022F9 | ⋹ |
isins; |
U+022F4 | ⋴ |
isinsv; |
U+022F3 | ⋳ |
isinv; |
U+02208 | ∈ |
it; |
U+02062 | |
Itilde; |
U+00128 | Ĩ |
itilde; |
U+00129 | ĩ |
Iukcy; |
U+00406 | І |
iukcy; |
U+00456 | і |
Iuml; |
U+000CF | Ï |
Iuml |
U+000CF | Ï |
iuml; |
U+000EF | ï |
iuml |
U+000EF | ï |
Jcirc; |
U+00134 | Ĵ |
jcirc; |
U+00135 | ĵ |
Jcy; |
U+00419 | Й |
jcy; |
U+00439 | й |
Jfr; |
U+1D50D | 𝔍 |
jfr; |
U+1D527 | 𝔧 |
jmath; |
U+00237 | ȷ |
Jopf; |
U+1D541 | 𝕁 |
jopf; |
U+1D55B | 𝕛 |
Jscr; |
U+1D4A5 | 𝒥 |
jscr; |
U+1D4BF | 𝒿 |
Jsercy; |
U+00408 | Ј |
jsercy; |
U+00458 | ј |
Jukcy; |
U+00404 | Є |
jukcy; |
U+00454 | є |
Kappa; |
U+0039A | Κ |
kappa; |
U+003BA | κ |
kappav; |
U+003F0 | ϰ |
Kcedil; |
U+00136 | Ķ |
kcedil; |
U+00137 | ķ |
Kcy; |
U+0041A | К |
kcy; |
U+0043A | к |
Kfr; |
U+1D50E | 𝔎 |
kfr; |
U+1D528 | 𝔨 |
kgreen; |
U+00138 | ĸ |
KHcy; |
U+00425 | Х |
khcy; |
U+00445 | х |
KJcy; |
U+0040C | Ќ |
kjcy; |
U+0045C | ќ |
Kopf; |
U+1D542 | 𝕂 |
kopf; |
U+1D55C | 𝕜 |
Kscr; |
U+1D4A6 | 𝒦 |
kscr; |
U+1D4C0 | 𝓀 |
lAarr; |
U+021DA | ⇚ |
Lacute; |
U+00139 | Ĺ |
lacute; |
U+0013A | ĺ |
laemptyv; |
U+029B4 | ⦴ |
lagran; |
U+02112 | ℒ |
Lambda; |
U+0039B | Λ |
lambda; |
U+003BB | λ |
Lang; |
U+027EA | ⟪ |
lang; |
U+027E8 | ⟨ |
langd; |
U+02991 | ⦑ |
langle; |
U+027E8 | ⟨ |
lap; |
U+02A85 | ⪅ |
Laplacetrf; |
U+02112 | ℒ |
laquo; |
U+000AB | « |
laquo |
U+000AB | « |
Larr; |
U+0219E | ↞ |
lArr; |
U+021D0 | ⇐ |
larr; |
U+02190 | ← |
larrb; |
U+021E4 | ⇤ |
larrbfs; |
U+0291F | ⤟ |
larrfs; |
U+0291D | ⤝ |
larrhk; |
U+021A9 | ↩ |
larrlp; |
U+021AB | ↫ |
larrpl; |
U+02939 | ⤹ |
larrsim; |
U+02973 | ⥳ |
larrtl; |
U+021A2 | ↢ |
lat; |
U+02AAB | ⪫ |
lAtail; |
U+0291B | ⤛ |
latail; |
U+02919 | ⤙ |
late; |
U+02AAD | ⪭ |
lates; |
U+02AAD U+0FE00 | ⪭︀ |
lBarr; |
U+0290E | ⤎ |
lbarr; |
U+0290C | ⤌ |
lbbrk; |
U+02772 | ❲ |
lbrace; |
U+0007B | { |
lbrack; |
U+0005B | [ |
lbrke; |
U+0298B | ⦋ |
lbrksld; |
U+0298F | ⦏ |
lbrkslu; |
U+0298D | ⦍ |
Lcaron; |
U+0013D | Ľ |
lcaron; |
U+0013E | ľ |
Lcedil; |
U+0013B | Ļ |
lcedil; |
U+0013C | ļ |
lceil; |
U+02308 | ⌈ |
lcub; |
U+0007B | { |
Lcy; |
U+0041B | Л |
lcy; |
U+0043B | л |
ldca; |
U+02936 | ⤶ |
ldquo; |
U+0201C | “ |
ldquor; |
U+0201E | „ |
ldrdhar; |
U+02967 | ⥧ |
ldrushar; |
U+0294B | ⥋ |
ldsh; |
U+021B2 | ↲ |
lE; |
U+02266 | ≦ |
le; |
U+02264 | ≤ |
LeftAngleBracket; |
U+027E8 | ⟨ |
LeftArrow; |
U+02190 | ← |
Leftarrow; |
U+021D0 | ⇐ |
leftarrow; |
U+02190 | ← |
LeftArrowBar; |
U+021E4 | ⇤ |
LeftArrowRightArrow; |
U+021C6 | ⇆ |
leftarrowtail; |
U+021A2 | ↢ |
LeftCeiling; |
U+02308 | ⌈ |
LeftDoubleBracket; |
U+027E6 | ⟦ |
LeftDownTeeVector; |
U+02961 | ⥡ |
LeftDownVector; |
U+021C3 | ⇃ |
LeftDownVectorBar; |
U+02959 | ⥙ |
LeftFloor; |
U+0230A | ⌊ |
leftharpoondown; |
U+021BD | ↽ |
leftharpoonup; |
U+021BC | ↼ |
leftleftarrows; |
U+021C7 | ⇇ |
LeftRightArrow; |
U+02194 | ↔ |
Leftrightarrow; |
U+021D4 | ⇔ |
leftrightarrow; |
U+02194 | ↔ |
leftrightarrows; |
U+021C6 | ⇆ |
leftrightharpoons; |
U+021CB | ⇋ |
leftrightsquigarrow; |
U+021AD | ↭ |
LeftRightVector; |
U+0294E | ⥎ |
LeftTee; |
U+022A3 | ⊣ |
LeftTeeArrow; |
U+021A4 | ↤ |
LeftTeeVector; |
U+0295A | ⥚ |
leftthreetimes; |
U+022CB | ⋋ |
LeftTriangle; |
U+022B2 | ⊲ |
LeftTriangleBar; |
U+029CF | ⧏ |
LeftTriangleEqual; |
U+022B4 | ⊴ |
LeftUpDownVector; |
U+02951 | ⥑ |
LeftUpTeeVector; |
U+02960 | ⥠ |
LeftUpVector; |
U+021BF | ↿ |
LeftUpVectorBar; |
U+02958 | ⥘ |
LeftVector; |
U+021BC | ↼ |
LeftVectorBar; |
U+02952 | ⥒ |
lEg; |
U+02A8B | ⪋ |
leg; |
U+022DA | ⋚ |
leq; |
U+02264 | ≤ |
leqq; |
U+02266 | ≦ |
leqslant; |
U+02A7D | ⩽ |
les; |
U+02A7D | ⩽ |
lescc; |
U+02AA8 | ⪨ |
lesdot; |
U+02A7F | ⩿ |
lesdoto; |
U+02A81 | ⪁ |
lesdotor; |
U+02A83 | ⪃ |
lesg; |
U+022DA U+0FE00 | ⋚︀ |
lesges; |
U+02A93 | ⪓ |
lessapprox; |
U+02A85 | ⪅ |
lessdot; |
U+022D6 | ⋖ |
lesseqgtr; |
U+022DA | ⋚ |
lesseqqgtr; |
U+02A8B | ⪋ |
LessEqualGreater; |
U+022DA | ⋚ |
LessFullEqual; |
U+02266 | ≦ |
LessGreater; |
U+02276 | ≶ |
lessgtr; |
U+02276 | ≶ |
LessLess; |
U+02AA1 | ⪡ |
lesssim; |
U+02272 | ≲ |
LessSlantEqual; |
U+02A7D | ⩽ |
LessTilde; |
U+02272 | ≲ |
lfisht; |
U+0297C | ⥼ |
lfloor; |
U+0230A | ⌊ |
Lfr; |
U+1D50F | 𝔏 |
lfr; |
U+1D529 | 𝔩 |
lg; |
U+02276 | ≶ |
lgE; |
U+02A91 | ⪑ |
lHar; |
U+02962 | ⥢ |
lhard; |
U+021BD | ↽ |
lharu; |
U+021BC | ↼ |
lharul; |
U+0296A | ⥪ |
lhblk; |
U+02584 | ▄ |
LJcy; |
U+00409 | Љ |
ljcy; |
U+00459 | љ |
Ll; |
U+022D8 | ⋘ |
ll; |
U+0226A | ≪ |
llarr; |
U+021C7 | ⇇ |
llcorner; |
U+0231E | ⌞ |
Lleftarrow; |
U+021DA | ⇚ |
llhard; |
U+0296B | ⥫ |
lltri; |
U+025FA | ◺ |
Lmidot; |
U+0013F | Ŀ |
lmidot; |
U+00140 | ŀ |
lmoust; |
U+023B0 | ⎰ |
lmoustache; |
U+023B0 | ⎰ |
lnap; |
U+02A89 | ⪉ |
lnapprox; |
U+02A89 | ⪉ |
lnE; |
U+02268 | ≨ |
lne; |
U+02A87 | ⪇ |
lneq; |
U+02A87 | ⪇ |
lneqq; |
U+02268 | ≨ |
lnsim; |
U+022E6 | ⋦ |
loang; |
U+027EC | ⟬ |
loarr; |
U+021FD | ⇽ |
lobrk; |
U+027E6 | ⟦ |
LongLeftArrow; |
U+027F5 | ⟵ |
Longleftarrow; |
U+027F8 | ⟸ |
longleftarrow; |
U+027F5 | ⟵ |
LongLeftRightArrow; |
U+027F7 | ⟷ |
Longleftrightarrow; |
U+027FA | ⟺ |
longleftrightarrow; |
U+027F7 | ⟷ |
longmapsto; |
U+027FC | ⟼ |
LongRightArrow; |
U+027F6 | ⟶ |
Longrightarrow; |
U+027F9 | ⟹ |
longrightarrow; |
U+027F6 | ⟶ |
looparrowleft; |
U+021AB | ↫ |
looparrowright; |
U+021AC | ↬ |
lopar; |
U+02985 | ⦅ |
Lopf; |
U+1D543 | 𝕃 |
lopf; |
U+1D55D | 𝕝 |
loplus; |
U+02A2D | ⨭ |
lotimes; |
U+02A34 | ⨴ |
lowast; |
U+02217 | ∗ |
lowbar; |
U+0005F | _ |
LowerLeftArrow; |
U+02199 | ↙ |
LowerRightArrow; |
U+02198 | ↘ |
loz; |
U+025CA | ◊ |
lozenge; |
U+025CA | ◊ |
lozf; |
U+029EB | ⧫ |
lpar; |
U+00028 | ( |
lparlt; |
U+02993 | ⦓ |
lrarr; |
U+021C6 | ⇆ |
lrcorner; |
U+0231F | ⌟ |
lrhar; |
U+021CB | ⇋ |
lrhard; |
U+0296D | ⥭ |
lrm; |
U+0200E | |
lrtri; |
U+022BF | ⊿ |
lsaquo; |
U+02039 | ‹ |
Lscr; |
U+02112 | ℒ |
lscr; |
U+1D4C1 | 𝓁 |
Lsh; |
U+021B0 | ↰ |
lsh; |
U+021B0 | ↰ |
lsim; |
U+02272 | ≲ |
lsime; |
U+02A8D | ⪍ |
lsimg; |
U+02A8F | ⪏ |
lsqb; |
U+0005B | [ |
lsquo; |
U+02018 | ‘ |
lsquor; |
U+0201A | ‚ |
Lstrok; |
U+00141 | Ł |
lstrok; |
U+00142 | ł |
LT; |
U+0003C | < |
LT |
U+0003C | < |
Lt; |
U+0226A | ≪ |
lt; |
U+0003C | < |
lt |
U+0003C | < |
ltcc; |
U+02AA6 | ⪦ |
ltcir; |
U+02A79 | ⩹ |
ltdot; |
U+022D6 | ⋖ |
lthree; |
U+022CB | ⋋ |
ltimes; |
U+022C9 | ⋉ |
ltlarr; |
U+02976 | ⥶ |
ltquest; |
U+02A7B | ⩻ |
ltri; |
U+025C3 | ◃ |
ltrie; |
U+022B4 | ⊴ |
ltrif; |
U+025C2 | ◂ |
ltrPar; |
U+02996 | ⦖ |
lurdshar; |
U+0294A | ⥊ |
luruhar; |
U+02966 | ⥦ |
lvertneqq; |
U+02268 U+0FE00 | ≨︀ |
lvnE; |
U+02268 U+0FE00 | ≨︀ |
macr; |
U+000AF | ¯ |
macr |
U+000AF | ¯ |
male; |
U+02642 | ♂ |
malt; |
U+02720 | ✠ |
maltese; |
U+02720 | ✠ |
Map; |
U+02905 | ⤅ |
map; |
U+021A6 | ↦ |
mapsto; |
U+021A6 | ↦ |
mapstodown; |
U+021A7 | ↧ |
mapstoleft; |
U+021A4 | ↤ |
mapstoup; |
U+021A5 | ↥ |
marker; |
U+025AE | ▮ |
mcomma; |
U+02A29 | ⨩ |
Mcy; |
U+0041C | М |
mcy; |
U+0043C | м |
mdash; |
U+02014 | — |
mDDot; |
U+0223A | ∺ |
measuredangle; |
U+02221 | ∡ |
MediumSpace; |
U+0205F | |
Mellintrf; |
U+02133 | ℳ |
Mfr; |
U+1D510 | 𝔐 |
mfr; |
U+1D52A | 𝔪 |
mho; |
U+02127 | ℧ |
micro; |
U+000B5 | µ |
micro |
U+000B5 | µ |
mid; |
U+02223 | ∣ |
midast; |
U+0002A | * |
midcir; |
U+02AF0 | ⫰ |
middot; |
U+000B7 | · |
middot |
U+000B7 | · |
minus; |
U+02212 | − |
minusb; |
U+0229F | ⊟ |
minusd; |
U+02238 | ∸ |
minusdu; |
U+02A2A | ⨪ |
MinusPlus; |
U+02213 | ∓ |
mlcp; |
U+02ADB | ⫛ |
mldr; |
U+02026 | … |
mnplus; |
U+02213 | ∓ |
models; |
U+022A7 | ⊧ |
Mopf; |
U+1D544 | 𝕄 |
mopf; |
U+1D55E | 𝕞 |
mp; |
U+02213 | ∓ |
Mscr; |
U+02133 | ℳ |
mscr; |
U+1D4C2 | 𝓂 |
mstpos; |
U+0223E | ∾ |
Mu; |
U+0039C | Μ |
mu; |
U+003BC | μ |
multimap; |
U+022B8 | ⊸ |
mumap; |
U+022B8 | ⊸ |
nabla; |
U+02207 | ∇ |
Nacute; |
U+00143 | Ń |
nacute; |
U+00144 | ń |
nang; |
U+02220 U+020D2 | ∠⃒ |
nap; |
U+02249 | ≉ |
napE; |
U+02A70 U+00338 | ⩰̸ |
napid; |
U+0224B U+00338 | ≋̸ |
napos; |
U+00149 | ʼn |
napprox; |
U+02249 | ≉ |
natur; |
U+0266E | ♮ |
natural; |
U+0266E | ♮ |
naturals; |
U+02115 | ℕ |
nbsp; |
U+000A0 | |
nbsp |
U+000A0 | |
nbump; |
U+0224E U+00338 | ≎̸ |
nbumpe; |
U+0224F U+00338 | ≏̸ |
ncap; |
U+02A43 | ⩃ |
Ncaron; |
U+00147 | Ň |
ncaron; |
U+00148 | ň |
Ncedil; |
U+00145 | Ņ |
ncedil; |
U+00146 | ņ |
ncong; |
U+02247 | ≇ |
ncongdot; |
U+02A6D U+00338 | ⩭̸ |
ncup; |
U+02A42 | ⩂ |
Ncy; |
U+0041D | Н |
ncy; |
U+0043D | н |
ndash; |
U+02013 | – |
ne; |
U+02260 | ≠ |
nearhk; |
U+02924 | ⤤ |
neArr; |
U+021D7 | ⇗ |
nearr; |
U+02197 | ↗ |
nearrow; |
U+02197 | ↗ |
nedot; |
U+02250 U+00338 | ≐̸ |
NegativeMediumSpace; |
U+0200B | |
NegativeThickSpace; |
U+0200B | |
NegativeThinSpace; |
U+0200B | |
NegativeVeryThinSpace; |
U+0200B | |
nequiv; |
U+02262 | ≢ |
nesear; |
U+02928 | ⤨ |
nesim; |
U+02242 U+00338 | ≂̸ |
NestedGreaterGreater; |
U+0226B | ≫ |
NestedLessLess; |
U+0226A | ≪ |
NewLine; |
U+0000A | ␊ |
nexist; |
U+02204 | ∄ |
nexists; |
U+02204 | ∄ |
Nfr; |
U+1D511 | 𝔑 |
nfr; |
U+1D52B | 𝔫 |
ngE; |
U+02267 U+00338 | ≧̸ |
nge; |
U+02271 | ≱ |
ngeq; |
U+02271 | ≱ |
ngeqq; |
U+02267 U+00338 | ≧̸ |
ngeqslant; |
U+02A7E U+00338 | ⩾̸ |
nges; |
U+02A7E U+00338 | ⩾̸ |
nGg; |
U+022D9 U+00338 | ⋙̸ |
ngsim; |
U+02275 | ≵ |
nGt; |
U+0226B U+020D2 | ≫⃒ |
ngt; |
U+0226F | ≯ |
ngtr; |
U+0226F | ≯ |
nGtv; |
U+0226B U+00338 | ≫̸ |
nhArr; |
U+021CE | ⇎ |
nharr; |
U+021AE | ↮ |
nhpar; |
U+02AF2 | ⫲ |
ni; |
U+0220B | ∋ |
nis; |
U+022FC | ⋼ |
nisd; |
U+022FA | ⋺ |
niv; |
U+0220B | ∋ |
NJcy; |
U+0040A | Њ |
njcy; |
U+0045A | њ |
nlArr; |
U+021CD | ⇍ |
nlarr; |
U+0219A | ↚ |
nldr; |
U+02025 | ‥ |
nlE; |
U+02266 U+00338 | ≦̸ |
nle; |
U+02270 | ≰ |
nLeftarrow; |
U+021CD | ⇍ |
nleftarrow; |
U+0219A | ↚ |
nLeftrightarrow; |
U+021CE | ⇎ |
nleftrightarrow; |
U+021AE | ↮ |
nleq; |
U+02270 | ≰ |
nleqq; |
U+02266 U+00338 | ≦̸ |
nleqslant; |
U+02A7D U+00338 | ⩽̸ |
nles; |
U+02A7D U+00338 | ⩽̸ |
nless; |
U+0226E | ≮ |
nLl; |
U+022D8 U+00338 | ⋘̸ |
nlsim; |
U+02274 | ≴ |
nLt; |
U+0226A U+020D2 | ≪⃒ |
nlt; |
U+0226E | ≮ |
nltri; |
U+022EA | ⋪ |
nltrie; |
U+022EC | ⋬ |
nLtv; |
U+0226A U+00338 | ≪̸ |
nmid; |
U+02224 | ∤ |
NoBreak; |
U+02060 | |
NonBreakingSpace; |
U+000A0 | |
Nopf; |
U+02115 | ℕ |
nopf; |
U+1D55F | 𝕟 |
Not; |
U+02AEC | ⫬ |
not; |
U+000AC | ¬ |
not |
U+000AC | ¬ |
NotCongruent; |
U+02262 | ≢ |
NotCupCap; |
U+0226D | ≭ |
NotDoubleVerticalBar; |
U+02226 | ∦ |
NotElement; |
U+02209 | ∉ |
NotEqual; |
U+02260 | ≠ |
NotEqualTilde; |
U+02242 U+00338 | ≂̸ |
NotExists; |
U+02204 | ∄ |
NotGreater; |
U+0226F | ≯ |
NotGreaterEqual; |
U+02271 | ≱ |
NotGreaterFullEqual; |
U+02267 U+00338 | ≧̸ |
NotGreaterGreater; |
U+0226B U+00338 | ≫̸ |
NotGreaterLess; |
U+02279 | ≹ |
NotGreaterSlantEqual; |
U+02A7E U+00338 | ⩾̸ |
NotGreaterTilde; |
U+02275 | ≵ |
NotHumpDownHump; |
U+0224E U+00338 | ≎̸ |
NotHumpEqual; |
U+0224F U+00338 | ≏̸ |
notin; |
U+02209 | ∉ |
notindot; |
U+022F5 U+00338 | ⋵̸ |
notinE; |
U+022F9 U+00338 | ⋹̸ |
notinva; |
U+02209 | ∉ |
notinvb; |
U+022F7 | ⋷ |
notinvc; |
U+022F6 | ⋶ |
NotLeftTriangle; |
U+022EA | ⋪ |
NotLeftTriangleBar; |
U+029CF U+00338 | ⧏̸ |
NotLeftTriangleEqual; |
U+022EC | ⋬ |
NotLess; |
U+0226E | ≮ |
NotLessEqual; |
U+02270 | ≰ |
NotLessGreater; |
U+02278 | ≸ |
NotLessLess; |
U+0226A U+00338 | ≪̸ |
NotLessSlantEqual; |
U+02A7D U+00338 | ⩽̸ |
NotLessTilde; |
U+02274 | ≴ |
NotNestedGreaterGreater; |
U+02AA2 U+00338 | ⪢̸ |
NotNestedLessLess; |
U+02AA1 U+00338 | ⪡̸ |
notni; |
U+0220C | ∌ |
notniva; |
U+0220C | ∌ |
notnivb; |
U+022FE | ⋾ |
notnivc; |
U+022FD | ⋽ |
NotPrecedes; |
U+02280 | ⊀ |
NotPrecedesEqual; |
U+02AAF U+00338 | ⪯̸ |
NotPrecedesSlantEqual; |
U+022E0 | ⋠ |
NotReverseElement; |
U+0220C | ∌ |
NotRightTriangle; |
U+022EB | ⋫ |
NotRightTriangleBar; |
U+029D0 U+00338 | ⧐̸ |
NotRightTriangleEqual; |
U+022ED | ⋭ |
NotSquareSubset; |
U+0228F U+00338 | ⊏̸ |
NotSquareSubsetEqual; |
U+022E2 | ⋢ |
NotSquareSuperset; |
U+02290 U+00338 | ⊐̸ |
NotSquareSupersetEqual; |
U+022E3 | ⋣ |
NotSubset; |
U+02282 U+020D2 | ⊂⃒ |
NotSubsetEqual; |
U+02288 | ⊈ |
NotSucceeds; |
U+02281 | ⊁ |
NotSucceedsEqual; |
U+02AB0 U+00338 | ⪰̸ |
NotSucceedsSlantEqual; |
U+022E1 | ⋡ |
NotSucceedsTilde; |
U+0227F U+00338 | ≿̸ |
NotSuperset; |
U+02283 U+020D2 | ⊃⃒ |
NotSupersetEqual; |
U+02289 | ⊉ |
NotTilde; |
U+02241 | ≁ |
NotTildeEqual; |
U+02244 | ≄ |
NotTildeFullEqual; |
U+02247 | ≇ |
NotTildeTilde; |
U+02249 | ≉ |
NotVerticalBar; |
U+02224 | ∤ |
npar; |
U+02226 | ∦ |
nparallel; |
U+02226 | ∦ |
nparsl; |
U+02AFD U+020E5 | ⫽⃥ |
npart; |
U+02202 U+00338 | ∂̸ |
npolint; |
U+02A14 | ⨔ |
npr; |
U+02280 | ⊀ |
nprcue; |
U+022E0 | ⋠ |
npre; |
U+02AAF U+00338 | ⪯̸ |
nprec; |
U+02280 | ⊀ |
npreceq; |
U+02AAF U+00338 | ⪯̸ |
nrArr; |
U+021CF | ⇏ |
nrarr; |
U+0219B | ↛ |
nrarrc; |
U+02933 U+00338 | ⤳̸ |
nrarrw; |
U+0219D U+00338 | ↝̸ |
nRightarrow; |
U+021CF | ⇏ |
nrightarrow; |
U+0219B | ↛ |
nrtri; |
U+022EB | ⋫ |
nrtrie; |
U+022ED | ⋭ |
nsc; |
U+02281 | ⊁ |
nsccue; |
U+022E1 | ⋡ |
nsce; |
U+02AB0 U+00338 | ⪰̸ |
Nscr; |
U+1D4A9 | 𝒩 |
nscr; |
U+1D4C3 | 𝓃 |
nshortmid; |
U+02224 | ∤ |
nshortparallel; |
U+02226 | ∦ |
nsim; |
U+02241 | ≁ |
nsime; |
U+02244 | ≄ |
nsimeq; |
U+02244 | ≄ |
nsmid; |
U+02224 | ∤ |
nspar; |
U+02226 | ∦ |
nsqsube; |
U+022E2 | ⋢ |
nsqsupe; |
U+022E3 | ⋣ |
nsub; |
U+02284 | ⊄ |
nsubE; |
U+02AC5 U+00338 | ⫅̸ |
nsube; |
U+02288 | ⊈ |
nsubset; |
U+02282 U+020D2 | ⊂⃒ |
nsubseteq; |
U+02288 | ⊈ |
nsubseteqq; |
U+02AC5 U+00338 | ⫅̸ |
nsucc; |
U+02281 | ⊁ |
nsucceq; |
U+02AB0 U+00338 | ⪰̸ |
nsup; |
U+02285 | ⊅ |
nsupE; |
U+02AC6 U+00338 | ⫆̸ |
nsupe; |
U+02289 | ⊉ |
nsupset; |
U+02283 U+020D2 | ⊃⃒ |
nsupseteq; |
U+02289 | ⊉ |
nsupseteqq; |
U+02AC6 U+00338 | ⫆̸ |
ntgl; |
U+02279 | ≹ |
Ntilde; |
U+000D1 | Ñ |
Ntilde |
U+000D1 | Ñ |
ntilde; |
U+000F1 | ñ |
ntilde |
U+000F1 | ñ |
ntlg; |
U+02278 | ≸ |
ntriangleleft; |
U+022EA | ⋪ |
ntrianglelefteq; |
U+022EC | ⋬ |
ntriangleright; |
U+022EB | ⋫ |
ntrianglerighteq; |
U+022ED | ⋭ |
Nu; |
U+0039D | Ν |
nu; |
U+003BD | ν |
num; |
U+00023 | # |
numero; |
U+02116 | № |
numsp; |
U+02007 | |
nvap; |
U+0224D U+020D2 | ≍⃒ |
nVDash; |
U+022AF | ⊯ |
nVdash; |
U+022AE | ⊮ |
nvDash; |
U+022AD | ⊭ |
nvdash; |
U+022AC | ⊬ |
nvge; |
U+02265 U+020D2 | ≥⃒ |
nvgt; |
U+0003E U+020D2 | >⃒ |
nvHarr; |
U+02904 | ⤄ |
nvinfin; |
U+029DE | ⧞ |
nvlArr; |
U+02902 | ⤂ |
nvle; |
U+02264 U+020D2 | ≤⃒ |
nvlt; |
U+0003C U+020D2 | <⃒ |
nvltrie; |
U+022B4 U+020D2 | ⊴⃒ |
nvrArr; |
U+02903 | ⤃ |
nvrtrie; |
U+022B5 U+020D2 | ⊵⃒ |
nvsim; |
U+0223C U+020D2 | ∼⃒ |
nwarhk; |
U+02923 | ⤣ |
nwArr; |
U+021D6 | ⇖ |
nwarr; |
U+02196 | ↖ |
nwarrow; |
U+02196 | ↖ |
nwnear; |
U+02927 | ⤧ |
Oacute; |
U+000D3 | Ó |
Oacute |
U+000D3 | Ó |
oacute; |
U+000F3 | ó |
oacute |
U+000F3 | ó |
oast; |
U+0229B | ⊛ |
ocir; |
U+0229A | ⊚ |
Ocirc; |
U+000D4 | Ô |
Ocirc |
U+000D4 | Ô |
ocirc; |
U+000F4 | ô |
ocirc |
U+000F4 | ô |
Ocy; |
U+0041E | О |
ocy; |
U+0043E | о |
odash; |
U+0229D | ⊝ |
Odblac; |
U+00150 | Ő |
odblac; |
U+00151 | ő |
odiv; |
U+02A38 | ⨸ |
odot; |
U+02299 | ⊙ |
odsold; |
U+029BC | ⦼ |
OElig; |
U+00152 | Œ |
oelig; |
U+00153 | œ |
ofcir; |
U+029BF | ⦿ |
Ofr; |
U+1D512 | 𝔒 |
ofr; |
U+1D52C | 𝔬 |
ogon; |
U+002DB | ˛ |
Ograve; |
U+000D2 | Ò |
Ograve |
U+000D2 | Ò |
ograve; |
U+000F2 | ò |
ograve |
U+000F2 | ò |
ogt; |
U+029C1 | ⧁ |
ohbar; |
U+029B5 | ⦵ |
ohm; |
U+003A9 | Ω |
oint; |
U+0222E | ∮ |
olarr; |
U+021BA | ↺ |
olcir; |
U+029BE | ⦾ |
olcross; |
U+029BB | ⦻ |
oline; |
U+0203E | ‾ |
olt; |
U+029C0 | ⧀ |
Omacr; |
U+0014C | Ō |
omacr; |
U+0014D | ō |
Omega; |
U+003A9 | Ω |
omega; |
U+003C9 | ω |
Omicron; |
U+0039F | Ο |
omicron; |
U+003BF | ο |
omid; |
U+029B6 | ⦶ |
ominus; |
U+02296 | ⊖ |
Oopf; |
U+1D546 | 𝕆 |
oopf; |
U+1D560 | 𝕠 |
opar; |
U+029B7 | ⦷ |
OpenCurlyDoubleQuote; |
U+0201C | “ |
OpenCurlyQuote; |
U+02018 | ‘ |
operp; |
U+029B9 | ⦹ |
oplus; |
U+02295 | ⊕ |
Or; |
U+02A54 | ⩔ |
or; |
U+02228 | ∨ |
orarr; |
U+021BB | ↻ |
ord; |
U+02A5D | ⩝ |
order; |
U+02134 | ℴ |
orderof; |
U+02134 | ℴ |
ordf; |
U+000AA | ª |
ordf |
U+000AA | ª |
ordm; |
U+000BA | º |
ordm |
U+000BA | º |
origof; |
U+022B6 | ⊶ |
oror; |
U+02A56 | ⩖ |
orslope; |
U+02A57 | ⩗ |
orv; |
U+02A5B | ⩛ |
oS; |
U+024C8 | Ⓢ |
Oscr; |
U+1D4AA | 𝒪 |
oscr; |
U+02134 | ℴ |
Oslash; |
U+000D8 | Ø |
Oslash |
U+000D8 | Ø |
oslash; |
U+000F8 | ø |
oslash |
U+000F8 | ø |
osol; |
U+02298 | ⊘ |
Otilde; |
U+000D5 | Õ |
Otilde |
U+000D5 | Õ |
otilde; |
U+000F5 | õ |
otilde |
U+000F5 | õ |
Otimes; |
U+02A37 | ⨷ |
otimes; |
U+02297 | ⊗ |
otimesas; |
U+02A36 | ⨶ |
Ouml; |
U+000D6 | Ö |
Ouml |
U+000D6 | Ö |
ouml; |
U+000F6 | ö |
ouml |
U+000F6 | ö |
ovbar; |
U+0233D | ⌽ |
OverBar; |
U+0203E | ‾ |
OverBrace; |
U+023DE | ⏞ |
OverBracket; |
U+023B4 | ⎴ |
OverParenthesis; |
U+023DC | ⏜ |
par; |
U+02225 | ∥ |
para; |
U+000B6 | ¶ |
para |
U+000B6 | ¶ |
parallel; |
U+02225 | ∥ |
parsim; |
U+02AF3 | ⫳ |
parsl; |
U+02AFD | ⫽ |
part; |
U+02202 | ∂ |
PartialD; |
U+02202 | ∂ |
Pcy; |
U+0041F | П |
pcy; |
U+0043F | п |
percnt; |
U+00025 | % |
period; |
U+0002E | . |
permil; |
U+02030 | ‰ |
perp; |
U+022A5 | ⊥ |
pertenk; |
U+02031 | ‱ |
Pfr; |
U+1D513 | 𝔓 |
pfr; |
U+1D52D | 𝔭 |
Phi; |
U+003A6 | Φ |
phi; |
U+003C6 | φ |
phiv; |
U+003D5 | ϕ |
phmmat; |
U+02133 | ℳ |
phone; |
U+0260E | ☎ |
Pi; |
U+003A0 | Π |
pi; |
U+003C0 | π |
pitchfork; |
U+022D4 | ⋔ |
piv; |
U+003D6 | ϖ |
planck; |
U+0210F | ℏ |
planckh; |
U+0210E | ℎ |
plankv; |
U+0210F | ℏ |
plus; |
U+0002B | + |
plusacir; |
U+02A23 | ⨣ |
plusb; |
U+0229E | ⊞ |
pluscir; |
U+02A22 | ⨢ |
plusdo; |
U+02214 | ∔ |
plusdu; |
U+02A25 | ⨥ |
pluse; |
U+02A72 | ⩲ |
PlusMinus; |
U+000B1 | ± |
plusmn; |
U+000B1 | ± |
plusmn |
U+000B1 | ± |
plussim; |
U+02A26 | ⨦ |
plustwo; |
U+02A27 | ⨧ |
pm; |
U+000B1 | ± |
Poincareplane; |
U+0210C | ℌ |
pointint; |
U+02A15 | ⨕ |
Popf; |
U+02119 | ℙ |
popf; |
U+1D561 | 𝕡 |
pound; |
U+000A3 | £ |
pound |
U+000A3 | £ |
Pr; |
U+02ABB | ⪻ |
pr; |
U+0227A | ≺ |
prap; |
U+02AB7 | ⪷ |
prcue; |
U+0227C | ≼ |
prE; |
U+02AB3 | ⪳ |
pre; |
U+02AAF | ⪯ |
prec; |
U+0227A | ≺ |
precapprox; |
U+02AB7 | ⪷ |
preccurlyeq; |
U+0227C | ≼ |
Precedes; |
U+0227A | ≺ |
PrecedesEqual; |
U+02AAF | ⪯ |
PrecedesSlantEqual; |
U+0227C | ≼ |
PrecedesTilde; |
U+0227E | ≾ |
preceq; |
U+02AAF | ⪯ |
precnapprox; |
U+02AB9 | ⪹ |
precneqq; |
U+02AB5 | ⪵ |
precnsim; |
U+022E8 | ⋨ |
precsim; |
U+0227E | ≾ |
Prime; |
U+02033 | ″ |
prime; |
U+02032 | ′ |
primes; |
U+02119 | ℙ |
prnap; |
U+02AB9 | ⪹ |
prnE; |
U+02AB5 | ⪵ |
prnsim; |
U+022E8 | ⋨ |
prod; |
U+0220F | ∏ |
Product; |
U+0220F | ∏ |
profalar; |
U+0232E | ⌮ |
profline; |
U+02312 | ⌒ |
profsurf; |
U+02313 | ⌓ |
prop; |
U+0221D | ∝ |
Proportion; |
U+02237 | ∷ |
Proportional; |
U+0221D | ∝ |
propto; |
U+0221D | ∝ |
prsim; |
U+0227E | ≾ |
prurel; |
U+022B0 | ⊰ |
Pscr; |
U+1D4AB | 𝒫 |
pscr; |
U+1D4C5 | 𝓅 |
Psi; |
U+003A8 | Ψ |
psi; |
U+003C8 | ψ |
puncsp; |
U+02008 | |
Qfr; |
U+1D514 | 𝔔 |
qfr; |
U+1D52E | 𝔮 |
qint; |
U+02A0C | ⨌ |
Qopf; |
U+0211A | ℚ |
qopf; |
U+1D562 | 𝕢 |
qprime; |
U+02057 | ⁗ |
Qscr; |
U+1D4AC | 𝒬 |
qscr; |
U+1D4C6 | 𝓆 |
quaternions; |
U+0210D | ℍ |
quatint; |
U+02A16 | ⨖ |
quest; |
U+0003F | ? |
questeq; |
U+0225F | ≟ |
QUOT; |
U+00022 | " |
QUOT |
U+00022 | " |
quot; |
U+00022 | " |
quot |
U+00022 | " |
rAarr; |
U+021DB | ⇛ |
race; |
U+0223D U+00331 | ∽̱ |
Racute; |
U+00154 | Ŕ |
racute; |
U+00155 | ŕ |
radic; |
U+0221A | √ |
raemptyv; |
U+029B3 | ⦳ |
Rang; |
U+027EB | ⟫ |
rang; |
U+027E9 | ⟩ |
rangd; |
U+02992 | ⦒ |
range; |
U+029A5 | ⦥ |
rangle; |
U+027E9 | ⟩ |
raquo; |
U+000BB | » |
raquo |
U+000BB | » |
Rarr; |
U+021A0 | ↠ |
rArr; |
U+021D2 | ⇒ |
rarr; |
U+02192 | → |
rarrap; |
U+02975 | ⥵ |
rarrb; |
U+021E5 | ⇥ |
rarrbfs; |
U+02920 | ⤠ |
rarrc; |
U+02933 | ⤳ |
rarrfs; |
U+0291E | ⤞ |
rarrhk; |
U+021AA | ↪ |
rarrlp; |
U+021AC | ↬ |
rarrpl; |
U+02945 | ⥅ |
rarrsim; |
U+02974 | ⥴ |
Rarrtl; |
U+02916 | ⤖ |
rarrtl; |
U+021A3 | ↣ |
rarrw; |
U+0219D | ↝ |
rAtail; |
U+0291C | ⤜ |
ratail; |
U+0291A | ⤚ |
ratio; |
U+02236 | ∶ |
rationals; |
U+0211A | ℚ |
RBarr; |
U+02910 | ⤐ |
rBarr; |
U+0290F | ⤏ |
rbarr; |
U+0290D | ⤍ |
rbbrk; |
U+02773 | ❳ |
rbrace; |
U+0007D | } |
rbrack; |
U+0005D | ] |
rbrke; |
U+0298C | ⦌ |
rbrksld; |
U+0298E | ⦎ |
rbrkslu; |
U+02990 | ⦐ |
Rcaron; |
U+00158 | Ř |
rcaron; |
U+00159 | ř |
Rcedil; |
U+00156 | Ŗ |
rcedil; |
U+00157 | ŗ |
rceil; |
U+02309 | ⌉ |
rcub; |
U+0007D | } |
Rcy; |
U+00420 | Р |
rcy; |
U+00440 | р |
rdca; |
U+02937 | ⤷ |
rdldhar; |
U+02969 | ⥩ |
rdquo; |
U+0201D | ” |
rdquor; |
U+0201D | ” |
rdsh; |
U+021B3 | ↳ |
Re; |
U+0211C | ℜ |
real; |
U+0211C | ℜ |
realine; |
U+0211B | ℛ |
realpart; |
U+0211C | ℜ |
reals; |
U+0211D | ℝ |
rect; |
U+025AD | ▭ |
REG; |
U+000AE | ® |
REG |
U+000AE | ® |
reg; |
U+000AE | ® |
reg |
U+000AE | ® |
ReverseElement; |
U+0220B | ∋ |
ReverseEquilibrium; |
U+021CB | ⇋ |
ReverseUpEquilibrium; |
U+0296F | ⥯ |
rfisht; |
U+0297D | ⥽ |
rfloor; |
U+0230B | ⌋ |
Rfr; |
U+0211C | ℜ |
rfr; |
U+1D52F | 𝔯 |
rHar; |
U+02964 | ⥤ |
rhard; |
U+021C1 | ⇁ |
rharu; |
U+021C0 | ⇀ |
rharul; |
U+0296C | ⥬ |
Rho; |
U+003A1 | Ρ |
rho; |
U+003C1 | ρ |
rhov; |
U+003F1 | ϱ |
RightAngleBracket; |
U+027E9 | ⟩ |
RightArrow; |
U+02192 | → |
Rightarrow; |
U+021D2 | ⇒ |
rightarrow; |
U+02192 | → |
RightArrowBar; |
U+021E5 | ⇥ |
RightArrowLeftArrow; |
U+021C4 | ⇄ |
rightarrowtail; |
U+021A3 | ↣ |
RightCeiling; |
U+02309 | ⌉ |
RightDoubleBracket; |
U+027E7 | ⟧ |
RightDownTeeVector; |
U+0295D | ⥝ |
RightDownVector; |
U+021C2 | ⇂ |
RightDownVectorBar; |
U+02955 | ⥕ |
RightFloor; |
U+0230B | ⌋ |
rightharpoondown; |
U+021C1 | ⇁ |
rightharpoonup; |
U+021C0 | ⇀ |
rightleftarrows; |
U+021C4 | ⇄ |
rightleftharpoons; |
U+021CC | ⇌ |
rightrightarrows; |
U+021C9 | ⇉ |
rightsquigarrow; |
U+0219D | ↝ |
RightTee; |
U+022A2 | ⊢ |
RightTeeArrow; |
U+021A6 | ↦ |
RightTeeVector; |
U+0295B | ⥛ |
rightthreetimes; |
U+022CC | ⋌ |
RightTriangle; |
U+022B3 | ⊳ |
RightTriangleBar; |
U+029D0 | ⧐ |
RightTriangleEqual; |
U+022B5 | ⊵ |
RightUpDownVector; |
U+0294F | ⥏ |
RightUpTeeVector; |
U+0295C | ⥜ |
RightUpVector; |
U+021BE | ↾ |
RightUpVectorBar; |
U+02954 | ⥔ |
RightVector; |
U+021C0 | ⇀ |
RightVectorBar; |
U+02953 | ⥓ |
ring; |
U+002DA | ˚ |
risingdotseq; |
U+02253 | ≓ |
rlarr; |
U+021C4 | ⇄ |
rlhar; |
U+021CC | ⇌ |
rlm; |
U+0200F | |
rmoust; |
U+023B1 | ⎱ |
rmoustache; |
U+023B1 | ⎱ |
rnmid; |
U+02AEE | ⫮ |
roang; |
U+027ED | ⟭ |
roarr; |
U+021FE | ⇾ |
robrk; |
U+027E7 | ⟧ |
ropar; |
U+02986 | ⦆ |
Ropf; |
U+0211D | ℝ |
ropf; |
U+1D563 | 𝕣 |
roplus; |
U+02A2E | ⨮ |
rotimes; |
U+02A35 | ⨵ |
RoundImplies; |
U+02970 | ⥰ |
rpar; |
U+00029 | ) |
rpargt; |
U+02994 | ⦔ |
rppolint; |
U+02A12 | ⨒ |
rrarr; |
U+021C9 | ⇉ |
Rrightarrow; |
U+021DB | ⇛ |
rsaquo; |
U+0203A | › |
Rscr; |
U+0211B | ℛ |
rscr; |
U+1D4C7 | 𝓇 |
Rsh; |
U+021B1 | ↱ |
rsh; |
U+021B1 | ↱ |
rsqb; |
U+0005D | ] |
rsquo; |
U+02019 | ’ |
rsquor; |
U+02019 | ’ |
rthree; |
U+022CC | ⋌ |
rtimes; |
U+022CA | ⋊ |
rtri; |
U+025B9 | ▹ |
rtrie; |
U+022B5 | ⊵ |
rtrif; |
U+025B8 | ▸ |
rtriltri; |
U+029CE | ⧎ |
RuleDelayed; |
U+029F4 | ⧴ |
ruluhar; |
U+02968 | ⥨ |
rx; |
U+0211E | ℞ |
Sacute; |
U+0015A | Ś |
sacute; |
U+0015B | ś |
sbquo; |
U+0201A | ‚ |
Sc; |
U+02ABC | ⪼ |
sc; |
U+0227B | ≻ |
scap; |
U+02AB8 | ⪸ |
Scaron; |
U+00160 | Š |
scaron; |
U+00161 | š |
sccue; |
U+0227D | ≽ |
scE; |
U+02AB4 | ⪴ |
sce; |
U+02AB0 | ⪰ |
Scedil; |
U+0015E | Ş |
scedil; |
U+0015F | ş |
Scirc; |
U+0015C | Ŝ |
scirc; |
U+0015D | ŝ |
scnap; |
U+02ABA | ⪺ |
scnE; |
U+02AB6 | ⪶ |
scnsim; |
U+022E9 | ⋩ |
scpolint; |
U+02A13 | ⨓ |
scsim; |
U+0227F | ≿ |
Scy; |
U+00421 | С |
scy; |
U+00441 | с |
sdot; |
U+022C5 | ⋅ |
sdotb; |
U+022A1 | ⊡ |
sdote; |
U+02A66 | ⩦ |
searhk; |
U+02925 | ⤥ |
seArr; |
U+021D8 | ⇘ |
searr; |
U+02198 | ↘ |
searrow; |
U+02198 | ↘ |
sect; |
U+000A7 | § |
sect |
U+000A7 | § |
semi; |
U+0003B | ; |
seswar; |
U+02929 | ⤩ |
setminus; |
U+02216 | ∖ |
setmn; |
U+02216 | ∖ |
sext; |
U+02736 | ✶ |
Sfr; |
U+1D516 | 𝔖 |
sfr; |
U+1D530 | 𝔰 |
sfrown; |
U+02322 | ⌢ |
sharp; |
U+0266F | ♯ |
SHCHcy; |
U+00429 | Щ |
shchcy; |
U+00449 | щ |
SHcy; |
U+00428 | Ш |
shcy; |
U+00448 | ш |
ShortDownArrow; |
U+02193 | ↓ |
ShortLeftArrow; |
U+02190 | ← |
shortmid; |
U+02223 | ∣ |
shortparallel; |
U+02225 | ∥ |
ShortRightArrow; |
U+02192 | → |
ShortUpArrow; |
U+02191 | ↑ |
shy; |
U+000AD | |
shy |
U+000AD | |
Sigma; |
U+003A3 | Σ |
sigma; |
U+003C3 | σ |
sigmaf; |
U+003C2 | ς |
sigmav; |
U+003C2 | ς |
sim; |
U+0223C | ∼ |
simdot; |
U+02A6A | ⩪ |
sime; |
U+02243 | ≃ |
simeq; |
U+02243 | ≃ |
simg; |
U+02A9E | ⪞ |
simgE; |
U+02AA0 | ⪠ |
siml; |
U+02A9D | ⪝ |
simlE; |
U+02A9F | ⪟ |
simne; |
U+02246 | ≆ |
simplus; |
U+02A24 | ⨤ |
simrarr; |
U+02972 | ⥲ |
slarr; |
U+02190 | ← |
SmallCircle; |
U+02218 | ∘ |
smallsetminus; |
U+02216 | ∖ |
smashp; |
U+02A33 | ⨳ |
smeparsl; |
U+029E4 | ⧤ |
smid; |
U+02223 | ∣ |
smile; |
U+02323 | ⌣ |
smt; |
U+02AAA | ⪪ |
smte; |
U+02AAC | ⪬ |
smtes; |
U+02AAC U+0FE00 | ⪬︀ |
SOFTcy; |
U+0042C | Ь |
softcy; |
U+0044C | ь |
sol; |
U+0002F | / |
solb; |
U+029C4 | ⧄ |
solbar; |
U+0233F | ⌿ |
Sopf; |
U+1D54A | 𝕊 |
sopf; |
U+1D564 | 𝕤 |
spades; |
U+02660 | ♠ |
spadesuit; |
U+02660 | ♠ |
spar; |
U+02225 | ∥ |
sqcap; |
U+02293 | ⊓ |
sqcaps; |
U+02293 U+0FE00 | ⊓︀ |
sqcup; |
U+02294 | ⊔ |
sqcups; |
U+02294 U+0FE00 | ⊔︀ |
Sqrt; |
U+0221A | √ |
sqsub; |
U+0228F | ⊏ |
sqsube; |
U+02291 | ⊑ |
sqsubset; |
U+0228F | ⊏ |
sqsubseteq; |
U+02291 | ⊑ |
sqsup; |
U+02290 | ⊐ |
sqsupe; |
U+02292 | ⊒ |
sqsupset; |
U+02290 | ⊐ |
sqsupseteq; |
U+02292 | ⊒ |
squ; |
U+025A1 | □ |
Square; |
U+025A1 | □ |
square; |
U+025A1 | □ |
SquareIntersection; |
U+02293 | ⊓ |
SquareSubset; |
U+0228F | ⊏ |
SquareSubsetEqual; |
U+02291 | ⊑ |
SquareSuperset; |
U+02290 | ⊐ |
SquareSupersetEqual; |
U+02292 | ⊒ |
SquareUnion; |
U+02294 | ⊔ |
squarf; |
U+025AA | ▪ |
squf; |
U+025AA | ▪ |
srarr; |
U+02192 | → |
Sscr; |
U+1D4AE | 𝒮 |
sscr; |
U+1D4C8 | 𝓈 |
ssetmn; |
U+02216 | ∖ |
ssmile; |
U+02323 | ⌣ |
sstarf; |
U+022C6 | ⋆ |
Star; |
U+022C6 | ⋆ |
star; |
U+02606 | ☆ |
starf; |
U+02605 | ★ |
straightepsilon; |
U+003F5 | ϵ |
straightphi; |
U+003D5 | ϕ |
strns; |
U+000AF | ¯ |
Sub; |
U+022D0 | ⋐ |
sub; |
U+02282 | ⊂ |
subdot; |
U+02ABD | ⪽ |
subE; |
U+02AC5 | ⫅ |
sube; |
U+02286 | ⊆ |
subedot; |
U+02AC3 | ⫃ |
submult; |
U+02AC1 | ⫁ |
subnE; |
U+02ACB | ⫋ |
subne; |
U+0228A | ⊊ |
subplus; |
U+02ABF | ⪿ |
subrarr; |
U+02979 | ⥹ |
Subset; |
U+022D0 | ⋐ |
subset; |
U+02282 | ⊂ |
subseteq; |
U+02286 | ⊆ |
subseteqq; |
U+02AC5 | ⫅ |
SubsetEqual; |
U+02286 | ⊆ |
subsetneq; |
U+0228A | ⊊ |
subsetneqq; |
U+02ACB | ⫋ |
subsim; |
U+02AC7 | ⫇ |
subsub; |
U+02AD5 | ⫕ |
subsup; |
U+02AD3 | ⫓ |
succ; |
U+0227B | ≻ |
succapprox; |
U+02AB8 | ⪸ |
succcurlyeq; |
U+0227D | ≽ |
Succeeds; |
U+0227B | ≻ |
SucceedsEqual; |
U+02AB0 | ⪰ |
SucceedsSlantEqual; |
U+0227D | ≽ |
SucceedsTilde; |
U+0227F | ≿ |
succeq; |
U+02AB0 | ⪰ |
succnapprox; |
U+02ABA | ⪺ |
succneqq; |
U+02AB6 | ⪶ |
succnsim; |
U+022E9 | ⋩ |
succsim; |
U+0227F | ≿ |
SuchThat; |
U+0220B | ∋ |
Sum; |
U+02211 | ∑ |
sum; |
U+02211 | ∑ |
sung; |
U+0266A | ♪ |
Sup; |
U+022D1 | ⋑ |
sup; |
U+02283 | ⊃ |
sup1; |
U+000B9 | ¹ |
sup1 |
U+000B9 | ¹ |
sup2; |
U+000B2 | ² |
sup2 |
U+000B2 | ² |
sup3; |
U+000B3 | ³ |
sup3 |
U+000B3 | ³ |
supdot; |
U+02ABE | ⪾ |
supdsub; |
U+02AD8 | ⫘ |
supE; |
U+02AC6 | ⫆ |
supe; |
U+02287 | ⊇ |
supedot; |
U+02AC4 | ⫄ |
Superset; |
U+02283 | ⊃ |
SupersetEqual; |
U+02287 | ⊇ |
suphsol; |
U+027C9 | ⟉ |
suphsub; |
U+02AD7 | ⫗ |
suplarr; |
U+0297B | ⥻ |
supmult; |
U+02AC2 | ⫂ |
supnE; |
U+02ACC | ⫌ |
supne; |
U+0228B | ⊋ |
supplus; |
U+02AC0 | ⫀ |
Supset; |
U+022D1 | ⋑ |
supset; |
U+02283 | ⊃ |
supseteq; |
U+02287 | ⊇ |
supseteqq; |
U+02AC6 | ⫆ |
supsetneq; |
U+0228B | ⊋ |
supsetneqq; |
U+02ACC | ⫌ |
supsim; |
U+02AC8 | ⫈ |
supsub; |
U+02AD4 | ⫔ |
supsup; |
U+02AD6 | ⫖ |
swarhk; |
U+02926 | ⤦ |
swArr; |
U+021D9 | ⇙ |
swarr; |
U+02199 | ↙ |
swarrow; |
U+02199 | ↙ |
swnwar; |
U+0292A | ⤪ |
szlig; |
U+000DF | ß |
szlig |
U+000DF | ß |
Tab; |
U+00009 | ␉ |
target; |
U+02316 | ⌖ |
Tau; |
U+003A4 | Τ |
tau; |
U+003C4 | τ |
tbrk; |
U+023B4 | ⎴ |
Tcaron; |
U+00164 | Ť |
tcaron; |
U+00165 | ť |
Tcedil; |
U+00162 | Ţ |
tcedil; |
U+00163 | ţ |
Tcy; |
U+00422 | Т |
tcy; |
U+00442 | т |
tdot; |
U+020DB | ◌⃛ |
telrec; |
U+02315 | ⌕ |
Tfr; |
U+1D517 | 𝔗 |
tfr; |
U+1D531 | 𝔱 |
there4; |
U+02234 | ∴ |
Therefore; |
U+02234 | ∴ |
therefore; |
U+02234 | ∴ |
Theta; |
U+00398 | Θ |
theta; |
U+003B8 | θ |
thetasym; |
U+003D1 | ϑ |
thetav; |
U+003D1 | ϑ |
thickapprox; |
U+02248 | ≈ |
thicksim; |
U+0223C | ∼ |
ThickSpace; |
U+0205F U+0200A | |
thinsp; |
U+02009 | |
ThinSpace; |
U+02009 | |
thkap; |
U+02248 | ≈ |
thksim; |
U+0223C | ∼ |
THORN; |
U+000DE | Þ |
THORN |
U+000DE | Þ |
thorn; |
U+000FE | þ |
thorn |
U+000FE | þ |
Tilde; |
U+0223C | ∼ |
tilde; |
U+002DC | ˜ |
TildeEqual; |
U+02243 | ≃ |
TildeFullEqual; |
U+02245 | ≅ |
TildeTilde; |
U+02248 | ≈ |
times; |
U+000D7 | × |
times |
U+000D7 | × |
timesb; |
U+022A0 | ⊠ |
timesbar; |
U+02A31 | ⨱ |
timesd; |
U+02A30 | ⨰ |
tint; |
U+0222D | ∭ |
toea; |
U+02928 | ⤨ |
top; |
U+022A4 | ⊤ |
topbot; |
U+02336 | ⌶ |
topcir; |
U+02AF1 | ⫱ |
Topf; |
U+1D54B | 𝕋 |
topf; |
U+1D565 | 𝕥 |
topfork; |
U+02ADA | ⫚ |
tosa; |
U+02929 | ⤩ |
tprime; |
U+02034 | ‴ |
TRADE; |
U+02122 | ™ |
trade; |
U+02122 | ™ |
triangle; |
U+025B5 | ▵ |
triangledown; |
U+025BF | ▿ |
triangleleft; |
U+025C3 | ◃ |
trianglelefteq; |
U+022B4 | ⊴ |
triangleq; |
U+0225C | ≜ |
triangleright; |
U+025B9 | ▹ |
trianglerighteq; |
U+022B5 | ⊵ |
tridot; |
U+025EC | ◬ |
trie; |
U+0225C | ≜ |
triminus; |
U+02A3A | ⨺ |
TripleDot; |
U+020DB | ◌⃛ |
triplus; |
U+02A39 | ⨹ |
trisb; |
U+029CD | ⧍ |
tritime; |
U+02A3B | ⨻ |
trpezium; |
U+023E2 | ⏢ |
Tscr; |
U+1D4AF | 𝒯 |
tscr; |
U+1D4C9 | 𝓉 |
TScy; |
U+00426 | Ц |
tscy; |
U+00446 | ц |
TSHcy; |
U+0040B | Ћ |
tshcy; |
U+0045B | ћ |
Tstrok; |
U+00166 | Ŧ |
tstrok; |
U+00167 | ŧ |
twixt; |
U+0226C | ≬ |
twoheadleftarrow; |
U+0219E | ↞ |
twoheadrightarrow; |
U+021A0 | ↠ |
Uacute; |
U+000DA | Ú |
Uacute |
U+000DA | Ú |
uacute; |
U+000FA | ú |
uacute |
U+000FA | ú |
Uarr; |
U+0219F | ↟ |
uArr; |
U+021D1 | ⇑ |
uarr; |
U+02191 | ↑ |
Uarrocir; |
U+02949 | ⥉ |
Ubrcy; |
U+0040E | Ў |
ubrcy; |
U+0045E | ў |
Ubreve; |
U+0016C | Ŭ |
ubreve; |
U+0016D | ŭ |
Ucirc; |
U+000DB | Û |
Ucirc |
U+000DB | Û |
ucirc; |
U+000FB | û |
ucirc |
U+000FB | û |
Ucy; |
U+00423 | У |
ucy; |
U+00443 | у |
udarr; |
U+021C5 | ⇅ |
Udblac; |
U+00170 | Ű |
udblac; |
U+00171 | ű |
udhar; |
U+0296E | ⥮ |
ufisht; |
U+0297E | ⥾ |
Ufr; |
U+1D518 | 𝔘 |
ufr; |
U+1D532 | 𝔲 |
Ugrave; |
U+000D9 | Ù |
Ugrave |
U+000D9 | Ù |
ugrave; |
U+000F9 | ù |
ugrave |
U+000F9 | ù |
uHar; |
U+02963 | ⥣ |
uharl; |
U+021BF | ↿ |
uharr; |
U+021BE | ↾ |
uhblk; |
U+02580 | ▀ |
ulcorn; |
U+0231C | ⌜ |
ulcorner; |
U+0231C | ⌜ |
ulcrop; |
U+0230F | ⌏ |
ultri; |
U+025F8 | ◸ |
Umacr; |
U+0016A | Ū |
umacr; |
U+0016B | ū |
uml; |
U+000A8 | ¨ |
uml |
U+000A8 | ¨ |
UnderBar; |
U+0005F | _ |
UnderBrace; |
U+023DF | ⏟ |
UnderBracket; |
U+023B5 | ⎵ |
UnderParenthesis; |
U+023DD | ⏝ |
Union; |
U+022C3 | ⋃ |
UnionPlus; |
U+0228E | ⊎ |
Uogon; |
U+00172 | Ų |
uogon; |
U+00173 | ų |
Uopf; |
U+1D54C | 𝕌 |
uopf; |
U+1D566 | 𝕦 |
UpArrow; |
U+02191 | ↑ |
Uparrow; |
U+021D1 | ⇑ |
uparrow; |
U+02191 | ↑ |
UpArrowBar; |
U+02912 | ⤒ |
UpArrowDownArrow; |
U+021C5 | ⇅ |
UpDownArrow; |
U+02195 | ↕ |
Updownarrow; |
U+021D5 | ⇕ |
updownarrow; |
U+02195 | ↕ |
UpEquilibrium; |
U+0296E | ⥮ |
upharpoonleft; |
U+021BF | ↿ |
upharpoonright; |
U+021BE | ↾ |
uplus; |
U+0228E | ⊎ |
UpperLeftArrow; |
U+02196 | ↖ |
UpperRightArrow; |
U+02197 | ↗ |
Upsi; |
U+003D2 | ϒ |
upsi; |
U+003C5 | υ |
upsih; |
U+003D2 | ϒ |
Upsilon; |
U+003A5 | Υ |
upsilon; |
U+003C5 | υ |
UpTee; |
U+022A5 | ⊥ |
UpTeeArrow; |
U+021A5 | ↥ |
upuparrows; |
U+021C8 | ⇈ |
urcorn; |
U+0231D | ⌝ |
urcorner; |
U+0231D | ⌝ |
urcrop; |
U+0230E | ⌎ |
Uring; |
U+0016E | Ů |
uring; |
U+0016F | ů |
urtri; |
U+025F9 | ◹ |
Uscr; |
U+1D4B0 | 𝒰 |
uscr; |
U+1D4CA | 𝓊 |
utdot; |
U+022F0 | ⋰ |
Utilde; |
U+00168 | Ũ |
utilde; |
U+00169 | ũ |
utri; |
U+025B5 | ▵ |
utrif; |
U+025B4 | ▴ |
uuarr; |
U+021C8 | ⇈ |
Uuml; |
U+000DC | Ü |
Uuml |
U+000DC | Ü |
uuml; |
U+000FC | ü |
uuml |
U+000FC | ü |
uwangle; |
U+029A7 | ⦧ |
vangrt; |
U+0299C | ⦜ |
varepsilon; |
U+003F5 | ϵ |
varkappa; |
U+003F0 | ϰ |
varnothing; |
U+02205 | ∅ |
varphi; |
U+003D5 | ϕ |
varpi; |
U+003D6 | ϖ |
varpropto; |
U+0221D | ∝ |
vArr; |
U+021D5 | ⇕ |
varr; |
U+02195 | ↕ |
varrho; |
U+003F1 | ϱ |
varsigma; |
U+003C2 | ς |
varsubsetneq; |
U+0228A U+0FE00 | ⊊︀ |
varsubsetneqq; |
U+02ACB U+0FE00 | ⫋︀ |
varsupsetneq; |
U+0228B U+0FE00 | ⊋︀ |
varsupsetneqq; |
U+02ACC U+0FE00 | ⫌︀ |
vartheta; |
U+003D1 | ϑ |
vartriangleleft; |
U+022B2 | ⊲ |
vartriangleright; |
U+022B3 | ⊳ |
Vbar; |
U+02AEB | ⫫ |
vBar; |
U+02AE8 | ⫨ |
vBarv; |
U+02AE9 | ⫩ |
Vcy; |
U+00412 | В |
vcy; |
U+00432 | в |
VDash; |
U+022AB | ⊫ |
Vdash; |
U+022A9 | ⊩ |
vDash; |
U+022A8 | ⊨ |
vdash; |
U+022A2 | ⊢ |
Vdashl; |
U+02AE6 | ⫦ |
Vee; |
U+022C1 | ⋁ |
vee; |
U+02228 | ∨ |
veebar; |
U+022BB | ⊻ |
veeeq; |
U+0225A | ≚ |
vellip; |
U+022EE | ⋮ |
Verbar; |
U+02016 | ‖ |
verbar; |
U+0007C | | |
Vert; |
U+02016 | ‖ |
vert; |
U+0007C | | |
VerticalBar; |
U+02223 | ∣ |
VerticalLine; |
U+0007C | | |
VerticalSeparator; |
U+02758 | ❘ |
VerticalTilde; |
U+02240 | ≀ |
VeryThinSpace; |
U+0200A | |
Vfr; |
U+1D519 | 𝔙 |
vfr; |
U+1D533 | 𝔳 |
vltri; |
U+022B2 | ⊲ |
vnsub; |
U+02282 U+020D2 | ⊂⃒ |
vnsup; |
U+02283 U+020D2 | ⊃⃒ |
Vopf; |
U+1D54D | 𝕍 |
vopf; |
U+1D567 | 𝕧 |
vprop; |
U+0221D | ∝ |
vrtri; |
U+022B3 | ⊳ |
Vscr; |
U+1D4B1 | 𝒱 |
vscr; |
U+1D4CB | 𝓋 |
vsubnE; |
U+02ACB U+0FE00 | ⫋︀ |
vsubne; |
U+0228A U+0FE00 | ⊊︀ |
vsupnE; |
U+02ACC U+0FE00 | ⫌︀ |
vsupne; |
U+0228B U+0FE00 | ⊋︀ |
Vvdash; |
U+022AA | ⊪ |
vzigzag; |
U+0299A | ⦚ |
Wcirc; |
U+00174 | Ŵ |
wcirc; |
U+00175 | ŵ |
wedbar; |
U+02A5F | ⩟ |
Wedge; |
U+022C0 | ⋀ |
wedge; |
U+02227 | ∧ |
wedgeq; |
U+02259 | ≙ |
weierp; |
U+02118 | ℘ |
Wfr; |
U+1D51A | 𝔚 |
wfr; |
U+1D534 | 𝔴 |
Wopf; |
U+1D54E | 𝕎 |
wopf; |
U+1D568 | 𝕨 |
wp; |
U+02118 | ℘ |
wr; |
U+02240 | ≀ |
wreath; |
U+02240 | ≀ |
Wscr; |
U+1D4B2 | 𝒲 |
wscr; |
U+1D4CC | 𝓌 |
xcap; |
U+022C2 | ⋂ |
xcirc; |
U+025EF | ◯ |
xcup; |
U+022C3 | ⋃ |
xdtri; |
U+025BD | ▽ |
Xfr; |
U+1D51B | 𝔛 |
xfr; |
U+1D535 | 𝔵 |
xhArr; |
U+027FA | ⟺ |
xharr; |
U+027F7 | ⟷ |
Xi; |
U+0039E | Ξ |
xi; |
U+003BE | ξ |
xlArr; |
U+027F8 | ⟸ |
xlarr; |
U+027F5 | ⟵ |
xmap; |
U+027FC | ⟼ |
xnis; |
U+022FB | ⋻ |
xodot; |
U+02A00 | ⨀ |
Xopf; |
U+1D54F | 𝕏 |
xopf; |
U+1D569 | 𝕩 |
xoplus; |
U+02A01 | ⨁ |
xotime; |
U+02A02 | ⨂ |
xrArr; |
U+027F9 | ⟹ |
xrarr; |
U+027F6 | ⟶ |
Xscr; |
U+1D4B3 | 𝒳 |
xscr; |
U+1D4CD | 𝓍 |
xsqcup; |
U+02A06 | ⨆ |
xuplus; |
U+02A04 | ⨄ |
xutri; |
U+025B3 | △ |
xvee; |
U+022C1 | ⋁ |
xwedge; |
U+022C0 | ⋀ |
Yacute; |
U+000DD | Ý |
Yacute |
U+000DD | Ý |
yacute; |
U+000FD | ý |
yacute |
U+000FD | ý |
YAcy; |
U+0042F | Я |
yacy; |
U+0044F | я |
Ycirc; |
U+00176 | Ŷ |
ycirc; |
U+00177 | ŷ |
Ycy; |
U+0042B | Ы |
ycy; |
U+0044B | ы |
yen; |
U+000A5 | ¥ |
yen |
U+000A5 | ¥ |
Yfr; |
U+1D51C | 𝔜 |
yfr; |
U+1D536 | 𝔶 |
YIcy; |
U+00407 | Ї |
yicy; |
U+00457 | ї |
Yopf; |
U+1D550 | 𝕐 |
yopf; |
U+1D56A | 𝕪 |
Yscr; |
U+1D4B4 | 𝒴 |
yscr; |
U+1D4CE | 𝓎 |
YUcy; |
U+0042E | Ю |
yucy; |
U+0044E | ю |
Yuml; |
U+00178 | Ÿ |
yuml; |
U+000FF | ÿ |
yuml |
U+000FF | ÿ |
Zacute; |
U+00179 | Ź |
zacute; |
U+0017A | ź |
Zcaron; |
U+0017D | Ž |
zcaron; |
U+0017E | ž |
Zcy; |
U+00417 | З |
zcy; |
U+00437 | з |
Zdot; |
U+0017B | Ż |
zdot; |
U+0017C | ż |
zeetrf; |
U+02128 | ℨ |
ZeroWidthSpace; |
U+0200B | |
Zeta; |
U+00396 | Ζ |
zeta; |
U+003B6 | ζ |
Zfr; |
U+02128 | ℨ |
zfr; |
U+1D537 | 𝔷 |
ZHcy; |
U+00416 | Ж |
zhcy; |
U+00436 | ж |
zigrarr; |
U+021DD | ⇝ |
Zopf; |
U+02124 | ℤ |
zopf; |
U+1D56B | 𝕫 |
Zscr; |
U+1D4B5 | 𝒵 |
zscr; |
U+1D4CF | 𝓏 |
zwj; |
U+0200D | |
zwnj; |
U+0200C | |
这些数据也可作为JSON文件获取。
上面显示的字形是非规范性的。有关所列字符的正式定义,请参阅Unicode。
字符引用名称源自XML字符实体定义,但只有上述内容被视为规范性的。[XMLENTITY]
此列表是静态的,将来不会扩展或更改。
在所有当前的引擎中都支持。
本节仅描述 XML 资源的规则。关于text/html
资源的规则在上面标题为"HTML 语法"的部分中讨论。
不推荐使用 XML 语法,原因包括没有定义 XML 解析器如何将字节或字符串映射到Document
对象的规范,以及 XML
语法本质上未被维护——即使添加了新功能,也不期望 XML 语法会添加任何进一步的功能(即使这些功能已添加到HTML
语法中)。
HTML 的 XML 语法以前被称为 "XHTML",但本规范不使用该术语(其中一个原因是,MathML 和 SVG 的 HTML 语法没有使用此类术语)。
XML 的语法定义在XML和XML 中的命名空间中。[XML] [XMLNS]
本规范未定义超出 XML 本身定义的任何语法级要求。
如果需要,XML 文档可以包含DOCTYPE
,但这不是符合本规范的必需条件。本规范未定义公共或系统标识符,也未提供正式的 DTD。
根据XML,不能保证 XML 处理器会处理在 DOCTYPE 中引用的外部 DTD 子集。这意味着,例如,如果字符在外部文件中定义,则在 XML 文档中使用实体引用是不安全的(<
、
>
、&
、
"
和'
除外)。
本节描述了 XML 和 DOM 之间的关系,特别强调了它如何与 HTML 交互。
为了本规范的目的,XML 解析器是一个遵循XML中给出的规则,将字节或字符串映射为Document
对象的构造体。
在撰写本文时,实际上并不存在这样的规则。
一个XML 解析器要么在创建时与Document
对象相关联,要么隐式创建一个。
然后必须使用 DOM 节点来填充该Document
,这些节点表示传递给解析器的输入的树结构,如XML、XML
中的命名空间和DOM中定义的那样。在创建表示元素的 DOM 节点时,必须使用为令牌创建元素算法或某种等效算法,该算法在适当的 XML
数据结构上运行,以确保创建正确的元素接口,并且正确设置自定义元素。
对于XML 解析器在 文档
的树上执行的操作,用户代理必须仿效元素和属性分别被追加和设置的方式,以触发本规范中关于当元素插入文档或其属性被设置时发生的规则,并且
DOM 的关于突变观察者的要求意味着突变观察者确实被触发。
[XML] [XMLNS] [DOM] [UIEVENTS]
在解析元素的开始标签与解析元素的结束标签或解析器检测到格式正确性错误之间的时间内,用户代理必须表现得像该元素位于打开元素堆栈中。
这被各种元素用于仅在它们从打开元素堆栈中弹出后才开始某些进程。
本规范提供了用户代理在检索外部实体时应使用的以下附加信息:以下列表中给出的公共标识符都对应于 链接提供的 URL. (此 URL 是一个 DTD,包含实体声明,用于命名字符引用部分中列出的名称。)[XML]
-//W3C//DTD XHTML 1.0 Transitional//EN
-//W3C//DTD XHTML 1.1//EN
-//W3C//DTD XHTML 1.0 Strict//EN
-//W3C//DTD XHTML 1.0 Frameset//EN
-//W3C//DTD XHTML Basic 1.0//EN
-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN
-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN
-//W3C//DTD MathML 2.0//EN
-//WAPFORUM//DTD XHTML Mobile 1.0//EN
此外,当使用上述公共标识符之一时,用户代理应尝试检索上述外部实体的内容,并且不应尝试检索任何其他外部实体的内容。
这并不严格算作XML的违规,但它确实与XML的要求精神相矛盾。这是出于希望用户代理能够以互操作的方式处理实体,而不需要任何网络访问来处理外部子集的考虑。[XML]
可以在启用 XML 脚本支持或禁用 XML 脚本支持的情况下调用 XML 解析器。除非另有说明,否则 XML 解析器是在启用 XML 脚本支持的情况下调用的。
当XML解析器在启用了XML脚本支持的情况下创建一个script
元素时,它必须设置其解析器文档,并将其强制异步设置为false。如果解析器是作为XML片段解析算法的一部分创建的,则元素的已启动必须设置为true。当元素的结束标签随后被解析时,用户代理必须执行微任务检查点,然后准备 script
元素。如果这导致存在挂起的解析阻塞脚本,则用户代理必须执行以下步骤:
由于document.write()
API 不适用于XML 文档,因此HTML
解析器中的许多复杂性在XML 解析器中是不需要的。
当XML
解析器将一个节点附加到template
元素时,它必须将其附加到该template
元素的模板内容(一个DocumentFragment
节点)中。
这是对XML的故意违反;不幸的是,XML 并没有以处理template
的方式进行正式扩展的能力。[XML]
当XML 解析器创建一个节点
对象时,它的节点文档必须设置为要插入新创建节点的节点的节点文档。
本规范中的某些算法一口一口地喂解析器字符。这种情况下,XML 解析器必须像面对由所有这些字符连接而成的单个字符串时一样行事。
当XML 解析器到达其输入的末尾时,它必须停止解析,并遵循与HTML 解析器相同的规则。XML 解析器也可以中止,这必须与HTML 解析器的中止方式相同。
为了符合性检查器的目的,如果确定资源采用XML 语法,那么它就是一个XML 文档。
用于Document
或Element
节点的XML 片段序列化算法要么返回表示该节点的 XML 片段,要么抛出异常。
对于Document
,如果没有适用的错误情况,该算法必须返回文档实体形式的字符串。
对于Element
,如果没有适用的错误情况,该算法必须返回内部通用解析实体形式的字符串。
在这两种情况下,返回的字符串必须是 XML 命名空间格式正确的,并且必须是该节点所有相关子节点的同构序列化,按树顺序排列。用户代理可以在序列化中调整前缀和命名空间声明(实际上在某些情况下可能不得不这样做,以获得命名空间格式正确的
XML)。用户代理可以使用常规文本和字符引用的组合来表示 DOM 中的Text
节点。
节点的相关子节点是根据以下规则适用的节点:
template
元素
template
元素的模板内容的子节点(如果有)。
对于Element
,如果序列化中的任何元素没有命名空间,则必须将这些元素的范围内的默认命名空间显式声明为空字符串。(这不适用于Document
情况。)[XML][XMLNS]
在本节的上下文中,如果一个文档由一个没有命名空间声明的元素组成,其内容是内部通用解析实体,那么该文档本身是 XML 命名空间格式正确的,则该内部通用解析实体被认为是 XML 命名空间格式正确的。
如果在正在序列化的 DOM 子树中发现以下任何错误情况,则该算法必须抛出一个"InvalidStateError
"DOMException
,而不是返回字符串:
Document
节点。
DocumentType
节点,其中包含的字符未与
XMLPubidChar
产生匹配。[XML]DocumentType
节点,其中同时包含
U+0022 引号 (") 和 U+0027 撇号 ('),或者包含的字符未与 XMLChar
产生匹配。[XML]
Name
产生匹配的节点。[XML]xmlns
"的Attr
节点。[XMLNS]Element
节点。
Char
产生匹配的字符的Attr
节点、Text
节点、Comment
节点或ProcessingInstruction
节点。[XML]
Comment
节点。
xml
"进行ASCII
不区分大小写匹配的ProcessingInstruction
节点。
ProcessingInstruction
节点。
?>
"的ProcessingInstruction
节点。
这些是使 DOM 无法序列化的唯一方法。DOM 强制执行所有其他 XML 约束;例如,尝试将两个元素附加到Document
节点将抛出"HierarchyRequestError
"DOMException
。
XML 片段解析算法要么返回一个Document
,要么抛出一个"SyntaxError
"DOMException
。给定一个字符串input和一个上下文元素context,算法如下:
创建一个新的XML 解析器。
将字符串(对应于context元素的开始标签)传递给刚刚创建的解析器,并声明该元素在 DOM 中范围内的所有命名空间前缀,以及声明在 DOM 中该元素范围内的默认命名空间(如果有)。
如果 DOM 元素上的lookupNamespaceURI()
方法为该前缀返回一个非 null 值,则命名空间前缀在范围内。
默认命名空间是 DOM 元素上的isDefaultNamespace()
方法为其返回 true 的命名空间。
不向解析器传递DOCTYPE
,因此不会引用任何外部子集,也不会识别任何实体。
将字符串input传递给刚刚创建的解析器。
如果出现 XML 格式正确性或 XML 命名空间格式正确性错误,则抛出一个"SyntaxError
"DOMException
。
如果生成的Document
的文档元素有任何兄弟节点,则抛出一个"SyntaxError
"DOMException
。
用户代理不需要以任何特定方式呈现HTML文档。然而,本节提供了一套渲染HTML文档的建议,如果遵循这些建议,可能会带来与文档作者预期的用户体验非常接近的结果。为了避免对本节的规范性产生混淆,没有使用"必须"一词。相反,使用了"预期"一词来表示将会导致这种体验的行为。对于被指定为支持建议的默认渲染的用户代理,"预期"一词在本节中的符合性含义与"必须"相同。
本节中的建议通常以CSS术语表达。用户代理应支持CSS,或将本节中给出的CSS规则转换为其他展示机制的近似值。
在没有相反的样式层规则(例如作者样式表)的情况下,用户代理应当渲染一个元素,使其能够向用户传达该元素所代表的含义,如本规范所述。
本节中的建议通常假定为96dpi或更高分辨率的视觉输出介质,但HTML旨在应用于多种媒介(它是一种媒介无关的语言)。鼓励用户代理实现者根据其目标媒介调整本节中的建议。
如果一个元素具有任何关联的CSS布局框、SVG布局框或其他样式语言中的等效物,则该元素被称为正在渲染。
仅仅在屏幕外并不意味着该元素没有正在渲染。通常, 属性的存在意味着该元素没有正在渲染,尽管这可能会被样式表覆盖。
完全活动状态不会影响一个元素是否正在渲染。即使一个文档不完全活动且根本不向用户显示,其内部的元素仍然可以视为"正在渲染"。
当一个元素正在渲染并且其关联的CSS布局框与视口相交时,称该元素与视口相交。
与正在渲染状态类似,非完全活动文档中的元素仍然可以与视口相交。视口在文档之间不共享,并且可能并不总是显示给用户,因此非完全活动文档中的元素仍然可以与其文档关联的视口相交。
本规范未定义何时测试交叉的精确时间,但建议该时间与Intersection Observer API的时间相匹配。[INTERSECTIONOBSERVER]
如果一个元素不正在渲染,但其子元素(如果有)可以渲染,则称该元素将其渲染委托给其子元素,这是CSS 'display: contents'的结果,或其他样式语言中的等效物。[CSSDISPLAY]
即使不遵循作者级别的CSS样式表,用户代理仍然应表现得像是以与本规范以及相关的CSS和Unicode规范一致的方式应用了本节中的CSS规则。[CSS] [UNICODE] [BIDI]
这对涉及'display'、'unicode-bidi'和'direction'属性的问题尤为重要。
除非另有说明,本小节中给出的CSS规则应作为包含HTML元素的所有文档的用户代理级别样式表默认值的一部分。
某些规则是为CSS层叠中的作者级零特异性呈现提示部分设计的;这些规则被明确标注为呈现提示。
当下文中提到某个元素element上的属性attribute 映射到像素长度属性(或多个属性properties)时,这意味着如果element具有属性attribute,并且使用解析非负整数的规则解析该属性的值没有产生错误,则用户代理应使用解析后的值作为properties的呈现提示的像素长度。
当下文中提到某个元素element上的属性attribute 映射到维度属性(或多个属性properties)时,这意味着如果element具有属性attribute,并且使用解析维度值的规则解析该属性的值没有产生错误,则用户代理应使用解析后的维度作为properties的呈现提示的值,如果维度是长度,则以像素长度表示该值,如果维度是百分比,则以百分比表示该值。
当下文中提到某个元素element上的属性attribute 映射到维度属性(忽略零)(或多个属性properties)时,这意味着如果element具有属性attribute,并且使用解析非零维度值的规则解析该属性的值没有产生错误,则用户代理应使用解析后的维度作为properties的呈现提示的值,如果维度是长度,则以像素长度表示该值,如果维度是百分比,则以百分比表示该值。
当下文中提到元素element上的一对属性w和h 映射到宽高比属性时,这意味着如果element具有属性w和h,并且使用解析非负整数的规则解析这些属性的值没有产生错误,则用户代理应使用解析后的整数作为呈现提示,其形式为auto w / h
。
当下文中提到元素element上的一对属性w和h 映射到宽高比属性(使用维度规则)时,这意味着如果element具有属性w和h,并且使用解析维度值的规则解析这些属性的值没有产生错误或返回百分比,则用户代理应使用解析后的维度作为呈现提示,其形式为auto w / h
。
当用户代理对节点的后代进行对齐时,用户代理应只对那些margin-inline-start
和margin-inline-end
属性计算值不为'auto'的后代进行对齐,这些后代是过度约束的,并且其中一个边距的使用值被强制为更大的值,并且它们本身没有适用的align
属性。当多个元素需要对齐特定的后代时,嵌套最深的元素应覆盖其他元素。对齐的元素应通过设置其边距在行左和行右侧的使用值来进行对齐。[CSSLOGICAL]
[CSSWM]
@namespace "http://www.w3.org/1999/xhtml" ;
area, base, basefont, datalist, head, link, meta, noembed,
noframes, param, rp, script, style, template, title {
display : none;
}
{
display : none;
}
[hidden=until-found i]:not(embed) {
content-visibility : hidden;
}
embed[hidden] { display : inline; height : 0 ; width : 0 ; }
input[type=hidden i] { display : none !important; }
@media (scripting) {
noscript { display: none !important; }
}
@namespace "http://www.w3.org/1999/xhtml" ;
html, body { display : block; }
对于下表中的每个属性,给定一个body
元素,存在的第一个属性映射到 body
元素的像素长度属性。如果未找到该属性的任何属性,或者找到的属性值无法成功解析,则应为该属性使用默认值8px。
属性 | 来源 |
---|---|
'margin-top' | body 元素的marginheight 属性
|
body 元素的topmargin 属性
|
|
body 元素的容器框架元素的marginheight 属性
|
|
'margin-right' | body 元素的marginwidth 属性
|
body 元素的rightmargin 属性
|
|
body 元素的容器框架元素的marginwidth 属性
|
|
'margin-bottom' | body 元素的marginheight 属性
|
body 元素的bottommargin 属性
|
|
body 元素的容器框架元素的marginheight 属性
|
|
'margin-left' | body 元素的marginwidth 属性
|
body 元素的leftmargin 属性
|
|
body 元素的容器框架元素的marginwidth 属性
|
如果 body
元素的
节点文档 的 节点可导航对象
是一个
子可导航对象,并且该可导航对象的 容器 是一个 frame
或 iframe
元素,那么该
body
元素的 容器框架元素 就是该 frame
或
iframe
元素。否则,没有
容器框架元素。
上述要求意味着页面可以通过例如iframe
更改另一个页面(包括来自其他来源的页面)的边距。这可能是一个安全风险,因为在某些情况下,它可能允许攻击者伪造出与作者意图不符的页面渲染,可能用于钓鱼或误导用户。
如果文档
的可导航节点是子可导航节点,则应将其定位并调整大小以适应该内容框内的容器的可导航节点。如果该容器没有正在渲染,则可导航节点应具有一个宽度和高度为零的视口。
如果文档
的可导航节点是子可导航节点,且该容器是该可导航节点的frame
或iframe
元素,该元素具有scrolling
属性,并且该属性的值与字符串"off
"、"noscroll
"或"no
"的ASCII不区分大小写匹配,则用户代理应防止该文档
的可导航节点的视口显示任何滚动条,无论应用于该视口的'overflow'属性为何。
当body
元素的background
属性设置为非空值时,新的值应相对于元素的
节点文档进行编码、解析和序列化,并且如果该操作未返回失败,则用户代理应将该属性视为呈现提示,将元素的'background-image'属性设置为返回值。
当body
元素的bgcolor
属性被设置时,新的值应使用解析遗留颜色
值的规则进行解析,并且如果该操作未返回错误,则用户代理应将该属性视为呈现提示,将元素的'background-color'属性设置为结果颜色。
当body
元素的text
属性被设置时,其值应使用解析遗留颜色值的规则进行解析,如果该操作未返回错误,则用户代理应将该属性视为呈现提示,将元素的'color'属性设置为结果颜色。
当body
元素的link
属性被设置时,其值应使用解析遗留颜色值的规则进行解析,如果该操作未返回错误,则用户代理应将该属性视为呈现提示,将任何在文档
中与:link
伪类匹配的元素的'color'属性设置为结果颜色。
当body
元素的vlink
属性被设置时,其值应使用解析遗留颜色值的规则进行解析,如果该操作未返回错误,则用户代理应将该属性视为呈现提示,将任何在文档
中与:visited
伪类匹配的元素的'color'属性设置为结果颜色。
当body
元素的alink
属性被设置时,其值应使用解析遗留颜色值的规则进行解析,如果该操作未返回错误,则用户代理应将该属性视为呈现提示,将任何在文档
中与:active
伪类和:link
伪类或:visited
伪类匹配的元素的'color'属性设置为结果颜色。
@namespace "http://www.w3.org/1999/xhtml" ;
address, blockquote, center, dialog, div, figure, figcaption, footer, form,
header, hr, legend, listing, main, p, plaintext, pre, search, xmp {
display : block;
}
blockquote, figure, listing, p, plaintext, pre, xmp {
margin-block : 1 em ;
}
blockquote, figure { margin-inline : 40 px ; }
address { font-style : italic; }
listing, plaintext, pre, xmp {
font-family : monospace; white-space : pre;
}
dialog:not([open]) { display : none; }
dialog {
position : absolute;
inset-inline-start : 0 ; inset-inline-end : 0 ;
width : fit-content;
height : fit-content;
margin : auto;
border : solid;
padding : 1 em ;
background-color : Canvas;
color : CanvasText;
}
dialog:modal {
position : fixed;
overflow : auto;
inset-block : 0 ;
max-width : calc ( 100 % - 6 px - 2 em );
max-height : calc ( 100 % - 6 px - 2 em );
}
dialog::backdrop {
background : rgba ( 0 , 0 , 0 , 0.1 );
}
[popover]:not(:popover-open):not(dialog[open]) {
display : none;
}
dialog:popover-open {
display : block;
}
[popover] {
position : fixed;
inset : 0 ;
width : fit-content;
height : fit-content;
margin : auto;
border : solid;
padding : 0.25 em ;
overflow : auto;
color : CanvasText;
background-color : Canvas;
}
:popover-open::backdrop {
position : fixed;
inset : 0 ;
pointer-events : none !important;
background-color: transparent;
}
slot {
display: contents;
}
以下规则也应适用,作为呈现提示:
@namespace "http://www.w3.org/1999/xhtml" ;
pre[wrap] { white-space : pre-wrap; }
在怪癖模式下,以下规则也应适用:
@namespace "http://www.w3.org/1999/xhtml" ;
form { margin-block-end : 1 em ; }
center
元素,以及具有align
属性且该属性值为与字符串"center
"或字符串"middle
"的ASCII不区分大小写匹配的div
元素,应将文本居中,仿佛它们的'text-align'属性在呈现提示中被设置为'center',并且应将后代元素对齐到中心。
具有align
属性且该属性值为与字符串"left
"的ASCII不区分大小写匹配的div
元素,应将文本左对齐,仿佛它的'text-align'属性在呈现提示中被设置为'left',并且应将后代元素对齐到左边。
具有align
属性且该属性值为与字符串"right
"的ASCII不区分大小写匹配的div
元素,应将文本右对齐,仿佛它的'text-align'属性在呈现提示中被设置为'right',并且应将后代元素对齐到右边。
具有align
属性且该属性值为与字符串"justify
"的ASCII不区分大小写匹配的div
元素,应将文本两端对齐,仿佛它的'text-align'属性在呈现提示中被设置为'justify',并且应将后代元素对齐到左边。
@namespace "http://www.w3.org/1999/xhtml" ;
cite, dfn, em, i, var { font-style : italic; }
b, strong { font-weight : bolder; }
code, kbd, samp, tt { font-family : monospace; }
big { font-size : larger; }
small { font-size : smaller; }
sub { vertical-align : sub; }
sup { vertical-align : super; }
sub, sup { line-height : normal; font-size : smaller; }
ruby { display : ruby; }
rt { display : ruby-text; }
:link { color : #0000EE; }
:visited { color : #551A8B; }
:link:active, :visited:active { color : #FF0000; }
:link, :visited { text-decoration : underline; cursor : pointer; }
:focus-visible { outline : auto; }
mark { background : yellow; color : black; } /* this color is just a suggestion and can be changed based on implementation feedback */
abbr[title], acronym[title] { text-decoration : dotted underline; }
ins, u { text-decoration : underline; }
del, s, strike { text-decoration : line-through; }
q::before { content : open-quote; }
q::after { content : close-quote; }
br { display-outside : newline; } /* this also has bidi implications */
nobr { white-space : nowrap; }
wbr { display-outside : break-opportunity; } /* this also has bidi implications */
nobr wbr { white-space : normal; }
以下规则也应适用,作为呈现提示:
@namespace "http://www.w3.org/1999/xhtml" ;
br[clear=left i] { clear : left; }
br[clear=right i] { clear : right; }
br[clear=all i], br[clear=both i] { clear : both; }
对于CSS ruby模型,ruby
元素的子元素中,不是rt
或rp
元素的部分应包装在匿名框中,其'display'属性的值为'ruby-base'。[CSSRUBY]
当ruby的某个部分有多个注释时,注释应分布在基文字的两侧,以尽量减少一侧的ruby注释堆叠。
当可能时,上述要求将更新为用CSS ruby术语表达。(目前,CSS ruby不处理嵌套的ruby
元素或多个连续的rt
元素,这是表达这种语义的方式。)
不支持正确ruby渲染的用户代理应在没有rp
元素的情况下,在rt
元素的文本周围呈现括号。
用户代理应支持行内元素上的'clear'属性(以便按照CSS中非规范性注释中描述的方式呈现具有br
元素的clear
属性的元素)。
'color'属性的初始值应为黑色。'background-color'属性的初始值应为透明。画布的背景应为白色。
当font
元素具有color
属性时,应使用解析遗留颜色值的规则解析其值,并且如果该操作未返回错误,用户代理应将该属性视为呈现提示,将元素的'color'属性设置为结果颜色。
当font
元素具有face
属性时,用户代理应将该属性视为呈现提示,将元素的'font-family'属性设置为该属性的值。
当font
元素具有size
属性时,用户代理应使用以下步骤,称为解析遗留字体大小的规则,将该属性视为呈现提示,设置元素的'font-size'属性:
令input为属性的值。
令position为指向input的指针,初始指向字符串的开头。
如果position超出input的末尾,则没有呈现提示。返回。
如果position处的字符是U+002B加号字符(+),则将mode设为relative-plus,并将position前移一个字符。否则,如果position处的字符是U+002D连字符(-),则将mode设为relative-minus,并将position前移一个字符。否则,将mode设为absolute。
收集从position给定的input中的ASCII数字的代码点序列,并将结果序列设为digits。
如果digits为空字符串,则没有呈现提示。返回。
将digits解释为十进制整数。将value设为结果数字。
如果mode为relative-plus,则将value加3。如果mode为relative-minus,则将value减去3。
如果value大于7,则将其设为7。
如果value小于1,则将其设为1。
根据以下表格,将'font-size'设置为与value的值对应的关键字:
value | 'font-size'关键字 |
---|---|
1 | 'x-small' |
2 | 'small' |
3 | 'medium' |
4 | 'large' |
5 | 'x-large' |
6 | 'xx-large' |
7 | 'xxx-large' |
@namespace "http://www.w3.org/1999/xhtml" ;
[dir]:dir(ltr), bdi:dir(ltr), input[type=tel i]:dir(ltr) { direction : ltr; }
[dir]:dir(rtl), bdi:dir(rtl) { direction : rtl; }
address, blockquote, center, div, figure, figcaption, footer, form, header, hr,
legend, listing, main, p, plaintext, pre, summary, xmp, article, aside, h1, h2,
h3, h4, h5, h6, hgroup, nav, section, search, table, caption, colgroup, col,
thead, tbody, tfoot, tr, td, th, dir, dd, dl, dt, menu, ol, ul, li, bdi, output,
[dir=ltr i], [dir=rtl i], [dir=auto i] {
unicode-bidi : isolate;
}
bdo, bdo[dir] { unicode-bidi : isolate-override; }
input[dir=auto i]:is([type=search i], [type=tel i], [type=url i],
[type=email i]), textarea[dir=auto i], pre[dir=auto i] {
unicode-bidi : plaintext;
}
/* see prose for input elements whose type attribute is in the Text state */
/* the rules setting the 'content' property on br
and wbr
elements also has bidi implications */
当input
元素的dir
属性处于auto状态,并且其type
属性处于文本状态时,用户代理应表现得如同它具有一个用户代理级别的样式表规则,将'unicode-bidi'属性设置为'plaintext'。
输入字段(即textarea
元素,和input
元素,当其type
属性处于文本、搜索、电话、URL或电子邮件状态时)应显示一个与元素的'direction'属性相匹配的编辑用户界面。
当文档的字符编码为ISO-8859-8时,以下规则应附加于上述规则之后:[ENCODING]
@namespace "http://www.w3.org/1999/xhtml" ;
address, blockquote, center, div, figure, figcaption, footer, form, header, hr,
legend, listing, main, p, plaintext, pre, summary, xmp, article, aside, h1, h2,
h3, h4, h5, h6, hgroup, nav, section, search, table, caption, colgroup, col,
thead, tbody, tfoot, tr, td, th, dir, dd, dl, dt, menu, ol, ul, li, [dir=ltr i],
[dir=rtl i], [dir=auto i], *|* {
unicode-bidi : bidi-override;
}
input:not([type=submit i]):not([type=reset i]):not([type=button i]),
textarea {
unicode-bidi : normal;
}
@namespace "http://www.w3.org/1999/xhtml" ;
article, aside, h1, h2, h3, h4, h5, h6, hgroup, nav, section {
display : block;
}
h1 { margin-block : 0.67 em ; font-size : 2.00 em ; font-weight : bold; }
h2 { margin-block : 0.83 em ; font-size : 1.50 em ; font-weight : bold; }
h3 { margin-block : 1.00 em ; font-size : 1.17 em ; font-weight : bold; }
h4 { margin-block : 1.33 em ; font-size : 1.00 em ; font-weight : bold; }
h5 { margin-block : 1.67 em ; font-size : 0.83 em ; font-weight : bold; }
h6 { margin-block : 2.33 em ; font-size : 0.67 em ; font-weight : bold; }
在以下CSS块中,x是以下选择器的简写::is(article, aside, nav, section)
@namespace "http://www.w3.org/1999/xhtml" ;
x h1 { margin-block : 0.83 em ; font-size : 1.50 em ; }
x x h1 { margin-block : 1.00 em ; font-size : 1.17 em ; }
x x x h1 { margin-block : 1.33 em ; font-size : 1.00 em ; }
x x x x h1 { margin-block : 1.67 em ; font-size : 0.83 em ; }
x x x x x h1 { margin-block : 2.33 em ; font-size : 0.67 em ; }
此简写用于保持该块代码至少具有一定的可读性。
@namespace "http://www.w3.org/1999/xhtml" ;
dir, dd, dl, dt, menu, ol, ul { display : block; }
li { display : list-item; text-align : match-parent; }
dir, dl, menu, ol, ul { margin-block : 1 em ; }
:is(dir, dl, menu, ol, ul) :is(dir, dl, menu, ol, ul) {
margin-block : 0 ;
}
dd { margin-inline-start : 40 px ; }
dir, menu, ol, ul { padding-inline-start : 40 px ; }
ol, ul, menu { counter-reset : list-item; }
ol { list-style-type : decimal; }
dir, menu, ul {
list-style-type : disc;
}
:is(dir, menu, ol, ul) :is(dir, menu, ul) {
list-style-type : circle;
}
:is(dir, menu, ol, ul) :is(dir, menu, ol, ul) :is(dir, menu, ul) {
list-style-type : square;
}
以下规则也应适用,作为呈现提示:
@namespace "http://www.w3.org/1999/xhtml" ;
ol[type="1"], li[type="1"] { list-style-type : decimal; }
ol[type=a s], li[type=a s] { list-style-type : lower-alpha; }
ol[type=A s], li[type=A s] { list-style-type : upper-alpha; }
ol[type=i s], li[type=i s] { list-style-type : lower-roman; }
ol[type=I s], li[type=I s] { list-style-type : upper-roman; }
ul[type=none i], li[type=none i] { list-style-type : none; }
ul[type=disc i], li[type=disc i] { list-style-type : disc; }
ul[type=circle i], li[type=circle i] { list-style-type : circle; }
ul[type=square i], li[type=square i] { list-style-type : square; }
在渲染li
元素时,非CSS用户代理应使用li
元素的序数值来渲染列表项标记中的计数器。
对于CSS用户代理,渲染列表项的一些方面由CSS Lists规范定义。此外,以下属性映射应适用:[CSSLISTS]
当li
元素具有value
属性,并且使用解析整数的规则解析该属性的值没有产生错误时,用户代理应将解析后的值value作为呈现提示用于'counter-set'属性,形式为list-item value
。
当ol
元素具有start
属性或reversed
属性,或两者都有时,用户代理应使用以下步骤将这些属性视为呈现提示用于'counter-reset'属性:
令value为null。
如果元素具有reversed
属性,则:
如果value是整数,则将value增加1,并返回reversed(list-item) value
。
否则,返回reversed(list-item)
。
可能是start
属性不存在,或解析其值时产生了错误。
否则:
如果value是整数,则将value减少1,并返回list-item value
。
否则,没有呈现提示。
@namespace "http://www.w3.org/1999/xhtml" ;
table { display : table; }
caption { display : table-caption; }
colgroup, colgroup[hidden] { display : table-column-group; }
col, col[hidden] { display : table-column; }
thead, thead[hidden] { display : table-header-group; }
tbody, tbody[hidden] { display : table-row-group; }
tfoot, tfoot[hidden] { display : table-footer-group; }
tr, tr[hidden] { display : table-row; }
td, th { display : table-cell; }
colgroup[hidden], col[hidden], thead[hidden], tbody[hidden],
tfoot[hidden], tr[hidden] {
visibility : collapse;
}
table {
box-sizing : border-box;
border-spacing : 2 px ;
border-collapse : separate;
text-indent : initial;
}
td, th { padding : 1 px ; }
th { font-weight : bold; }
caption { text-align : center; }
thead, tbody, tfoot, table > tr { vertical-align : middle; }
tr, td, th { vertical-align : inherit; }
thead, tbody, tfoot, tr { border-color : inherit; }
table[rules=none i], table[rules=groups i], table[rules=rows i],
table[rules=cols i], table[rules=all i], table[frame=void i],
table[frame=above i], table[frame=below i], table[frame=hsides i],
table[frame=lhs i], table[frame=rhs i], table[frame=vsides i],
table[frame=box i], table[frame=border i],
table[rules=none i] > tr > td, table[rules=none i] > tr > th,
table[rules=groups i] > tr > td, table[rules=groups i] > tr > th,
table[rules=rows i] > tr > td, table[rules=rows i] > tr > th,
table[rules=cols i] > tr > td, table[rules=cols i] > tr > th,
table[rules=all i] > tr > td, table[rules=all i] > tr > th,
table[rules=none i] > thead > tr > td, table[rules=none i] > thead > tr > th,
table[rules=groups i] > thead > tr > td, table[rules=groups i] > thead > tr > th,
table[rules=rows i] > thead > tr > td, table[rules=rows i] > thead > tr > th,
table[rules=cols i] > thead > tr > td, table[rules=cols i] > thead > tr > th,
table[rules=all i] > thead > tr > td, table[rules=all i] > thead > tr > th,
table[rules=none i] > tbody > tr > td, table[rules=none i] > tbody > tr > th,
table[rules=groups i] > tbody > tr > td, table[rules=groups i] > tbody > tr > th,
table[rules=rows i] > tbody > tr > td, table[rules=rows i] > tbody > tr > th,
table[rules=cols i] > tbody > tr > td, table[rules=cols i] > tbody > tr > th,
table[rules=all i] > tbody > tr > td, table[rules=all i] > tbody > tr > th,
table[rules=none i] > tfoot > tr > td, table[rules=none i] > tfoot > tr > th,
table[rules=groups i] > tfoot > tr > td, table[rules=groups i] > tfoot > tr > th,
table[rules=rows i] > tfoot > tr > td, table[rules=rows i] > tfoot > tr > th,
table[rules=cols i] > tfoot > tr > td, table[rules=cols i] > tfoot > tr > th,
table[rules=all i] > tfoot > tr > td, table[rules=all i] > tfoot > tr > th {
border-color : black;
}
以下规则也应适用,作为呈现提示:
@namespace "http://www.w3.org/1999/xhtml" ;
table[align=left i] { float : left; }
table[align=right i] { float : right; }
table[align=center i] { margin-inline : auto; }
thead[align=absmiddle i], tbody[align=absmiddle i], tfoot[align=absmiddle i],
tr[align=absmiddle i], td[align=absmiddle i], th[align=absmiddle i] {
text-align : center;
}
caption[align=bottom i] { caption-side : bottom; }
p[align=left i], h1[align=left i], h2[align=left i], h3[align=left i],
h4[align=left i], h5[align=left i], h6[align=left i] {
text-align : left;
}
p[align=right i], h1[align=right i], h2[align=right i], h3[align=right i],
h4[align=right i], h5[align=right i], h6[align=right i] {
text-align : right;
}
p[align=center i], h1[align=center i], h2[align=center i], h3[align=center i],
h4[align=center i], h5[align=center i], h6[align=center i] {
text-align : center;
}
p[align=justify i], h1[align=justify i], h2[align=justify i], h3[align=justify i],
h4[align=justify i], h5[align=justify i], h6[align=justify i] {
text-align : justify;
}
thead[valign=top i], tbody[valign=top i], tfoot[valign=top i],
tr[valign=top i], td[valign=top i], th[valign=top i] {
vertical-align : top;
}
thead[valign=middle i], tbody[valign=middle i], tfoot[valign=middle i],
tr[valign=middle i], td[valign=middle i], th[valign=middle i] {
vertical-align : middle;
}
thead[valign=bottom i], tbody[valign=bottom i], tfoot[valign=bottom i],
tr[valign=bottom i], td[valign=bottom i], th[valign=bottom i] {
vertical-align : bottom;
}
thead[valign=baseline i], tbody[valign=baseline i], tfoot[valign=baseline i],
tr[valign=baseline i], td[valign=baseline i], th[valign=baseline i] {
vertical-align : baseline;
}
td[nowrap], th[nowrap] { white-space : nowrap; }
table[rules=none i], table[rules=groups i], table[rules=rows i],
table[rules=cols i], table[rules=all i] {
border-style : hidden;
border-collapse : collapse;
}
table[border] { border-style : outset; } /* only if border is not equivalent to zero */
table[frame=void i] { border-style : hidden; }
table[frame=above i] { border-style : outset hidden hidden hidden; }
table[frame=below i] { border-style : hidden hidden outset hidden; }
table[frame=hsides i] { border-style : outset hidden outset hidden; }
table[frame=lhs i] { border-style : hidden hidden hidden outset; }
table[frame=rhs i] { border-style : hidden outset hidden hidden; }
table[frame=vsides i] { border-style : hidden outset; }
table[frame=box i], table[frame=border i] { border-style : outset; }
table[border] > tr > td, table[border] > tr > th,
table[border] > thead > tr > td, table[border] > thead > tr > th,
table[border] > tbody > tr > td, table[border] > tbody > tr > th,
table[border] > tfoot > tr > td, table[border] > tfoot > tr > th {
/* only if border is not equivalent to zero */
border-width : 1 px ;
border-style : inset;
}
table[rules=none i] > tr > td, table[rules=none i] > tr > th,
table[rules=none i] > thead > tr > td, table[rules=none i] > thead > tr > th,
table[rules=none i] > tbody > tr > td, table[rules=none i] > tbody > tr > th,
table[rules=none i] > tfoot > tr > td, table[rules=none i] > tfoot > tr > th,
table[rules=groups i] > tr > td, table[rules=groups i] > tr > th,
table[rules=groups i] > thead > tr > td, table[rules=groups i] > thead > tr > th,
table[rules=groups i] > tbody > tr > td, table[rules=groups i] > tbody > tr > th,
table[rules=groups i] > tfoot > tr > td, table[rules=groups i] > tfoot > tr > th,
table[rules=rows i] > tr > td, table[rules=rows i] > tr > th,
table[rules=rows i] > thead > tr > td, table[rules=rows i] > thead > tr > th,
table[rules=rows i] > tbody > tr > td, table[rules=rows i] > tbody > tr > th,
table[rules=rows i] > tfoot > tr > td, table[rules=rows i] > tfoot > tr > th {
border-width : 1 px ;
border-style : none;
}
table[rules=cols i] > tr > td, table[rules=cols i] > tr > th,
table[rules=cols i] > thead > tr > td, table[rules=cols i] > thead > tr > th,
table[rules=cols i] > tbody > tr > td, table[rules=cols i] > tbody > tr > th,
table[rules=cols i] > tfoot > tr > td, table[rules=cols i] > tfoot > tr > th {
border-width : 1 px ;
border-block-style : none;
border-inline-style : solid;
}
table[rules=all i] > tr > td, table[rules=all i] > tr > th,
table[rules=all i] > thead > tr > td, table[rules=all i] > thead > tr > th,
table[rules=all i] > tbody > tr > td, table[rules=all i] > tbody > tr > th,
table[rules=all i] > tfoot > tr > td, table[rules=all i] > tfoot > tr > th {
border-width : 1 px ;
border-style : solid;
}
table[rules=groups i] > colgroup {
border-inline-width : 1 px ;
border-inline-style : solid;
}
table[rules=groups i] > thead,
table[rules=groups i] > tbody,
table[rules=groups i] > tfoot {
border-block-width : 1 px ;
border-block-style : solid;
}
table[rules=rows i] > tr, table[rules=rows i] > thead > tr,
table[rules=rows i] > tbody > tr, table[rules=rows i] > tfoot > tr {
border-block-width : 1 px ;
border-block-style : solid;
}
在怪癖模式下,以下规则也应适用:
@namespace "http://www.w3.org/1999/xhtml" ;
table {
font-weight : initial;
font-style : initial;
font-variant : initial;
font-size : initial;
line-height : initial;
white-space : initial;
text-align : initial;
}
出于CSS表格模型的目的,col
元素应被视为出现了其span
属性指定的次数。
出于CSS表格模型的目的,colgroup
元素,如果它不包含col
元素,则应被视为包含了与其span
属性指定的数量相同的子元素。
出于CSS表格模型的目的,colspan
和rowspan
属性在td
和th
元素上应提供关于跨行和跨列单元格的特殊知识,参见解析非负整数的规则。
在HTML文档中,还应适用以下规则:
@namespace "http://www.w3.org/1999/xhtml" ;
:is(table, thead, tbody, tfoot, tr) > form { display : none !important; }
table
元素的cellspacing
属性映射到像素长度属性,即元素上的'border-spacing'。
table
元素的cellpadding
属性映射到像素长度属性,即任何td
和th
元素的'padding-top'、'padding-right'、'padding-bottom'和'padding-left',这些元素在与对应table
元素的表格对应的单元格中。
table
元素的height
属性映射到尺寸属性,即元素上的'height'。
table
元素的width
属性映射到尺寸属性(忽略零),即元素上的'width'。
col
元素的width
属性映射到尺寸属性,即元素上的'width'。
thead
、tbody
和tfoot
元素的height
属性映射到尺寸属性,即元素上的'height'。
tr
元素的height
属性映射到尺寸属性,即元素上的'height'。
td
和th
元素的height
属性映射到尺寸属性(忽略零),即元素上的'height'。
td
和th
元素的width
属性映射到尺寸属性(忽略零),即元素上的'width'。
thead
、tbody
、tfoot
、tr
、td
和th
元素,当它们具有align
属性且该属性的值与字符串"center
"或字符串"middle
"进行ASCII大小写不敏感匹配时,预期会将文本居中对齐,仿佛它们的'text-align'属性已设置为“center”作为呈现提示,并将子元素对齐到中心。
thead
、tbody
、tfoot
、tr
、td
和th
元素,当它们具有align
属性且该属性的值与字符串"left
"进行ASCII大小写不敏感匹配时,预期会将文本左对齐,仿佛它们的'text-align'属性已设置为“left”作为呈现提示,并将子元素对齐到左侧。
thead
、tbody
、tfoot
、tr
、td
和th
元素,当它们具有align
属性且该属性的值与字符串"right
"进行ASCII大小写不敏感匹配时,预期会将文本右对齐,仿佛它们的'text-align'属性已设置为“right”作为呈现提示,并将子元素对齐到右侧。
thead
、tbody
、tfoot
、tr
、td
和th
元素,当它们具有align
属性且该属性的值与字符串"justify
"进行ASCII大小写不敏感匹配时,预期会将文本两端对齐,仿佛它们的'text-align'属性已设置为“justify”作为呈现提示,并将子元素对齐到左侧。
用户代理预期在其用户代理样式表中具有匹配th
元素的规则,这些元素的父节点的计算值的'text-align'属性是其初始值,该声明块仅由一个将'text-align'属性设置为“center”的声明组成。
当table
、thead
、tbody
、tfoot
、tr
、td
或th
元素具有background
属性且其值为非空时,新的值应根据元素的节点文档进行编码、解析和序列化,如果这不返回失败,用户代理应将该属性视为呈现提示,将元素的'background-image'属性设置为返回值。
当table
、thead
、tbody
、tfoot
、tr
、td
或th
元素具有bgcolor
属性时,新的值应根据解析遗留颜色值的规则进行解析,如果这不返回错误,用户代理应将该属性视为呈现提示,将元素的'background-color'属性设置为结果颜色。
当table
元素具有bordercolor
属性时,其值应根据解析遗留颜色值的规则进行解析,如果这不返回错误,用户代理应将该属性视为呈现提示,将元素的'border-top-color'、'border-right-color'、'border-bottom-color'和'border-left-color'属性设置为结果颜色。
table
元素的border
属性映射到像素长度属性,即元素上的'border-top-width'、'border-right-width'、'border-bottom-width'和'border-left-width'属性。如果该属性存在,但使用解析非负整数的规则解析该属性的值时生成错误,则预期该属性使用1px的默认值。
在上述CSS块中标记为“仅当边框不等于零时”的规则应仅在选择器中提到的border
属性不仅存在,而且在使用解析非负整数的规则解析时,发现其值不为零或生成错误时才应用。
在怪癖模式下,具有nowrap
属性但也具有width
属性的td
元素或th
元素,当其值在使用解析非零尺寸值的规则解析时被视为长度(不是错误或被归类为百分比的数字),应有一个设置元素的呈现提示,将元素的'white-space'属性设置为“normal”,覆盖上述CSS块中的规则,该规则将其设置为“nowrap”。
节点是实质性的,如果它是一个文本节点且不是元素间空白,或者如果它是一个元素节点。
节点是空白的,如果它是一个不包含实质性节点的元素。
具有默认边距的元素包括以下元素:blockquote
、dir
、dl
、h1
、h2
、h3
、h4
、h5
、h6
、listing
、menu
、ol
、p
、plaintext
、pre
、ul
和xmp
。
在怪癖模式中,任何具有默认边距的元素,如果它是body
、td
或th
元素的子节点且没有实质性的前一个兄弟节点,则应具有一个用户代理级别的样式表规则,将其'margin-block-start'属性设置为零。
在怪癖模式中,任何具有默认边距的元素,如果它是body
、td
或th
元素的子节点,没有实质性的前一个兄弟节点且是空白的,则应具有一个用户代理级别的样式表规则,将其'margin-block-end'属性也设置为零。
在怪癖模式中,任何具有默认边距的元素,如果它是td
或th
元素的子节点,没有实质性的后一个兄弟节点且是空白的,则应具有一个用户代理级别的样式表规则,将其'margin-block-start'属性设置为零。
在怪癖模式中,任何p
元素,如果它是td
或th
元素的子节点且没有实质性的后一个兄弟节点,则应具有一个用户代理级别的样式表规则,将其'margin-block-end'属性设置为零。
@namespace "http://www.w3.org/1999/xhtml" ;
input, select, button, textarea {
letter-spacing : initial;
word-spacing : initial;
line-height : initial;
text-transform : initial;
text-indent : initial;
text-shadow : initial;
appearance : auto;
}
input:not([type=image i], [type=range i], [type=checkbox i], [type=radio i]) {
overflow : clip !important;
overflow-clip-margin: 0 !important;
}
input, select, textarea {
text-align: initial;
}
:autofill {
field-sizing: fixed !important;
}
input:is([type=reset i], [type=button i], [type=submit i]), button {
text-align: center;
}
input, button {
display: inline-block;
}
input[type=hidden i], input[type=file i], input[type=image i] {
appearance: none;
}
input:is([type=radio i], [type=checkbox i], [type=reset i], [type=button i],
[type=submit i], [type=color i], [type=search i]), select, button {
box-sizing: border-box;
}
textarea { white-space: pre-wrap; }
在怪异模式下,预期还会应用以下规则:
@namespace "http://www.w3.org/1999/xhtml" ;
input:not([type=image i]), textarea { box-sizing : border-box; }
每种表单控件也在小部件部分进行了描述,该部分描述了控件的外观和感觉。
对于input
元素,当其type
属性不处于 状态或图像按钮状态,且该元素正在渲染时,预期应如下操作:
内部显示类型始终为 'flow-root'。
hr
元素@namespace "http://www.w3.org/1999/xhtml" ;
hr {
color : gray;
border-style : inset;
border-width : 1 px ;
margin-block : 0.5 em ;
margin-inline : auto;
overflow : hidden;
}
以下规则也预期会作为表现提示适用:
@namespace "http://www.w3.org/1999/xhtml" ;
hr[align=left i] { margin-left : 0 ; margin-right : auto; }
hr[align=right i] { margin-left : auto; margin-right : 0 ; }
hr[align=center i] { margin-left : auto; margin-right : auto; }
hr[color], hr[noshade] { border-style : solid; }
如果一个hr
元素具有color
属性或noshade
属性,并且还具有size
属性,并且使用解析非负整数的规则解析该属性的值不会产生错误,那么预期用户代理将使用解析值除以二作为像素长度,为该元素的表现提示属性'border-top-width'、'border-right-width'、'border-bottom-width'和'border-left-width'设置提示。
否则,如果一个hr
元素既没有color
属性也没有noshade
属性,但具有size
属性,并且使用解析非负整数的规则解析该属性的值不会产生错误,那么:如果解析值为1,则预期用户代理将使用该属性作为表现提示,将元素的'border-bottom-width'设置为0;否则,如果解析值大于1,则预期用户代理将使用解析值减二作为像素长度,为元素的表现提示属性'height'设置提示。
当hr
元素具有color
属性时,预期其值将使用解析传统颜色值的规则进行解析,并且如果解析不返回错误,用户代理应将该属性视为表现提示,将元素的'color'属性设置为结果颜色。
fieldset
元素和legend
元素@namespace "http://www.w3.org/1999/xhtml" ;
fieldset {
display : block;
margin-inline : 2 px ;
border : groove 2 px ThreeDFace;
padding-block : 0.35 em 0.625 em ;
padding-inline : 0.75 em ;
min-inline-size : min-content;
}
legend {
padding-inline : 2 px ;
}
legend[align=left i] {
justify-self : left;
}
legend[align=center i] {
justify-self : center;
}
legend[align=right i] {
justify-self : right;
}
该元素预期将建立一个新的块格式化上下文。
'display'属性的预期行为如下:
如果'display'的计算值是外部显示类型为 'inline' 的值,则行为应为 'inline-block'。
否则,行为应为 'flow-root'。
这不会改变计算值。
如果元素的盒子有一个符合下列条件的子盒子,那么第一个这样的子盒子是 'fieldset' 元素的已渲染legend:
legend
元素。
如果元素有一个已渲染legend,则边框预期不会在使用fieldset书写模式定义的矩形背后绘制:
分配给元素块起始边的边框空间应为元素的'border-block-start-width'或已渲染legend的边距框尺寸(在fieldset的块流方向),取两者之大者。
用于计算使用的'block-size'时,如果计算的'block-size'不是 'auto',那么分配给已渲染legend的边距框超过边框的空间(如果有的话)应从'block-size'中减去。如果内容框的块大小为负数,则将其设置为零。
如果元素有已渲染legend,则该元素应为第一个子盒子。
匿名fieldset内容盒应出现在已渲染legend之后,并且应包含fieldset
元素的内容(包括
'::before' 和 '::after' 伪元素),但不包括已渲染legend(如果有)。
'padding-top'、'padding-right'、'padding-bottom'和'padding-left'属性的使用值应为零。
计算最小内容内联大小时,使用已渲染legend的最小内容内联大小和匿名fieldset内容盒的最小内容内联大小中的较大值。
计算最大内容内联大小时,使用已渲染legend的最大内容内联大小和匿名fieldset内容盒的最大内容内联大小中的较大值。
fieldset
元素的已渲染legend(如果有的话),预期行为如下:
'display'属性应表现为其计算值已被块化。
这不会改变计算值。
如果计算值为'inline-size'的值为 'auto',那么使用值应为适合内容的内联大小。
该元素应在内联方向上定位,就像块级元素一样(例如,考虑边距和'justify-self'属性)。
元素的盒子在内联方向上应由fieldset
的内联内容大小约束,就像它使用了其计算的内联填充一样。
例如,如果fieldset
指定了50px的填充,那么已渲染legend将在距离fieldset
边框50px的位置。填充将进一步应用于匿名fieldset内容盒,而不是fieldset
元素本身。
元素应在块流方向上定位,使其边框盒子位于fieldset
元素的块起始边框上方。
fieldset
元素的匿名fieldset内容盒预期行为如下:
'display'属性的预期行为如下:
以下属性应从fieldset
元素继承:
'block-size'属性的值应设置为 '100%'。
计算百分比填充时,应视为填充是为fieldset
元素计算的。
以下元素可以是替换元素:audio
,canvas
,embed
,iframe
,img
,input
,object
,以及video
。
embed
、iframe
和 video
元素预计会被视为替换元素。
当 canvas
元素表示嵌入内容时,预计它会被视为替换元素;此类元素的内容是元素的位图(如果有),否则是与元素具有相同自然尺寸的透明黑色位图。其他
canvas
元素预计会在渲染模型中被视为普通元素。
object
元素表示图像、插件或其内容导航时,预计会被视为替换元素。其他
object
元素预计会在渲染模型中被视为普通元素。
当 audio
元素显示用户界面时,预计会被视为高度大约为一行、宽度为所需的用户代理的用户界面特性,以便暴露的替换元素。当
audio
元素未显示用户界面时,预计用户代理会强制将其'display' 属性计算为 'none',无论CSS规则如何。
video
元素是否显示用户界面预计不会影响渲染大小;控件预计会覆盖在页面内容上方,不会引起任何布局变化,并且当用户不需要它们时预计会消失。
当 video
元素显示海报帧或视频帧时,预计海报帧或视频帧会按保持该海报帧或视频帧的纵横比的最大尺寸渲染,且不会超过 video
元素本身的高度或宽度,并且预计会居中显示在 video
元素中。
任何字幕或说明预计会直接覆盖在其video
元素上,如相关的渲染规则所定义的那样;对于WebVTT,这些规则是更新WebVTT文本轨道显示的规则。[WEBVTT]
当用户代理开始显示 video
元素的用户界面时,用户代理应运行该 更新文本轨道渲染的规则,以处理 video
元素中 文本轨道列表 中显示的且文本轨道类型为
subtitles
或 captions
的每个文本轨道(例如,对于基于WebVTT的文本轨道,则为更新WebVTT文本轨道显示的规则)。[WEBVTT]
调整 video
和 canvas
元素大小不会中断视频播放或清除画布。
预计以下CSS规则会被应用:
@namespace "http://www.w3.org/1999/xhtml" ;
iframe { border : 2 px inset; }
video { object-fit : contain; }
用户代理预计会根据以下列表中的第一个适用规则来渲染 img
元素和
input
元素,这些元素的
type
属性处于 图像按钮状态:
input
元素,预计该元素看起来像一个按钮,以指示该元素是一个按钮。
img
元素,并且该元素表示一些文本,且用户代理不期望这种情况发生变化img
元素,并且该元素表示为空,且用户代理不期望这种情况发生变化input
元素,且该元素未表示图片,且用户代理不期望这种情况发生变化上面提到的图标预计相对较小,以便不会干扰大多数文本,但易于点击。例如,在视觉环境中,图标可以是16像素乘16像素的正方形,或者如果图像可缩放,则为1em乘1em。在音频环境中,图标可以是一个短促的哔声。图标旨在向用户指示它们可以用于访问用户代理提供的图像选项,并且在适当的情况下,预计可以访问用户与实际图像交互时会弹出的上下文菜单。
所有具有相同绝对URL和相同图像数据的动画图像预计会同步到同一时间轴作为一个组渲染,时间轴从组中最近添加的时间点开始。
换句话说,当第二个具有相同绝对URL和动画图像数据的图像插入到文档中时,它会跳到动画周期中当前由第一个图像显示的点。
当用户代理需要重新启动动画以显示动画图像的 img
元素时,具有相同绝对URL和相同图像数据的所有动画图像预计会在该 img
元素的节点文档中从头开始重新启动它们的动画。
预计以下CSS规则会被应用:
@namespace "http://www.w3.org/1999/xhtml" ;
img:is([sizes="auto" i], [sizes^="auto," i]) {
contain : size !important;
contain-intrinsic-size: 300px 150px;
}
当 Document
处于怪异模式时,预计以下CSS规则会被应用:
@namespace "http://www.w3.org/1999/xhtml" ;
img[align=left i] { margin-right : 3 px ; }
img[align=right i] { margin-left : 3 px ; }
预计以下CSS规则会作为表现提示应用:
@namespace "http://www.w3.org/1999/xhtml" ;
iframe[frameborder='0'], iframe[frameborder=no i] { border : none; }
embed[align=left i], iframe[align=left i], img[align=left i],
input[type=image i][align=left i], object[align=left i] {
float : left;
}
embed[align=right i], iframe[align=right i], img[align=right i],
input[type=image i][align=right i], object[align=right i] {
float : right;
}
embed[align=top i], iframe[align=top i], img[align=top i],
input[type=image i][align=top i], object[align=top i] {
vertical-align : top;
}
embed[align=baseline i], iframe[align=baseline i], img[align=baseline i],
input[type=image i][align=baseline i], object[align=baseline i] {
vertical-align : baseline;
}
embed[align=texttop i], iframe[align=texttop i], img[align=texttop i],
input[type=image i][align=texttop i], object[align=texttop i] {
vertical-align : text-top;
}
embed[align=absmiddle i], iframe[align=absmiddle i], img[align=absmiddle i],
input[type=image i][align=absmiddle i], object[align=absmiddle i],
embed[align=abscenter i], iframe[align=abscenter i], img[align=abscenter i],
input[type=image i][align=abscenter i], object[align=abscenter i] {
vertical-align : middle;
}
embed[align=bottom i], iframe[align=bottom i], img[align=bottom i],
input[type=image i][align=bottom i], object[align=bottom i] {
vertical-align : bottom;
}
当 embed
、iframe
、img
或 object
元素,或者 input
元素,其 type
属性处于 Image Button 状态时,且具有
align
属性,其值与字符串 "center
" 或 "middle
" 进行 ASCII
不区分大小写 匹配时,用户代理预期会将该元素的 'vertical-align' 属性设置为将元素的垂直中线与父元素基线对齐的值。
hspace
属性在 embed
、img
或 object
元素,以及 input
元素中,其 type
属性处于 Image Button 状态,映射到维度属性的 'margin-left' 和 'margin-right' 属性。
vspace
属性在 embed
、img
或 object
元素,以及 input
元素中,其 type
属性处于 Image Button 状态,映射到维度属性的 'margin-top' 和 'margin-bottom' 属性。
当 img
元素、object
元素或 input
元素,其 type
属性处于 Image Button 状态时,并且其
border
属性的值在使用 解析非负整数的规则
解析时,发现其值大于零,则用户代理预计会将解析后的值用于八个 表现提示:四个设置解析后的值作为像素长度,用于元素的 'border-top-width'、'border-right-width'、'border-bottom-width' 和 'border-left-width' 属性,另外四个则设置元素的 'border-top-style'、'border-right-style'、'border-bottom-style' 和 'border-left-style' 属性为 'solid'。
width
和 height
属性在 img
元素的 尺寸属性源 映射到维度属性 'width' 和 'height'
分别对应于
img
元素。它们同样 映射到比例属性(使用尺寸规则)
的 img
元素。
width
和 height
属性在 embed
、iframe
、object
和 video
元素,以及 input
元素中,其 type
属性处于 Image Button
状态,并且要么表示图像,要么用户预计最终将表示图像,映射到维度属性 'width' 和 'height'
分别对应于该元素。
width
和 height
属性 映射到比例属性(使用尺寸规则)
的 img
和 video
元素,以及 input
元素中,其 type
属性处于 Image Button 状态。
width
和 height
属性 映射到比例属性 的 canvas
元素。
在 图像映射上的形状在 CSS 层叠的目的下,预计会表现为独立于原始的
area
元素的元素,这些元素恰好匹配相同的样式规则,但继承自 img
或
object
元素。
在渲染过程中,预计只有 'cursor' 属性会对形状产生任何影响。
因此,例如,如果一个 area
元素具有一个
style
属性,该属性将 'cursor' 属性设置为 'help',那么当用户指示该形状时,光标将变为帮助光标。
类似地,如果一个 area
元素有一个 CSS
规则,将其 'cursor' 属性设置为 'inherit'(或者如果没有设置 'cursor'
属性的规则匹配该元素),则该形状的光标将继承自 img
或
object
元素,而不是继承自 area
元素的父元素。
CSS 基础用户界面 规范称可以具有原生外观的元素为小部件,并根据 'appearance' 属性定义是否使用该 原生外观。该逻辑依赖于元素是被分类为 可退化的小部件还是 不可退化的小部件。本节定义了哪些元素与 HTML 的这些概念相符,它们的原生外观是什么,以及它们的退化状态或 基本外观的任何特殊性。 [CSSUI]
以下元素可以具有 原生外观,以便于 CSS 'appearance' 属性的使用。
有几个小部件的渲染是由 'writing-mode' CSS 属性控制的。对于这些小部件,我们有以下定义。
当解析控件的 'writing-mode' 属性时,计算值为 'horizontal-tb' 时,则为水平书写模式。
当解析控件的 'writing-mode' 属性时,计算值为 'vertical-rl'、'vertical-lr'、'sideways-rl' 或 'sideways-lr' 时,则为垂直书写模式。
当一个元素使用按钮布局时,它是一个可退化小部件,并且其本地外观与按钮相同。
按钮布局如下:
如果该元素是绝对定位的,则对于CSS 可视化格式模型的目的,表现为该元素是替换元素。[CSS]
如果计算值为'inline-size'是 'auto',则使用值为适应内容的内联大小。
为了'align-self'属性中的 'normal' 关键字的目的,表现为该元素是一个替换元素。
如果该元素是input
元素,或者如果它是一个button
元素且其'display'的计算值不是 'inline-grid'、'grid'、'inline-flex' 或
'flex',则该元素的框有一个子匿名按钮内容框,具有以下行为:
否则,没有匿名按钮内容框。
需要定义预期的原始外观。
button
元素button
元素在生成 CSS 盒子时,预期表现为一个按钮,并使用 按钮布局,其 匿名按钮内容盒子的内容(如果有 匿名按钮内容盒子)将是该元素的盒子原本应该拥有的子盒子。
details
和 summary
元素@namespace "http://www.w3.org/1999/xhtml" ;
details, summary {
display : block;
}
details > summary:first-of-type {
display : list-item;
counter-increment : list-item 0 ;
list-style : disclosure-closed inside;
}
details[open] > summary:first-of-type {
list-style-type : disclosure-open;
}
details
元素应当具有一个内部的 shadow
tree,其中包含三个子元素:
第一个子元素是一个 slot
,该元素应当接收
details
元素的第一个 summary
子元素(如果有的话)。该元素有一个单独的 summary
子元素,称为 默认摘要,其文本内容是 实现定义(并且可能与区域设置相关)。
这个 summary
元素表示允许用户请求显示或隐藏详细信息。
第二个子元素是一个 slot
,该元素应当接收
details
元素的其余后代(如果有的话)。该元素没有内容。
此元素应当匹配 '::details-content' 伪元素。
当 details
元素没有 open
属性时,此元素的 style
属性应设置为 "display: block; content-visibility: hidden;
"。当其具有 open
属性时,该元素的 style
属性应设置为 "display: block;
"。
由于这些 slot 隐藏在 shadow tree 中,这个 style
属性对作者代码是不可见的。然而,其影响是可见的。尤其是,选择 content-visibility: hidden
而不是 display: none
会影响查询布局信息的各种 API 的结果。
第三个子元素是一个 link
或 style
元素,具有以下针对 默认摘要 的样式:
:host summary {
display : list-item;
counter-increment : list-item 0 ;
list-style : disclosure-closed inside;
}
:host([open]) summary {
list-style-type : disclosure-open;
}
此子元素相对于其他两个子元素的位置是不可观察的。这意味着实现可能会将其与其兄弟元素顺序不同。实现甚至可能使用非元素的机制将样式与 shadow tree 关联起来。
通过 details
元素及 '::details-content' 伪元素对 CSS 样式的响应,可以观察到这个 shadow tree 的结构。
input
元素作为文本输入控件当 input
元素的 type
属性处于 文本、电话、URL 或 电子邮件 状态时,它是一个 可转化的控件。其预期的 原生外观 是呈现为一个
'inline-block' 框,显示为单行文本控件。
当 input
元素的 type
属性处于 搜索
状态时,它是一个 可转化的控件。其预期的 原生外观 是呈现为一个
'inline-block' 框,显示为单行文本控件。如果该元素的 计算值 的 'appearance' 属性不是 'textfield'
,它可能具有不同的样式,表明它是一个搜索字段。
当 input
元素的 type
属性处于 密码 状态时,它是一个 可转化的控件。其预期的 原生外观 是呈现为一个
'inline-block' 框,显示为掩码输入数据的单行文本控件。
对于 input
元素,其 type
属性处于上述状态之一,使用值的 'line-height' 属性必须是一个不小于 使用值为 'line-height:
normal' 的长度值。
使用值 将不会是实际的关键字 'normal'。此外,此规则不会影响 计算值。
如果这些文本控件提供文本选择,则当用户更改当前选择时,用户代理应 排队一个元素任务 在 用户交互任务源 上,给定 input
元素以 触发事件
名为
select
在元素上,bubbles
属性初始化为 true。
当 input
元素的 type
属性处于上述状态之一,它是一个 具有默认首选大小的元素,并且用户代理应应用 'field-sizing'
CSS 属性到该元素。用户代理应按以下步骤确定其 内联大小 的 内在大小:
如果元素上的 'field-sizing' 属性的 计算值 为 'content',则内联大小由元素显示的文本决定。文本可以是 值 或由 placeholder
属性指定的简短提示。用户代理可能会在内联大小中考虑文本插入符号的大小。
如果元素有一个 size
属性,并且使用 解析非负整数的规则
解析该属性的值不会产生错误,则返回通过应用 将字符宽度转换为像素
算法到该属性值所获得的值。
否则,返回通过应用 将字符宽度转换为像素 算法到数字20所获得的值。
将字符宽度转换为像素的算法返回 (size-1)×avg + max,其中 size 是要转换的字符宽度,avg 是元素的主要字体的平均字符宽度(以像素为单位),max 是同一字体的最大字符宽度(也以像素为单位)。(元素的 'letter-spacing' 属性不影响结果。)
这些文本控件应当是 滚动容器 并支持在 内联轴 上的滚动,而不是 块轴。
input
元素作为特定领域的控件
input
元素的 type
属性处于 日期 状态时,是一个 可演变控件,预期渲染为一个显示日期控件的
'inline-block' 块。
input
元素的 type
属性处于 月份 状态时,是一个 可演变控件,预期渲染为一个显示月份控件的
'inline-block' 块。
input
元素的 type
属性处于 周 状态时,是一个 可演变控件,预期渲染为一个显示周控件的
'inline-block' 块。
input
元素的 type
属性处于 时间 状态时,是一个 可演变控件,预期渲染为一个显示时间控件的
'inline-block' 块。
input
元素的 type
属性处于 本地日期和时间
状态时,是一个 可演变控件,预期渲染为一个显示本地日期和时间控件的 'inline-block' 块。
input
元素的 type
属性处于 数字 状态时,是一个 可演变控件,预期渲染为一个显示数字控件的
'inline-block' 块。
input
元素的 type
属性处于 数字 状态时,是一个 具有默认首选大小的元素,用户代理预期会将 'field-sizing'
CSS 属性应用于该元素。块尺寸的 固有尺寸大约为
一行高。如果该元素上的 'field-sizing'
属性的 计算值为 'content',则该元素的 内联尺寸的 固有尺寸预期应约为展示当前
值所需的宽度。否则,该元素的
内联尺寸的 固有尺寸预期应约为展示最宽可能值所需的宽度。
input
元素的 type
属性处于 日期、月份、周、时间或
本地日期和时间
状态时,预期应约为一行高,并约为展示最宽可能值所需的宽度。
input
元素作为范围控制input
元素,其 type
属性处于 范围
状态,是一个不可降级的小部件。其预期的本地外观
应呈现为一个显示滑块控制的“inline-block”框。
当此控件具有水平书写模式时,控件预计为水平滑块。如果“direction”属性的计算值为“rtl”,则其最小值在右侧,否则在左侧。当此控件具有垂直书写模式时,预计为垂直滑块。如果“direction”属性的计算值为“rtl”,则其最小值在底部,否则在顶部。
建议的预定义值(由 list
属性提供)预计显示为滑块上的刻度标记,滑块可以对其对齐。
需要详细说明预期的基本外观。
input
元素作为颜色选择器input
元素,其 type
属性处于 颜色
状态时,预计会显示一个颜色选择器,当激活时,它会为用户提供一个颜色选择工具(例如色轮或调色板),用户可以从中更改颜色。当元素生成 CSS 盒 时,预计会使用按钮布局,该布局没有 匿名按钮内容框的子框。匿名按钮内容框预计会有一个将 表现提示 设置为元素的“background-color”属性的值。
建议的预定义值(由 list
属性提供)预计显示在颜色选择界面中,而不是颜色选择器本身。
input
元素作为复选框和单选按钮部件
input
元素,其 type
属性处于 复选框 状态,是一个不可降级的小部件,预计会渲染为包含单个复选框控件的“inline-block”框,无标签。
input
元素,其 type
属性处于 单选按钮
状态,是一个不可降级的小部件,预计会渲染为包含单个单选按钮控件的“inline-block”框,无标签。
input
元素作为文件上传控件input
元素,其 type
属性处于 文件上传 状态时,当它生成 CSS 盒 时,预计会渲染为一个包含文本段的 “inline-block” 框,显示(如果有的话)已选择文件
的文件名,后面跟着一个按钮,激活时为用户提供一个文件选择器,用户可以通过该选择器更改选择。该按钮预计使用按钮布局,并与 “::file-selector-button” 伪元素匹配。其 匿名按钮内容框 的内容预计为实现定义(可能与区域相关)的文本,例如“选择文件”。
用户代理可以将 input
元素的 type
属性处于 文件上传 状态时视为具有默认首选大小的元素,并且用户代理可以将 “field-sizing”
CSS 属性应用于该元素。如果该元素上的“field-sizing”
属性的计算值为 “content”,则该元素的 固有大小
预计取决于其内容,例如
“::file-selector-button” 伪元素和已选择的文件名。
input
元素作为按钮input
元素,其 type
属性处于 提交按钮、重置按钮 或 按钮
状态时,当它生成
CSS 盒 时,预计会显示为一个按钮,并使用按钮布局,匿名按钮内容框的内容预计为元素的 value
属性的文本(如果有的话),否则为从元素的 type
属性派生的文本,按照 实现定义(可能与区域相关)的方式处理。
marquee
元素@namespace "http://www.w3.org/1999/xhtml" ;
marquee {
display : inline-block;
text-align : initial;
overflow : hidden !important;
}
当 marquee
元素开启时,预计根据其属性以下列方式以动画形式渲染:
behavior
属性处于
scroll 状态
按照 direction
属性描述的方向滑动元素的内容,如下所述,使其从 marquee
的起始边缘开始,最终与内侧终止边缘对齐。
例如,如果 direction
属性为 left(默认值),则内容将从其左边缘位于 marquee
的右边缘之外开始,然后内容将滑动到其左边缘与 marquee
的左内侧边缘对齐的点。
一旦动画结束,预计用户代理会增加 marquee 当前循环索引。如果在此之后该元素仍然开启,则预计用户代理会重新启动动画。
behavior
属性处于
slide 状态
按照 direction
属性描述的方向滑动元素的内容,如下所述,使其从 marquee
的起始边缘开始,并在 marquee
的终止边缘外结束。
例如,如果 direction
属性为 left(默认值),则内容将从其左边缘位于 marquee
的右边缘之外开始,然后内容将滑动到其右边缘与 marquee
的左内侧边缘对齐的点。
一旦动画结束,预计用户代理会增加 marquee 当前循环索引。如果在此之后该元素仍然开启,则预计用户代理会重新启动动画。
behavior
属性处于
alternate 状态
当 marquee
当前循环索引 为偶数(或零)时,按照 direction
属性描述的方向滑动元素的内容,如下所述,使其从 marquee
的起始边缘与内侧对齐,并在 marquee
的终止边缘与内侧对齐处结束。
当 marquee
当前循环索引 为奇数时,按照与 direction
属性描述的方向相反的方向滑动元素的内容,如下所述,使其从 marquee
的终止边缘与内侧对齐,并在 marquee
的起始边缘与内侧对齐处结束。
例如,如果 direction
属性为 left(默认值),则内容将从其右边缘与 marquee
的右内侧边缘对齐开始,然后内容将滑动到其左边缘与 marquee
的左内侧边缘对齐的点。
一旦动画结束,预计用户代理会增加 marquee 当前循环索引。如果在此之后该元素仍然开启,则预计用户代理会继续动画。
direction
属性的含义如下表所示:
direction
属性状态
|
动画方向 | 起始边缘 | 终止边缘 | 相反方向 |
---|---|---|---|---|
left | ← 右到左 | 右 | 左 | → 左到右 |
right | → 左到右 | 左 | 右 | ← 右到左 |
up | ↑ 上(下到上) | 下 | 上 | ↓ 下(上到下) |
down | ↓ 下(上到下) | 上 | 下 | ↑ 上(下到上) |
在任何情况下,动画应以每帧之间有一个由 marquee 滚动间隔 给出的延迟进行,并且内容每帧最多移动由 marquee 滚动距离 给出的距离。
当 marquee
元素设置了 bgcolor
属性时,预计该值将使用 解析旧版颜色值的规则
进行解析,如果不返回错误,预计用户代理将把该属性视为设置元素的表现提示的一个“background-color” 属性。
在 marquee
元素上的 width
和 height
属性映射到维度属性,即元素上的 “width” 和 “height” 属性。
当 marquee
元素的 direction
属性处于 up 或 down 状态时,其自然高度为 200 CSS 像素。
marquee
元素的 vspace
属性映射到维度属性,即元素上的“margin-top” 和 “margin-bottom” 属性。marquee
元素的 hspace
属性映射到维度属性,即元素上的“margin-left” 和 “margin-right” 属性。
meter
元素@namespace "http://www.w3.org/1999/xhtml" ;
meter { appearance : auto; }
meter
元素是一个可降级的小部件。其预期的本地外观应呈现为一个“inline-block”框,具有 “block-size” 为“1em”和“inline-size”为“5em”,“vertical-align”为“-0.2em”,其内容显示为一个量表。
当此元素具有水平书写模式时,预计显示为水平量表。如果“direction”属性的计算值为“rtl”,则其最小值在右侧,否则在左侧。当此元素具有垂直书写模式时,预计显示为垂直量表。如果“direction”属性的计算值为“rtl”,则其最小值在底部,否则在顶部。
预计用户代理会使用与平台惯例一致的展示方式来显示量表(如果有)。
在量表中必须显示的内容要求包含在 meter
元素的定义中。
需要详细说明预期的基本外观。
progress
元素@namespace "http://www.w3.org/1999/xhtml" ;
progress { appearance : auto; }
progress
元素是一个可降级的小部件。其预期的本地外观应呈现为一个
“inline-block” 框,具有 “block-size” 为“1em”,“inline-size”为“10em”,“vertical-align”为“-0.2em”。
当此元素具有水平书写模式时,预计显示为一个水平进度条。如果此元素的“direction”属性的计算值为“rtl”,则起始点在右侧,终点在左侧;否则,起始点在左侧,终点在右侧。当此元素具有垂直书写模式时,预计显示为一个垂直进度条。如果此元素的“direction”属性的计算值为“rtl”,则起始点在底部,终点在顶部;否则,起始点在顶部,终点在底部。
预计用户代理会使用与平台惯例一致的展示方式来显示进度条。特别是,预计用户代理会为确定性和不确定性进度条使用不同的展示方式。用户代理还预计会根据元素的尺寸调整展示方式。
如何确定进度条是确定性还是不确定性的要求,以及确定性进度条应显示的进度内容,包含在 progress
元素的定义中。
需要详细说明预期的基本外观。
select
元素select
元素是一个具有默认首选大小的元素,预计用户代理会将“field-sizing” CSS 属性应用于select
元素。
select
元素根据其属性可以是一个列表框或下拉框。
select
元素如果存在 multiple
属性,预计会渲染为一个多选列表框。
select
元素如果不存在 multiple
属性,且其显示大小大于1,预计会渲染为一个单选列表框。
当元素渲染为列表框时,它是一个可降级的小部件,预计会渲染为一个“inline-block”框。其内联大小的固有大小是“select”标签的宽度加上滚动条的宽度。其块大小的固有大小由以下步骤确定:
如果元素上的“field-sizing”属性的计算值为“content”,则返回容纳所有项目行所需的高度。
如果 size
属性不存在或没有有效值,则返回容纳四行所需的高度。
否则,返回容纳由元素的显示大小给定的行数所需的高度。
select
元素如果不存在 multiple
属性,且其显示大小为1,预计会渲染为一个“inline-block”的一行下拉框。其内联大小的固有大小是“select”标签的宽度。如果元素上的“field-sizing”属性的计算值为“content”,则其内联大小的固有大小取决于显示的文本。显示的文本通常是一个option的标签,其选中状态为 true。
当元素渲染为下拉框时,它是一个可降级的小部件。在降级状态下的外观,以及当元素的计算值为“appearance”属性为“menulist-button”
时的外观,都是下拉框,包括一个“下拉按钮”,但不一定使用主操作系统的原生控件渲染。在这种状态下,“color”、“background-color” 和 'border' 等 CSS 属性不应被忽略(如在根据其本地外观渲染元素时通常允许的那样)。
在任何情况下(列表框或下拉框),该元素的项目预计是元素的选项列表,元素的optgroup
元素的子元素(如果有)为选项组提供标题。
optgroup
元素预计通过显示元素的 label
属性来渲染。
option
元素预计通过显示元素的 label来渲染,并在其所属的
optgroup
元素下缩进显示(如果有)。
每个包含一个或多个子 hr
元素的序列可以渲染为一个分隔符。
“select”标签的宽度是渲染最宽的optgroup
元素和渲染最宽的option
元素(包括其缩进,如果有)的宽度中的较宽者。
如果 select
元素包含一个占位符标签选项,预计用户代理会以传达其是标签而不是控件有效选项的方式渲染该 option
。这可以包括防止用户明确选择占位符标签选项。当 占位符标签选项 的选中状态为 true
时,预计控件会以表示当前未选择有效选项的方式显示。
预计用户代理会以在标签作为页面一部分显示或在菜单控件中显示时都保持一致对齐的方式渲染 select
中的标签。
textarea
元素textarea
元素是一个可降级的小部件,预计渲染为一个“inline-block”框,显示一个多行文本控件。如果此多行文本控件提供了一个选区,则当用户更改当前选区时,预计用户代理会队列化一个元素任务,在用户交互任务源中给予该textarea
元素,触发一个事件,名为select
,并将
bubbles
属性初始化为 true。
textarea
元素是一个具有默认首选大小的元素,预计用户代理会将“field-sizing” CSS 属性应用于textarea
元素。
如果元素上的“field-sizing”属性的计算值为“content”,其固有大小由元素显示的文本确定。文本可以是原始值或由placeholder
属性指定的简短提示。用户代理可以在确定固有大小时考虑文本光标的大小。否则,其固有大小是根据textarea 有效宽度和textarea
有效高度(如以下定义)计算的。
textarea 有效宽度是textarea
元素的size×avg + sbw,其中size是元素的字符宽度,avg是元素主字体的平均字符宽度,以CSS 像素为单位,sbw是滚动条的宽度,以CSS 像素为单位。(元素的“letter-spacing” 属性不影响结果。)
textarea 有效高度是textarea
元素的高度,以CSS 像素为单位,由元素的字符高度指定的行数加上滚动条的高度(以CSS 像素为单位)组成。
预计用户代理会将“white-space” CSS 属性应用于textarea
元素。由于历史原因,如果元素具有wrap
属性,其值与字符串“off
”进行ASCII
大小写不敏感匹配,则预计用户代理会将该属性视为设置元素表现提示的一个属性,设置元素的“white-space”属性为“pre”。
预计用户代理将 frameset
元素渲染为一个具有 视口 高度和宽度的框,其表面按照以下布局算法进行渲染:
cols 和 rows 变量是由数字和单位(单位为 百分比、相对和绝对 之一)组成的零个或多个对的列表。
使用 解析尺寸列表的规则 解析元素的 cols
属性值(如果有)。将 cols 设为结果,如果没有此类属性,则为空列表。
使用 解析尺寸列表的规则 解析元素的 rows
属性值(如果有)。将 rows 设为结果,如果没有此类属性,则为空列表。
对于 cols 或 rows 中单位为 相对 的条目,如果数字为零,则将条目的数字更改为一。
如果 cols 没有条目,则在 cols 中添加一个值为 1 且单位为 相对 的条目。
如果 rows 没有条目,则在 rows 中添加一个值为 1 且单位为 相对 的条目。
调用以下定义的算法将尺寸列表转换为像素值列表,使用
cols 作为输入列表,并以 frameset
所渲染表面的宽度(以CSS 像素为单位)作为输入尺寸。将结果列表设为 sized cols。
调用以下定义的算法将尺寸列表转换为像素值列表,使用
rows 作为输入列表,并以 frameset
所渲染表面的高度(以CSS 像素为单位)作为输入尺寸。将结果列表设为 sized rows。
将表面分割成 w×h 的矩形网格,其中 w 是 sized cols 中的条目数,h 是 sized rows 中的条目数。
设置列的大小,使得网格中的每一列的宽度都与 sized cols 列表中对应条目的像素值相同。
设置行的大小,使得网格中的每一行的高度都与 sized rows 列表中对应条目的像素值相同。
将 children 设为frame
和 frameset
元素的列表,这些元素是调用该算法的 frameset
元素的子元素。
对于在前一步中创建的矩形网格的每一行,从上到下执行以下子步骤:
如果 frameset
元素有边框,则围绕矩形绘制一组外边框,使用元素的框架边框颜色。
对于每个矩形,如果该矩形被分配了一个元素,并且该元素有边框,则围绕该矩形绘制一组内边框,使用元素的框架边框颜色。
对于每一个(可见的)边框,如果它没有与分配了 frame
元素且带有
noresize
属性的矩形相邻(包括进一步嵌套的 frameset
元素中的矩形),则预计用户代理允许用户移动边框,重新调整矩形的大小,同时保持嵌套 frameset
网格的比例。
一个 frameset
或
frame
元素是否有边框,取决于以下算法是否返回 true:
如果元素有一个 frameborder
属性,其值不为空字符串且第一个字符为 U+0031 数字 1(1)字符、U+0079 小写字母 y(y)字符或 U+0059 大写字母
Y(Y)字符,则返回 true。
否则,如果元素有 frameborder
属性,则返回 false。
否则,如果元素有一个父元素且该父元素是一个 frameset
元素,则如果该元素有边框则返回 true,否则返回
false。
否则,返回 true。
框架边框颜色是 frameset
或 frame
元素的颜色,按以下算法获得:
如果元素有 bordercolor
属性,并且将解析传统颜色值的规则
应用于该属性的值时没有导致错误,则返回所获得的颜色。
否则,返回灰色。
将尺寸列表转换为像素值列表的算法包括以下步骤:
将 input list 设为传递给该算法的数字和单位的列表。
将 output list 设为与 input list 长度相同且所有值均为零的数字列表。
output list 中的条目对应于 input list 中具有相同位置的条目。
将 input dimension 设为传递给算法的大小。
将 count percentage 设为 input list 中单位为 百分比 的条目数。
将 total percentage 设为 input list 中单位为 百分比 的所有数字的总和。
将 count relative 设为 input list 中单位为 相对 的条目数。
将 total relative 设为 input list 中单位为 相对 的所有数字的总和。
将 count absolute 设为 input list 中单位为 绝对 的条目数。
将 total absolute 设为 input list 中单位为 绝对 的所有数字的总和。
将 remaining space 设为 input dimension 的值。
如果 total absolute 大于 remaining space,则对于 input list 中单位为 绝对 的每个条目,将 output list 中对应的值设为 input list 中该条目的数字乘以 remaining space 再除以 total absolute。然后,将 remaining space 设为零。
否则,对于 input list 中单位为 绝对 的每个条目,将 output list 中对应的值设为 input list 中该条目的数字。然后,将 remaining space 减去 total absolute。
如果 total percentage 乘以 input dimension 并除以 100 大于 remaining space,则对于 input list 中单位为 百分比 的每个条目,将 output list 中对应的值设为 input list 中该条目的数字乘以 remaining space 并除以 total percentage。然后,将 remaining space 设为零。
否则,对于 input list 中单位为 百分比 的每个条目,将 output list 中对应的值设为 input list 中该条目的数字乘以 input dimension 并除以 100。然后,将 remaining space 减去 total percentage 乘以 input dimension 并除以 100。
对于 input list 中单位为 相对 的每个条目,将 output list 中对应的值设为 input list 中该条目的数字乘以 remaining space 并除以 total relative。
返回 output list。
对于以整数值处理框架宽度的用户代理(与可以以子像素精度布局框架的用户代理不同),预计它们会首先将余数分配给单位为 相对 的最后一个条目,然后平均分配(而不是按比例分配)给单位为 百分比 的每个条目,再平均分配(而不是按比例分配)给单位为 绝对 的每个条目,最后,所有其他方法都失败时,分配给最后一个条目。
没有 frameset
父元素的
frame
元素的内容预计会被渲染为 透明黑;在这种情况下,预计用户代理不会渲染其 可导航内容,并且其可导航内容预计会有一个宽度和高度为零的 视口。
预计用户代理允许用户控制超链接激活和表单提交的各个方面,例如用于后续导航的可导航对象。
预计用户代理允许用户在触发导航之前,发现超链接和表单的目的地。
预计用户代理会告知用户某个超链接是否包含超链接审计,并至少告知用户哪些域将作为此类审计的一部分被联系。
用户代理可以允许用户将可导航对象 导航到由cite
属性指示的
URL解析,包括 q
,blockquote
,ins
和 del
元素。
用户代理可以在其用户界面中显示由link
元素创建的超链接,如之前讨论的那样。
title
属性预计用户代理在用户请求时公开元素的建议性信息,并让用户了解此类信息的存在。
在用户可以使用指针设备的交互式图形系统上,这可以采用工具提示的形式。当用户无法使用指针设备时,预计用户代理会通过其他方式使内容可用,例如将该元素设为可聚焦区域并始终显示当前聚焦元素的建议性信息,或在触摸设备上,当用户在屏幕上移动时,显示用户手指下元素的建议性信息。
预计 U+000A 换行符(LF)字符会在工具提示中引起换行;预计 U+0009 字符制表符(tab)字符会呈现为非零水平位移,使下一个字形与下一个制表位对齐,制表位出现在 U+0020 空格字符宽度的 8 倍的倍数处。
再例如,屏幕阅读器在读取带有工具提示的元素时可以提供音频提示,并配有一个键,用于读取上一个播放提示的工具提示。
当前的文本编辑插入符(即活动范围,如果它是空的并且在编辑容器中),预计在 CSS 渲染模型中表现为一个内联的替换元素,其垂直尺寸为插入符的高度,宽度为零。
这意味着即使是一个空块也可以包含插入符,并且当插入符位于这样的元素中时,它会阻止边距在元素内折叠。
用户代理应遵循在用户界面中暴露的文本的Unicode语义,例如在对话框、标题栏、弹出菜单和工具提示中显示的文本中支持双向算法。来自元素内容的文本应以尊重该元素的方向性的方式呈现。来自属性的文本应以尊重该属性方向性的方式呈现。
考虑以下标记,其中包含希伯来语文本,用于选择编程语言,鉴于某些名称中的标点符号,语言文本的从左到右方向性非常重要:
< p dir = "rtl" lang = "he" >
< label >
בחר שפת תכנות:
< select >
< option dir = "ltr" > C++</ option >
< option dir = "ltr" > C#</ option >
< option dir = "ltr" > FreePascal</ option >
< option dir = "ltr" > F#</ option >
</ select >
</ label >
</ p >
如果select
元素呈现为下拉框,正确的呈现应确保标点符号在下拉框中和显示当前选择的框中相同。
属性的方向性取决于属性本身以及元素的dir
属性,如以下示例所示。考虑以下标记:
< table >
< tr >
< th abbr = "(א" dir = ltr > A
< th abbr = "(א" dir = rtl > A
< th abbr = "(א" dir = auto > A
</ table >
如果abbr
属性呈现,例如在工具提示或其他用户界面中,第一个将显示左括号(因为方向是'ltr'),第二个将显示右括号(因为方向是'rtl'),第三个将显示右括号(因为方向从属性值中确定为'rtl')。
然而,如果属性不是方向性支持属性,结果将有所不同:
< table >
< tr >
< th data-abbr = "(א" dir = ltr > A
< th data-abbr = "(א" dir = rtl > A
< th data-abbr = "(א" dir = auto > A
</ table >
在这种情况下,如果用户代理在用户界面中显示data-abbr
属性(例如在调试环境中),最后一种情况下将显示一个左括号,因为方向将从元素内容中确定。
由脚本提供的字符串(例如window.alert()
的参数)在显示时应作为一个或多个双向算法段落的独立集合处理,如双向算法所定义的那样,包括支持U+000A换行符字符的段落中断行为。为了确定双向算法中此类文本的段落级别,本规范不会为规则P2和P3提供更高级别的覆盖。[BIDI]
在必要时,作者可以通过在段落开头插入Unicode U+200E从左到右标记或U+200F从右到左标记字符来强制执行特定方向。
因此,以下脚本:
alert( '\u05DC\u05DE\u05D3 HTML \u05D4\u05D9\u05D5\u05DD!' )
...将始终显示一条消息:"למד LMTH היום!"(而不是"דמל HTML םויה!"),无论用户代理界面的语言是什么,页面或其任何元素的方向如何。
对于更复杂的示例,请考虑以下脚本:
/* Warning: this script does not handle right-to-left scripts correctly */
var s;
if ( s = prompt( 'What is your name?' )) {
alert( s + '! Ok, Fred, ' + s + ', and Wilma will get the car.' );
}
当用户输入"Kitty"时,用户代理将提示"Kitty! 好的, Fred, Kitty, 和 Wilma 会去取车。"。然而,如果用户输入"لا أفهم",则双向算法将确定段落的方向为从右到左,因此输出将成为以下意想不到的混乱情况:"لا أفهم! derF ,kO, لا أفهم, rac eht teg lliw amliW dna."。
为了强制从用户提供的文本(或其他未知方向性的文本)开始的提示框呈现为从左到右,可以在字符串前加上U+200E从左到右标记字符:
var s;
if ( s = prompt( 'What is your name?' )) {
alert( ' \u200E ' + s + '! Ok, Fred, ' + s + ', and Wilma will get the car.' );
}
用户代理应允许用户请求获得获取物理形式(或物理形式的表示)文档
的机会。例如,选择打印页面或将其转换为PDF格式的选项。[PDF]
当用户实际获取物理形式(或物理形式的表示)文档
时,用户代理应为打印媒体创建该文档
的新渲染。
HTML用户代理在某些情况下可能会渲染非HTML文档,这些文档使用的词汇表可能是用户代理没有内置知识的。本节为用户代理提供了一种处理这些文档的有用方式。
当文档
符合以下条件时,它是一个无样式文档:
文档
没有作者样式表(无论是通过HTTP头、处理指令、类似link
的元素、内联元素如style
,或任何其他机制引用)。
文档
中的任何元素都没有表现提示。
文档
中的任何元素都没有任何样式属性。文档
中的任何元素都不属于以下命名空间:HTML命名空间,SVG命名空间,MathML命名空间。文档
没有任何可聚焦区域(例如来自XLink的),除视口外。文档
没有超链接(例如来自XLink的)。Window
对象,并且这个文档
是其关联的Document
。文档
中的任何元素都没有注册事件监听器。
无样式文档视图是指DOM没有按照CSS渲染(在这种情况下,由于没有适用的样式,最终只会产生一堆文本),而是以对开发者有用的方式进行渲染。它可以只是显示文档
对象的源代码,可能带有语法高亮,或者显示DOM树,或者仅仅显示一条消息,说明页面不是样式化文档。
如果文档
不再是无样式文档,则上述条件不再适用,因此,遵循这些要求的用户代理将切换到使用常规的CSS渲染。
本节中列出的功能将在合规性检查器中触发警告。
作者不应在border
属性上为img
元素指定值。如果此属性存在,则其值必须是字符串“0
”。应使用CSS代替。
作者不应在charset
属性上为script
元素指定值。如果此属性存在,其值必须是“utf-8
”的ASCII不区分大小写匹配字符串。(在符合本标准其他要求的文档中,这不会产生任何影响,这些文档应以UTF-8编码。)
作者不应在language
属性上为script
元素指定值。如果此属性存在,其值必须是字符串“JavaScript
”的ASCII不区分大小写匹配,并且type
属性必须省略,或者其值必须是字符串“text/javascript
”的ASCII不区分大小写匹配。此属性应完全省略(使用“JavaScript
”作为值时,它不会产生任何影响),或者使用type
属性代替。
作者不应在script
元素的type
属性上指定值为空字符串或为JavaScript MIME类型本质匹配。相反,应该省略该属性,这将产生相同的效果。
作者不应在style
元素上指定type
属性。如果该属性存在,其值必须与“text/css
”的ASCII不区分大小写匹配。
作者不应在a
元素上指定name
属性。如果该属性存在,其值不得为空字符串,并且不得等于元素所在树中任何ID的值(除非是元素自身的ID),也不得等于元素所在树中任何其他name
属性的值。如果此属性存在,并且元素有一个ID,那么属性值必须等于元素的ID。在早期版本的语言中,此属性旨在为URL中的片段指定可能的目标。应改用id
属性。
作者不应(尽管在本规范的其他部分有相反的要求)在input
元素上指定maxlength
和size
属性,这些元素的type
属性处于Number状态。尽管如此,一个合理的原因是,为了帮助不支持input
元素的旧版用户代理,这些旧版用户代理无法正确渲染带有type="number"
的文本控件。
为了简化从HTML4过渡到本规范定义的语言,并为了劝阻在极少数情况下才允许的某些功能,合规性检查器必须在文档中使用以下功能时向用户发出警告。这些通常是没有效果的旧的废弃功能,仅允许用于区分可能的错误(常规的合规性错误)和仅仅是残留标记或不常见且不推荐的做法(这些警告)。
以下功能必须如上所述分类:
在charset
属性值与“utf-8
”的ASCII不区分大小写匹配的情况下,script
元素上出现此属性。
在language
属性值与字符串“JavaScript
”的ASCII不区分大小写匹配的情况下,script
元素上出现此属性,并且如果没有type
属性,或者有该属性并且其值与字符串“text/javascript
”的ASCII不区分大小写匹配。
在type
属性值为JavaScript MIME类型本质匹配的情况下,script
元素上出现此属性。
在type
属性值与“text/css
”的ASCII不区分大小写匹配的情况下,style
元素上出现此属性。
合规性检查器必须区分没有合规性错误且没有这些废弃功能的页面和没有合规性错误但有这些废弃功能的页面。
例如,验证器可以将某些页面报告为“有效的HTML”,而将其他页面报告为“带有警告的有效HTML”。
以下列表中的元素已完全废弃,作者不得使用:
applet
acronym
请改用abbr
。
bgsound
请改用audio
。
dir
请改用ul
。
frame
frameset
noframes
请改用iframe
和CSS,或使用服务器端包含生成包含各个不变部分的完整页面。
isindex
keygen
对于企业设备管理的使用场景,请使用设备本地的管理功能。
对于证书注册的使用场景,请使用Web Cryptography API生成证书的密钥对,然后导出证书和密钥,以允许用户手动安装它们。[WEBCRYPTO]
listing
menuitem
要实现自定义上下文菜单,请使用脚本处理contextmenu
事件。
nextid
请改用GUID。
noembed
param
plaintext
请改用"text/plain
"MIME类型。
rb
rtc
strike
xmp
basefont
big
blink
center
font
marquee
multicol
nobr
spacer
tt
请改用适当的元素或CSS。
如果tt
元素曾用于标记键盘输入,请考虑使用kbd
元素;对于变量,请考虑使用var
元素;对于计算机代码,请考虑使用code
元素;对于计算机输出,请考虑使用samp
元素。
同样,如果big
元素用于表示标题,请考虑使用h1
元素;如果它用于标记重要段落,请考虑使用strong
元素;如果用于突出显示参考目的的文本,请考虑使用mark
元素。
另请参见文本级语义使用摘要,其中提供了更多建议和示例。
以下属性已废弃(尽管元素仍然是语言的一部分),作者不得使用:
charset
在a
元素上charset
在link
元素上
请改用链接资源上的HTTP `Content-Type
`
头。
charset
在script
元素上(除了前一部分中提到的情况)
coords
在a
元素上
shape
在a
元素上
对于图像映射,请改用area
元素。
methods
在a
元素上
methods
在link
元素上
请改用HTTP OPTIONS功能。
name
在a
元素上(除了前一部分中提到的情况)
name
在embed
元素上
name
在img
元素上
name
在option
元素上
请改用id
属性。
rev
在a
元素上
rev
在link
元素上
请改用rel
属性,并使用相反的术语。(例如,不使用rev="made"
,而使用rel="author"
。)
urn
在a
元素上
urn
在link
元素上
请改用href
属性指定首选持久标识符。
accept
在form
元素上
hreflang
在area
元素上
type
在area
元素上
这些属性没有任何实用作用,出于历史原因,area
元素上没有相应的IDL属性。请完全省略它们。
nohref
在area
元素上
profile
在head
元素上
不必要。请完全省略它。
manifest
在html
元素上
请改用服务工作线程。[SW]
version
在html
元素上
不必要。请完全省略它。
ismap
在input
元素上
usemap
在input
元素上
usemap
在object
元素上
对于图像映射,请改用img
元素。
longdesc
在iframe
元素上
longdesc
在img
元素上
lowsrc
在img
元素上
请改用渐进式JPEG图像(在src
属性中给出),而不是使用两个单独的图像。
target
在link
元素上
不必要。请完全省略它。
type
在menu
元素上
要实现自定义上下文菜单,请使用脚本处理contextmenu
事件。对于工具栏菜单,请省略此属性。
label
在menu
元素上
contextmenu
在所有元素上onshow
在所有元素上要实现自定义上下文菜单,请使用脚本处理contextmenu
事件。
scheme
在meta
元素上
每个字段仅使用一个方案,或使方案声明成为值的一部分。
archive
在object
元素上
classid
在object
元素上
code
在object
元素上
codebase
在object
元素上
codetype
在object
元素上
declare
在object
元素上
每次重新使用资源时,请完全重复object
元素。
standby
在object
元素上
优化链接资源,使其加载速度更快,或至少是增量加载。
typemustmatch
在object
元素上
避免使用带有不受信任资源的object
元素。
language
在script
元素上(除了前一部分中提到的情况)
event
在script
元素上
for
在script
元素上
请使用DOM事件机制来注册事件监听器。[DOM]
type
在style
元素上(除了前一部分中提到的情况)
datapagesize
在table
元素上
不必要。请完全省略它。
summary
在table
元素上
abbr
在td
元素上
请使用以明确简洁方式开头的文本,并在之后包括任何更详细的文本。title
属性也可以在包括更详细的文本时有用,以便使单元格的内容简洁。如果是标题,请使用th
(它有一个abbr
属性)。
axis
在td
和th
元素上
scope
在td
元素上
对于标题单元格,请使用th
元素。
datasrc
在 a
、button
、div
、frame
、iframe
、img
、input
、label
、legend
、marquee
、object
、option
、select
、span
和 table
元素上datafld
在 a
、button
、div
、fieldset
、frame
、iframe
、img
、input
、label
、legend
、marquee
、object
、select
、span
和 textarea
元素上dataformatas
在 button
、div
、input
、label
、legend
、marquee
、object
、option
、select
、span
和 table
元素上使用脚本和诸如 XMLHttpRequest
等机制来动态填充页面。[XHR]
dropzone
在所有元素上alink
在body
元素上
bgcolor
在body
元素上
bottommargin
在body
元素上
leftmargin
在body
元素上
link
在body
元素上
marginheight
在body
元素上
marginwidth
在body
元素上
rightmargin
在body
元素上
text
在body
元素上
topmargin
在body
元素上
vlink
在body
元素上
clear
在br
元素上
align
在caption
元素上
align
在col
元素上
char
在col
元素上
charoff
在col
元素上
valign
在col
元素上
width
在col
元素上
align
在div
元素上
compact
在dl
元素上
align
在embed
元素上
hspace
在embed
元素上
vspace
在embed
元素上
align
在hr
元素上
color
在hr
元素上
noshade
在hr
元素上
size
在hr
元素上
width
在hr
元素上
align
在h1
—h6
元素上
align
在iframe
元素上
allowtransparency
在iframe
元素上
frameborder
在iframe
元素上
framespacing
在iframe
元素上
hspace
在iframe
元素上
marginheight
在iframe
元素上
marginwidth
在iframe
元素上
scrolling
在iframe
元素上
vspace
在iframe
元素上
align
在input
元素上
border
在input
元素上
hspace
在input
元素上
vspace
在input
元素上
align
在img
元素上
border
在img
元素上(除了前一部分中提到的情况)
hspace
在img
元素上
vspace
在img
元素上
align
在legend
元素上
type
在li
元素上
compact
在menu
元素上
align
在object
元素上
border
在object
元素上
hspace
在object
元素上
vspace
在object
元素上
compact
在ol
元素上
align
在p
元素上width
在pre
元素上
align
在table
元素上
bgcolor
在table
元素上
border
在table
元素上
bordercolor
在table
元素上
cellpadding
在table
元素上
cellspacing
在table
元素上
frame
在table
元素上
height
在table
元素上
rules
在table
元素上
width
在table
元素上
align
在tbody
、thead
和tfoot
元素上
char
在tbody
、thead
和tfoot
元素上
charoff
在tbody
、thead
和tfoot
元素上
height
在thead
、tbody
和tfoot
元素上
valign
在tbody
、thead
和tfoot
元素上
align
在td
和th
元素上
bgcolor
在td
和th
元素上
char
在td
和th
元素上
charoff
在td
和th
元素上
height
在td
和th
元素上
nowrap
在td
和th
元素上
valign
在td
和th
元素上
width
在td
和th
元素上
align
在tr
元素上
bgcolor
在tr
元素上
char
在tr
元素上
charoff
在tr
元素上
height
在tr
元素上
valign
在tr
元素上
compact
在ul
元素上
type
在ul
元素上
background
在body
、table
、thead
、tbody
、tfoot
、tr
、td
和th
元素上
请使用CSS。
marquee
元素marquee
元素是一个用于动画内容的表现元素。CSS 过渡和动画是更合适的机制。[CSSANIMATIONS] [CSSTRANSITIONS]
marquee
元素必须实现 HTMLMarqueeElement
接口。
[Exposed =Window ]
interface HTMLMarqueeElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString behavior ;
[CEReactions ] attribute DOMString bgColor ;
[CEReactions ] attribute DOMString direction ;
[CEReactions ] attribute DOMString height ;
[CEReactions ] attribute unsigned long hspace ;
[CEReactions ] attribute long loop ;
[CEReactions ] attribute unsigned long scrollAmount ;
[CEReactions ] attribute unsigned long scrollDelay ;
[CEReactions ] attribute boolean trueSpeed ;
[CEReactions ] attribute unsigned long vspace ;
[CEReactions ] attribute DOMString width ;
undefined start ();
undefined stop ();
};
当调用 start()
方法时,marquee
元素必须打开。
当调用 stop()
方法时,marquee
元素必须关闭。
behavior
属性在
marquee
元素上是一个枚举属性,具有以下关键字和状态(均不符合标准):
关键字 | 状态 |
---|---|
scroll |
scroll |
slide |
slide |
alternate |
alternate |
direction
属性在 marquee
元素上是一个枚举属性,具有以下关键字和状态(均不符合标准):
关键字 | 状态 |
---|---|
left |
left |
right |
right |
up |
up |
down |
down |
truespeed
属性在 marquee
元素上是一个布尔属性。
marquee
元素具有一个滚动间隔,通过以下方式获得:
如果元素具有scrolldelay
属性,并且使用解析非负整数的规则解析其值时未返回错误,则将delay设置为解析后的值。否则,将delay设置为85。
如果元素没有truespeed
属性,并且delay值小于60,则将delay设置为60。
滚动间隔为delay,以毫秒为单位。
marquee
元素具有一个滚动距离,如果元素具有scrollamount
属性,并且使用解析非负整数的规则解析其值时未返回错误,则该值以CSS
像素为单位解析,否则为6CSS 像素。
marquee
元素具有一个循环次数,如果元素具有loop
属性,并且使用解析整数的规则解析其值时未返回错误或数字小于1,则该值为解析后的值,否则为-1。
loop
IDL属性在获取时,必须返回元素的循环次数;在设置时,如果新值与元素的循环次数不同,并且大于零或等于-1,则必须将元素的loop
内容属性(如有必要)设置为表示新值的有效整数。(其他值将被忽略。)
marquee
元素还具有一个当前循环索引,该索引在元素创建时为零。
渲染层偶尔会增加当前循环索引,这将导致运行以下步骤:
behavior
、direction
、height
、hspace
、vspace
和width
IDL属性必须反映同名内容属性。
bgColor
IDL属性必须反映 bgcolor
内容属性。
scrollAmount
IDL属性必须反映 scrollamount
内容属性。默认值为6。
scrollDelay
IDL属性必须反映 scrolldelay
内容属性。默认值为85。
trueSpeed
IDL属性必须反映 truespeed
内容属性。
frameset
元素在使用框架的文档中充当body 元素。
frameset
元素必须实现 HTMLFrameSetElement
接口。
[Exposed =Window ]
interface HTMLFrameSetElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString cols ;
[CEReactions ] attribute DOMString rows ;
};
HTMLFrameSetElement includes WindowEventHandlers ;
cols
和
rows
IDL
属性必须反映同名内容属性。
frameset
元素公开了一些事件处理程序内容属性,这些属性属于
Window
对象的事件处理程序。它还会镜像其事件处理程序 IDL
属性。
Window
对象的事件处理程序,由Window
反映 body 元素事件处理程序集命名,在
frameset
元素上公开时,替换了通常由HTML 元素支持的具有相同名称的通用事件处理程序。
frame
元素具有类似于 iframe
元素的可导航内容,但在 frameset
元素中呈现。
frame
的HTML
元素插入步骤,给定 insertedNode,如下:
如果 insertedNode 不在文档树中,则返回。
为 insertedNode 处理
frame
属性,并将 initialInsertion 设置为 true。
frame
的HTML
元素删除步骤,给定 removedNode,是销毁给定 removedNode 的子导航。
每当具有非空可导航内容的 frame
元素的 src
属性被设置、更改或删除时,用户代理必须处理
frame
属性。
为元素 element 处理 frame
属性,可选地带有布尔值 initialInsertion:
让 url 是在给定 element 和 initialInsertion 的情况下运行iframe 和 frame 元素的共享属性处理步骤的结果。
如果 url 为 null,则返回。
如果 url 匹配
about:blank
并且 initialInsertion 为 true,则:
frame
元素必须实现 HTMLFrameElement
接口。
[Exposed =Window ]
interface HTMLFrameElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString name ;
[CEReactions ] attribute DOMString scrolling ;
[CEReactions ] attribute USVString src ;
[CEReactions ] attribute DOMString frameBorder ;
[CEReactions ] attribute USVString longDesc ;
[CEReactions ] attribute boolean noResize ;
readonly attribute Document ? contentDocument ;
readonly attribute WindowProxy ? contentWindow ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString marginHeight ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString marginWidth ;
};
name
、scrolling
和
src
IDL
属性必须反映同名内容属性。为反映的目的,frame
元素的 src
内容属性被定义为包含URL。
frameBorder
IDL 属性必须反映元素的 frameborder
内容属性。
longDesc
IDL 属性必须反映元素的 longdesc
内容属性,该属性为反映的目的被定义为包含URL。
noResize
IDL 属性必须反映元素的 noresize
内容属性。
marginHeight
IDL 属性必须反映元素的 marginheight
内容属性。
marginWidth
IDL 属性必须反映元素的 marginwidth
内容属性。
contentDocument
的获取步骤是返回this的内容文档。
contentWindow
的获取步骤是返回this的内容窗口。
用户代理必须将acronym
元素视为与abbr
元素在语义和渲染目的上等效。
partial interface HTMLAnchorElement {
[CEReactions ] attribute DOMString coords ;
[CEReactions ] attribute DOMString charset ;
[CEReactions ] attribute DOMString name ;
[CEReactions ] attribute DOMString rev ;
[CEReactions ] attribute DOMString shape ;
};
coords
、
charset
、
name
、rev
和shape
IDL
属性必须反映同名内容属性。
partial interface HTMLAreaElement {
[CEReactions ] attribute boolean noHref ;
};
noHref
IDL
属性必须反映元素的nohref
内容属性。
partial interface HTMLBodyElement {
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString text ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString link ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString vLink ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString aLink ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString bgColor ;
[CEReactions ] attribute DOMString background ;
};
bgColor
IDL
属性必须反映元素的bgcolor
内容属性。
background
IDL 属性必须反映元素的background
内容属性。(background
内容不是
被定义为包含URL,尽管在上面的渲染部分中有处理它的规则。)
partial interface HTMLBRElement {
[CEReactions ] attribute DOMString clear ;
};
clear
IDL
属性必须反映同名内容属性。
partial interface HTMLTableCaptionElement {
[CEReactions ] attribute DOMString align ;
};
align
IDL 属性必须反映同名内容属性。
partial interface HTMLTableColElement {
[CEReactions ] attribute DOMString align ;
[CEReactions ] attribute DOMString ch ;
[CEReactions ] attribute DOMString chOff ;
[CEReactions ] attribute DOMString vAlign ;
[CEReactions ] attribute DOMString width ;
};
align
和width
IDL
属性必须反映同名内容属性。
chOff
IDL 属性必须反映元素的charoff
内容属性。
vAlign
IDL 属性必须反映元素的valign
内容属性。
用户代理必须将dir
元素
视为与ul
元素在语义和渲染目的上等效。
dir
元素必须实现HTMLDirectoryElement
接口。
[Exposed =Window ]
interface HTMLDirectoryElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute boolean compact ;
};
compact
IDL 属性必须反映同名内容属性。
partial interface HTMLDivElement {
[CEReactions ] attribute DOMString align ;
};
align
IDL
属性必须反映同名内容属性。
partial interface HTMLDListElement {
[CEReactions ] attribute boolean compact ;
};
compact
IDL
属性必须反映同名内容属性。
partial interface HTMLEmbedElement {
[CEReactions ] attribute DOMString align ;
[CEReactions ] attribute DOMString name ;
};
name
和
align
IDL
属性必须反映同名内容属性。
font
元素
必须实现HTMLFontElement
接口。
[Exposed =Window ]
interface HTMLFontElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString color ;
[CEReactions ] attribute DOMString face ;
[CEReactions ] attribute DOMString size ;
};
color
、
face
和
size
IDL
属性必须反映同名内容属性。
partial interface HTMLHeadingElement {
[CEReactions ] attribute DOMString align ;
};
align
IDL
属性必须反映同名内容属性。
profile
IDL 属性在head
元素上(与
HTMLHeadElement
接口一起)是故意省略的。除非其他适用的规范有此要求其他适用规范,
实现因此不会支持此属性。(这里提到它是因为它在以前版本的DOM中定义过。)
partial interface HTMLHRElement {
[CEReactions ] attribute DOMString align ;
[CEReactions ] attribute DOMString color ;
[CEReactions ] attribute boolean noShade ;
[CEReactions ] attribute DOMString size ;
[CEReactions ] attribute DOMString width ;
};
align
、
color
、size
和width
IDL
属性必须反映同名内容属性。
noShade
IDL
属性必须反映元素的noshade
内容属性。
partial interface HTMLHtmlElement {
[CEReactions ] attribute DOMString version ;
};
version
IDL 属性必须反映同名内容属性。
partial interface HTMLIFrameElement {
[CEReactions ] attribute DOMString align ;
[CEReactions ] attribute DOMString scrolling ;
[CEReactions ] attribute DOMString frameBorder ;
[CEReactions ] attribute USVString longDesc ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString marginHeight ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString marginWidth ;
};
align
和scrolling
IDL 属性必须反映同名内容属性。
frameBorder
IDL 属性必须反映元素的frameborder
内容属性。
longDesc
IDL 属性必须反映元素的longdesc
内容属性,出于反映的目的,
定义为包含URL。
marginHeight
IDL 属性必须反映元素的marginheight
内容属性。
marginWidth
IDL 属性必须反映元素的marginwidth
内容属性。
partial interface HTMLImageElement {
[CEReactions ] attribute DOMString name ;
[CEReactions ] attribute USVString lowsrc ;
[CEReactions ] attribute DOMString align ;
[CEReactions ] attribute unsigned long hspace ;
[CEReactions ] attribute unsigned long vspace ;
[CEReactions ] attribute USVString longDesc ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString border ;
};
name
、
align
、
border
、
hspace
和
vspace
IDL
属性必须反映同名内容属性。
longDesc
IDL 属性必须反映元素的longdesc
内容属性,出于反映的目的
定义为包含URL。
lowsrc
IDL
属性必须反映元素的lowsrc
内容属性,出于反映的目的
定义为包含URL。
partial interface HTMLInputElement {
[CEReactions ] attribute DOMString align ;
[CEReactions ] attribute DOMString useMap ;
};
align
IDL
属性必须反映同名内容属性。
useMap
IDL 属性必须反映元素的usemap
内容属性。
partial interface HTMLLegendElement {
[CEReactions ] attribute DOMString align ;
};
align
IDL 属性必须反映同名内容属性。
partial interface HTMLLIElement {
[CEReactions ] attribute DOMString type ;
};
type
IDL
属性必须反映同名内容属性。
partial interface HTMLLinkElement {
[CEReactions ] attribute DOMString charset ;
[CEReactions ] attribute DOMString rev ;
[CEReactions ] attribute DOMString target ;
};
charset
、
rev
和
target
IDL
属性必须反映同名内容属性。
用户代理必须将listing
元素视为与pre
元素在语义和渲染目的上等效。
partial interface HTMLMenuElement {
[CEReactions ] attribute boolean compact ;
};
compact
IDL 属性必须反映同名内容属性。
partial interface HTMLMetaElement {
[CEReactions ] attribute DOMString scheme ;
};
用户代理可以将scheme
内容属性视为
meta
元素的name
内容属性的扩展,当处理一个
meta
元素
其中name属性的值是用户代理识别为支持
scheme
属性时。
鼓励用户代理忽略scheme
属性
并且改为处理元数据name所给的值,仿佛它已为
scheme
属性的每个期望值指定。
例如,如果用户代理对meta
元素采取行动,其中name
属性的值为"eGMS.subject.keyword",并且知道
scheme
属性与此元数据名称一起使用,
那么它可以将scheme
属性考虑在内,
仿佛它是name
属性的扩展。因此,
以下两个meta
元素可以被视为两个元素,它们为两个不同的元数据名称提供值,一个由"eGMS.subject.keyword"和
"LGCL"的组合组成,另一个由"eGMS.subject.keyword"和"ORLY"的组合组成:
<!-- this markup is invalid -->
< meta name = "eGMS.subject.keyword" scheme = "LGCL" content = "Abandoned vehicles" >
< meta name = "eGMS.subject.keyword" scheme = "ORLY" content = "Mah car: kthxbye" >
然而,建议对该标记的处理等同于以下内容:
< meta name = "eGMS.subject.keyword" content = "Abandoned vehicles" >
< meta name = "eGMS.subject.keyword" content = "Mah car: kthxbye" >
scheme
IDL
属性必须反映同名内容属性。
partial interface HTMLObjectElement {
[CEReactions ] attribute DOMString align ;
[CEReactions ] attribute DOMString archive ;
[CEReactions ] attribute DOMString code ;
[CEReactions ] attribute boolean declare ;
[CEReactions ] attribute unsigned long hspace ;
[CEReactions ] attribute DOMString standby ;
[CEReactions ] attribute unsigned long vspace ;
[CEReactions ] attribute DOMString codeBase ;
[CEReactions ] attribute DOMString codeType ;
[CEReactions ] attribute DOMString useMap ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString border ;
};
align
、
archive
、
border
、
code
、
declare
、
hspace
、
standby
、
vspace
IDL 属性必须反映同名内容属性。
codeBase
IDL 属性必须反映元素的codebase
内容属性,出于反映的目的,
定义为包含URL。
codeType
IDL 属性必须反映元素的codetype
内容属性。
支持所有当前引擎。
partial interface HTMLOListElement {
[CEReactions ] attribute boolean compact ;
};
compact
IDL 属性必须反映同名内容属性。
partial interface HTMLParagraphElement {
[CEReactions ] attribute DOMString align ;
};
align
IDL
属性必须反映同名内容属性。
param
元素必须实现
HTMLParamElement
接口。
[Exposed =Window ]
interface HTMLParamElement : HTMLElement {
[HTMLConstructor ] constructor ();
[CEReactions ] attribute DOMString name ;
[CEReactions ] attribute DOMString value ;
[CEReactions ] attribute DOMString type ;
[CEReactions ] attribute DOMString valueType ;
};
name
、value
和 type
IDL 属性的 param
元素必须 反映 同名内容属性。
valueType
IDL 属性的 param
元素必须 反映 元素的
valuetype
内容属性。
用户代理必须将 plaintext
元素视为与 pre
元素相同的语义,并用于呈现。 (解析器对此元素有特殊行为。)
partial interface HTMLPreElement {
[CEReactions ] attribute long width ;
};
width
IDL 属性的 pre
元素必须 反映 同名内容属性。
partial interface HTMLStyleElement {
[CEReactions ] attribute DOMString type ;
};
type
IDL 属性的 style
元素必须 反映 元素的 type
内容属性。
partial interface HTMLScriptElement {
[CEReactions ] attribute DOMString charset ;
[CEReactions ] attribute DOMString event ;
[CEReactions ] attribute DOMString htmlFor ;
};
charset
和 event
的 IDL 属性的 script
元素必须 反映 同名内容属性。
htmlFor
的 IDL 属性的 script
元素必须 反映 元素的 for
内容属性。
partial interface HTMLTableElement {
[CEReactions ] attribute DOMString align ;
[CEReactions ] attribute DOMString border ;
[CEReactions ] attribute DOMString frame ;
[CEReactions ] attribute DOMString rules ;
[CEReactions ] attribute DOMString summary ;
[CEReactions ] attribute DOMString width ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString bgColor ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString cellPadding ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString cellSpacing ;
};
align
、border
、frame
、summary
、rules
和
width
IDL 属性的 table
元素必须 反映 同名内容属性。
bgColor
IDL 属性的 table
元素必须 反映 元素的 bgcolor
内容属性。
cellPadding
IDL 属性的 table
元素必须 反映 元素的 cellpadding
内容属性。
cellSpacing
IDL 属性的 table
元素必须 反映 元素的 cellspacing
内容属性。
partial interface HTMLTableSectionElement {
[CEReactions ] attribute DOMString align ;
[CEReactions ] attribute DOMString ch ;
[CEReactions ] attribute DOMString chOff ;
[CEReactions ] attribute DOMString vAlign ;
};
align
IDL 属性的 tbody
、thead
和 tfoot
元素必须 反映 同名内容属性。
ch
IDL 属性的 tbody
、thead
和 tfoot
元素必须 反映 元素的 char
内容属性。
chOff
IDL 属性的 tbody
、thead
和 tfoot
元素必须 反映 元素的 charoff
内容属性。
vAlign
IDL 属性的 tbody
、thead
和 tfoot
元素必须 反映 元素的 valign
内容属性。
partial interface HTMLTableCellElement {
[CEReactions ] attribute DOMString align ;
[CEReactions ] attribute DOMString axis ;
[CEReactions ] attribute DOMString height ;
[CEReactions ] attribute DOMString width ;
[CEReactions ] attribute DOMString ch ;
[CEReactions ] attribute DOMString chOff ;
[CEReactions ] attribute boolean noWrap ;
[CEReactions ] attribute DOMString vAlign ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString bgColor ;
};
align
、axis
、height
和 width
IDL 属性的 td
和 th
元素必须 反映 同名内容属性。
ch
IDL 属性的 td
和 th
元素必须 反映 元素的 char
内容属性。
chOff
IDL 属性的 td
和 th
元素必须 反映 元素的 charoff
内容属性。
noWrap
IDL 属性的 td
和 th
元素必须 反映 元素的 nowrap
内容属性。
vAlign
IDL 属性的 td
和 th
元素必须 反映 元素的 valign
内容属性。
bgColor
IDL 属性的 td
和 th
元素必须 反映 元素的 bgcolor
内容属性。
partial interface HTMLTableRowElement {
[CEReactions ] attribute DOMString align ;
[CEReactions ] attribute DOMString ch ;
[CEReactions ] attribute DOMString chOff ;
[CEReactions ] attribute DOMString vAlign ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString bgColor ;
};
align
IDL 属性的 tr
元素必须 反映 同名内容属性。
ch
IDL 属性的 tr
元素必须 反映 元素的 char
内容属性。
chOff
IDL 属性的 tr
元素必须 反映 元素的 charoff
内容属性。
vAlign
IDL 属性的 tr
元素必须 反映 元素的 valign
内容属性。
bgColor
IDL 属性的 tr
元素必须 反映 元素的 bgcolor
内容属性。
partial interface HTMLUListElement {
[CEReactions ] attribute boolean compact ;
[CEReactions ] attribute DOMString type ;
};
compact
和 type
的 IDL 属性的 ul
元素必须 反映 同名内容属性。
用户代理必须将 xmp
元素视为与 pre
元素相同的语义,并用于呈现。 (解析器对此元素有特殊行为。)
partial interface Document {
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString fgColor ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString linkColor ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString vlinkColor ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString alinkColor ;
[CEReactions ] attribute [LegacyNullToEmptyString ] DOMString bgColor ;
[SameObject ] readonly attribute HTMLCollection anchors ;
[SameObject ] readonly attribute HTMLCollection applets ;
undefined clear ();
undefined captureEvents ();
undefined releaseEvents ();
[SameObject ] readonly attribute HTMLAllCollection all ;
};
Document
对象的属性在下表的第一列中列出,必须 反映 第二列中对应的 body 元素
上具有相同名称的内容属性,如果 body
元素 是 body
元素(而不是 frameset
元素)。当没有 body 元素
或者如果它是 frameset
元素时,这些属性在获取时必须返回空字符串,并在设置时不执行任何操作。
ID属性 | 内容属性 |
---|---|
fgColor |
text
|
linkColor |
link
|
vlinkColor |
vlink
|
alinkColor |
alink
|
bgColor |
bgcolor
|
anchors
属性必须返回一个 HTMLCollection
,以
Document
节点为根,其过滤器仅匹配具有 name
属性的 a
元素。
applets
属性必须返回一个 HTMLCollection
,以
Document
节点为根,其过滤器不匹配任何内容。(它出于历史原因存在。)
clear()
、captureEvents()
和 releaseEvents()
方法必须不执行任何操作。
all
属性必须返回一个 HTMLAllCollection
,以
Document
节点为根,其过滤器匹配所有元素。
partial interface Window {
undefined captureEvents ();
undefined releaseEvents ();
[Replaceable , SameObject ] readonly attribute External external ;
};
captureEvents()
和 releaseEvents()
方法必须不执行任何操作。
external
属性必须返回 Window
接口的一个
External
接口实例:
[Exposed =Window ]
interface External {
undefined AddSearchProvider ();
undefined IsSearchProviderInstalled ();
};
AddSearchProvider()
和 IsSearchProviderInstalled()
方法必须不执行任何操作。
text/html
此注册供社区审查,并将提交给 IESG 以进行审查、批准和向 IANA 注册。
charset
可以提供 charset
参数来指定 文档的字符编码,覆盖文档中的任何 字符编码声明(字节顺序标记(BOM)除外)。该参数的值必须与字符串
"utf-8
"
进行 ASCII 不区分大小写 匹配。[ENCODING]
关于适用于 HTML 文档的安全注意事项,已经写了整本小说。本文件中列出了许多,读者可参阅以了解更多细节。然而,这里提到了一些一般关注的问题:
HTML 是一种脚本语言,具有大量的 API(其中一些在本文件中有描述)。脚本可能会使用户面临信息泄露、凭证泄露、跨站脚本攻击、跨站请求伪造以及许多其他问题的潜在风险。虽然本规范中的设计旨在正确实现时是安全的,但完全实现是一个庞大的工作,和任何软件一样,用户代理可能会有安全漏洞。
即使没有脚本,HTML 中也有一些特定功能由于历史原因需要与旧内容广泛兼容,但这会使用户面临不幸的安全问题。特别是,img
元素可以与其他一些功能结合使用,作为从用户在互联网上的位置进行端口扫描的一种方式。这可能会暴露攻击者无法确定的本地网络拓扑。
HTML 依赖于一种隔离方案,有时称为 同源策略。来源 在大多数情况下由使用相同协议、在相同端口上提供的所有页面组成。
因此,至关重要的是,确保任何不受信任的内容作为站点的一部分托管在与该站点上的任何敏感内容不同的 来源 上。不受信任的内容可以很容易地伪造同一来源上的任何其他页面,读取该来源的数据,使该来源中的脚本执行,即使它们受到独特令牌的跨站请求伪造攻击保护,也可以提交表单到该来源并从该来源提交表单,并利用暴露给该来源的任何第三方资源或授予该来源的权利。
html
" 和 "htm
" 通常(但绝不是唯一的)用作 HTML 文档的扩展名。TEXT
片段 用于 text/html
资源时,指向对应 文档的指示部分,或为页面内的脚本提供状态信息。
multipart/x-mixed-replace
此注册供社区审查,并将提交给 IESG 以进行审查、批准和向 IANA 注册。
boundary
(定义于 RFC2046)[RFC2046]multipart/x-mixed-replace
资源的子资源可以是任何类型,包括具有非平凡安全隐患的类型,例如 text/html
。
multipart/mixed
相同。[RFC2046]
multipart/x-mixed-replace
资源。片段 用于 multipart/x-mixed-replace
资源时,适用于每个由该主体部分使用的类型定义的主体部分。
application/xhtml+xml
此注册供社区审查,并将提交给 IESG 以进行审查、批准和向 IANA 注册。
application/xml
相同 [RFC7303]application/xml
相同 [RFC7303]application/xml
相同 [RFC7303]application/xml
相同 [RFC7303]application/xml
相同 [RFC7303]application/xhtml+xml
类型表明该资源是一个 XML 文档,并且可能具有来自 文档元素 的 HTML 命名空间。因此,相关的规范是 XML、XML 命名空间 以及本规范。[XML] [XMLNS]application/xml
相同 [RFC7303]application/xml
相同 [RFC7303]xhtml
" 和 "xht
" 有时用作具有来自 文档元素 的 HTML 命名空间 的 XML 资源的扩展名。TEXT
片段 用于 application/xhtml+xml
资源时,其语义与任何 XML MIME 类型 相同。[RFC7303]
text/ping
此注册供社区审查,并将提交给 IESG 以进行审查、批准和向 IANA 注册。
charset
可以提供 charset
参数。该参数的值必须为 "utf-8
"。此参数没有实际用途;仅为了与旧版服务器兼容而允许使用。
如果完全按照超链接审计的上下文中描述的方式使用,则此类型不会引入新的安全问题。
text/ping
资源始终由四个字节
0x50 0x49 0x4E 0x47 (`PING
`) 组成。ping
属性时生成的 HTTP
POST
请求。application/microdata+json
此注册供社区审查,并将提交给 IESG 以进行审查、批准和向 IANA 注册。
application/json
相同 [JSON]application/json
相同 [JSON]application/json
相同 [JSON]application/json
相同 [JSON]application/microdata+json
类型表明该资源是一个 JSON 文本,该文本由一个包含单个名为 "items
" 的条目的对象组成,该条目由一个条目数组组成,每个条目由一个对象组成,其中包含一个名为
"id
"
的条目,其值为字符串,另一个名为 "type
" 的条目,其值为另一个字符串,以及一个名为 "properties
"
的条目,其值为一个对象,该对象的每个条目都具有一个由对象或字符串组成的数组值,这些对象的形式与上述 "items
" 条目中的对象相同。因此,相关的规范是 JSON
和本规范。[JSON]与 HTML 的 microdata 功能一起传输数据的应用程序,特别是在拖放操作的上下文中,是此类型的主要应用程序类。
application/json
相同 [JSON]application/json
相同 [JSON]application/json
相同 [JSON]片段 用于 application/microdata+json
资源时,其语义与用于 application/json
时相同(即在撰写本文时,没有任何语义)。[JSON]
text/event-stream
此注册供社区审查,并将提交给 IESG 以进行审查、批准和向 IANA 注册。
charset
可以提供 charset
参数。该参数的值必须为 "utf-8
"。此参数没有实际用途;仅为了与旧版服务器兼容而允许使用。
来自与使用事件流的内容的来源不同的来源的事件流可能会导致信息泄露。为避免这种情况,要求用户代理应用 CORS 语义。[FETCH]
事件流可能会使用户代理不堪重负;预期用户代理会应用适当的限制,以避免由于来自事件流的信息过多而耗尽本地资源。
如果服务器导致客户端快速重新连接,服务器可能会不堪重负。服务器应使用 5xx 状态码来表示容量问题,因为这将防止符合标准的客户端自动重新连接。
片段 对于 text/event-stream
资源没有意义。
web+
scheme 前缀本节描述了 IANA URI 协议注册表中使用的约定。它本身并未注册特定的协议。[RFC7595]
web+
" 开头,后跟一个或多个 a
-z
范围内字母的协议。web+
" 协议在相关情况下应使用 UTF-8 编码。web+
" 协议注册一个处理程序。因此,这些协议不得用于预期为核心平台功能(例如 HTTP)的功能。同样,此类协议不得在其 URL
中存储机密信息,例如用户名、密码、个人信息或机密项目名称。以下部分仅涵盖符合规范的元素和特性。
本节为非规范性内容。
表格中的单元格内标有星号(*)表示实际规则比上表中显示的更为复杂。
† "父级"列中的类别指的是在其内容模型中列出了给定类别的父级元素,而不是那些自身属于这些类别的元素。例如,a
元素的"父级"列中显示为"短语",因此任何内容模型包含"短语"类别的元素都可以是a
元素的父级。由于"流"类别包含所有的"短语"元素,这意味着th
元素可以是a
元素的父级。
本节为非规范性内容。
本节为非规范性内容。
属性 | 元素 | 描述 | 值 |
---|---|---|---|
abbr
|
th
|
用于在其他上下文中引用单元格时使用的替代标签 | 文本* |
accept
|
input
|
文件上传控件的预期文件类型提示 | 由逗号分隔的令牌集合*,包括没有参数的有效MIME类型字符串
或 audio/* 、video/* 或 image/*
|
accept-charset
|
form
|
用于表单提交的字符编码 | 与"UTF-8 "的ASCII不区分大小写匹配
|
accesskey
|
HTML 元素 | 激活或聚焦元素的键盘快捷键 | 唯一空格分隔令牌的有序集合,其中没有一个与另一个相同, 每个由一个代码点组成 |
action
|
form
|
用于URL 用于表单提交 | 有效的非空URL,可能周围有空格 |
allow
|
iframe
|
应用于iframe 内容的权限策略
|
序列化权限策略 |
allowfullscreen
|
iframe
|
是否允许iframe 内容使用requestFullscreen()
|
布尔属性 |
alt
|
area ;
img ;
input
|
图像不可用时使用的替代文本 | 文本* |
as
|
link
|
用于预加载请求的潜在目的地(对于rel ="preload "
和 rel ="modulepreload ")
|
潜在目的地,对于rel ="preload ";
类脚本目的地,对于rel ="modulepreload "
|
async
|
script
|
在脚本可用时执行,而无需在获取时阻塞 | 布尔属性 |
autocapitalize
|
HTML 元素 | 推荐的自动大写行为(适用于支持的输入法) | "on ";
"off ";
"none ";
"sentences ";
"words ";
"characters "
|
autocomplete
|
form
|
表单控件的自动填充功能的默认设置 | "on "; "off "
|
autocomplete
|
input ;
select ;
textarea
|
表单自动填充功能的提示 | 自动填充字段 名称及相关令牌* |
autocorrect
| HTML 元素 | 推荐的自动更正行为(对于支持的输入方法) | "on ";
"off "
|
autofocus
|
HTML 元素 | 页面加载时自动聚焦元素 | 布尔属性 |
autoplay
|
audio ;
video
|
提示页面加载时可以自动启动媒体资源 | 布尔属性 |
blocking
|
link ;
script ;
style
|
元素是否可能阻碍渲染 | 唯一空格分隔令牌的无序集合* |
charset
|
meta
|
字符编码声明 | "utf-8 "
|
checked
|
input
|
控件是否被选中 | 布尔属性 |
cite
|
blockquote ;
del ;
ins ;
q
|
链接到引用的来源或有关编辑的更多信息 | 有效的URL,可能周围有空格 |
class
|
HTML 元素 | 元素所属的类 | 空格分隔令牌集合 |
color
|
link
|
自定义站点图标时使用的颜色(对于 rel ="mask-icon ")
|
CSS <color> |
cols
|
textarea
|
每行的最大字符数 | 有效的非负整数,大于零 |
colspan
|
td ;
th
|
单元格要跨越的列数 | 有效的非负整数,大于零 |
content
|
meta
|
元素的值 | 文本* |
contenteditable
|
HTML 元素 | 元素是否可编辑 | "true "; "plaintext-only ";
"false "
|
controls
|
audio ;
video
|
显示用户代理控件 | 布尔属性 |
coords
|
area
|
用于在图像映射中创建形状的坐标 | 有效的浮点数列表* |
crossorigin
|
audio ;
img ;
link ;
script ;
video
|
元素如何处理跨域请求 | "anonymous ";
"use-credentials "
|
data
|
object
|
资源的地址 | 有效的非空URL,可能周围有空格 |
datetime
|
del ;
ins
|
变更的日期和(可选)时间 | 有效的日期字符串,带有可选时间 |
datetime
|
time
|
机器可读的值 | 有效的月份字符串, 有效的日期字符串, 有效的无年份日期字符串, 有效的时间字符串, 有效的本地日期和时间字符串, 有效的时区偏移字符串, 有效的全球日期和时间字符串, 有效的周字符串, 有效的非负整数,或 有效的持续时间字符串 |
decoding
|
img
|
在处理此图像以进行呈现时使用的解码提示 | "sync ";
"async ";
"auto "
|
default
|
track
|
如果没有其他文本轨道更合适,则启用此轨道 | 布尔属性 |
defer
|
script
|
延迟脚本执行 | 布尔属性 |
dir
|
HTML 元素 | 元素的文本方向性 | "ltr ";
"rtl ";
"auto "
|
dir
|
bdo
|
元素的文本方向性 | "ltr ";
"rtl "
|
dirname
|
input ;
textarea
|
用于在表单提交中发送元素方向性的表单控件名称 | 文本* |
disabled
|
button ;
input ;
optgroup ;
option ;
select ;
textarea ;
表单关联的自定义元素
|
表单控件是否禁用 | 布尔属性 |
disabled
|
fieldset
|
是否禁用后代表单控件,但在legend 中的任何控件除外
|
布尔属性 |
disabled
|
link
|
链接是否禁用 | 布尔属性 |
download
|
a ;
area
|
是否下载资源而不是导航到它,以及如果是,则是其文件名 | 文本 |
draggable
|
HTML 元素 | 元素是否可拖动 | "true "; "false "
|
enctype
|
form
|
用于表单提交的条目列表编码类型 | "application/x-www-form-urlencoded ";
"multipart/form-data ";
"text/plain "
|
enterkeyhint
|
HTML 元素 | 选择回车键动作的提示 | "enter ";
"done ";
"go ";
"next ";
"previous ";
"search ";
"send "
|
fetchpriority
|
img ;
link ;
script
|
为元素启动的获取设置优先级 | "auto ";
"high ";
"low "
|
for
|
label
|
将标签与表单控件关联 | ID* |
for
|
output
|
指定计算输出的控件 | 由ID组成的唯一空格分隔令牌的无序集合* |
form
|
button ;
fieldset ;
input ;
object ;
output ;
select ;
textarea ;
表单关联的自定义元素
|
将元素与表单 元素关联
|
ID* |
formaction
|
button ;
input
|
用于表单提交的URL | 有效的非空URL,可能周围有空格 |
formenctype
|
button ;
input
|
用于表单提交的条目列表编码类型 | "application/x-www-form-urlencoded ";
"multipart/form-data ";
"text/plain "
|
formmethod
|
button ;
input
|
用于表单提交的变体 | "GET ";
"POST ";
"dialog "
|
formnovalidate
|
button ;
input
|
绕过表单控件验证以进行表单提交 | 布尔属性 |
formtarget
|
button ;
input
|
用于表单提交的可导航元素 | 有效的可导航目标名称或关键字 |
headers
|
td ;
th
|
该单元格的标题单元格 | 由ID组成的唯一空格分隔令牌的无序集合* |
height
|
canvas ;
embed ;
iframe ;
img ;
input ;
object ;
source
(在 picture );
video
|
垂直尺寸 | 有效的非负整数 |
hidden
|
元素是否相关 | " | "; " "; 空字符串|
high
|
meter
|
高范围的低限制 | 有效的浮点数* |
href
|
a ;
area
|
超链接的地址 | 有效的URL,可能周围有空格 |
href
|
link
|
超链接 的地址 | 有效的非空URL,可能周围有空格 |
href
|
base
|
文档基本URL | 有效的URL,可能周围有空格 |
hreflang
|
a ;
link
|
链接资源的语言 | 有效的BCP 47语言标签 |
http-equiv
|
meta
|
Pragma 指令 | "content-type ";
"default-style ";
"refresh ";
"x-ua-compatible ";
"content-security-policy "
|
id
|
HTML 元素 | 元素的 ID | 文本* |
imagesizes
|
link
|
不同页面布局的图像尺寸(用于 rel ="preload ")
|
有效的源尺寸列表 |
imagesrcset
|
link
|
用于不同情况的图像,例如高分辨率显示器、小型显示器等(用于 rel ="preload ")
|
逗号分隔的 图像候选字符串 |
inert
|
HTML 元素 | 元素是否是 无效的 | 布尔属性 |
inputmode
|
HTML 元素 | 输入模式的提示 | "none ";
"text ";
"tel ";
"email ";
"url ";
"numeric ";
"decimal ";
"search "
|
integrity
|
link ;
script
|
用于 子资源完整性 检查的完整性元数据 [SRI] | 文本 |
is
|
HTML 元素 | 创建一个 自定义内置元素 | 有效的自定义元素名称,定义的 自定义内置元素 |
ismap
|
img
|
图像是否为服务器端图像地图 | 布尔属性 |
itemid
|
HTML 元素 | 微数据项的 全局标识符 | 有效的URL,可能周围有空格 |
itemprop
|
HTML 元素 | 微数据项的 属性名称 | 无序的唯一空格分隔标记集,由 有效绝对URL、定义的属性名称 或文本* 组成 |
itemref
|
HTML 元素 | 引用 的元素 | 无序的唯一空格分隔标记集,由ID* 组成 |
itemscope
|
HTML 元素 | 引入一个微数据项 | 布尔属性 |
itemtype
|
HTML 元素 | 微数据项的 项类型 | 无序的唯一空格分隔令牌集合 由 有效的绝对 URL 组成* |
kind
|
track
|
文本轨道的类型 | "subtitles ";
"captions ";
"descriptions ";
"chapters ";
"metadata "
|
label
|
optgroup ;
option ;
track
|
用户可见标签 | 文本 |
lang
|
HTML 元素 | 元素的 语言 | 有效的 BCP 47 语言标签或空字符串 |
list
|
input
|
自动完成选项的列表 | ID* |
loading
|
iframe ;
img
|
用于确定加载延迟 | "lazy ";
"eager "
|
loop
|
audio ;
video
|
是否循环播放 媒体资源 | 布尔属性 |
low
|
meter
|
低范围的高限 | 有效的浮点数* |
max
|
input
|
最大值 | 变化* |
max
|
meter ;
progress
|
范围的上限 | 有效的浮点数* |
maxlength
|
input ;
textarea
|
最大的 长度 值 | 有效的非负整数 |
media
|
link ;
meta ;
source ;
style
|
适用的媒体 | 有效的媒体查询列表 |
method
|
form
|
用于 表单提交 的变体 | "GET ";
"POST ";
"dialog "
|
min
|
input
|
最小值 | 变化* |
min
|
meter
|
范围的下限 | 有效的浮点数* |
minlength
|
input ;
textarea
|
最小的 长度 值 | 有效的非负整数 |
multiple
|
input ;
select
|
是否允许多个值 | 布尔属性 |
muted
|
audio ;
video
|
是否默认静音 媒体资源 | 布尔属性 |
name
|
button ;
fieldset ;
input ;
output ;
select ;
textarea ;
与表单关联的自定义元素
|
用于 表单提交 和
form.elements
API 的元素名称
|
文本* |
name
|
details
|
互斥的 details
元素的组名称
|
文本* |
name
|
form
|
在 document.forms
API 中使用的表单名称
|
文本* |
name
|
iframe ;
object
|
内容可导航 | 有效的可导航目标名称或关键字 |
name
|
map
|
图像映射 的名称,从 usemap
属性中引用
|
文本* |
name
|
meta
|
元数据名称 | 文本* |
name
|
slot
|
阴影树插槽的名称 | 文本 |
nomodule
|
script
|
防止在支持 模块脚本 的用户代理中执行 | 布尔属性 |
nonce
|
HTML 元素 | 用于 内容安全策略 检查的加密 nonce [CSP] | 文本 |
novalidate
|
form
|
在 表单提交 时绕过表单控件验证 | 布尔属性 |
open
|
details
|
是否可见 | 布尔属性 |
open
|
dialog
|
对话框是否正在显示 | 布尔属性 |
optimum
|
meter
|
量表中的最佳值 | 有效的浮点数* |
pattern
|
input
|
表单控件值需匹配的模式 | 匹配 JavaScript Pattern 生产 |
ping
|
a ;
area
|
URLs 要 ping | 空格分隔的令牌集合 由 有效的非空 URL 组成 |
placeholder
|
input ;
textarea
|
用户可见的标签,将放置在表单控件内 | 文本* |
playsinline
|
video
|
鼓励用户代理在元素的播放区域内显示视频内容 | 布尔属性 |
popover
|
HTML 元素 | 使元素成为 弹出层 元素 | "auto ";
"manual ";
|
popovertarget
|
button ;
input
|
目标弹出层元素以切换、显示或隐藏 | ID* |
popovertargetaction
|
button ;
input
|
指示目标弹出层元素是否被切换、显示或隐藏 | "toggle ";
"show ";
"hide "
|
poster
|
video
|
视频播放前显示的海报帧 | 有效的非空 URL 可能被空格包围 |
preload
|
audio ;
video
|
提示媒体资源需要多少缓冲 | "none ";
"metadata ";
"auto "
|
readonly
|
input ;
textarea
|
是否允许用户编辑值 | 布尔属性 |
readonly
|
与表单相关的自定义元素 | 影响 willValidate ,
以及自定义元素作者添加的任何行为
|
布尔属性 |
referrerpolicy
|
a ;
area ;
iframe ;
img ;
link ;
script
|
引用政策 适用于由元素发起的 fetch | 引用政策 |
rel
|
a ;
area
|
文档中包含超链接与目标资源之间的关系 | 唯一的空格分隔令牌的无序集合* |
rel
|
link
|
文档中包含超链接与目标资源之间的关系 | 唯一的空格分隔令牌的无序集合* |
required
|
input ;
select ;
textarea
|
控件是否在 表单提交 时为必需 | 布尔属性 |
reversed
|
ol
|
反向编号列表 | 布尔属性 |
rows
|
textarea
|
显示的行数 | 有效的非负整数 大于零 |
rowspan
|
td ;
th
|
单元格跨越的行数 | 有效的非负整数 |
sandbox
|
iframe
|
嵌套内容的安全规则 | 唯一空格分隔标记的无序集合, ASCII 不区分大小写, 由以下内容组成
|
scope
|
th
|
指定标题单元格适用于哪些单元格 | "row ";
"col ";
"rowgroup ";
"colgroup "
|
selected
|
option
|
选项是否默认被选中 | 布尔属性 |
shadowrootclonable
|
template
|
在声明性 shadow root 上设置可克隆 | 布尔属性 |
shadowrootdelegatesfocus
|
template
|
在声明性 shadow root 上设置委派焦点 | 布尔属性 |
shadowrootmode
|
template
|
启用流式声明性 shadow root | "open ";
"closed "
|
shadowrootserializable
|
template
|
在声明性 shadow root 上设置可序列化 | 布尔属性 |
shape
|
area
|
在图像映射中创建的形状类型 | "circle ";
"default ";
"poly ";
"rect "
|
size
|
input ;
select
|
控件的大小 | 有效的非负整数大于零 |
sizes
|
link
|
图标的大小(对于rel ="icon ")
|
唯一空格分隔标记的无序集合, ASCII 不区分大小写, 由 sizes* 组成 |
sizes
|
img ;
source
|
不同页面布局的图像大小 | 有效的源尺寸列表 |
slot
|
HTML 元素 | 元素的期望插槽 | 文本 |
span
|
col ;
colgroup
|
元素跨越的列数 | 有效的非负整数大于零 |
spellcheck
|
HTML 元素 | 是否要检查元素的拼写和语法 | "true ";
"false ";
空字符串
|
src
|
audio ;
embed ;
iframe ;
img ;
input ;
script ;
source
(video 或audio );
track ;
video
|
资源地址 | 有效的非空 URL(可能被空格包围) |
srcdoc
|
iframe
|
在iframe 中渲染的文档
|
一个iframe
srcdoc 文档的来源*
|
srclang
|
track
|
文本轨道的语言 | 有效的 BCP 47 语言标签 |
srcset
|
img ;
source
|
在不同情况下使用的图像,例如高分辨率显示器、小型显示器等 | 以逗号分隔的图像候选字符串列表 |
start
|
ol
|
列表的起始值 | 有效整数 |
step
|
input
|
表单控件值的粒度 | 有效的浮点数大于零,或"any "
|
style
|
HTML 元素 | 表现和格式化指令 | CSS 声明* |
tabindex
|
HTML 元素 | 元素是否可聚焦且可顺序聚焦,以及元素在顺序焦点导航中的相对顺序 | 有效整数 |
target
|
a ;
area
|
可导航用于超链接导航 | 有效的可导航目标名称或关键字 |
target
|
base
|
默认的可导航用于超链接 导航和表单提交 | 有效的可导航目标名称或关键字 |
target
|
form
|
可导航用于表单提交 | 有效的可导航目标名称或关键字 |
title
|
HTML 元素 | 元素的建议信息 | 文本 |
title
|
abbr ;
dfn
|
缩写的完整术语或扩展 | 文本 |
title
|
input
|
模式的描述(与pattern
属性一起使用时)
|
文本 |
title
|
link
|
链接的标题 | 文本 |
title
|
link ;
style
|
CSS 样式表集名称 | 文本 |
translate
|
HTML 元素 | 页面本地化时是否翻译元素 | "yes "; "no "
|
type
|
a ;
link
|
引用资源类型的提示 | 有效的 MIME 类型字符串 |
type
|
button
|
按钮类型 | "submit ";
"reset ";
"button "
|
type
|
embed ;
object ;
source
|
嵌入资源类型 | 有效的 MIME 类型字符串 |
type
|
input
|
表单控件类型 | input
类型关键字
|
type
|
ol
|
列表标记类型 | "1 ";
"a ";
"A ";
"i ";
"I "
|
type
|
script
|
脚本类型 | "module "; 一个有效的
MIME
类型字符串,但不是JavaScript MIME 类型匹配
|
usemap
|
img
|
要使用的图像映射的名称 | 有效的哈希名称引用* |
value
|
button ;
option
|
用于表单提交的值 | 文本 |
value
|
data
|
机器可读的值 | 文本* |
value
|
input
|
表单控件的值 | 视情况而定* |
value
|
li
|
列表项的序数值 | 有效整数 |
value
|
meter ;
progress
|
元素的当前值 | 有效浮点数 |
width
|
canvas ;
embed ;
iframe ;
img ;
input ;
object ;
source
(picture );
video
|
水平尺寸 | 有效非负整数 |
wrap
|
textarea
|
表单控件的值在表单提交时如何换行 | "soft ";
"hard "
|
writingsuggestions
|
HTML 元素 | 元素是否可以提供写作建议 | "true ";
"false ";
空字符串
|
单元格中的星号(*)表示实际规则比上表中所示的更为复杂。
所有当前引擎中均支持。
所有当前引擎中均支持。
所有当前引擎中均支持。
所有当前引擎中均支持。
所有当前引擎中均支持。
所有当前引擎中均支持。
所有当前引擎中均支持。
本节为非规范性内容。
本节为非规范性内容。
AudioTrack
AudioTrackList
BarProp
BeforeUnloadEvent
BroadcastChannel
CanvasGradient
CanvasPattern
CanvasRenderingContext2D
CloseWatcher
CustomElementRegistry
CustomStateSet
DOMParser
DOMStringList
DOMStringMap
DataTransfer
DataTransferItem
DataTransferItemList
DedicatedWorkerGlobalScope
Document
, partial
1
2
DragEvent
Element
,
partial
ElementInternals
ErrorEvent
EventSource
External
FormDataEvent
HTMLAllCollection
HTMLAnchorElement
,
partial
HTMLAreaElement
,
partial
HTMLAudioElement
HTMLBRElement
,
partial
HTMLBaseElement
HTMLBodyElement
,
partial
HTMLButtonElement
HTMLCanvasElement
HTMLDListElement
,
partial
HTMLDataElement
HTMLDataListElement
HTMLDetailsElement
HTMLDialogElement
HTMLDirectoryElement
HTMLDivElement
,
partial
HTMLElement
HTMLEmbedElement
,
partial
HTMLFieldSetElement
HTMLFontElement
HTMLFormControlsCollection
HTMLFormElement
HTMLFrameElement
HTMLFrameSetElement
HTMLHRElement
,
partial
HTMLHeadElement
HTMLHeadingElement
,
partial
HTMLHtmlElement
,
partial
HTMLIFrameElement
,
partial
HTMLImageElement
,
partial
HTMLInputElement
,
partial
HTMLLIElement
,
partial
HTMLLabelElement
HTMLLegendElement
,
partial
HTMLLinkElement
,
partial
HTMLMapElement
HTMLMarqueeElement
HTMLMediaElement
HTMLMenuElement
,
partial
HTMLMetaElement
,
partial
HTMLMeterElement
HTMLModElement
HTMLOListElement
,
partial
HTMLObjectElement
,
partial
HTMLOptGroupElement
HTMLOptionElement
HTMLOptionsCollection
HTMLOutputElement
HTMLParagraphElement
,
partial
HTMLParamElement
HTMLPictureElement
HTMLPreElement
,
partial
HTMLProgressElement
HTMLQuoteElement
HTMLScriptElement
,
partial
HTMLSelectElement
HTMLSlotElement
HTMLSourceElement
HTMLSpanElement
HTMLStyleElement
,
partial
HTMLTableCaptionElement
,
partial
HTMLTableCellElement
,
partial
HTMLTableColElement
,
partial
HTMLTableElement
,
partial
HTMLTableRowElement
,
partial
HTMLTableSectionElement
,
partial
HTMLTemplateElement
HTMLTextAreaElement
HTMLTimeElement
HTMLTitleElement
HTMLTrackElement
HTMLUListElement
,
partial
HTMLUnknownElement
HTMLVideoElement
HashChangeEvent
History
ImageBitmap
ImageBitmapRenderingContext
ImageData
Location
MediaError
MessageChannel
MessageEvent
MessagePort
MimeType
MimeTypeArray
NavigateEvent
Navigation
NavigationActivation
NavigationCurrentEntryChangeEvent
NavigationDestination
NavigationHistoryEntry
NavigationTransition
Navigator
, partialNotRestoredReasonDetails
NotRestoredReasons
OffscreenCanvas
OffscreenCanvasRenderingContext2D
PageRevealEvent
PageSwapEvent
PageTransitionEvent
Path2D
Plugin
PluginArray
PopStateEvent
PromiseRejectionEvent
RadioNodeList
Range
,
partial
ShadowRoot
,
partial
SharedWorker
SharedWorkerGlobalScope
Storage
StorageEvent
SubmitEvent
TextMetrics
TextTrack
TextTrackCue
TextTrackCueList
TextTrackList
TimeRanges
ToggleEvent
TrackEvent
UserActivation
ValidityState
VideoTrack
VideoTrackList
VisibilityStateEntry
Window
, partial
Worker
WorkerGlobalScope
WorkerLocation
WorkerNavigator
Worklet
WorkletGlobalScope
本节为非规范性内容。
下表列出了此文档触发的事件,不包括已经在 媒体元素事件 和 拖放事件 中定义的事件。
事件 | 接口 | 相关目标 | 描述 |
---|---|---|---|
DOMContentLoaded
所有当前引擎均支持。 Firefox1+Safari3.1+Chrome1+
Opera9+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+ |
Event
|
Document
|
在解析器完成解析后触发 Document
|
afterprint
所有当前引擎均支持。 Firefox6+Safari13+Chrome63+
Opera?Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
Event
|
Window
|
在打印后触发 Window
|
beforeprint
所有当前引擎均支持。 Firefox6+Safari13+Chrome63+
Opera?Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
Event
|
Window
|
在打印前触发 Window
|
beforematch
仅在一个引擎中支持。 Firefox否Safari否Chrome102+
Opera否Edge102+ Edge (旧版)?Internet Explorer否 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
Event
|
元素 | 在带有 | 属性的元素被显示前触发。
beforetoggle
HTMLElement/beforetoggle_event 所有当前引擎均支持。 Firefox🔰
114+Safaripreview+Chrome114+
Opera?Edge114+ Edge (旧版)?Internet Explorer否 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
ToggleEvent
|
元素 | 在带有 popover
属性的元素在显示与隐藏之间过渡时触发
|
beforeunload
所有当前引擎均支持。 Firefox1+Safari3+Chrome1+
Opera12+Edge79+ Edge (旧版)12+Internet Explorer4+ Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
BeforeUnloadEvent
|
Window
|
当页面即将卸载时在 Window
上触发,以防页面希望显示警告提示
|
blur
|
Event
|
Window , 元素
|
当节点停止 聚焦 时触发 |
cancel
HTMLDialogElement/cancel_event 所有当前引擎均支持。 Firefox98+Safari15.4+Chrome37+
Opera?Edge79+ Edge (旧版)?Internet Explorer否 Firefox Android?Safari iOS?Chrome Android否WebView Android?Samsung Internet?Opera Android? |
Event
|
CloseWatcher ,
对话框
元素, 输入
元素
|
在 CloseWatcher
对象或 对话框
元素上接收到 关闭请求
时触发,或当用户未更改选择时,在文件上传状态(type=file)的 输入
元素上触发
|
change
所有当前引擎均支持。 Firefox1+Safari3+Chrome1+
Opera9+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+ |
Event
|
表单控件 | 当用户提交值更改时在控件上触发(另见 input
事件)
|
click
|
PointerEvent
|
元素 | 通常是鼠标事件;当从非指针输入设备(例如键盘)激活元素时,也会在元素上合成触发,在其 激活行为 运行之前 |
close
所有当前引擎均支持。 Firefox98+Safari15.4+Chrome37+
Opera?Edge79+ Edge (旧版)?Internet Explorer否 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
Event
|
CloseWatcher ,
对话框
元素, MessagePort
|
在 CloseWatcher
对象或 对话框
元素关闭时通过 关闭请求 或通过 Web
开发者代码,或在
MessagePort
对象在解耦时触发
|
connect
SharedWorkerGlobalScope/connect_event 所有当前引擎均支持。 Firefox29+Safari16+Chrome4+
Opera10.6+Edge79+ Edge (旧版)?Internet Explorer否 Firefox Android?Safari iOS16+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
MessageEvent
|
SharedWorkerGlobalScope
|
当新客户端连接时,在共享 worker 的全局范围内触发 |
contextlost
HTMLCanvasElement/webglcontextlost_event 仅支持一个引擎。 Firefox否Safari否Chrome98+
Opera?Edge98+ Edge (旧版)?Internet Explorer否 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
Event
|
canvas
元素, OffscreenCanvas
对象
|
在对应的 CanvasRenderingContext2D
或 OffscreenCanvasRenderingContext2D
丢失时触发
|
contextrestored
HTMLCanvasElement/contextrestored_event 仅支持一个引擎。 Firefox否Safari否Chrome98+
Opera?Edge98+ Edge (旧版)?Internet Explorer否 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
Event
|
canvas
元素, OffscreenCanvas
对象
|
在对应的 CanvasRenderingContext2D
或 OffscreenCanvasRenderingContext2D
在丢失后恢复时触发
|
currententrychange
|
NavigationCurrentEntryChangeEvent
|
Navigation
|
在 navigation.currentEntry
更改时触发
|
dispose
|
Event
|
NavigationHistoryEntry
|
当对应于 NavigationHistoryEntry
的 会话历史条目
被永久驱逐出会话历史且无法再导航到时触发
|
error
支持所有当前引擎。 Firefox6+Safari5+Chrome6+
Opera12+Edge79+ Edge (旧版)?Internet Explorer否 Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ 支持所有当前引擎。 Firefox6+Safari5.1+Chrome10+
Opera?Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
Event
或 ErrorEvent
|
全局范围对象, Worker
对象, 元素,
与网络相关的对象
|
当发生意外错误时触发(例如网络错误、脚本错误、解码错误) |
focus
|
Event
|
Window , 元素
|
在获取焦点的节点上触发 gaining focus |
formdata
HTMLFormElement/formdata_event 支持所有当前引擎。 Firefox72+Safari15+Chrome77+
Opera?Edge79+ Edge (旧版)?Internet Explorer否 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
FormDataEvent
|
form
元素
|
在 form
元素构建条目列表时触发 constructing the entry list
|
hashchange
支持所有当前引擎。 Firefox3.6+Safari5+Chrome8+
Opera10.6+Edge79+ Edge (旧版)12+Internet Explorer8+ Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+ |
HashChangeEvent
|
Window
|
在 Window
当文档的 片段 部分 URL 发生更改时触发
|
input
|
Event
|
元素 | 当用户更改 contenteditable
元素的内容或表单控件的值时触发。另请参阅表单控件的 change 事件。
|
invalid
HTMLInputElement/invalid_event 支持所有当前引擎。 Firefox4+Safari5+Chrome10+
Opera10+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android64+Safari iOS5+Chrome Android?WebView Android4+Samsung Internet4.0+Opera Android12+ |
Event
|
表单控件 | 在表单验证期间,如果控件不满足其约束,则在控件上触发 |
languagechange
支持所有当前引擎。 Firefox32+Safari10.1+Chrome37+
Opera?Edge79+ Edge (旧版)?Internet Explorer否 Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet4.0+Opera Android? WorkerGlobalScope/languagechange_event 支持所有当前引擎。 Firefox74+Safari4+Chrome4+
Opera11.5+Edge79+ Edge (旧版)?Internet Explorer否 Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
Event
|
全局范围对象 | 当用户的首选语言更改时,在全局范围对象上触发 |
load
|
Event
|
Window , 元素
|
在文档加载完成时,在 Window
上触发;在包含资源的元素上触发(例如 img 、embed )
当其资源加载完成时
|
message
BroadcastChannel/message_event 支持所有当前引擎。 Firefox38+Safari15.4+Chrome54+
Opera?Edge79+ Edge (旧版)?Internet Explorer否 Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? DedicatedWorkerGlobalScope/message_event 支持所有当前引擎。 Firefox3.5+Safari4+Chrome4+
Opera10.6+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11.5+ 支持所有当前引擎。 Firefox6+Safari5+Chrome6+
Opera12+Edge79+ Edge (旧版)?Internet Explorer否 Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ 支持所有当前引擎。 Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11.5+ 支持所有当前引擎。 Firefox9+Safari4+Chrome60+
Opera?Edge79+ Edge (旧版)12+Internet Explorer8+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+ 支持所有当前引擎。 Firefox3.5+Safari4+Chrome4+
Opera10.6+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11.5+ |
MessageEvent
|
Window , EventSource , MessagePort ,
BroadcastChannel ,
DedicatedWorkerGlobalScope ,
Worker , ServiceWorkerContainer
|
当对象接收到消息时触发 |
messageerror
BroadcastChannel/messageerror_event 在所有当前引擎中均受支持。 Firefox57+Safari15.4+Chrome60+
Opera?Edge79+ Edge (旧版)?Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+ DedicatedWorkerGlobalScope/messageerror_event 在所有当前引擎中均受支持。 Firefox57+Safari16.4+Chrome60+
Opera?Edge79+ Edge (旧版)18Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+ MessagePort/messageerror_event 在所有当前引擎中均受支持。 Firefox57+Safari16.4+Chrome60+
Opera?Edge79+ Edge (旧版)18Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+ 在所有当前引擎中均受支持。 Firefox57+Safari16.4+Chrome60+
Opera?Edge79+ Edge (旧版)18Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+ 在所有当前引擎中均受支持。 Firefox57+Safari16.4+Chrome60+
Opera?Edge79+ Edge (旧版)18Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+ |
MessageEvent
|
Window , MessagePort ,
BroadcastChannel ,
DedicatedWorkerGlobalScope ,
Worker , ServiceWorkerContainer
|
在对象接收到无法反序列化的消息时触发 |
navigate
|
NavigateEvent
|
Navigation
|
在 navigable 导航、重新加载、遍历历史记录,或 以其他方式 更改其 URL 之前触发 |
navigateerror
|
ErrorEvent
|
Navigation
|
当导航未成功完成时触发 |
navigatesuccess
|
Event
|
Navigation
|
当导航成功完成时触发 |
offline
在所有当前引擎中均受支持。 Firefox9+Safari4+Chrome3+
Opera?Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
Event
|
全局范围对象 | 当网络连接失败时在全局范围对象中触发 |
online
在所有当前引擎中均受支持。 Firefox9+Safari4+Chrome3+
Opera?Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
Event
|
全局范围对象 | 当网络连接恢复时在全局范围对象中触发 |
open
在所有当前引擎中均受支持。 Firefox6+Safari5+Chrome6+
Opera12+Edge79+ Edge (旧版)?Internet ExplorerNo Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+ |
Event
|
EventSource
|
当建立连接时在 EventSource
对象中触发
|
pageswap
|
PageSwapEvent
|
Window
|
在 Window
导航导致文档 卸载 之前触发。
|
pagehide
在所有当前引擎中均受支持。 Firefox6+Safari5+Chrome3+
Opera?Edge79+ Edge (旧版)12+Internet Explorer11 Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
PageTransitionEvent
|
Window
|
当页面的 会话历史条目 停止
作为 活动条目
时在 Window 上触发
|
pagereveal
|
PageRevealEvent
|
Window
|
当页面在
初始化或 重新激活
后首次开始渲染时在 Window 上触发
|
pageshow
在所有当前引擎中均受支持。 Firefox6+Safari5+Chrome3+
Opera?Edge79+ Edge (旧版)12+Internet Explorer11 Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
PageTransitionEvent
|
Window
|
当页面的 会话历史条目
成为 活动条目
时在 Window 上触发
|
pointercancel
|
PointerEvent
|
元素和 Text
节点
|
当用户尝试启动拖放操作时在 源节点 上触发 |
popstate
在所有当前引擎中均受支持。 Firefox4+Safari5+Chrome5+
Opera11.5+Edge79+ Edge (旧版)12+Internet Explorer10+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11.5+ |
PopStateEvent
|
Window
|
在某些会话历史遍历情况下在 Window 上触发
|
readystatechange
Document/readystatechange_event 在所有当前引擎中均受支持。 Firefox4+Safari5.1+Chrome9+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer4+ Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+ |
Event
|
Document
|
在 Document
完成解析时触发,并在其所有子资源加载完毕后再次触发
|
rejectionhandled
|
PromiseRejectionEvent
|
全局范围对象 | 当先前未处理的 promise 拒绝变为已处理时在全局范围对象中触发 |
reset
在所有当前引擎中均受支持。 Firefox6+Safari3+Chrome1+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+ |
Event
|
form
元素
|
在 form
元素被 重置 时触发
|
select
在所有当前引擎中均受支持。 Firefox6+Safari1+Chrome1+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ HTMLTextAreaElement/select_event 在所有当前引擎中均受支持。 Firefox6+Safari1+Chrome1+
Opera12.1+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+ |
Event
|
表单控件 | 在表单控件的文本选择被调整时(无论是通过 API 还是用户)触发 |
storage
在所有当前引擎中均受支持。 Firefox45+Safari4+Chrome1+
Opera?Edge79+ Edge (旧版)15+Internet Explorer9+ Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android? |
StorageEvent
|
Window
|
当相应的 localStorage
或 sessionStorage
存储区域发生变化时在 Window
事件中触发
|
submit
在所有当前引擎中均受支持。 Firefox1+Safari3+Chrome1+
Opera8+Edge79+ Edge (旧版)12+Internet Explorer9+ Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+ |
SubmitEvent
|
form
元素
|
在 form
元素被 提交 时触发
|
toggle
HTMLDetailsElement/toggle_event 在所有当前引擎中均受支持。 Firefox49+Safari10.1+Chrome36+
Opera?Edge79+ Edge (旧版)?Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? 在所有当前引擎中均受支持。 🔰
114+Safari预览版+Chrome114+
Opera?Edge114+ Edge (旧版)?Internet ExplorerNo Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android? |
ToggleEvent
|
details
和 popover 元素
|
在 details
元素打开或关闭时触发;在带有 popover
属性的元素在显示和隐藏之间过渡时触发
|
unhandledrejection
Window/unhandledrejection_event 在所有当前引擎中均受支持。 Firefox69+Safari11+Chrome49+
Opera?Edge79+ Edge (旧版)?Internet ExplorerNo Firefox Android?Safari iOS11.3+Chrome Android?WebView Android?Samsung Internet?Opera Android? |
PromiseRejectionEvent
|
全局范围对象 | 当 promise 拒绝未处理时在全局范围对象中触发 |
unload
在所有当前引擎中均受支持。 Firefox1+Safari3+Chrome1+
Opera4+Edge79+ Edge (旧版)12+Internet Explorer4+ Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+ |
Event
|
Window
|
当页面将要消失时在 Window
对象上触发
|
visibilitychange
Document/visibilitychange_event 在所有当前引擎中均受支持。 Firefox56+Safari14.1+Chrome62+
Opera49+Edge79+ Edge (旧版)18Internet Explorer🔰 10+ Firefox Android?Safari iOS?Chrome Android?WebView Android62+Samsung Internet?Opera Android46+ |
Event
|
Document
|
当页面对用户变得可见或隐藏时在 Document
对象上触发
|
本节为非规范性内容。
本规范定义了以下 HTTP 请求头部:
Last-Event-ID
`
Ping-From
`Ping-To
`本规范定义了以下 HTTP 响应头部:
Cross-Origin-Embedder-Policy
`
Cross-Origin-Embedder-Policy-Report-Only
`
Cross-Origin-Opener-Policy
`
Cross-Origin-Opener-Policy-Report-Only
`
Origin-Agent-Cluster
`
Refresh
`X-Frame-Options
`
本节为非规范性内容。
本规范中提到了以下 MIME 类型:
application/atom+xml
application/json
application/octet-stream
application/microdata+json
application/rss+xml
application/x-www-form-urlencoded
application/xhtml+xml
application/xml
image/gif
image/jpeg
image/png
image/svg+xml
multipart/form-data
multipart/mixed
multipart/x-mixed-replace
text/css
text/event-stream
text/javascript
text/json
text/plain
text/html
text/ping
text/uri-list
text/vcard
text/vtt
text/xml
video/mp4
video/mpeg
所有参考文献均为规范性引用,除非标注为“非规范性”。
XMLHttpRequest
, A. van Kesteren.
WHATWG.
感谢蒂姆·伯纳斯-李发明了 HTML,没有他,这一切都不会存在。
感谢 Aankhen, Aaqa Ishtyaq, Aaron Boodman, Aaron Leventhal, Aaron Krajeski, Abhishek Ghaskata, Abhishek Gupta, Adam Barth, Adam de Boor, Adam Hepton, Adam Klein, Adam Rice, Adam Roben, Addison Phillips, Adele Peterson, Adrian Bateman, Adrian Roselli, Adrian Sutton, Agustín Fernández, Aharon (Vladimir) Lanin, Ajai Tirumali, Ajay Poshak, Akash Balenalli Akatsuki Kitamura, Alan Plum, Alastair Campbell, Alejandro G. Castro, Alex Bishop, Alex Nicolaou, Alex Nozdriukhin, Alex Rousskov, Alex Soncodi, Alexander Farkas, Alexander J. Vincent, Alexander Kalenik, Alexandre Dieulot, Alexandre Morgaut, Alexey Feldgendler, Алексей Проскуряков (Alexey Proskuryakov), Alexey Shvayka, Alexis Deveria, Alfred Agrell, Ali Juma, Alice Boxhall, Alice Wonder, Allan Clements, Allen Wirfs-Brock, Alex Komoroske, Alex Russell, Alphan Chen, Aman Ansari, Ami Fischman, Amos Jeffries, Amos Lim, Anders Carlsson, André Bargull, André E. Veltstra, Andrea Rendine, Andreas, Andreas Deuschlinger, Andreas Farre, Andreas Kling, Andrei Popescu, Andres Gomez, Andres Rios, Andreu Botella, Andrew Barfield, Andrew Clover, Andrew Gove, Andrew Grieve, Andrew Kaster, Andrew Macpherson, Andrew Oakley, Andrew Paseltiner, Andrew Simons, Andrew Smith, Andrew W. Hagen, Andrew Williams, Andrey V. Lukyanov, Andry Rendy, Andy Davies, Andy Earnshaw, Andy Heydon, Andy Paicu, Andy Palay, Anjana Vakil, Ankur Kaushal, Anna Belle Leiserson, Anna Sidwell, Anthony Boyd, Anthony Bryan, Anthony Hickson, Anthony Ramine, Anthony Ricaud, Anton Vayvod, Antonio Sartori, Antti Koivisto, Arfat Salman, Arkadiusz Michalski, Arne Thomassen, Aron Spohr, Arphen Lin, Arthur Hemery, Arthur Sonzogni, Arthur Stolyar, Arun Patole, Aryeh Gregor, Asanka Herath, Asbjørn Ulsberg, Ashley Gullen, Ashley Sheridan, Asumu Takikawa, Atsushi Takayama, Attila Haraszti, Aurelien Levy, Ave Wrigley, Avi Drissman, Axel Dahmen, 방성범 (Bang Seongbeom), Barry Pollard, Ben Boyle, Ben Godfrey, Ben Golightly, Ben Kelly, Ben Lerner, Ben Leslie, Ben Meadowcroft, Ben Millard, Benjamin Carl Wiley Sittler, Benjamin Hawkes-Lewis, Benji Bilheimer, Benoit Ren, Bert Bos, Bijan Parsia, Bil Corry, Bill Mason, Bill McCoy, Billy Wong, Billy Woods, Bjartur Thorlacius, Björn Höhrmann, Blake Frantz, Bob Lund, Bob Owen, Bobby Holley, Boris Zbarsky, Brad Fults, Brad Neuberg, Brad Spencer, Bradley Meck, Brady Eidson, Brandon Jones, Brendan Eich, Brenton Simpson, Brett Wilson, Brett Zamir, Brian Birtles, Brian Blakely, Brian Campbell, Brian Korver, Brian Kuhn, Brian M. Dube, Brian Ryner, Brian Smith, Brian Wilson, Bryan Sullivan, Bruce Bailey, Bruce D'Arcus, Bruce Lawson, Bruce Miller, Bugs Nash, C. Scott Ananian, C. Williams, Cameron McCormack, Cameron Zemek, Cao Yipeng, Carlos Amengual, Carlos Gabriel Cardona, Carlos Ibarra López, Carlos Perelló Marín, Carolyn MacLeod, Casey Leask, Cătălin Badea, Cătălin Mariș, Cem Turesoy, ceving, Chao Cai, 윤석찬 (Channy Yun), Charl van Niekerk, Charlene Wright, Charles Iliya Krempeaux, Charles McCathie Nevile, Charlie Reis, 白丞祐 (Cheng-You Bai), Chris Apers, Chris Cressman, Chris Dumez, Chris Evans, Chris Harrelson, Chris Markiewicz, Chris Morris, Chris Nardi, Chris Needham, Chris Pearce, Chris Peterson, Chris Rebert, Chris Weber, Chris Wilson, Christian Biesinger, Christian Johansen, Christian Schmidt, Christoph Päper, Christophe Dumez, Christopher Aillon, Christopher Cameron, Christopher Ferris, Chriswa, Clark Buehler, Cole Robison, Colin Fine, Collin Jackson, Corey Farwell, Corprew Reed, Craig Cockburn, Csaba Gabor, Csaba Marton, Cynthia Shelly, Cyrille Tuzi, Daksh Shah, Dan Callahan, Dan Yoder, Dane Foster, Daniel Barclay, Daniel Bratell, Daniel Brooks, Daniel Brumbaugh Keeney, Daniel Buchner, Daniel Cheng, Daniel Clark, Daniel Davis, Daniel Ehrenberg, Daniel Glazman, Daniel Holbert, Daniel Peng, Daniel Schattenkirchner, Daniel Spång, Daniel Steinberg, Daniel Tan, Daniel Trebbien, Daniel Vogelheim, Danny Sullivan, Daphne Preston-Kendal, Darien Maillet Valentine, Darin Adler, Darin Fisher, Darxus, Dave Camp, Dave Cramer, Dave Hodder, Dave Lampton, Dave Singer, Dave Tapuska, Dave Townsend, David Baron, David Bloom, David Bokan, David Bruant, David Carlisle, David E. Cleary, David Egan Evans, David Fink, David Flanagan, David Gerard, David Grogan, David Hale, David Håsäther, David Hyatt, David I. Lehn, David John Burrowes, David Matja, David Remahl, David Resseguie, David Smith, David Storey, David Vest, David Woolley, David Zbarsky, Dave Methvin, DeWitt Clinton, Dean Edridge, Dean Edwards, Dean Jackson, Debanjana Sarkar, Debi Orton, Delan Azabani, Derek Featherstone, Derek Guenther, Devarshi Pant, Devdatta, Devin Mullins, Devin Rousso, Di Zhang, Diego Ferreiro Val, Diego González Zúñiga, Diego Ponce de León, Dimitri Glazkov, Dimitry Golubovsky, Dirk Pranke, Dirk Schulze, Dirkjan Ochtman, Divya Manian, Dmitry Lazutkin, Dmitry Titov, dolphinling, Dominic Cooney, Dominique Hazaël-Massieux, Don Brutzman, Donovan Glover, Doron Rosenberg, Doug Kramer, Doug Simpkinson, Drew Wilson, Edgar Chen, Edmund Lai, Eduard Pascual, Eduardo Vela, Edward Welbourne, Edward Z. Yang, Ehsan Akhgari, Eira Monstad, Eitan Adler, Eli Friedman, Eli Grey, Eliot Graff, Elisabeth Robson, Elizabeth Castro, Elliott Sprehn, Elliotte Harold, Emilio Cobos Álvarez, Emily Stark, Eric Carlson, Eric Casler, Eric Lawrence, Eric Portis, Eric Rescorla, Eric Semling, Eric Shepherd, Eric Willigers, Erik Arvidsson, Erik Charlebois, Erik Rose, 栗本 英理子 (Eriko Kurimoto), espretto, Evan Jacobs, Evan Martin, Evan Prodromou, Evan Stade, Evert, Evgeny Kapun, ExE-Boss, Ezequiel Garzón, fantasai, Félix Sanz, Felix Sasaki, Fernando Altomare Serboncini, Forbes Lindesay, Francesco Schwarz, Francis Brosnan Blazquez, Franck 'Shift' Quélain, François Marier, Frank Barchard, Frank Liberato, Franklin Shirley, Frederik Braun, Fredrik Söderquist, 鵜飼文敏 (Fumitoshi Ukai), Futomi Hatano, Gavin Carothers, Gavin Kistner, Gareth Rees, Garrett Smith, Gary Blackwood, Gary Kacmarcik, Gary Katsevman, Geoff Richards, Geoffrey Garen, Georg Neis, George Lund, Gianmarco Armellin, Giovanni Campagna, Giuseppe Pascale, Glenn Adams, Glenn Maynard, Graham Klyne, Greg Botten, Greg Houston, Greg Wilkins, Gregg Tavares, Gregory J. Rosmaita, Gregory Terzian, Grey, guest271314, Guilherme Johansson Tramontina, Guy Bedford, Gytis Jakutonis, Håkon Wium Lie, Habib Virji, Hajime Morrita, Hallvord Reiar Michaelsen Steen, Hanna Laakso, Hans S. Tømmerhalt, Hans Stimer, Harald Alvestrand, Hayato Ito, 何志翔 (HE Zhixiang), Henri Sivonen, Henrik Lied, Henrik Lievonen, Henry Lewis, Henry Mason, Henry Story, Hermann Donfack Zeufack, 中川博貴 (Hiroki Nakagawa), Hiroshige Hayashizaki, Hiroyuki USHITO, Hitoshi Yoshida, Hongchan Choi, 王华 (Hua Wang), Hugh Bellamy, Hugh Guiney, Hugh Winkler, Ian Bicking, Ian Clelland, Ian Davis, Ian Fette, Ian Henderson, Ian Kilpatrick, Ibrahim Ahmed, Ido Green, Ignacio Javier, Igor Oliveira, 安次嶺 一功 (Ikko Ashimine), Ilya Grigorik, Ingvar Stepanyan, isonmad, Iurii Kucherov, Ivan Enderlin, Ivan Nikulin, Ivan Panchenko, Ivo Emanuel Gonçalves, J. King, J.C. Jones, Jackson Ray Hamilton, Jacob Davies, Jacques Distler, Jake Archibald, Jake Verbaten, Jakub Vrána, Jakub Łopuszański, Jakub Wilk, James Craig, James Graham, James Greene, James Justin Harrell, James Kozianski, James M Snell, James Perrett, James Robinson, Jamie Liu, Jamie Lokier, Jamie Mansfield, Jan Kühle, Jan Miksovsky, Janice Shiu, Janusz Majnert, Jan-Ivar Bruaroey, Jan-Klaas Kollhof, Jared Jacobs, Jason Duell, Jason Kersey, Jason Lustig, Jason Orendorff, Jason White, Jasper Bryant-Greene, Jasper St. Pierre, Jatinder Mann, Jay Henry Kao, Jean-Yves Avenard, Jed Hartman, Jeff Balogh, Jeff Cutsinger, Jeff Gilbert, Jeff "=JeffH" Hodges, Jeff Schiller, Jeff Walden, Jeffrey Yasskin, Jeffrey Zeldman, 胡慧鋒 (Jennifer Braithwaite), Jellybean Stonerfish, Jennifer Apacible, Jens Bannmann, Jens Fendler, Jens Oliver Meiert, Jens Widell, Jer Noble, Jeremey Hustman, Jeremy Keith, Jeremy Orlow, Jeremy Roman, Jeroen van der Meer, Jerry Smith, Jesse Renée Beach, Jessica Jong, jfkthame, Jian Li, Jihye Hong, Jim Jewett, Jim Ley, Jim Meehan, Jim Michaels, Jinho Bang, Jinjiang (勾三股四), Jirka Kosek, Jjgod Jiang, Joaquim Medeiros, João Eiras, Jochen Eisinger, Joe Clark, Joe Gregorio, Joel Spolsky, Joel Verhagen, Joey Arhar, Johan Herland, Johanna Herman, John Boyer, John Bussjaeger, John Carpenter, John Daggett, John Fallows, John Foliot, John Harding, John Keiser, John Law, John Musgrave, John Snyders, John Stockton, John-Mark Bell, Johnny Stenback, Jon Coppeard, Jon Ferraiolo, Jon Gibbins, Jon Jensen, Jon Perlow, Jonas Sicking, Jonathan Cook, Jonathan Kew, Jonathan Neal, Jonathan Oddy, Jonathan Rees, Jonathan Watt, Jonathan Worent, Jonny Axelsson, Joram Schrijver, Jordan Tucker, Jorgen Horstink, Joris van der Wel, Jorunn Danielsen Newth, Joseph Kesselman, Joseph Mansfield, Joseph Pecoraro, Josh Aas, Josh Hart, Josh Juran, Josh Levenberg, Josh Matthews, Joshua Bell, Joshua Chen, Joshua Randall, Juan Olvera, Juanmi Huertas, Jukka K. Korpela, Jules Clément-Ripoche, Julian Reschke, Julio Lopez, 小勝 純 (Jun Kokatsu), Jun Yang (harttle), Jungkee Song, Jürgen Jeka, Justin Lebar, Justin Novosad, Justin Rogers, Justin Schuh, Justin Sinclair, Juuso Lapinlampi, Ka-Sing Chou, Kagami Sascha Rosylight, Kai Hendry, Kamishetty Sreeja, 呂康豪 (KangHao Lu), Karl Dubost, Karl Tomlinson, Kartik Arora, Kartikaya Gupta, Kathy Walton, 河童エクマ(Kawarabe Ecma) Keith Cirkel, Keith Rollin, Keith Yeung, Kelly Ford, Kelly Norton, Ken Russell, Kenji Baheux, Kevin Benson, Kevin Cole, Kevin Gadd, Kevin Venkiteswaran, Khushal Sagar, Kinuko Yasuda, Koji Ishii, Kornél Pál, Kornel Lesinski, 上野 康平 (UENO, Kouhei), Kris Northfield, Kristof Zelechovski, Krzysztof Maczyński, 黒澤剛志 (Kurosawa Takeshi), Kyle Barnhart, Kyle Hofmann, Kyle Huey, Léonard Bouchet, Léonie Watson, Lachlan Hunt, Larry Masinter, Larry Page, Lars Gunther, Lars Solberg, Laura Carlson, Laura Granka, Laura L. Carlson, Laura Wisewell, Laurens Holst, Lawrence Forooghian, Lee Kowalkowski, Leif Halvard Silli, Leif Kornstaedt, Lenny Domnitser, Leonard Rosenthol, Leons Petrazickis, Liviu Tinta, Lobotom Dysmon, Logan, Logan Moore, Loune, Lucas Gadani, Łukasz Pilorz, Luke Kenneth Casson Leighton, Luke Warlow, Luke Wilde, Maciej Stachowiak, Magne Andersson, Magnus Kristiansen, Maik Merten, Majid Valipour, Malcolm Rowe, Manish Goregaokar, Manish Tripathi, Manuel Martinez-Almeida, Manuel Rego Casasnovas, Marc Hoyois, Marc-André Choquette, Marc-André Lafortune, Marco Zehe, Marcus Bointon, Marcus Otterström, Marijn Kruisselbrink, Mark Amery, Mark Birbeck, Mark Davis, Mark Green, Mark Miller, Mark Nottingham, Mark Pilgrim, Mark Rogers, Mark Rowe, Mark Schenk, Mark Vickers, Mark Wilton-Jones, Markus Cadonau, Markus Stange, Martijn van der Ven, Martijn Wargers, Martin Atkins, Martin Chaov, Martin Dürst, Martin Honnen, Martin Janecke, Martin Kutschker, Martin Nilsson, Martin Thomson, Masataka Yakura, Masatoshi Kimura, Mason Freed, Mason Mize, Mathias Bynens, Mathieu Henri, Matias Larsson, Matt Brubeck, Matt Di Pasquale, Matt Falkenhagen, Matt Giuca, Matt Harding, Matt Schmidt, Matt Wright, Matthew Gaudet, Matthew Gregan, Matthew Mastracci, Matthew Noorenberghe, Matthew Raymond, Matthew Thomas, Matthew Tylee Atkinson, Mattias Waldau, Max Romantschuk, Maxim Tsoy, Mayeul Cantan, Menachem Salomon, Menno van Slooten, Micah Dubinko, Micah Nerren, Michael 'Ratt' Iannarelli, Michael A. Nachbaur, Michael A. Puls II, Michael Carter, Michael Daskalov, Michael Day, Michael Dyck, Michael Enright, Michael Gratton, Michael Kohler, Michael McKelvey, Michael Nordman, Michael Powers, Michael Rakowski, Michael(tm) Smith, Michael Walmsley, Michal Zalewski, Michel Buffa, Michel Fortin, Michelangelo De Simone, Michiel van der Blonk, Miguel Casas-Sanchez, Mihai Şucan, Mihai Parparita, Mike Brown, Mike Dierken, Mike Dixon, Mike Hearn, Mike Pennisi, Mike Schinkel, Mike Shaver, Mikko Rantalainen, Mingye Wang, Mirko Brodesser, Mohamed Zergaoui, Mohammad Al Houssami, Mohammad Reza Zakerinasab, Momdo Nakamura, Morten Stenshorne, Mounir Lamouri, Ms2ger, mtrootyy, 邱慕安 (Mu-An Chiou), Mukilan Thiyagarajan, Mustaq Ahmed, Myles Borins, Nadia Heninger, Nate Chapin, NARUSE Yui, Navid Zolghadr, Neil Deakin, Neil Rashbrook, Neil Soiffer, Nereida Rondon, networkException, Nicholas Shanks, Nicholas Stimpson, Nicholas Zakas, Nickolay Ponomarev, Nicolas Gallagher, Nicolas Pena Moreno, Nicolò Ribaudo, Nidhi Jaju, Nikki Bee, Niklas Gögge, Nina Satragno, Noah Mendelsohn, Noah Slater, Noam Rosenthal, Noel Gordon, Nolan Waite, NoozNooz42, Norbert Lindenberg, Oisín Nolan, Ojan Vafai, Olaf Hoffmann, Olav Junker Kjær, Oldřich Vetešník, Oli Studholme, Oliver Hunt, Oliver Rigby, Olivia (Xiaoni) Lai, Olivier Gendrin, Olli Pettay, Ondřej Žára, Ori Avtalion, Oriol Brufau, oSand, Pablo Flouret, Patrick Dark, Patrick Garies, Patrick H. Lauke, Patrik Persson, Paul Adenot, Paul Lewis, Paul Norman, Per-Erik Brodin, 一丝 (percyley), Perry Smith, Peter Beverloo, Peter Karlsson, Peter Kasting, Peter Moulder, Peter Occil, Peter Stark, Peter Van der Beken, Peter van der Zee, Peter-Paul Koch, Phil Pickering, Philip Ahlberg, Philip Brembeck, Philip Taylor, Philip TAYLOR, Philippe De Ryck, Pierre-Arnaud Allumé, Pierre-Marie Dartus, Pierre-Yves Gérardy, Piers Wombwell, Pooja Sanklecha, Prashant Hiremath, Prashanth Chandra, Prateek Rungta, Pravir Gupta, Prayag Verma, 李普君 (Pujun Li), Rachid Finge, Rafael Weinstein, Rafał Miłecki, Rahul Purohit, Raj Doshi, Rajas Moonka, Rakina Zata Amni, Ralf Stoltze, Ralph Giles, Raphael Champeimont, Rebecca Star, Remci Mizkur, Remco, Remy Sharp, Rene Saarsoo, Rene Stach, Ric Hardacre, Rich Clark, Rich Doughty, Richa Rupela, Richard Gibson, Richard Ishida, Ricky Mondello, Rigo Wenning, Rikkert Koppes, Rimantas Liubertas, Riona Macnamara, Rob Buis, Rob Ennals, Rob Jellinghaus, Rob S, Rob Smith, Robert Blaut, Robert Collins, Robert Hogan, Robert Kieffer, Robert Linder, Robert Millan, Robert O'Callahan, Robert Sayre, Robin Berjon, Robin Schaufler, Rodger Combs, Roland Steiner, Roma Matusevich, Romain Deltour, Roman Ivanov, Roy Fielding, Rune Lillesveen, Russell Bicknell, Ruud Steltenpool, Ryan King, Ryan Landay, Ryan Sleevi, Ryo Kajiwara, Ryo Kato, Ryosuke Niwa, S. Mike Dierken, Salvatore Loreto, Sam Dutton, Sam Kuper, Sam Ruby, Sam Sneddon, Sam Weinig, Samikshya Chand, Samuel Bronson, Samy Kamkar, Sander van Lambalgen, Sanjoy Pal, Sanket Joshi, Sarah Gebauer, Sarven Capadisli, Satrujit Behera, Sayan Sivakumaran, Schalk Neethling, Scott Beardsley, Scott González, Scott Hess, Scott Miles, Scott O'Hara, Sean B. Palmer, Sean Feng, Sean Fraser, Sean Hayes, Sean Hogan, Sean Knapp, Sebastian Markbåge, Sebastian Schnitzenbaumer, Sendil Kumar N, Seth Call, Seth Dillingham, Shannon Moeller, Shanti Rao, Shaun Inman, Shiino Yuki, 贺师俊 (HE Shi-Jun), Shiki Okasaka, Shivani Sharma, shreyateeza, Shubheksha Jalan, Sidak Singh Aulakh, Sierk Bornemann, Sigbjørn Finne, Sigbjørn Vik, Silver Ghost, Silvia Pfeiffer, Šime Vidas, Simon Fraser, Simon Montagu, Simon Sapin, Yu Han, Simon Spiegel, Simon Wülker, skeww, Smylers, Srirama Chandra Sekhar Mogali, Stanton McCandlish, stasoid, Stefan Håkansson, Stefan Haustein, Stefan Santesson, Stefan Schumacher, Ştefan Vargyas, Stefan Weiss, Steffen Meschkat, Stephen Ma, Stephen Stewart, Stephen White, Steve Comstock, Steve Faulkner, Steve Fink, Steve Orvell, Steve Runyon, Steven Bennett, Steven Bingler, Steven Garrity, Steven Tate, Stewart Brodie, Stuart Ballard, Stuart Langridge, Stuart Parmenter, Subramanian Peruvemba, Sudhanshu Jaiswal, sudokus999, Sunava Dutta, Surma, Susan Borgrink, Susan Lesch, Sylvain Pasche, T.J. Crowder, Tab Atkins-Bittner, Taiju Tsuiki, Takashi Toyoshima, Takayoshi Kochi, Takeshi Yoshino, Tantek Çelik, 田村健人 (Kent TAMURA), Tawanda Moyo, Taylor Hunt, Ted Mielczarek, Terence Eden, Terrence Wood, Tetsuharu OHZEKI, Theresa O'Connor, Thijs van der Vossen, Thomas Broyer, Thomas Koetter, Thomas O'Connor, Tim Altman, Tim Dresser, Tim Johansson, Tim Nguyen, Tim Perry, Tim van der Lippe, TJ VanToll, Tobias Schneider, Tobie Langel, Toby Inkster, Todd Moody, Tom Baker, Tom Pike, Tom Schuster, Tom ten Thij, Tomasz Jakut, Tomek Wytrębowicz, Tommy Thorsen, Tony Ross, Tooru Fujisawa, Toru Kobayashi, Traian Captan, Travis Leithead, Trevor Rowbotham, Trevor Saunders, Trey Eckels, triple-underscore, Tristan Fraipont, 保呂 毅 (Tsuyoshi Horo), Tyler Close, Valentin Gosu, Vardhan Gupta, Vas Sudanagunta, Veli Şenol, Victor Carbune, Victor Costan, Vipul Snehadeep Chawathe, Vitya Muhachev, Vlad Levin, Vladimir Katardjiev, Vladimir Vukićević, Vyacheslav Aristov, voracity, Walter Steiner, Wakaba, Wayne Carr, Wayne Pollock, Wellington Fernando de Macedo, Wenson Hsieh, Weston Ruter, Wilhelm Joys Andersen, Will Levine, Will Ray, William Chen, William Swanson, Willy Martin Aguirre Rodriguez, Wladimir Palant, Wojciech Mach, Wolfram Kriesing, Xan Gregg, xenotheme, XhmikosR, Xida Chen, Xidorn Quan, Xue Fuqiao, Yang Chen, Yao Xiao, Yash Handa, Yay295, Ye-Kui Wang, Yehuda Katz, Yi Xu, Yi-An Huang, Yngve Nysaeter Pettersen, Yoav Weiss, Yonathan Randolph, Yu Huojiang, Yuki Okushi, Yury Delendik, 平野裕 (Yutaka Hirano), Yuzo Fujishima, 西條柚 (Yuzu Saijo), Zhenbin Xu, 张智强 (Zhiqiang Zhang), Zoltan Herczeg, Zyachel, and Øistein E. Andersen, 感谢他们提出的有益意见,无论大小,这些意见在多年来促成了本规范的变化。
特别感谢 Richard Williamson 在 Safari 中首次实现了 canvas
,从中设计出了
canvas 功能。
也特别感谢微软员工,他们首次实现了基于事件的拖放机制,contenteditable
,以及其他首次由
Windows Internet Explorer 浏览器广泛部署的功能。
特别感谢并奖励 $10,000 给 David Hyatt,他提出了 收养代理算法 的一个破损实现,编辑不得不进行逆向工程和修复后才能在解析部分使用。
感谢微数据可用性研究的参与者允许我们利用他们的错误作为设计微数据功能的指导。
感谢许多为规范中使用的示例提供灵感的来源。
同样感谢微软博客社区提供的一些想法,感谢W3C Web应用和复合文档研讨会的与会者提供的灵感,感谢#mrt团队、#mrt.no团队、#whatwg团队,以及Pillar和Hedral的想法和支持。
感谢Igor Zhbanov为规范生成PDF版本。
特别感谢RICG开发了picture
元素和相关功能;特别感谢Adrian
Bateman、Bruce Lawson、David Newton、Ilya Grigorik、John Schoenick、Leon de Rijke、Mat Marquis、Marcos Cáceres、Tab
Atkins、Theresa O'Connor和Yoav Weiss的贡献。
特别感谢WPWG孵化了自定义元素功能。特别感谢David Hyatt和Ian Hickson通过XBL规范的影响,感谢Dimitri Glazkov为自定义元素规范的首个草案,以及感谢 Alex Komoroske, Alex Russell, Andres Rios, Boris Zbarsky, Brian Kardell, Daniel Buchner, Dominic Cooney, Erik Arvidsson, Elliott Sprehn, Hajime Morrita, Hayato Ito, Jan Miksovsky, Jonas Sicking, Olli Pettay, Rafael Weinstein, Roland Steiner, Ryosuke Niwa, Scott Miles, Steve Faulkner, Steve Orvell, Tab Atkins, Theresa O'Connor, Tim Perry, and William Chen 的贡献。
特别感谢CSSWG开发了worklets。特别感谢Ian Kilpatrick作为原始worklets规范的编辑所做的工作。
从2003年开始的约十年间,该标准几乎完全由Ian Hickson(Google,ian@hixie.ch)编写。
从2015年开始,编辑小组扩大了。它目前由以下人员维护: Anne van Kesteren (Apple, annevk@annevk.nl), Domenic Denicola (Google, d@domenic.me) Dominic Farolino (Google, domfarolino@gmail.com), Philip Jägenstedt (Google, philip@foolip.org),以及 Simon Pieters (Mozilla, zcorpan@gmail.com)。
介绍中的图片基于 一张照片, 由 Wonderlane 提供。 (CC BY 2.0)
嵌入内容介绍中的狼的图片基于 一张照片, 由 Barry O'Neill 提供。 (公共领域)
Canvas演示中使用的蓝色机器人玩家精灵基于 一项作品, 由 JohnColburn 提供。 (CC BY-SA 3.0)
2013年硅谷地区FIRST机器人竞赛中148号机器人爬塔的照片基于 一项作品, 由 Lenore Edman 提供。 (CC BY 2.0)
用于演示基于模块的workers的图像解码演示借鉴了 一个教程中的示例代码, 由 Ilmari Heikkinen 提供。 (CC BY 3.0)
<flag-icon>
示例灵感来源于 一个自定义元素,
由 Steven
Skelton
提供。
(MIT)
关于 picture
元素及相关功能的部分修订历史可以在
ResponsiveImagesCG/picture-element
仓库中找到,
该仓库根据 W3C
软件和文档许可证 提供。
关于 theme-color
元数据名称的部分修订历史可以在
whatwg/meta-theme-color
仓库中找到,
该仓库根据 CC0 提供。
关于 自定义元素功能的部分修订历史可以在
w3c/webcomponents
仓库中找到,
该仓库根据 W3C
软件和文档许可证 提供。
关于 innerText
获取器和设置器的部分修订历史可以在
rocallahan/innerText-spec
仓库中找到,
该仓库根据 CC0 提供。
关于 worklets
功能的部分修订历史可以在
w3c/css-houdini-drafts
仓库中找到,
该仓库根据 W3C
软件和文档许可证 提供。
关于 导入映射
功能的部分修订历史可以在
WICG/import-maps
仓库中找到,
该仓库根据 W3C
软件和文档许可证 提供。
关于 导航 API
功能的部分修订历史可以在
WICG/navigation-api
仓库中找到,
该仓库根据 W3C
软件和文档许可证 提供。
关于 关闭请求和关闭监视器
部分的修订历史可以在
WICG/close-watcher
仓库中找到,
该仓库根据 W3C
软件和文档许可证 提供。
版权所有 © WHATWG (Apple, Google, Mozilla, Microsoft)。本作品根据 创作共用署名4.0国际许可证 许可发布。若其部分内容被纳入源代码中,则该部分源代码依据 BSD 3-Clause许可证 授权。
这是现行标准。希望查看专利审核版本的人士应查阅 现行标准审核草案。