目录

  1. 1 简介
  2. 2 通用基础设施
  3. 3 HTML文档的语义、结构和API
  4. 4 HTML元素
  5. 5 微数据
  6. 6 用户交互
  7. 7 加载网页
  8. 8 Web应用程序API
  9. 9 通信
  10. 10 Web workers
  11. 11 Worklets
  12. 12 Web存储
  13. 13 HTML语法
  14. 14 XML语法
  15. 15 渲染
  16. 16 废弃特性
  17. 17 IANA考虑
  18. 索引
  19. 参考资料
  20. 致谢
  21. 知识产权

完整目录

  1. 1 简介
    1. 1.1 本规范的适用范围
    2. 1.2 这是HTML5吗?
    3. 1.3 背景
    4. 1.4 读者
    5. 1.5 范围
    6. 1.6 历史
    7. 1.7 设计说明
      1. 1.7.1 脚本执行的可序列化
      2. 1.7.2 与其他规范的兼容性
      3. 1.7.3 扩展性
    8. 1.8 HTML 与 XML 语法
    9. 1.9 本规范的结构
      1. 1.9.1 如何阅读本规范
      2. 1.9.2 排版约定
    10. 1.10 HTML简要介绍
      1. 1.10.1 使用HTML编写安全应用程序
      2. 1.10.2 使用脚本 API 时需避免的常见陷阱
      3. 1.10.3 如何捕捉编写 HTML 时的错误:验证器和合规检查器
    11. 1.11 对作者的合规要求
      1. 1.11.1 表现性标记
      2. 1.11.2 语法错误
      3. 1.11.3 内容模型和属性值的限制
    12. 1.12 建议阅读
  2. 2 常见基础设施
    1. 2.1 术语
      1. 2.1.1 并行处理
      2. 2.1.2 资源
      3. 2.1.3 XML兼容性
      4. 2.1.4 DOM树
      5. 2.1.5 脚本
      6. 2.1.6 插件
      7. 2.1.7 字符编码
      8. 2.1.8 合规类
      9. 2.1.9 依赖关系
      10. 2.1.10 扩展性
      11. 2.1.11 与 XPath 和 XSLT 的交互
    2. 2.2 政策控制的功能
    3. 2.3 通用微语法
      1. 2.3.1 通用解析器习惯用法
      2. 2.3.2 布尔属性
      3. 2.3.3 关键字和枚举属性
      4. 2.3.4 数字
        1. 2.3.4.1 有符号整数
        2. 2.3.4.2 非负整数
        3. 2.3.4.3 浮点数
        4. 2.3.4.4 百分比和长度
        5. 2.3.4.5 非零百分比和长度
        6. 2.3.4.6 浮点数列表
        7. 2.3.4.7 维度列表
      5. 2.3.5 日期和时间
        1. 2.3.5.1 月份
        2. 2.3.5.2 日期
        3. 2.3.5.3 无年份的日期
        4. 2.3.5.4 时间
        5. 2.3.5.5 本地日期和时间
        6. 2.3.5.6 时区
        7. 2.3.5.7 全球日期和时间
        8. 2.3.5.8
        9. 2.3.5.9 持续时间
        10. 2.3.5.10 更模糊的时间点
      6. 2.3.6 颜色
      7. 2.3.7 空格分隔的标记
      8. 2.3.8 逗号分隔的标记
      9. 2.3.9 引用
      10. 2.3.10 媒体查询
      11. 2.3.11 唯一内部值
    4. 2.4 URLs
      1. 2.4.1 术语
      2. 2.4.2 解析 URL
      3. 2.4.3 基础 URL 的动态更改
    5. 2.5 获取资源
      1. 2.5.1 术语
      2. 2.5.2 确定资源类型
      3. 2.5.3meta元素中提取字符编码
      4. 2.5.4 CORS 设置属性
      5. 2.5.5 引荐政策属性
      6. 2.5.6 Nonce属性
      7. 2.5.7 延迟加载属性
      8. 2.5.8 阻塞属性
      9. 2.5.9 获取优先级属性
    6. 2.6 常见 DOM 接口
      1. 2.6.1 在 IDL 属性中反射内容属性
      2. 2.6.2 在规范中使用 reflect
      3. 2.6.3 集合
        1. 2.6.3.1 HTMLAllCollection接口
          1. 2.6.3.1.1 [[Call]] ( thisArgument, argumentsList )
        2. 2.6.3.2 HTMLFormControlsCollection接口
        3. 2.6.3.3 HTMLOptionsCollection接口
      4. 2.6.4 DOMStringList接口
    7. 2.7 安全传递结构化数据
      1. 2.7.1 可序列化对象
      2. 2.7.2 可转移对象
      3. 2.7.3 StructuredSerializeInternal ( value, forStorage [ , memory ] )
      4. 2.7.4 StructuredSerialize ( value )
      5. 2.7.5 StructuredSerializeForStorage ( value )
      6. 2.7.6 StructuredDeserialize ( serialized, targetRealm [ , memory ] )
      7. 2.7.7 StructuredSerializeWithTransfer ( value, transferList )
      8. 2.7.8 StructuredDeserializeWithTransfer ( serializeWithTransferResult, targetRealm )
      9. 2.7.9 从其他规范执行序列化和传输
      10. 2.7.10 结构化克隆 API
  3. 3 HTML文档的语义、结构和API
    1. 3.1 文档
      1. 3.1.1 Document对象
      2. 3.1.2 DocumentOrShadowRoot接口
      3. 3.1.3 资源元数据管理
      4. 3.1.4 报告文档加载状态
      5. 3.1.5 渲染阻塞机制
      6. 3.1.6 DOM 树访问器
    2. 3.2 元素
      1. 3.2.1 语义
      2. 3.2.2 DOM中的元素
      3. 3.2.3 HTML元素构造函数
      4. 3.2.4 元素定义
        1. 3.2.4.1 属性
      5. 3.2.5 内容模型
        1. 3.2.5.1 “nothing”内容模型
        2. 3.2.5.2 内容种类
          1. 3.2.5.2.1 元数据内容
          2. 3.2.5.2.2 流内容
          3. 3.2.5.2.3 分节内容
          4. 3.2.5.2.4 标题内容
          5. 3.2.5.2.5 内联内容
          6. 3.2.5.2.6 嵌入内容
          7. 3.2.5.2.7 交互内容
          8. 3.2.5.2.8 可感知内容
          9. 3.2.5.2.9 脚本支持元素
        3. 3.2.5.3 透明内容模型
        4. 3.2.5.4 段落
      6. 3.2.6 全局属性
        1. 3.2.6.1 title属性
        2. 3.2.6.2 langxml:lang属性
        3. 3.2.6.3 translate属性
        4. 3.2.6.4 dir属性
        5. 3.2.6.5 style属性
        6. 3.2.6.6 嵌入自定义不可见数据 使用data-*属性
      7. 3.2.7 innerTextouterText属性
      8. 3.2.8 与双向算法相关的要求
        1. 3.2.8.1 双向算法格式化字符的编写一致性标准
        2. 3.2.8.2 用户代理一致性标准
      9. 3.2.9 与 ARIA 及平台无障碍 API 相关的要求
  4. 4 HTML 元素
    1. 4.1 文档元素
      1. 4.1.1 html元素
    2. 4.2 文档元数据
      1. 4.2.1 head元素
      2. 4.2.2 title元素
      3. 4.2.3 base元素
      4. 4.2.4 link元素
        1. 4.2.4.1 处理 media 属性
        2. 4.2.4.2 处理 type 属性
        3. 4.2.4.3link 元素获取和处理资源
        4. 4.2.4.4 处理 `Link` 头部
        5. 4.2.4.5 早期提示
        6. 4.2.4.6 提供用户通过 link 元素创建的超链接进行访问的方式
      5. 4.2.5 meta元素
        1. 4.2.5.1 标准元数据名称
        2. 4.2.5.2 其他元数据名称
        3. 4.2.5.3 Pragma指令
        4. 4.2.5.4 指定文档的字符编码
      6. 4.2.6 style元素
      7. 4.2.7 样式和脚本的交互
    3. 4.3 区块
      1. 4.3.1 body元素
      2. 4.3.2 article元素
      3. 4.3.3 section元素
      4. 4.3.4 nav元素
      5. 4.3.5 aside元素
      6. 4.3.6 h1h2h3h4h5h6 元素
      7. 4.3.7 hgroup元素
      8. 4.3.8 header元素
      9. 4.3.9 footer元素
      10. 4.3.10 address元素
      11. 4.3.11 标题和大纲
        1. 4.3.11.1 示例大纲
        2. 4.3.11.2 向用户暴露大纲
      12. 4.3.12 使用摘要
        1. 4.3.12.1 文章还是区块?
    4. 4.4 内容分组
      1. 4.4.1 p元素
      2. 4.4.2 hr元素
      3. 4.4.3 pre元素
      4. 4.4.4 blockquote元素
      5. 4.4.5 ol元素
      6. 4.4.6 ul元素
      7. 4.4.7 menu元素
      8. 4.4.8 li元素
      9. 4.4.9 dl元素
      10. 4.4.10 dt元素
      11. 4.4.11 dd元素
      12. 4.4.12 figure元素
      13. 4.4.13 figcaption元素
      14. 4.4.14 main元素
      15. 4.4.15 search元素
      16. 4.4.16 div元素
    5. 4.5 文本级语义
      1. 4.5.1 a元素
      2. 4.5.2 em元素
      3. 4.5.3 strong元素
      4. 4.5.4 small元素
      5. 4.5.5 s元素
      6. 4.5.6 cite元素
      7. 4.5.7 q元素
      8. 4.5.8 dfn元素
      9. 4.5.9 abbr元素
      10. 4.5.10 ruby元素
      11. 4.5.11 rt元素
      12. 4.5.12 rp元素
      13. 4.5.13 data元素
      14. 4.5.14 time元素
      15. 4.5.15 code元素
      16. 4.5.16 var元素
      17. 4.5.17 samp元素
      18. 4.5.18 kbd元素
      19. 4.5.19 subsup元素
      20. 4.5.20 i元素
      21. 4.5.21 b元素
      22. 4.5.22 u元素
      23. 4.5.23 mark元素
      24. 4.5.24 bdi元素
      25. 4.5.25 bdo元素
      26. 4.5.26 span元素
      27. 4.5.27 br元素
      28. 4.5.28 wbr元素
      29. 4.5.29 使用总结
    6. 4.6 链接
      1. 4.6.1 介绍
      2. 4.6.2aarea 元素创建的链接
      3. 4.6.3 aarea 元素的 API
      4. 4.6.4 跟随超链接
      5. 4.6.5 下载资源
      6. 4.6.6 超链接审计
        1. 4.6.6.1 `Ping-From` 和 `Ping-To` 头部
      7. 4.6.7 链接类型
        1. 4.6.7.1 链接类型 "alternate"
        2. 4.6.7.2 链接类型 "author"
        3. 4.6.7.3 链接类型 "bookmark"
        4. 4.6.7.4 链接类型 "canonical"
        5. 4.6.7.5 链接类型 "dns-prefetch"
        6. 4.6.7.6 链接类型 "expect"
        7. 4.6.7.7 链接类型 "external"
        8. 4.6.7.8 链接类型 "help"
        9. 4.6.7.9 链接类型 "icon"
        10. 4.6.7.10 链接类型 "license"
        11. 4.6.7.11 链接类型 "manifest"
        12. 4.6.7.12 链接类型 "modulepreload"
        13. 4.6.7.13 链接类型 "nofollow"
        14. 4.6.7.14 链接类型 "noopener"
        15. 4.6.7.15 链接类型 "noreferrer"
        16. 4.6.7.16 链接类型 "opener"
        17. 4.6.7.17 链接类型 "pingback"
        18. 4.6.7.18 链接类型 "preconnect"
        19. 4.6.7.19 链接类型 "prefetch"
        20. 4.6.7.20 链接类型 "preload"
        21. 4.6.7.21 链接类型 "privacy-policy"
        22. 4.6.7.22 链接类型 "search"
        23. 4.6.7.23 链接类型 "stylesheet"
        24. 4.6.7.24 链接类型 "tag"
        25. 4.6.7.25 链接类型 "terms-of-service"
        26. 4.6.7.26 顺序链接类型
          1. 4.6.7.26.1 链接类型 "next"
          2. 4.6.7.26.2 链接类型 "prev"
        27. 4.6.7.27 其他链接类型
    7. 4.7 编辑
      1. 4.7.1 ins 元素
      2. 4.7.2 del 元素
      3. 4.7.3 insdel 元素的公共属性
      4. 4.7.4 编辑与段落
      5. 4.7.5 编辑与列表
      6. 4.7.6 编辑与表格
    8. 4.8 嵌入内容
      1. 4.8.1 picture 元素
      2. 4.8.2 source 元素
      3. 4.8.3 img 元素
      4. 4.8.4 图像
        1. 4.8.4.1 介绍
          1. 4.8.4.1.1 自适应图像
        2. 4.8.4.2 sourceimglink 元素的共同属性
          1. 4.8.4.2.1 Srcset 属性
          2. 4.8.4.2.2 Sizes 属性
        3. 4.8.4.3 处理模型
          1. 4.8.4.3.1 何时获取图像
          2. 4.8.4.3.2 对 DOM 变更的响应
          3. 4.8.4.3.3 可用图像列表
          4. 4.8.4.3.4 解码图像
          5. 4.8.4.3.5 更新图像数据
          6. 4.8.4.3.6 为展示准备图像
          7. 4.8.4.3.7 选择图像源
          8. 4.8.4.3.8 从属性创建source set
          9. 4.8.4.3.9 更新source set
          10. 4.8.4.3.10 解析 srcset 属性
          11. 4.8.4.3.11 解析 sizes 属性
          12. 4.8.4.3.12 规范化源密度
          13. 4.8.4.3.13 应对环境变化
        4. 4.8.4.4 提供文本作为图像的替代要求
          1. 4.8.4.4.1 一般准则
          2. 4.8.4.4.2 只包含图像的链接或按钮
          3. 4.8.4.4.3 带有替代图形表示的短语或段落:图表、图解、图形、地图、插图
          4. 4.8.4.4.4 带有替代图形表示的短语或标签:图标、标志
          5. 4.8.4.4.5 图形化呈现的文本
          6. 4.8.4.4.6 周围文本的图形表示
          7. 4.8.4.4.7 辅助图像
          8. 4.8.4.4.8 纯装饰性图像,不添加任何信息
          9. 4.8.4.4.9 一组没有链接的图像组成一幅更大的图片
          10. 4.8.4.4.10 一组形成单个大图的图片,带有链接
          11. 4.8.4.4.11 内容的关键部分
          12. 4.8.4.4.12 不打算给用户显示的图像
          13. 4.8.4.4.13 在电子邮件或私人文档中,打算给一个已知能查看图像的特定人
          14. 4.8.4.4.14 标记生成器的指导
          15. 4.8.4.4.15 合规检查器的指导
      5. 4.8.5 iframe 元素
      6. 4.8.6 embed 元素
      7. 4.8.7 object 元素
      8. 4.8.8 video 元素
      9. 4.8.9 audio 元素
      10. 4.8.10 track 元素
      11. 4.8.11 媒体元素
        1. 4.8.11.1 错误代码
        2. 4.8.11.2 媒体资源的位置
        3. 4.8.11.3 MIME 类型
        4. 4.8.11.4 网络状态
        5. 4.8.11.5 加载媒体资源
        6. 4.8.11.6 媒体资源的偏移量
        7. 4.8.11.7 就绪状态
        8. 4.8.11.8 播放媒体资源
        9. 4.8.11.9 寻找
        10. 4.8.11.10 具有多个媒体轨道的媒体资源
          1. 4.8.11.10.1 AudioTrackListVideoTrackList 对象
          2. 4.8.11.10.2 以声明方式选择特定的音频和视频轨道
        11. 4.8.11.11 定时文本轨迹
          1. 4.8.11.11.1 文本轨道模型
          2. 4.8.11.11.2 嵌入式文本轨迹的来源
          3. 4.8.11.11.3 外部文本轨迹的来源
          4. 4.8.11.11.4 在各种格式中暴露提示的指南
          5. 4.8.11.11.5 文本轨道 API
          6. 4.8.11.11.6 文本轨道API对象的事件处理程序
          7. 4.8.11.11.7 元数据文本轨道的最佳实践
        12. 4.8.11.12 通过 URL 识别轨道类型
        13. 4.8.11.13 用户界面
        14. 4.8.11.14 时间范围
        15. 4.8.11.15 TrackEvent 接口
        16. 4.8.11.16 事件摘要
        17. 4.8.11.17 安全和隐私考量
        18. 4.8.11.18 使用媒体元素的作者的最佳实践
        19. 4.8.11.19 实现媒体元素的最佳实践
      12. 4.8.12 map 元素
      13. 4.8.13 area 元素
      14. 4.8.14 图像映射
        1. 4.8.14.1 编写
        2. 4.8.14.2 处理模型
      15. 4.8.15 MathML
      16. 4.8.16 SVG
      17. 4.8.17 尺寸属性
    9. 4.9 表格数据
      1. 4.9.1 table 元素
        1. 4.9.1.1 描述表格的技巧
        2. 4.9.1.2 表格设计技巧
      2. 4.9.2 caption 元素
      3. 4.9.3 colgroup 元素
      4. 4.9.4 col 元素
      5. 4.9.5 tbody 元素
      6. 4.9.6 thead 元素
      7. 4.9.7 tfoot 元素
      8. 4.9.8 tr 元素
      9. 4.9.9 td 元素
      10. 4.9.10 th 元素
      11. 4.9.11 tdth 元素的共有属性
      12. 4.9.12 处理模型
        1. 4.9.12.1 表格的形成
        2. 4.9.12.2 在数据单元格和标题单元格之间形成关系
      13. 4.9.13 示例
    10. 4.10 表单
      1. 4.10.1 介绍
        1. 4.10.1.1 编写表单的用户界面
        2. 4.10.1.2 实现表单的服务器端处理
        3. 4.10.1.3 配置表单与服务器通信
        4. 4.10.1.4 客户端表单验证
        5. 4.10.1.5 启用客户端自动填充表单控件
        6. 4.10.1.6 改善移动设备上的用户体验
        7. 4.10.1.7 字段类型、自动填充字段名称和输入方式之间的区别
        8. 4.10.1.8 日期、 时间和数字格式
      2. 4.10.2 类别
      3. 4.10.3 form 元素
      4. 4.10.4 label 元素
      5. 4.10.5 input 元素
        1. 4.10.5.1 type 属性的状态
          1. 4.10.5.1.1 隐藏状态 (type=hidden)
          2. 4.10.5.1.2 文本 (type=text) 状态和搜索状态 (type=search)
          3. 4.10.5.1.3 电话状态 (type=tel)
          4. 4.10.5.1.4 URL 状态 (type=url)
          5. 4.10.5.1.5 电子邮件状态 (type=email)
          6. 4.10.5.1.6 密码状态 (type=password)
          7. 4.10.5.1.7 日期状态 (type=date)
          8. 4.10.5.1.8 月份状态 (type=month)
          9. 4.10.5.1.9 周状态 (type=week)
          10. 4.10.5.1.10 时间状态 (type=time)
          11. 4.10.5.1.11 本地日期和时间状态 (type=datetime-local)
          12. 4.10.5.1.12 数字状态 (type=number)
          13. 4.10.5.1.13 范围状态 (type=range)
          14. 4.10.5.1.14 颜色状态 (type=color)
          15. 4.10.5.1.15 复选框状态 (type=checkbox)
          16. 4.10.5.1.16 单选按钮状态 (type=radio)
          17. 4.10.5.1.17 文件上传状态 (type=file)
          18. 4.10.5.1.18 提交按钮状态 (type=submit)
          19. 4.10.5.1.19 图像按钮状态 (type=image)
          20. 4.10.5.1.20 重置按钮状态 (type=reset)
          21. 4.10.5.1.21 按钮状态 (type=button)
        2. 4.10.5.2 关于表单控件本地化的实现说明
        3. 4.10.5.3 常见的 input 元素属性
          1. 4.10.5.3.1 maxlengthminlength 属性
          2. 4.10.5.3.2 size 属性
          3. 4.10.5.3.3 readonly 属性
          4. 4.10.5.3.4 required 属性
          5. 4.10.5.3.5 multiple 属性
          6. 4.10.5.3.6 pattern 属性
          7. 4.10.5.3.7 minmax 属性
          8. 4.10.5.3.8 step 属性
          9. 4.10.5.3.9 list 属性
          10. 4.10.5.3.10 placeholder 属性
        4. 4.10.5.4 通用 input 元素 API
        5. 4.10.5.5 常见事件行为
      6. 4.10.6 button 元素
      7. 4.10.7 select 元素
      8. 4.10.8 datalist 元素
      9. 4.10.9 optgroup 元素
      10. 4.10.10 option 元素
      11. 4.10.11 textarea 元素
      12. 4.10.12 output 元素
      13. 4.10.13 progress 元素
      14. 4.10.14 meter 元素
      15. 4.10.15 fieldset 元素
      16. 4.10.16 legend 元素
      17. 4.10.17 表单控件基础设施
        1. 4.10.17.1 表单控件的值
        2. 4.10.17.2 可变性
        3. 4.10.17.3 控件与表单的关联
      18. 4.10.18 表单控件通用属性
        1. 4.10.18.1 表单控件命名:name 属性
        2. 4.10.18.2 提交元素方向性:dirname 属性
        3. 4.10.18.3 限制用户输入长度:maxlength 属性
        4. 4.10.18.4 设置最小输入长度要求:minlength 属性
        5. 4.10.18.5 启用和禁用表单控件:disabled 属性
        6. 4.10.18.6 表单提交属性
        7. 4.10.18.7 自动填充
          1. 4.10.18.7.1 自动填充表单控件:autocomplete 属性
          2. 4.10.18.7.2 处理模型
      19. 4.10.19 文本控件选择的 API
      20. 4.10.20 约束
        1. 4.10.20.1 定义
        2. 4.10.20.2 约束验证
        3. 4.10.20.3 约束验证 API
        4. 4.10.20.4 安全性
      21. 4.10.21 表单提交
        1. 4.10.21.1 介绍
        2. 4.10.21.2 隐式提交
        3. 4.10.21.3 表单提交算法
        4. 4.10.21.4 构建条目列表
        5. 4.10.21.5 选择表单提交编码
        6. 4.10.21.6 将条目列表转换为名称-值对列表
        7. 4.10.21.7 URL 编码的表单数据
        8. 4.10.21.8 多部分表单数据
        9. 4.10.21.9 纯文本表单数据
        10. 4.10.21.10 SubmitEvent 接口
        11. 4.10.21.11 FormDataEvent 接口
      22. 4.10.22 重置表单
    11. 4.11 交互式元素
      1. 4.11.1 details 元素
      2. 4.11.2 summary 元素
      3. 4.11.3 命令
        1. 4.11.3.1 方面
        2. 4.11.3.2 使用 a 元素定义命令
        3. 4.11.3.3 使用 button 元素定义命令
        4. 4.11.3.4 使用 input 元素定义命令
        5. 4.11.3.5 使用 option 元素定义命令
        6. 4.11.3.6 使用 accesskey 属性在 legend 元素上定义命令
        7. 4.11.3.7 使用 accesskey 属性在其他元素上定义命令
      4. 4.11.4 dialog 元素
    12. 4.12 脚本
      1. 4.12.1 script 元素
        1. 4.12.1.1 处理模型
        2. 4.12.1.2 脚本语言
        3. 4.12.1.3 script 元素内容的限制
        4. 4.12.1.4 外部脚本的内联文档
        5. 4.12.1.5 script 元素和XSLT的交互
      2. 4.12.2 noscript 元素
      3. 4.12.3 template 元素
        1. 4.12.3.1 template 元素与 XSLT 和 XPath 的交互
      4. 4.12.4 slot 元素
      5. 4.12.5 canvas 元素
        1. 4.12.5.1 2D 渲染上下文
          1. 4.12.5.1.1 实现说明
          2. 4.12.5.1.2 画布状态
          3. 4.12.5.1.3 线条样式
          4. 4.12.5.1.4 文本样式
          5. 4.12.5.1.5 创建路径
          6. 4.12.5.1.6 Path2D 对象
          7. 4.12.5.1.7 转换
          8. 4.12.5.1.8 2D 渲染上下文的图像源
          9. 4.12.5.1.9 填充和描边样式
          10. 4.12.5.1.10 绘制矩形到位图
          11. 4.12.5.1.11 绘制文本到位图
          12. 4.12.5.1.12 绘制路径到画布
          13. 4.12.5.1.13 绘制焦点环
          14. 4.12.5.1.14 绘制图像
          15. 4.12.5.1.15 像素操作
          16. 4.12.5.1.16 合成
          17. 4.12.5.1.17 图像平滑
          18. 4.12.5.1.18 阴影
          19. 4.12.5.1.19 滤镜
          20. 4.12.5.1.20 使用外部定义的 SVG 滤镜
          21. 4.12.5.1.21 绘图模型
          22. 4.12.5.1.22 最佳实践
          23. 4.12.5.1.23 示例
        2. 4.12.5.2 ImageBitmap 渲染上下文
          1. 4.12.5.2.1 介绍
          2. 4.12.5.2.2 ImageBitmapRenderingContext 接口
        3. 4.12.5.3 OffscreenCanvas 接口
          1. 4.12.5.3.1 离屏 2D 渲染上下文
        4. 4.12.5.4 颜色空间和颜色空间转换
        5. 4.12.5.5 将位图序列化到文件
        6. 4.12.5.6 使用 canvas 元素的安全性
        7. 4.12.5.7 预乘 alpha 和 2D 渲染上下文
    13. 4.13 自定义元素
      1. 4.13.1 简介
        1. 4.13.1.1 创建一个自主自定义元素
        2. 4.13.1.2 创建一个与表单关联的自定义元素
        3. 4.13.1.3 创建一个具有默认可访问角色、状态和属性的自定义元素
        4. 4.13.1.4 创建一个定制的内置元素
        5. 4.13.1.5 自主自定义元素的缺点
        6. 4.13.1.6 在创建之后升级元素
        7. 4.13.1.7 暴露自定义元素状态
      2. 4.13.2 自定义元素构造函数和反应的要求
      3. 4.13.3 核心概念
      4. 4.13.4 CustomElementRegistry 接口
      5. 4.13.5 升级
      6. 4.13.6 自定义元素反应
      7. 4.13.7 元素内部
        1. 4.13.7.1 ElementInternals 接口
        2. 4.13.7.2 Shadow 根访问
        3. 4.13.7.3 表单关联的自定义元素
        4. 4.13.7.4 可访问性语义
        5. 4.13.7.5 自定义状态伪类
    14. 4.14 常见惯用法,无专用元素
      1. 4.14.1 面包屑导航
      2. 4.14.2 标签云
      3. 4.14.3 对话
      4. 4.14.4 脚注
    15. 4.15 禁用元素
    16. 4.16 使用选择器和 CSS 匹配 HTML 元素
      1. 4.16.1 CSS 'attr()' 函数的大小写敏感性
      2. 4.16.2 选择器的大小写敏感性
      3. 4.16.3 伪类
  5. 5 微数据
    1. 5.1 介绍
      1. 5.1.1 概述
      2. 5.1.2 基本语法
      3. 5.1.3 类型化项目
      4. 5.1.4 项目的全局标识符
      5. 5.1.5 定义词汇表时选择名称
    2. 5.2 编码微数据
      1. 5.2.1 微数据模型
      2. 5.2.2 项目
      3. 5.2.3 名称:itemprop 属性
      4. 5.2.4
      5. 5.2.5 将名称与项目关联
      6. 5.2.6 微数据和其他命名空间
    3. 5.3 示例微数据词汇表
      1. 5.3.1 vCard
        1. 5.3.1.1 转换为 vCard
        2. 5.3.1.2 示例
      2. 5.3.2 vEvent
        1. 5.3.2.1 转换为 iCalendar
        2. 5.3.2.2 示例
      3. 5.3.3 许可作品
        1. 5.3.3.1 示例
    4. 5.4 将 HTML 转换为其他格式
      1. 5.4.1 JSON
  6. 6 用户交互
    1. 6.1 hidden 属性
    2. 6.2 页面可见性
      1. 6.2.1 VisibilityStateEntry 接口
    3. 6.3 惰性子树
      1. 6.3.1 模态对话框和惰性子树
      2. 6.3.2 inert 属性
    4. 6.4 跟踪用户激活
      1. 6.4.1 数据模型
      2. 6.4.2 处理模型
      3. 6.4.3 受用户激活限制的API
      4. 6.4.4 UserActivation 接口
      5. 6.4.5 用户代理自动化
    5. 6.5 元素的激活行为
      1. 6.5.1 ToggleEvent 接口
    6. 6.6 焦点
      1. 6.6.1 介绍
      2. 6.6.2 数据模型
      3. 6.6.3 tabindex 属性
      4. 6.6.4 处理模型
      5. 6.6.5 顺序焦点导航
      6. 6.6.6 焦点管理 API
      7. 6.6.7 autofocus 属性
    7. 6.7 分配键盘快捷键
      1. 6.7.1 介绍
      2. 6.7.2 accesskey 属性
      3. 6.7.3 处理模型
    8. 6.8 编辑
      1. 6.8.1 使文档区域可编辑:contenteditable 内容属性
      2. 6.8.2 使整个文档可编辑:designMode getter 和 setter
      3. 6.8.3 页面编辑器的最佳实践
      4. 6.8.4 编辑API
      5. 6.8.5 拼写和语法检查
      6. 6.8.6 写作建议
      7. 6.8.7 自动大写
      8. 6.8.8 自动更正
      9. 6.8.9 输入方式:inputmode 属性
      10. 6.8.10 输入方式:enterkeyhint 属性
    9. 6.9 页面内查找
      1. 6.9.1 介绍
      2. 6.9.2detailshidden=until-found 的交互
      3. 6.9.3 与选择的交互
    10. 6.10 关闭请求和关闭监视器
      1. 6.10.1 关闭请求
      2. 6.10.2 关闭监视器基础设施
      3. 6.10.3 CloseWatcher 接口
    11. 6.11 拖放
      1. 6.11.1 介绍
      2. 6.11.2 拖放数据存储
      3. 6.11.3 DataTransfer 接口
        1. 6.11.3.1 DataTransferItemList 接口
        2. 6.11.3.2 DataTransferItem 接口
      4. 6.11.4 DragEvent 接口
      5. 6.11.5 处理模型
      6. 6.11.6 事件总结
      7. 6.11.7 draggable 属性
      8. 6.11.8 拖放模型中的安全风险
    12. 6.12 popover 属性
      1. 6.12.1 Popover 目标属性
      2. 6.12.2 Popover 轻量关闭
  7. 7 加载网页
    1. 7.1 支持的概念
      1. 7.1.1 来源
        1. 7.1.1.1 站点
        2. 7.1.1.2 放宽同源限制
      2. 7.1.2 基于源的代理集群
      3. 7.1.3 跨源打开者策略
        1. 7.1.3.1 头部信息
        2. 7.1.3.2 由于跨源打开者策略导致的浏览上下文组切换
        3. 7.1.3.3 报告
      4. 7.1.4 跨域嵌入策略
        1. 7.1.4.1 标头
        2. 7.1.4.2 嵌入策略检查
      5. 7.1.5 沙盒
      6. 7.1.6 策略容器
    2. 7.2 与导航和会话历史相关的 APIs
      1. 7.2.1 WindowWindowProxyLocation 对象的安全基础设施
        1. 7.2.1.1 与 IDL 的集成
        2. 7.2.1.2 共享内部槽:[[CrossOriginPropertyDescriptorMap]]
        3. 7.2.1.3 共享抽象操作
          1. 7.2.1.3.1 CrossOriginProperties ( O )
          2. 7.2.1.3.2 CrossOriginPropertyFallback ( P )
          3. 7.2.1.3.3 IsPlatformObjectSameOrigin ( O )
          4. 7.2.1.3.4 CrossOriginGetOwnPropertyHelper ( O, P )
          5. 7.2.1.3.5 CrossOriginGet ( O, P, Receiver )
          6. 7.2.1.3.6 CrossOriginSet ( O, P, V, Receiver )
          7. 7.2.1.3.7 CrossOriginOwnPropertyKeys ( O )
      2. 7.2.2 Window 对象
        1. 7.2.2.1 打开和关闭窗口
        2. 7.2.2.2Window 对象上的索引访问
        3. 7.2.2.3Window 对象上的命名访问
        4. 7.2.2.4 访问相关窗口
        5. 7.2.2.5 历史浏览器界面元素 API
        6. 7.2.2.6 Window 对象的脚本设置
      3. 7.2.3 WindowProxy 特殊对象
        1. 7.2.3.1 [[GetPrototypeOf]] ( )
        2. 7.2.3.2 [[SetPrototypeOf]] ( V )
        3. 7.2.3.3 [[IsExtensible]] ( )
        4. 7.2.3.4 [[PreventExtensions]] ( )
        5. 7.2.3.5 [[GetOwnProperty]] ( P )
        6. 7.2.3.6 [[DefineOwnProperty]] ( P, Desc )
        7. 7.2.3.7 [[Get]] ( P, Receiver )
        8. 7.2.3.8 [[Set]] ( P, V, Receiver )
        9. 7.2.3.9 [[Delete]] ( P )
        10. 7.2.3.10 [[OwnPropertyKeys]] ( )
      4. 7.2.4 Location 接口
        1. 7.2.4.1 [[GetPrototypeOf]] ( )
        2. 7.2.4.2 [[SetPrototypeOf]] ( V )
        3. 7.2.4.3 [[IsExtensible]] ( )
        4. 7.2.4.4 [[PreventExtensions]] ( )
        5. 7.2.4.5 [[GetOwnProperty]] ( P )
        6. 7.2.4.6 [[DefineOwnProperty]] ( P, Desc )
        7. 7.2.4.7 [[Get]] ( P, Receiver )
        8. 7.2.4.8 [[Set]] ( P, V, Receiver )
        9. 7.2.4.9 [[Delete]] ( P )
        10. 7.2.4.10 [[OwnPropertyKeys]] ( )
      5. 7.2.5 History 接口
      6. 7.2.6 导航 API
        1. 7.2.6.1 介绍
        2. 7.2.6.2 Navigation 接口
        3. 7.2.6.3 核心基础设施
        4. 7.2.6.4 初始化和更新条目列表
        5. 7.2.6.5 NavigationHistoryEntry 接口
        6. 7.2.6.6 历史条目列表
        7. 7.2.6.7 发起导航
        8. 7.2.6.8 正在进行的导航跟踪
        9. 7.2.6.9 NavigationActivation 接口
        10. 7.2.6.10 navigate 事件
          1. 7.2.6.10.1 NavigateEvent 接口
          2. 7.2.6.10.2 NavigationDestination 接口
          3. 7.2.6.10.3 触发事件
          4. 7.2.6.10.4 滚动和焦点行为
      7. 7.2.7 事件接口
        1. 7.2.7.1 NavigationCurrentEntryChangeEvent 接口
        2. 7.2.7.2 PopStateEvent 接口
        3. 7.2.7.3 HashChangeEvent 接口
        4. 7.2.7.4 PageSwapEvent 接口
        5. 7.2.7.5 PageRevealEvent 接口
        6. 7.2.7.6 PageTransitionEvent 接口
        7. 7.2.7.7 BeforeUnloadEvent 接口
      8. 7.2.8 NotRestoredReasons 接口
    3. 7.3 文档序列的基础设施
      1. 7.3.1 可导航对象
        1. 7.3.1.1 可遍历的可导航对象
        2. 7.3.1.2 顶级可遍历对象
        3. 7.3.1.3 子导航元素
        4. 7.3.1.4 Jake 图表
        5. 7.3.1.5 相关的 navigable 集合
        6. 7.3.1.6 Navigable 销毁
        7. 7.3.1.7 导航目标名称
      2. 7.3.2 浏览上下文
        1. 7.3.2.1 创建浏览上下文
        2. 7.3.2.2 相关浏览上下文
        3. 7.3.2.3 浏览上下文的分组
      3. 7.3.3 完全活动文档
    4. 7.4 导航和会话历史
      1. 7.4.1 会话历史
        1. 7.4.1.1 会话历史条目
        2. 7.4.1.2 文档状态
        3. 7.4.1.3 会话历史的集中修改
        4. 7.4.1.4 低级别操作会话历史
      2. 7.4.2 导航
        1. 7.4.2.1 支持概念
        2. 7.4.2.2 开始导航
        3. 7.4.2.3 结束导航
          1. 7.4.2.3.1 通常的跨文档导航情况
          2. 7.4.2.3.2 javascript: URL 的特殊情况
          3. 7.4.2.3.3 片段导航
          4. 7.4.2.3.4 非 fetch 方案和外部软件
        4. 7.4.2.4 防止导航
        5. 7.4.2.5 中止导航
      3. 7.4.3 重新加载和遍历
      4. 7.4.4 非片段同步“导航”
      5. 7.4.5 填充会话历史条目
      6. 7.4.6 应用历史步骤
        1. 7.4.6.1 更新可遍历
        2. 7.4.6.2 更新文档
        3. 7.4.6.3 显示文档
        4. 7.4.6.4 滚动到片段
        5. 7.4.6.5 持久化历史条目状态
    5. 7.5 文档生命周期
      1. 7.5.1 共享文档创建基础设施
      2. 7.5.2 加载 HTML 文档
      3. 7.5.3 加载 XML 文档
      4. 7.5.4 加载文本文档
      5. 7.5.5 加载 multipart/x-mixed-replace 文档
      6. 7.5.6 加载媒体文档
      7. 7.5.7 加载没有 DOM 的内联内容文档
      8. 7.5.8 完成加载过程
      9. 7.5.9 卸载文档
      10. 7.5.10 销毁文档
      11. 7.5.11 中止文档加载
    6. 7.6 `X-Frame-Options` 头部
    7. 7.7 `Refresh` 头部
    8. 7.8 浏览器用户界面考虑
  8. 8 Web 应用程序 API
    1. 8.1 脚本
      1. 8.1.1 简介
      2. 8.1.2 代理和代理集群
        1. 8.1.2.1 与 JavaScript 代理形式的集成
        2. 8.1.2.2 与 JavaScript 代理集群形式的集成
      3. 8.1.3 域及其对应物
        1. 8.1.3.1 环境
        2. 8.1.3.2 环境设置对象
        3. 8.1.3.3 域、设置对象和全局对象
          1. 8.1.3.3.1 入口
          2. 8.1.3.3.2 在任
          3. 8.1.3.3.3 当前
          4. 8.1.3.3.4 相关
        4. 8.1.3.4 启用和禁用脚本
        5. 8.1.3.5 安全 上下文
      4. 8.1.4 脚本处理模型
        1. 8.1.4.1 脚本
        2. 8.1.4.2 获取脚本
        3. 8.1.4.3 创建脚本
        4. 8.1.4.4 调用脚本
        5. 8.1.4.5 终止脚本
        6. 8.1.4.6 运行时脚本错误
        7. 8.1.4.7 未处理的 Promise 拒绝
        8. 8.1.4.8 Import map 解析结果
      5. 8.1.5 模块说明符解析
        1. 8.1.5.1 解析算法
        2. 8.1.5.2 Import maps
        3. 8.1.5.3 导入映射处理模型
      6. 8.1.6 JavaScript 规范宿主钩子
        1. 8.1.6.1 HostEnsureCanAddPrivateElement(O)
        2. 8.1.6.2 HostEnsureCanCompileStrings(realm, parameterStrings, bodyString, codeString, compilationType, parameterArgs, bodyArg)
        3. 8.1.6.3 HostGetCodeForEval(argument)
        4. 8.1.6.4 HostPromiseRejectionTracker(promise, operation)
        5. 8.1.6.5 HostSystemUTCEpochNanoseconds(global)
        6. 8.1.6.6 与 JavaScript 任务相关的宿主钩子
          1. 8.1.6.6.1 HostCallJobCallback(callback, V, argumentsList)
          2. 8.1.6.6.2 HostEnqueueFinalizationRegistryCleanupJob(finalizationRegistry)
          3. 8.1.6.6.3 HostEnqueueGenericJob(job, realm)
          4. 8.1.6.6.4 HostEnqueuePromiseJob(job, realm)
          5. 8.1.6.6.5 HostEnqueueTimeoutJob(job, realm, milliseconds)
          6. 8.1.6.6.6 HostMakeJobCallback(callable)
        7. 8.1.6.7 与 JavaScript 模块系统相关的宿主钩子
          1. 8.1.6.7.1 HostGetImportMetaProperties(moduleRecord)
          2. 8.1.6.7.2 HostGetSupportedImportAttributes()
          3. 8.1.6.7.3 HostLoadImportedModule(referrer, moduleRequest, loadState, payload)
      7. 8.1.7 事件循环
        1. 8.1.7.1 定义
        2. 8.1.7.2 任务排队
        3. 8.1.7.3 处理模型
        4. 8.1.7.4 通用任务源
        5. 8.1.7.5 处理其他规范中的事件循环
      8. 8.1.8 事件
        1. 8.1.8.1 事件处理程序
        2. 8.1.8.2 元素、Document 对象和 Window 对象上的事件处理程序
          1. 8.1.8.2.1 IDL 定义
        3. 8.1.8.3 事件触发
    2. 8.2 WindowOrWorkerGlobalScope 混入
    3. 8.3 Base64 实用方法
    4. 8.4 动态标记插入
      1. 8.4.1 打开输入流
      2. 8.4.2 关闭输入流
      3. 8.4.3 document.write()
      4. 8.4.4 document.writeln()
    5. 8.5 DOM 解析与序列化 API
      1. 8.5.1 DOMParser 接口
      2. 8.5.2 不安全的 HTML 解析方法
      3. 8.5.3 HTML 序列化方法
      4. 8.5.4 innerHTML 属性
      5. 8.5.5 outerHTML 属性
      6. 8.5.6 insertAdjacentHTML() 方法
      7. 8.5.7 createContextualFragment() 方法
    6. 8.6 定时器
    7. 8.7 微任务队列
    8. 8.8 用户提示
      1. 8.8.1 简单对话框
      2. 8.8.2 打印
    9. 8.9 系统状态和能力
      1. 8.9.1 Navigator 对象
        1. 8.9.1.1 客户端识别
        2. 8.9.1.2 语言偏好
        3. 8.9.1.3 浏览器状态
        4. 8.9.1.4 自定义方案处理程序:registerProtocolHandler() 方法
          1. 8.9.1.4.1 安全性和隐私性
          2. 8.9.1.4.2 用户代理自动化
        5. 8.9.1.5 Cookies
        6. 8.9.1.6 PDF 查看支持
    10. 8.10 图片
    11. 8.11 动画帧
  9. 9 通信
    1. 9.1 MessageEvent 接口
    2. 9.2 服务器发送事件
      1. 9.2.1 简介
      2. 9.2.2 EventSource 接口
      3. 9.2.3 处理模型
      4. 9.2.4 `Last-Event-ID` 请求头
      5. 9.2.5 解析事件流
      6. 9.2.6 解释事件流
      7. 9.2.7 编写说明
      8. 9.2.8 无连接推送及其他功能
      9. 9.2.9 垃圾回收
      10. 9.2.10 实现建议
    3. 9.3 跨文档消息传递
      1. 9.3.1 介绍
      2. 9.3.2 安全性
        1. 9.3.2.1 作者注意事项
        2. 9.3.2.2 用户代理
      3. 9.3.3 发送消息
    4. 9.4 通道消息传递
      1. 9.4.1 介绍
        1. 9.4.1.1 示例
        2. 9.4.1.2 端口作为 Web 上的对象能力模型基础
        3. 9.4.1.3 端口作为服务实现抽象的基础
      2. 9.4.2 消息通道
      3. 9.4.3 消息端口
      4. 9.4.4 端口与垃圾回收
    5. 9.5 广播到其他浏览上下文
  10. 10 Web workers
    1. 10.1 介绍
      1. 10.1.1 范围
      2. 10.1.2 示例
        1. 10.1.2.1 一个后台数字处理Worker
        2. 10.1.2.2 使用 JavaScript 模块作为 worker
        3. 10.1.2.3 Shared workers 介绍
        4. 10.1.2.4 使用 shared worker 实现共享状态
        5. 10.1.2.5 委托
        6. 10.1.2.6 提供库
      3. 10.1.3 教程
        1. 10.1.3.1 创建一个专用 worker
        2. 10.1.3.2 与专用 worker 通信
        3. 10.1.3.3 共享工作线程
    2. 10.2 基础设施
      1. 10.2.1 全局作用域
        1. 10.2.1.1 WorkerGlobalScope 公共接口
        2. 10.2.1.2 专用 worker 和 DedicatedWorkerGlobalScope 接口
        3. 10.2.1.3 Shared workers 和 SharedWorkerGlobalScope 接口
      2. 10.2.2 事件循环
      3. 10.2.3 Worker的生命周期
      4. 10.2.4 处理模型
      5. 10.2.5 运行时脚本错误
      6. 10.2.6 创建 workers
        1. 10.2.6.1 AbstractWorker 混合
        2. 10.2.6.2 Workers 的脚本设置
        3. 10.2.6.3 专用 Worker 与 Worker 接口
        4. 10.2.6.4 共享 worker 和 SharedWorker 接口
      7. 10.2.7 并发硬件能力
    3. 10.3 工作线程可用的 API
      1. 10.3.1 导入脚本和库
      2. 10.3.2 WorkerNavigator 接口
      3. 10.3.3 WorkerLocation 接口
  11. 11 Worklets
    1. 11.1 介绍
      1. 11.1.1 动机
      2. 11.1.2 代码的幂等性
      3. 11.1.3 推测性评估
    2. 11.2 示例
      1. 11.2.1 加载脚本
      2. 11.2.2 注册类并调用其方法
    3. 11.3 基础设施
      1. 11.3.1 全局范围
        1. 11.3.1.1 代理和事件循环
        2. 11.3.1.2 创建和终止
        3. 11.3.1.3 Worklets 的脚本设置
      2. 11.3.2 Worklet
      3. 11.3.3 Worklet 的生命周期
  12. 12 Web 存储
    1. 12.1 简介
    2. 12.2 API
      1. 12.2.1 Storage 接口
      2. 12.2.2 sessionStorage 获取器
      3. 12.2.3 localStorage 获取器
      4. 12.2.4 StorageEvent 接口
    3. 12.3 隐私
      1. 12.3.1 用户跟踪
      2. 12.3.2 数据的敏感性
    4. 12.4 安全性
      1. 12.4.1 DNS 欺骗攻击
      2. 12.4.2 跨目录攻击
      3. 12.4.3 实现风险
  13. 13 HTML 语法
    1. 13.1 编写 HTML 文档
      1. 13.1.1 DOCTYPE
      2. 13.1.2 元素
        1. 13.1.2.1 起始标签
        2. 13.1.2.2 结束标签
        3. 13.1.2.3 属性
        4. 13.1.2.4 可选标签
        5. 13.1.2.5 内容模型的限制
        6. 13.1.2.6 原始文本和可转义原始文本元素的内容限制
      3. 13.1.3 文本
        1. 13.1.3.1 换行符
      4. 13.1.4 字符引用
      5. 13.1.5 CDATA 部分
      6. 13.1.6 注释
    2. 13.2 解析 HTML 文档
      1. 13.2.1 解析模型概述
      2. 13.2.2 解析错误
      3. 13.2.3 输入字节流
        1. 13.2.3.1 具有已知字符编码的解析
        2. 13.2.3.2 确定字符编码
        3. 13.2.3.3 字符编码
        4. 13.2.3.4 在解析过程中更改编码
        5. 13.2.3.5 预处理输入流
      4. 13.2.4 解析状态
        1. 13.2.4.1 插入模式
        2. 13.2.4.2 打开的元素栈
        3. 13.2.4.3 活动格式化元素列表
        4. 13.2.4.4 元素指针
        5. 13.2.4.5 其他解析状态标志
      5. 13.2.5 标记化
        1. 13.2.5.1 数据状态
        2. 13.2.5.2 RCDATA 状态
        3. 13.2.5.3 RAWTEXT 状态
        4. 13.2.5.4 脚本数据状态
        5. 13.2.5.5 纯文本状态
        6. 13.2.5.6 标签打开状态
        7. 13.2.5.7 结束标签打开状态
        8. 13.2.5.8 标签名称状态
        9. 13.2.5.9 RCDATA 小于号状态
        10. 13.2.5.10 RCDATA 结束标签打开状态
        11. 13.2.5.11 RCDATA 结束标签名称状态
        12. 13.2.5.12 RAWTEXT 小于号状态
        13. 13.2.5.13 RAWTEXT 结束标签打开状态
        14. 13.2.5.14 RAWTEXT 结束标签名称状态
        15. 13.2.5.15 脚本数据小于号状态
        16. 13.2.5.16 脚本数据结束标签打开状态
        17. 13.2.5.17 脚本数据结束标签名称状态
        18. 13.2.5.18 脚本数据转义起始状态
        19. 13.2.5.19 脚本数据转义起始连字符状态
        20. 13.2.5.20 脚本数据转义状态
        21. 13.2.5.21 脚本数据转义连字符状态
        22. 13.2.5.22 脚本数据转义连字符连字符状态
        23. 13.2.5.23 脚本数据转义小于号状态
        24. 13.2.5.24 脚本数据转义结束标签打开状态
        25. 13.2.5.25 脚本数据转义结束标签名称状态
        26. 13.2.5.26 脚本数据双重转义起始状态
        27. 13.2.5.27 脚本数据双重转义状态
        28. 13.2.5.28 脚本数据双重转义连字符状态
        29. 13.2.5.29 脚本数据双重转义连字符连字符状态
        30. 13.2.5.30 脚本数据双重转义小于号状态
        31. 13.2.5.31 脚本数据双重转义结束状态
        32. 13.2.5.32 属性名称之前状态
        33. 13.2.5.33 属性名称状态
        34. 13.2.5.34 属性名称之后状态
        35. 13.2.5.35 属性值之前状态
        36. 13.2.5.36 属性值(双引号)状态
        37. 13.2.5.37 属性值(单引号)状态
        38. 13.2.5.38 属性值(无引号)状态
        39. 13.2.5.39 属性值(引号)之后状态
        40. 13.2.5.40 自闭合起始标签状态
        41. 13.2.5.41 伪注释状态
        42. 13.2.5.42 标记声明打开状态
        43. 13.2.5.43 注释开始状态
        44. 13.2.5.44 评论开始连字符状态
        45. 13.2.5.45 注释状态
        46. 13.2.5.46 注释小于号状态
        47. 13.2.5.47 注释小于号感叹号状态
        48. 13.2.5.48 注释小于号感叹号连字符状态
        49. 13.2.5.49 注释小于号感叹号连字符双连字符状态
        50. 13.2.5.50 注释结束连字符状态
        51. 13.2.5.51 注释结束状态
        52. 13.2.5.52 注释结束感叹号状态
        53. 13.2.5.53 DOCTYPE 状态
        54. 13.2.5.54 DOCTYPE 名称之前状态
        55. 13.2.5.55 DOCTYPE 名称状态
        56. 13.2.5.56 DOCTYPE 名称之后状态
        57. 13.2.5.57 DOCTYPE public 关键字之后状态
        58. 13.2.5.58 DOCTYPE public 标识符之前状态
        59. 13.2.5.59 DOCTYPE public 标识符(双引号)状态
        60. 13.2.5.60 DOCTYPE public 标识符(单引号)状态
        61. 13.2.5.61 DOCTYPE public 标识符之后状态
        62. 13.2.5.62 DOCTYPE public 和系统标识符之间状态
        63. 13.2.5.63 DOCTYPE system 关键字之后状态
        64. 13.2.5.64 DOCTYPE system 标识符之前状态
        65. 13.2.5.65 DOCTYPE system 标识符(双引号)状态
        66. 13.2.5.66 DOCTYPE system 标识符(单引号)状态
        67. 13.2.5.67 DOCTYPE system 标识符之后状态
        68. 13.2.5.68 伪 DOCTYPE 状态
        69. 13.2.5.69 CDATA 段状态
        70. 13.2.5.70 CDATA 段括号状态
        71. 13.2.5.71 CDATA 段结束状态
        72. 13.2.5.72 字符引用状态
        73. 13.2.5.73 命名字符引用状态
        74. 13.2.5.74 不明确的与号状态
        75. 13.2.5.75 数值字符引用状态
        76. 13.2.5.76 十六进制字符引用开始状态
        77. 13.2.5.77 十进制字符引用开始状态
        78. 13.2.5.78 十六进制字符引用状态
        79. 13.2.5.79 十进制字符引用状态
        80. 13.2.5.80 数值字符引用结束状态
      6. 13.2.6 树构建
        1. 13.2.6.1 创建和插入节点
        2. 13.2.6.2 解析仅包含文本的元素
        3. 13.2.6.3 关闭具有隐含结束标签的元素
        4. 13.2.6.4 在 HTML 内容中解析令牌的规则
          1. 13.2.6.4.1 “initial” 插入模式
          2. 13.2.6.4.2 “before html” 插入模式
          3. 13.2.6.4.3 “before head” 插入模式
          4. 13.2.6.4.4 “in head” 插入模式
          5. 13.2.6.4.5 “in head noscript” 插入模式
          6. 13.2.6.4.6 “after head” 插入模式
          7. 13.2.6.4.7 “in body” 插入模式
          8. 13.2.6.4.8 “文本” 插入模式
          9. 13.2.6.4.9 “在表格中” 插入模式
          10. 13.2.6.4.10 “表格文本中” 插入模式
          11. 13.2.6.4.11 “在标题中” 插入模式
          12. 13.2.6.4.12 “在列组中” 插入模式
          13. 13.2.6.4.13 “在表格主体中” 插入模式
          14. 13.2.6.4.14 “在行中” 插入模式
          15. 13.2.6.4.15 “在单元格中” 插入模式
          16. 13.2.6.4.16 “在选择框中” 插入模式
          17. 13.2.6.4.17 “在表格中的选择框” 插入模式
          18. 13.2.6.4.18 “在模板中” 插入模式
          19. 13.2.6.4.19 “在主体之后” 插入模式
          20. 13.2.6.4.20 “在框架集内” 插入模式
          21. 13.2.6.4.21 “在框架集之后” 插入模式
          22. 13.2.6.4.22 “在主体之后之后” 插入模式
          23. 13.2.6.4.23 “在框架集之后之后” 插入模式
        5. 13.2.6.5 在“外来内容”中解析令牌的规则
      7. 13.2.7 结束
      8. 13.2.8 推测性 HTML 解析
      9. 13.2.9 将 HTML DOM 强制转换为信息集
      10. 13.2.10 解析器中的错误处理和奇怪情况介绍
        1. 13.2.10.1 标签嵌套错误:<b><i></b></i>
        2. 13.2.10.2 标签嵌套错误:<b><p></b></p>
        3. 13.2.10.3 表格中的意外标记
        4. 13.2.10.4 解析时修改页面的脚本
        5. 13.2.10.5 跨多个文档移动的脚本的执行
        6. 13.2.10.6 未闭合的格式化元素
    3. 13.3 序列化HTML片段
    4. 13.4 解析 HTML 片段
    5. 13.5 命名字符引用
  14. 14 XML 语法
    1. 14.1 使用 XML 语法编写文档
    2. 14.2 解析 XML 文档
    3. 14.3 序列化 XML 片段
    4. 14.4 解析 XML 片段
  15. 15 渲染
    1. 15.1 介绍
    2. 15.2 CSS 用户代理样式表和呈现提示
    3. 15.3 非替换元素
      1. 15.3.1 隐藏元素
      2. 15.3.2 页面
      3. 15.3.3 流内容
      4. 15.3.4 短语内容
      5. 15.3.5 双向文本
      6. 15.3.6 章节和标题
      7. 15.3.7 列表
      8. 15.3.8 表格
      9. 15.3.9 边距折叠怪癖
      10. 15.3.10 表单控件
      11. 15.3.11 hr 元素
      12. 15.3.12 fieldsetlegend 元素
    4. 15.4 替换元素
      1. 15.4.1 嵌入内容
      2. 15.4.2 图片
      3. 15.4.3 嵌入内容和图像的属性
      4. 15.4.4 图像映射
    5. 15.5 小部件
      1. 15.5.1 原生外观
      2. 15.5.2 书写模式
      3. 15.5.3 按钮布局
      4. 15.5.4 button 元素
      5. 15.5.5 detailssummary 元素
      6. 15.5.6 input 元素作为文本输入控件
      7. 15.5.7 input 元素作为特定领域的控件
      8. 15.5.8 input 元素作为范围控制
      9. 15.5.9 input 元素作为颜色选择器
      10. 15.5.10 input 元素作为复选框和单选按钮部件
      11. 15.5.11 input 元素作为文件上传控件
      12. 15.5.12 input 元素作为按钮
      13. 15.5.13 marquee 元素
      14. 15.5.14 meter 元素
      15. 15.5.15 progress 元素
      16. 15.5.16 select 元素
      17. 15.5.17 textarea 元素
    6. 15.6 Frame 和 frameset
    7. 15.7 交互媒体
      1. 15.7.1 链接、表单和导航
      2. 15.7.2 title 属性
      3. 15.7.3 编辑容器
      4. 15.7.4 在原生用户界面中呈现的文本
    8. 15.8 打印媒体
    9. 15.9 无样式的 XML 文档
  16. 16 废弃的功能
    1. 16.1 废弃但合规的功能
      1. 16.1.1 废弃但合规功能的警告
    2. 16.2 不合规功能
    3. 16.3 实现要求
      1. 16.3.1 marquee 元素
      2. 16.3.2 框架
      3. 16.3.3 其他元素、属性和 API
  17. 17 IANA 考虑事项
    1. 17.1 text/html
    2. 17.2 multipart/x-mixed-replace
    3. 17.3 application/xhtml+xml
    4. 17.4 text/ping
    5. 17.5 application/microdata+json
    6. 17.6 text/event-stream
    7. 17.7 web+ scheme 前缀
  18. 索引
    1. 元素
    2. 元素内容类别
    3. 属性
    4. 元素接口
    5. 所有接口
    6. 事件
    7. HTTP 头部
    8. MIME 类型
  19. 参考文献
  20. 致谢
  21. 知识产权

1 简介

1.1 本规范的适用范围

该规范定义了网页平台的大部分内容,详细程度很高。它在网页平台规范堆栈中的位置相对于其他规范可以总结如下:

CSS SVG MathML 服务worker IDB Fetch CSP AV1 Opus PNG 本规范 HTTP TLS DOM Unicode Web IDL MIME URL XML JavaScript 编码

1.2 这是 HTML5 吗?

本节为非规范性内容。

简而言之:是的。

更详细地说:“HTML5”这一术语广泛用作现代网页技术的流行词,其中许多(尽管并非全部)是由 WHATWG 开发的。本文档即为其中之一;其他文档可在 WHATWG 标准概览 中找到。

1.3 背景

本节为非规范性内容。

HTML 是万维网的核心标记语言。最初,HTML 主要被设计为一种用于语义描述科学文档的语言。然而,它的总体设计使得它在随后的几年中被适应为描述其他多种文档类型甚至应用程序的语言。

1.4 读者

本节为非规范性内容。

本规范旨在为使用本规范中定义的特性的文档和脚本的作者、操作使用本规范中定义特性的页面的工具的实现者,以及希望确认文档或实现是否符合本规范要求的个人提供参考。

本文件可能不适合没有至少基础了解网络技术的读者,因为在某些地方,它牺牲了清晰性以追求精确性,牺牲了简洁性以求完整性。更易于接近的教程和创作指南可以为读者提供更温和的入门介绍。

特别是,对于本规范中一些更技术性的部分,了解 DOM 的基础知识是必要的。理解 Web IDL、HTTP、XML、Unicode、字符编码、JavaScript 和 CSS 在某些地方也会有所帮助,但不是必须的。

1.5 范围

本节为非规范性内容。

本规范的范围限于提供一个语义级别的标记语言和相关的语义级别脚本 API,用于创建从静态文档到动态应用的可访问网页。

本规范的范围不包括提供媒体特定的呈现定制机制(尽管规范末尾包括了默认的网页浏览器渲染规则,并且提供了若干与 CSS 相关的钩子机制)。

本规范的范围也不包括描述整个操作系统。特别是,硬件配置软件、图像处理工具以及用户预期在高端工作站上日常使用的应用程序均不在范围之内。就应用程序而言,本规范特别针对那些预期用户偶尔使用的应用程序,或定期但在不同地点使用的应用程序,并且对 CPU 的要求较低。这类应用程序的例子包括在线购物系统、搜索系统、游戏(尤其是多人在线游戏)、公共电话簿或地址簿、通信软件(电子邮件客户端、即时消息客户端、讨论软件)、文档编辑软件等。

1.6 历史

本节为非规范性内容。

在其最初的五年(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,即本文档。

1.7 设计说明

本节为非规范性内容。

必须承认,HTML的许多方面乍一看似乎是毫无意义和不一致的。

HTML及其支持的DOM API,以及许多支持技术,已经由一系列不同优先级的人们在数十年的时间里开发完成,在很多情况下,这些人彼此之间并不知道对方的存在。

因此,特性来源于多个来源,并且设计方式并不总是特别一致。此外,由于网页的独特特性,实施错误往往成为事实上的标准,甚至现在是法定标准,因为内容通常会在修复这些错误之前以依赖它们的方式被无意中编写。

尽管如此,仍然努力坚持某些设计目标。这些目标将在接下来的几个小节中进行描述。

1.7.1 脚本执行的可序列化

本节为非规范性内容。

为了避免将多线程的复杂性暴露给网页作者,HTML和DOM API的设计使得脚本无法检测到其他脚本的同时执行。即使在工作线程中,设计的意图也是使实现行为可以被认为是完全串行化所有脚本在所有全局上下文中的执行。

这一通用设计原则的例外是JavaScript SharedArrayBuffer 类。使用 SharedArrayBuffer 对象,实际上可以观察到其他代理中的脚本同时执行。此外,由于JavaScript内存模型,存在一些情况不仅不能通过序列化的脚本执行来表示,而且不能通过序列化的语句执行来表示这些脚本中的内容。

1.7.2 与其他规范的兼容性

本节为非规范性内容。

本规范与许多其他规范进行交互并依赖于它们。在某些情况下,不幸的是,冲突的需求导致本规范违反了这些其他规范的要求。每当发生这种情况时,违规行为都会被标注为“故意违反”,并说明违反的原因。

1.7.3 扩展性

本节为非规范性内容。

HTML 提供了多种扩展机制,可以安全地添加语义:

1.8 HTML 与 XML 语法

本节为非规范性内容。

本规范定义了一种用于描述文档和应用程序的抽象语言,以及一些用于与使用该语言的资源的内存表示进行交互的 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 语法中表示。

1.9 本规范的结构

本节为非规范性内容。

本规范分为以下主要部分:

引言
提供 HTML 标准的背景信息的非规范性材料。
通用基础设施
规范的合规类、算法、定义及其余部分的共同基础。
HTML 文档的语义、结构和 API
文档由元素构建。这些元素使用 DOM 形成树。本节定义了此 DOM 的特性,并介绍了所有元素的共同特性及定义元素所使用的概念。
HTML 的元素
每个元素都有预定义的含义,本节对这些含义进行了说明。还提供了作者如何使用元素的规则,以及用户代理对每个元素的处理要求。这包括 HTML 的大型特性,如视频播放和字幕、表单控件和表单提交,以及一个称为 HTML 画布的 2D 图形 API。
微数据
本规范引入了一种机制,用于向文档添加机器可读的注释,以便工具可以从文档中提取名称-值对树。本节描述了此机制以及一些用于将 HTML 文档转换为其他格式的算法。本节还定义了一些示例微数据词汇表,如联系信息、日历事件和许可作品。
用户交互
HTML 文档可以提供多种机制供用户与内容交互和修改,本节描述了这些机制,如焦点的工作原理和拖放。
加载网页
HTML 文档不是在真空中存在的——本节定义了影响处理多个页面的环境(如网页浏览器)的许多特性。
Web 应用程序 API
本节介绍了 HTML 应用程序脚本的基本特性。
Web Workers
本节定义了 JavaScript 背景线程的 API。
Worklets
本节定义了需要与主 JavaScript 执行环境分开运行的 JavaScript API 的基础设施。
通信 API
本节描述了使用 HTML 编写的应用程序可以用来与同一客户端上运行的不同域中的其他应用程序通信的一些机制。它还介绍了一种称为服务器发送事件(Server Sent Events)或 EventSource 的服务器推送事件流机制,以及一种名为 Web Sockets 的双向全双工套接字协议。
Web 存储
本节定义了一种基于名称-值对的客户端存储机制。
HTML 语法
XML 语法
所有这些特性如果不能以序列化形式表示并传送给其他人,将毫无意义,因此这些部分定义了 HTML 和 XML 的语法,以及如何使用这些语法解析内容的规则。
渲染
本节定义了网页浏览器的默认渲染规则。

此外,还有一些附录,列出了 过时的特性IANA 注意事项,以及几个索引。

1.9.1 如何阅读本规范

阅读本规范的方法与其他规范类似。首先,应该全面阅读多次。然后,至少要反向阅读一次。接着,可以通过从目录中随机挑选章节并跟踪所有交叉引用来进行阅读。

如下面的合规要求部分所述,本规范描述了多种合规类别的合规标准。特别是,有些合规要求适用于 生产者,例如作者及其创建的文档,还有些合规要求适用于 消费者,例如网页浏览器。它们可以通过要求的内容来区分:对生产者的要求说明了允许的内容,而对消费者的要求则说明了软件应该如何行动。

例如,“foo 属性的值必须是一个 有效整数”是对生产者的要求,因为它规定了允许的值;相比之下,“foo 属性的值必须按照 解析整数的规则 进行解析”的要求是对消费者的要求,因为它描述了如何处理内容。

对生产者的要求对消费者没有任何影响。

继续上述示例,一个声明特定属性值受限于 有效整数 的要求明确地 意味着对消费者的要求。可能消费者实际上被要求将属性视为不透明字符串,完全不受值是否符合要求的影响。也可能(如上例所示),消费者被要求使用特定规则解析值,定义如何处理无效(在此情况下为非数字)值。

1.9.2 排版约定

这是一个定义、要求或解释。

这是一个备注。

这是一个示例。

这是一个未解决的问题。

这是一个警告。

[Exposed=Window]
interface Example {
// 这是一个IDL定义
};
variable = object.method([optionalArgument])

这是一个描述接口使用的注释。

/* 这是一个CSS片段 */

术语的定义实例标记为 这样。该术语的使用标记为 这样这样

元素、属性或API的定义实例标记为 这样。对该元素、属性或API的引用标记为 这样

其他代码片段标记为 这样

变量标记为 这样

在算法中,同步部分中的步骤标记为 ⌛。

在某些情况下,要求以带有条件和对应要求的列表形式给出。在这种情况下,适用于条件的要求始终是紧跟在条件后的第一组要求,即使对于这些要求有多个条件组。这样的情况呈现如下:

这是一个条件
这是另一个条件
这是适用于上述条件的要求。
这是第三个条件
这是适用于第三个条件的要求。

1.10 HTML简要介绍

本节非规范性。

一个基本的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 文档中始终出现在该位置的元素。它包含两个元素, headbody, 以及它们之间的一个 文本 节点。

在 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 的更多详细信息,建议作者查阅教程和指南。虽然本规范中包含的一些示例可能也会有所帮助,但新手作者需注意,本规范为了必要性,以一种可能难以理解的细节水平定义了语言。

1.10.1 使用 HTML 编写安全应用程序

本节为非规范性内容。

当 HTML 被用于创建交互式网站时,需要注意避免引入漏洞,通过这些漏洞攻击者可以破坏网站自身或用户的安全。

对这一问题的全面研究超出了本文档的范围,强烈建议作者更详细地研究这一问题。然而,本节尝试提供对 HTML 应用开发中一些常见陷阱的快速介绍。

网络的安全模型基于“来源”概念,相应地,许多对网络的潜在攻击涉及跨源操作。 [ORIGIN]

未验证用户输入
跨站脚本攻击(XSS)
SQL 注入

在接受不可信的输入时,例如用户生成的内容如文本评论、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

如果攻击者成功地说服受害用户访问此页面,攻击者选择的脚本将在页面上运行。这样的脚本可以执行任何数量的恶意操作,仅受网站提供的功能的限制:例如,如果网站是电子商务商店,这样的脚本可能导致用户在不知情的情况下进行任意多的购买。

这被称为跨站脚本攻击。

有许多构造可以用来尝试欺骗网站执行代码。以下是一些作者在编写白名单过滤器时被鼓励考虑的:

跨站请求伪造(CSRF)

如果网站允许用户进行具有用户特定副作用的表单提交,例如在论坛上以用户的名义发布消息、进行购买或申请护照,则必须验证请求是否确实由用户自愿发出,而不是由其他网站欺骗用户无意中发出请求。

这个问题存在是因为 HTML 表单可以提交到其他来源。

网站可以通过填充带有用户特定的隐藏令牌的表单,或通过检查 `Origin` 头来防止此类攻击。

点击劫持

提供用户执行他们可能不愿意执行的操作的接口的页面需要设计得足够谨慎,以避免用户被欺骗以激活该接口。

一种用户可能被欺骗的方法是,如果恶意网站将受害网站放在一个小的 iframe 中,然后通过让用户玩反应游戏来说服用户点击。例如,一旦用户开始玩游戏,恶意网站可以快速将 iframe 定位到鼠标指针下方,正当用户准备点击时,从而欺骗用户点击受害网站的界面。

为了避免这种情况,建议不期望在框架中使用的站点仅在检测到它们不在框架中时启用其接口(例如,通过将 window 对象与 top 属性的值进行比较)。

1.10.2 使用脚本 API 时需避免的常见陷阱

本节为非规范性内容。

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>

1.10.3 如何捕捉编写 HTML 时的错误:验证器和合规检查器

本节为非规范性内容。

建议作者使用合规检查器(也称为 验证器)来捕捉常见错误。WHATWG 维护了一个此类工具的列表:https://whatwg.org/validator/

1.11 对作者的合规要求

本节为非规范性内容。

与之前版本的 HTML 规范不同,本规范详细定义了无效文档和有效文档的处理要求。

然而,即使无效内容的处理在大多数情况下是明确的,文档的合规要求仍然很重要:实际上,互操作性(即所有实现以可靠和相同或等效的方式处理特定内容)并不是文档合规要求的唯一目标。本节详细说明了仍然区分符合规范的文档和有错误的文档的一些常见原因。

1.11.1 表现性标记

本节为非规范性内容。

以前版本的 HTML 中大多数表现性特性现在已不再允许。表现性标记通常存在一些问题:

使用表现性元素会导致可访问性差

虽然可以以提供给辅助技术(AT)用户可接受体验的方式使用表现性标记(例如,使用 ARIA),但这样做比使用语义上合适的标记要困难得多。此外,即使使用这些技术,也无法帮助非 AT 用户,如文本模式浏览器用户,使页面变得可访问。

另一方面,使用与媒体无关的标记可以提供一种简单的方法,使文档能够以更适合更多用户(例如文本浏览器用户)的方式编写。

维护成本更高

维护风格无关的站点要容易得多。例如,更改整个站点中使用 <font color=""> 的颜色需要对整个站点进行更改,而对基于 CSS 的站点进行类似更改只需更改一个文件。

文档大小更大

表现性标记往往更加冗余,因此导致文档大小更大。

由于这些原因,表现性标记在这一版本的 HTML 中已被移除。这一变化并不令人惊讶;HTML4 很多年前已弃用了表现性标记,并提供了一种模式(HTML4 Transitional)来帮助作者摆脱表现性标记;随后,XHTML 1.1 进一步将这些特性完全废弃。

HTML 中唯一剩余的表现性标记特性是 style 属性和 style 元素。style 属性在生产环境中使用有些不被推荐,但在快速原型制作(其规则可以随后直接移入单独的样式表)和在特定情况下提供特殊样式时(在这种情况下使用单独的样式表可能不方便)是有用的。类似地,style 元素在聚合或页面特定样式中可能很有用,但一般来说,当样式适用于多个页面时,外部样式表可能更为方便。

还值得注意的是,一些以前被认为是表现性的元素在本规范中被重新定义为与媒体无关:bihrssmallu

1.11.2 语法错误

本节为非规范性内容。

HTML 的语法被约束以避免各种问题。

不直观的错误处理行为

某些无效的语法构造在解析时,会生成非常不直观的 DOM 树。

例如,以下标记片段会导致 DOM 中的 hr 元素成为相应 table 元素的 前面 的兄弟元素:

<table><hr>...
具有可选错误恢复的错误

为了使用户代理在受控环境中使用而无需实现更奇异和复杂的错误处理规则,允许用户代理在遇到 解析错误 时失败。

错误处理行为与流式用户代理不兼容

一些错误处理行为,例如上面提到的 <table><hr>... 示例,不兼容流式用户代理(即以单次传递处理 HTML 文件的用户代理,不存储状态)。为了避免与这些用户代理的互操作性问题,任何导致这种行为的语法都被视为无效。

可能导致 infoset 强制转换的错误

当基于 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&copy",因为即使没有最终的分号,"&copy" 也会被处理为 "&copy;",从而被解释为 "©":

<a href="?art&copy">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&amp;copy">Art and Copy</a> <!-- the & has to be escaped, since &copy is a named character reference -->
涉及已知的旧版用户代理互操作性问题的错误

某些语法构造已知会在旧版用户代理中引发特别微妙或严重的问题,因此被标记为不符合规范,以帮助作者避免这些问题。

例如,这就是为什么 U+0060 GRAVE ACCENT 字符(`)不允许出现在未加引号的属性中。在某些旧版用户代理中,它有时被当作引号字符处理。

另一个例子是 DOCTYPE,它被要求触发 无怪异模式,因为在 怪异模式 下旧版用户代理的行为通常大多未记录。

可能暴露作者于安全攻击的错误

某些限制纯粹是为了避免已知的安全问题。

例如,限制使用 UTF-7 的规定纯粹是为了避免作者受到利用 UTF-7 的已知跨站脚本攻击的威胁。 [UTF7]

作者意图不明确的情况

作者意图非常不明确的标记通常被标记为不符合规范。尽早纠正这些错误可以使后续维护更容易。

例如,以下内容作者是否意图将其作为 h1 标题还是 h2 标题尚不清楚:

<h1>Contact details</h2>
可能是打字错误的情况

当用户犯简单的打字错误时,如果能够及早捕捉到错误,这将有助于节省作者大量的调试时间。因此,本规范通常将使用与规范中定义的名称不匹配的元素名称、属性名称等视为错误。

例如,如果作者输入了 <capton> 而不是 <caption>,这将被标记为错误,作者可以立即纠正这个打字错误。

可能干扰未来新语法的错误

为了允许将来扩展语言语法,某些原本无害的特性被禁止。

例如,结束标签中的“属性”目前被忽略,但它们是无效的,以防将来对语言进行修改时,使用该语法特性而不与已经部署的(并且有效的!)内容冲突。

一些作者发现,总是引用所有属性并始终包括所有可选标签的做法是有帮助的,他们更倾向于从这种习惯中获得的一致性,而不是利用HTML语法的灵活性所带来的微小好处。为了帮助这些作者,符合性检查工具可以提供一种操作模式,其中强制执行这些约定。

1.11.3 内容模型和属性值的限制

本节是非规范性的。

除了语言的语法之外,本规范还对如何指定元素和属性进行限制。这些限制存在的原因类似:

涉及可疑语义的内容错误

为了避免误用具有明确意义的元素,定义了内容模型以限制元素在这种嵌套不太可能有价值的情况下的嵌套方式。

例如,本规范不允许将一个section 元素嵌套在一个kbd 元素内,因为作者不太可能表示整个部分应输入的意思。

涉及表达语义冲突的错误

同样,为了引起作者对元素使用错误的注意,明确的语义矛盾也被视为符合性错误。

例如,在下面的片段中,语义是不合理的:分隔符不能同时是单元格,单选按钮也不能是进度条。

<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 属性,尽管在实践中circcircle 值作为同义词接受,但禁止使用circ 值,以简化教程和其他学习工具。允许两者没有任何好处,但会在教授语言时引起额外的混淆。

涉及解析器特性的错误

某些元素以有些古怪的方式解析(通常是历史原因),其内容模型限制旨在避免作者暴露于这些问题。

例如,一个form 元素不允许在短语内容 中,因为当作为HTML解析时,form 元素的开始标签将暗示一个 p 元素的结束标签。因此,以下标记会产生两个 段落,而不是一个:

<p>Welcome. <form><label>Name:</label> <input></form>

它的解析方式与以下内容完全相同:

<p>Welcome. </p><form><label>Name:</label> <input></form>
导致脚本难以调试的错误

某些错误旨在帮助防止难以调试的脚本问题。

例如,这就是为什么具有相同值的两个id 属性是非规范的。重复的ID会导致选择错误的元素,有时会导致难以确定原因的灾难性效果。

浪费创作时间的错误

某些构造被禁止是因为它们在历史上已导致了大量的创作时间浪费,通过鼓励作者避免犯这些错误,可以在未来的工作中节省时间。

例如,一个script 元素的src 属性会导致元素的内容被忽略。然而,这并不明显,特别是当元素的内容看起来像可执行脚本时——这会导致作者花费大量时间尝试调试内联脚本,而没有意识到它没有执行。为了减少这个问题,本规范使在存在src 属性时,在script 元素中包含可执行脚本为非规范。这意味着验证其文档的作者不太可能在这种错误上浪费时间。

涉及在HTML和XML语法之间迁移的作者的错误

有些作者喜欢编写可以同时作为XML和HTML解释并具有类似结果的文件。尽管这种做法在一般情况下由于涉及的各种微妙复杂性(尤其是涉及脚本、样式或任何形式的自动化序列化)而不鼓励,但本规范有一些限制旨在至少在某种程度上缓解这些困难。这使得作者在HTML和XML语法之间迁移时可以更轻松地使用此过渡步骤。

例如,围绕langxml:lang 属性的规则相对复杂,旨在保持两者同步。

另一个例子是HTML序列化中xmlns属性值的限制,旨在确保无论是作为HTML还是XML处理,符合规范的文档中的元素最终都会位于相同的命名空间中。

涉及为未来扩展保留的区域的错误

与旨在允许将来修订语言的新语法的语法限制一样,对元素的内容模型和属性值的某些限制旨在允许HTML词汇的未来扩展。

例如,限制以U+005F下划线字符(_)开头的target 属性的值仅限于特定的预定义值,以便将来可以引入新的预定义值,而不会与作者定义的值冲突。

涉及误用其他规范的错误

某些限制旨在支持其他规范的限制。

例如,要求使用媒体查询列表的属性仅使用有效的媒体查询列表,加强了遵循该规范的符合性规则的重要性。

1.12 建议阅读

本节是非规范性的。

以下文档可能对本规范的读者感兴趣。

万维网字符模型 1.0: 基础 [CHARMOD]

本架构规范为规范的作者、软件开发人员和内容开发人员提供了一个共同的参考,用于在万维网上进行可互操作的文本处理,基于Unicode标准和ISO/IEC 10646共同定义的通用字符集。涉及的主题包括“字符”、“编码”和“字符串”的使用术语、参考处理模型、字符编码的选择和标识、字符转义和字符串索引。

Unicode 安全考虑 [UTR36]

由于Unicode包含了大量字符并结合了世界上各种书写系统,不正确的使用可能会使程序或系统面临潜在的安全攻击。这在越来越多的产品国际化时尤为重要。本文件描述了程序员、系统分析员、标准开发人员和用户应考虑的一些安全问题,并提供了具体的建议以降低问题的风险。

网页内容无障碍指南 (WCAG) [WCAG]

网页内容无障碍指南 (WCAG) 涵盖了一系列使网页内容更具可访问性的建议。遵循这些指南将使内容对更多有残疾的人更易访问,包括盲人和低视力者、聋人和听力损失者、学习障碍者、认知限制者、行动不便者、言语障碍者、光敏感者及其组合。遵循这些指南通常也会使您的网页内容对一般用户更易用。

创作工具无障碍指南 (ATAG) 2.0 [ATAG]

本规范提供了设计更易于残障人士使用的网页内容创作工具的指南。符合这些指南的创作工具将通过为残障作者提供可访问的用户界面以及通过启用、支持和促进所有作者创作可访问的网页内容来促进无障碍。

用户代理无障碍指南 (UAAG) 2.0 [UAAG]

本文件提供了设计用户代理的指南,以降低残障人士在网页无障碍方面的障碍。用户代理包括浏览器和其他类型的检索和呈现网页内容的软件。符合这些指南的用户代理将通过其自身的用户界面和其他内部功能(包括与其他技术(尤其是辅助技术)通信的能力)促进无障碍。此外,所有用户,不仅仅是残障用户,都会发现符合这些指南的用户代理更易用。

2 常见基础设施

本规范依赖于 Infra[INFRA]

2.1 术语

本规范提到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类型的资源。


为了简化,术语如显示呈现可见有时可能用于指代文档呈现给用户的方式。这些术语并不意味着特指视觉媒介;它们必须被视为在其他媒介中具有等效的应用。

2.1.1 并行处理

按照定义并行执行步骤,意味着这些步骤在标准中的其他逻辑(例如,事件循环)同时运行。该标准未定义实现这一目标的精确机制,无论是时间共享协作多任务处理、纤程、线程、进程、使用不同的超线程、核心、CPU、机器等。相比之下,立即运行的操作必须中断当前正在运行的任务,自己运行,然后恢复之前正在运行的任务。

有关编写利用并行处理规范的指南,请参见其他规范中的事件循环处理

为了避免不同并行算法在操作相同数据时产生竞争条件,可以使用并行队列

并行队列表示必须按顺序运行的一系列算法步骤。

并行队列有一个算法队列(一个队列),最初为空。

要将步骤加入队列并行队列加入算法步骤到并行队列算法队列

启动一个新的并行队列,请运行以下步骤:

  1. parallelQueue为一个新的并行队列

  2. 并行运行以下步骤:

    1. 当为真时:

      1. steps为从parallelQueue算法队列出队的结果。

      2. 如果steps不为空,则运行steps

      3. 断言:运行steps未抛出异常,因为并行运行的步骤不得抛出异常。

      实现不需要将此作为持续运行的循环来实现。标准中的算法应易于理解,不一定对电池寿命或性能有好处。

  3. 返回parallelQueue

并行运行的步骤本身可以并行运行其他步骤。例如,在并行队列内并行运行一系列步骤可能是有用的。

设想一个标准定义的nameList(一个列表),以及一个方法将name添加到nameList,除非nameList已经 包含name,在这种情况下,它将拒绝。

以下解决方案存在竞态条件:

  1. p成为在此对象相关领域中创建的一个新承诺。

  2. 按以下步骤并行运行

    1. 如果nameList包含name, 则在全局任务队列中基于 此对象相关全局对象 拒绝p,并抛出 TypeError, 并中止这些步骤。

    2. 进行一些可能耗时的工作。

    3. name追加到 nameList

    4. 在全局任务队列中,基于 此对象相关全局对象, 以undefined解析p

  3. 返回p

以上两个调用可以同时运行,这意味着在步骤 2.1 中name不在nameList中,但在步骤 2.3 运行之前,它 可能被添加,这意味着name最终在nameList中出现了两次。

并行队列解决了这个问题。标准将让nameListQueue作为 启动一个新并行队列的结果,然后:

  1. p成为在此对象相关领域中创建的一个新承诺。

  2. 将以下步骤加入队列nameListQueue

    1. 如果nameList包含name, 则在全局任务队列中基于 此对象相关全局对象 拒绝p,并抛出 TypeError, 并中止这些步骤。

    2. 进行一些可能耗时的工作。

    3. name追加到 nameList

    4. 在全局任务队列中,基于 此对象相关全局对象, 以undefined解析p

  3. 返回p

这些步骤现在会排队,竞态得以避免。

2.1.2 资源

本规范使用术语支持的来指用户代理是否具有能够解码外部资源语义的实现。当实现能够处理某种格式或类型的外部资源而不会忽略资源的关键方面时,该格式或类型被称为支持的。特定资源是否支持的可能取决于资源格式中使用的功能。

例如,如果可以解码并渲染PNG图像的像素数据,即使实现不知道图像还包含动画数据,该图像也被认为是支持的格式。

如果使用的压缩格式不支持,即使实现可以从文件的元数据中确定电影的尺寸,MPEG-4视频文件也不会被认为是支持的格式。

某些规范(特别是HTTP规范)所指的表示在本规范中被称为资源[HTTP]

资源的关键子资源是指资源需要可用以便被正确处理的那些资源。哪些资源被认为是关键资源由定义资源格式的规范规定。

对于CSS样式表,我们在此暂时定义它们的关键子资源是通过@import规则导入的其他样式表,包括由其他导入的样式表间接导入的样式表。

此定义尚未完全互操作;此外,一些用户代理似乎将背景图像或网页字体等资源视为关键子资源。理想情况下,CSS工作组将定义这一点;请参见w3c/csswg-drafts issue #1088以跟踪此方面的进展。

2.1.3 XML兼容性

为了简化从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]

2.1.4 DOM树

当声明某个元素或属性被忽略,或被视为其他值,或处理为其他内容时,这仅指节点在DOM中处理的情况。在这种情况下,用户代理不得更改DOM。

只有当内容属性的新值与其先前的值不同,才说内容属性改变了值;将属性设置为它已经具有的值不会改变它。

当术语用于属性值、文本节点或字符串时,表示文本的长度为零(即,不包含控制字符或U+0020空格)。

HTML 元素可以具有特定的 HTML 元素插入步骤HTML 元素连接后步骤HTML 元素移除步骤,这些步骤都是根据元素的 本地名称 定义的。

HTML标准的插入步骤,给定insertedNode,定义如下:

  1. 如果insertedNode是一个元素,并且其命名空间HTML 命名空间,并且本标准为insertedNode本地名称定义了HTML 元素插入步骤,则运行相应的HTML 元素插入步骤,给定insertedNode

  2. 如果insertedNode表单关联元素或其祖先是表单关联元素,则:

    1. 如果表单关联元素解析器插入标志已设置,则返回。

    2. 重置表单关联元素的表单所有者。

  3. 如果insertedNode是一个不在打开元素栈中的HTML解析器Element,则处理内部资源链接,给定insertedNode节点文档

连接后的步骤对于 HTML 标准,给定 insertedNode,定义如下:

  1. 如果 insertedNode 是一个元素,并且其 命名空间HTML 命名空间,且本标准为 insertedNode本地名称定义了HTML 元素连接后的步骤,则在给定 insertedNode 的情况下运行相应的 HTML 元素连接后的步骤

HTML标准的移除步骤,给定removedNodeoldParent,定义如下:

  1. documentremovedNode节点文档

  2. 如果document聚焦区域removedNode,则将document聚焦区域设置为document视口,并将document相关全局对象导航API正在进行导航期间焦点更改设置为false。

    执行失焦步骤聚焦步骤焦点更新步骤,因此不会触发失焦更改事件。

  3. 如果removedNode是其命名空间 HTML命名空间的元素,并且本标准为removedNode本地名称定义了HTML元素移除步骤,则运行对应的HTML元素移除步骤,给定removedNodeoldParent

  4. 如果removedNode表单关联元素或其祖先是表单关联元素,则:

    1. 如果表单关联元素表单所有者,且表单关联元素和其表单所有者不再在同一个中,则重置表单关联元素的表单所有者。

  5. 如果removedNode弹出框属性不在无弹出框状态,则运行隐藏弹出框算法,给定removedNode、false、false和false。

插入步骤以某个节点作为参数调用时,并且该节点现在在文档树中,则称该节点已插入文档。类似地,当移除步骤以某个节点作为参数调用时,并且该节点现在不再在文档树中,则称该节点已从文档中移除

插入步骤以某个节点作为参数调用时,并且该节点现在已连接,则该节点变为连接状态。类似地,当移除步骤以某个节点作为参数调用时,并且该节点现在不再已连接,则该节点变为断开状态

当某个节点已连接且其包含阴影根浏览上下文非空时,该节点是浏览上下文连接的。当插入步骤以某个节点作为参数调用时,并且该节点现在浏览上下文连接的,则该节点变为浏览上下文连接的。当移除步骤以某个节点作为参数调用时,并且该节点现在不再浏览上下文连接的,或当其包含阴影根浏览上下文变为空时,该节点变为浏览上下文断开的

2.1.5 脚本

构造 "一个 Foo 对象",其中 Foo 实际上是一个接口,有时被用于代替更准确的 "实现接口 Foo 的对象"。

当IDL属性的值被检索(例如通过作者脚本)时,称该属性正在获取值,当为其赋予新值时,称其正在设置值。

如果某个DOM对象被称为实时的,则该对象上的属性和方法必须操作实际的底层数据,而不是数据的快照。

2.1.6 插件

术语插件是指由用户代理使用的一组实现定义的内容处理程序,这些处理程序可以参与用户代理对文档对象的渲染,但既不作为文档子导航,也不会向文档的DOM引入任何节点对象。

通常,这些内容处理程序由第三方提供,但用户代理也可以将内置的内容处理程序指定为插件。

用户代理不得将类型text/plainapplication/octet-stream视为已注册的插件

插件的一个例子是当用户导航到PDF文件时,在导航器中实例化的PDF查看器。无论PDF查看器组件的实现方与用户代理的实现方是否相同,这都算作插件。然而,与用户代理分开的启动的PDF查看器应用程序(而不是使用相同的界面)不符合插件的定义。

本规范未定义与插件交互的机制,因为这被认为是用户代理和平台特定的。一些用户代理可能选择支持诸如Netscape插件API之类的插件机制;其他可能使用远程内容转换器或内置支持某些类型。事实上,本规范并不要求用户代理支持插件。[NPAPI]

浏览器在与外部内容(例如插件)交互时应格外小心。当第三方软件与用户代理本身具有相同的权限运行时,第三方软件中的漏洞变得与用户代理中的漏洞一样危险。

(This is a tracking vector.)由于不同用户拥有不同的插件集提供了一个跟踪向量,增加了唯一识别用户的可能性,建议用户代理为每个用户支持完全相同的插件集。

2.1.7 字符编码

字符编码,或在不产生歧义的情况下仅称为编码,是一种在字节流和Unicode字符串之间转换的定义方式,如编码中定义的那样。一个编码具有一个编码名称和一个或多个编码标签,在编码标准中被称为编码的名称标签[ENCODING]

2.1.8 合规类

本规范描述了与实现者相关的用户代理和与作者及创作工具实现者相关的文档的合规标准。

合规文档是指符合所有文档合规标准的文档。为了便于阅读,这些合规要求中的一些被表述为对作者的合规要求;这些要求隐含为对文档的要求:根据定义,所有文档都假定由某个作者创建。(在某些情况下,作者本身可能是用户代理——此类用户代理需要遵守下面解释的额外规则。)

例如,如果某个要求规定“作者不得使用foobar元素”,则意味着文档中不允许包含名为foobar的元素。

文档合规要求与实现合规要求之间没有隐含关系。用户代理不得自由处理不合规的文档;无论输入文档是否合规,本规范描述的处理模型都适用于实现。

用户代理分为几类(重叠),具有不同的合规要求。

Web浏览器和其他交互式用户代理

支持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系统也不能构成合规检查器。

换句话说,有三种类型的合规标准:

  1. 可以在DTD中表达的标准。
  2. 不能用DTD表达,但仍然可以用机器检查的标准。
  3. 只能由人类检查的标准。

合规检查器必须检查前两类错误。简单的基于DTD的验证器只能检查第一类错误,因此根据本规范不构成合规检查器。

数据挖掘工具

为了渲 染文档或检查其合规性之外的目的处理HTML和XML文档的应用程序和工具,应根据其处理的文档的语义行事。

生成文档大纲的工具,但每段都增加嵌套级别并且不增加标题嵌套级别的工具,将不符合规范。

创作工具和标记生成器

创作工具和标记生成器必须生成合规文档。适用于作者的合规标准在适当时也适用于创作工具。

创作工具不受严格使用元素只用于其指定目的的要求的限制,但仅限于创作工具尚无法确定作者意图的情况。然而,创作工具不得自动滥用元素或鼓励其用户这样做。

例如,使用address元素标记任意联系信息是不合规的;该元素只能用于标记其最近的articlebody元素祖先的联系信息。然而,由于创作工具可能无法区分,创作工具对此要求免除。这并不意味着创作工具可以将address元素用于任何斜体文本块(例如);这仅意味着创作工具不必验证用户在插入article元素的联系信息工具时,用户确实在插入联系信息而不是插入其他内容。

在合规检查方面,编辑器必须输出符合与合规检查器将验证的程度相同的文档。

当使用创作工具编辑不合规文档时,它可以在编辑过程中未编辑的文档部分保留合规错误(即编辑工具可以原样保存错误内容)。然而,如果错误被这样保留,创作工具不得声称输出是合规的。

创作工具预计分为两大类:基于结构或语义数据的工具和基于所见即所得的媒体特定编辑工具(WYSIWYG)。

前者是创作HTML工具的首选机制,因为源信息中的结构可以用于在HTML元素和属性的选择上做出明智的选择。

然而,所见即所得工具也是合法的。所见即所得工具应使用它们知道合适的元素,并且不应使用它们不知道合适的元素。这在某些极端情况下可能意味着将流元素的使用限制在少数几个元素,如divbispan,并广泛使用style属性。

无论是所见即所得还是其他类型的创作工具,都应尽最大努力使用户能够创建结构良好、语义丰富、与媒体无关的内容。

为了与现有内容和先前规范兼容,本规范描述了两种创作格式:一种基于XML,另一种使用自定义格式,受到SGML的启发(称为HTML语法)。实现必须至少支持这两种格式中的一种,尽管鼓励支持两者。

一些合规要求表述为对元素、属性、方法或对象的要求。这些要求分为两类:描述内容模型限制的要求和描述实现行为的要求。前者是对文档和创作工具的要求。后者是对用户代理的要求。同样,一些合规要求表述为对作者的要求;这些要求应解释为对作者生成的文档的合规要求。(换句话说,本规范不区分对作者的合规标准和对文档的合规标准。)

2.1.9 依赖关系

本规范依赖于几个其他的基础规范。

基础结构(Infra)

以下术语在基础结构(Infra)中定义:[INFRA]

Unicode and Encoding

Unicode字符集用于表示文本数据,Encoding定义了与字符编码相关的要求。 [UNICODE]

本规范引入了 基于这些规范中定义的术语,如前所述。

以下术语在Encoding中定义:[ENCODING]

  • 获取编码
  • 获取输出编码
  • 通用解码算法,该算法接受字节流和编码并返回字符流
  • UTF-8解码算法,该算法接受字节流并返回字符流,另外还会去除一个前导UTF-8字节顺序标记(BOM)(如果有)
  • 无BOM的UTF-8解码算法,该算法与UTF-8解码 相同,但不会去除一个前导的UTF-8字节顺序标记(BOM)
  • 编码算法,该算法接受字符流和编码并返回字节流
  • UTF-8编码算法,该算法接受字符流并返回字节流
  • BOM检测 算法,该算法接受字节流并返回编码或null。
XML and related specifications

支持HTML的XML语法的实现必须支持某个版本的XML及其对应的命名空间规范,因为该语法使用带有命名空间的XML序列化。[XML] [XMLNS]

在不运行脚本、不评估CSS或XPath表达式,或不将结果DOM暴露给任意内容的情况下执行内容操作的数据挖掘工具和其他用户代理,可以通过仅断言其DOM节点类似物在某些命名空间中来“支持命名空间”,而无需实际暴露命名空间字符串。

HTML语法中,命名空间前缀和命名空间声明与XML中的效果不同。例如,冒号在HTML元素名称中没有特殊含义。


XML命名空间中名称为space的属性由可扩展标记语言 (XML)定义。[XML]

Name生成规则在XML中定义。[XML]

本规范还引用了与XML文档关联样式表中定义的<?xml-stylesheet?>处理指令。[XMLSSPI]

本规范还非规范性地提及了XSLTProcessor接口及其transformToFragment()transformToDocument()方法。[XSLTP]

URLs

以下术语在URL中定义:[URL]

本规范还引用了多个方案和协议:

媒体片段语法媒体片段URI中定义。[MEDIAFRAG]

HTTP and related specifications

以下术语在HTTP规范中定义:[HTTP]

以下术语在HTTP State Management Mechanism中定义:[COOKIES]

以下术语在Web Linking中定义:[WEBLINK]

以下术语在Structured Field Values for HTTP中定义:[STRUCTURED-FIELDS]

以下术语在MIME Sniffing中定义:[MIMESNIFF]

Fetch

以下术语在Fetch中定义:[FETCH]

以下术语在Referrer Policy中定义:[REFERRERPOLICY]

以下术语在Mixed Content中定义:[MIX]

以下术语在Subresource Integrity中定义:[SRI]

Paint Timing

Paint Timing 中定义了以下术语:[PAINTTIMING]

Navigation Timing

Navigation Timing 中定义了以下术语:[NAVIGATIONTIMING]

Resource Timing

Resource Timing 中定义了以下术语: [RESOURCETIMING]

Performance Timeline

Performance Timeline 中定义了以下术语: [PERFORMANCETIMELINE]

Long Animation Frames

Long Animation Frames 中定义了以下术语: [LONGANIMATIONFRAMES]

Long Tasks

Long Tasks 中定义了以下术语: [LONGTASKS]

Web IDL

本规范中的 IDL 片段必须按照 Web IDL 的要求进行解释,以符合 IDL 片段的要求。 [WEBIDL]

以下术语在 Web IDL 中定义:

Web IDL 还定义了以下在本规范的 Web IDL 片段中使用的类型:

本规范中术语 throw 的使用定义见 Web IDLDOMException 类型和以下异常名称由 Web IDL 定义,并由本规范使用:

当本规范要求用户代理创建一个表示特定时间(可能是特殊值 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]

术语“JavaScript”用来指代 ECMA-262,而不是正式术语 ECMAScript,因为 JavaScript 这个术语更广为人知。

以下术语在 JavaScript 规范中定义,并在本规范中使用:

支持 JavaScript 的用户代理还必须实现 动态代码品牌检查 提案。以下术语在那里定义,并在本规范中使用: [JSDYNAMICCODEBRANDCHECKS]

支持 JavaScript 的用户代理还必须实现 ECMAScript 国际化 API[JSINTL]

支持 JavaScript 的用户代理还必须实现 导入属性 提案。以下术语在那里定义,并在本规范中使用: [JSIMPORTATTRIBUTES]

支持 JavaScript 的用户代理还必须实现 JSON 模块 提案。以下术语在那里定义,并在本规范中使用: [JSJSONMODULES]

支持 JavaScript 的用户代理还必须实现 可调整大小的 ArrayBuffer 和可增长的 SharedArrayBuffer 提案。以下术语在那里定义,并在本规范中使用: [JSRESIZABLEBUFFERS]

支持 JavaScript 的用户代理还必须实现 Temporal 提案。以下术语在那里定义,并在本规范中使用: [JSTEMPORAL]

WebAssembly

以下术语在 WebAssembly JavaScript Interface 中定义:[WASMJS]

DOM

文档对象模型 (DOM) 是文档及其内容的表示——一种模型。DOM 不仅仅是一个 API;HTML 实现的符合性标准在本规范中以对 DOM 的操作来定义。[DOM]

实现必须支持 DOM 和在 UI Events 中定义的事件,因为本规范是根据 DOM 定义的,并且一些功能被定义为对 DOM 接口的扩展。[DOM] [UIEVENTS]

特别地,以下功能在 DOM 中定义:[DOM]

以下功能在 UI Events 中定义:[UI EVENTS]

以下功能在 Touch Events 中定义:[TOUCH]

以下功能在 Pointer Events 中定义:[POINTEREVENTS]

以下事件在 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]

High Resolution Time 提供了以下功能:[HRT]

File API

本规范使用 File API 中定义的以下功能:[FILEAPI]

Indexed Database API

本规范使用 Indexed Database API 定义的 清理 Indexed Database 事务[INDEXEDDB]

Media Source Extensions

以下术语在 Media Source Extensions 中定义: [MEDIASOURCE]

Media Capture and Streams

以下术语在 Media Capture and Streams 中定义: [MEDIASTREAM]

Reporting

以下术语在 Reporting 中定义:[REPORTING]

XMLHttpRequest

以下功能和术语在 XMLHttpRequest 中定义: [XHR]

Battery Status

以下功能在 Battery Status API 中定义:[BATTERY]

Media Queries

实现必须支持 Media Queries。其中定义了 <media-condition> 特性。[MQ]

CSS 模块

虽然本规范的实现不要求完全支持 CSS(尽管我们鼓励支持,尤其是对 web 浏览器而言),但有些特性是根据特定的 CSS 要求定义的。

当本规范要求按照特定的 CSS 语法解析某些内容时,必须遵循 CSS Syntax 中相关的算法,包括错误处理规则。[CSSSYNTAX]

例如,用户代理在意外发现样式表末尾时,需要关闭所有未闭合的结构。因此,当解析字符串 "rgb(0,0,0"(缺少闭合括号)作为颜色值时,根据此错误处理规则,闭合括号是隐含的,并且会得到一个值(颜色为 '黑色')。然而,类似的结构 "rgb(0,0,"(既缺少括号又缺少 "蓝色" 值)不能被解析,因为闭合未闭合的结构不会得到一个有效的值。

以下术语和特性在 Cascading Style SheetsCSS)中定义:[CSS]

基本版本的'display'属性在CSS中定义,并且该属性由其他CSS模块扩展。[CSS] [CSSRUBY] [CSSTABLE]

以下术语和功能在CSS Box Model中定义:[CSSBOX]

以下功能在CSS逻辑属性中定义:[CSSLOGICAL]

以下术语和功能在CSS颜色中定义:[CSSCOLOR]

以下术语在CSS Images中定义:[CSSIMAGES]

术语paint sourceCSS Images Level 4中定义,用于定义某些HTML元素与CSS 'element()'函数的交互。[CSSIMAGES4]

以下功能在CSS Backgrounds and Borders中定义:[CSSBG]

CSS Backgrounds and Borders还定义了以下边框属性:[CSSBG]

边框属性
宽度 'border-top-width' 'border-bottom-width' 'border-left-width' 'border-right-width'
样式 'border-top-style' 'border-bottom-style' 'border-left-style' 'border-right-style'
颜色 'border-top-color' 'border-bottom-color' 'border-left-color' 'border-right-color'

以下功能在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]

以下功能和术语在CSS Syntax中定义:[CSSSYNTAX]

以下术语在Selectors中定义:[SELECTORS]

以下功能在CSS Values and Units中定义:[CSSVALUES]

以下功能在CSS View Transitions中定义:[CSSVIEWTRANSITIONS]

术语style attributeCSS Style Attributes中定义。[CSSATTR]

以下术语在CSS Cascading and Inheritance中定义:[CSSCASCADE]

CanvasRenderingContext2D对象对字体的使用依赖于CSSFontsFont Loading规范中描述的功能,特别是FontFace对象和字体来源概念。[CSSFONTS] [CSSFONTLOAD]

以下接口和术语在Geometry Interfaces中定义:[GEOMETRY]

以下术语在CSS Scoping中定义:[CSSSCOPING]

以下术语和功能在CSS Color Adjustment中定义:[CSSCOLORADJUST]

以下术语在CSS Pseudo-Elements中定义:[CSSPSEUDO]

以下术语在CSS Containment中定义:[CSSCONTAIN]

交叉观察器 (Intersection Observer)

以下术语在Intersection Observer中定义:[INTERSECTIONOBSERVER]

Resize Observer

以下术语在Resize Observer中定义:[RESIZEOBSERVER]

WebGL

以下接口在WebGL规范中定义:[WEBGL]

WebGPU

以下接口在WebGPU中定义:[WEBGPU]

WebVTT

实现可能支持将WebVTT作为字幕、说明、元数据等的文本轨格式,用于媒体资源。[WEBVTT]

本规范中使用的以下术语在WebVTT中定义:

ARIA

role属性在Accessible Rich Internet ApplicationsARIA)中定义,如下角色也是:[ARIA]

此外,以下aria-*内容属性在ARIA中定义:[ARIA]

最后,以下术语在ARIA中定义:[ARIA]

Content Security Policy

以下术语在Content Security Policy中定义:[CSP]

Service Workers

以下术语在Service Workers中定义:[SW]

Secure Contexts

以下算法在Secure Contexts中定义:[SECURE-CONTEXTS]

Permissions Policy

以下术语在Permissions Policy中定义:[PERMISSIONSPOLICY]

Payment Request API

以下功能在Payment Request API中定义:[PAYMENTREQUEST]

MathML

虽然本规范不要求全面支持MathML(尽管至少鼓励网页浏览器支持),某些功能依赖于实现MathML的一小部分。[MATHML]

以下功能在Mathematical Markup LanguageMathML)中定义:

SVG

虽然本规范不要求全面支持SVG(尽管至少鼓励网页浏览器支持),但某些功能依赖于实现SVG的部分内容。

实现SVG的用户代理必须实现SVG 2规范,而不是任何早期版本。

以下功能在SVG 2规范中定义:[SVG]

Filter Effects

以下功能在Filter Effects中定义:[FILTERS]

Compositing

以下功能在Compositing and Blending中定义:[COMPOSITE]

Cooperative Scheduling of Background Tasks

以下功能在Cooperative Scheduling of Background Tasks中定义:[REQUESTIDLECALLBACK]

Screen Orientation

以下术语在Screen Orientation中定义:[SCREENORIENTATION]

Storage

以下术语在Storage中定义:[STORAGE]

Web App Manifest

以下功能在Web App Manifest中定义:[MANIFEST]

WebAssembly JavaScript 接口:ESM 集成

以下术语在WebAssembly JavaScript 接口:ESM 集成中定义:[WASMESM]

WebCodecs

以下功能在WebCodecs中定义:[WEBCODECS]

WebDriver

以下术语在WebDriver中定义:[WEBDRIVER]

WebDriver BiDi

以下术语在WebDriver BiDi中定义:[WEBDRIVERBIDI]

Web Cryptography API

以下术语在Web Cryptography API中定义: [WEBCRYPTO]

WebSockets

以下术语在WebSockets中定义:[WEBSOCKETS]

WebTransport

以下术语在WebTransport中定义:[WEBTRANSPORT]

Web Authentication: An API for accessing Public Key Credentials

以下术语在Web Authentication: An API for accessing Public Key Credentials中定义:[WEBAUTHN]

Credential Management

以下术语在Credential Management中定义:[CREDMAN]

Console

以下术语在Console中定义:[CONSOLE]

Web Locks API

以下术语在Web Locks API中定义:[WEBLOCKS]

Trusted Types

本规范使用在Trusted Types中定义的以下功能: [TRUSTED-TYPES]


本规范并不要求支持任何特定的网络协议、样式表语言、脚本语言或超出上述列表中要求的任何 DOM 规范。然而,本规范描述的语言倾向于使用 CSS 作为样式语言,JavaScript 作为脚本语言,以及 HTTP 作为网络协议,并且多个功能假定这些语言和协议正在使用。

实现 HTTP 协议的用户代理必须同时实现HTTP State Management Mechanism(Cookies)。[HTTP] [COOKIES]

本规范可能在各自的章节中对字符编码、图像格式、音频格式和视频格式有某些额外要求。

2.1.10 扩展性

强烈不建议对本规范进行厂商特定的专有用户代理扩展。文档不得使用此类扩展,因为这样做会降低互操作性并分裂用户群体,导致只有特定用户代理的用户才能访问相关内容。

所有扩展必须定义为使用扩展既不矛盾也不导致规范中定义的功能不合格。

例如,尽管强烈不建议这样做,但实现可以向控件添加一个新的 IDL 属性 "typeTime",该属性返回用户选择当前控件值所花费的时间。另一方面,定义一个出现在表单的 elements 数组中的新控件将违反上述要求,因为它将违反本规范中给出的 elements 的定义。


当需要对本规范进行中立扩展时,可以相应地更新本规范,或者可以编写一个扩展规范来覆盖本规范中的要求。当某人将本规范应用于其活动时,决定认可此类扩展规范的要求时,它将成为本规范符合性要求目的的 适用规范

有人可以编写一个规范,定义任何任意字节流都是合格的,然后声称他们的随机垃圾是合格的。然而,这并不意味着他们的随机垃圾实际上对所有人的目的都是合格的:如果其他人决定该规范不适用于他们的工作,那么他们可以很合法地说上述随机垃圾只是垃圾,根本不合格。就符合性而言,特定社区中的重要问题是该社区 同意 适用的是什么。


用户代理必须将不理解的元素和属性视为语义中性;将它们留在 DOM 中(对于 DOM 处理器),并根据 CSS 进行样式设置(对于 CSS 处理器),但不从中推断任何意义。

当某个功能的支持被禁用时(例如作为减轻安全问题的紧急措施,或为开发提供帮助,或出于性能原因),用户代理必须表现得好像他们完全不支持该功能,并且该功能未在本规范中提及。例如,如果通过 Web IDL 接口中的属性访问某个特定功能,该属性本身将从实现该接口的对象中省略——将属性留在对象上但使其返回 null 或抛出异常是不足够的。

2.1.11 与 XPath 和 XSLT 的交互

在根据本规范描述的方式解析或创建的 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 表达式时,默认元素命名空间的值按以下方式确定:

  1. 如果上下文节点来自 HTML DOM,则默认元素命名空间为 "http://www.w3.org/1999/xhtml"。
  2. 否则,默认元素命名空间 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 的交互进行了额外的非规范性注释。

2.2 策略控制的功能

Headers/Permissions-Policy/document-domain

仅在一个引擎中支持。

Firefox🔰 74+SafariNoChrome🔰 88+
Opera?Edge🔰 88+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome AndroidNoWebView Android?Samsung Internet?Opera Android?

本文档定义了以下策略控制的功能

Headers/Feature-Policy/autoplay

Firefox🔰 74+SafariNoChrome64+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Headers/Permissions-Policy/autoplay

仅在一个引擎中支持。

Firefox🔰 74+SafariNoChrome88+
Opera?Edge88+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

2.3 通用微语法

HTML 中有很多地方接受特定的数据类型,例如日期或数字。本节描述了这些格式内容的符合性标准以及如何解析它们。

强烈建议实现者仔细检查可能考虑使用的任何第三方库,以实现以下描述的语法解析。例如,日期库可能会实现与本规范要求不同的错误处理行为,因为描述类似于本规范中使用的日期语法的规范中通常未定义错误处理行为,因此实现往往在如何处理错误方面存在很大差异。

2.3.1 通用解析器习惯用法

下面描述的一些微解析器遵循一种模式,即具有一个保存解析字符串的 input 变量,以及一个指向 input 中下一个要解析的字符的 position 变量。

2.3.2 布尔属性

有许多属性是 布尔属性。元素上存在布尔属性表示真值,而不存在该属性表示假值。

如果该属性存在,其值必须是空字符串或与属性规范名称进行 ASCII 大小写不敏感 匹配的值,且没有前导或尾随空格。

布尔属性上不允许使用值 "true" 和 "false"。要表示假值,必须完全省略该属性。

以下是一个已选中且禁用的复选框示例。checkeddisabled 属性是布尔属性。

<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>

2.3.3 关键字和枚举属性

一些属性称为枚举属性,它们取一组有限的状态。此类属性的状态通过将属性值、每个属性规范中给出的关键字/状态映射集和属性规范中可能给出的两种特殊状态结合起来得出。这些特殊状态是无效值默认值缺失值默认值

多个关键字可以映射到同一状态。

空字符串可以是有效的关键字。注意,缺失值默认值仅在属性缺失时适用,而不是当它以空字符串值存在时。

要确定属性的状态,请使用以下步骤:

  1. 如果未指定该属性:

    1. 如果属性定义了缺失值默认值状态,则返回该缺失值默认值状态。

    2. 否则,不返回任何状态。

  2. 如果属性的值与为该属性定义的关键字之一进行ASCII大小写不敏感匹配,则返回该关键字表示的状态。

  3. 如果属性定义了无效值默认值状态,则返回该无效值默认值状态。

  4. 不返回任何状态。

出于编写符合性目的,如果指定了枚举属性,则属性的值必须与该属性的一个合规关键字进行ASCII大小写不敏感匹配,且没有前导或尾随空格。

出于反射目的,有任何关键字映射到的状态被称为具有规范关键字。其确定方式如下:

2.3.4 数字

2.3.4.1 有符号整数

如果一个字符串由一个或多个ASCII数字组成,并且可以选择以U+002D连字符-字符(-)为前缀,则该字符串是有效整数

没有U+002D连字符-前缀的有效整数表示由该数字字符串表示的十进制数。有U+002D连字符-前缀的有效整数表示由跟随U+002D连字符-的数字字符串表示的十进制数,从零减去。

解析整数的规则如下所示。当调用时,必须按给定顺序执行步骤,在返回值的第一个步骤中中止。该算法将返回一个整数或一个错误。

  1. input为正在解析的字符串。

  2. positioninput中的指针,最初指向字符串的开头。

  3. sign的值为“positive”。

  4. 跳过ASCII空白字符input中给定position

  5. 如果position超过input的末尾,则返回错误。

  6. 如果position指示的字符(第一个字符)是U+002D连字符-字符(-):

    1. sign为“negative”。
    2. position前进到下一个字符。
    3. 如果position超过input的末尾,则返回错误。

    否则,如果position指示的字符(第一个字符)是U+002B加号字符(+):

    1. position前进到下一个字符。(“+”被忽略,但它不符合规范。)
    2. 如果position超过input的末尾,则返回错误。
  7. 如果position指示的字符不是ASCII数字,则返回错误。

  8. 收集一系列代码点,这些代码点是input中给定positionASCII数字,并将结果序列解释为十进制整数。令value为该整数。

  9. 如果sign为“positive”,则返回value,否则返回从零减去value的结果。

2.3.4.2 非负整数

如果一个字符串由一个或多个ASCII数字组成,则该字符串是有效非负整数

一个有效非负整数表示由该数字字符串表示的十进制数。

解析非负整数的规则如下所示。当调用时,必须按给定顺序执行步骤,在返回值的第一个步骤中中止。该算法将返回零、正整数或错误。

  1. input为正在解析的字符串。

  2. value为使用解析整数的规则解析input的结果。

  3. 如果value是一个错误,则返回错误。

  4. 如果value小于零,则返回错误。

  5. 返回value

2.3.4.3 浮点数

如果一个字符串包含以下内容,则该字符串是有效浮点数

  1. 可选的U+002D HYPHEN-MINUS字符(-)。

  2. 以下两项之一或两项,按给定顺序:

    1. 一系列一个或多个ASCII数字

    2. 以下两项,按给定顺序:

      1. 一个单独的U+002E FULL STOP字符(.)。

      2. 一系列一个或多个ASCII数字

  3. 可选的:

    1. U+0065拉丁小写字母E字符(e)或U+0045拉丁大写字母E字符(E)。

    2. 可选的U+002D HYPHEN-MINUS字符(-)或U+002B PLUS SIGN字符(+)。

    3. 一系列一个或多个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获得特定值时,用户代理必须始终返回该值的相同字符串(尽管它可能与其他用户代理使用的值不同)。

解析浮点数值的规则如下所示。该算法必须在返回值的第一个步骤中中止。该算法将返回数字或错误。

  1. input为正在解析的字符串。

  2. position为指向input的指针,最初指向字符串的开头。

  3. value的值为1。

  4. divisor的值为1。

  5. exponent的值为1。

  6. 跳过ASCII空白,在input中给定position

  7. 如果position超过input的末尾,则返回错误。

  8. 如果position指示的字符是U+002D HYPHEN-MINUS字符(-):

    1. valuedivisor更改为-1。
    2. position前移到下一个字符。
    3. 如果position超过input的末尾,则返回错误。

    否则,如果position指示的字符(第一个字符)是U+002B PLUS SIGN字符(+):

    1. position前移到下一个字符。(“+”被忽略,但不符合规范。)
    2. 如果position超过input的末尾,则返回错误。
  9. 如果position指示的字符是U+002E FULL STOP(.),并且不是input中的最后一个字符,并且position指示的字符后的字符是ASCII数字,则 将value设为零并跳转到标记为fraction的步骤。

  10. 如果position指示的字符不是ASCII数字,则返回错误。

  11. 收集一系列代码点,这些代码点是ASCII数字,从input中给定position,并将结果序列解释为十进制整数。将value乘以该整数。

  12. 如果position超过input的末尾,则跳转到标记为conversion的步骤。
  13. Fraction:如果position指示的字符是U+002E FULL STOP(.),请运行这些子步骤:

    1. position前移到下一个字符。

    2. 如果position超过input的末尾,或者position指示的字符不是ASCII数字,U+0065拉丁小写字母E(e),或U+0045拉丁大写字母E(E),则跳转到标记为conversion的步骤。

    3. 如果position指示的字符是U+0065拉丁小写字母E字符(e)或U+0045拉丁大写字母E字符(E),则跳过这些子步骤的其余部分。

    4. Fraction loop:将divisor乘以10。

    5. 将由position指示的字符的值解释为十进制数字(0..9)并除以divisor,然后加到value
    6. position前移到下一个字符。

    7. 如果position超过input的末尾,则跳转到标记为conversion的步骤。

    8. 如果position指示的字符是ASCII数字,则跳回这些子步骤中标记为fraction loop的步骤。

  14. 如果position指示的字符是U+0065(e)或U+0045(E),则:

    1. position前移到下一个字符。

    2. 如果position超过input的末尾,则跳转到标记为conversion的步骤。

    3. 如果position指示的字符是U+002D HYPHEN-MINUS字符(-):

      1. exponent更改为-1。
      2. position前移到下一个字符。
      3. 如果position超过input的末尾,则跳转到标记为conversion的步骤。

      否则,如果position指示的字符是U+002B PLUS SIGN字符(+):

      1. position前移到下一个字符。
      2. 如果position超过input的末尾,则跳转到标记为conversion的步骤。

    4. 如果position指示的字符不是ASCII数字,则跳转到标记为conversion的步骤。

    5. 收集一系列代码点,这些代码点是ASCII数字,从input中给定position,并将结果序列解释为十进制整数。将exponent乘以该整数。

    6. value乘以10的exponent次方。

  15. Conversion:令S为一组有限的IEEE 754双精度浮点值,除了-0,但增加了两个特殊值:21024和-21024

  16. rounded-valueS中最接近value的数,如果有两个同样接近的值,则选择有效数字为偶数的数。(这两个特殊值21024和-21024被视为具有偶数有效数字)。

  17. 如果rounded-value是21024或-21024,则返回错误。

  18. 返回rounded-value

2.3.4.4 百分比和长度

解析尺寸值的规则如下所示。调用时,必须按给定顺序执行这些步骤,在返回值的第一个步骤中中止。该算法将返回大于或等于0.0的数字或失败;如果返回数字,则进一步分类为百分比或长度。

  1. input为正在解析的字符串。

  2. positioninput位置变量,最初指向input的开头。

  3. 跳过ASCII空白,在input中给定position

  4. 如果position超过input的末尾或inputposition处的代码点不是ASCII数字,则返回失败。

  5. 收集一系列代码点,这些代码点是ASCII数字,从input中给定position,并将结果序列解释为十进制整数。令value为该数字。

  6. 如果position超过input的末尾,则返回value作为长度。

  7. 如果inputposition处的代码点是U+002E (.),则:

    1. position前移1。

    2. 如果position超过input的末尾或inputposition处的代码点不是ASCII数字,则返回带有valueinputposition当前尺寸值

    3. divisor的值为1。

    4. 一直循环:

      1. divisor乘以10。

      2. inputposition处的代码点的值,解释为十进制数字(0..9)并除以divisor,加到value

      3. position前移1。

      4. 如果position超过input的末尾,则返回value作为长度。

      5. 如果inputposition处的代码点不是ASCII数字,则中止

  8. 返回带有valueinputposition当前尺寸值

给定valueinputposition,确定当前尺寸值如下:

  1. 如果position超过input的末尾,则返回value作为长度。

  2. 如果inputposition处的代码点是U+0025 (%),则返回value作为百分比。

  3. 返回value作为长度。

2.3.4.5 非零百分比和长度

解析非零尺寸值的规则如下所示。调用时,必须按给定顺序执行这些步骤,在返回值的第一个步骤中中止。该算法将返回大于0.0的数字或错误;如果返回数字,则进一步分类为百分比或长度。

  1. input为正在解析的字符串。

  2. value为使用解析尺寸值的规则解析input的结果。

  3. 如果value是错误,则返回错误。

  4. 如果value为零,则返回错误。

  5. 如果value是百分比,则返回value作为百分比。

  6. 返回value作为长度。

2.3.4.6 浮点数列表

一个有效的浮点数列表是由U+002C逗号字符分隔的多个有效的浮点数,不包含其他字符(例如没有ASCII空白字符)。此外,还可能对可以给出的浮点数的数量或允许的值范围有限制。

解析浮点数列表的规则如下:

  1. input为正在解析的字符串。

  2. positioninput中的一个指针,初始指向字符串的开始。

  3. numbers为一个初始为空的浮点数列表。该列表将是此算法的结果。

  4. 收集一系列代码点,这些代码点是input中的ASCII空白字符、U+002C逗号或U+003B分号字符,位置由position指示。此操作会跳过任何前导分隔符。

  5. position未越过input的末尾时:

    1. 收集一系列代码点,这些代码点不是ASCII空白字符、U+002C逗号、U+003B分号、ASCII数字、U+002E句号或U+002D连字符,位置由position指示。这会跳过前导的无效字符。

    2. 收集一系列代码点,这些代码点不是ASCII空白字符、U+002C逗号或U+003B分号字符,位置由position指示,并将结果命名为unparsed number

    3. 使用解析浮点数值的规则解析unparsed number,得到number

    4. 如果number是错误,则将number设为零。

    5. number附加到numbers中。

    6. 收集一系列代码点,这些代码点是input中的ASCII空白字符、U+002C逗号或U+003B分号字符,位置由position指示。这会跳过分隔符。

  6. 返回numbers

2.3.4.7 维度列表

解析维度列表的规则如下。这些规则返回零个或多个由一个数字和一个单位组成的对,其中单位可以是百分比相对绝对

  1. raw input为正在解析的字符串。

  2. 如果raw input的最后一个字符是U+002C逗号字符(,),则移除该字符。

  3. 按逗号分割字符串raw input。令raw tokens为结果的标记列表。

  4. result为一个空的数字/单位对列表。

  5. 对于raw tokens中的每个标记,运行以下子步骤:

    1. input为该标记。

    2. positioninput中的一个指针,初始指向字符串的开始。

    3. value为数字0。

    4. unit绝对

    5. 如果position已超出input的末尾,则将unit设为相对并跳至最后一个子步骤。

    6. 如果position处的字符是ASCII数字,则收集一系列代码点,这些代码点是input中的ASCII数字,将结果解释为一个以十进制表示的整数,并将value增加该整数。

    7. 如果position处的字符是U+002E(.),则:

      1. 收集一系列代码点,这些代码点由ASCII空白字符和ASCII数字组成,从input中给定position。令s为结果序列。

      2. 移除s中的所有ASCII空白

      3. 如果s不是空字符串,则:

        1. lengths中的字符数(删除空格后)。

        2. fraction为将s解释为一个十进制整数,然后将该数除以10length的结果。

        3. fraction加到value中。

    8. 跳过ASCII空白字符,在input中的position

    9. 如果position处的字符是U+0025百分号字符(%),则将unit设为百分比

      否则,如果position处的字符是U+002A星号字符(*),则将unit设为相对

    10. 将一个由value给定的数字和unit给定的单位组成的条目添加到result中。

  6. 返回列表result

2.3.5 日期和时间

在以下算法中,年份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元素。

2.3.5.1 月份

月份由一个特定的前置格里高利日期组成,没有时区信息,并且日期信息仅限于年份和月份。[GREGORIAN]

如果字符串包含以下顺序的组件,则表示一个年份year和月份month有效月份字符串

  1. 四个或更多ASCII数字,表示year,其中year > 0
  2. 一个U+002D连字符(-)
  3. 两个ASCII数字,表示month,范围为1 ≤ month ≤ 12

解析月份字符串的规则如下。这将返回一个年份和月份,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。

  1. input为要解析的字符串。

  2. position为指向input的指针,最初指向字符串的开始。

  3. 解析月份组件以获得yearmonth。如果返回为空,则失败。

  4. 如果position不在input的结尾之外,则失败。

  5. 返回yearmonth

解析月份组件的规则如下,给定一个input字符串和一个position。这将返回一个年份和月份,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。

  1. 收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不足四个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为year

  2. 如果year不是大于零的数值,则失败。

  3. 如果position超出input的结尾或position处的字符不是U+002D连字符,则失败。否则,将position前移一个字符。

  4. 收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不正好是两个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为month

  5. 如果month不是范围在1 ≤ month ≤ 12之间的数值,则失败。

  6. 返回yearmonth

2.3.5.2 日期

日期由一个特定的前置格里高利日期组成,没有时区信息,由年、月和日组成。[GREGORIAN]

如果字符串包含以下顺序的组件,则表示一个年份year、月份month和日期day有效日期字符串

  1. 一个有效月份字符串,表示yearmonth
  2. 一个U+002D HYPHEN-MINUS字符(-)
  3. 两个ASCII数字,表示day,范围为1 ≤ daymaxday,其中maxday该年该月中的天数

解析日期字符串的规则如下。这将返回一个日期,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。

  1. input为要解析的字符串。

  2. position为指向input的指针,最初指向字符串的开始。

  3. 解析日期组件以获得yearmonthday。如果返回为空,则失败。

  4. 如果position不在input的结尾之外,则失败。

  5. date为具有yearmonthday的日期。

  6. 返回date

解析日期组件的规则如下,给定一个input字符串和一个position。这将返回一个年份、月份和日期,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。

  1. 解析月份组件以获得yearmonth。如果返回为空,则失败。

  2. maxday为该年该月的天数

  3. 如果position超出input的结尾或position处的字符不是U+002D HYPHEN-MINUS字符,则失败。否则,将position前移一个字符。

  4. 收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不正好是两个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为day

  5. 如果day不是范围在1 ≤ daymaxday之间的数值,则失败。

  6. 返回yearmonthday

2.3.5.3 无年份的日期

无年份的日期由一个公历月份和该月份中的一天组成,但没有关联的年份信息。[GREGORIAN]

如果字符串包含以下顺序的组件,则表示一个月份month和日期day有效无年份日期字符串

  1. 可选的两个U+002D HYPHEN-MINUS字符(-)
  2. 两个ASCII数字,表示月份month,范围为1 ≤ month ≤ 12
  3. 一个U+002D HYPHEN-MINUS字符(-)
  4. 两个ASCII数字,表示日期day,范围为1 ≤ daymaxday,其中maxday是该月份的天数,以任意闰年(例如4或2000年)为准

换句话说,如果month是“02”,表示二月,那么日期可以是29日,就像该年份是闰年一样。

解析无年份日期字符串的规则如下。这将返回一个月份和日期,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。

  1. input为要解析的字符串。

  2. position为指向input的指针,最初指向字符串的开始。

  3. 解析无年份日期组件以获得monthday。如果返回为空,则失败。

  4. 如果position不在input的结尾之外,则失败。

  5. 返回monthday

解析无年份日期组件的规则如下,给定一个input字符串和一个position。这将返回一个月份和日期,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。

  1. 收集一系列码点,这些码点是input中的U+002D HYPHEN-MINUS字符(-),根据position。如果收集的序列长度不正好是零个或两个字符,则失败。

  2. 收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不正好是两个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为month

  3. 如果month不是范围在1 ≤ month ≤ 12之间的数值,则失败。

  4. maxday为该月份的天数,以任意闰年(例如4或2000年)为准。

  5. 如果position超出input的结尾或position处的字符不是U+002D HYPHEN-MINUS字符,则失败。否则,将position前移一个字符。

  6. 收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不正好是两个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为day

  7. 如果day不是范围在1 ≤ daymaxday之间的数值,则失败。

  8. 返回monthday

2.3.5.4 时间

时间由具体的时间组成,不包含时区信息,包括小时、分钟、秒和秒的小数部分。

如果字符串包含以下顺序的组件,则表示一个小时hour、分钟minute和秒second有效时间字符串

  1. 两个ASCII数字,表示hour,范围为0 ≤ hour ≤ 23
  2. 一个U+003A COLON字符(:)
  3. 两个ASCII数字,表示minute,范围为0 ≤ minute ≤ 59
  4. 如果second不为零,或可选地如果second为零:
    1. 一个U+003A COLON字符(:)
    2. 两个ASCII数字,表示second的整数部分,范围为0 ≤ s ≤ 59
    3. 如果second不是整数,或可选地如果second是整数:
      1. 一个U+002E FULL STOP字符(.)
      2. 一、二或三ASCII数字,表示second的小数部分

second组件不能为60或61;无法表示闰秒。

解析时间字符串的规则如下。这将返回一个时间或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。

  1. input为要解析的字符串。

  2. position为指向input的指针,最初指向字符串的开始。

  3. 解析时间组件以获得hourminutesecond。如果返回为空,则失败。

  4. 如果position不在input的结尾之外,则失败。

  5. time为具有小时hour、分钟minute和秒second的时间。

  6. 返回time

解析时间组件的规则如下,给定一个input字符串和一个position。这将返回一个小时、分钟和秒,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。

  1. 收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不正好是两个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为hour

  2. 如果hour不是范围在0 ≤ hour ≤ 23之间的数值,则失败。

  3. 如果position超出input的结尾或position处的字符不是U+003A COLON字符,则失败。否则,将position前移一个字符。

  4. 收集一系列码点,这些码点是input中的ASCII数字,根据position。如果收集的序列长度不正好是两个字符,则失败。否则,将结果序列解释为十进制整数。将该数值作为minute

  5. 如果minute不是范围在0 ≤ minute ≤ 59之间的数值,则失败。

  6. second为0。

  7. 如果position不在input的结尾之外且position处的字符是U+003A COLON字符(:),则:

    1. position前移至input中的下一个字符。

    2. 如果position超出input的结尾,或在input的最后一个字符,或如果position开始的两个字符都不是ASCII数字,则失败。

    3. 收集一系列码点,这些码点是input中的ASCII数字或U+002E FULL STOP字符。根据position。如果收集的序列长度为三字符,或如果它长于三字符并且第三个字符不是U+002E FULL STOP字符,或如果它包含多个U+002E FULL STOP字符,则失败。否则,将结果序列解释为十进制数(可能包含小数部分)。将second设置为该数值。

    4. 如果second不是范围在0 ≤ second < 60之间的数值,则失败。

  8. 返回hourminutesecond

2.3.5.5 本地日期和时间

本地日期和时间由一个特定的前置格里高利日期(包括年份、月份和日期)和一个时间(包括小时、分钟、秒和秒的小数部分)组成,但不包含时区信息。[GREGORIAN]

如果字符串包含以下顺序的组件,则表示日期和时间的有效本地日期和时间字符串

  1. 有效日期字符串,表示日期
  2. 一个U+0054拉丁大写字母T字符(T)或一个U+0020空格字符
  3. 有效时间字符串,表示时间

如果字符串包含以下顺序的组件,则表示日期和时间的有效规范化本地日期和时间字符串

  1. 有效日期字符串,表示日期
  2. 一个U+0054拉丁大写字母T字符(T)
  3. 有效时间字符串,表示时间,以给定时间的最短可能字符串表示(例如,如果时间为整分钟,则省略秒组件)

解析本地日期和时间字符串的规则如下。这将返回一个日期和时间,或不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。

  1. input为要解析的字符串。

  2. position为指向input的指针,最初指向字符串的开始。

  3. 解析日期组件以获得yearmonthday。如果返回为空,则失败。

  4. 如果position超出input的结尾或position处的字符既不是U+0054拉丁大写字母T字符(T)也不是U+0020空格字符,则失败。否则,将position前移一个字符。

  5. 解析时间组件以获得hourminutesecond。如果返回为空,则失败。

  6. 如果position不在input的结尾之外,则失败。

  7. date为具有年份year、月份month和日期day的日期。

  8. time为具有小时hour、分钟minute和秒second的时间。

  9. 返回datetime

2.3.5.6 时区

时区偏移由若干小时和分钟组成。

如果字符串符合以下任意一种情况,则表示一个有效的时区偏移字符串

此格式允许时区偏移范围为-23:59到+23:59。目前,实际时区的偏移范围为-12:00到+14:00,且偏移的分钟部分通常为00、30或45。然而,由于时区是政治因素的产物,可能会发生变化。

有关使用时区偏移表示历史时间的详细信息,请参阅全局日期和时间部分中的使用说明和示例。

解析时区偏移字符串的规则如下。这将返回一个时区偏移,或者不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。

  1. input为要解析的字符串。

  2. position为指向input的指针,最初指向字符串的开始。

  3. 解析时区偏移组件以获得timezonehourstimezoneminutes。如果返回无,则失败。

  4. 如果position未超出input的结尾,则失败。

  5. 返回与UTC相差timezonehours小时和timezoneminutes分钟的时区偏移。

解析时区偏移组件的规则如下,给定一个input字符串和一个position。这将返回时区小时和分钟,或者不返回任何内容。如果在任何时候算法指示“失败”,则意味着算法在该点中止并返回无。

  1. 如果position处的字符为U+005A拉丁大写字母Z字符(Z),则:

    1. timezonehours为0。

    2. timezoneminutes为0。

    3. position前移到input中的下一个字符。

    否则,如果position处的字符是U+002B加号(+)或U+002D连字符(-),则:

    1. 如果position处的字符是U+002B加号(+),则令sign为“positive”。否则,它是U+002D连字符(-);令sign为“negative”。

    2. position前移到input中的下一个字符。

    3. 收集position开始的inputASCII数字序列。令s为收集的序列。

    4. 如果s恰好为两个字符长,则:

      1. s解释为十进制整数。令该数为timezonehours

      2. 如果position超出input的结尾或position处的字符不是U+003A冒号字符,则失败。否则,将position前移一个字符。

      3. 收集position开始的inputASCII数字序列。如果收集的序列不恰好为两个字符长,则失败。否则,将结果序列解释为十进制整数。令该数为timezoneminutes

      如果s恰好为四个字符长,则:

      1. s的前两个字符解释为十进制整数。令该数为timezonehours

      2. s的后两个字符解释为十进制整数。令该数为timezoneminutes

      否则,失败。

    5. 如果timezonehours不在0≤timezonehours≤23范围内,则失败。
    6. 如果sign为“negative”,则将timezonehours取反。
    7. 如果timezoneminutes不在0≤timezoneminutes≤59范围内,则失败。
    8. 如果sign为“negative”,则将timezoneminutes取反。

    否则 ,失败。

  2. 返回timezonehourstimezoneminutes

2.3.5.7 全球日期和时间

全球日期和时间包括一个特定的 前置格里高利日期,包括年份、月份和日期,以及时间,包括小时、分钟、秒和秒的小数部分,用时区偏移量表示,包括一个带符号的小时数和分钟数。 [GREGORIAN]

如果一个字符串包含以下顺序的组件,则表示一个日期、时间和时区偏移量,它是一个有效的全球日期和时间字符串

  1. 一个表示日期的有效日期字符串
  2. 一个U+0054拉丁大写字母T字符(T)或一个U+0020空格字符
  3. 一个表示时间的有效时间字符串
  4. 一个表示时区偏移量的有效时区偏移字符串

在20世纪中期UTC形成之前的日期中的时间必须用UT1(在0°经度的当代地球太阳时间)表示和解释,而不是UTC(以SI秒计时的UT1的近似)。在时区形成之前的时间必须用显式时区的UT1时间表示和解释,这些时区近似于当代格林威治伦敦所在地时间和适当本地时间之间的差异。

以下是一些用有效全球日期和时间字符串书写的日期示例。

"0037-12-13 00:00Z"
尼禄(罗马皇帝)生日当天使用伦敦时间的午夜。关于这个日期实际上对应的时间见下文进一步讨论。
"1979-10-14T12:00:00.001-04:00"
1979年10月14日中午过一毫秒,位于美国东海岸使用夏令时的时区。
"8592-01-01T02:09+02:09"
8592年1月1日午夜UTC。该时间所关联的时区比UTC早两个小时九分钟,这目前不是一个真实的时区,但仍然是允许的。

这些日期有几个显著之处:

解析全球日期和时间字符串的规则如下。这将返回UTC时间,以及用于回溯或显示目的的相关时区偏移信息,或什么也不返回。如果算法中任何一点指出它"失败",这意味着它在该点中止并返回什么也没有。

  1. input成为被解析的字符串。

  2. position成为input中的一个指针,最初指向字符串的开始。

  3. 解析日期组件以获得yearmonthday。如果没有返回值,则失败。

  4. 如果position超出input的末尾或position处的字符既不是U+0054拉丁大写字母T字符(T),也不是U+0020空格字符,则失败。否则,将position向前移动一个字符。

  5. 解析时间组件以获得hourminutesecond。如果没有返回值,则失败。

  6. 如果position超出input的末尾,则失败。

  7. 解析时区偏移组件以获得timezonehourstimezoneminutes。如果没有返回值,则失败。

  8. 如果position不超出input的末尾,则失败。

  9. time成为year年、month月、day日、hour时、minute分、second秒的时间,减去timezonehours小时和timezoneminutes分钟。这个时间点是UTC时区的时间点。

  10. timezone成为比UTC快timezonehours小时和timezoneminutes分钟的时区偏移量。

  11. 返回timetimezone

2.3.5.8

由一个周年编号和一个周编号组成,表示一个从星期一开始的七天周期。在该日历系统中,每个周年有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,它是一个有效的周字符串

  1. 四个或更多的ASCII数字,表示year,其中year > 0
  2. 一个U+002D连字符(-)
  3. 一个U+0057拉丁大写字母W字符(W)
  4. 两个ASCII数字,表示周week,范围为1 ≤ week ≤ maxweek,其中maxweek是该周年的最后一天的周编号

解析周字符串的规则如下。这将返回一个周年编号和周编号,或者返回空值。如果在任何时候算法指示"失败",这意味着它在该点中止并返回空值。

  1. input为被解析的字符串。

  2. positioninput中的指针,最初指向字符串的开头。

  3. 收集一系列代码点,这些代码点是ASCII数字,从position处的input中收集。如果收集到的序列不超过四个字符,则失败。否则,将结果序列解释为十进制整数。令该数为year

  4. 如果year不是大于零的数字,则失败。

  5. 如果position超出input的末尾或position处的字符不是U+002D连字符,则失败。否则,将position向前移动一个字符。

  6. 如果position超出input的末尾或position处的字符不是U+0057拉丁大写字母W字符,则失败。否则,将position向前移动一个字符。

  7. 收集一系列代码点,这些代码点是ASCII数字,从position处的input中收集。如果收集到的序列不是恰好两个字符,则失败。否则,将结果序列解释为十进制整数。令该数为week

  8. maxweek为年份year的最后一天的周编号

  9. 如果week不是1 ≤ week ≤ maxweek范围内的数字,则失败。

  10. 如果position未超出input的末尾,则失败。

  11. 返回周年编号year和周编号week

2.3.5.9 持续时间

持续时间由若干秒组成。

由于月份和秒不可比较(一个月不是一个精确的秒数,而是一个其精确长度取决于从何时开始测量的时间段),本规范中定义的持续时间不能包括月份(或等同于十二个月的年份)。只能描述特定秒数的持续时间。

如果字符串符合以下任一形式,则表示持续时间t,且该字符串为有效持续时间字符串

解析持续时间字符串的规则如下。这将返回一个持续时间或返回空值。如果在任何时候算法指示"失败",这意味着它在该点中止并返回空值。

  1. input为被解析的字符串。

  2. positioninput中的指针,最初指向字符串的开头。

  3. monthssecondscomponent count均为零。

  4. M-disambiguatorminutes

    此标志的另一个值为months。它用于消除ISO8601持续时间中"M"单位的歧义,这些持续时间使用相同的单位表示月份和分钟。月份不允许,但解析为了未来的兼 容性,并避免误解在其他上下文中有效的ISO8601持续时间。

  5. 跳过ASCII空白字符input中给定position

  6. 如果position超出input的末尾,则失败。

  7. 如果inputposition指向的字符是U+0050拉丁大写字母P字符,则将position前进到下一个字符,将M-disambiguator设置为months,并跳过ASCII空白字符input中给定position

  8. 当条件为真时,执行以下操作:

    1. units未定义。它将被赋值为以下值之一:yearsmonthsweeksdayshoursminutesseconds

    2. next character未定义。它用于处理input中的字符。

    3. 如果position超出input的末尾,则中断。

    4. 如果inputposition指向的字符是U+0054拉丁大写字母T字符,则将position前进到下一个字符,将M-disambiguator设置为minutes跳过ASCII空白字符input中给定position,并继续

    5. next character设置为inputposition指向的字符。

    6. 如果next character是U+002E全停止符(.),则令N等于零。(不要前进position。稍后会处理这一点。)

      否则,如果next characterASCII数字,则收集一系列代码点,这些代码点是ASCII数字,从position处的input中收集,将结果序列解释为十进制整数,并将N设置为该数。

      否则,next character不是数字的一部分;失败。

    7. 如果position超出input的末尾,则失败。

    8. next character设置为inputposition指向的字符,并将position前进到下一个字符。(如果next character之前是U+002E全停止符(.),这次仍将是该字符。)

    9. 如果next character是U+002E(.),则:

      1. 收集一系列代码点,这些代码点是ASCII数字,从position处的input中收集。令s为结果序列。

      2. 如果s是空字符串,则失败。

      3. lengths中的字符数。

      4. fraction为将s解释为十进制整数,然后将该数除以10length的结果。

      5. N增加fraction

      6. 跳过ASCII空白字符input中给定position

      7. 如果position超出input的末尾,则失败。

      8. next character设置为inputposition指向的字符,并将position前进到下一个字符。

      9. 如果next character既不是U+0053拉丁大写字母S字符,也不是U+0073拉丁小写字母s字符,则失败。

      10. units设置为seconds

      否则:

      1. 如果next characterASCII空白字符,则跳过ASCII空白字符input中给定position,将next character设置为inputposition指向的字符,并将position前进到下一个字符。

      2. 如果next character是U+0059拉丁大写字母Y字符或U+0079拉丁小写字母y字符,将units设置为years,并将M-disambiguator设置为months

        如果next character是U+004D拉丁大写字母M字符或U+006D拉丁 小写字母m字符,并且M-disambiguatormonths,则将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-disambiguatorminutes,则将units设置为minutes

        如果next character是U+0053拉丁大写字母S字符或U+0073拉丁小写字母s字符,将units设置为seconds,并将M-disambiguator设置为minutes

        否则,如果next character不是上述任何一个字符,则失败。

    10. 增加component count

    11. multiplier为1。

    12. 如果unitsyears,则将multiplier乘以12,并将units设置为months

    13. 如果unitsmonths,则将Nmultiplier的乘积加到months中。

      否则:

      1. 如果unitsweeks,则将multiplier乘以7,并将units设置为days

      2. 如果unitsdays,则将multiplier乘以24,并将units设置为hours

      3. 如果unitshours,则将multiplier乘以60,并将units设置为minutes

      4. 如果unitsminutes,则将multiplier乘以60,并将units设置为seconds

      5. 最终,units现在是seconds。将Nmultiplier的乘积加到seconds中。

    14. 跳过ASCII空白字符input中给定position

  9. 如果component count为零,则失败。

  10. 如果months不为零,则失败。

  11. 返回由seconds秒组成的持续时间

2.3.5.10 更模糊的时间点

如果字符串也是以下之一,则该字符串是一个有效的包含可选时间的日期字符串


解析日期或时间字符串的规则如下。该算法将返回一个日期、一个时间、一个全球日期和时间,或什么都不返回。如果在任何时候算法说它“失败”,这意味着它在该点中止并返回什么都没有。

  1. input为正在解析的字符串。

  2. positioninput中的指针,最初指向字符串的开头。

  3. start position设置为与position相同的位置。

  4. date presenttime present标志设置为true。

  5. 解析日期组件以获取yearmonthday。如果解析失败,则将date present标志设置为false。

  6. 如果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相同的位置。

  7. 如果time present标志为true,则解析时间组件以获取hourminutesecond。如果解析失败,则失败。

  8. 如果date presenttime present标志都为true,但position超出input的末尾,则失败。

  9. 如果date presenttime present标志都为true,解析时区偏移组件以获取timezonehourstimezoneminutes。如果解析失败,则失败。

  10. 如果position没有超出input的末尾,则失败。

  11. 如果date present标志为true且time present标志为false,则令date为具有yearmonthday的日期,并返回date

    否则,如果time present标志为true且date present标志为false,则令time为具有hourminutesecond的时间,并返回time

    否则,令time为年year、月month、日day、小时hour、分钟minute、秒second的时间减去timezonehours小时和timezoneminutes分钟,该时间点为UTC时区的时间点;令timezone为距离UTC的timezonehours小时和timezoneminutes分钟;并返回timetimezone

2.3.6 颜色

一个简单颜色由三个范围在0到255(含)之间的8位数字组成,分别代表颜色的红色、绿色和蓝色分量,在'srgb'颜色空间中。

如果字符串长度正好为七个字符,且第一个字符是U+0023号码符号字符(#),并且剩下的六个字符都是ASCII十六进制数字,那么该字符串是有效的简单颜色,其中前两个数字代表红色分量,中间两个数字代表绿色分量,最后两个数字代表蓝色分量,采用十六进制表示。

如果一个字符串是有效的简单颜色且不使用范围在U+0041拉丁大写字母A到U+0046拉丁大写字母F之间的任何字符,则该字符串是有效的小写简单颜色

解析简单颜色值的规则如下。在调用时,必须按给定顺序执行这些步骤,在第一个返回值的步骤处中止。该算法将返回一个简单颜色或错误。

  1. input为正在解析的字符串。

  2. 如果input长度不是正好七个字符,则返回错误。

  3. 如果input的第一个字符不是U+0023号码符号字符(#),则返回错误。

  4. 如果input的最后六个字符不是全部为ASCII十六进制数字,则返回错误。

  5. result为一个简单颜色

  6. 将第二个和第三个字符解释为十六进制数字,并将结果作为result的红色分量。

  7. 将第四个和第五个字符解释为十六进制数字,并将结果作为result的绿色分量。

  8. 将第六个和第七个字符解释为十六进制数字,并将结果作为result的蓝色分量。

  9. 返回result

给定一个简单颜色序列化简单颜色值的规则如下:

  1. result为一个由单个U+0023号码符号字符(#)组成的字符串。

  2. 将红色、绿色和蓝色分量依次转换为两位十六进制数字,使用ASCII小写十六进制数字,必要时进行零填充,并按红色、绿色、蓝色的顺序将这些数字附加到result

  3. 返回result,它将是一个有效的小写简单颜色


一些过时的遗留属性以更复杂的方式解析颜色,使用解析遗留颜色值的规则,如下算法所示。在调用时,必须按给定顺序执行这些步骤,在第一个返回值的步骤处中止。该算法将返回一个简单颜色或错误。

  1. input为正在解析的字符串。

  2. 如果input为空字符串,则返回错误。

  3. 去除input的前导和尾随ASCII空白字符

  4. 如果input与字符串"transparent"进行ASCII大小写不敏感匹配,则返回错误。

  5. 如果input与其中一个命名颜色进行ASCII大小写不敏感匹配,则返回与该关键字对应的简单颜色[CSSCOLOR]

    CSS2系统颜色不被识别。

  6. 如果input代码点长度为四,并且input的第一个字符是U+0023(#),并且input的最后三个字符都是ASCII十六进制数字,则:

    1. result为一个简单颜色

    2. input的第二个字符解释为十六进制数字;令result的红色分量为结果数字乘以 17。

    3. input的第三个字符解释为十六进制数字;令result的绿色分量为结果数字乘以17。

    4. input的第四个字符解释为十六进制数字;令result的蓝色分量为结果数字乘以17。

    5. 返回result

  7. input中所有代码点大于U+FFFF的字符(即任何不在基本多语言平面中的字符)替换为两个字符的字符串"00"。

  8. 如果input代码点长度大于128,则截断input,只保留前128个字符。

  9. 如果input的第一个字符是U+0023号码符号字符(#),则将其移除。

  10. input中任何不是ASCII十六进制数字的字符替换为U+0030数字零字符(0)。

  11. input代码点长度为零或不是三的倍数时,将U+0030数字零字符(0)附加到input

  12. input拆分为三个相等代码点长度的字符串,以获得三个组件。令length为所有这些组件的代码点长度input的代码点长度的三分之一)。

  13. 如果length大于8,则删除每个组件中前length-8个字符,并将length设置为8。

  14. length大于两个并且每个组件的第一个字符是U+0030数字零字符(0)时,移除该字符并减少length

  15. 如果length仍大于两个,则截断每个组件,只保留每个组件的前两个字符。

  16. result为一个简单颜色

  17. 将第一个组件解释为十六进制数字;令result的红色分量为结果数字。

  18. 将第二个组件解释为十六进制数字;令result的绿色分量为结果数字。

  19. 将第三个组件解释为十六进制数字;令result的蓝色分量为结果数字。

  20. 返回result


2D图形上下文有一个单独的颜色语法,也处理不透明度。

2.3.7 空格分隔的标记

一个 空格分隔的标记集 是一个包含零个或多个单词(称为标记)的字符串,这些单词由一个或多个 ASCII 空白字符 分隔,其中单词由一个或多个字符组成,这些字符都不是 ASCII 空白字符

一个包含 空格分隔的标记集 的字符串可以有前导或尾随的 ASCII 空白字符

一个 无序的唯一空格分隔标记集 是一个 空格分隔的标记集,其中的标记没有重复。

一个 有序的唯一空格分隔标记集 是一个 空格分隔的标记集,其中的标记没有重复,但标记的顺序是有意义的。

空格分隔的标记集 有时具有定义的允许值集合。当定义了允许值集合时,标记必须全部来自该允许值列表;其他值不符合规范。如果没有提供这样的允许值集合,则所有值都是符合规范的。

如何比较 空格分隔的标记集 中的标记(例如,区分大小写或不区分大小写)是按集合来定义的。

2.3.8 逗号分隔的标记

一个 逗号分隔的标记集 是一个包含零个或多个标记的字符串,每个标记之间用一个 U+002C 逗号字符(,)分隔,其中标记由零个或多个字符组成,既不以 ASCII 空白字符 开头或结尾,也不包含任何 U+002C 逗号字符(,),并且可以选择性地被 ASCII 空白字符 包围。

例如,字符串 " a ,b,,d d " 由四个标记组成:"a","b",空字符串和 "d d"。每个标记周围的前导和尾随空白字符不计入标记的一部分,并且空字符串可以是一个标记。

逗号分隔的标记集 有时对有效标记的构成有进一步的限制。当定义了这些限制时,标记必须全部符合这些限制;其他值是不符合规范的。如果没有规定这样的限制,则所有值都是符合规范的。

2.3.9 引用

一个 有效的哈希名称引用 到一个类型为 type 的元素,是一个包含 U+0023 数字符号字符 (#) 后跟一个与同一个 中类型为 type 的元素的 name 属性值完全匹配的字符串。

给定上下文节点 scope,解析类型为 type 的元素的哈希名称引用的 规则 如下:

  1. 如果被解析的字符串不包含 U+0023 数字符号字符,或者如果字符串中的第一个这样的字符是字符串中的最后一个字符,则返回 null。

  2. s 成为从被解析字符串中第一个 U+0023 数字符号字符之后的字符到字符串末尾的字符串。

  3. 返回 scope 中按 树顺序 排列的第一个类型为 type 且其 idname 属性的值为 s 的元素,如果没有这样的元素,则返回 null。

    尽管在解析时会考虑 id 属性,但它们不会用于确定一个值是否为 有效的 哈希名称引用。也就是说,基于 id 引用元素的哈希名称引用是一个一致性错误(除非该元素也有一个具有相同值的 name 属性)。

2.3.10 媒体查询

如果字符串符合 Media Queries<media-query-list> 生成规则,则该字符串是一个 有效的媒体查询列表[MQ]

如果字符串为空字符串、仅包含 ASCII 空白字符,或是一个根据 Media Queries 中定义的符合用户环境的媒体查询列表,则该字符串 符合用户环境[MQ]

2.3.11 唯一内部值

一个 唯一内部值 是一个可序列化、按值可比较且从不暴露给脚本的值。

要创建一个 新的唯一内部值,返回一个从未被此算法返回过的 唯一内部值

2.4 URLs

2.4.1 术语

如果字符串是一个 有效的 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,用作 URLiframe srcdoc 文档[ABOUT]

备用基础 URL文档 对象 documentURL 记录,通过执行以下步骤获得:

  1. 如果 document一个 iframe srcdoc 文档,则:

    1. 断言documentabout 基础 URL 非空。

    2. 返回 documentabout 基础 URL

  2. 如果 documentURL 匹配 about:blank 并且 documentabout 基础 URL 非空,则返回 documentabout 基础 URL

  3. 返回 documentURL

文档基础 URL文档 对象的 URL 记录,通过执行以下步骤获得:

  1. 如果 base 元素在 文档 中没有 href 属性,则返回 文档备用基础 URL

  2. 否则,返回 base 元素中第一个具有 href 属性的 文 档冻结基础 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

2.4.2 解析 URL

解析 URL 是将一个字符串转换为其表示的 URL 记录 的过程。虽然这个过程在 URL 中有定义,但 HTML 标准定义了几个封装器来抽象基础 URL 和编码。[URL]

大多数新的 API 应该使用 解析 URL。较旧的 API 和 HTML 元素可能需要使用 编码解析 URL。当需要自定义基础 URL 或不希望使用基础 URL 时,URL 解析器 也可以直接使用。

解析 URL,给定一个字符串 url,相对于 文档 对象或 环境设置对象 environment,执行以下步骤。这些步骤返回失败或一个 URL

  1. baseURLenvironment基础 URL,如果 environment 是一个 文档 对象;否则为 environmentAPI 基础 URL

  2. 返回应用于 urlURL 解析器 的结果,使用 baseURL

编码解析 URL,给定一个字符串 url,相对于一个 文档 对象或 环境设置对象 environment,执行以下步骤。这些步骤返回失败或一个 URL

  1. encodingUTF-8

  2. 如果 environment 是一个 文档 对象,则将 encoding 设置为 environment字符编码

  3. 否则,如果 environment相关全局对象 是一个 Window 对象,将 encoding 设置为 environment相关全局对象关联 Document字符编码

  4. baseURLenvironment基础 URL,如果 environment 是一个 文档 对象;否则为 environmentAPI 基础 URL

  5. 返回应用于 urlURL 解析器 的结果,使用 baseURLencoding

编码解析并序列化 URL,给定一个字符串 url,相对于一个 文档 对象或 环境设置对象 environment,执行以下步骤。这些步骤返回失败或一个字符串。

  1. url编码解析 URL 的结果,给定 url,相对于 environment

  2. 如果 url 失败,则返回失败。

  3. 返回应用于 urlURL 序列化器 的结果。

2.4.3 基础 URL 的动态更改

当文档的 文档基础 URL 更改时,该文档中的所有元素 都会 受到基础 URL 更改的影响

以下是 基础 URL 更改步骤,当元素 受到基础 URL 更改的影响(如 DOM 定义的)时执行:

如果元素创建了一个 超链接

如果超链接标识的 URL 正显示给用户,或者任何从该 URL 派生的数据影响了显示,则 href 属性的值应该 重新解析,相对于元素的 节点文档,并且 UI 应适当更新。

例如,CSS :link/:visited 伪类 可能已经受到影响。

如果超链接具有 ping 属性 并且其 URL(s) 正显示给用户,则 ping 属性的标记应该 重新解析,相对于元素的 节点文档,并且 UI 应适当更新。

如果元素是一个 qblockquoteins, 或 del 元素,且具有 cite 属性

如果 URL 标识的 cite 属性正在显示给用户,或者任何从该 URL 派生的数据影响了显示, 则 cite 属性的值应该 重新解析,相对于元素的 节点文档,并且 UI 应适当更新。

否则

该元素不会直接受到影响。

例如,更改基础 URL 不会影响 img 元素显示的图像,尽管从脚本中对 src IDL 属性的后续访问将返回一个新的 绝对 URL,可能不再对应于正在显示的图像。

2.5 获取资源

2.5.1 术语

一个 响应 如果其 类型 为 "basic"、"cors" 或 "default",则称为 CORS-同源[FETCH]

一个 响应 如果其 类型 为 "opaque" 或 "opaqueredirect",则称为 CORS-跨源

一个 响应不安全响应 是其 内部响应,如果有的话,否则就是该 响应 本身。

创建一个潜在的 CORS 请求,给定一个 urldestinationcorsAttributeState 和一个可选的 同源回退标志,执行以下步骤:

  1. 如果 corsAttributeState无 CORS,则让 mode 为 "no-cors",否则为 "cors"。

  2. 如果 同源回退标志 被设置且 mode 为 "no-cors",则将 mode 设置为 "same-origin"。

  3. credentialsMode 为 "include"。

  4. 如果 corsAttributeState匿名,则将 credentialsMode 设置为 "same-origin"。

  5. request 为一个新的 请求,其 URLurl目的地destination模式mode凭证模式credentialsMode,且 使用 URL 凭证标志 被设置。

2.5.2 确定资源类型

资源的 内容类型元数据 必须以与 MIME Sniffing 要求一致的方式获取和解释。 [MIMESNIFF]

资源的 计算 MIME 类型 必须以与 MIME Sniffing 要求一致的方式确定。[MIMESNIFF]

对于 图像的嗅探规则区分资源是文本还是二进制的规则音频和视频的嗅探规则 也在 MIME Sniffing 中定义。这些规则返回一个 MIME 类型 作为结果。[MIMESNIFF]

务必严格遵守 MIME Sniffing 中的规则。当用户代理使用不同于服务器预期的内容类型检测启发式方法时,可能会发生安全问题。更多详细信息,请参见 MIME Sniffing[MIMESNIFF]

2.5.3meta 元素中提取字符编码

给定一个字符串 s,从 meta 元素中提取字符编码的 算法 如下。它要么返回一个字符编码,要么返回无结果。

  1. position 为指向 s 的指针,初始时指向字符串的开始。

  2. 循环: 找到 position 之后的 s 中前七个字符中与单词 "charset" 的 ASCII 不区分大小写 匹配的第一个字符。如果没有找到这样的匹配,返回无结果。

  3. 跳过紧跟在单词 "charset" 之后的任何 ASCII 空白字符(可能没有)。

  4. 如果下一个字符不是 U+003D 等号 (=),则将 position 移动到指向该下一个字符之前,并返回到标记为 循环 的步骤。

  5. 跳过紧跟在等号之后的任何 ASCII 空白字符(可能没有)。

  6. 处理下一个字符如下:

    如果它是一个 U+0022 引号字符 ("),并且在 s 中存在一个后续的 U+0022 引号字符 (")
    如果它是一个 U+0027 单引号字符 ('),并且在 s 中存在一个后续的 U+0027 单引号字符 (')
    返回从该字符到下一个最早出现的相同字符的子字符串的 编码获取结果
    如果它是一个未配对的 U+0022 引号字符 (")
    如果它是一个未配对的 U+0027 单引号字符 (')
    如果没有下一个字符
    返回无结果。
    否则
    返回从该字符到第一个 ASCII 空白字符 或 U+003B 分号字符 (;),或 s 的结束(以最早到达者为准)的子字符串的 编码获取结果

该算法与 HTTP 规范中的那些算法不同(例如,HTTP 不允许使用单引号,并且要求支持一个不被该算法支持的反斜杠转义机制)。虽然该算法用于历史上与 HTTP 相关的上下文中,但实现所支持的语法已经有一段时间偏离。[HTTP]

2.5.4 CORS 设置属性

Attributes/crossorigin

在所有当前引擎中均受支持。

Firefox8+Safari6+Chrome13+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

CORS 设置属性 是一个 枚举属性, 具有以下关键字和状态:

关键字 状态 简要描述
anonymous 匿名 对元素的请求 将其 模式 设置为 "cors",并将其 凭证模式 设置为 "same-origin"。
(空字符串)
use-credentials 使用凭证 对元素的请求 将其 模式 设置为 "cors",并将其 凭证模式 设置为 "include"。

该属性的 缺失值默认值无 CORS 状态,其 无效值默认值匿名 状态。为了 反射 的目的,规范关键字匿名 状态是 anonymous 关键字。

大多数受 CORS 设置属性 管辖的请求将通过 创建潜在 CORS 请求 算法进行。

对于更现代的功能,其中请求的 模式 始终为 "cors",某些 CORS 设置属性 已被重新定义为具有略有不同的含义,其中它们仅影响 请求凭证模式。为了进行此转换,我们定义 CORS 设置属性凭证模式 为通过切换属性状态来确定:

无 CORS
匿名
"same-origin"
使用 凭证
"include"

2.5.5 引荐政策属性

引荐政策属性 是一个 枚举属性。每个 引荐政策, 包括空字符串,都是该属性的关键字,对应一个同名的状态。

该属性的 缺失值默认值无效值默认值 都是空字符串状态。

这些状态对各种 fetch 请求 的处理模型的影响在本规范中有更详细的定义,包括 FetchReferrer Policy[FETCH] [REFERRERPOLICY]

几个信号可以影响用于给定 fetch 请求 的处理模型;引荐政策属性 只是其中之一。通常,这些信号的处理顺序为:

  1. 首先,存在一个 noreferrer 链接类型;

  2. 然后是 引荐政策属性 的值;

  3. 然后是任何带有 meta 元素,并且 name 属性设置为 referrer

  4. 最后是 `Referrer-Policy` HTTP 头部。

2.5.6 Nonce 属性

Global_attributes/nonce

所有当前引擎都支持。

Firefox31+SafariChrome
Opera?Edge
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

nonce 内容 属性表示一个加密 nonce(“仅使用一次的数字”),可以由 内容安全策略 用来决定是否允许给定的 fetch 请求继续进行。其值为文本。[CSP]

具有 nonce 内容属性的元素 确保加密 nonce 只暴露给脚本(而非通过 CSS 属性选择器等侧信道)。它通过从内容属性中获取值,将其移动到一个名为 [[CryptographicNonce]] 的内部插槽中,通过 HTMLOrSVGElement 接口混合来暴露给脚本,并将内容属性设置为空字符串。除非另有说明,插槽的值为空字符串。

element.nonce

返回 element 的加密 nonce 的值。如果没有使用 setter,这将是原始的 nonce 内容属性中的值。

element.nonce = value

更新 element 的加密 nonce 值。

HTMLElement/nonce

Firefox75+Safari🔰 10+Chrome61+
Opera?Edge79+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

nonce IDL 属性必须在获取时返回该元素的 [[CryptographicNonce]] 的值;在设置时,将该元素的 [[CryptographicNonce]] 设置为给定的值。

注意,nonce IDL 属性的 setter 不会更新对应的内容属性。这以及当一个元素 变为浏览上下文连接 时将 nonce 内容属性设置为空字符串,是为了防止通过容易读取内容属性的机制(如选择器)泄露 nonce 值。了解更多信息请参见 问题 #2369,该行为在此处被引入。

以下 属性更改步骤 适用于 nonce 内容属性:

  1. 如果 element 包含 HTMLOrSVGElement, 则返回。

  2. 如果 localName 不是 noncenamespace 不为 null,则返回。

  3. 如果 value 为 null,则将 element[[CryptographicNonce]] 设置为空字符串。

  4. 否则,将 element[[CryptographicNonce]] 设置为 value

每当一个元素 包含 HTMLOrSVGElement 变为浏览上下文连接 时,用户代理必须对 element 执行以下步骤:

  1. CSP listelementshadow-including root策略容器CSP list

  2. 如果 CSP list 包含一个头部传递的内容安全策略,并且 element 具有一个 nonce 内容 属性 attr,其值不是空字符串,则:

    1. nonceelement[[CryptographicNonce]]

    2. 设置属性值element 使用 "nonce" 和空字符串。

    3. element[[CryptographicNonce]] 设置为 nonce

    如果 element[[CryptographicNonce]] 没有恢复,那么在此时它将是空字符串。

对于 包含 HTMLOrSVGElement 的元素,克隆步骤必须将副本上的 [[CryptographicNonce]] 插槽设置为元素被克隆时插槽的值。

2.5.7 延迟加载属性

延迟加载

所有当前引擎都支持。

Firefox75+Safari15.4+Chrome77+
Opera?Edge79+
Edge(旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

一个 延迟加载属性 是一个 枚举属性, 具有以下关键字和状态:

关键字 状态 简要描述
lazy 延迟 用于在满足某些条件之前推迟获取资源。
eager 立即 用于立即获取资源;默认状态。

该属性指示用户代理立即获取资源,或根据属性的当前状态,在满足与元素相关的一些条件之后再获取资源。

该属性的 缺失值默认值无效值默认值 都是 立即 状态。


对于给定的元素 element将延迟加载元素步骤 如下:

  1. 如果 脚本功能被禁用,则返回 false。

    这是一个反跟踪措施,因为如果用户代理在脚本功能被禁用时仍支持延迟加载,那么一个网站可以通过在页面的标记中战略性地放置图像,以便服务器可以跟踪请求的图像数量及其时间,从而在整个会话中跟踪用户的大致滚动位置。

  2. 如果 element延迟加载属性 处于 延迟 状态,则返回 true。

  3. 返回 false。

每个 imgiframe 元素都有相关的 延迟加载恢复步骤,最初为 null。

对于那些 将延迟加载imgiframe 元素,这些步骤会在 延迟加载交叉观察器 的回调中运行,或当其 延迟加载属性 设置为 立即 状态时。这会导致元素继续加载。

每个 文档 都有一个 延迟加载交叉观察器,最初设置为 null,但可以设置为一个 IntersectionObserver 实例。

开始交叉观察一个延迟加载元素 element,执行以下步骤:

  1. doc 设为 element节点文档

  2. 如果 doc延迟加载交叉观察器 为 null, 将其设置为一个新的 IntersectionObserver 实例,初始化如下:

    意图是使用 IntersectionObserver 构造函数的原始值。然而,我们被迫使用本规范中的 JavaScript 暴露构造函数,直到 Intersection Observer 为规范中的使用提供低级钩子。请参见跟踪此问题的 bug w3c/IntersectionObserver#464[INTERSECTIONOBSERVER]

  3. 调用 doc延迟加载交叉观察器observe 方法,以 element 作为参数。

    意图是使用 observe 方法的原始值。参见 w3c/IntersectionObserver#464[INTERSECTIONOBSERVER]

停止交叉观察延迟加载元素 element,执行以下步骤:

  1. doc 设为 element节点文档

  2. 断言doc延迟加载交叉观察器 不为 null。

  3. 调用 doc延迟加载交叉观察器unobserve 方法,以 element 作为参数。

    意图是使用 unobserve 方法的原始值。参见 w3c/IntersectionObserver#464[INTERSECTIONOBSERVER]

(这是一个跟踪向量。) 延迟加载滚动边距 是一个 实现定义 的值,但有以下建议供参考:

为了 保护隐私延迟加载滚动边距 不应泄露额外的信息。例如,当前设备的典型滚动速度可能不够精确,以免引入新的指纹识别向量。

2.5.8 阻塞属性

阻塞属性 明确表示在获取外部资源时应阻止某些操作。这些操作可以被阻止的由 可能的阻塞令牌 表示,这些令牌以字符串形式列于下表:

可能的阻塞令牌 描述
"render" 该元素是 可能阻塞渲染 的。

将来可能会有更多的 可能的阻塞令牌

一个 阻塞属性 必须具有一个值,该值是一个 唯一的以空格分隔的令牌无序集合,每个令牌都是 可能的阻塞令牌。一个 支持的令牌可能的阻塞令牌。任何元素最多只能有一个 阻塞属性

阻塞令牌集 是针对一个元素 el 的以下步骤的结果:

  1. valueel阻塞属性 的值,如果不存在这样的属性,则为 空字符串。

  2. value 转换为 ASCII 小写

  3. rawTokens按 ASCII 空白字符分割 value 的结果。

  4. 返回一个包含 rawTokens 中所有 可能的阻塞令牌 的集合。

一个元素如果其 阻塞令牌集 包含 "render", 或者如果它是 隐式潜在渲染阻塞 的,这将在各个元素中定义。 默认情况下,元素不是 隐式潜在渲染阻塞 的。

2.5.9 获取优先级属性

获取优先级属性 是一个 枚举属性, 具有以下关键字和状态:

关键字 状态 简要描述
high high 表示相对于其他具有相同 目的地 的资源,这是一个高优先级的 获取 操作。
low low 表示相对于其他具有相同 目的地 的资源,这是一个低优先级的 获取 操作。
auto auto 表示自动确定相对于其他具有相同 目的地获取 优先级。

该属性的 缺失值默认值无效值默认值 都是 auto 状态。

2.6 常见 DOM 接口

2.6.1 在 IDL 属性中反射内容属性

反射的构建块如下:

反射 IDL 属性 可以被定义为 反射 反射内容属性名称反射目标。通常,这意味着 IDL 属性的 getter 返回内容属性的当前值,setter 则将内容属性的值更改为给定值。

如果 反射目标 是一个元素,则 反射 IDL 属性 还可以声明 支持 ElementInternals。这意味着 ElementInternals 接口也有一个 反射 IDL 属性,具有相同的标识符,并且该 反射 IDL 属性 反射 相同的 反射内容属性名称

fooBar IDL 属性必须 反射 foobar 内容属性,并且 支持 ElementInternals

反射目标 具有以下关联算法:

对于一个 反射目标,如果它是一个元素 element,这些算法定义如下:

获取元素
  1. 返回 element

获取内容属性
  1. attribute 为运行 按命名空间和本地名称获取属性 的结果, 传入 null、反射内容属性名称element

  2. 如果 attribute 为 null,则返回 null。

  3. 返回 attribute

设置内容属性 使用字符串 value
  1. 设置属性值,传入 element反射内容属性名称value

删除内容属性
  1. 按命名空间和本地名称删除属性, 传入 null、反射内容属性名称element

对于一个 反射目标,如果它是一个 ElementInternals 对象 elementInternals,这些算法定义如下:

获取元素
  1. 返回 elementInternals目标元素

获取内容属性
  1. 如果 elementInternals目标元素内部内容属性映射[反射内容属性名称] 不存在,则返回 null。

  2. 返回 elementInternals目标元素内部内容属性映射[反射内容属性名称]。

设置内容属性 使用字符串 value
  1. 设置 elementInternals目标元素内部内容属性映射[反射内容属性名称] 为 value

删除内容属性
  1. 移除 elementInternals目标元素内部内容属性映射[反射内容属性名称]。

这会导致 ElementInternals 对象出现一些冗余的数据结构,因为其 目标元素内部内容属性映射 不能直接操作,因此反射只发生在单向。这种方法尽管如此,仍被选择以减少定义在 反射目标 之间共享的 IDL 属性的错误,并从通用 API 语义中受益。


类型为 DOMStringDOMString? 的 IDL 属性如果 反射 枚举 内容属性,则可以 限制为仅已知值。 根据下面的处理模型,这些将导致这些 IDL 属性的 getter 仅返回这些枚举属性的关键字,或者空字符串或 null。

如果一个 反射的 IDL 属性 的 类型为 DOMString

如果一个 反射的 IDL 属性 的类型是 DOMString?

如果一个 反射的 IDL 属性 的类型是 USVString

如果一个 反射的 IDL 属性 的类型是 boolean

这对应于 布尔内容属性 的规则。

If a 反射的 IDL 属性 的类型是 long, 可选地 限制为非负数 并且可选地具有 默认值 defaultValue

如果一个 反射的 IDL 属性 的类型是 unsigned long, 可选地 限制为仅正数限制为仅正数(带回退),或 夹紧到范围 [clampedMinclampedMax],并且可选地具有 默认值 defaultValue

如果一个 反射的 IDL 属性 的类型是 double, 可选地 限制为仅正数,并且可选地具有 默认值 defaultValue

值 Infinity 和 Not-a-Number (NaN) 在设置时会抛出异常,如 Web IDL 中定义。[WEBIDL]

如果一个 反射的 IDL 属性 的类型是 DOMTokenList, 那么它的 getter 步骤是返回一个 DOMTokenList 对象,其关联的元素是 this,关联属性的本地名称是 反射的内容属性名称。规范作者不能使用 支持 ElementInternals 来处理此类型的 IDL 属性。

如果一个 反射的 IDL 属性 的类型是 T?, 其中 TElement 或从 Element 继承的接口,则 attr反射的内容属性名称

反射的 IDL 属性 这种类型的属性强烈建议其标识符以 "Element" 结尾,以保持一致性。

如果一个 反射的 IDL 属性 的类型是 FrozenArray<T>?,其中 TElement 或一个继承自 Element 的接口,那么对于 attr 作为 反射的内容属性名称

反射的 IDL 属性 强烈建议其标识符以 "Elements" 结尾,以保持一致性。

2.6.2 在规范中使用 reflect

反射 主要是通过给开发者提供通过 反射的 IDL 属性 类型访问内容属性,以改善开发者的使用体验。网页平台的最终事实来源是内容属性本身。也就是说,规范作者不能使用 反射的 IDL 属性 的 getter 或 setter 步骤,而应使用内容属性的存在和值。(或其上的抽象,如 枚举属性 的状态。)

两个重要的例外是 反射的 IDL 属性 其类型是以下之一:

对于这些情况,规范作者必须使用 反射目标获取 attr-关联元素获取 attr-关联元素 的步骤。内容属性的存在和值不应使用,因为它们不能完全与 反射的 IDL 属性 同步。

反射目标显式设置的 attr-元素显式设置的 attr-元素缓存的 attr-关联元素缓存的 attr-关联元素对象 应被视为内部实现细节,而不应基于它们进行构建。

2.6.3 集合

HTMLFormControlsCollectionHTMLOptionsCollection 接口是从 HTMLCollection 接口派生的 集合HTMLAllCollection 接口是一个集合,但不是这样派生的。

2.6.3.1 HTMLAllCollection 接口

HTMLAllCollection 接口用于遗留的 document.all 属性。它的操作类似于 HTMLCollection;主要区别在于它允许各种不同的(滥用)方法返回一些内容,并且它可以作为函数调用,而不是属性访问。

所有 HTMLAllCollection 对象都根植于 Document,并具有匹配所有元素的过滤器,因此 由集合表示 的元素 HTMLAllCollection 对象由根 Document 的所有后代元素组成。

实现 HTMLAllCollection 接口的对象是 遗留平台对象,具有附加的 [[Call]] 内部方法,如下面部分所述。它们还具有 [[IsHTMLDDA]] 内部槽。

实现 HTMLAllCollection 接口的对象有几个不寻常的行为,因为它们具有 [[IsHTMLDDA]] 内部槽:

这些特殊行为是为了兼容两类遗留内容:一类是使用 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 属性的非空值,这些元素 由集合表示,按 树顺序,忽略后续的重复项,如果一个元素同时提供 idname 且它们不同且都不是早期条目的重复项,则 idname 之前。

length 的 getter 步骤是返回 由集合表示 的节点数。

索引属性 getter 必须返回通过给定传递的索引 获取“全部”索引的元素 的结果 this

namedItem(name) 方法步骤是返回 获取“全部”命名的元素 的结果 this 给定 name

item(nameOrIndex) 方法步骤是:

  1. 如果未提供 nameOrIndex,则返回 null。

  2. 返回 获取“全部”索引或命名的元素 的结果 this 给定 nameOrIndex


以下元素是 “全部”命名元素abuttonembedformframeframesetiframeimginputmapmetaobjectselect,以及textarea

HTMLAllCollection collection获取“全部”索引的元素 给定索引 index,返回 collection 中的第 index 个元素,如果没有这样的 index 个元素,则返回 null。

HTMLAllCollection collection获取“全部”命名的元素 给定名称 name,执行以下步骤:

  1. 如果 name 是空字符串,则返回 null。

  2. subCollection 成为一个 HTMLCollection 对象,它以与 collection 相同的 Document 为根,其过滤器仅匹配以下任一元素:

  3. 如果 subCollection 中只有一个元素,则返回该元素。

  4. 否则,如果 subCollection 为空,则返回 null。

  5. 否则,返回 subCollection

HTMLAllCollection collection获取“全部”索引或命名的元素 给定 nameOrIndex

  1. 如果 nameOrIndex转换 为 JavaScript 字符串值,是一个 数组索引属性名称,则返回通过给定 nameOrIndex 表示的数字从 collection 获取“全部”索引的元素 的结果。

  2. 返回通过给定 nameOrIndexcollection 获取“all”命名的元素 的结果。

2.6.3.1.1 [[Call]] (thisArgument, argumentsList)
  1. 如果 argumentsList大小 为零,或者 argumentsList[0] 是 undefined,则返回 null。

  2. argumentsList[0] 转换DOMString 的结果赋值给 nameOrIndex

  3. 将从此 HTMLAllCollection获取“全部”索引或命名的元素 的结果赋值给 result,给定 nameOrIndex

  4. 返回将 result 转换 为 ECMAScript 值的结果。

忽略 thisArgument,因此诸如 Function.prototype.call.call(document.all, null, "x") 的代码仍将搜索元素。(document.all.call 不存在,因为 document.all 不继承自 Function.prototype。)

2.6.3.2 HTMLFormControlsCollection 接口

HTMLFormControlsCollection 接口用于 集合form 元素中的 列出元素

HTMLFormControlsCollection

Support in all current engines.

Firefox1+Safari4+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

RadioNodeList

Support in all current engines.

Firefox33+Safari7+Chrome21+
Opera?Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
[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.

Firefox33+Safari4+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
radioNodeList = collection.namedItem(name)
element = collection[name]
radioNodeList = collection[name]

collection 返回 ID 或 namename 的项。

如果有多个匹配的项,则返回包含所有这些元素的 RadioNodeList 对象。

radioNodeList.value

返回 radioNodeList 所代表的第一个选中的单选按钮的值。

radioNodeList.value = value

选择第一个值为 valueradioNodeList 所代表的单选按钮。

The 支持的属性名称 由所有非空值组成 idname 属性的所有元素由集合表示,按树顺序,忽略后续的重复项,其中id 的元素优先于其name 如果它们同时贡献,它们彼此不同,并且都不是先前条目的重复项。

namedItem(name) 方法必须按照以下算法操作:

  1. 如果 name 为空字符串,则返回 null 并停止算法。
  2. 如果在调用方法时,集合中有且仅有一个节点具有 id 属性或 name 属性等于 name,则返回该节点并停止算法。
  3. 否则,如果集合中没有任何节点具有 id 属性或 name 属性等于 name,则返回 null 并停止算法。
  4. 否则,创建一个新的 RadioNodeList 对象,表示 动态 查看 HTMLFormControlsCollection 对象的视图,进一步过滤,使得 RadioNodeList 对象中的唯一节点是那些具有 id 属性或 name 属性等于 name 的节点。RadioNodeList 对象中的节点必须按 树顺序 排序。
  5. 返回该 RadioNodeList 对象。

RadioNodeList 接口的成员从 NodeList 接口继承,必须像在 NodeList 对象上一样表现。

RadioNodeList/value

Support in all current engines.

Firefox33+Safari7+Chrome21+
Opera?Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

value IDL 属性在 RadioNodeList 对象上,获取时必须返回通过运行以下步骤返回的值:

  1. element 成为由 RadioNodeList 对象表示的第一个元素,在 树顺序 中是一个 input 元素,其 type 属性处于 单选按钮 状态并且其 已选中 状态为真。否则,让其为 null。

  2. 如果 element 为 null,则返回空字符串。

  3. 如果 element 是一个没有 value 属性的元素,则返回字符串 "on"。

  4. 否则,返回 elementvalue 属性的值。

在设置时,value IDL 属性必须运行以下步骤:

  1. 如果新值为字符串 "on":让 element 成为由 RadioNodeList 对象表示的第一个元素,在 树顺序 中是一个 input 元素,其 type 属性处于 单选按钮 状态并且其 value 内容属性不存在,或存在且等于新值,如果有。如果不存在这样的元素,则让 element 为 null。

  2. 否则:让 element 成为由 RadioNodeList 对象表示的第一个元素,在 树顺序 中是一个 input 元素,其 type 属性处于 单选按钮 状态并且其 value 内容属性存在并等于新值,如果有。如果不存在这样的元素,则让 element 为 null。

  3. 如果 element 不为 null,则将其 已选中 状态设置为真。

2.6.3.3 HTMLOptionsCollection 接口

HTMLOptionsCollection

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

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 中具有 IDnamename 的项。

如果有多个匹配项,则返回第一个匹配项。

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 中索引为 indexoption 元素。

对象的 支持的属性索引HTMLCollection 对象中定义。

length 的获取步骤是返回 collection 表示的节点数

length 的设置步骤为:

  1. currentcollection 表示的节点数

  2. 如果给定值大于 current,则:

    1. 如果给定的值大于100,000,则返回。

    2. nvaluecurrent

    3. n 个没有属性和子节点的新 option 元素追加到 select 元素上,其中 this 是其根节点。

  3. 如果给定值小于 current,则:

    1. ncurrent - value

    2. 从其父节点中移除集合中的最后 n 个节点。

设置 length 永远不会移除或添加任何 optgroup 元素,也不会向现有的 optgroup 元素中添加新的子节点(尽管它可以从中移除子节点)。

The 支持的属性名称 由所有非空值组成 idname 属性的所有元素由集合表示,按树顺序,忽略后续的重复项,其中id 的元素优先于其name 如果它们同时贡献,它们彼此不同,并且都不是先前条目的重复项。

当用户代理要 设置新索引属性的值设置现有索引属性的值时,必须运行以下算法:

  1. 如果 value 为 null,则调用 remove 方法,将 index 作为参数,并返回。

  2. lengthcollection 表示的节点数

  3. nindex 减去 length

  4. 如果 n 大于零,则 附加 一个由 n-1 个新的没有属性和子节点的 option 元素组成的 DocumentFragmentselect 元素上。

  5. 如果 n 大于或等于零,则 附加 valueselect 元素。否则,替换 集合中的第 index 个元素为 value

add(element, before) 方法必须按以下算法操作:

  1. 如果 elementselect 元素的祖先,则抛出 "HierarchyRequestError" DOMException

  2. 如果 before 是一个元素,但该元素不是 select 元素的后代,则抛出 "NotFoundError" DOMException

  3. 如果 elementbefore 是同一个元素,则返回。

  4. 如果 before 是一个节点,则令 reference 为该节点。否则,如果 before 是一个整数,并且集合中存在第 before 个节点,则令 reference 为该节点。否则,令 reference 为 null。

  5. 如果 reference 不为 null,则令 parentreference 的父节点。否则,令 parentselect 元素。

  6. 预插入 elementparent 节点中,在 reference 之前。

remove(index) 方法必须按以下算法操作:

  1. 如果 collection 表示的节点数 为零,则返回。

  2. 如果 index 不是大于等于 0 且小于 collection 表示的节点数 的数字,则返回。

  3. element 为集合中的第 index 个元素。

  4. 从其父节点中移除 element

selectedIndex IDL 属性必须像 select 元素上的同名属性一样操作,该 HTMLOptionsCollection 根植于该元素上。

2.6.4 DOMStringList 接口

DOMStringList

所有当前引擎支持。

Firefox1+Safari5.1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+

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 接口 支持索引属性支持的属性索引的关联列表的 索引

DOMStringList/length

所有当前引擎支持。

Firefox1+Safari5.1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+

length 获取器步骤是返回关联列表的大小

DOMStringList/item

所有当前引擎支持。

Firefox1+Safari5.1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+

item(index) 方法步骤是返回 关联列表中的第 index 项,或者如果 index 加一大于 关联列表的 大小,则返回 null。

DOMStringList/contains

所有当前引擎支持。

Firefox1.5+Safari5.1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+

contains(string) 方法步骤是如果 关联列表 包含 string,则返回 true,否则返回 false。

2.7 安全传递结构化数据

为了支持在不同realm边界之间传递JavaScript对象,包括平台对象,本规范定义了以下用于序列化和反序列化对象的基础设施,包括在某些情况下传输底层数据而不是复制数据。总体而言,这种序列化/反序列化过程被称为“结构化克隆”,尽管大多数API执行的是单独的序列化和反序列化步骤。(显著的例外是structuredClone()方法。)

本节使用了JavaScript规范中的术语和排版约定。[JAVASCRIPT]

2.7.1 可序列化对象

/developer.mozilla.org/en-US/docs/Glossary/Serializable_object

Firefox103+SafariNoChrome77+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

可序列化对象支持以独立于任何特定realm的方式进行序列化和稍后反序列化。这使得它们可以存储在磁盘上并稍后恢复,或跨代理甚至代理集群边界进行克隆。

并非所有对象都是可序列化对象,而且并非所有可序列化对象的所有方面在序列化时都会被保留。

平台对象可以是可序列化对象,如果它们的主要接口带有[Serializable]IDL扩展属性。这些接口还必须定义以下算法:

序列化步骤,接受一个平台对象value,一个记录serialized,以及一个布尔值forStorage

一组步骤,将value中的数据序列化为serialized的字段。序列化到serialized中的结果数据必须独立于任何realm

如果序列化不可能,这些步骤可能会抛出异常。

这些步骤可能执行子序列化以序列化嵌套的数据结构。它们不应直接调用StructuredSerialize,因为这样做会遗漏重要的memory参数。

如果forStorage参数与算法无关,应在引入这些步骤时省略提及。

反序列化步骤,接受一个记录serialized,一个平台对象value,以及一个realmtargetRealm

一组步骤,将serialized中的数据反序列化,适当设置valuevalue将是所涉及的平台对象类型的新创建实例,其内部数据未设置;设置这些数据是这些步骤的任务。

如果反序列化不可能,这些步骤可能会抛出异常。

这些步骤可能执行子反序列化以反序列化嵌套的数据结构。它们不应直接调用StructuredDeserialize,因为这样做会遗漏重要的targetRealmmemory参数。

定义单个平台对象的数据在这些步骤中如何被序列化和反序列化是个体平台对象定义的责任。通常这些步骤是非常对称的。

[Serializable]扩展属性不得带有任何参数,并且只能出现在接口上。在一个接口上不得出现超过一次。

对于给定的平台对象,只有对象的主要接口在(反)序列化过程中被考虑。因此,如果在定义接口时涉及继承,每个继承链中的[Serializable]注释接口需要定义独立的序列化步骤反序列化步骤,包括考虑任何可能来自继承接口的重要数据。

假设我们定义了一个平台对象Person,它关联了两部分数据:

然后我们可以通过将Person接口注释为[Serializable]扩展属性,并定义以下配套算法,使Person实例成为可序列化对象

序列化步骤
  1. 设置serialized.[[Name]]为value的关联名称值。

  2. serializedBestFriend成为value的关联最好朋友值的子序列化

  3. 设置serialized.[[BestFriend]]为serializedBestFriend

反序列化步骤
  1. 设置value的关联名称值为serialized.[[Name]]。

  2. deserializedBestFriend成为serialized.[[BestFriend]]的子反序列化

  3. 设置value的关联最好朋友值为deserializedBestFriend

JavaScript规范中定义的对象由StructuredSerialize抽象操作直接处理。

最初,本规范定义了“可克隆对象”的概念,可以从一个realm克隆到另一个realm。然而,为了更好地指定某些更复杂情况的行为,模型被更新为使序列化和反序列化显式化。

2.7.2 可转移对象

可转移对象支持在代理之间转移。转移实际上是重新创建对象,同时共享对底层数据的引用,然后分离被转移的对象。这对于转移昂贵资源的所有权非常有用。并非所有对象都是可转移对象,而且并非所有可转移对象的所有方面在转移时都会被保留。

转移是不可逆且非幂等的操作。一旦对象被转移,它不能再被转移,甚至不能再被使用。

平台对象可以是可转移对象,如果它们的主要接口带有[Transferable]IDL扩展属性。这些接口还必须定义以下算法:

转移步骤,接受一个平台对象value,以及一个记录dataHolder

一组步骤,将value中的数据转移到dataHolder的字段中。保存在dataHolder中的结果数据必须独立于任何realm

如果转移不可能,这些步骤可能会抛出异常。

接收转移步骤,接受一个记录dataHolder,以及一个平台对象value

一组步骤,接收dataHolder中的数据,适当设置valuevalue将是所涉及的平台对象类型的新创建实例,其内部数据未设置;设置这些数据是这些步骤的任务。

如果无法接收转移,这些步骤可能会抛出异常。

定义单个平台对象的数据在这些步骤中如何被转移是个体平台对象定义的责任。通常这些步骤是非常对称的。

[Transferable]扩展属性不得带有任何参数,并且只能出现在接口上。在一个接口上不得出现超过一次。

对于给定的平台对象,只有对象的主要接口在转移过程中被考虑。因此,如果在定义接口时涉及继承,每个继承链中的[Transferable]注释接口需要定义独立的转移步骤接收转移步骤,包括考虑任何可能来自继承接口的重要数据。

作为可转移对象的平台对象具有一个[[Detached]]内部槽。这用于确保一旦平台对象被转移,它不能再次被转移。

JavaScript规范中定义的对象由StructuredSerializeWithTransfer抽象操作直接处理。

2.7.3 StructuredSerializeInternal (value, forStorage [ , memory ] )

StructuredSerializeInternal 抽象操作以一个 JavaScript 值 value 为输入,将其序列化为一个独立于 realm 的形式,这里表示为一个 记录。这种序列化形式包含所有必要的信息,以便以后在不同的 realm 中反序列化为一个新的 JavaScript 值。

此过程可能会抛出异常,例如尝试序列化不可序列化的对象时。

  1. 如果未提供 memory,则让 memory 成为空的 map

    memory map 的目的是避免对象被序列化两次。这最终保留了图中的循环和重复对象的身份。

  2. 如果 memory[value] 存在,则返回 memory[value]。

  3. deep 为 false。

  4. 如果 Type(value) 是 Undefined、Null、Boolean、Number、BigInt 或 String,则返回 { [[Type]]: "primitive", [[Value]]: value }。

  5. 如果 Type(value) 是 Symbol,则抛出 "DataCloneError" DOMException

  6. serialized 成为一个未初始化的值。

  7. 如果 value 有 [[BooleanData]] 内部槽,则将 serialized 设置为 { [[Type]]: "Boolean", [[BooleanData]]: value.[[BooleanData]] }。

  8. 否则,如果 value 有 [[NumberData]] 内部槽,则将 serialized 设置为 { [[Type]]: "Number", [[NumberData]]: value.[[NumberData]] }。

  9. 否则,如果 value 有 [[BigIntData]] 内部槽,则将 serialized 设置为 { [[Type]]: "BigInt", [[BigIntData]]: value.[[BigIntData]] }。

  10. 否则,如果 value 有 [[StringData]] 内部槽,则将 serialized 设置为 { [[Type]]: "String", [[StringData]]: value.[[StringData]] }。

  11. 否则,如果 value 有 [[DateValue]] 内部槽,则将 serialized 设置为 { [[Type]]: "Date", [[DateValue]]: value.[[DateValue]] }。

  12. 否则,如果 value 有 [[RegExpMatcher]] 内部槽,则将 serialized 设置为 { [[Type]]: "RegExp", [[RegExpMatcher]]: value.[[RegExpMatcher]], [[OriginalSource]]: value.[[OriginalSource]], [[OriginalFlags]]: value.[[OriginalFlags]] }。

  13. 否则,如果 value 有 [[ArrayBufferData]] 内部槽,则:

    1. 如果 IsSharedArrayBuffer(value) 是 true,则:

      1. 如果 当前设置对象跨域隔离能力 为 false,则抛出 "DataCloneError" DOMException

        此检查仅在序列化时需要(反序列化时不需要),因为 跨域隔离能力 不能随时间改变,且 SharedArrayBuffer 不能离开一个 agent 集群

      2. 如果 forStorage 为 true,则抛出 "DataCloneError" DOMException

      3. 如果 value 有 [[ArrayBufferMaxByteLength]] 内部槽,则将 serialized 设置为 { [[Type]]: "GrowableSharedArrayBuffer", [[ArrayBufferData]]: value.[[ArrayBufferData]], [[ArrayBufferByteLengthData]]: value.[[ArrayBufferByteLengthData]], [[ArrayBufferMaxByteLength]]: value.[[ArrayBufferMaxByteLength]], [[AgentCluster]]: 周围 agentagent 集群 }。

      4. 否则,将 serialized 设置为 { [[Type]]: "SharedArrayBuffer", [[ArrayBufferData]]: value.[[ArrayBufferData]], [[ArrayBufferByteLength]]: value.[[ArrayBufferByteLength]], [[AgentCluster]]: 周围 agentagent 集群 }。

    2. 否则:

      1. 如果 IsDetachedBuffer(value) 是 true,则抛出 "DataCloneError" DOMException

      2. sizevalue.[[ArrayBufferByteLength]]。

      3. dataCopy 成为 ? CreateByteDataBlock(size)。

        在分配失败时,这可能会抛出 RangeError 异常。

      4. 执行 CopyDataBlockBytes(dataCopy, 0, value.[[ArrayBufferData]], 0, size)。

      5. 如果 value 有 [[ArrayBufferMaxByteLength]] 内部槽,则将 serialized 设置为 { [[Type]]: "ResizableArrayBuffer", [[ArrayBufferData]]: dataCopy, [[ArrayBufferByteLength]]: size, [[ArrayBufferMaxByteLength]]: value.[[ArrayBufferMaxByteLength]] }。

      6. 否则,将 serialized 设置为 { [[Type]]: "ArrayBuffer", [[ArrayBufferData]]: dataCopy, [[ArrayBufferByteLength]]: size }。

  14. 否则,如果 value 有 [[ViewedArrayBuffer]] 内部槽,则:

    1. 如果 IsArrayBufferViewOutOfBounds(value) 是 true,则抛出 "DataCloneError" DOMException

    2. buffer 成为 value 的 [[ViewedArrayBuffer]] 内部槽的值。

    3. bufferSerialized 成为 ? StructuredSerializeInternal(buffer, forStorage, memory)。

    4. 断言bufferSerialized.[[Type]] 是 "ArrayBuffer"、"ResizableArrayBuffer"、"SharedArrayBuffer" 或 "GrowableSharedArrayBuffer"。

    5. 如果 value 有 [[DataView]] 内部槽,则将 serialized 设置为 { [[Type]]: "ArrayBufferView", [[Constructor]]: "DataView", [[ArrayBufferSerialized]]: bufferSerialized, [[ByteLength]]: value.[[ByteLength]], [[ByteOffset]]: value.[[ByteOffset]] }。

    6. 否则:

      1. 断言value 有 [[TypedArrayName]] 内部槽。

      2. serialized 设置为 { [[Type]]: "ArrayBufferView", [[Constructor]]: value.[[TypedArrayName]], [[ArrayBufferSerialized]]: bufferSerialized, [[ByteLength]]: value.[[ByteLength]], [[ByteOffset]]: value.[[ByteOffset]], [[ArrayLength]]: value.[[ArrayLength]] }。

  15. 否则,如果 value 有 [[MapData]] 内部槽,则:

    1. serialized 设置为 { [[Type]]: "Map", [[MapData]]: 一个新的空 列表 }。

    2. deep 设置为 true。

  16. 否则,如果 value 有 [[SetData]] 内部槽,则:

    1. serialized 设置为 { [[Type]]: "Set", [[SetData]]: 一个新的空 列表 }。

    2. deep 设置为 true。

  17. 否则,如果 value 有 [[ErrorData]] 内部槽且 value 不是 平台对象,则:

    1. name 成为 ? 获取(value, "name")。

    2. 如果 name 不是 "Error"、"EvalError"、"RangeError"、"ReferenceError"、"SyntaxError"、"TypeError" 或 "URIError" 之一,则将 name 设置为 "Error"。

    3. valueMessageDesc 成为 ? value.[[GetOwnProperty]]("message")。

    4. 如果 IsDataDescriptor(valueMessageDesc) 为 false,则将 message 设置为 undefined;否则,将 message 设置为 ? ToString(valueMessageDesc.[[Value]])。

    5. serialized 设置为 { [[Type]]: "Error", [[Name]]: name, [[Message]]: message }。

    6. 用户代理应将尚未指定的任何有趣的附带数据的序列化表示附加到 serialized,特别是 stack 属性。

      请参见 Error Stacks 提案,了解关于指定此数据的进行中的工作。[JSERRORSTACKS]

  18. 否则,如果 value 是一个数组异类对象,则:

    1. valueLenDescriptor 成为 ? OrdinaryGetOwnProperty(value, "length")。

    2. valueLen 成为 valueLenDescriptor.[[Value]]。

    3. serialized 设置为 { [[Type]]: "Array", [[Length]]: valueLen, [[Properties]]: 一个新的空 列表 }。

    4. deep 设置为 true。

  19. 否则,如果 value 是一个 平台对象,且是一个 可序列化对象

    1. 如果 value 有一个值为 true 的 [[Detached]] 内部槽,则抛出 "DataCloneError" DOMException

    2. typeString 成为 主接口 的标识符。

    3. serialized 设置为 { [[Type]]: typeString }。

    4. deep 设置为 true。

  20. 否则,如果 value 是一个 平台对象,则抛出 "DataCloneError" DOMException

  21. 否则,如果 IsCallable(value) 为 true,则抛出 "DataCloneError" DOMException

  22. 否则,如果 value 有任何内部槽,除 [[Prototype]]、[[Extensible]] 或 [[PrivateElements]] 外,则抛出 "DataCloneError" DOMException

    例如,一个 [[PromiseState]] 或 [[WeakMapData]] 内部槽。

  23. 否则,如果 value 是一个异类对象,且 value 不是与任何 realm 关联的 %Object.prototype% 内在对象,则抛出 "DataCloneError" DOMException

    例如,一个代理对象。

  24. 否则:

    1. serialized 设置为 { [[Type]]: "Object", [[Properties]]: 一个新的空 列表 }。

    2. deep 设置为 true。

    %Object.prototype% 将通过此步骤和后续步骤进行处理。最终结果是忽略其异类性,并且在反序列化后结果将是一个空对象(不是一个 不可变原型异类对象)。

  25. 设置 memory[value] 为 serialized

  26. 如果 deep 为 true,则:

    1. 如果 value 有 [[MapData]] 内部槽,则:

      1. copiedList 成为一个新的空 列表

      2. 对于每个 记录 { [[Key]], [[Value]] } entryvalue.[[MapData]] 中:

        1. copiedEntry 成为一个新的 记录 { [[Key]]: entry.[[Key]], [[Value]]: entry.[[Value]] }。

        2. 如果 copiedEntry.[[Key]] 不是特殊值 ,则将 copiedEntry 附加copiedList

      3. 对于每个 记录 { [[Key]], [[Value]] } entrycopiedList 中:

        1. serializedKey 成为 ? StructuredSerializeInternal(entry.[[Key]], forStorage, memory)。

        2. serializedValue 成为 ? StructuredSerializeInternal(entry.[[Value]], forStorage, memory)。

        3. 将 { [[Key]]: serializedKey, [[Value]]: serializedValue } 附加serialized.[[MapData]]。

    2. 否则,如果 value 有 [[SetData]] 内部槽,则:

      1. copiedList 成为一个新的空 列表

      2. 对于每个 entryvalue.[[SetData]] 中:

        1. 如果 entry 不是特殊值 ,则将 entry 附加copiedList

      3. 对于每个 entrycopiedList 中:

        1. serializedEntry 成为 ? StructuredSerializeInternal(entry, forStorage, memory)。

        2. serializedEntry 附加serialized.[[SetData]]。

    3. 否则,如果 value 是一个 平台对象,且是一个 可序列化对象,则为 value主接口 执行 序列化步骤,给定 valueserializedforStorage

      序列化步骤 可能需要执行 子序列化。这是一个以值 subValue 为输入的操作,并返回 StructuredSerializeInternal(subValue, forStorage, memory)。(换句话说,一个 子序列化StructuredSerializeInternal 在此次调用中的特化。)

    4. 否则,对于 ! EnumerableOwnProperties(value, key) 中的每个 key

      1. 如果 ! HasOwnProperty(value, key) 为 true,则:

        1. inputValue 成为 ? value.[[Get]](key, value)。

        2. outputValue 成为 ? StructuredSerializeInternal(inputValue, forStorage, memory)。

        3. 将 { [[Key]]: key, [[Value]]: outputValue } 附加serialized.[[Properties]]。

  27. 返回 serialized

需要注意的是,记录StructuredSerializeInternal生成的可能包含指向其他记录的“指针”,这些指针会创建循环引用。例如,当我们将以下 JavaScript 对象传递给StructuredSerializeInternal时:

const o = {};
o.myself = o;

它会生成以下结果:

{
  [[Type]]: "Object",
  [[Properties]]: «
    {
      [[Key]]: "myself",
      [[Value]]: <a pointer to this whole structure>
    }
  »
}

2.7.4 StructuredSerialize ( value )

  1. 返回 ? StructuredSerializeInternal(value, false)。

2.7.5 StructuredSerializeForStorage ( value )

  1. 返回 ? StructuredSerializeInternal(value, true)。

2.7.6 结构化反序列化 (serialized, targetRealm [, memory])

结构化反序列化抽象操作接受一个记录serialized作为输入,该记录之前由结构化序列化存储用结构化序列化生成,并将其反序列化为在targetRealm中创建的新JavaScript值。

此过程可能会抛出异常,例如在尝试为新对象(尤其是ArrayBuffer对象)分配内存时。

  1. 如果未提供memory,则将memory设为空的映射

    memory映射的目的是避免对象的两次反序列化。这最终保留了图中循环和重复对象的身份。

  2. 如果memory[serialized] 存在,则返回memory[serialized]。

  3. deep设为false。

  4. value设为未初始化的值。

  5. 如果serialized.[[Type]]是"primitive",则将value设为serialized.[[Value]]。

  6. 否则,如果serialized.[[Type]]是"Boolean",则将value设为在targetRealm中新的Boolean对象,其[[BooleanData]]内部槽值为serialized.[[BooleanData]]。

  7. 否则,如果serialized.[[Type]]是"Number",则将value设为在targetRealm中新的Number对象,其[[NumberData]]内部槽值为serialized.[[NumberData]]。

  8. 否则,如果serialized.[[Type]]是"BigInt",则将value设为在targetRealm中新的BigInt对象,其[[BigIntData]]内部槽值为serialized.[[BigIntData]]。

  9. 否则,如果serialized.[[Type]]是"String",则将value设为在targetRealm中新的String对象,其[[StringData]]内部槽值为serialized.[[StringData]]。

  10. 否则,如果serialized.[[Type]]是"Date",则将value设为在targetRealm中新的Date对象,其[[DateValue]]内部槽值为serialized.[[DateValue]]。

  11. 否则,如果serialized.[[Type]]是"RegExp",则将value设为在targetRealm中新的RegExp对象,其[[RegExpMatcher]]内部槽值为serialized.[[RegExpMatcher]],其[[OriginalSource]]内部槽值为serialized.[[OriginalSource]],其[[OriginalFlags]]内部槽值为serialized.[[OriginalFlags]]。

  12. 否则,如果serialized.[[Type]]是"SharedArrayBuffer",则:

    1. 如果targetRealm对应的代理集群不是serialized.[[AgentCluster]],则抛出"DataCloneError" DOMException

    2. 否则,将value设为在targetRealm中新的SharedArrayBuffer对象,其[[ArrayBufferData]]内部槽值为serialized.[[ArrayBufferData]],其[[ArrayBufferByteLength]]内部槽值为serialized.[[ArrayBufferByteLength]]。

  13. 否则,如果serialized.[[Type]]是"GrowableSharedArrayBuffer",则:

    1. 如果targetRealm对应的代理集群不是serialized.[[AgentCluster]],则抛出"DataCloneError" DOMException

    2. 否则,将value设为在targetRealm中新的SharedArrayBuffer对象,其[[ArrayBufferData]]内部槽值为serialized.[[ArrayBufferData]],其[[ArrayBufferByteLengthData]]内部槽值为serialized.[[ArrayBufferByteLengthData]],其[[ArrayBufferMaxByteLength]]内部槽值为serialized.[[ArrayBufferMaxByteLength]]。

  14. 否则,如果serialized.[[Type]]是"ArrayBuffer",则将value设为在targetRealm中新的ArrayBuffer对象,其[[ArrayBufferData]]内部槽值为serialized.[[ArrayBufferData]],其[[ArrayBufferByteLength]]内部槽值为serialized.[[ArrayBufferByteLength]]。

    如果这抛出了异常,捕获它,然后抛出"DataCloneError" DOMException

    如果没有足够的内存可用来创建这样的ArrayBuffer对象,此步骤可能会抛出异常。

  15. 否则,如果serialized.[[Type]]是"ResizableArrayBuffer",则将value设为在targetRealm中新的ArrayBuffer对象,其[[ArrayBufferData]]内部槽值为serialized.[[ArrayBufferData]],其[[ArrayBufferByteLength]]内部槽值为serialized.[[ArrayBufferByteLength]],其[[ArrayBufferMaxByteLength]]内部槽值为serialized.[[ArrayBufferMaxByteLength]]。

    如果这抛出了异常,捕获它,然后抛出"DataCloneError" DOMException

    如果没有足够的内存可用来创建这样的ArrayBuffer对象,此步骤可能会抛出异常。

  16. 否则,如果serialized.[[Type]]是"ArrayBufferView",则:

    1. deserializedArrayBuffer为? 结构化反序列化(serialized.[[ArrayBufferSerialized]], targetRealm, memory)。

    2. 如果serialized.[[Constructor]]是"DataView",则将value设为在targetRealm中新的DataView对象,其[[ViewedArrayBuffer]]内部槽值为deserializedArrayBuffer,其[[ByteLength]]内部槽值为serialized.[[ByteLength]],其[[ByteOffset]]内部槽值为serialized.[[ByteOffset]]。

    3. 否则,将value设为在targetRealm中新的类型数组对象,使用serialized.[[Constructor]]给定的构造函数,其[[ViewedArrayBuffer]]内部槽值为deserializedArrayBuffer,其[[TypedArrayName]]内部槽值为serialized.[[Constructor]],其[[ByteLength]]内部槽值为serialized.[[ByteLength]],其[[ByteOffset]]内部槽值为serialized.[[ByteOffset]],其[[ArrayLength]]内部槽值为serialized.[[ArrayLength]]。

  17. 否则,如果serialized.[[Type]]是"Map",则:

    1. value设为在targetRealm中新的Map对象,其[[MapData]]内部槽值为新的空列表

    2. deep设为true。

  18. 否则,如果serialized.[[Type]]是"Set",则:

    1. value设为在targetRealm中新的Set对象,其[[SetData]]内部槽值为新的空列表

    2. deep设为true。

  19. 否则,如果serialized.[[Type]]是"Array",则:

    1. outputPrototargetRealm.[[Intrinsics]].[[%Array.prototype%]]。

    2. value设为! 数组创建(serialized.[[Length]], outputProto)。

    3. deep设为true。

  20. 否则,如果serialized.[[Type]]是"Object",则:

    1. value设为在targetRealm中的新对象。

    2. deep设为true。

  21. 否则,如果serialized.[[Type]]是"Error",则:

    1. prototype%Error.prototype%

    2. 如果serialized.[[Name]]是"EvalError",则将prototype设为%EvalError.prototype%

    3. 如果serialized.[[Name]]是"RangeError",则将prototype设为%RangeError.prototype%

    4. 如果serialized.[[Name]]是"ReferenceError",则将prototype设为%ReferenceError.prototype%

    5. 如果serialized.[[Name]]是"SyntaxError",则将prototype设为%SyntaxError.prototype%

    6. 如果serialized.[[Name]]是"TypeError",则将prototype设为%TypeError.prototype%

    7. 如果serialized.[[Name]]是"URIError",则将prototype设为%URIError.prototype%

    8. messageserialized.[[Message]]。

    9. value设为普通对象创建(prototype,«[[ErrorData]]»)。

    10. messageDesc属性描述符{[[Value]]: message, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}。

    11. 如果message不为undefined,则执行! 普通定义自有属性(value, "message", messageDesc)。

    12. 任何附加到serialized上的有趣的附加数据都应该被反序列化并附加到value上。

  22. 否则:

    1. interfaceNameserialized.[[Type]]。

    2. 如果interfaceName标识的接口在targetRealm中不是暴露的,则抛出"DataCloneError" DOMException

    3. value设为在targetRealm中创建的由interfaceName标识的接口的新实例。

    4. deep设为true。

  23. 设置 memory[serialized]为value

  24. 如果deep为true,则:

    1. 如果serialized.[[Type]]是"Map",则:

      1. 对每个 记录 {[[Key]], [[Value]]}entryserialized.[[MapData]]进行:

        1. deserializedKey为? 结构化反序列化(entry.[[Key]], targetRealm, memory)。

        2. deserializedValue为? 结构化反序列化(entry.[[Value]], targetRealm, memory)。

        3. 附加 {[[Key]]: deserializedKey, [[Value]]: deserializedValue}到value.[[MapData]]。

    2. 否则,如果serialized.[[Type]]是"Set",则:

      1. 对每个 entryserialized.[[SetData]]进行:

        1. deserializedEntry为? 结构化反序列化(entry, targetRealm, memory)。

        2. 附加 deserializedEntryvalue.[[SetData]]。

    3. 否则,如果serialized.[[Type]]是"Array"或"Object",则:

      1. 对每个 记录 {[[Key]], [[Value]]}entryserialized.[[Properties]]进行:

        1. deserializedValue为? 结构化反序列化(entry.[[Value]], targetRealm, memory)。

        2. result为! 创建数据属性(value, entry.[[Key]], deserializedValue)。

        3. 断言result为true。

    4. 否则:

      1. 执行由serialized.[[Type]]标识的接口的适当反序列化步骤,给定serializedvaluetargetRealm

        反序列化步骤可能需要执行子反序列化。这是一个操作,接受先前序列化的记录subSerialized作为输入,并返回结构化反序列化(subSerializedtargetRealmmemory)。(换句话说,子反序列化结构化反序列化的特化,以在此调用中保持一致。)

  25. 返回value

2.7.7 StructuredSerializeWithTransfer ( value, transferList )

  1. memory 为一个空的map

    除了 StructuredSerializeInternal 正常使用外,在这个算法中 memory 还用于确保 StructuredSerializeInternal 忽略 transferList 中的项目,并让我们自己处理。

  2. 对于每个 transferabletransferList

    1. 如果 transferable 既没有 [[ArrayBufferData]] 内部槽也没有[[Detached]] 内部槽,则抛出 "DataCloneError" DOMException

    2. 如果 transferable 具有 [[ArrayBufferData]] 内部槽且 IsSharedArrayBuffer(transferable) 为真,则抛出 "DataCloneError" DOMException

    3. 如果 memory[transferable] 存在,则抛出 "DataCloneError" DOMException

    4. 设置 memory[transferable] 为 {[[Type]]: 未初始化的值}。

      transferable 尚未传输,因为传输有副作用,并且 StructuredSerializeInternal 需要先能够抛出。

  3. serialized 为 ? StructuredSerializeInternal(value, false, memory)。

  4. transferDataHolders 为一个新的空的 List

  5. 对于每个 transferabletransferList

    1. 如果 transferable 具有 [[ArrayBufferData]] 内部槽且 IsDetachedBuffer(transferable) 为真,则抛出 "DataCloneError" DOMException

    2. 如果 transferable 具有 [[Detached]] 内部槽且 transferable.[[Detached]] 为真,则抛出 "DataCloneError" DOMException

    3. dataHoldermemory[transferable]。

    4. 如果 transferable 具有 [[ArrayBufferData]] 内部槽,则:

      1. 如果 transferable 具有 [[ArrayBufferMaxByteLength]] 内部槽,则:

        1. dataHolder.[[Type]] 设为 "ResizableArrayBuffer"。

        2. dataHolder.[[ArrayBufferData]] 设为 transferable.[[ArrayBufferData]]。

        3. dataHolder.[[ArrayBufferByteLength]] 设为 transferable.[[ArrayBufferByteLength]]。

        4. dataHolder.[[ArrayBufferMaxByteLength]] 设为 transferable.[[ArrayBufferMaxByteLength]]。

      2. 否则:

        1. dataHolder.[[Type]] 设为 "ArrayBuffer"。

        2. data Holder.[[ArrayBufferData]] 设为 transferable.[[ArrayBufferData]]。

        3. dataHolder.[[ArrayBufferByteLength]] 设为 transferable.[[ArrayBufferByteLength]]。

      3. 执行 ? DetachArrayBuffer(transferable)。

        规范可以使用 [[ArrayBufferDetachKey]] 内部槽来防止 ArrayBuffer 被分离。例如,这在 WebAssembly JavaScript Interface 中使用。[WASMJS]

    5. 否则:

      1. 断言transferable 是一个 平台对象,并且是一个 可转移对象

      2. interfaceName主接口的标识符。transferable

      3. dataHolder.[[Type]] 设为 interfaceName

      4. 执行适当的 传输步骤,给定 transferabledataHolder,由 interfaceName 标识的接口。

      5. transferable.[[Detached]] 设为真。

    6. 追加 dataHoldertransferDataHolders

  6. 返回 { [[Serialized]]: serialized, [[TransferDataHolders]]: transferDataHolders }。

2.7.8 StructuredDeserializeWithTransfer ( serializeWithTransferResult, targetRealm )

  1. memory 为一个空的map

    类似于 StructuredSerializeWithTransfer,除了正常被 StructuredDeserialize 使用外,在这个算法中 memory 还用于确保 StructuredDeserialize 忽略 serializeWithTransferResult.[[TransferDataHolders]] 中的项目,让我们自己进行处理。

  2. transferredValues 为一个新的空的List

  3. 对于每个 transferDataHolderserializeWithTransferResult.[[TransferDataHolders]]:

    1. value 为一个未初始化的值。

    2. 如果 transferDataHolder.[[Type]] 是 "ArrayBuffer",则将 value 设为在 targetRealm 中创建的新 ArrayBuffer 对象,其 [[ArrayBufferData]] 内部槽值为 transferDataHolder.[[ArrayBufferData]],且 [[ArrayBufferByteLength]] 内部槽值为 transferDataHolder.[[ArrayBufferByteLength]]。

      在原始内存仍可访问的情况下,这一步骤不太可能抛出异常,因为不需要分配新的内存:[[ArrayBufferData]] 占用的内存只是被转移到新的 ArrayBuffer 中。这可能在源和目标领域在同一进程中时为真。

    3. 否则,如果 transferDataHolder.[[Type]] 是 "ResizableArrayBuffer",则将 value 设为在 targetRealm 中创建的新 ArrayBuffer 对象,其 [[ArrayBufferData]] 内部槽值为 transferDataHolder.[[ArrayBufferData]],[[ArrayBufferByteLength]] 内部槽值为 transferDataHolder.[[ArrayBufferByteLength]],以及 [[ArrayBufferMaxByteLength]] 内部槽值为 transferDataHolder.[[ArrayBufferMaxByteLength]]。

      与前一步相同,这一步骤也不太可能抛出异常。

    4. 否则:

      1. interfaceNametransferDataHolder.[[Type]]。

      2. 如果由 interfaceName 标识的接口在 targetRealm 中不可用,则抛出 "DataCloneError" DOMException

      3. value 设为在 targetRealm 中创建的由 interfaceName 标识的接口的新实例。

      4. 执行适当的接收转移步骤,针对由 interfaceName 标识的接口,给定 transferDataHoldervalue

    5. 设置 memory[transferDataHolder] 为 value

    6. 追加 valuetransferredValues

  4. deserialized 为 ? StructuredDeserialize(serializeWithTransferResult.[[Serialized]], targetRealm, memory)。

  5. 返回 { [[Deserialized]]: deserialized, [[TransferredValues]]: transferredValues }。

2.7.9 从其他规范执行序列化和传输

其他规范可以使用此处定义的抽象操作。以下提供了一些关于每个抽象操作通常何时有用的指导,并附有示例。

StructuredSerializeWithTransfer
StructuredDeserializeWithTransfer

将一个值克隆到另一个realm,使用一个传输列表,但目标realm事先未知。在这种情况下,可以立即执行序列化步骤,而反序列化步骤则延迟到目标realm变得已知时再进行。

messagePort.postMessage() 使用这对抽象操作,因为直到MessagePort 已被发送后,目标realm才会变得已知。

StructuredSerialize
StructuredSerializeForStorage
StructuredDeserialize

创建一个给定值的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值。


那些不是因为作者代码同步调用用户代理方法而调用的调用点,必须在调用StructuredSerializeStructuredSerializeForStorageStructuredSerializeWithTransfer抽象操作之前,做好适当的准备运行脚本准备运行回调。这是必要的,因为序列化过程可以在其最终深度序列化步骤中调用作者定义的访问器,而这些访问器可能会调用依赖于正确设置entryincumbent概念的操作。

window.postMessage() 在其参数上执行StructuredSerializeWithTransfer,但要小心立即在其算法的同步部分内执行。因此,它可以使用这些算法,而不需要准备运行脚本准备运行回调

相比之下,一个假设的API,使用StructuredSerialize来定期序列化一些作者提供的对象,直接从任务事件循环上进行,将需要确保它事先执行适当的准备。截至目前,我们知道平台上没有这样的API;通常,提前进行序列化作为作者代码的同步结果会更简单。

2.7.10 结构化克隆 API

result = self.structuredClone(value[, { transfer }])

获取输入值并通过执行结构化克隆算法返回一个深拷贝。可转移对象列在transfer数组中,这些对象被转移而不仅仅是克隆,这意味着它们在输入值中不再可用。

如果输入值的任何部分不是可序列化对象,则抛出一个"DataCloneError" DOMException

structuredClone

所有当前引擎都支持。

Firefox94+ Safari15.4+ Chrome98+
Opera? Edge98+
Edge (旧版)? Internet ExplorerNo
Firefox Android? Safari iOS? Chrome Android? WebView Android? Samsung Internet? Opera Android?

structuredClone(value, options) 方法步骤如下:

  1. serialized为 ? StructuredSerializeWithTransfer(value, options["transfer"])。

  2. deserializeRecord为 ? StructuredDeserializeWithTransfer(serialized, this相关realm)。

  3. 返回deserializeRecord.[[Deserialized]]。

3 HTML文档的语义、结构和API

3.1 文档

HTML UA中的每个XML和HTML文档都由一个Document对象表示。[DOM]

Document对象的URLDOM中定义。它在Document对象创建时设置,但在Document对象的生命周期内可以更改;例如,当用户导航到页面上的片段时以及当调用pushState()方法时URL会更改。[DOM]

交互式用户代理通常在其用户界面中显示Document对象的URL。这是用户判断网站是否试图冒充其他网站的主要机制。

Document对象的originDOM中定义。它在Document对象创建时设置,并且只有在设置document.domain时才能在Document的生命周期内更改。Documentorigin可以与其URL的origin不同;例如,当创建一个子导航时,它的活动文档origin继承自其父文档活动文档origin,即使其活动文档URLabout:blank[DOM]

当一个Document脚本使用createDocument()createHTMLDocument()方法创建时,Document会立即准备好进行加载后任务

文档的引用者是一个字符串(表示URL),可以在Document创建时设置。如果未显式设置,则其值为空字符串。

3.1.1 Document 对象

Document

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

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 containerpolicy 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阻止详情,这是一个集合,包含未恢复原因详情,最初为空。

3.1.2 DocumentOrShadowRoot 接口

DOM 定义了 DocumentOrShadowRoot mixin,本规范对此进行了扩展。

partial interface mixin DocumentOrShadowRoot {
  readonly attribute Element? activeElement;
};

3.1.3 资源元数据管理

document.referrer

Document/referrer

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

返回用户从中导航到此页面的DocumentURL,如果被阻止或没有这样的文档,则返回空字符串。

noreferrer链接类型可用于阻止referrer。

referrer属性必须返回文档的引用者


document.cookie [ = value ]

返回适用于Document的HTTP cookies。如果没有cookies或cookies不能应用于此资源,则返回空字符串。

可以设置,以将新cookie添加到元素的HTTP cookies集中。

如果内容被沙盒化为不透明来源(例如,在具有iframesandbox属性的iframe中),则在获取和设置时会抛出DOMException类型的"SecurityError"。

Document/cookie

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

cookie属性表示由文档的URL标识的资源的cookies。

满足以下条件之一的Document对象是cookie-averse Document对象

(This is a tracking vector.) 在获取时,如果文档是cookie-averse Document对象,则用户代理必须返回空字符串。否则,如果Document来源不透明来源,用户代理必须抛出DOMException类型的"SecurityError"。否则,用户代理必须返回文档的cookie-string,对于“非HTTP”API,使用UTF-8解码(无BOM)进行解码。[COOKIES]

在设置时,如果文档是cookie-averse Document对象,则用户代理必须什么也不做。否则,如果Document来源是不透明来源,用户代理必须抛出DOMException类型的"SecurityError"。否则,用户代理必须按照接收文档的URLset-cookie-string处理新值,使用UTF-8编码[COOKIES] [ENCODING]

由于cookie属性可跨帧访问,因此cookies的路径限制只是帮助管理cookies发送到站点不同部分的工具,而不是安全功能。

cookie属性的getter和setter同步访问共享状态。由于没有锁机制,多个进程用户代理中的其他浏览上下文可以在脚本运行时修改cookies。例如,一个站点可以尝试读取cookie,增加其值,然后写回新值,使用cookie的新值作为会话的唯一标识符;如果该站点在两个不同的浏览器窗口中同时进行两次此操作,可能会使用相同的“唯一”标识符来表示两个会话,可能会产生灾难性后果。


document.lastModified

Document/lastModified

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回服务器报告的文档的最后修改日期,格式为“MM/DD/YYYY hh:mm:ss”,以用户的本地时区表示。

如果不知道最后的修改日期,则返回当前时间。

lastModified属性在获取时必须返回文档源文件最后修改的日期和时间,以用户的本地时区,格式如下:

  1. 日期的月份部分。

  2. U+002F SOLIDUS字符(/)。

  3. 日期的天部分。

  4. U+002F SOLIDUS字符(/)。

  5. 日期的年份部分。

  6. U+0020 SPACE字符。

  7. 时间的小时部分。

  8. U+003A COLON字符(:)。

  9. 时间的分钟部分。

  10. U+003A COLON字符(:)。

  11. 时间的秒部分。

上述所有的数字部分,除年份外,必须表示为基数十的两个ASCII数字,必要时填充零。年份必须表示为最短可能的字符串,至少四个ASCII数字,必要时填充零。

Document的源文件最后修改日期和时间必须从使用的网络协议的相关特性中获取,例如从文档的HTTP Last-Modified标头的值或本地文件的文件系统元数据中获取。如果最后修改日期和时间未知,属性必须返回上述格式的当前日期和时间。

3.1.4 报告文档加载状态

document.readyState

Document加载时返回“loading”,解析完成但仍在加载子资源时返回“interactive”,加载完成后返回“complete”。

当此值发生变化时,readystatechange事件会在Document对象上触发。

在从“interactive”过渡到“complete”之前,当除asyncscript元素外的所有子资源加载完成时,会触发DOMContentLoaded事件。

Document/readyState

所有当前引擎支持。

Firefox3.6+Safari1+Chrome1+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+

每个Document都有一个当前文档准备状态,一个字符串,最初为“complete”。

对于通过创建和初始化Document对象算法创建的Document对象,这将在任何脚本观察到document.readyState值之前立即重置为“loading”。此默认值适用于其他情况,例如初始about:blank Document或没有浏览上下文Document

readyStategetter步骤是返回this当前文档准备状态

要为Document document更新当前文档准备状态为readinessValue

  1. 如果document当前文档准备状态等于readinessValue,则返回。

  2. document当前文档准备状态设置为readinessValue

  3. 如果documentHTML解析器相关联,则:

    1. now成为给定document相关全局对象当前高分辨率时间

    2. 如果readinessValue是“complete”,并且document加载时间信息DOM完成时间为0,则将document加载时间信息DOM完成时间设置为now

    3. 否则,如果readinessValue是“interactive”,并且document加载时间信息DOM交互时间为0,则将document加载时间信息DOM交互时间设置为now

  4. 触发一个事件,名为readystatechangedocument


如果一个Document与尚未停止中止HTML解析器XML解析器相关联,则称其具有活动解析器


Document有一个文档加载时间信息 加载时间信息

Document有一个文档卸载时间信息 以前的文档卸载时间

Document有一个布尔值通过跨域重定向创建,最初为false。

文档加载时间信息结构体具有以下

导航开始时间(默认0)
一个数字
DOM交互时间(默认0)
DOM内容加载事件开始时间(默认0)
DOM内容加载事件结束时间(默认0)
DOM完成时间(默认0)
加载事件开始时间(默认0)
加载事件结束时间(默认0)
DOMHighResTimeStamp

文档卸载时间信息结构体具有以下

卸载事件开始时间(默认0)
卸载事件结束时间(默认0)
DOMHighResTimeStamp

3.1.5 渲染阻塞机制

每个Document都有一个渲染阻塞元素集合,这是一个集合,初始为空集合。

如果Document document内容类型是“text/html”并且documentbody元素为null,则document允许添加渲染阻塞元素。

如果以下两个条件都为真,则Document document被认为是渲染阻塞

如果元素el节点文档 document渲染阻塞并且eldocument渲染阻塞元素集合中,则el渲染阻塞的。

阻止渲染元素el

  1. documentel节点文档

  2. 如果document允许添加渲染阻塞元素,则将el附加到document渲染阻塞元素集合中。

解除渲染阻塞元素el

  1. documentel节点文档

  2. document渲染阻塞元素集合移除el

每当渲染阻塞元素el变为浏览上下文断开,或者el阻塞属性的值发生变化,使el不再潜在地渲染阻塞时,则解除渲染阻塞el

3.1.6 DOM 树访问器

文档的html元素是它的文档元素,如果它是一个html元素,否则为 null。


document.head

Document/head

Support in all current engines.

Firefox4+Safari5+Chrome4+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+

返回head 元素

文档的head元素是第一个作为head元素的子元素,如果存在,否则为 null。

在获取时,head属性必须返回文档的head 元素(一个head元素或 null)。


document.title [ = value ]

返回文档的标题,如由 HTML 中的title 元素和 SVG 中的SVG title 元素所给定的。

可以设置,以更新文档的标题。如果没有合适的元素可以更新,新值将被忽略。

文档的title元素是文档中的第一个title元素(按树顺序),如果存在,否则为 null。

Document/title

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

在获取时,title属性必须运行以下算法:

  1. 如果文档元素SVG svg元素,则让value为第一个作为文档元素的子元素的SVG title元素的子文本内容

  2. 否则,让valuetitle 元素子文本内容,如果title 元素为 null,则为空字符串。

  3. 去除并折叠 ASCII 空白value中。

  4. 返回value

在设置时,必须运行以下列表中第一个匹配条件的步骤:

如果文档元素SVG svg元素
  1. 如果有一个作为文档元素子元素的SVG title元素,则让element为第一个这样的元素。

  2. 否则:

    1. element为给定文档元素节点文档titleSVG 命名空间创建元素的结果。

    2. element插入作为文档元素第一个子节点

  3. element中使用给定值字符串替换所有

如果文档元素HTML 命名空间
  1. 如果title 元素为 null 并且head 元素为 null,则返回。

  2. 如果title 元素非 null,则让elementtitle 元素

  3. 否则:

    1. element为给定文档元素节点文档titleHTML 命名空间创建元素的结果。

    2. element附加到head 元素

  4. element中使用给定值字符串替换所有

否则

什么也不做。


document.body [ = value ]

Document/body

Support in all current engines.

Firefox60+Safari1+Chrome1+
Opera9.6+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

返回body 元素

可以设置,以替换body 元素

如果新值不是bodyframeset元素,这将抛出一个"HierarchyRequestError" DOMException

文档的 body 元素是第一个作为html 元素的子元素的body 元素frameset 元素,如果存在,否则为 null。

在获取时,body属性必须返回文档的body 元素(一个body元素,一个frameset元素,或 null)。在设置时,必须运行以下算法:

  1. 如果新值不是bodyframeset元素,则抛出一个"HierarchyRequestError" DOMException
  2. 否则,如果新值与body 元素相同,则返回。
  3. 否则,如果body 元素不是 null,则在替换 body 元素与新值的父节点内的body 元素并返回。
  4. 否则,如果没有文档元素,则抛出一个"HierarchyRequestError" DOMException
  5. 否则,body 元素为 null,但有一个文档元素。将新值附加到文档元素

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

Document/images

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回一个HTMLCollection,其中包含img元素在Document中。

document.embeds

Document/embeds

所有当前引擎都支持。

Firefox1+Safari10.1+Chrome64+
Opera51+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+
document.plugins

Document/plugins

所有当前引擎都支持。

Firefox1+Safari10.1+Chrome64+
Opera51+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS10.3+Chrome Android?WebView Android?Samsung Internet?Opera Android47+

返回一个HTMLCollection,其中包含embed元素在Document中。

document.links

Document/links

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回一个HTMLCollection,其中包含aarea元素在Document中具有href属性。

document.forms

Document/forms

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回一个 HTMLCollection,包含在 form 元素的 Document 中。

document.scripts

Document/scripts

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回一个HTMLCollection,包含script元素在Document中。

images属性必须返回一个根植于HTMLCollectionDocument节点,过滤器仅匹配img元素。

embeds属性必须返回一个根植于HTMLCollectionDocument节点,过滤器仅匹配embed元素。

plugins属性必须返回与embeds属性返回的对象相同的对象。

links属性必须返回一个根植于HTMLCollectionDocument节点,过滤器仅匹配带有a元素的href属性和带有area元素的href属性。

forms属性必须返回一个HTMLCollection的根节点在文档节点,过滤器仅匹配form元素。

scripts属性必须返回一个HTMLCollection的根节点在文档节点,过滤器仅匹配script元素。


collection = document.getElementsByName(name)

Document/getElementsByName

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera5+Edge79+
Edge (旧版)12+Internet Explorer5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

返回一个NodeList的元素在文档中有name属性值为name

getElementsByName(elementName)方法步骤是返回一个实时 NodeList包含文档中所有有name属性值为elementNameHTML 元素,按树顺序。当该方法再次在文档对象上使用相同的参数调用时,用户代理可以返回与之前调用返回的对象相同的对象。在其他情况下,必须返回一个新的NodeList对象。


document.currentScript

Document/currentScript

Support in all current engines.

Firefox4+Safari8+Chrome29+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回script元素,或者SVG script元素,当前正在执行的脚本,只要该元素代表一个经典脚本。在递归脚本执行的情况下,返回最早开始执行但尚未完成执行的脚本。

如果文档当前没有执行scriptSVG script元素(例如,因为正在运行的脚本是事件处理程序或超时),或者当前正在执行的scriptSVG script元素代表一个模块脚本,则返回 null。

currentScript属性,在获取时,必须返回最近设置的值。当文档创建时,currentScript必须初始化为 null。

此 API 在实现者和标准社区中已经失宠,因为它全局暴露scriptSVG script元素。因此,它在较新的上下文中不可用,例如运行模块脚本或在影子树中运行脚本时。我们正在研究在这种上下文中识别运行脚本的新解决方案,这不会使其全局可用:请参见问题#1013


接口Document支持命名属性支持的属性名称文档对象document的任何时刻包括以下内容,按贡献它们的元素的树顺序,忽略后面的重复项,值来自id属性在来自name属性的值之前贡献相同时:

为了确定命名属性name的值对于文档,用户代理必须返回使用以下步骤获得的值:

  1. elements成为带有name命名元素的列表,这些元素在文档树中的文档作为其根

    会有至少一个这样的元素,因为该算法否则不会被由 Web IDL 调用

  2. 如果elements只有一个元素,并且该元素是iframe元素,并且该iframe元素的内容可导航不为 null,则返回该元素的活动WindowProxy

  3. 否则,如果elements只有一个元素,则返回该元素。

  4. 否则,返回一个HTMLCollection的根节点在文档节点,过滤器仅匹配具有名称name命名元素

命名元素带有名称name,对于上述算法而言,是那些要么是:

embedobject元素被称为暴露的如果它没有暴露的object祖先,并且对于object元素,此外,还没有显示其回退内容或没有objectembed后代。


dir属性在文档接口中与dir内容属性一起定义。

3.2 元素

3.2.1 语义

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将更新渲染以显示进度的变化。

3.2.2 DOM中的元素

DOM中表示HTML元素的节点必须实现并向脚本公开本规范相关部分列出的接口。这包括在HTML元素XML文档中,即使这些文档在另一个上下文中(例如在XSLT转换内)。

DOM中的元素代表事物;也就是说,它们具有内在的意义,也称为语义。

例如,一个ol元素代表一个有序列表。

元素可以通过某种方式显式或隐式地被引用。DOM中的元素可以通过给元素一个id属性,然后创建一个超链接,使用该id属性的值作为片段标识符,来显式引用该元素。然而,引用并不需要超链接;任何引用该元素的方法都可以。

考虑以下被赋予id属性的figure元素:

<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>

可以使用超链接元素a创建一个基于超链接的引用,如下所示:

As we can see in <a href="#module-script-graph">figure 27</a>, ...

然而,还有许多其他方法可以引用figure元素,例如:

所有HTML元素接口继承的基本接口,并且必须由没有其他要求的元素使用的是HTMLElement接口。

HTMLElement

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android1+Samsung Internet?Opera Android10.1+

HTMLUnknownElement

所有当前引擎支持。

Firefox1+Safari6+Chrome15+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
[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接口包含与许多不同特性相关的方法和属性,因此该接口的成员在本规范的各个不同部分中进行了描述。


HTML命名空间中名称为name的元素的元素接口确定如下:

  1. 如果nameappletbgsoundblinkisindexkeygenmulticolnextidspacer,则返回HTMLUnknownElement

  2. 如果nameacronymbasefontbigcenternobrnoembednoframesplaintextrbrtcstrikett,则返回HTMLElement

  3. 如果namelistingxmp,则返回HTMLPreElement

  4. 否则,如果本规范定义了与局部名称name对应的元素类型的适当接口,则返回该接口。

  5. 如果其他适用规范定义了name的适当接口,则返回它们定义的接口。

  6. 如果name有效的自定义元素名称,则返回HTMLElement

  7. 返回HTMLUnknownElement

有效的自定义元素名称的情况下,使用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);

3.2.3 HTML元素构造函数

为了支持自定义元素功能,所有HTML元素都有特殊的构造函数行为。这是通过[HTMLConstructor] IDL扩展属性来表示的。它表明给定接口的接口对象在调用时将具有特定行为,详见以下定义。

[HTMLConstructor]扩展属性不得带有参数,并且只能出现在构造函数操作上。它必须仅在构造函数操作上出现一次,并且接口必须仅包含单个带注释的构造函数操作,而没有其他的。带注释的构造函数操作必须声明为不带参数。

带有[HTMLConstructor]扩展属性的构造函数操作的接口具有以下覆盖的构造函数步骤

  1. registry当前全局对象CustomElementRegistry对象。

  2. 如果NewTarget等于活动函数对象,则抛出TypeError

    这种情况可能发生在使用元素接口作为其构造函数定义自定义元素时:

    customElements.define("bad-1", HTMLButtonElement);
    new HTMLButtonElement();          // (1)
    document.createElement("bad-1");  // (2)

    在这种情况下,在执行HTMLButtonElement(显式调用如(1),或隐式调用如(2))时,活动函数对象NewTarget都是HTMLButtonElement。如果没有此检查,就可能创建本地名称为bad-1HTMLButtonElement实例。

  3. definitionregistry中构造函数等于NewTarget的条目。如果没有这样的定义,则抛出TypeError

    由于registry中不能有构造函数为undefined的条目,因此此步骤还防止HTML元素构造函数作为函数被调用(因为在这种情况下NewTarget将为undefined)。

  4. is value为null。

  5. 如果definition本地名称等于definition名称(即definition独立自定义元素),则:

    1. 如果活动函数对象不是HTMLElement,则抛出TypeError

      这种情况可能发生在定义不扩展任何本地名称但继承自非HTMLElement类的自定义元素时:

      customElements.define("bad-2", class Bad2 extends HTMLParagraphElement {});

      在这种情况下,在构造Bad2实例时发生的(隐式)super()调用期间,活动函数对象HTMLParagraphElement,而不是HTMLElement

  6. 否则(即definition定制内建元素),则:

    1. valid local names为在本规范或其他适用规范中定义的使用活动函数对象作为其元素接口的元素的本地名称列表。

    2. 如果valid local names不包含definition本地名称,则抛出TypeError

      这种情况可能发生在定义扩展给定本地名称但继承自错误类的自定义元素时:

      customElements.define("bad-3", class Bad3 extends HTMLQuoteElement {}, { extends: "p" });

      在这种情况下,在构造Bad3实例时发生的(隐式)super()调用期间,valid local names是包含qblockquote的列表,但definition本地名称p,它不在该列表中。

    3. is value设置为definition名称

  7. 如果definition构造栈为空,则:

    1. element内部创建一个实现接口的新对象的结果,该接口与活动函数对象对应,给定当前领域NewTarget

    2. element节点文档设置为当前全局对象关联的Document

    3. element命名空间设置为HTML命名空间

    4. element命名空间前缀设置为null。

    5. element本地名称设置为definition本地名称

    6. element自定义元素状态设置为“custom”。

    7. element自定义元素定义设置为definition

    8. elementis设置为is value

    9. 返回element

    当作者脚本直接构造新的自定义元素时,例如通过new MyCustomElement(),会发生这种情况。

  8. prototype为?获取(NewTarget,“prototype”)。

  9. 如果类型(prototype)不是对象,则:

    1. realm为?获取函数领域(NewTarget)。

    2. prototype设置为realm接口原型对象,其接口与活动函数对象相同。

    活动函数对象的领域可能不是realm,因此我们使用跨领域的“相同接口”的更一般概念;我们不是在寻找接口对象的等同性。这种后备行为,包括使用NewTarget的领域并在那里查找适当的原型,旨在匹配JavaScript内置和Web IDL的内部创建实现接口的新对象算法的类似行为。

  10. elementdefinition构造栈中的最后一个条目。

  11. 如果 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();
      }
    }

    这种情况也可能发生在自定义元素构造函数中的作者代码不合规地调用了两次super()时,因为根据JavaScript规范,这实际上会调用超类构造函数(即本算法)两次,然后抛出错误:

    class DontDoThisEither extends HTMLElement {
      constructor() {
        super();
    
        // This will throw, but not until it has already called into the HTMLElement constructor
        super();
      }
    }
  12. 执行?element.[[SetPrototypeOf]](prototype)。

  13. definition构造栈中的最后一个条目替换为已经构造的标记

  14. 返回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);

3.2.4 元素定义

本规范中的每个元素都有一个定义,包含以下信息:

类别

元素所属类别的列表。这些类别用于定义每个元素的内容模型。

元素可以使用的上下文

元素可以使用的上下文的非规范性描述。这些信息与允许此元素作为子元素的元素的内容模型是冗余的,仅为方便提供。

为简洁起见,仅列出了最具体的期望。

例如,所有短语内容都是流内容。因此,属于短语内容的元素将仅列为“在期望短语内容的地方”,因为这是更具体的期望。任何期望流内容的地方也期望短语内容,因此也符合此期望。

内容模型

规范性描述了必须作为子元素和后代元素包含的内容。

在 text/html 中省略标签

text/html 语法中,是否可以省略开始和结束标签的非规范性描述。这些信息与规范要求是冗余的,仅为方便提供。

内容属性

规范性列出了可以在元素上指定的属性(除非另有禁止),以及这些属性的非规范性描述。(破折号左边的内容是规范性的,右边的内容则不是。)

无障碍考虑

对于作者:ARIA 角色和 aria-* 属性的符合性要求定义在 ARIA in HTML 中。[ARIA] [ARIAHTML]

对于实现者:用户代理实现无障碍 API 语义的要求定义在 HTML Accessibility API Mappings 中。[HTMLAAM]

DOM 接口

元素必须实现的 DOM 接口的规范性定义。

随后是元素代表什么的描述,以及可能适用于作者和实现的任何其他规范性符合标准。有时还包括示例。

3.2.4.1 属性

属性值是一个字符串。除非另有规定,HTML 元素上的属性值可以是任何字符串值,包括空字符串,对于这些属性值中可以指定的文本没有限制。

3.2.5 内容模型

本规范中定义的每个元素都有一个内容模型:该元素预期内容的描述。HTML元素必须包含符合其内容模型中描述的要求的内容。元素的内容是其在DOM中的子节点。

ASCII空白字符始终允许出现在元素之间。用户代理会在源标记中的这些字符之间表示为DOM中的文本节点。仅包含这些字符序列的空文本节点被视为元素间空白

元素间空白、注释节点和处理指令节点在确定元素的内容是否符合其内容模型时,必须忽略这些节点,在遵循定义文档和元素语义的算法时,也必须忽略这些节点。

因此,如果元素A和第二个元素B具有相同的父节点,并且它们之间没有其他元素节点或文本节点(除了元素间空白),则可以说元素AB的前驱或后继。同样,如果一个元素仅包含元素间空白、注释节点和处理指令节点,则该节点是该元素的唯一子节点。

作者不得在未明确允许的地方使用HTML元素,除非其他规范明确要求。对于XML复合文档,如果这些上下文是在其他命名空间中的元素内定义的,那么这些上下文可以在这些元素内。

Atom订阅格式定义了一个content元素。当其type属性的值为xhtml时,Atom订阅格式要求它包含一个HTML div元素。因此,div元素在该上下文中是允许的,尽管这并未明确地由本规范规范化地陈述。[ATOM]

此外,HTML元素可以是孤立的节点(即没有父节点)。

例如,在脚本中创建一个td元素并将其存储在全局变量中是符合规范的,尽管td元素通常只应该在tr元素中使用。

var data = {
  name: "Banana",
  cell: document.createElement('td'),
};
3.2.5.1 “nothing”内容模型

当一个元素的内容模型为nothing时,该元素不得包含任何文本节点(除了元素间空白)和任何元素节点。

大多数内容模型为“nothing”的HTML元素,为了方便起见,也是空元素(在HTML语法中没有结束标签的元素)。然而,这些概念是完全独立的。

3.2.5.2 内容种类

HTML中的每个元素属于一个或多个类别,这些类别将具有相似特征的元素分组在一起。本规范中使用了以下广泛类别:

一些元素也属于其他类别,这些类别在本规范的其他部分定义。

这些类别的关系如下:

分区内容、标题内容、短语内容、嵌入内容和交互内容都是流内容的一种。元数据有时是流内容。元数据和交互内容有时是短语内容。嵌入内容也是一种短语内容,有时是交互内容。

其他类别也用于特定目的,例如,表单控件使用多个类别来定义通用要求。一些元素具有独特的要求,不属于任何特定类别。

3.2.5.2.1 元数据内容

元数据内容是设置其余内容的呈现或行为,或者设置文档与其他文档之间的关系,或者传递其他“带外”信息的内容。

来自其他命名空间的元素,其语义主要与元数据相关(例如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序列化中,这是不可能的。

3.2.5.2.2 流内容

大多数在文档和应用程序主体中使用的元素被归类为流内容

3.2.5.2.3 分节内容

分节内容是定义headerfooter元素作用范围的内容。

3.2.5.2.4 标题内容

标题内容定义了一个部分的标题(无论是显式标记为分节内容元素,还是由标题内容本身隐含)。

3.2.5.2.5 内联内容

内联内容是文档的文本,以及在段内级别标记这些文本的元素。内联内容的连续部分形成段落

大多数被归类为短语内容的元素只能包含本身也是短语内容的元素,而不能包含任何流内容。

文本在内容模型的上下文中,意味着要么没有内容,要么包含文本节点。文本有时被单独用作内容模型,但也属于短语内容,并且可以是元素间空白(如果文本节点是空的或仅包含ASCII空白)。

文本节点和属性值必须由标量值组成,不包括非字符控制字符,除ASCII空白外。

本规范根据具体上下文对文本节点和属性值的确切值提出了额外的约束。

3.2.5.2.6 嵌入内容

嵌入内容是将其他资源导入文档,或将来自其他词汇的内容插入文档的内容。

来自HTML命名空间以外的命名空间且传递内容但不传递元数据的元素,在本规范定义的内容模型中被视为嵌入内容。(例如,MathML或SVG。)

一些嵌入内容元素可以有后备内容:当外部资源无法使用时(例如,由于格式不支持),使用的内容。元素定义会说明后备内容的情况(如果有的话)。

3.2.5.2.7 交互内容

交互内容是专为用户交互设计的内容。

3.2.5.2.8 可感知内容

作为一般规则,允许任何流内容短语内容的元素,其内容模型中应至少有一个节点是可感知内容,并且未指定hidden属性。

可感知内容通过提供一些后代非空的文本,使元素非空,或者提供用户可以听到的内容(如音频元素),或用户可以看到的内容(如视频图片画布元素),或与之交互的内容(例如,交互式表单控件)。

这一要求并不是硬性规定,因为在许多情况下,元素可以合法地为空,例如用作占位符,稍后会由脚本填充,或当元素是模板的一部分时,在某些页面上通常会填充,但在其他页面上可能不相关。

鼓励符合性检查器为作者提供一种机制,帮助他们查找未满足此要求的元素,作为一种创作辅助工具。

以下元素是可感知内容:

3.2.5.2.9 脚本支持元素

脚本支持元素是那些本身不表示任何内容的元素(即它们不被渲染),而是用于支持脚本,例如为用户提供功能。

以下元素是脚本支持元素:

3.2.5.3 透明内容模型

有些元素被描述为透明;它们的内容模型描述中包含“透明”一词。一个透明元素的内容模型源自其父元素的内容模型:在透明部分所需的元素与透明元素所在的父元素内容模型中所需的元素相同。

例如,一个ins 元素在ruby 元素内不能包含rt 元素,因为ruby 元素的内容模型允许ins 元素的部分是允许短语内容的部分,而rt 元素不是短语内容

在某些情况下,透明元素嵌套在彼此之中,需要迭代地应用此过程。

考虑以下标记片段:

<p><object><param><ins><map><a href="/">Apples</a></map></ins></object></p>

要检查"Apples"是否允许在a 元素内,需要检查内容模型。a 元素的内容模型是透明的,map 元素的内容模型也是透明的,ins 元素的内容模型也是透明的,以及object 元素中包含ins 元素的部分也是透明的。object 元素包含在p 元素中,p元素的内容模型是短语内容。因此, "Apples"是允许的,因为文本是短语内容。

当一个透明元素没有父元素时,其内容模型中“透明”的部分必须改为接受任何流内容

3.2.5.4 段落

本节定义的段落术语不仅仅用于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>

流内容中的段落相对于没有ainsdelmap元素的文档外观来定义,因为这些元素及其混合内容模型可以跨越段落边界,如下面的前两个示例所示。

通常,最好避免元素跨越段落边界。维护这样的标记可能很困难。

以下示例采用早期示例中的标记,并在一些标记周围放置insdel 元素,显示文本已更改(尽管在这种情况下,这些更改确实没有多大意义)。请注意,本示例与前一个示例具有完全相同的段落,尽管存在insdel 元素——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的视图,用文档中的内容替换所有ainsdelmap 元素。然后,在view中,对于每个由其他类型内容不间断的兄弟短语内容节点组成的运行,在一个接受内容类型不仅限于短语内容以及短语内容的元素中,令first为运行的第一个节点,令 last为运行的最后一个节点。对于每个由至少一个既不是嵌入内容也不是元素间空白的节点组成的运行,原始DOM中的一个段落存在于first之前到last之后。(因此段落可以跨越ainsdelmap 元素。)

符合性检查器可能会警告作者他们有段落相互重叠的情况(这种情况可能发生在objectvideoaudiocanvas 元素中,及通过允许HTML进一步嵌入其中的其他命名空间中的元素间接发生,如SVG svgMathML math)。

一个段落也可以通过p元素显式形成。

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>

共有五个段落:

  1. 段落说“你可以玩我的猫模拟器。object我对此非常自豪。”,其中objectobject元素。
  2. 段落说“要查看猫模拟器,请使用以下链接之一:”。
  3. 段落说“下载模拟器文件”。
  4. 段落说“使用在线模拟器”。
  5. 段落说“或者,升级到Mellblom浏览器。”。

第一个段落被其他四个段落重叠。支持“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>

3.2.6 全局属性

Global_attributes

以下属性是所有HTML元素(即使那些未在本规范中定义的元素)共有的,并且可以在所有HTML元素上指定:

这些属性仅在本规范中定义为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>

Global_attributes/slot

Support in all current engines.

Firefox63+Safari10+Chrome53+
Opera?Edge79+
Edge (旧版)NoInternet Explorer?
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

DOM定义了用户代理对任何命名空间中的任何元素的classidslot属性的要求。 [DOM]

classidslot属性可以在所有HTML元素上指定。

HTML元素上指定时,class属性必须具有一个值,该值是由空格分隔的标记集,表示元素所属的各种类。

为元素分配类会影响CSS选择器中的类匹配、DOM中的getElementsByClassName()方法等功能。

作者可以在class属性中使用的标记没有其他限制,但鼓励作者使用描述内容性质的值,而不是描述内容所需呈现的值。

HTML元素上指定时,id属性值在元素的中的所有ID中必须是唯一的,并且必须包含至少一个字符。该值不得包含任何ASCII空白字符

id属性指定了其元素的唯一标识符(ID)

ID可以采取任何形式;特别是,ID可以仅由数字组成,以数字开头,以下划线开头,仅由标点符号组成等。

元素的唯一标识符可以用于多种目的,最著名的是作为使用片段链接到文档特定部分的方式,作为脚本定位元素的方式,以及从CSS样式化特定元素的方式。

标识符是不可解释的字符串。不应从id属性的值中推导出特定含义。

对于HTML元素slot属性没有特定的符合性要求。

这个slot属性用于分配插槽给一个元素:具有slot属性的元素被分配给由slot元素创建的插槽,其name属性的值与该slot属性的值匹配——但前提是该slot元素在其影子树中的宿主具有相应的slot属性值。


为了使辅助技术产品能够提供比HTML元素和属性更细粒度的接口,可以指定一组辅助技术产品的注释(ARIA rolearia-*属性)。 [ARIA]


以下事件处理程序内容属性可以在任何HTML元素上指定:

带星号的属性在body元素上指定时有不同的含义,因为这些元素公开具有相同名称的事件处理程序Window对象。

虽然这些属性适用于所有元素,但并不是在所有元素上都有用。例如,只有媒体元素才会接收到由用户代理触发的volumechange事件。


自定义数据属性(例如data-foldernamedata-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属性。

3.2.6.1 title 属性

Global_attributes/title

在所有当前引擎中支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

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>

一些元素,如linkabbr,和input,对title属性定义了额外的语义。

元素的建议信息是以下算法返回的值,一旦返回值,算法将终止。当算法返回空字符串时,则表示没有建议信息。

  1. 如果元素有title属性,则返回对其值运行规范化换行符的结果。

  2. 如果元素有父元素,则返回父元素的建议信息

  3. 返回空字符串。

用户代理应在元素有建议信息时通知用户,否则这些信息将不可发现。


HTMLElement/title

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

title IDL 属性必须反映title内容属性。

3.2.6.2 langxml:lang 属性

Global_attributes/lang

在所有当前引擎中支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

lang 属性(不在任何命名空间中)指定元素内容的主要语言以及任何包含文本的元素属性。其值必须是有效的 BCP 47 语言标签,或为空字符串。将该属性设置为空字符串表示主要语言未知。[BCP47]

lang 属性在XML 命名空间中定义于 XML 中。[XML]

如果这些属性在元素中省略,那么该元素的语言与其父元素的语言相同(如果有父元素)(slot 元素在shadow tree 中除外)。

没有命名空间的 lang 属性可以用于任何HTML 元素

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 命名空间的元素

使用该属性的值。

如果节点是一个HTML 元素SVG 命名空间中的元素,并且它具有没有命名空间的 lang 属性

使用该属性的值。

如果节点的父节点是shadow root

使用该 语言shadow root主机

如果节点的父元素不为空

使用该语言父元素

否则

如果设置了默认语言,则该节点的语言为该语言。如果没有设置默认语言,则必须使用来自更高层协议(如 HTTP)的语言信息(如果有)作为最终的回退语言。如果没有任何这种语言信息,并且在更高层协议中报告了多种语言,则该节点的语言未知,相应的语言标签为空字符串。

如果结果值不是识别的语言标签,则必须将其视为具有给定语言标签的未知语言,与所有其他语言不同。为了进行回绕或与期望语言标签的其他服务进行通信,用户代理应该将未知的语言标签不作修改地传递,并标记为 BCP 47 语言标签,以便后续服务不会将数据解释为另一种类型的语言描述。[BCP47]

因此,例如,带有lang="xyzzy"的元素将被选择器:lang(xyzzy)(例如在 CSS 中)匹配,但不会被:lang(abcde)匹配,即使两者同样无效。同样,如果网络浏览器和屏幕阅读器共同工作,浏览器会告知屏幕阅读器该元素的语言是“xyzzy”,即使它知道这是无效的,只是以防屏幕阅读器实际上支持该标签的语言。即使屏幕阅读器同时支持 BCP 47 和另一种语法来编码语言名称,并且在另一种语法中字符串“xyzzy”是一种表示白俄罗斯语的方式,屏幕阅读器将文本视为白俄罗斯语是错误的,因为“xyzzy”不是 BCP 47 编码中描述白俄罗斯语的方式(BCP 47 使用代码“be”表示白俄罗斯语)。

如果结果值为空字符串,则必须将其解释为该节点的语言明确未知。


用户代理可以使用元素的语言来确定适当的处理或渲染(例如在选择适当的字体或发音,字典选择,或表单控件如日期选择器的用户界面)。


HTMLElement/lang

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

lang IDL 属性必须反映没有命名空间的lang内容属性。

3.2.6.3 translate 属性

Global_attributes/translate

在所有当前引擎中支持。

Firefox111+Safari6+Chrome19+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

translate 属性用于指定在页面本地化时,是否翻译元素的属性值及其文本节点子元素的值,还是保持它们不变。该属性是一个枚举属性,具有以下关键字和状态:

关键字 状态 简短描述
yes yes 翻译模式设置为翻译启用
(空字符串)
no no 翻译模式设置为不翻译

属性的缺省值无效值缺省都是继承状态。

每个元素(即使是非 HTML 元素)都有一个翻译模式,可以是翻译启用状态,也可以是不翻译状态。如果HTML 元素translate属性处于yes状态,则该元素的翻译模式处于翻译启用状态;否则,如果该元素的translate属性处于no状态,则该元素的翻译模式处于不翻译状态。否则,元素的translate属性处于继承状态,或者该元素不是HTML 元素,因此没有translate属性;无论哪种情况,元素的翻译模式与其父元素的状态相同,如果有的话,或者如果元素的父元素为空,则处于翻译启用状态。

当元素处于翻译启用状态时,元素的可翻译属性及其文本节点子元素的值在页面本地化时应被翻译。

当元素处于不翻译状态时,元素的属性值及其文本节点子元素的值在页面本地化时应保持不变,例如因为该元素包含个人姓名或计算机程序的名称。

以下属性是可翻译属性

其他规范可以定义其他也是可翻译属性的属性。例如,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>
3.2.6.4 dir 属性

Global_attributes/dir

Support in all current engines.

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

The dir attribute 是一个枚举属性,具有以下关键字和状态:

关键字 状态 简要描述
ltr ltr 元素内容是明确方向隔离的从左到右文本。
rtl rtl 元素内容是明确方向隔离的从右到左文本。
auto auto 元素内容是明确方向隔离的文本,但方向应通过程序根据元素内容确定(如下所述)。

auto状态使用的启发式方法非常粗略(它只看具有强方向性的第一个字符,类似于双向算法中的段落级确定)。建议作者仅在文本方向确实未知且无法应用更好的服务器端启发式方法时才使用此值。[BIDI]

对于textareapre元素,启发式方法是逐段应用的。

该属性的缺省值无效值缺省都是未定义状态。


元素(任何元素,不仅是HTML元素)的方向性要么是'ltr',要么是'rtl'。给定元素element方向性的计算方法如下:

ltr

返回'ltr'。

rtl

返回'rtl'。

auto
  1. result成为element自动方向性

  2. 如果result为null,则返回'ltr'。

  3. 返回result

undefined
如果elementbdi元素
  1. result成为element自动方向性

  2. 如果result为null,则返回'ltr'。

  3. 返回result

如果elementinput元素且其type属性处于电话状态

返回'ltr'。

否则

返回element父方向性

由于dir属性仅对HTML元素定义,它不能出现在其他命名空间的元素上。因此,其他命名空间的元素总是使用父方向性

自动方向性表单关联元素包括:

给定元素element自动方向性的计算方法如下:

  1. 如果 element 是一个自动方向性关联表单元素:

    1. 如果 element包含 一个双向字符类型为 AL 或 R 的字符,并且在元素的中该字符之前没有任何双向字符类型为 L 的字符,则返回 'rtl'。 [BIDI]

    2. 如果 element不是空字符串, 则返回 'ltr'。

    3. 返回 null。

  2. 如果 element 是一个 slot 元素,且其 是一个 shadow root 并且 element已分配节点不为空:

    1. 对于每个 element已分配节点的节点 child

      1. childDirection 为 null。

      2. 如果 child 是一个 Text 节点,则将 childDirection 设置为 child文本节点方向性

      3. 否则:

        1. 断言child 是一个 Element 节点。

        2. childDirection 设置为 child包含文本自动方向性,其中canExcludeRoot 设置为 true。

      4. 如果 childDirection 不是 null,则返回 childDirection

    2. 返回 null。

  3. 返回 element包含文本自动方向性,其中canExcludeRoot 设置为 false。

要计算元素 element包含文本自动方向性,且带有布尔值 canExcludeRoot

  1. 对于每个 element后代节点,按树顺序

    1. 如果以下任意条件成立

      • descendant
      • 作为 element 后代的任何祖先元素
      • 如果 canExcludeRoot 为 true,element

      属于以下类型之一

      继续

    2. 如果 descendant 是一个 slot 元素,并且其 是一个shadow root,则返回该方向性

    3. 如果 descendant 不是一个 Text 节点,则继续

    4. resultdescendant文本节点方向性

    5. 如果 result 不是 null,则返回 result

  2. 返回 null。

要计算给定 Text 节点 text文本节点方向性

  1. 如果 text数据 不包含双向字符类型为 L、AL 或 R 的代码点,则返回 null。 [BIDI]

  2. codePointtext数据中第一个双向字符类型为 L、AL 或 R 的代码点。

  3. 如果 codePoint 的双向字符类型为 AL 或 R,则返回 'rtl'。

  4. 如果 codePoint 的双向字符类型为 L,则返回 'ltr'。

要计算给定元素 element父级方向性

  1. parentNodeelement 的父节点。

  2. 如果 parentNode 是一个 shadow root,则返回 parentNode方向性,即 parentNode宿主的方向性。

  3. 如果 parentNode 是一个元素,则返回 parentNode方向性

  4. 返回 'ltr'。

此属性涉及使用双向算法进行渲染


HTML元素的一个属性的方向性,在该属性的文本要以某种方式包含在渲染中时,其确定方法如下:

如果该属性是支持方向性的属性,并且该元素的dir属性处于auto状态

查找属性值的第一个双向字符类型为L、AL或R的字符(按逻辑顺序)。[BIDI]

如果找到了这样的字符,并且它的双向字符类型为AL或R,则该属性的方向性为'rtl'。

否则,该属性的方向性为'ltr'。

否则
该属性的方向性元素的方向性相同。

以下属性是支持方向性的属性


document.dir [ = value ]

返回html元素dir属性的值(如果有)。

可以设置为"ltr"、"rtl"或"auto",以替换html元素dir属性的值。

如果没有html元素,则返回空字符串并忽略新值。

HTMLElement/dir

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

dir IDL属性在元素上必须反映该元素的dir内容属性,仅限于已知值

Document/dir

Support in all current engines.

Firefox1+Safari10.1+Chrome64+
Opera51+Edge79+
Edge (旧版)12+Internet Explorer5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+

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?”出现在阿拉伯文本的左侧。

3.2.6.5 style 属性

Global_attributes/style

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

所有HTML元素 都可以设置style 内容属性。这是一个样式属性,定义在 CSS Style Attributes中。[CSSATTR]

在支持CSS的用户代理中,当添加或更改属性值时,必须按照样式属性的规则解析该属性的值。 [CSSATTR]

但是,如果在执行应该通过内容安全政策阻止元素的内联行为吗?算法时返回“Blocked”,并在属性的元素、“style attribute”和属性的值上执行,那么属性值中定义的样式规则不得应用于元素[CSP]

使用任何元素的style 属性的文档,即使这些属性被删除,也必须能够理解和使用。

特别是,使用style 属性来隐藏和显示内容,或传达文档中未包含的意义,是不符合规范的。(要隐藏和显示内容,请使用hidden 属性。)


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>
3.2.6.6 嵌入自定义不可见数据 使用 data-* 属性

Global_attributes/data-*

在所有当前引擎中支持。

Firefox6+Safari5.1+Chrome7+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

自定义数据属性是一种没有命名空间的属性,其名称以字符串 "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

HTMLElement/dataset

在所有当前引擎中支持。

Firefox6+Safari5.1+Chrome7+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android11+

SVGElement/dataset

在所有当前引擎中支持。

Firefox51+Safari5.1+Chrome55+
Opera41+Edge79+
Edge (旧版)17+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android41+

返回一个 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 的名称-值对,请运行以下算法:

  1. list 成为空的名称-值对列表。

  2. 对于 DOMStringMap关联元素 上的每个内容属性,其前五个字符是字符串 "data-",其余字符(如果有)不包含任何 ASCII 大写字母,按这些属性在元素的 属性列表中列出的顺序,为 list 添加一个名称-值对,其名称为去掉前五个字符后的属性名称,其值为属性的值。

  3. 对于 list 中的每个名称,对于名称中每个后面跟有一个 ASCII 小写字母 的 U+002D 连字符,将 U+002D 连字符删除,并用相同字符 转换为 ASCII 大写字母 替换其后的字符。

  4. 返回 list

在任何时刻,支持的属性名称DOMStringMap对象上,是从获取DOMStringMap的名称-值对时返回的每对名称,在返回的顺序中。

确定命名属性的值 name,对于 DOMStringMap,返回名称-值对列表中名称为 name 的值部分。

设置新命名属性的值设置现有命名属性的值 对于 DOMStringMap,给定属性名称 name 和新值 value,运行以下步骤:

  1. 如果 name 包含一个后跟 ASCII 小写字母 的 U+002D 连字符,则抛出一个 "SyntaxError" DOMException

  2. 对于 name 中的每个 ASCII 大写字母,在该字符前插入一个 U+002D 连字符,并将该字符替换为相同字符 转换为 ASCII 小写字母

  3. name 的前面插入字符串 data-

  4. 如果 name 不匹配 XML 名称 生成规则,则抛出一个 "InvalidCharacterError" DOMException

  5. 使用 namevalueDOMStringMap关联元素 设置一个属性值。

删除现有命名属性 name 对于 DOMStringMap,运行以下步骤:

  1. 对于 name 中的每个 ASCII 大写字母,在该字符前插入一个 U+002D 连字符,并将该字符 替换为相同字符 转换为 ASCII 小写字母

  2. name 的前面插入字符串 data-

  3. 通过名称删除属性 给定 nameDOMStringMap关联元素

此算法只会由 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
  }
}

3.2.7 innerTextouterText 属性

HTMLElement/innerText

在所有当前引擎中支持。

Firefox45+Safari1+Chrome1+
Opera9.6+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android1+Samsung Internet?Opera Android10.1+
element.innerText [ = value ]

返回元素的“渲染后”文本内容。

可以设置,替换元素的子节点为给定值,但换行符会转换为 br 元素。

element.outerText [ = value ]

返回元素的“渲染后”文本内容。

可以设置,替换元素为给定值,但换行符会转换为 br 元素。

获取文本步骤,给定 HTMLElement element,如下:

  1. 如果 element被渲染 或用户代理是非 CSS 用户代理,则返回 element后代文本内容

    这一步可能产生令人惊讶的结果,因为当对未 被渲染 的元素调用 innerText getter 时,它的文本内容会被返回,但当对 被渲染 的元素访问时,其所有未 被渲染 的子元素的文本内容将被忽略。

  2. results 为一个新的空的 列表

  3. 对于 element 的每个子节点 node

    1. current 为对 node 运行 渲染文本收集步骤 所得到的 列表results 中的每一项将是一个 字符串 或一个正整数(一个需要的换行符计数)。

      直观上,一个 需要的换行符计数 项表示在该点有一定数量的换行符,但它们可以与相邻的 需要的换行符计数 项的换行符合并,类似于 CSS 的边距折叠。

    2. current 中的每一项附加到 results

  4. 移除 results 中所有空字符串项。

  5. 移除 results 开头或结尾的任何连续的 需要的换行符计数 项。

  6. 替换 每个剩余的连续的 需要的换行符计数 项,以包含与该 需要的换行符计数 项中的最大值相同数量的 U+000A LF 码点的字符串。

  7. 返回 results 中字符串项的连接结果。

HTMLElement/outerText

在所有当前引擎中支持。

Firefox98+Safari1.3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android1+Samsung Internet?Opera Android12.1+

innerTextouterText getter 步骤是运行 获取文本步骤,以 this 为参数。

渲染文本收集步骤,给定 节点 node,如下:

  1. node 的每个子节点按 树顺序运行 渲染文本收集步骤 所得到的结果连接为一个 列表

  2. 如果 node计算值'visibility' 不是 'visible',则返回 items

  3. 如果 node被渲染,则返回 items。对于此步骤,如果 计算值'display' 属性不是 'none',则以下元素必须按如下描述行为:

    items 可能由于 'display:contents' 而非空。

  4. 如果 nodeText 节点,则对于由 node 生成的每个 CSS 文本框,按内容顺序,计算应用 CSS 'white-space' 处理规则和 'text-transform' 规则后的文本,将 items 设置为结果字符串的 列表,并返回 items。CSS 'white-space' 处理规则稍有修改:行尾的可折叠空格总是会被折叠,但只有当行是块的最后一行,或以 br 元素结尾时,才会被移除。软连字符应保留。[CSSTEXT]

  5. 如果 nodebr 元素,则向 items 添加包含单个 U+000A LF 码点的字符串。

  6. 如果 node计算值'display''table-cell',且 nodeCSS 盒 不是其包围的 'table-row' 盒的最后一个 'table-cell' 盒,则向 items 添加包含单个 U+0009 TAB 码点的字符串。

  7. 如果 node计算值'display''table-row',且 nodeCSS 盒 不是最近的祖先 'table' 盒的最后一个 'table-row' 盒,则向 items 添加包含单个 U+000A LF 码点的字符串。

  8. 如果 nodep 元素,则在 items 的开头和结尾添加 2(一个需要的换行符计数)。

  9. 如果 node使用值'display'块级'table-caption',则在 items 的开头和结尾添加 1(一个需要的换行符计数)。[CSSDISPLAY]

    浮动和绝对定位的元素属于此类别。

  10. 返回 items

请注意,大多数替换元素(例如 textareainputvideo —— 但不包括 button)的后代节点严格来说不会被 CSS 渲染,因此在此算法中没有 CSS 盒

此算法可以概括为适用于 范围。然后我们可以将其用作 Selection 的字符串化的基础,甚至可以直接在 范围 上公开它。请参阅 Bugzilla bug 10583


设置内部文本步骤,给定 HTMLElement element 和字符串 value,如下:

  1. fragment 为给定 element渲染文本片段

  2. 替换所有 element 内的 fragment

innerText setter 步骤是运行 设置内部文本步骤

outerText setter 步骤如下:

  1. 如果 this 的父节点为 null,则抛出 "NoModificationAllowedError" DOMException

  2. nextthis下一个兄弟节点

  3. previousthis上一个兄弟节点

  4. fragment 为给定 value渲染文本片段,给定 this节点文档

  5. 如果 fragment 没有 子节点,则 追加 一个新的 Text 节点,其 数据为空字符串,其 节点文档this节点文档fragment

  6. thisthis 的父节点内替换 fragment

  7. 如果 next 非空且 next上一个兄弟节点Text 节点,则 合并到下一个文本节点,给定 next上一个兄弟节点

  8. 如果 previousText 节点,则 合并到下一个文本节点,给定 previous

渲染文本片段,给定字符串 inputDocument document,运行以下步骤:

  1. fragment 为一个新的 DocumentFragment,其 节点文档document

  2. position位置变量,最初指向 input 的开头。

  3. text 为空字符串。

  4. position 未越过 input 的末尾时:

    1. 收集input 给定 position 开始的非 U+000A LF 或 U+000D CR 的一系列码点,并将 text 设置为结果。

    2. 如果 text 不是空字符串,则 追加 一个新的 Text 节点,其 数据text,其 节点文档documentfragment

    3. position 未越过 input 的末尾,且 position 处的码点为 U+000A LF 或 U+000D CR 时:

      1. 如果 position 处的码点为 U+000D CR 且下一个码点为 U+000A LF,则将 position 前移到 input 的下一个码点。

      2. position 前移到 input 的下一个码点。

      3. 追加documentbrHTML 命名空间 创建的元素的结果到 fragment

  5. 返回 fragment

与下一个文本节点合并,给定 Text 节点 node

  1. nextnode下一个兄弟节点

  2. 如果 next 不是一个 Text 节点,则返回。

  3. nodenode数据长度、0 和 next数据替换数据。

  4. 移除 next

3.2.8 与双向算法相关的要求

3.2.8.1 双向算法格式化字符的编写一致性标准

HTML元素中的文本内容,以及其内容中的文本节点,以及HTML元素中允许自由格式文本的属性中的文本,可以包含范围为 U+202A 至 U+202E 和 U+2066 至 U+2069 的字符(双向算法格式化字符)。[BIDI]

作者被鼓励使用 dir 属性、bdo 元素和 bdi 元素,而不是手动维护双向算法格式化字符。双向算法格式化字符与 CSS 交互不佳。

3.2.8.2 用户代理一致性标准

用户代理必须实现 Unicode 双向算法,以确定在渲染文档和文档部分时字符的正确排序。[BIDI]

HTML 到 Unicode 双向算法的映射必须通过以下三种方式之一进行。用户代理必须实现 CSS,特别是 CSS 的 'unicode-bidi''direction''content' 属性,并且在其用户代理样式表中,必须包含在本规范的渲染部分中给出的使用这些属性的规则;或者,用户代理必须表现得像实现了上述属性,并且有一个包含所有上述规则的用户代理样式表,但不允许文档中指定的样式表覆盖它们;或者,用户代理必须实现另一种具有等效语义的样式语言。[CSSGC]

以下元素和属性的要求由渲染部分定义,由于本节中的要求,这些要求对所有用户代理(不仅仅是那些支持建议的默认渲染的用户代理)都是强制性的:

3.2.9 与 ARIA 及平台无障碍 API 相关的要求

HTML 元素上实现无障碍 API 语义的用户代理要求在HTML Accessibility API Mappings中定义。除了那里规定的规则外,对于一个自定义元素 element,默认的 ARIA 角色语义按如下方式确定:[HTMLAAM]

  1. mapelement内部内容属性映射

  2. 如果 map["role"] 存在,则返回它。

  3. 返回无角色。

类似地,对于一个自定义元素 element,默认的 ARIA 状态和属性语义,对于名为 stateOrProperty 的状态或属性,按如下方式确定:

  1. 如果 element附加内部不为空:

    1. 如果 element附加内部获取 stateOrProperty 关联元素存在,则返回运行结果。

    2. 如果 element附加内部获取 stateOrProperty 关联元素存在,则返回运行结果。

  2. 如果 element内部内容属性映射[stateOrProperty] 存在,则返回它。

  3. 返回 stateOrProperty 的默认值。

此处提到的“默认语义”有时在ARIA中也称为“本机”、“隐式”或“主机语言”语义。[ARIA]

这些定义的一个含义是默认语义可以随时间变化。这允许自定义元素具有与内置元素相同的表达能力;例如,比较 a 元素的默认 ARIA 角色语义在 href 属性添加或移除时如何变化。

有关实际应用的示例,请参见自定义元素部分


HTML 元素上检查使用 ARIA rolearia-* 属性的一致性检查器要求在ARIA in HTML中定义。[ARIAHTML]

4 HTML元素

4.1 文档元素

4.1.1 html 元素

元素/html

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLHtmlElement

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
无。
可以使用此元素的上下文:
作为文档的 文档元素
在复合文档中,只要允许子文档片段的地方。
内容模型:
一个 head 元素,后面跟着一个 body 元素。
在 text/html 中的标签省略:
如果 html 元素的 开始标签 可以省略, 如果 html 元素内的第一个内容不是 注释
如果 html 元素的 结束标签 可以省略,前提是 html 元素后面没有紧接着一个 注释
内容属性:
全局属性
无障碍考虑:
对于作者
对于实施者
DOM 接口:
[Exposed=Window]
interface HTMLHtmlElement : HTMLElement {
  [HTMLConstructor] constructor();

  // also has obsolete members
};

html 元素 表示 HTML 文档的根。

建议作者在根 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>

4.2 文档元数据

4.2.1 head 元素

Element/head

支持所有当前的引擎。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge(遗留版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLHeadElement

支持所有当前的引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge(遗留版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别
无。
可以使用该元素的上下文
作为 html 元素中的第一个元素。
内容模型
如果文档是 一个 iframe srcdoc 文档 或 如果从更高层协议中可以获得标题信息:零个或多个 元数据内容 元素,其中最多一个是 title 元素,最多一个是 base 元素。
否则:一个或多个 元数据内容 元素,其中恰好一个是 title 元素,最多一个是 base 元素。
在 text/html 中的标签省略
head 元素的 开始标签 可以省略,如果该元素为空,或者如果 head 元素中的第一个元素是一个元素。
head 元素的 结束标签 可以省略,如果 head 元素后面没有紧接着 ASCII 空白字符注释
内容属性
全局属性
可访问性考虑
针对作者
针对实施者
DOM 接口
[Exposed=Window]
interface HTMLHeadElement : HTMLElement {
  [HTMLConstructor] constructor();
};

head 元素 表示 一个 文档的元数据集合。

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 元素。

4.2.2 title 元素

Element/title

在所有当前引擎中均受支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer1+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLTitleElement

在所有当前引擎中均受支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别
元数据内容
此元素可使用的上下文
在不包含其他 head 元素中包含的 title 元素。
内容模型
文本,不是 元素间的空白
文本/html 中的标签省略
两个标签都不能省略。
内容属性
全局属性
可访问性考虑
针对作者
针对实施者
DOM 接口
[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 元素的内容以这种方式使用时,方向性 应用于设置用户界面中文档标题的方向性。

4.2.3 base 元素

Element/base

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge(遗留版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLBaseElement

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge(遗留版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别
元数据内容
可以使用该元素的上下文
在不包含其他 head 元素的 base 元素中。
内容模型
在 text/html 中的标签省略
没有 结束标签
内容属性
全局属性
href文档基本 URL
target — 默认 可导航 用于 超链接 导航表单提交
可访问性考虑
对于作者
对于实施者
DOM 接口
[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 属性,则除第一个之外的所有元素都将被忽略。

获取元素的目标,给定一个 aarea, 或 form 元素 element,以及一个可选的字符串或空值 target (默认为 null),请执行以下步骤:

  1. 如果 target 为 null,则:

    1. 如果 element 有一个 target 属性,则将 target 设置为该属性的值。

    2. 否则,如果 element节点文档 包含一个 base 元素具有一个 target 属性,则将 target 设置为第一个此类 base 元素的 target 属性的 值。

  2. 如果 target 不为 null,并且包含一个 ASCII 制表符或换行符 和一个 U+003C (<),则将 target 设置为 "_blank"。

  3. 返回 target


在文档树中第一个具有 base 元素的 base 元素具有 href 内容属性的 冻结基本 URL冻结基本 URL 必须在任何以下情况发生时 立即 为一个元素 设置

设置冻结基本 URL 为元素 element

  1. document 成为 element节点文档

  2. urlRecord 成为 解析 elementhref 内容属性的结果, 使用 document后备基本 URL,和 document字符编码。(因此,base 元素不会受到自身的影响。)

  3. 如果以下任何情况为真:

    然后将 element冻结基本 URL 设置为 document后备基本 URL 并返回。

  4. element冻结基本 URL 设置为 urlRecord

href IDL 属性,在获取时,必须返回运行以下算法的结果:

  1. document 成为 element节点文档

  2. url 成为该元素的 href 属性的值(如果有),否则为空字符串。

  3. urlRecord 成为 解析 url 的结果,使用 document后备基本 URLdocument字符编码。 (因此,base 元素不会受到其他 base 元素或 自身的影响。)

  4. 如果 urlRecord 失败,则返回 url

  5. 返回 序列化urlRecord

href IDL 属性,在设置时,必须将 href 内容属性设置为给定的新值。

target IDL 属性必须 反映同名的内容 属性。

在这个例子中,一个 base 元素用于设置 文档基本 URL

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>This is an example for the &lt;base&gt; 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" 的链接。

Element/link

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLLinkElement

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
类别:
元数据内容
如果元素是允许出现在正文中的: 流内容
如果元素是允许出现在正文中的: 短语内容
此元素可使用的上下文:
在需要元数据内容的地方。
在一个 noscript 元素中,该元素是 head 元素的子元素。
如果元素是允许出现在正文中的: 在需要短语内容的地方。
内容模型:
无内容
在text/html中的标签省略:
没有结束标签
内容属性:
全局属性
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样式表集名称
无障碍考量:
针对作者
针对实现者
DOM接口:
[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,可能被空格包围。必须存在 hrefimagesrcset 属性中的一个或两个。

如果 hrefimagesrcset 属性都不存在,则该元素不定义链接。

链接的类型(关系)由 rel 属性的值给出,该属性(如果存在)必须具有一个 唯一的用空格分隔的标记的无序集合允许的关键字及其含义 在后面的部分定义。如果 rel 属性缺失、没有关键字,或使用的关键字都不符合本规范中的定义,则该元素不会创建任何链接。

rel支持的标记 是在 HTML 链接类型 中定义的关键字,这些关键字在 link 元素上是被允许的,会影响处理模型,并且由用户代理支持。可能的 支持的标记 包括 alternatedns-prefetchexpecticonmanifestmodulepreloadnextpingbackpreconnectprefetchpreloadsearchstylesheetrel支持的标记 必须仅包括用户代理实现处理模型的标记。

理论上,用户代理可以支持 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 关键字),并且它们会受到其他属性(如 mediatitle)的不同影响。

例如,下面的 link 元素创建了两个 超链接(指向相同的页面):

<link rel="author license" href="/about">

这个元素创建的两个链接分别具有以下语义:一个是目标页面有关于当前页面作者的信息,另一个是目标页面有关于当前页面提供的许可证的信息。

使用 link 元素及其 rel 属性创建的 超链接 适用于整个文档。这与 rel 属性在 aarea 元素中的作用不同,后者指示了链接的类型,其上下文由链接在文档中的位置决定。

aarea 元素创建的链接不同,超链接link 元素创建时,默认情况下不会在文档中显示(在支持 建议默认渲染 的用户代理中)。即使通过 CSS 强制显示,它们也没有 激活行为。它们主要提供语义信息,可能被页面或其他使用页面内容的软件利用。此外,用户代理可以 提供自己的用户界面以跟随这些超链接

外部资源链接 的确切行为取决于具体的关系,按相关 链接类型 定义。


crossorigin 属性是一个 CORS 设置属性。它旨在用于 外部资源链接

media 属性指定资源适用于哪些媒体。其值必须是一个 有效的媒体查询列表

子资源完整性

支持所有当前的浏览器。

Firefox43+Safari11.1+Chrome45+
Opera?Edge79+
Edge(经典版)17+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

integrity 属性表示此元素负责的请求的 完整性元数据。该值为文本。该属性只能在具有 rel 属性且包含 stylesheetpreloadmodulepreload 关键字的 link 元素上指定。 [SRI]

hreflang 属性在 link 元素上具有与 hreflang 属性在 a 元素 上相同的语义。

type 属性提供了链接资源的 MIME 类型。它纯属建议。该值必须是 有效的 MIME 类型字符串

对于 外部资源链接type 属性作为提示提供给用户代理,以便它们可以避免获取不支持的资源。

referrerpolicy 属性是一个 引荐策略属性。它用于 外部资源链接,帮助设置 引荐策略,该策略在 获取和处理链接资源 时使用。[REFERRERPOLICY]

title 属性提供了链接的标题。除一个例外外,它纯属建议。该值为文本。唯一的例外是样式表链接,这些链接位于 文档树 中,对于这些链接,title 属性定义了 CSS 样式表集合

title 属性在 link 元素上的行为与大多数其他元素的全局 title 属性不同:没有标题的链接不会继承父元素的标题;它只是没有标题。


imagesrcset 属性可以存在,并且是一个 srcset 属性

imagesrcsethref 属性(如果没有使用 宽度描述符)共同构成 图像源源集合

如果 imagesrcset 属性存在且具有任何使用 宽度描述符图像候选字符串,则 imagesizes 属性也必须存在,并且是一个 sizes 属性imagesizes 属性贡献了 源大小源集合

imagesrcsetimagesizes 属性只能在 link 元素上指定,这些元素具有 rel 属性,该属性指定 preload 关键字,以及一个处于 "image" 状态的 as 属性。

这些属性允许预加载适当的资源,稍后由具有相应值的 img 元素使用,其 srcsetsizes 属性如下:

<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 属性是一个 阻塞属性。它用于链接类型 stylesheetexpect,并且只能在具有包含这些关键字的 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">

HTMLLinkElement/fetchPriority

Firefox不支持Safari🔰 预览+Chrome102+
Opera?Edge102+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

fetchpriority 属性是一个 获取优先级属性,旨在与 外部资源链接 一起使用,用于设置 请求优先级,该优先级在 获取和处理链接资源 时使用。


HTMLLinkElement/rel

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

IDL 属性 hrefhreflangintegritymediarelsizestypeblockingdisabled 必须 反映 同名的内容属性。

对于 color 属性,没有反映的 IDL 属性,但这可能会在以后添加。

HTMLLinkElement/as

在所有当前引擎中支持。

Firefox56+Safari10+Chrome50+
Opera?Edge79+
Edge (旧版)17+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

as IDL 属性必须 反映 as 内容属性,仅限于已知值

crossOrigin IDL 属性必须 反映 crossorigin 内容属性,仅限于已知值

HTMLLinkElement/referrerPolicy

所有当前引擎都支持。

Firefox50+Safari14.1+Chrome58+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

referrerPolicy IDL 属性必须 反映 referrerpolicy 内容属性,仅限于已知值。

fetchPriority IDL 属性必须 反映 fetchpriority 内容属性,仅限于已知值。

imageSrcset IDL 属性必须 反映 imagesrcset 内容属性。

imageSizes IDL 属性必须 反映 imagesizes 内容属性。

HTMLLinkElement/relList

所有当前引擎都支持。

Firefox30+Safari9+Chrome50+
Opera?Edge79+
Edge (旧版)17+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

relList IDL 属性必须 反映 rel 内容属性。

relList 属性可以用于功能检测,通过调用其 supports() 方法检查支持的 链接类型

4.2.4.1 处理 media 属性

如果链接是 超链接,那么 media 属性仅为建议性质,描述了文档设计的媒体类型。

然而,如果链接是 外部资源链接,那么 media 属性是规定性的。当 media 属性的值 匹配环境 且其他相关条件适用时,用户代理必须应用 外部资源,否则不得应用。

如果省略了 media 属性,则默认值为 "all",意味着默认情况下链接适用于所有媒体。

外部资源可能在该限制内定义了进一步的适用性限制。例如,CSS 样式表可能有一些 @media 块。本规范不会覆盖这些进一步的限制或要求。

4.2.4.2 处理 type 属性

如果 type 属性存在,则用户代理必须假设资源是给定类型的(即使那不是一个 有效的 MIME 类型字符串,例如空字符串)。如果属性被省略,但 外部资源链接 类型有一个默认类型定义,则用户代理必须假设资源是该类型。如果用户代理不支持给定的 MIME 类型 对于给定的链接关系,则用户代理应该 获取和处理链接资源;如果用户代理支持给定的 MIME 类型 对于给定的链接关系,则用户代理应该 获取和处理链接资源,按照为 外部资源链接 特定类型指定的适当时间进行。如果属性被省略,而 外部资源链接 类型没有默认类型定义,但用户代理会 获取和处理链接资源 如果类型已知且被支持,则用户代理应该 获取和处理链接资源,假设它将被支持。

用户代理不得将 type 属性视为权威 — 在获取资源时,用户代理不得使用 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 元素 el默认的获取和处理链接资源 如下:

  1. options 成为从 el 创建链接选项 的结果。

  2. request 成为给定 options创建链接请求 的结果。

  3. 如果 request 为 null,则返回。

  4. 设置 request同步标志

  5. 运行 链接资源获取设置步骤,给定 elrequest。如果结果为 false,则返回。

  6. 如果 elrel 属性包含关键字 stylesheet,则将 request发起者类型 设置为 "css";否则设置为 "link"。

  7. 获取 request,将 processResponseConsumeBody 设置为以下步骤,给定 响应 response 和 null、失败,或 字节序列 bodyBytes

    1. success 为 true。

    2. 如果以下任何一个为真:

      • bodyBytes 为 null 或失败;或者

      • response状态 不是一个 ok 状态

      则将 success 设置为 false。

      注意,特定内容的错误,例如 CSS 解析错误或 PNG 解码错误,不会影响 success

    3. 否则,等待 链接资源关键子资源 加载完成。

      定义链接类型的 关键子资源(例如 CSS)的规范,预计会描述如何获取和处理这些子资源。然而,由于目前这尚不明确,本规范描述了等待 链接资源关键子资源 被获取和处理,期望这样能正确完成。

    4. 给定 elsuccessresponsebodyBytes处理链接资源

给定一个 链接处理选项 options创建链接请求

  1. 断言: optionshref 不是空字符串。

  2. 如果 optionsdestination 为 null,则返回 null。

  3. url 成为给定 options编码解析 URL 的结果,相对于 options基本 URL

    传递基本 URL 而不是文档或环境的问题由 issue #9715 跟踪。

  4. 如果 url 失败,则返回 null。

  5. request 成为给定 urloptions创建潜在 CORS 请求 的结果,以及 optionsdestinationcrossorigin

  6. request策略容器 设置为 options策略容器

  7. request完整性元数据 设置为 options完整性

  8. request加密随机数元数据 设置为 options加密随机数元数据

  9. request引用政策 设置为 options引用政策

  10. request客户端 设置为 options环境

  11. request优先级 设置为 options获取优先级

  12. 返回 request

用户代理可以选择仅在需要时尝试 获取和处理 这些资源,而不是主动获取所有未应用的 外部资源

类似于 获取和处理链接资源 算法,所有 外部资源链接 都有一个 处理链接资源 算法,该算法接受一个 link 元素 el,一个布尔值 success,一个 响应 response,以及一个 字节序列 bodyBytes。各个链接类型可以提供自己的 处理链接资源 算法,但除非明确声明,否则该算法不执行任何操作。

除非对给定的 rel 关键字另有说明,否则元素必须 延迟元素的加载事件,直到所有尝试 获取和处理链接资源 及其 关键子资源 完成。(用户代理尚未尝试获取和处理的资源,例如因为等待资源被需要,这些资源不会 延迟加载事件。)

所有可以作为 外部资源链接 的链接类型都定义了一个 处理链接头部 算法,该算法接收 链接处理选项。这个算法定义了这些链接在 HTTP `Link` 响应头部中出现时的反应方式。

对于大多数链接类型,这个算法不会执行任何操作。总结表 是快速了解某个链接类型是否定义了 处理链接头部 步骤的良好参考。

链接处理选项 是一个 结构。它具有以下

href(默认值为空字符串)
destination(默认值为空字符串)
initiator(默认值为 "link")
integrity(默认值为空字符串)
type(默认值为空字符串)
加密随机数元数据(默认值为空字符串)
一个字符串
crossorigin(默认值 无 CORS
一个 CORS 设置属性 状态
referrer policy(默认值为空字符串)
一个 referrer policy
source set(默认值为 null)
Null 或一个 source set
基本 URL
一个 URL
origin
一个 origin
environment
一个 environment
policy container
一个 policy container
document(默认值为 null)
Null 或一个 Document
on document ready(默认值为 null)
Null 或一个算法,接受一个 Document
fetch priority(默认值 auto
一个 fetch priority attribute 状态

一个 链接处理选项 具有一个 基本 URL 和一个 href,而不是解析后的 URL,因为 URL 可能是选项的 source set 的结果。

要从一个 link 元素 el 创建链接选项:

  1. documentel节点文档

  2. options 为一个新的 链接处理选项,其值为:

    destination
    翻译 elas 属性的状态。
    crossorigin
    elcrossorigin 内容属性的状态
    referrer policy
    elreferrerpolicy 内容属性的状态
    source set
    elsource set
    基本 URL
    document文档基本 URL
    origin
    documentorigin
    environment
    document相关设置对象
    policy container
    documentpolicy container
    document
    document
    加密随机数元数据
    当前值为 el[[CryptographicNonce]] 内部槽
    fetch priority
    elfetchpriority 内容属性的状态
  3. 如果 el 有一个 href 属性,则将 optionshref 设置为 elhref 属性的值。

  4. 如果 el 有一个 integrity 属性,则将 optionsintegrity 设置为 elintegrity 内容属性的值。

  5. 如果 el 有一个 type 属性,则将 optionstype 设置为 eltype 属性的值。

  6. 断言optionshref 不能为空字符串,或者 optionssource set 不能为 null。

    一个既没有 href 属性,也没有 imagesrcset 属性的 link 元素不代表一个链接。

  7. 返回 options

要从头部中 提取链接,给定一个 头部列表 headers

  1. links 为一个新的 列表

  2. rawLinkHeaders 为从 response头部列表 中获取、解码和拆分 `Link` 的结果。

  3. 对于每个 linkHeaderrawLinkHeaders

    1. linkObject解析 linkHeader 的结果。 [WEBLINK]

    2. 如果 linkObject["target_uri"] 不 存在,则 继续

    3. linkObject 添加到 links 中。

  4. 返回 links

处理链接头部,给定一个 文档 doc,一个 响应 response,以及一个 "pre-media" 或 "media" phase

  1. links 为从 response头部列表提取链接 的结果。

  2. 对于每个 linkObjectlinks 中:

    1. rellinkObject["relation_type"]。

    2. attribslinkObject["target_attributes"]。

    3. expectedPhase 为 "media" 如果 "srcset", "imagesrcset", 或 "media" 存在attribs 中;否则为 "pre-media"。

    4. 如果 expectedPhase 不是 phase,则 继续

    5. 如果 attribs["media"] 存在attribs["media"] 不 匹配环境,则 继续

    6. options 为一个新的 链接处理选项,其具有:

      href
      linkObject["target_uri"]
      基本 URL
      doc文档基本 URL
      来源
      doc来源
      环境
      doc相关设置对象
      策略容器
      doc策略 容器
      文档
      doc
    7. 将解析头部属性的链接选项应用options 给定 attribs

    8. 如果 attribs["imagesrcset"] 存在attribs["imagesizes"] 存在,则将 options源集 设置为结果 创建源集 的结果,给定 linkObject["target_uri"]、attribs["imagesrcset"]、 attribs["imagesizes"], 和 null。

    9. 运行 处理链接头部 步骤,以 reloptions 进行。

将从解析的头部属性中获取的链接选项 应用链接处理选项 options 给定 attribs

  1. 如果 attribs["as"] 存在,则将 options目标 设置为 翻译 attribs["as"] 的结果。

  2. 如果 attribs["crossorigin"] 存在 并且是某个 ASCII 不区分大小写 匹配的 CORS 设置属性 关键词, 则将 optionscrossorigin 设置为与该关键词对应的 CORS 设置属性 状态。

  3. 如果 attribs["integrity"] 存在,则将 options完整性 设置为 attribs["integrity"]。

  4. 如果 attribs["referrerpolicy"] 存在 并且是某个 ASCII 不区分大小写 匹配的 引荐政策,则将 options引荐政策 设置为该 引荐政策

  5. 如果 attribs["nonce"] 存在,则将 optionsnonce 设置为 attribs["nonce"]。

  6. 如果 attribs["type"] 存在,则将 optionstype 设置为 attribs["type"]。

  7. 如果 attribs["fetchpriority"] 存在 并且是某个 ASCII 不区分大小写 匹配的 获取优先级属性 关键词,则将 options获取优先级 设置为该 获取优先级属性 关键词。

4.2.4.5 早期提示

状态/103

Firefoxpreview+SafariChrome103+
OperaEdge103+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

早期提示 允许用户代理执行一些操作,例如在导航请求被服务器完全处理和响应码返回之前,推测性地加载文档可能会使用的资源。服务器可以通过在发送最终的响应之前,先发送一个状态码为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` 元素中,按相应顺序。

  1. earlyPolicyContainer 成为创建策略容器从 fetch 响应的结果,给定 responsereservedEnvironment

    这允许早期提示 响应 包含一个 内容安全策略,在获取早期提示 请求时会被 强制执行

  2. links 成为 response头部列表中提取链接的结果。

  3. earlyHints 成为空的列表

  4. 对于每个 linkObjectlinks 中:

    一旦我们收到早期提示链接头部,我们就开始 获取 earlyRequest。如果在 Document 创建之前返回,我们将 earlyResponse 设置为该 响应 的结果,并且一旦 Document 被创建,我们就提交它(通过将其在 预加载资源映射中可用,仿佛它是一个 link 元素)。如果 Document 首先被创建,一旦 响应 可用时立即提交。

    1. rellinkObject["relation_type"]。

    2. options 成为一个新的 链接处理选项,包括

      href
      linkObject["target_uri"]
      initiator
      "early-hint"
      base URL
      responseURL
      origin
      responseURL
      环境
      reservedEnvironment
      策略容器
      earlyPolicyContainer
    3. attribslinkObject["target_attributes"]。

      只有 ascrossoriginintegrity,和 type 属性作为早期提示处理的一部分。其他属性,特别是 blockingimagesrcsetimagesizesmedia 只有在 Document 被创建后才适用。

    4. 从解析的头部属性中应用链接选项options 给定 attribs

    5. 运行 处理链接头部 步骤给 rel 给定 options

    6. 附加 optionsearlyHints

  5. 根据 Document 返回以下子步骤 doc对于每个 optionsearlyHints 中:

    1. 如果 optionson document ready 为 null,则将 optionsdocument 设置为 doc

    2. 否则,使用 doc 调用 optionson document ready

交互式用户代理可以在其用户界面的某处为用户提供通过link元素创建的超链接访问的方式。此类超链接访问算法的调用必须将userInvolvement参数设置为"browser UI"。该规范未定义具体界面,但它可以包括以下信息(从元素的属性中获取,如下所述),以某种形式或另一种形式(可能简化),用于文档中每个使用link元素创建的超链接

用户代理还可以包括其他信息,例如资源的类型(由type属性给出)。

4.2.5 meta 元素

Element/meta

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLMetaElement

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
分类:
元数据内容
如果存在itemprop属性: 流内容
如果存在itemprop属性: 短语内容
此元素可使用的上下文:
如果存在charset属性,或元素的http-equiv属性处于编码声明状态:在head元素中。
如果存在http-equiv属性但不在编码声明状态中:在head元素中。
如果存在http-equiv属性但不在编码声明状态中:在作为head元素子元素的noscript元素中。
如果存在name属性: 在期望元数据内容的地方。
如果存在itemprop属性: 在期望元数据内容的地方。
如果存在itemprop属性: 在期望短语内容的地方 。
内容模型:
无内容
在 text/html 中省略标签:
结束标签
内容属性:
全局属性
name — 元数据名称
http-equiv — 指令
content — 元素的值
charset字符编码声明
media — 适用的媒体
可访问性考虑:
作者须知
实现者须知
DOM 接口:
[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 元素 表示各种无法通过 titlebaselinkstylescript元素表示的元数据。

The meta 元素可以通过 name 属性表示文档级元数据,通过 http-equiv 属性表示指令,通过 字符编码声明 表示 HTML 文档在序列化为字符串形式(例如用于网络传输或磁盘存储)时的文件编码,并使用 charset 属性表示。

必须指定 namehttp-equivcharsetitemprop 属性中的一个。

如果指定了 namehttp-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 属性说明元数据适用的媒体。其值必须是有效的媒体查询列表。除非 nametheme-colormedia 属性对处理模型没有影响,作者不得使用。

The namecontent,和 media IDL 属性必须反映同名的相应内容属性。IDL 属性 httpEquiv 必须 反映内容属性 http-equiv

4.2.5.1 标准元数据名称

Element/meta/name

Support in all current engines.

Firefox1+Safari4+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

本规范定义了一些用于 name 属性的 meta 元素名称。

名称不区分大小写,并且必须以 ASCII 不区分大小写 的方式进行比较

application-name

值必须是一个简短的自由格式字符串,表示页面所代表的 Web 应用程序的名称。如果页面不是 Web 应用程序,则 application-name 元数据名称不得使用。可以使用 lang 属性指定每个名称的语言,提供 Web 应用程序名称的翻译。

每个文档中,不应有多个带有给定语言并且 name 属性值与 application-name ASCII 不区分大小写匹配的 meta 元素。

用户代理可能会在 UI 中优先使用应用程序名称,而不是页面的 title,因为标题可能包含与页面特定时间点相关的状态消息等信息,而不仅仅是应用程序的名称。

为了在给定语言列表(例如英国英语、美式英语和英语)中找到要使用的应用程序名称,用户代理必须执行以下步骤:

  1. languages 为语言列表。

  2. default languageDocument文档元素语言,如果有,并且该语言不是未知的。

  3. 如果有 default language,并且该语言与 languages 中的任何语言不同,则将其追加到 languages

  4. winning languagelanguages 中第一个有 meta 元素的语言,其中 name 属性值与 application-name ASCII 不区分大小写匹配,并且其语言是相关语言。

    如果没有语言具有这样的 meta 元素,则返回;没有给定的应用程序名称。

  5. 返回 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>
  ...

许多搜索引擎不考虑此类关键字,因为这种功能历史上被不可靠甚至误导性地用于通过使用不适合用户的关键字来垃圾搜索引擎结果。

为了获取作者指定为页面适用的关键字列表,用户代理必须运行以下步骤:

  1. keywords 为一个空列表。

  2. 对于每个具有 name 属性和 content 属性的 meta 元素,并且其 name 属性值与 keywords ASCII 不区分大小写匹配:

    1. 将元素的 content 属性的值按逗号分割

    2. 将生成的令牌(如果有)添加到 keywords

  3. keywords 中删除任何重复项。

  4. 返回 keywords。这是作者指定为页面适用的关键字列表。

当信息的可靠性不足时,用户代理不应使用此信息。

例如,内容管理系统在系统内页面中使用关键字信息来填充站点搜索引擎的索引是合理的,但大型内容聚合器使用此信息可能会发现某些用户会尝试通过使用不合适的关键字来操纵其排名机制。

referrer

值必须是一个 referrer policy,它定义了 Document 的默认 referrer policy[REFERRERPOLICY]

如果任何 meta 元素 element插入到文档中,或其 namecontent 属性发生变化,用户代理必须运行以下算法:

  1. 如果 element在文档树中,则返回。

  2. 如果 element 没有 name 属性,其值与 "referrer" ASCII 不区分大小写匹配,则返回。

  3. 如果 element 没有 content 属性,或者该属性的值为空字符串,则返回。

  4. valueelementcontent 属性的值,转换为 ASCII 小写

  5. 如果 value 是以下表格第一列中的值之一,则将 value 设置为第二列中的值:

    旧值 引用政策
    never no-referrer
    default 默认引用政策
    always unsafe-url
    origin-when-crossorigin origin-when-cross-origin
  6. 如果 value引用政策,则将 element节点文档政策容器引用政策 设置为 policy

由于历史原因,与其他标准元数据名称不同,referrer 的处理模型对元素移除不敏感,并且不使用 树顺序。只有最新插入或最近修改的 meta 元素在此状态下有效。

theme-color

Element/meta/name/theme-color

FirefoxNoSafari15+🔰 73+
OperaNo🔰 79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android80+WebView AndroidNoSamsung Internet6.2+Opera AndroidNo

值必须是与 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)">
...

为了获取页面的主题颜色,用户代理必须运行以下步骤:

  1. candidate elements 为满足以下条件的所有 meta 元素列表,按 树顺序 排列:

  2. 对于 candidate elements 中的每个 element

    1. 如果 element 具有 media 属性,并且 elementmedia 属性的值不与环境匹配,则 继续

    2. value去除前导和尾随 ASCII 空格 后的 elementcontent 属性的值。

    3. color解析 value 的结果。

    4. 如果 color 不是失败,则返回 color

  3. 返回无(页面没有主题颜色)。

如果任何 meta 元素被插入到文档中从文档中移除,或现有的 meta 元素的 namecontentmedia 属性发生变化,或者环境变化导致任何 meta 元素的 media 属性的值现在可能与环境匹配或不匹配,用户代理必须重新运行上述算法并将结果应用于任何受影响的 UI。

在 UI 中使用主题颜色时,用户代理可能会以实现特定的方式调整它,使其更适合相应的 UI。例如,如果用户代理打算使用主题颜色作为背景并在其上显示白色文本,则可能会在 UI 的该部分中使用较深的主题颜色变体,以确保足够的对比度。

color-scheme

为了帮助用户代理立即以所需的配色方案渲染页面背景(而不是等待页面中的所有CSS加载完成),可以在‘color-scheme’值中提供在meta元素中。

该值必须是符合CSS‘color-scheme’属性值语法的字符串。它决定了页面支持的配色方案

每个文档中不得有多个meta元素,其name属性值设置为color-schemeASCII不区分大小写匹配。

以下声明指示页面可以处理具有深色背景和浅色前景颜色的颜色方案:

<meta name="color-scheme" content="dark">

为了获取页面支持的颜色方案,用户代理必须运行以下步骤:

  1. candidate elements 为满足以下条件的所有 meta 元素列表,按 树顺序 排列:

  2. 对于 candidate elements 中的每个 element

    1. parsed解析组件值列表 的结果,给定 elementcontent 属性的值。
    2. 如果 parsed 是有效的 CSS 'color-scheme' 属性值,则返回 parsed
  3. 返回 null。

如果任何 meta 元素被 插入到文档中从文档中移除,或者现有的 meta 元素的 namecontent 属性发生变化,用户代理必须重新运行上述算法。

由于这些规则会检查连续的元素直到找到匹配项,因此作者可以提供多个这样的值以处理旧版用户代理的回退。与 CSS 属性的回退方式相反,多个 meta 元素需要按旧版值在新值之后的顺序排列。

4.2.5.2 其他元数据名称

任何人都可以创建并使用他们自己的扩展预定义的元数据名称集合。没有要求必须注册这些扩展。

但是,在以下任何情况下都不应创建新的元数据名称:

此外,在创建和使用新的元数据名称之前,建议咨询 WHATWG Wiki MetaExtensions 页面 — 以避免选择已经在使用的元数据名称,避免重复已经在使用的元数据名称的目的,并避免新标准化名称与您选择的名称冲突。[WHATWGWIKI]

任何人都可以随时编辑 WHATWG Wiki MetaExtensions 页面以添加元数据名称。新的元数据名称可以用以下信息来指定:

关键词

实际定义的名称。名称不应与任何其他定义的名称相似(例如,仅在大小写上不同)。

简短描述

元数据名称含义的简短非规范性描述,包括值所需的格式。

规范
链接到更详细描述元数据名称的语义和要求的链接。它可以是 wiki 上的另一页,或者是指向外部页面的链接。
同义词

具有完全相同处理要求的其他名称列表。作者不应使用定义为同义词的名称(它们仅用于允许用户代理支持旧内容)。任何人都可以删除实际上未使用的同义词;仅需要为了与旧内容兼容而处理为同义词的名称应以这种方式注册。

状态

以下之一:

已提议
该名称尚未经过广泛的同行审查和批准。有人提出了它并且正在或即将使用它。
已批准
该名称已通过广泛的同行审查和批准。它有一个规范,明确定义了如何处理使用该名称的页面,包括在错误使用该名称时的处理方式。
已停用
该元数据名称已通过广泛的同行审查,但被发现存在问题。现有页面使用此元数据名称,但新页面应避免使用。“简短描述”和“规范”条目将提供详细信息,说明作者应使用的替代项(如果有)。

如果发现元数据名称与现有值重复,则应将其删除并列为现有值的同义词。

如果元数据名称在“已提议”状态下添加一个月或更长时间而未使用或未规范,则可以将其从 WHATWG Wiki MetaExtensions 页面中删除。

如果元数据名称在“已提议”状态下添加,并被发现与现有值重复,则应将其删除并列为现有值的同义词。如果元数据名称在“已提议”状态下添加并被发现有害,则应将其更改为“已停用”状态。

任何人都可以随时更改状态,但应仅按照上述定义进行更改。

4.2.5.3 Pragma指令

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默认语言

  1. 如果 meta 元素没有 content 属性,则返回。

  2. 如果元素的 content 属性包含U+002C逗号字符(,),则返回。

  3. input为元素的 content 属性的值。

  4. position指向 input 的第一个字符。

  5. 跳过ASCII空白字符在input中给定position

  6. 收集一系列码点,这些码点不是ASCII 空白字符,从input给定的position

  7. candidate为前一步骤结果的字符串。

  8. 如果candidate为空字符串,则返回。

  9. 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")

替代样式表

仅在一个引擎中支持。

Firefox3+Safari?Chrome1–48
OperaYesEdgeNo
Edge (旧版)?Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

此pragma设置默认CSS样式表集名称

  1. 如果meta 元素没有content 属性,或该属性的值为空字符串,则返回。

  2. 更改首选CSS样式表集名称,名称为元素的content 属性的值。 [CSSOM]

刷新状态 (http-equiv="refresh")

此pragma充当定时重定向。

一个文档 对象具有一个关联的将声明性刷新(一个布尔值)。最初为false。

  1. 如果meta 元素没有content 属性,或该属性的值为空字符串,则返回。

  2. input为元素的content 属性的值。

  3. 使用meta 元素的节点文档inputmeta元素运行共享声明性刷新步骤

给定一个文档对象document、字符串input和可选的meta元素meta共享声明性刷新步骤如下:

  1. 如果document将声明性刷新为true,则返回。

  2. position指向input的第一个码点

  3. 跳过ASCII空白input中给定position

  4. time为0。

  5. 收集一系列码点,这些码点是ASCII数字input中给定position,并令结果为timeString

  6. 如果timeString为空字符串,则:

    1. 如果inputposition指向的码点不是U+002E (.),则返回。

  7. 否则,将time设置为使用解析非负整数的规则解析timeString的结果。

  8. 收集一系列码点,这些码点是ASCII数字和U+002E全停止字符(.)从input中给定position。忽略任何收集到的字符。

  9. urlRecorddocumentURL

  10. 如果position不在input的末尾,则:

    1. 如果inputposition指向的码点不是U+003B(;),U+002C(,),或ASCII空白,则返回。

    2. 跳过ASCII空白input中给定position

    3. 如果inputposition指向的码点是U+003B(;)或U+002C(,),则将position前进到下一个码点

    4. 跳过ASCII空白input中给定position

  11. 如果position不在input的末尾,则:

    1. urlStringinput的子字符串,从position码点到字符串的末尾。

    2. 如果inputposition指向的码点是U+0055 (U)或U+0075 (u),则将position前进到下一个码点。否则,跳到标签为skip quotes的步骤。

    3. 如果inputposition指向的码点是U+0052 (R)或U+0072 (r),则将position前进到下一个码点。否则,跳到标签为parse的步骤。

    4. 如果inputposition指向的码点是U+004C (L)或U+006C (l),则将position前进到下一个码点。否则,跳到标签为parse的步骤。

    5. 跳过ASCII空白input中给定position

    6. 如果inputposition指向的码点是U+003D(=),则将position前进到下一个码点。否则,跳到标签为parse的步骤。

    7. 跳过ASCII空白input中给定position

    8. 跳过引号:如果inputposition指向的码点是U+0027(')或U+0022("),则令quote为该码点,并将position前进到下一个码点。否则,令quote为空字符串。

    9. urlString设置为input的子字符串,从position码点到字符串的末尾。

    10. 如果quote不是空字符串,并且urlString中有一个码点等于quote,则在该码点处截断urlString,以便将其及所有后续码点移除。

    11. 解析:将urlRecord设置为编码解析URL的结果给定urlString,相对于document

    12. 如果urlRecord失败,则返回。

  12. document将声明性刷新设置为true。

  13. 执行以下一个或多个步骤:

    • 在刷新到期后(定义如下),如果用户未取消重定向,并且如果给定metadocument活动沙箱标志集没有沙箱自动功能浏览上下文标志设置,则导航document节点可导航urlRecord使用document历史处理设置为"替换"。

      为了上段的目的,刷新被认为是到期的,只要以下两个条件中的较晚一个发生:

      • 至少time秒已经过去了自document完全加载时间,调整以考虑用户或用户代理偏好。
      • 如果给定meta,至少time秒已经过去了自meta插入到文档document,调整以考虑用户或用户代理偏好。

      此处使用document非常重要,而不是meta节点文档,因为在初始步骤和刷新到期之间可能已更改,并且meta并不总是给定(在HTTPRefresh标头的情况下)。

    • 向用户提供一个界面,当选择时,导航document节点可导航urlRecord使用document

    • 什么都不做。

    此外,用户代理可以像任何操作一样,通知用户其操作的任何和所有方面,包括定时器的状态、任何定时重定向的目的地等。

对于meta 元素,其http-equiv 属性处于刷新状态,其content 属性的值必须是以下之一:

在前一种情况下,整数表示页面重新加载之前的秒数;在后一种情况下,整数表示页面替换为给定URL页面之前的秒数。

新闻组织的首页可能会在页面的head 元素中包含以下标记,以确保页面每五分钟自动从服务器重新加载一次:

<meta http-equiv="Refresh" content="300">

一系列页面 可以用作自动幻灯片放映,每个页面使用类似以下的标记刷新到序列中的下一个页面:

<meta http-equiv="Refresh" content="20; URL=page4.html">
Set-Cookie 状态 (http-equiv="set-cookie")

此pragma不符合规范且无效。

用户代理必须忽略此pragma。

X-UA-Compatible 状态 (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]

  1. 如果meta 元素不是head 元素的子元素,则返回。

  2. 如果meta 元素没有content 属性,或该属性的值为空字符串,则返回。

  3. policy为执行内容安全策略的解析序列化内容安全策略算法的结果,针对meta元素的content属性的值,来源为"meta",并且处置为"enforce"。

  4. policy中移除所有report-uriframe-ancestorssandbox指令

  5. 强制执行策略policy

对于具有meta元素中的http-equiv属性的元素在内容安全策略状态中,content属性必须具有由有效内容安全策略组成的值,但不得包含任何report-uriframe-ancestorssandbox 指令。在content属性中给出的内容安全策略将被强制执行于当前文档。[CSP]

在将meta元素插入到文档中时,一些资源可能已经被获取。例如,在动态插入具有http-equiv属性的meta元素之前,图像可能已存储在可用图像列表中。已经获取的资源不保证被内容安全策略阻止,这些策略被强制执行得较晚。

一个页面可能选择通过阻止内联JavaScript的执行以及阻止所有插件内容来降低跨站点脚本攻击的风险,使用如下策略:

<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'">

文档中同一时间不应有多个meta 元素处于任何特定状态。

4.2.5.4 指定文档的字符编码

字符编码声明是一种用于指定存储或传输文档时所使用的字符编码的机制。

编码标准要求使用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"?>

4.2.6 style 元素

Element/style

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera3.5+Edge79+
Edge (旧版)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

HTMLStyleElement

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别
元数据内容
此元素可用于的上下文
在期望元数据内容的地方。
noscript元素中,该元素是head元素的子元素。
内容模型
文本,提供符合标准的样式表
在text/html中的标签省略
两个标签都不能省略。
内容属性
全局属性
media — 适用的媒体
blocking — 元素是否可能阻碍渲染
此外,title属性在该元素上具有特殊语义CSS样式表集名称
无障碍考虑
给作者
给实现者
DOM接口
[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元素是样式处理模型的多个输入之一。该元素不表示用户内容。

HTMLStyleElement/disabled

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)13+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

disabled获取器步骤如下:

  1. 如果this没有关联的CSS样式表,则返回false。

  2. 如果this关联的CSS样式表禁用标志已设置,则返回true。

  3. 返回false。

disabled设置器步骤如下:

  1. 如果this没有关联的CSS样式表,则返回。

  2. 如果给定的值为true,则设置this关联的CSS样式表禁用标志。否则,取消设置this关联的CSS样式表禁用标志

重要的是,只有当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属性是一个阻碍属性

Alternative_style_sheets

仅在一个引擎中支持。

Firefox3+Safari?Chrome1–48
OperaYesEdgeNo
Edge (旧版)?Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

title属性在style元素上定义了CSS样式表集。如果style元素没有title属性,则它没有标题;祖先的title属性不适用于style元素。如果style元素不在文档树中,则忽略title属性。[CSSOM]

title属性在style元素上,与title属性在link元素上不同,全局title属性不适用于没有标题的style块:它只是没有标题。

style元素的子文本内容必须是符合标准的样式表

style元素如果是由其节点文档的解析器创建的,则隐含地可能阻碍渲染


用户代理必须在发生以下任何情况时运行更新style算法:

更新style算法如下:

  1. element成为style元素。

  2. 如果element关联的CSS样式表,则移除CSS样式表

  3. 如果element不是连接状态,则返回。

  4. 如果elementtype属性存在且其值既不是空字符串也不是text/cssASCII大小写不敏感匹配,则返回。

    特别是,具有参数的type值,如"text/css; charset=utf-8",将导致此算法提前返回。

  5. 如果内容安全策略应阻止元素的内联行为吗?算法在style元素、"style"和style元素的子文本内容上执行时返回"Blocked",则返回。[CSP]

  6. 创建一个CSS样式表,具有以下属性:

    类型

    text/css

    所有者节点

    element

    媒体

    elementmedia属性。

    这是对(可能在此时不存在的)属性的引用,而不是属性当前值的副本。CSSOM定义了当属性被动态设置、更改或删除时会发生什么。

    标题

    如果element文档树中,则为elementtitle属性,否则为空字符串。

    同样,这只是对属性的引用。

    替代标志

    未设置。

    源干净标志

    已设置。

    位置
    父CSS样式表
    所有者CSS规则

    null

    禁用标志

    保持默认值。

    CSS规则

    保持未初始化状态。

    这似乎不正确。大概我们应该使用元素的子文本内容?作为问题#2997进行跟踪。

  7. 如果element贡献了阻止脚本的样式表,则将element追加到其节点文档阻止脚本样式表集中。

  8. 如果elementmedia属性的值与环境匹配,且element可能阻碍渲染,则阻碍渲染

一旦尝试获取样式表的关键子资源(如果有)完成,或者,如果样式表没有关键子资源,则一旦样式表已解析和处理,用户代理必须运行这些步骤:

获取关键子资源未明确定义;可能问题#968是对此的最佳解决方案。同时,任何关键子资源请求应根据当前style元素是否阻碍渲染来设置其阻碍渲染标志。

  1. element成为style元素,与样式表关联。

  2. success为true。

  3. 如果获取样式表的任何关键子资源的尝试因任何原因(例如,DNS错误、HTTP 404响应、连接过早关闭、不支持的Content-Type)失败,则将success设置为false。

    请注意,内容特定的错误,例如CSS解析错误或PNG解码错误,不会影响success

  4. 将一个元素任务排队,在网络任务源上,给定element和以下步骤:

    1. 如果success为true,则触发名为load的事件,目标是element

    2. 否则,触发名为error的事件,目标是element

    3. 如果element贡献了阻止脚本的样式表

      1. 断言element节点文档阻止脚本样式表集包含element

      2. 从列表中移除element,从其节点文档阻止脚本样式表集

    4. 解除渲染阻塞

该元素必须延迟加载事件,直到所有尝试获取样式表的关键子资源(如果有)完成。

本规范未指定样式系统,但大多数网页浏览器预计会支持CSS。[CSS]

HTMLStyleElement/media

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

mediablockingIDL属性必须分别反映同名的内容属性。

LinkStyle接口也由该元素实现。[CSSOM]

以下文档将强调部分样式为亮红色文本,而非斜体文本,同时保持作品标题和拉丁文的默认斜体。它展示了如何使用适当的元素来简化文档的重新样式化。

<!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>

4.2.7 样式和脚本的交互

如果样式表未引用其他资源(例如,它是由没有@import规则的style元素给出的内部样式表),则样式规则必须立即提供给脚本;否则,样式规则必须在事件循环到达其更新渲染步骤时才提供给脚本。

文档的上下文中,一个元素el如果满足以下所有条件,则贡献了阻止脚本的样式表

预计上述规则的对应规则也适用于<?xml-stylesheet?>处理指令。但是,这尚未彻底调查。

文档有一个阻止脚本的样式表集,这是一个有序集,最初为空。

如果以下步骤返回true,则文档document有一个阻止脚本的样式表

  1. 如果document阻止脚本的样式表集为空,则返回true。

  2. 如果document节点可导航对象为null,则返回false。

  3. containerDocumentdocument节点可导航对象容器文档

  4. 如果containerDocument非null且containerDocument阻止脚本的样式表集为空,则返回true。

  5. 返回false。

如果一个文档没有阻止脚本的样式表,则它不有一个阻止脚本的样式表

4.3 区块

Introduction_to_HTML/Document_and_website_structure#HTML_for_structuring_content

所有当前引擎支持。

Firefox4+ Safari5+ Chrome5+
Opera11.1+ Edge79+
Edge (旧版)12+ Internet Explorer9+
Firefox Android? Safari iOS? Chrome Android? WebView Android? Samsung Internet? Opera Android11.1+

4.3.1 body 元素

Element/body

所有当前引擎支持。

Firefox1+ Safari1+ Chrome1+
Opera? Edge79+
Edge (旧版)12+ Internet ExplorerYes
Firefox Android? Safari iOS? Chrome Android? WebView Android? Samsung Internet? Opera Android?

HTMLBodyElement

所有当前引擎支持。

Firefox1+ Safari3+ Chrome1+
Opera12.1+ Edge79+
Edge (旧版)12+ Internet Explorer4+
Firefox Android? Safari iOS1+ Chrome Android? WebView Android? Samsung Internet? Opera Android12.1+
分类:
无。
该元素可用的上下文:
作为 html 元素中的第二个元素。
内容模型:
流内容
在 text/html 中标签的省略:
如果元素为空,或者 body 元素内的第一个内容不是 ASCII 空白注释,则可以省略 body 元素的开始标签,除非 body 元素内的第一个内容是 metanoscriptlinkscriptstyletemplate 元素。
如果 body 元素后面不是紧跟一个 注释,则可以省略 body 元素的结束标签。
内容属性:
全局属性
onafterprint
onbeforeprint
onbeforeunload
onhashchange
onlanguagechange
onmessage
onmessageerror
onoffline
ononline
onpageswap
onpagehide
onpagereveal
onpageshow
onpopstate
onrejectionhandled
onstorage
onunhandledrejection
onunload
可访问性考虑:
针对作者
针对实现者
DOM 接口:
[Exposed=Window]
interface HTMLBodyElement : HTMLElement {
  [HTMLConstructor] constructor();

  // also has obsolete members
};

HTMLBodyElement includes WindowEventHandlers;

body 元素 代表 文档的内容。

在符合规范的文档中,只有一个 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>

4.3.2 article 元素

元素/article

在所有当前引擎中支持。

Firefox4+Safari5+Chrome5+
Opera11.1+Edge79+
Edge(遗留版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11.1+
类别:
流内容.
分区内容.
可触及内容.
该元素可以使用的上下文:
分区内容的地方。
内容模型:
流内容.
文本/html中的标签省略:
没有标签可以省略。
内容属性:
全局属性
无障碍考虑:
对于作者.
对于实现者.
DOM 接口:
使用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>

4.3.3 section 元素

Element/section

所有当前浏览器均支持。

Firefox4+Safari5+Chrome5+
Opera11.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11.1+
类别:
流内容.
分区内容.
可感知内容.
可用上下文:
期望有分区内容的地方。
内容模型:
流内容.
文本/HTML中的标签省略:
没有标签是可以省略的。
内容属性:
全局属性
无障碍考虑:
针对作者.
针对实现者.
DOM接口:
使用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: 2em; }
 section.chapter h2 { font: 2em Roboto, Helvetica Neue, sans-serif; }
 section.appendix h2 { font: small-caps 2em 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>

4.3.4 nav 元素

Element/nav

在所有当前的引擎中都支持。

Firefox4+Safari5+Chrome5+
Opera11.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11.1+
类别:
流内容.
章节内容.
可感知内容.
此元素可以使用的上下文:
在需要章节内容的地方。
内容模型:
流内容.
在 text/html 中的标签省略:
没有标签是可以省略的。
内容属性:
全局属性
无障碍考虑:
给作者.
给实施者.
DOM 接口:
使用 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>

4.3.5 aside 元素

Element/aside

支持所有当前引擎。

Firefox4+Safari5+Chrome5+
Opera11.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11.1+
类别:
流内容.
分节内容.
显性内容.
该元素可以使用的上下文:
分节内容中。
内容模型:
流内容.
text/html中的标签省略:
两个标签都不可省略。
内容属性:
全局属性
无障碍考虑:
给作者的建议.
给实施者的建议.
DOM接口:
使用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>

4.3.6 h1h2h3h4h5h6 元素

元素/标题元素

支持所有当前的浏览器引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (遗留版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

元素/标题元素

支持所有当前的浏览器引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (遗留版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

元素/标题元素

支持所有当前的浏览器引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (遗留版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

元素/标题元素

支持所有当前的浏览器引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (遗留版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

元素/标题元素

支持所有当前的浏览器引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (遗留版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

元素/标题元素

支持所有当前的浏览器引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (遗留版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLHeadingElement

支持所有当前的浏览器引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (遗留版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容
标题内容
可感知内容
可以使用该元素的上下文:
作为 hgroup 元素的子元素。
标题内容 预期的位置。
内容模型:
短语内容
文本/html 中的标签省略:
两个标签都不可省略。
内容属性:
全局属性
无障碍考虑:
对于作者
对于实施者
DOM 接口:
[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>

作者可能会因为前一种风格的简洁性而偏好它,或者因为后一种风格的额外样式钩子而偏好它。哪种更好完全是作者个人风格的选择问题。

4.3.7 hgroup 元素

Element/hgroup

所有当前引擎都支持。

Firefox4+Safari5+Chrome5+
Opera11.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android2.2+Samsung Internet?Opera Android11.1+
类别:
流内容.
标题内容.
可感知内容.
此元素可用的上下文:
在期望有标题内容的地方。
内容模型:
零个或多个p元素,接着一个h1h2h3h4h5h6元素,之后跟零个或多个p元素,可能夹杂有脚本支持元素
在 text/html 中的标签省略:
两个标签都不可省略。
内容属性:
全局属性
可访问性考虑:
供作者参考.
供实施者参考.
DOM 接口:
使用HTMLElement.

hgroup 元素 表示 一个标题和相关内容。该元素可用于将一个或多个 h1h6 元素与一个或多个包含子标题、替代标题或标语内容的 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>

4.3.8 header 元素

Element/header

所有当前引擎都支持。

Firefox4+Safari5+Chrome5+
Opera11.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11.1+
类别:
流内容.
可感知内容.
此元素可以使用的上下文:
在期望有 流内容 的地方。
内容模型:
流内容,但没有 headerfooter 元素的后代。
在 text/html 中的标签省略:
没有标签可以省略。
内容属性:
全局属性
可访问性考虑:
如果存在祖先 分区内容 元素: 供作者参考; 供实现者参考.
否则: 供作者参考; 供实现者参考.
DOM 接口:
使用 HTMLElement.

header 元素 表示 一组介绍性或导航辅助工具。

header 元素通常旨在包含一个标题(h1h6 元素或 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" -->
 ...

Element/footer

支持所有当前引擎。

Firefox4+Safari5+Chrome5+
Opera11.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11.1+
类别:
流内容
可触及内容
可以使用此元素的上下文:
在预期出现 流内容 的地方。
内容模型:
流内容,但没有 headerfooter 元素的后代。
在 text/html 中的标签省略:
两个标签都不能省略。
内容属性:
全局属性
可访问性考虑:
如果有祖先 分区内容 元素: 供作者参考; 供实现者参考
否则: 供作者参考; 供实现者参考
DOM 接口:
使用 HTMLElement

footer 元素 表示 它最近的祖先 分区内容 元素的页脚,或者如果没有这样的祖先,则为 主体元素。页脚通常包含有关其部分的信息,如撰写者、相关文档的链接、版权数据等。

footer 元素包含整个部分时,它们 表示 附录、索引、长篇后记、详细的许可协议以及其他类似内容。

部分的作者或编辑的联系信息应放在 address 元素中,该元素可能位于一个 footer 元素内部。署名和其他可能适合于 headerfooter 的信息可以放在任意一个(或都不放)。这些元素的主要目的是帮助作者编写自解释的标记,易于维护和样式化;它们并不打算对作者强加特定的结构。

页脚不一定非得出现在部分的 末尾,尽管通常会这样。

当没有祖先 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>

4.3.10 address 元素

元素/address

所有当前浏览器都支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容
可触及内容
可以使用此元素的上下文:
在期望有流内容的地方。
内容模型:
流内容,但没有标题内容后代,没有分节内容后代,并且没有headerfooteraddress元素的后代。
在 text/html 中的标签省略:
标签不可省略。
内容属性:
全局属性
可访问性考虑:
给作者
给实现者
DOM 接口:
使用HTMLElement

address 元素 表示 其最近的 articlebody 元素祖先的联系信息。如果该祖先是 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 元素的集合:

如果 nodearticle 元素
如果 nodebody 元素

联系信息包括所有以 node 为祖先的 address 元素,并且这些元素没有其他 bodyarticle 元素祖先是 node 的后代。

如果 node 有一个祖先元素是 article 元素
如果 node 有一个祖先元素是 body 元素

node 的联系信息与最近的 articlebody 元素祖先的联系信息相同,以最近者为准。

如果 node节点文档一个 body 元素

node 的联系信息与 Documentbody 元素 的联系信息相同。

否则

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>

4.3.11 标题和大纲

h1h6元素具有一个标题级别,由元素名称中的数字给出。

这些元素 表示 标题。标题的 标题级别 越低,该标题拥有的祖先部分就越少。

大纲 是文档中的所有 标题,按 树状顺序排列。

大纲 应用于生成文档大纲,例如生成目录时。当创建交互式目录时,条目应跳转到相关的 标题

如果文档中有一个或多个 标题,则 大纲 中至少应有一个 标题 具有标题级别 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>
4.3.11.1 示例大纲

以下标记片段:

<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 个文档标题:

  1. <h1>HTML: Living Standard</h1>

  2. <h2>Table of contents</h2>.

  3. <h2>First section</h2>.

渲染后的 大纲 可能如下所示:

Top-level section with the heading "HTML: Living Standard" and two subsections; "Table of contents" and "First section".

首先,这里是一个文档,内容是一本章节非常短且包含子章节的书:

<!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>

它的大纲可以如下所示:

  1. The Tax Book
    1. Earning money
      1. Getting a job
    2. Spending money
      1. Cheap things
      2. Expensive things
    3. Investing money
    4. Losing money
      1. Poor judgement

注意到,title 元素不是 标题

一个文档可以包含多个顶级标题:

<!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>

文档的大纲可以呈现如下:

  1. Apples
  2. Bananas
  3. Carambola

header 元素不会影响文档的 大纲

<!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. Ray's blog
    1. We're adopting a child!

以下示例符合规范,但不推荐使用,因为它没有任何标题,其标题级别为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. Apples
    2. Bananas
    3. Carambola

以下示例符合规范,但不推荐,因为第一个标题标题级别不是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>

文档的大纲可以呈现如下:

    1. A plea from our caretakers
  1. Feathers
4.3.11.2 向用户暴露大纲

鼓励用户代理向用户暴露页面大纲,以帮助导航。这对于非视觉媒体尤其重要,例如屏幕阅读器。

例如,用户代理可以将箭头键映射如下:

Shift + ← 左箭头
转到前一个标题
Shift + → 右箭头
转到下一个标题
Shift + ↑ 向上箭头
转到下一个标题,其级别比当前标题的级别低一个
Shift + ↓ 向下箭头
转到下一个标题,其级别与当前标题的级别相同

4.3.12 使用摘要

本节为非规范性内容。

元素 目的
示例
body 文档的内容。
<!DOCTYPE HTML>
<html lang="en">
 <head> <title>Steve Hill's Home Page</title> </head>
 <body> <p>Hard Trance is My Life.</p> </body>
</html>
article 文档、页面、应用程序或站点中的一个完整或自包含的组成部分,原则上可以独立分发或重用,例如在联合发布中。这可以是论坛帖子、杂志或报纸文章、博客条目、用户提交的评论、互动小部件或工具,或任何其他独立的内容项。
<article>
 <img src="/tumblr_masqy2s5yn1rzfqbpo1_500.jpg" alt="Yellow smiley face with the caption 'masif'">
 <p>My fave Masif tee so far!</p>
 <footer>Posted 2 days ago</footer>
</article>
<article>
 <img src="/tumblr_m9tf6wSr6W1rzfqbpo1_500.jpg" alt="">
 <p>Happy 2nd birthday Masif Saturdays!!!</p>
 <footer>Posted 3 weeks ago</footer>
</article>
section 文档或应用程序中的一个通用部分。在此上下文中,部分是内容的主题性分组,通常带有标题。
<h1>Biography</h1>
<section>
 <h1>The facts</h1>
 <p>1500+ shows, 14+ countries</p>
</section>
<section>
 <h1>2010/2011 figures per year</h1>
 <p>100+ shows, 8+ countries</p>
</section>
nav 一个链接到其他页面或页面内部部分的页面部分:一个包含导航链接的部分。
<nav>
 <p><a href="/">Home</a>
 <p><a href="/biog.html">Bio</a>
 <p><a href="/discog.html">Discog</a>
</nav>
aside 一个页面部分,包含与围绕aside元素的内容间接相关的内容,且这些内容可以被认为是独立于该内容的。这些部分通常在印刷排版中表现为侧边栏。
<h1>Music</h1>
<p>As any burner can tell you, the event has a lot of trance.</p>
<aside>You can buy the music we played at our <a href="buy.html">playlist page</a>.</aside>
<p>This year we played a kind of trance that originated in Belgium, Germany, and the Netherlands in the mid-90s.</p>
h1h6 一个标题
<h1>The Guide To Music On The Playa</h1>
<h2>The Main Stage</h2>
<p>If you want to play on a stage, you should bring one.</p>
<h2>Amplified Music</h2>
<p>Amplifiers up to 300W or 90dB are welcome.</p>
hgroup 一个标题及相关内容。该元素可用于将一个或多个 h1h6 元素与一个或多个 p 元素组合在一起,这些元素包含表示子标题、替代标题或标语的内容。
<hgroup>
 <h1>Burning Music</h1>
 <p>The Guide To Music On The Playa</p>
</hgroup>
<section>
 <hgroup>
  <h1>Main Stage</h1>
  <p>The Fiction Of A Music Festival</p>
 </hgroup>
 <p>If you want to play on a stage, you should bring one.</p>
</section>
<section>
 <hgroup>
  <h1>Loudness!</h1>
  <p>Questions About Amplified Music</p>
 </hgroup>
 <p>Amplifiers up to 300W or 90dB are welcome.</p>
</section>
header 一组引导性或导航性辅助工具。
<article>
 <header>
  <h1>Hard Trance is My Life</h1>
  <p>By DJ Steve Hill and Technikal</p>
 </header>
 <p>The album with the amusing punctuation has red artwork.</p>
</article>
footer 其最近祖先的分区内容元素的页脚,或者如果没有这样的祖先,则为body元素。页脚通常包含有关其部分的信息,例如作者、相关文档的链接、版权数据等。
<article>
 <h1>Hard Trance is My Life</h1>
 <p>The album with the amusing punctuation has red artwork.</p>
 <footer>
  <p>Artists: DJ Steve Hill and Technikal</p>
 </footer>
</article>
4.3.12.1 文章还是区块?

本节为非规范性内容。

section 是其他内容的一部分。article 是一个独立的内容。但如何区分这两者呢?大多数情况下,真正的答案是“这取决于作者的意图”。

例如,可以想象一本书中有一章关于“格兰尼·史密斯”苹果,只提到“这些多汁的绿色苹果是制作苹果派的绝佳填料”;这将是一个 section,因为还有很多其他章节(可能)讲述其他种类的苹果。

另一方面,可以想象一条推文或Reddit评论或Tumblr帖子或报纸分类广告只说了“格兰尼·史密斯。这些多汁的绿色苹果是制作苹果派的绝佳填料”;这将是 article,因为这就是全部内容。

对文章的评论不是其所在 article 的一部分,因此它是自己的 article

4.4 内容分组

4.4.1 p 元素

Element/p

在所有当前引擎中都支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLParagraphElement

在所有当前引擎中都支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容
可触及内容
此元素可使用的上下文:
在期望出现流内容的地方。
内容模型:
措辞内容
在 text/html 中的标签省略:
p 元素的结束标签 可以省略,如果该p元素后面紧跟着一个 addressarticleasideblockquotedetailsdivdlfieldsetfigcaptionfigurefooterformh1h2h3h4h5h6headerhgrouphrmainmenunavolppresearchsectiontable,或 ul 元素,或者如果父元素没有更多内容且父元素是一个HTML 元素(不是 aaudiodelinsmapnoscript,或 video 元素,或一个自主自定义元素
内容属性:
全局属性
可访问性考虑:
对于作者
对于实现者
DOM 接口:
[Exposed=Window]
interface HTMLParagraphElement : HTMLElement {
  [HTMLConstructor] constructor();

  // also has obsolete members
};

p 元素 表示 一个 段落

虽然段落通常在视觉媒体中通过与相邻块之间通过空行物理分隔的文本块表示,样式表或用户代理同样可以用不同的方式来呈现段落分隔,例如使用行内段落标记 (¶)。

以下示例是符合规范的 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>

列表元素(特别是 olul 元素)不能作为 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 进行样式设置,而不必单独考虑示例的每个部分。

4.4.2 hr 元素

Element/hr

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLHRElement

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容
此元素可以使用的上下文:
在期望 流内容 的地方。
作为 select 元素的子元素。
内容模型:
在 text/html 中的标签省略:
没有 结束标签
内容属性:
全局属性
无障碍考虑:
对于作者
对于实现者
DOM 接口:
[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>

在部分之间不需要使用 hr 元素,因为 section 元素和 h1 元素本身就暗示了主题的变化。

以下摘自彼得·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>

`hr` 元素不会影响文档的 大纲

4.4.3 `pre` 元素

Element/pre

所有当前引擎均支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLPreElement

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容.
可感知内容.
可以使用此元素的上下文:
期望出现 流内容 的地方。
内容模型:
短语内容.
在 text/html 中的标签省略:
没有标签可以省略。
内容属性:
全局属性
无障碍考虑:
针对作者.
针对实现者.
DOM 接口:
[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>

在以下片段中,sampkbd 元素混合在一个 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>

4.4.4 blockquote 元素

Element/blockquote

支持所有当前的浏览器。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLQuoteElement

支持所有当前的浏览器。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
类别:
流内容
可触及内容
可以使用此元素的上下文:
在期望 流内容 的地方。
内容模型:
流内容
在 text/html 中的标签省略:
两个标签都不可省略。
内容属性:
全局属性
cite — 链接到引用的来源或更多关于编辑的信息
无障碍考虑:
供作者参考
供实施者参考
DOM 接口:
[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>

下一个示例展示了 citeblockquote 一起使用的情况:

<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...

如何表示对话的示例 会在后面的章节中展示;不适合使用 citeblockquote 元素来实现这一目的。

4.4.5 ol 元素

Element/ol

Support in all current engines.

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLOListElement

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容
如果元素的子元素包括至少一个 li 元素:可触及内容
此元素可用的上下文:
在期望 流内容 的地方。
内容模型:
零个或多个 li 元素和 支持脚本的 元素。
在 text/html 中的标签省略:
两个标签都不可省略。
内容属性:
全局属性
reversed — 反向编号列表
start — 列表的 起始值
type — 列表标记的类型
无障碍考虑:
对于作者
对于实现者
DOM 接口:
[Exposed=Window]
interface HTMLOListElement : HTMLElement {
  [HTMLConstructor] constructor();

  [CEReactions] attribute boolean reversed;
  [CEReactions] attribute long start;
  [CEReactions] attribute DOMString type;

  // also has obsolete members
};

ol 元素表示一系列项目,其中项目经过刻意排序,改变顺序会改变文档的意义。

列表的项目是li元素的子节点,ol元素按树顺序排列。

Element/ol#attr-reversed

Support in all current engines.

Firefox18+Safari6+Chrome18+
Opera?Edge79+
Edge (旧版)≤79+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

reversed 属性是一个布尔属性。如果存在,它表示列表是降序的(..., 3, 2, 1)。如果省略该属性,列表是升序的(1, 2, 3, ...)。

start 属性如果存在,必须是一个有效整数。它用于确定列表的起始值

ol元素有一个起始值,这是一个按以下方式确定的整数:

  1. 如果ol元素有start属性,则:

    1. parsed解析属性值为整数的结果。

    2. 如果parsed没有错误,则返回parsed

  2. 如果ol元素有reversed属性,则返回拥有的li元素的数量。

  3. 返回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列表样式;这样做会影响列表项的呈现方式。

reversedtype IDL属性必须反映同名的相应内容属性。

start IDL属性必须反映同名的内容属性,默认值为1

这意味着在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>

4.4.6 ul元素

Element/ul

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLUListElement

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容
如果元素的子元素包含至少一个li元素: 可感知内容
此元素可使用的上下文:
期望流内容的地方。
内容模型:
零个或多个li脚本支持元素。
在text/html中的标签省略:
两个标签都不可省略。
内容属性:
全局属性
无障碍考虑:
给作者的建议
给实现者的建议
DOM接口:
[Exposed=Window]
interface HTMLUListElement : HTMLElement {
  [HTMLConstructor] constructor();

  // also has obsolete members
};

ul元素表示一系列项目,这些项目的顺序并不重要——也就是说,改变顺序不会实质性地改变文档的意义。

列表的项目是li元素的子节点,属于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>

4.4.7 menu元素

Element/menu

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLMenuElement

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容
如果元素的子元素包含至少一个li元素:可感知内容
此元素可使用的上下文:
期望流内容的地方。
内容模型:
零个或多个li脚本支持元素。
在text/html中的标签省略:
两个标签都不可省略。
内容属性:
全局属性
无障碍考虑:
给作者的建议
给实现者的建议
DOM接口:
[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>

请注意,将其样式化为传统工具栏菜单的样式取决于应用程序。

4.4.8 li 元素

Element/li

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLLIElement

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
无。
此元素可以使用的上下文:
ol 元素中。
ul 元素中。
menu 元素中。
内容模型:
流内容
在 text/html 中的标签省略:
如果 li 元素后面紧跟另一个 li 元素,或者父元素中没有更多内容,则 结束标签 可以省略。
内容属性:
全局属性
如果该元素不是 ulmenu 元素的子元素: value — 列表项的序数值
可访问性注意事项:
给作者的建议
给实现者的建议
DOM 接口:
[Exposed=Window]
interface HTMLLIElement : HTMLElement {
  [HTMLConstructor] constructor();

  [CEReactions] attribute long value;

  // also has obsolete members
};

li 元素 代表 列表项。如果它的父元素是 olulmenu 元素,那么该元素就是父元素列表中的一项,如这些元素的定义所示。否则,该列表项与任何其他 li 元素没有定义的列表相关关系。

value 属性(如果存在)必须是有效整数。当 li列表所有者ol 元素时,用于确定列表项的序数值


任何其 计算值'display' 为 'list-item' 的元素都有一个 列表所有者,其确定方式如下:

  1. 如果该元素没有被渲染,则返回 null;该元素没有 列表所有者

  2. ancestor 成为该元素的父元素。

  3. 如果该元素有 olulmenu 祖先元素,则将 ancestor 设置为最近的此类祖先元素。

  4. 返回 ancestor 最近的包含祖先元素,该祖先元素生成一个 CSS 框

    这样的元素总是存在的,因为至少 文档元素 总是会生成一个 CSS 框

要确定由给定的 列表所有者 owner 拥有的每个元素的 序数值,请执行以下步骤:

  1. i 为 1。

  2. 如果 ownerol 元素,则将 numbering 设置为 owner起始值。否则,将 numbering 设置为 1。

  3. 循环:如果 i 大于 owner 拥有的列表项 的数量,则返回;所有 owner已拥有列表项 已分配 序数值

  4. itemowner 的第 i已拥有列表项,按 树顺序

  5. 如果 item 是具有 value 属性的 li 元素,则:

    1. parsed 设置为解析 该属性的值为整数的结果。

    2. 如果 parsed 没有错误,则将 numbering 设置为 parsed

  6. item序数值numbering

  7. 如果 ownerol 元素,且 owner 具有 reversed 属性,则将 numbering 减 1;否则,将 numbering 加 1。

  8. i 加 1。

  9. 转到标记为 循环 的步骤。


value IDL 属性必须反映 value 内容属性的值。

元素的 value IDL 属性不直接对应其 序数值;它只是反映内容属性。例如,给定此列表:

<ol>
 <li>Item 1
 <li value="3">Item 3
 <li>Item 4
</ol>

序数值为 1、3 和 4,而 value IDL 属性获取时返回 0、3、0。

以下示例中列出了前十名电影(按逆序)。请注意,通过使用 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)是符合规范的,但这可能不会传达作者想要表达的语义。标题会开启一个新的部分,因此列表中的标题会隐式地将列表分割成多个部分。

4.4.9 dl 元素

Element/dl

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLDListElement

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容
如果元素的子元素包含至少一个名称-值组:明显内容
此元素可使用的上下文:
预期 流内容 的地方。
内容模型:
可以是:一个或多个组,每个组由一个或多个 dt 元素组成,后跟一个或多个 dd 元素,可选地夹杂 脚本支持元素
或:一个或多个 div 元素,可选地夹杂 脚本支持元素
在 text/html 中的标签省略:
标签不可省略。
内容属性:
全局属性
可访问性注意事项:
给作者的建议
给实现者的建议
DOM 接口:
[Exposed=Window]
interface HTMLDListElement : HTMLElement {
  [HTMLConstructor] constructor();

  // also has obsolete members
};

dl 元素 代表 一个关联列表,由零个或多个名称-值组(描述列表)组成。名称-值组由一个或多个名称(dt 元素,可能是 div 元素的子元素)后跟一个或多个值(dd 元素,可能是 div 元素的子元素),忽略除 dtdd 元素以外的所有节点,以及作为 div 元素子元素的 dtdd 元素。在单个 dl 元素中,每个名称不应有多个 dt 元素。

名称-值组可以是术语和定义、元数据主题和值、问题和答案,或任何其他名称-值数据组。

组内的值是替代的;构成同一值的多个段落必须都包含在同一 dd 元素中。

组列表的顺序以及每个组内名称和值的顺序可能很重要。

为了用 微数据 属性或其他适用于整个组的 全局属性 注释组,或仅用于样式目的,dl 元素中的每个组都可以包含在 div 元素中。这不会改变 dl 元素的语义。

dl 元素 dl 的名称-值组是使用以下算法确定的。名称-值组有一个名称(dt 元素列表,最初为空)和一个值(dd 元素列表,最初为空)。

  1. groups 为一个空的名称-值组列表。

  2. current 为一个新的名称-值组。

  3. seenDd 为 false。

  4. childdl第一个子节点

  5. grandchild 为 null。

  6. child 不为 null 时:

    1. 如果 childdiv 元素,则:

      1. grandchildchild第一个子节点

      2. grandchild 不为 null 时:

        1. 处理 dtdd 以处理 grandchild

        2. grandchild 设置为 grandchild下一个兄弟节点

    2. 否则,处理 dtdd 以处理 child

    3. child 设置为 child下一个兄弟节点

  7. 如果 current 不为空,则将 current 追加到 groups

  8. 返回 groups

处理 dtdd 节点 node,需执行以下步骤:

  1. groupscurrentseenDd 为调用这些步骤的算法中同名的变量。

  2. 如果 nodedt 元素,则:

    1. 如果 seenDd 为 true,则将 current 追加到 groups,将 current 设置为一个新的名称-值组,并将 seenDd 设置为 false。

    2. node 追加到 current 的名称中。

  3. 否则,如果 nodedd 元素,则将 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 元素将 dtdd 元素组围起来,以帮助样式化。

<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 元素不适合用于标记对话。请参阅一些如何标记对话的示例

4.4.10 dt 元素

Element/dt

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
无。
此元素可使用的上下文:
dl 元素中,在 dddt 元素之前。
dl 元素的子元素 div 元素中,在 dddt 元素之前。
内容模型:
流内容,但不能有 headerfooter分区内容标题内容 的后代。
在 text/html 中的标签省略:
如果 dt 元素后面紧跟另一个 dt 元素或 dd 元素,则其结束标签可以省略。
内容属性:
全局属性
可访问性注意事项:
给作者的建议
给实现者的建议
DOM 接口:
使用 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>

4.4.11 dd 元素

Element/dd

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
无。
此元素可使用的上下文:
dl 元素中,在 dtdd 元素之后。
dl 元素的子元素 div 元素中,在 dtdd 元素之后。
内容模型:
流内容
在 text/html 中的标签省略:
如果 dd 元素后面紧跟另一个 dd 元素或 dt 元素,或者父元素中没有更多内容,则其结束标签可以省略。
内容属性:
全局属性
可访问性注意事项:
给作者的建议
给实现者的建议
DOM 接口:
使用 HTMLElement

dd 元素表示描述列表(dl 元素)中术语-描述组的描述、定义或值部分。

dl 可以用于定义词汇表,就像在字典中一样。在以下示例中,每个条目由带有 dtdfn 给出,并有多个 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>

4.4.12 figure 元素

Element/figure

支持所有当前引擎。

Firefox4+Safari5.1+Chrome8+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+
类别:
流内容
明显内容
此元素可使用的上下文:
预期 流内容 的地方。
内容模型:
可以是:一个 figcaption 元素后跟 流内容
或者:流内容 后跟一个 figcaption 元素。
或者:流内容
在 text/html 中的标签省略:
标签不可省略。
内容属性:
全局属性
可访问性注意事项:
给作者的建议
给实现者的建议
DOM 接口:
使用 HTMLElement

figure 元素表示一些独立的流内容,可选地带有标题,通常作为单一单元从文档的主流中引用

在此上下文中,“独立”并不一定意味着独立。例如,段落中的每个句子都是独立的;作为句子一部分的图像不适合使用 figure,但由图像构成的完整句子则是合适的。

因此,该元素可以用来注释插图、图表、照片、代码列表等。

figure 从文档的主要内容中通过标题(例如,通过图号)进行引用时,这样的内容可以很容易地从主内容中移开,例如,移到页面侧边、专用页面或附录,而不会影响文档的流。

如果 figure 元素通过其相对位置引用,例如,“在上面的照片中”或“如下一图所示”,则移动图形会破坏页面的意义。鼓励作者使用标签引用图形,而不是使用此类相对引用,以便可以轻松地重新设计页面而不影响页面的意义。

元素的第一个 figcaption 元素子元素(如果有),表示 figure 元素内容的标题。如果没有 figcaption 子元素,则没有标题。

figure 元素的内容是周围流的一部分。如果页面的目的是显示图形,例如图片共享网站上的照片,则可以使用 figurefigcaption 元素明确提供该图形的标题。对于仅与周围流略有相关或具有不同目的的内容,应使用 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&lt;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>

4.4.13 figcaption 元素

Element/figcaption

支持所有当前引擎。

Firefox4+Safari5.1+Chrome8+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+
类别:
无。
此元素可使用的上下文:
作为 figure 元素的第一个或最后一个子元素。
内容模型:
流内容
在 text/html 中的标签省略:
标签不可省略。
内容属性:
全局属性
可访问性注意事项:
给作者的建议
给实现者的建议
DOM 接口:
使用 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>

4.4.14 main 元素

Element/main

支持所有当前引擎。

Firefox21+Safari7+Chrome26+
Opera16+Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容
明显内容
此元素可使用的上下文:
预期 流内容 的地方,但仅当它是层次结构正确的 main 元素
内容模型:
流内容
在 text/html 中的标签省略:
标签不可省略。
内容属性:
全局属性
可访问性注意事项:
给作者的建议
给实现者的建议
DOM 接口:
使用 HTMLElement

main 元素表示文档的主要内容。

文档中不能有多个未指定 hidden 属性的 main 元素。

层次结构正确的 main 元素 是指其祖先元素仅限于 htmlbodydiv、没有可访问名称form 元素和 自主自定义元素。每个 main 元素都必须是层次结构正确的 main 元素

在此示例中,作者使用了一种将页面的每个组件呈现在一个框中的布局。为了包装页面的主要内容(而不是页眉、页脚、导航栏和侧边栏),使用了 main 元素。

<!DOCTYPE html>
<html lang="en">
<title>RPG System 17</title>
<style>
 header, nav, aside, main, footer {
   margin: 0.5em; border: thin solid; padding: 0.5em;
   background: #EFF; color: black; box-shadow: 0 0 0.25em #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 元素,并使用脚本使导航在不进行服务器往返的情况下工作,并为非当前元素设置 hidden 属性:

<!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>

4.4.15 search 元素

Element/search

当前引擎不支持。

FirefoxNoSafariNoChromeNo
OperaNoEdgeNo
Edge (旧版)NoInternet ExplorerNo
Firefox Android?Safari iOS?Chrome AndroidNoWebView Android?Samsung Internet?Opera Android?
类别:
流内容
明显内容
此元素可使用的上下文:
预期 流内容 的地方。
内容模型:
流内容
在 text/html 中的标签省略:
标签不可省略。
内容属性:
全局属性
可访问性注意事项:
给作者的建议
给实现者的建议
DOM 接口:
使用 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>

4.4.16 div 元素

Element/div

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLDivElement

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容
可感知内容
此元素可使用的上下文:
预期 流内容 的地方。
作为 dl 元素的子元素。
内容模型:
如果元素是 dl 元素的子元素:一个或多个 dt 元素,后跟一个或多个 dd 元素,可以与 脚本支持元素 混合。
如果元素不是 dl 元素的子元素:流内容
在 text/html 中的标签省略:
标签不可省略。
内容属性:
全局属性
可访问性注意事项:
给作者的建议
给实现者的建议
DOM 接口:
[Exposed=Window]
interface HTMLDivElement : HTMLElement {
  [HTMLConstructor] constructor();

  // also has obsolete members
};

div 元素本身没有任何特殊含义。它表示其子元素。它可以与 classlangtitle 属性一起使用,以标记一组连续元素的语义。它还可以在 dl 元素中使用,包裹 dtdd 元素的组。

强烈建议作者将 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>

4.5 文本级语义

4.5.1 a 元素

Element/a

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAnchorElement

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
分类:
流内容
短语内容
如果该元素有 href 属性: 交互内容
感知内容
此元素可用的上下文:
期望 短语内容 的地方。
内容模型:
透明,但不得有 交互内容 后代, a 元素后代,或具有 tabindex 属性的后代。
text/html 中的标签省略:
两端标签都不能省略。
内容属性:
全局属性
href超链接 的地址
target可导航对象 用于 超链接 导航
download — 是否下载资源而不是导航到它,以及如果是则下载的文件名
ping — 要 ping 的 URL
rel — 包含 超链接 的文档位置与目标资源之间的关系
hreflang — 链接资源的语言
type — 被引用资源的类型提示
referrerpolicy — 元素发起的 引用策略fetches
可访问性考虑:
如果该元素有 href 属性: 作者; 实现者
否则: 作者; 实现者
DOM 接口:
[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 属性,则 targetdownloadpingrelhreflangtypereferrerpolicy 属性必须省略。

如果 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>

hreftargetdownloadpingreferrerpolicy 属性影响用户 跟随超链接下载超链接 时发生的事情,这些超链接是使用 a 元素创建的。relhreflangtype 属性可用于在用户跟随链接之前向其指示目标资源的可能性质。

a.text

Same as textContent.

HTMLAnchorElement/download

支持所有当前的引擎。

Firefox20+Safari10.1+Chrome15+
Opera?Edge79+
Edge (传统版)13+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAnchorElement/rel

支持所有当前的引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (传统版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

IDL 属性 downloadpingtargetrelhreflangtype,必须反映同名的相应内容属性。

HTMLAnchorElement/relList

支持所有当前的引擎。

Firefox30+Safari9+Chrome65+
Opera?Edge79+
Edge (传统版)18Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

IDL 属性 relList 必须 反映 rel 内容属性。

HTMLAnchorElement/referrerPolicy

支持所有当前的引擎。

Firefox50+Safari14+Chrome52+
Opera?Edge79+
Edge (传统版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

IDL 属性 referrerPolicy 必须 反映 referrerpolicy 内容属性,仅限已知值

text 属性的 getter 必须返回该元素的 后代文本内容

text 属性的 setter 必须 用给定的值替换所有字符串

a 元素可以包裹整个段落、列表、表格等,甚至整个部分,只要其中没有交互内容(例如按钮或其他链接)。此示例展示了如何将整个广告块变成一个链接:

<aside class="advertising">
 <h1>Advertising</h1>
 <a href="https://ad.example.com/?adid=1929&amp;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&amp;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>

4.5.2 em 元素

Element/em

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别
流内容
短语内容
显著内容
可以使用该元素的上下文
在预期短语内容的地方。
内容模型
短语内容
在 text/html 中省略标签
标签不可省略。
内容属性
全局属性
可访问性考虑
作者参考
实现者参考
DOM 接口
使用 HTMLElement

em 元素 表示 其内容的强调。

特定内容的强调程度由其祖先 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>

em 元素不是一个通用的“斜体”元素。有时,文本需要从段落的其余部分中脱颖而出,就像是以不同的情绪或语气书写的。对于这种情况,i 元素更合适。

em 元素也不是用来表达重要性的;对于这个目的,strong 元素更合适。

4.5.3 strong 元素

Element/strong

Support in all current engines.

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
Categories:
流内容
短语内容
可感知内容
此元素可以使用的上下文:
在需要 短语内容的地方。
内容模型:
短语内容
在 text/html 中的标签省略:
标签不能省略。
内容属性:
全局属性
可访问性考虑:
对作者
对实现者
DOM 接口:
使用 HTMLElement

strong 元素 表示 其内容的重要性、严肃性或紧迫性。

重要性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>

4.5.4 small 元素

Element/small

Support in all current engines.

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容.
短语内容.
可感知内容.
该元素可用的上下文:
短语内容预期出现的地方。
内容模型:
短语内容。
在 text/html 中省略标签:
两个标签都不可省略。
内容属性:
全局属性
无障碍考虑:
对于作者.
对于实现者.
DOM 接口:
使用 HTMLElement.

small 元素 表示 旁注,如小字打印。

小字打印通常包括免责声明、警告、法律限制或版权声明。小字打印有时也用于归属,或满足许可要求。

small 元素并不会“降低”或减少通过 em 元素强调的文本或通过 strong 元素标记为重要的文本的重要性。要标记文本为不强调或不重要,只需不要使用 emstrong 元素即可。

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>

4.5.5 s 元素

元素/s

所有当前引擎均支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容
短语内容
可触及内容
此元素可用的上下文:
短语内容中。
内容模型:
短语内容
在 text/html 中的标签省略:
两个标签都不可省略。
内容属性:
全局属性
无障碍考虑:
面向作者
面向实现者
DOM 接口:
使用HTMLElement

s 元素表示不再准确或不再相关的内容。

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>

4.5.6 cite 元素

元素/cite

所有当前引擎均支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容
短语内容
可触及内容
此元素可用的上下文:
短语内容中。
内容模型:
短语内容
在 text/html 中的标签省略:
两个标签都不可省略。
内容属性:
全局属性
无障碍考虑:
面向作者
面向实现者
DOM 接口:
使用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>

4.5.7 q 元素

元素/q

在所有当前的引擎中均有支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容.
短语内容.
可感知内容.
此元素可以使用的上下文:
在需要 短语内容 的地方。
内容模型:
短语内容.
在 text/html 中的标签省略:
两个标签都不可省略。
内容属性:
全局属性
cite — 链接到引用的来源或有关编辑的更多信息
可访问性考虑:
给作者的建议.
给实现者的建议.
DOM 接口:
使用 HTMLQuoteElement.

q 元素 表示 从其他来源引用的一些 短语内容

引用标点(如引号)不应立即出现在 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>

4.5.8 dfn 元素

Element/dfn

所有当前引擎均支持。

Firefox1+Safari6+Chrome15+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容.
短语内容.
可感知内容.
该元素可以使用的上下文:
在预期的 短语内容 中。
内容模型:
短语内容,但其中不能有 dfn 元素的后代。
文本/html 中的标签省略:
两个标签都不能省略。
内容属性:
全局属性
此外,title 属性 在此元素上具有特殊语义: 术语的完整形式或缩写的扩展。
无障碍考虑:
针对作者.
针对实现者.
DOM 接口:
使用 HTMLElement.

dfn 元素 表示 术语的定义实例。最近的 段落描述列表组部分,即 dfn 元素的最近祖先,必须还包含 术语 的定义,该术语由 dfn 元素给出。

定义术语: 如果 dfn 元素有一个 title 属性,那么该属性的确切值就是正在定义的术语。否则,如果它包含恰好一个子元素节点且没有子 Text 节点,并且该子元素是带有 title 属性的 abbr 元素,那么 属性的确切值就是正在定义的术语。否则,就是 后代文本内容,即 dfn 元素给出的定义术语。

如果 title 属性存在,那么它必须仅包含正在定义的术语。

祖先元素的 title 属性不会影响 dfn 元素。

一个链接到 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>

通过添加一个 a 元素,可以使 引用 变得明确:

<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>

4.5.9 abbr 元素

Element/abbr

在所有当前引擎中均受支持。

Firefox1+Safari4+Chrome2+
Opera?Edge79+
Edge (旧版)12+Internet Explorer7+
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容.
措辞内容.
可感知内容.
可以使用该元素的上下文:
在期望 措辞内容 的地方。
内容模型:
措辞内容.
在 text/html 中的标签省略:
两个标签都不能省略。
内容属性:
全局属性
此外,title 属性在此元素上具有 特殊语义:缩写的完整术语或扩展
无障碍考虑:
供作者参考.
供实现者参考.
DOM 接口:
使用 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>

不必使用此元素来标记缩写。它在以下情况下被认为是有用的:

title 属性中提供一次扩展不会导致同一文档中其他具有相同内容但没有 title 属性的 abbr 元素表现得像具有相同扩展一样。每个 abbr 元素都是独立的。

4.5.10 ruby 元素

Element/ruby

在所有当前引擎中均受支持。

Firefox38+Safari5+Chrome5+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容
措辞内容
可感知内容
可以使用此元素的上下文:
在期望 措辞内容 的地方。
内容模型:
参见正文。
在 text/html 中的标签省略:
没有标签可以省略。
内容属性:
全局属性
可访问性考虑:
对于作者
对于实现者
DOM 接口:
使用 HTMLElement

ruby 元素允许一个或多个短语内容的片段被标记为 ruby 注释。Ruby 注释是与基础文本并排显示的短文本片段,主要用于东亚排版,作为发音指南或包含其他注释。在 日语中,这种排版形式也被称为 furigana

ruby 元素的内容模型由以下一种或多种 序列组成:

  1. 以下之一:

  2. 以下之一:

rubyrt 元素可以用于多种类型的注释,尤其包括(但不限于)下述描述的那些。有关特别是日语 Ruby 的更多细节,以及如何为日语渲染 Ruby,请参见 日语文本布局要求[JLREQ]

在撰写时,CSS 还未提供完全控制 HTML ruby 元素渲染的方式。希望 CSS 能在适当的时候扩展以支持下述样式。

日语中单个基本字符的单字注音

一个或多个平假名或片假名字符(注音标注)与每个表意字符(基本文本)一起放置。这用于提供汉字字符的读音。

<ruby>B<rt>annotation</ruby>

在此示例中,请注意每个注音如何对应一个基本字符。

<ruby><rt>くん</ruby><ruby><rt></ruby><ruby><rt></ruby>して<ruby><rt>どう</ruby>ぜず。

くんしてどう ぜず。

在这个例子中,可以用一个ruby元素来书写,包含两个基本文本片段和两个注音(每个一个),而不是两个连续的ruby元素,每个包含一个基本文本片段和注音(如上面的标记所示):

<ruby><rt>くん</rt><rt></rt>
复合词(熟语)的单字注音

这与前面的情况类似:复合词中的每个表意字符(基本文本)都用平假名或片假名字符(注音标注)给出其读音。不同之处在于,基本文本片段形成复合词,而不是彼此分离。

<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>

編集者editor

熟字注音的组注音

对应于多个基本字符的语音读音,因为一对一的映射将非常困难。(在英语中,“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>の方角

とうなん Southeast の方角


在没有ruby元素祖先的ruby元素中,内容被分段并分为三类:基本文本段、注释段和被忽略的段。被忽略的段不构成文档的语义(它们包含一些元素间空白rp元素,后者用于不支持ruby的遗留用户代理)。基本文本段可以重叠(每个位置最多两个段重叠,且任何段具有早于重叠段的开始点也必须具有相同或更晚的结束点,任何段具有晚于重叠段的结束点也必须具有相同或更早的开始点)。注释段对应于rt元素。每个注释段可以与一个基本文本段相关联,每个基本文本段也可以有注释段关联。(在符合规范的文档中,每个基本文本段都与至少一个注释段相关联,每个注释段都与一个基本文本段相关联。)ruby元素表示它包含的基本文本段的并集,以及这些基本文本段与注释段的映射。段的描述基于DOM范围;注释段范围始终由一个元素组成。[DOM]

在任何特定时间,ruby元素内容的分段和分类结果是运行以下算法得到的结果:

  1. base text segments成为一个空的基本文本段列表,每个段可能有一个基本文本子段列表。

  2. annotation segments成为一个空的注释段列表,每个段可能与一个基本文本段或子段相关联。

  3. root成为正在运行算法的ruby元素。

  4. 如果root有一个ruby元素祖先,则跳到标记为结束的步骤。

  5. current parentroot

  6. index为0。

  7. start index为null。

  8. parent start index为null。

  9. current base text为null。

  10. 开始模式:如果index大于或等于current parent中的子节点数量,则跳到标记为结束模式的步骤。

  11. 如果current parent中的第index个节点是rtrp元素,则跳到标记为注释模式的步骤。

  12. start index设置为index的值。

  13. 基本模式:如果current parent中的第index个节点是ruby元素,并且current parent是与root相同的元素,则推送一个ruby层级,然后跳到标记为开始模式的步骤。

  14. 如果current parent中的第index个节点是rtrp元素,则设置当前基本文本,然后跳到标记为注释模式的步骤。

  15. index增加1。

  16. 基本模式后递增:如果index大于或等于current parent中的子节点数量,则跳到标记为结束模式的步骤。

  17. 跳回到标记为基本模式的步骤。

  18. 注释模式:如果current parent中的第index个节点是rt元素,则推送一个ruby注释,然后跳到标记为注释模式递增的步骤。

  19. 如果current parent中的第index个节点是rp元素,则跳到标记为注释模式递增的步骤。

  20. 如果current parent中的第index个节点不是Text节点,或者是一个不是元素间空白Text节点,则跳到标记为基本模式的步骤。

  21. 注释模式递增:让lookahead indexindex加1。

  22. 注释模式空白跳过:如果lookahead index等于current parent中的子节点数量,则跳到标记为结束模式的步骤。

  23. 如果lookahead index中的第lookahead index个节点是rt元素或rp元素,则将index设置为lookahead index,并跳到标记为注释模式的步骤。

  24. 如果lookahead index中的第lookahead index个节点不是Text节点,或者是一个不是元素间空白Text节点,则跳到标记为基本模式的步骤(不再增加index,所以到目前为止看到的元素间空白成为下一个基本文本段的一部分)。

  25. lookahead index增加1。

  26. 跳到标 记为注释模式空白跳过的步骤。

  27. 结束模式:如果current parent不是与root相同的元素,则弹出一个ruby层级,并跳到标记为基本模式后递增的步骤。

  28. 结束:返回base text segmentsannotation segmentsruby元素的任何内容如果没有被这两个列表中的段描述,则隐含在被忽略的段中。

当上述步骤提到设置当前基本文本时,意味着在算法中的那个点上执行以下步骤:

  1. annotation range是一个DOM范围,其开始边界点current parentstart index),其结束边界点current parentindex)。

  2. base text segments是一个由范围annotation range描述的基本文本段。

  3. base text segments添加到base text segments中。

  4. current base textbase text segments

  5. start index为null。

当上述步骤提到推送一个ruby层级时,意味着在算法中的那个点上执行以下步骤:

  1. current parentcurrent parent中的第index个节点。

  2. index为0。

  3. saved start index设置为start index的值。

  4. start index为null。

当上述步骤提到弹出一个ruby层级时,意味着在算法中的那个点上执行以下步骤:

  1. indexcurrent parentroot中的位置。

  2. current parentroot

  3. index增加1。

  4. start index设置为saved start index的值。

  5. saved start index为null。

当上述步骤提到推送一个ruby注释时,意味着在算法中的那个点上执行以下步骤:

  1. rtrt元素,它是current parent的第index个节点。

  2. annotation range是一个DOM范围,其开始边界点current parentindex),其结束边界点current parentindex加一)(即,仅包含rt)。

  3. new annotation segment是一个由范围annotation range描述的注释段。

  4. 如果current base text不为null,将new annotation segmentcurrent base text关联。

  5. new annotation segment添加到annotation segments中。

在这个例子中,日文文本漢字中的每个汉字都用平假名注释其读音。

...
<ruby><rt>かん</rt><rt></rt></ruby>
...

这可能会被渲染为:

The two main ideographs, each with its annotation in hiragana rendered in a smaller font above it.

在这个示例中,繁体中文文本中的每个汉字都标注了其注音符号读音。

<ruby><rt>ㄏㄢˋ</rt><rt>ㄗˋ</rt></ruby>

这可能会渲染成:

The two main ideographs, each with its bopomofo annotation rendered in a smaller font next to it.

在这个例子中,每个简体中文文本汉字中的汉字都附有它的拼音注音。

...<ruby><rt>hàn</rt><rt></rt></ruby>...

这可能会渲染成:

The two main ideographs, each with its pinyin annotation rendered in a smaller font above it.

在这个更复杂的示例中,缩写“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>

4.5.11 rt 元素

Element/rt

在所有当前引擎中都支持。

Firefox38+Safari5+Chrome5+
Opera?Edge79+
Edge (旧版)?Internet Explorer5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
无。
该元素可以使用的上下文:
作为 ruby 元素的子元素。
内容模型:
短语内容
在 text/html 中的标签省略:
rt 元素的 结束标签 可以省略,如果该 rt 元素后面紧跟着一个 rtrp 元素,或者如果父元素中没有更多内容。
内容属性:
全局属性
无障碍考虑:
给作者的建议
给实现者的建议
DOM 接口:
使用 HTMLElement

rt 元素标记了 ruby 注释的 ruby 文本组件。当它是 ruby 元素的子元素时,它本身并不 代表 任何东西,但 ruby 元素使用它作为确定 代表 什么的一部分。

一个不属于 ruby 元素的 rt 元素 代表 与它的子元素相同的东西。

4.5.12 rp 元素

Element/rp

Support in all current engines.

Firefox38+Safari5+Chrome5+
Opera?Edge79+
Edge (旧版)?Internet Explorer5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
无。
可以使用该元素的上下文:
作为 ruby 元素的子元素,紧接在 rt 元素之前或之后。
内容模型:
文本
在 text/html 中的标签省略:
rp 元素的 结束标签 可以省略,如果该 rp 元素后面紧跟着一个 rt 元素或另一个 rp 元素,或者父元素中没有更多内容。
内容属性:
全局属性
可访问性考虑:
给作者的建议
给实施者的建议
DOM 接口:
使用 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.

4.5.13 data 元素

Element/data

支持所有当前的浏览器。

Firefox22+Safari10+Chrome62+
Opera?Edge79+
Edge (旧版)18Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLDataElement

支持所有当前的浏览器。

Firefox22+Safari10+Chrome62+
Opera?Edge79+
Edge (旧版)14+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容.
短语内容.
可触及内容.
此元素可以使用的上下文:
在期望出现短语内容的地方。
内容模型:
短语内容.
在 text/html 中的标签省略:
没有标签是可省略的。
内容属性:
全局属性
value — 机器可读的值
无障碍考虑:
对于作者.
对于实现者.
DOM 接口:
[Exposed=Window]
interface HTMLDataElement : HTMLElement {
  [HTMLConstructor] constructor();

  [CEReactions] attribute DOMString value;
};

data 元素 表示 其内容,并在 value 属性中提供这些内容的机器可读形式。

value 属性必须存在。其值必须是元素内容的机器可读格式的表示。

当值与日期或时间相关时,可以使用更具体的 time 元素。

该元素可以用于多种目的。

与本规范中定义的微格式或 微数据属性 结合使用时,该元素可以为数据处理器提供机器可读的值,并为网页浏览器呈现提供人类可读的值。在这种情况下,value 属性中使用的格式由所使用的微格式或微数据词汇决定。

然而,该元素也可以与页面中的脚本一起使用,当脚本需要存储与人类可读值并存的字面值时。在这种情况下,所使用的格式仅取决于脚本的需要。(data-* 属性在这种情况下也可能有用。)

HTMLDataElement/value

支持所有当前浏览器。

Firefox22+Safari10+Chrome62+
Opera?Edge79+
Edge (旧版)14+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

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>

4.5.14 time 元素

元素/time

所有当前引擎的支持。

Firefox22+Safari7+Chrome62+
Opera49+Edge79+
Edge (旧版)18Internet Explorer
Firefox Android?Safari iOS4+Chrome Android?WebView Android?Samsung Internet?Opera Android46+

HTMLTimeElement

所有当前引擎的支持。

Firefox22+Safari10+Chrome62+
Opera49+Edge79+
Edge (旧版)14+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android46+
类别:
流内容.
短语内容.
可感知内容.
此元素可以使用的上下文:
在期望有短语内容的地方。
内容模型:
如果元素有一个 datetime 属性: 短语内容.
否则: 文本,但必须符合下面文本中的要求。
在 text/html 中的标签省略:
没有标签是可以省略的。
内容属性:
全局属性
datetime — 机器可读值
可访问性考虑:
作者
实现者
DOM 接口:
[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>
四个或更多ASCII数字,其中至少有一个不是U+0030数字零(0)
<time>2011</time>
<time>0001</time>
一个有效的持续时间字符串
<time>PT4H18M3S</time>
<time>4h18m 3s</time>

元素内容的 机器可读等效 必须通过以下算法从元素的 datetime 值 获取:

  1. 如果从元素的 datetime 值 解析一个 月份字符串 返回一个 月份,那就是机器可读的等效;返回。

  2. 如果从元素的 datetime 值 解析一个 日期字符串 返回一个 日期,那就是机器可读的等效;返回。

  3. 如果从元素的 datetime 值 解析一个 无年份日期字符串 返回一个 无年份日期,那就是机器可读的等效;返回。

  4. 如果从元素的 datetime 值 解析一个 时间字符串 返回一个 时间,那就是机器可读的等效;返回。

  5. 如果从元素的 datetime 值 解析一个 本地日期和时间字符串 返回一个 本地日期和时间,那就是机器可读的等效;返回。

  6. 如果从元素的 datetime 值 解析一个 时区偏移字符串 返回一个 时区偏移,那就是机器可读的等效;返回。

  7. 如果从元素的 datetime 值 解析一个 全球日期和时间字符串 返回一个 全球日期和时间,那就是机器可读的等效;返回。

  8. 如果从元素的 datetime 值 解析一个 周字符串 返回一个 ,那就是机器可读的等效;返回。

  9. 如果元素的 datetime 值 仅由 ASCII 数字 组成,其中至少一个不是 U+0030 DIGIT ZERO (0),那么机器可读的等效是这些数字的十进制解释,代表一个年份;返回。

  10. 如果从元素的 datetime 值 解析一个 持续时间字符串 返回一个 持续时间,那就是机器可读的等效;返回。

  11. 没有机器可读的等效。

上述提到的算法旨在设计成对于任何任意字符串 s,只有一个算法会返回一个值。更高效的方法可能是创建一个算法,能够在一次操作中解析所有这些数据类型;开发这样的算法留给读者作为练习。

HTMLTimeElement/dateTime

在所有当前引擎中都受支持。

Firefox22+Safari10+Chrome62+
Opera49+Edge79+
Edge(旧版)14+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android46+

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>.

4.5.15 code 元素

Element/code

所有当前引擎都支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容.
短语内容.
可感知内容.
此元素可以使用的上下文:
在期望有短语内容的地方。
内容模型:
短语内容.
在 text/html 中的标签省略:
没有标签可以省略。
内容属性:
全局属性
无障碍考虑:
针对作者.
针对实现者.
DOM 接口:
使用 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>

以下示例展示了如何使用 precode 元素标记一段代码。

<pre><code class="language-pascal">var i: Integer;
begin
   i := 1;
end.</code></pre>

在该示例中使用了一个类来指示所用的语言。

有关更多详细信息,请参见 pre 元素。

4.5.16 var 元素

Element/var

所有当前引擎都支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容.
短语内容.
可触及内容.
该元素可以使用的上下文:
在期望出现 短语内容 的地方。
内容模型:
短语内容.
在 text/html 中的标签省略:
没有标签可以省略。
内容属性:
全局属性
无障碍考虑:
对于作者.
对于实现者.
DOM 接口:
使用 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>

4.5.17 samp 元素

Element/samp

所有当前引擎都支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容.
短语内容.
可触及内容.
该元素可以使用的上下文:
在期望出现 短语内容 的地方。
内容模型:
短语内容.
在 text/html 中的标签省略:
没有标签可以省略。
内容属性:
全局属性
无障碍考虑:
对于作者.
对于实现者.
DOM 接口:
使用 HTMLElement.

samp 元素 表示 从另一个程序或计算系统中获取的示例或引用输出。

请参阅 prekbd 元素以获取更多详细信息。

该元素可以与 output 元素进行对比,后者可用于提供 Web 应用程序中的即时输出。

此示例显示了 samp 元素的内联用法:

<p>The computer said <samp>Too much cheese in tray
two</samp> but I didn't know what that meant.</p>

第二个示例展示了来自控制台程序的示例输出块。嵌套的 sampkbd 元素允许使用样式表对示例输出的特定元素进行样式设置。还有一些 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>

第三个示例展示了一个输入块及其相应的输出。该示例使用了 codesamp 元素。

<pre>
<code class="language-javascript">console.log(2.3 + 2.4)</code>
<samp>4.699999999999999</samp>
</pre>

4.5.18 kbd 元素

Element/kbd

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容.
短语内容.
可触及内容.
可以使用此元素的上下文:
在期望有短语内容的地方。
内容模型:
短语内容.
在 text/html 中的标签省略:
两个标签都不可省略。
内容属性:
全局属性
无障碍考虑:
给作者的建议.
给实施者的建议.
DOM 接口:
使用 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>

4.5.19 subsup 元素

元素/sub

所有当前浏览器均支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

元素/sup

所有当前浏览器均支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
分类:
流内容
短语内容
可触及内容
可以使用此元素的上下文:
在期望 短语内容 的地方。
内容模型:
短语内容
在 text/html 中的标签省略:
两个标签都不可省略。
内容属性:
全局属性
无障碍考虑:
sub 元素: 给作者给实施者
sup 元素: 给作者给实施者
DOM 接口:
使用 HTMLElement

sup 元素 表示 上标,而 sub 元素 表示 下标。

这些元素只能用于标记具有特定含义的排版约定,而不是为了排版效果而使用。例如,将 subsup 元素用于 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 来标记数学内容,但如果不需要详细的数学标记,作者可以选择使用 subsup[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>

4.5.20 i 元素

元素/i

所有当前引擎均支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge(遗留版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容.
短语内容.
可感知内容.
此元素可以使用的上下文:
期望出现的短语内容
内容模型:
短语内容.
在 text/html 中的标签省略:
标签不可省略。
内容属性:
全局属性
无障碍考虑:
面向作者.
面向实现者.
DOM 接口:
使用 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 元素中的内容不一定会被斜体显示。

4.5.21 b 元素

Element/b

所有当前浏览器均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
分类:
流内容.
短语内容.
可感知内容.
可以使用此元素的上下文:
在期望出现短语内容的地方。
内容模型:
短语内容.
在 text/html 中的标签省略:
没有标签可以省略。
内容属性:
全局属性
无障碍考虑:
供作者参考.
供实施者参考.
DOM 接口:
使用 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>元素。

以下是不正确的用法:

<p><b>WARNING!</b> Do not frob the barbinator!</p>

在之前的例子中,正确的元素应该是strong,而不是b

样式表可以用于格式化 b 元素,就像可以重新样式化任何其他元素一样。因此,b 元素中的内容不一定会被加粗。

4.5.22 u 元素

Element/u

在所有当前引擎中都支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge(遗留版)12+Internet Explorer
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别
流内容
措辞内容
可触及内容
此元素可用的上下文
在期望 措辞内容 的地方。
内容模型
措辞内容
文本/html 中的标签省略
两个标签都不可省略。
内容属性
全局属性
无障碍考虑
供作者参考
供实施者参考
DOM 接口
使用 HTMLElement

u 元素 表示 一段文本,该文本具有未明确表达但显式呈现的非文本注释,例如在中文文本中标记该文本为专有名称(中文专有名称标记),或标记该文本为拼写错误。

在大多数情况下,另一个元素可能更合适:用于标记强调的,应该使用 em 元素;用于标记关键词或短语,根据上下文应使用 b 元素或 mark 元素;用于标记书名,应该使用 cite 元素;用于带有明确文本注释的标记,应该使用 ruby 元素;用于技术术语、分类名称、音译、思想,或在西方文本中标记船名,应该使用 i 元素。

在视觉呈现中,u 元素的默认渲染与超链接(下划线)的传统渲染相冲突。建议作者避免在可能与超链接混淆的情况下使用 u 元素。

在这个示例中,使用了 u 元素来标记一个拼写错误的词:

<p>The <u>see</u> is full of fish.</p>

4.5.23 mark 元素

Element/mark

在所有当前引擎中都支持。

Firefox4+Safari5.1+Chrome7+
Opera11+Edge79+
Edge(遗留版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别
流内容
措辞内容
可触及内容
此元素可用的上下文
在期望 措辞内容 的地方。
内容模型
措辞内容
文本/html 中的标签省略
两个标签都不可省略。
内容属性
全局属性
无障碍考虑
供作者参考
供实施者参考
DOM 接口
使用 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>

4.5.24 bdi 元素

Element/bdi

支持所有当前的浏览器。

Firefox10+Safari6+Chrome16+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android?
类别:
流内容.
短语内容.
可感知内容.
此元素可以使用的上下文:
在期望有短语内容的地方。
内容模型:
短语内容.
在 text/html 中的标签省略:
没有标签可以省略。
内容属性:
全局属性
此外,dir 全局属性在此元素上具有特殊语义。
可访问性考虑:
针对作者.
针对实现者.
DOM 接口:
使用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”和句号。

4.5.25 bdo 元素

Element/bdo

在所有当前引擎中都支持。

Firefox10+Safari4+Chrome15+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容
措辞内容
可感知内容
可以使用该元素的上下文:
在需要措辞内容的地方。
内容模型:
措辞内容
在 text/html 中的标签省略:
没有标签可以省略。
内容属性:
全局属性
此外,dir全局属性在该元素上具有特殊语义。
无障碍考虑:
对于作者
对于实施者
DOM 接口:
使用 HTMLElement

bdo 元素 表示 对其子元素的显式文本方向格式控制。它允许作者通过显式指定方向覆盖来覆盖 Unicode 双向算法。[BIDI]

作者必须在该元素上指定 dir 属性,值为 ltr 以指定从左到右的覆盖,值为 rtl 以指定从右到左的覆盖。auto 值不得指定。

该元素 具有涉及双向算法的渲染要求

4.5.26 span 元素

元素/span

在所有当前浏览器中均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLSpanElement

在所有当前浏览器中均支持。

Firefox1+Safari6+Chrome15+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
流内容
措辞内容
可感知内容
可以使用该元素的上下文:
在需要措辞内容的地方。
内容模型:
措辞内容
在 text/html 中的标签省略:
没有标签可以省略。
内容属性:
全局属性
无障碍考虑:
对于作者
对于实施者
DOM 接口:
[Exposed=Window]
interface HTMLSpanElement : HTMLElement {
  [HTMLConstructor] constructor();
};

span 元素本身没有特定含义,但与 全局属性(例如 classlangdir)一起使用时非常有用。它 表示 其子元素。

在这个示例中,代码片段使用了 span 元素和 class 属性进行标记,以便通过 CSS 对其关键字和标识符进行颜色编码:

<pre><code class="lang-c"><span class="keyword">for</span> (<span class="ident">j</span> = 0; <span class="ident">j</span> &lt; 256; <span class="ident">j</span>++) {
  <span class="ident">i_t3</span> = (<span class="ident">i_t3</span> & 0x1ffff) | (<span class="ident">j</span> &lt;&lt; 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>

4.5.27 br 元素

Element/br

所有当前引擎的支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLBRElement

所有当前引擎的支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容.
措辞内容.
可以使用该元素的上下文:
在需要措辞内容的地方。
内容模型:
.
在 text/html 中的标签省略:
没有结束标签
内容属性:
全局属性
无障碍考虑:
对于作者.
对于实施者.
DOM 接口:
[Exposed=Window]
interface HTMLBRElement : HTMLElement {
  [HTMLConstructor] constructor();

  // also has obsolete members
};

br 元素表示一个换行符。

虽然换行符在视觉媒体中通常通过将后续文本物理移动到新行来表示,但样式表或用户代理同样可以将换行符以其他方式呈现,例如作为绿色点或额外的间距。

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元素内部的内容 不应被视为周围文本的一部分。

这个元素有涉及双向算法的呈现要求

4.5.28 wbr 元素

元素/wbr

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera11.6+Edge79+
Edge (旧版)?Internet Explorer5.5–7
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
类别:
流内容
短语内容
该元素可以使用的上下文:
在期望 短语内容 的地方。
内容模型:
在 text/html 中的标签省略:
没有 结束标签
内容属性:
全局属性
无障碍考虑:
对于作者
对于实施者
DOM 接口:
使用 HTMLElement

wbr 元素 表示 一种换行机会。

在以下示例中,有人引用了某句话,这句话为了效果被写成了一个长单词。然而,为了确保文本可以以可读的方式换行,这句话中的单词使用了 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);

该元素 具有涉及双向算法的渲染要求

4.5.29 使用总结

本节为非规范性内容。

元素 用途 示例
a 超链接
访问我的<a href="drinks.html">drinks</a>页面。
em 强调重音
我必须说我<em>非常喜爱</em>柠檬水。
strong 重要性
这茶<strong>非常烫</strong>
small 附带评论
这些葡萄被酿成了酒。<small>酒精具有成瘾性。</small>
s 不准确的文本
价格:<s>£4.50</s> £2.00!
cite 作品标题
案件<cite>Hugo v. Danielle</cite>在此具有相关性。
q 引用
法官说<q>你可以喝鱼缸里的水</q>但不建议这么做。
dfn 定义实例
术语<dfn>有机食品</dfn>指不使用合成化学品生产的食品。
abbr 缩写
爱尔兰的有机食品由<abbr title="Irish Organic Farmers and Growers Association">IOFGA</abbr>认证。
ruby, rt, rp 注音标注
<ruby>OJ<rp>(<rt>橙汁</rp>)</ruby>
data 机器可读的等价物
今天起有售!<data value="UPC:022014640201">北岸有机苹果酒</data>
time 日期或时间相关数据的机器可读等价物
<time datetime="2011-11-18">11月18日</time>开始有售!
code 计算机代码
<code>fruitdb</code>程序可用于跟踪水果生产。
var 变量
如果碗里有<var>n</var>个水果,至少<var>n</var>÷2会是熟的。
samp 计算机输出
电脑显示<samp>未知错误 -3</samp>
kbd 用户输入
<kbd>F1</kbd>继续。
sub 下标
水的化学式为 H<sub>2</sub>O。
sup 上标
重水中的氢通常是<sup>2</sup>H。
i 替代声音
柠檬水主要由<i>柠檬柑橘</i>组成。
b 关键词
拿一个<b>柠檬</b>并用一个<b>榨汁机</b>榨汁。
u 注解
苹果汁与<u class="spelling">接骨木花</u>汁的混合物非常宜人。
mark 高亮
接骨木花糖浆,按<mark>1 份</mark>糖浆兑 10 份水的比例调配,与其他饮品<mark>显著不同</mark>
bdi 文本方向隔离
推荐的餐厅是<bdi lang="">My Juice Café (At The Beach)</bdi>
bdo 文本方向格式化
提议是用反向顺序写英语。"Juice" 会变成 "<bdo dir=rtl>eciuJ</bdo>"。
span 其他
在法语中我们称它为<span lang="fr">sirop de sureau</span>
br 换行
Simply Orange Juice Company<br>Apopka, FL 32703<br>美国
wbr 换行机会
www.simply<wbr>orange<wbr>juice.com

4.6.1 介绍

链接是一个概念性构造,通过 aareaformlink 元素创建,这些元素 表示 两个资源之间的连接,其中一个是当前的 文档。在 HTML 中有三种类型的链接:

外部资源链接

这些链接指向需要用来增强当前文档的资源,通常由用户代理自动处理。所有 外部资源链接 都具有 获取和处理链接资源 算法,用于描述如何获取资源。

超链接

这些链接指向其他资源,通常由用户代理向用户公开,以便用户可以使用户代理 导航 到这些资源,例如访问它们或下载它们。

内部资源链接

这些链接指向当前文档中的资源,用于赋予这些资源特殊的意义或行为。

对于具有 link 元素、href 属性和 rel 属性的链接,必须为 rel 属性的关键字创建链接,这些关键字在 链接类型 部分中定义。

类似地,对于具有 aarea 元素、href 属性和 rel 属性的链接,必须为 rel 属性的关键字创建链接,这些关键字在 链接类型 部分中定义。然而,与 link 元素不同的是,aarea 元素如果具有 href 属性,但没有 rel 属性,或者其 rel 属性没有定义为指定 超链接 的关键字,也必须创建一个 超链接。这种隐含的超链接没有特殊意义(它没有 链接类型),仅仅是将元素的 节点文档 链接到元素的 href 属性指定的资源。

类似地,对于具有 form 元素和 rel 属性的链接,必须为 rel 属性的关键字创建链接,这些关键字在 链接类型 部分中定义。没有 rel 属性的 form 元素,或者其 rel 属性没有定义为指定 超链接 的关键字,也必须创建一个 超链接

一个 超链接 可以有一个或多个 超链接注解,这些注解修改该超链接的处理语义。

href 属性在 aarea 元素上必须具有一个 有效的 URL,可能被空格包围 的值。

href 属性在 aarea 元素上不是必需的;当这些元素没有 href 属性时,它们不会创建超链接。

target 属性(如果存在)必须是 有效的可导航目标名称或关键字。它给出了将使用的 可导航目标 的名称。用户代理在 跟随超链接 时使用此名称。

download 属性(如果存在)表示作者打算将超链接用于 下载资源。该属性可以有一个值;如果有,该值指定作者建议用于在本地文件系统中标记资源的默认文件名。对允许的值没有限制,但作者应注意,大多数文件系统对文件名中支持的标点符号有限制,用户代理可能会相应地调整文件名。

Element/a#attr-ping

所有当前引擎的支持。

Firefox🔰 1+ Safari6+ Chrome12+
Opera? Edge79+
Edge (旧版)17+ Internet Explorer
Firefox Android? Safari iOS? Chrome Android? WebView Android≤37+ Samsung Internet? Opera Android?

ping 属性(如果存在)提供了希望在用户跟随超链接时收到通知的资源的 URL。其值必须是一个用空格分隔的令牌集合,每个令牌必须是一个有效的非空 URL,其方案必须是HTTP(S) 方案。该值由用户代理用于超链接审计

rel 属性在aarea 元素上控制元素创建的链接类型。属性值必须是一个无序的唯一空格分隔令牌集合允许的关键词及其含义在下文定义。

rel支持的令牌HTML 链接类型中定义的允许在aarea 元素上使用的关键词,这些关键词影响处理模型,并由用户代理支持。可能的支持的令牌包括noreferrernoopeneropenerrel支持的令牌必须仅包括用户代理实现处理模型的令牌。

rel 属性没有默认值。如果省略该属性,或者属性中的值都未被用户代理识别,则文档与目标资源之间没有特定的关系,只是两个之间存在一个超链接。

hreflang 属性在创建超链接a 元素上(如果存在)提供了链接资源的语言。该属性仅供参考。其值必须是有效的 BCP 47 语言标签。[BCP47] 用户代理不应将该属性视为权威性——在获取资源时,用户代理必须仅使用与资源关联的语言信息来确定其语言,而不是链接中包含的元数据。

type 属性(如果存在)提供了链接资源的MIME 类型。该属性仅供参考。其值必须是有效的 MIME 类型字符串。用户代理不得将type 属性视为权威性——在获取资源时,用户代理不得使用链接中包含的元数据来确定其类型。

referrerpolicy 属性是一个referrer 策略属性。其目的是设置在跟随超链接时使用的referrer 策略[REFERRERPOLICY]


aarea 元素的激活行为 被触发时,用户代理可以允许用户表示是否希望将超链接用于导航,或者是否希望下载指定的资源。

在没有用户偏好的情况下,如果元素没有download 属性,则默认行为应为导航;如果元素具有该属性,则默认行为应为下载指定的资源。

一个aarea 元素的激活行为 在给定事件event 时为:

  1. 如果element没有href属性,则返回。

  2. hyperlinkSuffix设为null。

  3. 如果elementa元素,并且event目标是具有ismap属性的img,则:

    1. xy设为0。

    2. 如果eventisTrusted属性被初始化为true,则将x设为图像左边缘到点击位置的距离(以CSS 像素为单位),将y设为图像上边缘到点击位置的距离(以CSS 像素为单位)。

    3. 如果x为负,则将x设为0。

    4. 如果y为负,则将y设为0。

    5. hyperlinkSuffix设为U+003F(?)、x的值(以十进制整数形式使用ASCII 数字表示)、U+002C(,)和y的值(以十进制整数形式使用ASCII 数字表示)的拼接。

  4. userInvolvement设为event用户导航参与

  5. 如果用户表示了下载超链接的偏好,则将userInvolvement设为"browser UI"。

    即,如果用户表示了特定的下载偏好,这不再被视为仅仅是"activation"。

  6. 如果element具有download属性,或者用户表示了下载超链接的偏好,则下载由element创建的超链接,将hyperlinkSuffix设为hyperlinkSuffix,将userInvolvement设为userInvolvement

  7. 否则,跟随由element创建的超链接,将hyperlinkSuffix设为hyperlinkSuffix,将userInvolvement设为userInvolvement

4.6.3 aarea 元素的 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

HTMLAnchorElement/href

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLAnchorElement/toString

所有当前引擎都支持。

Firefox22+Safari3+Chrome52+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAreaElement/href

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLAreaElement/toString

所有当前引擎都支持。

Firefox22+Safari10.1+Chrome32+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回超链接的 URL。

可以设置,以更改 URL。

hyperlink.origin

HTMLAnchorElement/origin

所有当前浏览器均支持。

Firefox26+Safari5.1+Chrome8+
Opera?Edge79+
Edge (旧版)17+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android?

HTMLAreaElement/origin

所有当前浏览器均支持。

Firefox26+Safari10+Chrome32+
Opera?Edge79+
Edge (旧版)17+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android?

返回超链接的 URL 来源。

hyperlink.protocol

HTMLAnchorElement/protocol

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAreaElement/protocol

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回超链接 URL 的 scheme。

可以设置,以更改 URL 的 scheme。

hyperlink.username

HTMLAnchorElement/username

所有当前引擎均支持。

Firefox26+Safari10+Chrome32+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAreaElement/username

所有当前引擎均支持。

Firefox26+Safari10+Chrome32+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回超链接的 URL 的用户名。

可以设置,以更改 URL 的用户名。

hyperlink.password

HTMLAnchorElement/password

所有当前引擎均支持。

Firefox26+Safari10+Chrome32+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAreaElement/password

所有当前引擎均支持。

Firefox26+Safari10+Chrome32+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回超链接的 URL 的密码。

可以设置,以更改 URL 的密码。

hyperlink.host

HTMLAnchorElement/host

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAreaElement/host

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回超链接的 URL 的主机和端口(如果与 scheme 的默认端口不同)。

可以设置,以更改 URL 的主机和端口。

hyperlink.hostname

HTMLAnchorElement/hostname

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAreaElement/hostname

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回超链接的 URL 的主机。

可以设置,以更改 URL 的主机。

hyperlink.port

HTMLAnchorElement/port

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAreaElement/port

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回超链接的 URL 的端口。

可以设置,以更改 URL 的端口。

hyperlink.pathname

HTMLAnchorElement/pathname

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAreaElement/pathname

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回超链接的 URL 的路径。

可以设置,以更改 URL 的路径。

hyperlink.search

HTMLAnchorElement/search

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAreaElement/search

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回超链接的 URL 的查询(包括前导的 "?",如果非空)。

可以设置,以更改 URL 的查询(忽略前导的 "?")。

hyperlink.hash

HTMLAnchorElement/hash

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAreaElement/hash

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回超链接的 URL 的片段(包括前导的 "#",如果非空)。

可以设置,以更改 URL 的片段(忽略前导的 "#")。

实现了 HTMLHyperlinkElementUtils mixin 的元素有一个关联的 url(为 null 或 URL)。初始值为 null。

实现了 HTMLHyperlinkElementUtils mixin 的元素有一个关联的 设置 URL 算法,该算法执行以下步骤:

  1. 将此元素的 url 设置为 null。

  2. 如果此元素的 href 内容属性缺失,则返回。

  3. url 成为 编码解析 URL 的结果,给定此元素的 href 内容属性的值,相对于此元素的 节点文档

  4. 如果 url 不是失败,则将此元素的 url 设置为 url

当实现了 HTMLHyperlinkElementUtils mixin 的元素被创建时,以及每当这些元素的 href 内容属性被设置、修改或删除时,用户代理必须 设置 url

这只对 blob: URLs 可观察,因为 解析 它们涉及到一个 Blob URL 存储 查找。

实现了 HTMLHyperlinkElementUtils mixin 的元素有一个关联的 重新初始化 url 算法,该算法执行以下步骤:

  1. 如果元素的 url 非空,它的 scheme 为 "blob",并且它具有一个 不透明路径,则终止这些步骤。

  2. 设置 url

更新 href,将元素的 href 内容属性的值设置为元素的 url,并进行 序列化


href 获取器步骤如下:

  1. 重新初始化 url

  2. urlthisurl

  3. 如果 url 为 null 且 this 没有 href 内容属性,则返回空字符串。

  4. 否则,如果 url 为 null,则返回 thishref 内容属性的值。

  5. 返回 url,并进行 序列化

href 设置器步骤如下:将 thishref 内容属性的值设置为给定的值。

origin 获取器步骤如下:

  1. 重新初始化 url

  2. 如果 thisurl 为 null,则返回空字符串。

  3. 返回 序列化thisurlorigin

protocol 获取器步骤如下:

  1. 重新初始化 url

  2. 如果 thisurl 为 null,则返回 ":"。

  3. 返回 thisurlscheme,后跟 ":"。

protocol 设置器步骤如下:

  1. 重新初始化 url

  2. 如果 thisurl 为 null,则返回。

  3. 对给定值进行 基本 URL 解析, 后跟 ":",使用 thisurl 作为 urlscheme start state 作为 state override

    因为 URL 解析器会忽略多个连续的冒号,所以提供 "https:"(甚至 "https::::")与提供 "https" 是一样的。

  4. 更新 href

username 获取器步骤如下:

  1. 重新初始化 url

  2. 如果 thisurl 为 null,则返回空字符串。

  3. 返回 thisurlusername

username 设置器步骤如下:

  1. 重新初始化 url

  2. urlthisurl

  3. 如果 url 为 null 或 url 不能具有用户名/密码/端口,则返回。

  4. 设置用户名,给定 url 和给定值。

  5. 更新 href

password 获取器步骤如下:

  1. 重新初始化 url

  2. urlthisurl

  3. 如果 url 为 null,则返回空字符串。

  4. 返回 url密码

password 设置器步骤如下:

  1. 重新初始化 url

  2. urlthisurl

  3. 如果 url 为 null 或 url 不能有用户名/密码/端口,则返回。

  4. 设置密码,给定 url 和指定值。

  5. 更新 href

host 获取器步骤如下:

  1. 重新初始化 url

  2. urlthisurl

  3. 如果 urlurlhost 为 null, 返回空字符串。

  4. 如果 urlport 为 null, 返回 urlhost序列化

  5. 返回 urlhost序列化, 后跟 ":" 和 urlport序列化

host 设置器步骤如下:

  1. 重新初始化 url

  2. urlthisurl

  3. 如果 url 为 null 或 url 有一个 不透明路径,则 返回。

  4. 基本 URL 解析 给定值,将 url 作为 urlhost 状态 作为 状态覆盖

  5. 更新 href

hostname 获取器步骤如下:

  1. 重新初始化 url

  2. urlthisurl

  3. 如果 urlurlhost 为 null, 返回空字符串。

  4. 返回 urlhost序列化

hostname 设置器步骤如下:

  1. 重新初始化 url

  2. urlthisurl

  3. 如果 url 为 null 或 url 有一个 不透明路径,则返回。

  4. 基本 URL 解析 给定的值,使用 url 作为 url主机名状态 作为 状态覆盖

  5. 更新 href

port的getter步骤如下:

  1. 重新初始化 URL

  2. urlthisurl

  3. 如果 urlurl端口 为 null,则返回空字符串。

  4. 返回 url端口,并将其 序列化

port 设置器步骤如下:

  1. 重新初始化 URL

  2. urlthisurl

  3. 如果 url 为 null 或 url 不能包含用户名/密码/端口,则返回。

  4. 如果给定的值为空字符串,则将 url端口 设置为 null。

  5. 否则,基本 URL 解析 给定值,将 url 作为 url,将 端口状态 作为 状态覆盖

  6. 更新 href

pathname 获取器步骤如下:

  1. 重新初始化 URL

  2. urlthisurl

  3. 如果 url 为 null,则返回空字符串。

  4. 返回 URL 路径序列化 url 的结果。

pathname 设置器步骤如下:

  1. 重新初始化 URL

  2. urlthisurl

  3. 如果 url 为 null 或 url 具有 不透明路径,则返回。

  4. url路径 设置为空列表。

  5. 基本 URL 解析 给定值,将 url 作为 url,将 路径开始状态 作为 状态覆盖

  6. 更新 href

search 获取器步骤如下:

  1. 重新初始化 URL

  2. urlthisurl

  3. 如果 url 为 null,或者 url查询 为 null 或空字符串,则返回空字符串。

  4. 返回 "?",后跟 url查询

search 设置器步骤如下:

  1. 重新初始化 URL

  2. urlthisurl

  3. 如果 url 为 null,则终止这些步骤。

  4. 如果给定值为空字符串,则将 url查询 设置为 null。

  5. 否则:

    1. input 为给定值,去除前导的 "?"(如果有的话)。

    2. url查询 设置为空字符串。

    3. 基本 URL 解析 input,将 url 作为 url,将 查询状态 作为 状态覆盖

  6. 更新 href

hash 获取器步骤如下:

  1. 重新初始化 URL

  2. urlthisurl

  3. 如果 url 为 null,或者 url片段 为 null 或空字符串,则返回空字符串。

  4. 返回 "#",后跟 url片段

hash 设置器步骤如下:

  1. 重新初始化 URL

  2. urlthisurl

  3. 如果 url 为 null,则返回。

  4. 如果给定值为空字符串,则将 url片段 设置为 null。

  5. 否则:

    1. input 为给定值,去除前导的 "#"(如果有的话)。

    2. url片段 设置为空字符串。

    3. 基本 URL 解析 input,将 url 作为 url,将 片段状态 作为 状态覆盖

  6. 更新 href

如果满足以下任意条件,则元素 element 不能导航

这也被 表单提交 用于 form 元素。a 元素的例外是为了与网页内容兼容。

获取元素的 noopener,给定一个 aarea,或 form 元素 element 和一个字符串 target

  1. 如果 element链接类型 包含 noopenernoreferrer 关键字,则返回 true。

  2. 如果 element链接类型 不包含 opener 关键字,并且 target 是对 "_blank" 的 ASCII 不区分大小写 匹配,则返回 true。

  3. 返回 false。

跟随由元素 subject 创建的超链接,给定一个可选的 hyperlinkSuffix(默认值为 null)和一个可选的 userInvolvement(默认值为 "none"):

  1. 如果 subject 不能导航,则返回。

  2. replace 设置为 false。

  3. targetAttributeValue 设置为空字符串。

  4. 如果 subjectaarea 元素,则将 targetAttributeValue 设置为 获取元素的目标 的结果,给定 subject

  5. noopener 设置为 获取元素的 noopener 的结果,使用 subjecttargetAttributeValue

  6. targetNavigable 设置为应用 选择可导航对象的规则 的第一个返回值,给定 targetAttributeValuesubject节点可导航性noopener

  7. 如果 targetNavigable 为 null,则返回。

  8. urlString 设置为 编码-解析-序列化 URL 的结果,给定 subjecthref 属性值,相对于 subject节点文档

  9. 如果 urlString 失败,则返回。

  10. 如果 hyperlinkSuffix 非 null,则将其附加到 urlString

  11. referrerPolicy 设置为 subject 的当前状态的 referrerpolicy 内容属性。

  12. 如果 subject链接类型 包含 noreferrer 关键字,则将 referrerPolicy 设置为 "no-referrer"。

  13. 导航 targetNavigableurlString,使用 subject节点文档,将 referrerPolicy 设置为 referrerPolicy,将 userInvolvement 设置为 userInvolvement

    与许多其他类型的导航不同,跟随超链接在文档未 完全加载 时没有特殊的 "replace" 行为。这对于用户发起的跟随超链接实例以及通过例如 aElement.click() 触发的脚本也是如此。

4.6.5 下载资源

HTMLAnchorElement/download

所有当前引擎都支持。

Firefox20+Safari10.1+Chrome15+
Opera?Edge79+
Edge (旧版)13+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

在某些情况下,资源旨在用于稍后而不是立即查看。为了表示资源旨在被下载以便后续使用,而不是立即使用,可以在创建指向该资源的超链接aarea元素上指定download属性。

此外,属性还可以指定一个值,以指定用户代理在将资源存储在文件系统中时应使用的文件名。这个值可以被Content-Disposition HTTP 头的文件名参数覆盖。[RFC6266]

在跨源情况下,download属性必须与Content-Disposition HTTP 头结合使用,特别是与attachment处置类型,以避免用户被警告可能的恶意活动。(这是为了保护用户免于在没有完全理解的情况下下载敏感的个人或机密信息。)


要下载由元素subject创建的超链接,给定一个可选的hyperlinkSuffix(默认为null)和一个可选的userInvolvement(默认为"none"):

  1. 如果subject 无法导航,则返回。

  2. 如果subject节点文档活动沙箱标志设置了沙箱下载浏览上下文标志,则返回。

  3. urlString成为编码、解析和序列化URL的结果,给定subjecthref属性值,相对于subject节点文档

  4. 如果urlString失败,则返回。

  5. 如果hyperlinkSuffix非空,则将其附加到urlString

  6. 如果userInvolvement不是"browser UI",则:

    1. 断言subject具有download属性。

    2. navigation成为subject相关全局对象导航API

    3. filename成为subjectdownload属性的值。

    4. continue成为在navigation上触发下载请求navigate事件的结果,设置destinationURLurlStringuserInvolvementuserInvolvementfilenamefilename

    5. 如果continue为false,则返回。

  7. 并行执行以下步骤:

    1. 用户代理可以选择中止这些步骤,如果认为这样做可以保护用户免受潜在的恶意下载。

    2. request成为一个新的请求,其URLurlString客户端入口设置对象发起者为"download",目的地为空字符串,并且其同步标志使用URL凭证标志被设置。

    3. 处理对request获取结果,作为下载处理。

当用户代理需要将从fetch获取的资源作为下载处理时,如果成功获取资源,它应该提供一种方式让用户将资源保存以便后用。否则,它应该向用户报告任何下载文件时出现的问题。

如果用户代理需要为作为下载处理的资源选择一个文件名,它应使用以下算法。

该算法旨在减轻从不信任的网站下载文件的安全风险,强烈建议用户代理遵循此算法。

  1. filename设为未定义值。

  2. 如果资源有一个`Content-Disposition`头部,该头部指定了attachment处置类型,并且头部包含文件名信息,则将filename设为头部指定的值,然后跳转到下列sanitize步骤。[RFC6266]

  3. interface origin设为Documentdownloadnavigate操作发起的origin,如果有的话。

  4. resource origin设为下载资源的URL的origin,除非该URL的scheme组件是data,在这种情况下,将resource origin设为interface origin,如果有的话。

  5. 如果没有interface origin,则将trusted operation设为true。否则,如果resource origininterface origin相同来源,则将trusted operation设为true,否则设为false。

  6. 如果trusted operation为true,并且资源有一个`Content-Disposition`头部且头部包含文件名信息,则将filename设为头部指定的值,然后跳转到下列sanitize步骤。[RFC6266]

  7. 如果下载不是由aarea元素创建的超链接发起的,或者发起下载的超链接的元素在下载发起时没有download属性,或者有该属性但其值在下载发起时为空字符串,则跳到标记为无建议文件名的步骤。

  8. proposed filename设为发起下载时hyperlink的`download`属性的值。

  9. 如果trusted operation为true,则将filename设为proposed filename,然后跳转到下列sanitize步骤。

  10. 如果资源有一个`Content-Disposition`头部且该头部指定了attachment处置类型,则将filename设为proposed filename,然后跳转到下列sanitize步骤。[RFC6266]

  11. No proposed filename:如果trusted operation为true,或者用户表示希望下载该资源,则将filename的值从资源的URL中以实现定义的方式派生,并跳转到下列sanitize步骤。

  12. filename设为用户的首选文件名或用户代理选择的文件名,然后跳转到下列sanitize步骤。

    如果算法达到此步骤,则表示下载是从与资源来源不同的来源发起的,并且该来源没有标记文件为适合下载,并且下载不是由用户发起的。这可能是因为使用了`download`属性来触发下载,或因为所涉及的资源不是用户代理支持的类型。

    这可能是危险的,例如,恶意服务器可能试图让用户在不知情的情况下下载私人信息,并将其重新上传到恶意服务器,通过欺骗用户认为数据来自恶意服务器。

    因此,用户的利益在于某种方式通知用户该资源来自完全不同的来源,并且为了防止混淆,任何潜在恶意的interface origin所建议的文件名应被忽略。

  13. Sanitize:可选地,允许用户影响filename。例如,用户代理可以提示用户输入文件名,可能将上述确定的filename作为默认值。

  14. filename调整为适合本地文件系统的格式。

    例如,这可能涉及去除文件名中不合法的字符,或修剪前导和尾随空白字符。

  15. 如果平台约定在任何方式上不使用扩展名来确定文件系统上的文件类型,则将filename作为文件名返回。

  16. claimed type设为资源的Content-Type元数据给出的类型(如果已知)。将named type设为filename扩展名给出的类型(如果已知)。对于此步骤的目的,type是一个将MIME类型映射到扩展名的映射。

  17. 如果named type与用户的首选项一致(例如,因为filename的值是通过提示用户确定的),则将filename作为文件名返回。

  18. 如果claimed typenamed type是相同的类型(即资源的Content-Type元数据filename扩展名给出的类型一致),则将filename作为文件名返回。

  19. 如果claimed type已知,则更改filename以添加与claimed type对应的扩展名

    否则,如果named type已知为潜在危险(例如,平台约定将其视为本地可执行文件、shell脚本、HTML应用程序或可执行宏文档),则可选地更改filename以添加一个已知安全的扩展名(例如".txt")。

    最后一步可能使得无法下载可执行文件,这可能不是所期望的。正如往常一样,实现者必须在安全性和可用性之间做出平衡。

  20. filename作为文件名返回。

对于本算法的目的,文件扩展名指的是文件名中任何由平台约定用于识别文件类型的部分。例如,许多操作系统使用文件名中最后一个点(".")之后的部分来确定文件的类型,并从中决定文件的打开或执行方式。

用户代理在决定将生成的文件存储在用户文件系统中的位置时,应忽略资源本身、其URL和任何download属性提供的目录或路径信息。

如果由aarea元素创建的超链接具有ping属性,并且用户跟随该超链接,而元素的href属性的值可以相对于元素的节点文档进行解析,且解析不会失败,则用户代理必须获取ping属性的值,在ASCII空白处拆分该字符串,相对于元素的节点文档解析每个结果令牌,然后为每个结果URL ping URL运行这些步骤,忽略解析返回失败的情况:

  1. 如果ping URL方案不是HTTP(S) 方案,则返回。

  2. 可选地,返回。(例如,用户代理可能希望根据用户表达的偏好忽略任何或所有 ping URL。)

  3. settingsObject成为元素的节点文档相关设置对象

  4. request成为一个新的请求,其URLping URL方法是`POST`,头部列表是 « (`Content-Type`, `text/ping`) »,主体是`PING`,客户端settingsObject目标是空字符串,凭证模式是`include`,引用者是`no-referrer`,并且request使用URL凭证标志被设置,且发起者类型是`ping`。

  5. target URL成为对元素的href 属性的值,相对于元素的节点文档进行的编码-解析和序列化 URL的结果,然后:

    如果包含正在审核的超链接的Document对象的URLping URL具有相同的来源
    如果来源不同,但URL方案不是`https`
    request必须包含一个`Ping-From`头部,其值为包含超链接的文档的URL,以及一个`Ping-To` HTTP头部,其值为target URL
    否则
    request必须包含一个`Ping-To` HTTP头部,其值为target URLrequest不包含`Ping-From`头部。
  6. 获取 request

这可以与主要获取操作并行进行,并且与该获取操作的结果无关。

用户代理应允许用户调整此行为,例如与禁用发送HTTP `Referer`(如所写)头部的设置结合使用。根据用户的偏好,用户代理可以完全忽略 ping属性,或者有选择地忽略列表中的URL(例如,忽略任何第三方URL);这在上述步骤中已明确考虑。

用户代理必须忽略响应中返回的任何实体主体。用户代理可以在开始接收响应主体后提前关闭连接。

当存在ping属性时,用户代理应清楚地向用户指示,跟随该超链接还会在后台发送辅助请求,可能包括列出实际的目标URL。

例如,视觉用户代理可以在状态栏或工具提示中包含目标ping URL的主机名和超链接的实际URL。

ping 属性与现有技术如HTTP重定向和JavaScript在允许网页跟踪哪些外部链接最受欢迎或允许广告商跟踪点击率方面是冗余的。

然而,ping 属性为用户提供了相对于这些替代方案的以下优势:

因此,虽然可以在没有此功能的情况下跟踪用户,但鼓励作者使用ping 属性,以便用户代理可以使用户体验更透明。

4.6.6.1 `Ping-From` 和 `Ping-To` 头部

`Ping-From` 和 `Ping-To` HTTP 请求头部包含在超链接审计 请求中。它们的值是一个URL序列化的。

4.6.7 链接类型

链接类型

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

Link_types

下表总结了本规范定义的链接类型及其对应的关键词。此表为非规范性表格;实际的链接类型定义将在接下来的几节中给出。

在本节中,术语引用文档指的是由表示链接的元素标识的资源,而术语当前文档指的是表示链接的元素所在的资源。

要确定哪些链接类型适用于linkaareaform元素,必须对元素的rel属性进行ASCII 空格分割。生成的令牌即为适用于该元素的链接类型的关键词。

除非另有说明,否则每个rel属性中不得指定重复的关键词。

一些表格下方的部分会列出某些关键词的同义词。所指示的同义词应按用户代理指定的方式处理,但不得在文档中使用(例如,关键词"copyright")。

关键词总是ASCII 不区分大小写,并且必须按此方式进行比较。

因此,rel="next"rel="NEXT"是相同的。

被标记为body-ok的关键词会影响link元素是否可以出现在文档主体中body-ok关键词包括dns-prefetchmodulepreloadpingbackpreconnectprefetchpreloadstylesheet

需要由网页浏览器实现的新链接类型将被添加到此标准中。其余类型可以注册为扩展

4.6.7.1 链接类型 "alternate"

备用样式表

仅在一个引擎中支持。

Firefox3+Safari?Chrome1–48
OperaYesEdgeNo
Edge (旧版)?Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

alternate 关键字可以与 linkaarea 元素一起使用。

这个关键字的含义取决于其他属性的值。

如果元素是 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+xmlapplication/atom+xml 一起使用

这个关键字创建了一个 超链接,引用了一个聚合源(虽然不一定与当前页面聚合完全相同的内容)。

为了进行源自动发现,用户代理应考虑文档中所有使用 link 元素且 alternate 关键字的元素,以及其 type 属性设置为 application/rss+xmlapplication/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 自动发现。

否则

该关键词创建一个引用当前文档的备用表示形式的超链接

引用文档的性质由hreflangtype属性给出。

如果alternate关键词与hreflang属性一起使用,并且该属性的值与文档元素语言不同,则表示引用的文档是一个翻译版本。

如果alternate关键词与type属性一起使用,则表示引用的文档是当前文档在指定格式中的重新表述。

当使用alternate关键词时,hreflangtype属性可以组合使用。

以下示例展示了如何指定使用替代格式、面向其他语言和其他媒体的页面版本:

<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 关键字可以与 linkaarea 元素一起使用。这个关键字创建一个 超链接

对于 aarea 元素,author 关键字表示所引用的文档提供有关定义超链接的元素最近的 article 元素祖先的更多信息(如果有的话),否则提供有关整个页面的信息。

对于 link 元素,author 关键字表示所引用的文档提供有关整个页面的作者的更多信息。

"引用的文档" 可以是(并且通常是)一个 mailto: URL,提供作者的电子邮件地址。 [MAILTO]

同义词:出于历史原因,用户代理还必须将具有 rev 属性值为 "made" 的 linkaarea 元素视为具有 author 关键字指定的链接关系。

bookmark 关键字可以与 aarea 元素一起使用。这个关键字创建一个 超链接

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 关键字可以与 link 元素一起使用。这个关键字创建一个 超链接

canonical 关键字表示由 href 属性给出的 URL 是当前文档的首选 URL。 这有助于搜索引擎减少重复内容,详细描述见 The Canonical Link Relation[RFC6596]

Link_types/dns-prefetch

Firefox3+Safari?Chrome46+
Opera?Edge79+
Edge (旧版)NoInternet Explorer?
Firefox Android?Safari iOS?Chrome AndroidYesWebView Android46+Samsung Internet?Opera Android?

The dns-prefetch 关键字可以与 link 元素一起使用。此关键字创建一个外部资源链接。此关键字是body-ok

The dns-prefetch 关键字表示,预先为指定资源的执行DNS解析可能是有益的,因为用户很可能需要位于该的资源,预先解决DNS解析的延迟成本将改善用户体验。

对于 dns-prefetch 关键字,没有默认的资源类型。

适合获取和处理此类链接的时间是:

此类型链接资源的获取和处理步骤,给定一个link元素el,如下:

  1. url成为给定elhref属性值相对el节点文档编码解析URL的结果。

  2. 如果url解析失败,则返回。

  3. partitionKey成为给定el节点文档相关设置对象网络分区键的确定的结果。

  4. 用户代理应给定partitionKeyurl解析源

    由于此算法的结果可以被缓存,因此将来的获取可能会更快。

expect 关键字可用于link元素。此关键字创建一个内部资源链接

expect关键字创建的内部资源链接可以用来阻止渲染,直到它指示的元素连接到文档并完全解析。

expect关键字没有默认的资源类型。

link元素el发生以下任何情况时:

然后处理el

为了给定一个link元素el处理内部资源链接,执行以下步骤:

  1. doc成为el节点文档

  2. url成为给定elhref属性值的编码解析URL的结果,相对于doc

  3. 如果失败,或者url等于docURL,并且排除片段设置为false,则取消阻止渲染 el并返回。

  4. indicatedElement成为给定docurl选择指示部分的结果。

  5. 如果以下所有条件都为真:

    然后阻止渲染el

  6. 否则,取消阻止渲染el

为了给定一个文档doc处理内部资源链接

  1. 对于每个expectlink元素linkdoc渲染阻塞元素集中,处理link

以下属性更改步骤,给定elementlocalNamevaluenamespace,用于确保expectlink元素响应动态idname更改:

  1. 如果namespace不为null,则返回。

  2. 如果element位于一个打开元素栈HTML解析器中,则返回。

  3. 如果以下任一条件为真:

    然后处理内部资源链接给定element节点文档

external 关键字可用于aareaform元素。此关键字不会创建超链接,但会注释由该元素创建的任何其他超链接(如果没有其他关键字创建,则为隐含超链接)。

external 关键字表示该链接指向的文档不属于当前文档所在网站的一部分。

help 关键字可用于linkaareaform元素。此关键字创建一个超链接

对于aareaform元素,help关键字表示引用的文档为定义超链接的元素的父元素及其子元素提供进一步的帮助信息。

在以下示例中,表单控件具有相关的上下文帮助。例如,当用户按下“帮助”或“F1”键时,用户代理可以使用此信息显示引用的文档。

 <p><label> 主题: <input name=topic> <a href="help/topic.html" rel="help">(帮助)</a></label></p>

对于link元素,help关键字表示引用的文档为整个页面提供帮助。

对于aarea元素,在某些浏览器中,help关键字会使链接使用不同的光标。

4.6.7.9 链接类型 "icon"

Link_types#icon

Support in all current engines.

Firefox2+Safari3.1+Chrome4+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android4+Safari iOSNoChrome Android18+WebView Android38+Samsung Internet4.0+Opera AndroidNo
caniuse.com table

icon 关键字可用于link元素。此关键字创建一个外部资源链接

指定的资源是代表页面或网站的图标,应该由用户代理在用户界面中代表页面时使用。

图标可以是听觉图标、视觉图标或其他类型的图标。如果提供了多个图标,用户代理必须根据typemediasizes属性选择最合适的图标。如果有多个同样合适的图标,用户代理必须使用在用户代理收集图标列表时树顺序中最后声明的图标。如果用户代理尝试使用一个图标但在进一步检查时发现该图标实际上不合适(例如,因为它使用了不支持的格式),那么用户代理必须尝试下一个根据属性确定的最合适的图标。

用户代理不要求在图标列表更改时更新图标,但鼓励这样做。

icon关键字没有默认的资源类型。然而,为了确定资源类型,用户代理必须期望资源是图像。

sizes关键字表示图标的原始像素大小(相对于CSS 像素)。

一个宽度为50 CSS 像素的图标,适用于每个CSS 像素具有两个设备像素(2x,192dpi)的显示器,其宽度为100原始像素。此功能不支持指示在小高分辨率图标与大低分辨率图标之间使用不同的资源(例如50×50 2x与100×100 1x)。

要解析和处理属性的值,用户代理必须首先在ASCII空白处拆分属性的值,然后必须解析每个结果关键字以确定它代表什么。

any关键字表示资源包含一个可缩放的图标,例如由SVG图像提供的图标。

其他关键字必须进一步解析如下,以确定它们代表什么:

sizes属性中指定的关键字不得表示实际不可用的图标大小。

对于给定的link元素el请求request,这种类型的链接资源的链接资源获取设置步骤为:

  1. 设置request目的地为"image"。

  2. 返回true。

这种类型的链接资源的处理链接头步骤不执行任何操作。

在没有带有linkicon关键字的情况下,对于HTTP(S)协议Document对象,用户代理可以改为并行运行以下步骤:

  1. request成为一个新的请求,其URL是通过将URL记录解析为"/favicon.ico"而获得的URL,相对于Document对象的URL客户端Document对象的相关设置对象目的地为"image",同步标志被设置,凭证模式为"include",并且使用URL凭证标志被设置。

  2. response获取request的结果。

  3. 使用response不安全响应作为图标,就像它是用icon关键字声明的一样。

以下代码片段显示了带有多个图标的应用程序顶部部分。

<!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 关键字可用于linkaareaform元素。此关键字创建一个超链接

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关键字。

Link_types/manifest

仅在一个引擎中支持。

Firefox?Safari?ChromeNo
Opera?EdgeNo
Edge (旧版)?Internet Explorer?
Firefox Android?Safari iOS?Chrome Android39+WebView Android?Samsung Internet?Opera Android?

manifest 关键字可以用于 link 元素。这个关键字创建一个 外部资源链接

manifest 关键字指示提供与当前文档相关的元数据的清单文件。

manifest 关键字指定的资源没有默认类型。

当Web应用程序未 安装 时,适当的时间来 获取和处理链接资源 类型的链接是当用户代理认为有必要时。例如,当用户选择 安装Web应用程序 时。

对于已 安装的Web应用程序,适当的时间来 获取和处理链接资源 类型的链接是:

在任何情况下,只有第一个 link 元素在 树顺序 中,其 rel 属性包含 manifest 标记,才能被使用。

用户代理不得为了这种链接类型 延迟加载事件

对于这种类型的链接资源,给定一个 link 元素 el请求 request链接资源获取设置步骤 是:

  1. navigable 成为 el节点文档节点可导航

  2. 如果 navigable 为空,则返回 false。

  3. 如果 navigable 不是 顶级可遍历,则返回 false。

  4. request发起者 设置为 "manifest"。

  5. request目标 设置为 "manifest"。

  6. request模式 设置为 "cors"。

  7. request凭据模式 设置为 elcrossorigin 内容属性的 CORS设置属性凭据模式

  8. 返回 true。

处理这种类型的链接资源 给定一个 link 元素 el、布尔值 success响应 response字节序列 bodyBytes

  1. 如果 responseContent-Type元数据 不是 JSON MIME类型,则将 success 设置为 false。

  2. 如果 success 为 true:

    1. document URL 成为 el节点文档URL

    2. manifest URL 成为 responseURL

    3. 处理清单 给定 document URLmanifest URLbodyBytes[MANIFEST]

对于这种类型的链接资源,处理链接头 步骤是无操作。

Link_types/modulepreload

Firefox115+Safari?Chrome66+
Opera?Edge79+
Edge (旧版)NoInternet Explorer?
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

modulepreload 关键字可以用于 link 元素。这个关键字创建一个 外部资源链接。这个关键字是 body-ok

modulepreload 关键字是 preload 关键字的专业替代,具有针对预加载 模块脚本 的处理模型。特别是,它使用特定的模块脚本获取行为(包括,例如,对 crossorigin 属性的不同解释),并将结果放入适当的 模块映射 中以便稍后评估。相比之下,使用 preload 关键字的类似 外部资源链接 会将结果放入预加载缓存中,而不会影响文档的 模块映射

此外,实现可以利用 模块脚本 声明其依赖关系的事实来预先获取指定模块的依赖关系。这被视为一种优化机会,因为用户代理知道,很可能稍后也需要这些依赖关系。通常情况下,除非使用诸如service workers之类的技术或在服务器端进行监控,否则不会察觉。值得注意的是,适当的 loaderror 事件将在指定模块被获取后发生,不会等待任何依赖关系。

用户代理不得为了这种链接类型 延迟加载事件

适当的时间来 获取和处理链接资源 类型的链接是:

与其他一些链接关系不同,更改这些 ascrossoriginreferrerpolicy 相关属性不会触发新获取。这是因为文档的 模块映射 已经被之前的获取填充,因此重新获取毫无意义。

获取和处理链接资源 算法用于 modulepreload 链接,给定一个 link 元素 el,其步骤如下:

  1. 如果 elhref 属性的值为空字符串,则返回。

  2. destination 成为 elas 属性的当前状态(一个 目标),或者如果它没有状态,则为 "script"。

  3. 如果 destination 不是 类似脚本的,则在 排队一个元素任务 上,在给定 el网络任务源触发一个事件 名为 errorel 上,并返回。

  4. url 成为 编码解析一个URL 的结果,给定 elhref 属性的值,相对于 el节点文档

  5. 如果 url 失败,则返回。

  6. settings object 成为 el节点文档相关设置对象

  7. credentials mode 成为 elcrossorigin 属性的 CORS设置属性凭据模式

  8. cryptographic nonce 成为 el.[[CryptographicNonce]]

  9. integrity metadata 成为 elintegrity 属性的值,如果指定的话,否则为空字符串。

  10. 如果 el 没有 integrity 属性,则将 integrity metadata 设置为 解析模块完整性元数据 的结果,给定 urlsettings object

  11. referrer policy 成为 elreferrerpolicy 属性的当前状态。

  12. fetch priority 成为 elfetchpriority 属性的当前状态。

  13. options 成为 脚本获取选项,其 密码随机数cryptographic nonce完整性元数据integrity metadata解析器元数据 为 "not-parser-inserted",凭据模式credentials mode引用策略referrer policy获取优先级fetch priority

  14. 获取一个modulepreload模块脚本图,给定 urldestinationsettings objectoptions,并使用以下步骤,给定 result

    1. 如果 result 为 null,则 触发一个事件 名为 errorel 上,并返回。

    2. 触发一个事件 名为 loadel 上。

对于这种类型的链接资源,处理链接头 步骤是无操作。

以下代码段显示了具有多个模块预加载的应用程序的顶部部分:

<!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">
...

假设应用程序的模块图如下所示:

The module graph is rooted at app.mjs, which depends on irc.mjs and fog-machine.mjs. In turn, irc.mjs depends on helpers.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 关键字可以用于 aareaform 元素。这个关键字不会创建一个 超链接,而是 注释 任何其他由元素创建的超链接(如果没有其他关键字创建超链接,则为隐含的超链接)。

nofollow 关键字表示链接不被页面的原始作者或出版者认可,或者链接到引用的文档主要是由于两个页面的相关人员之间的商业关系而包含的。

Link_types/noopener

所有当前引擎均支持。

Firefox52+Safari10.1+Chrome49+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Link_types/noopener

所有当前引擎均支持。

Firefox52+Safari10.1+Chrome49+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

noopener 关键字可以用于 aareaform 元素。这个关键字不会创建一个 超链接,而是 注释 任何其他由元素创建的超链接(如果没有其他关键字创建超链接,则为隐含的超链接)。

这个关键字表示,通过遵循 超链接 生成的任何新创建的 顶级可遍历 不会包含 辅助浏览上下文。例如,结果 Windowopener 获取器将返回 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>

Link_types/noreferrer

所有当前引擎均支持。

Firefox33+Safari5+Chrome16+
Opera?Edge79+
Edge (旧版)13+Internet Explorer🔰 11
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet1.5+Opera Android?

Link_types/noreferrer

所有当前引擎均支持。

Firefox33+Safari5+Chrome16+
Opera?Edge79+
Edge (旧版)13+Internet Explorer🔰 11
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet1.5+Opera Android?

noreferrer 关键字可以用于 aareaform 元素。这个关键字不会创建一个 超链接,而是 注释 任何其他由元素创建的超链接(如果没有其他关键字创建超链接,则为隐含的超链接)。

它表示在跟随链接时不会泄露任何引用信息,并且还暗示在相同条件下 noopener 关键字的行为。

另见直接操作引用的 处理模型

<a href="..." rel="noreferrer" target="_blank"><a href="..." rel="noreferrer noopener" target="_blank"> 具有相同的行为。

opener 关键字可以用于 aareaform 元素。这个关键字不会创建一个 超链接,而是 注释 任何其他由元素创建的超链接(如果没有其他关键字创建超链接,则为隐含的超链接)。

这个关键字表示,通过遵循 超链接 生成的任何新创建的 顶级可遍历 将包含一个 辅助浏览上下文

另见 处理模型

在以下示例中,opener 用于允许帮助页面弹出窗口导航其打开者,例如,当用户正在寻找的内容可以在其他地方找到时。一种替代方法可能是使用命名目标,而不是 _blank,但这可能会与现有名称冲突。

<a href="..." rel=opener target=_blank>Help!</a>

pingback 关键字可以用于 link 元素。这个关键字创建一个 外部资源链接。这个关键字是 body-ok

关于 pingback 关键字的语义,请参见 Pingback 1.0[PINGBACK]

Link_types/preconnect

所有当前引擎均支持。

Firefox39+Safari11.1+Chrome46+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet4.0+Opera Android?

preconnect 关键字可以用于 link 元素。这个关键字创建一个 外部资源链接。这个关键字是 body-ok

preconnect 关键字表示预先与指定资源的 建立连接可能是有利的,因为用户很可能需要位于该 的资源,通过预先解决与建立连接相关的延迟成本可以改善用户体验。

没有资源类型的默认类型由 preconnect 关键字指定。

用户代理不得因这种链接类型 延迟加载事件

合适的 获取和处理 此类链接的时机是:

获取和处理此类型链接资源 的步骤,给定一个 link 元素 el,是 el 创建链接选项 并给定结果进行 预连接

对于这种类型的链接资源,给定 链接处理选项 options处理链接头 步骤是给定 options 进行 预连接

给定 链接处理选项 options 进行 预连接

  1. 如果 optionshref 为空字符串,则返回。

  2. 给定 optionshrefoptions基本URL,进行 编码-解析 URL 并得到 url

    将基本URL传递而不是文档或环境是由 issue #9715 追踪的。

  3. 如果 url 解析失败,则返回。

  4. 如果 url方案 不是 HTTP(S) 方案,则返回。

  5. 给定 options环境,确定网络分区键并得到 partitionKey

  6. 设定 useCredentials 为 true。

  7. 如果 optionscrossorigin匿名 并且 optionsoriginurlorigin 不同源,则设定 useCredentials 为 false。

  8. 用户代理应尝试给定 partitionKeyurloriginuseCredentials获取连接

    此连接已获取但未直接使用。它将保留在 连接池 中以供后续使用。

    用户代理应尽可能尝试启动预连接并执行完整的连接握手(HTTP 为 DNS+TCP,HTTPS 源为 DNS+TCP+TLS),但由于资源限制或其他原因,允许选择执行部分握手(HTTP 仅为 DNS,HTTPS 源为 DNS 或 DNS+TCP),或完全跳过。

    每个源的最佳连接数取决于协商协议、用户当前的连接配置文件、可用设备资源、全局连接限制和其他特定上下文变量。因此,多少连接应打开的决定由用户代理决定。

Link_types/prefetch

Firefox2+SafariNoChrome8+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet1.5+Opera Android?

prefetch 关键字可以用于 link 元素。这个关键字创建一个 外部资源链接。这个关键字是 body-ok

prefetch 关键字表示预先 获取 和缓存指定的资源或同站点文档可能是有益的,因为用户很可能会在将来导航中需要此资源。

没有资源类型的默认类型由 prefetch 关键字指定。

合适的 获取和处理 此类链接的时机是:

获取和处理此类型链接资源 的算法,给定一个 link 元素 el,如下:

  1. 如果 elhref 属性的值为空字符串,则返回。

  2. options 设为 el 创建链接选项 的结果。

  3. 设定 optionsdestination 为空字符串。

  4. request 设为 创建一个链接请求 并给定 options 的结果。

  5. 如果 request 为 null,则返回。

  6. 设定 requestinitiator 为 "prefetch"。

  7. processPrefetchResponse 设为以下步骤,给定 响应 response 和 null、失败或 字节序列 bytesOrNull

    1. 如果 response网络错误触发一个 名为 error 的事件于 el

    2. 否则,触发一个 名为 load 的事件于 el

  8. 用户代理应 获取 request,并将 processResponseConsumeBody 设为 processPrefetchResponse。用户代理可以延迟获取 request 以优先处理当前文档所需的其他请求。

处理链接头 步骤对于这种类型的链接资源是无操作。

Link_types/preload

Support in one engine only.

Firefox85+Safari?🔰 50+
Opera37+🔰 79+
Edge (旧版)NoInternet Explorer?
Firefox Android?Safari iOS?Chrome Android?WebView Android50+Samsung Internet5.0+Opera Android?

preload 关键字可以用于 link 元素。这个关键字创建一个 外部资源链接。这个关键字是 body-ok

preload 关键字表示用户代理会根据 as 属性给出的 潜在目的地fetchpriority 属性给出的 优先级 预先 获取 和缓存指定的资源,因为用户很可能需要该资源用于当前导航。

用户代理在加载资源时可能会执行额外的操作,例如预先 解码图片创建样式表。但是,这些额外的操作不能有可观察的效果。

没有资源类型的默认类型由 preload 关键字指定。

用户代理不得为了这种链接类型 延迟加载事件

合适的 获取和处理 此类链接的时机是:

Document 有一个 预加载资源的映射,这是一个 有序映射,初始为空。

预加载键 是一个 结构体。它有以下

URL
一个 URL
目的地
一个字符串
模式
一个 请求模式,可以是 "same-origin"、"cors" 或 "no-cors"
凭证模式
一个 凭证模式

预加载条目 是一个 结构体。它有以下

完整性元数据
一个字符串
响应
空或一个 响应
响应可用时
空,或一个接受 响应 或空的算法

消费一个预加载的资源Window window,给定一个 URL url、一个字符串 destination、一个字符串 mode、一个字符串 credentialsMode、一个字符串 integrityMetadataonResponseAvailable,这是一个接受 响应 的算法:

  1. key 成为一个 预加载键,其 URLurl目的地destination模式mode凭证模式credentialsMode

  2. preloads 成为 window关联的 Document预加载资源的映射

  3. 如果 key存在preloads 中,则返回 false。

  4. entry 成为 preloads[key]。

  5. consumerIntegrityMetadata 成为 解析 integrityMetadata 的结果。

  6. preloadIntegrityMetadata 成为 解析 entry完整性元数据 的结果。

  7. 如果以下条件都不适用:

    则返回 false。

    预加载和消费者之间完整性元数据的差异,即使两者都匹配数据,也会导致从网络重新请求资源。

    将网络错误添加到预加载缓存中是很重要的,因此如果预加载请求导致错误,错误的响应不会在稍后从网络重新请求。这也有安全方面的影响;考虑一个开发人员在预加载请求上指定了子资源完整性元数据,但在随后的资源请求上没有。如果预加载请求未通过子资源完整性验证并被丢弃,资源请求将从网络获取并使用潜在的恶意响应,而不验证其完整性。[SRI]

  8. 移除 preloads[key]。

  9. 如果 entry响应 是空的,则设置 entry响应可用时onResponseAvailable

  10. 否则,用 entry响应 调用 onResponseAvailable

  11. 返回 true。

为此部分,字符串 type 若满足以下算法,则 匹配 字符串 destination

  1. 如果 type 是空字符串,则返回 true。

  2. 如果 destination 是 "fetch",则返回 true。

  3. mimeTypeRecord 成为 解析 type 的结果。

  4. 如果 mimeTypeRecord 是失败,则返回 false。

  5. 如果 mimeTypeRecord 不是 用户代理支持的,则返回 false。

  6. 如果以下任何一个为真:

    则返回 true。

  7. 返回 false。

要为一个 请求 request 创建一个预加载键,返回一个新的 预加载键,其 URLrequestURL目的地request目的地模式request模式,并且 凭证模式request凭证模式

要 给定一个字符串 destination 翻译预加载目的地

  1. 如果 destination 不是 "fetch"、"font"、"image"、"script"、"style" 或 "track",则返回 null。

  2. 返回 翻译 destination 的结果。

预加载 给定一个 链接处理选项 options 和一个可选的 processResponse,这是一个接受 响应 的算法:

  1. 如果 options类型匹配 options目的地,则返回。

  2. 如果 options目的地 是 "image" 并且 options源集 不是 null,则将 optionshref 设置为 选择一个图片源options源集

  3. request 成为 创建一个链接请求 给定 options 的结果。

  4. 如果 request 为 null,则返回。

  5. unsafeEndTime 为 0。

  6. entry 成为一个新的 预加载条目,其 完整性元数据options完整性

  7. key 成为 创建一个预加载键 给定 request 的结果。

  8. 如果 options文档 是 "pending",则将 request发起者类型 设置为 "early hint"。

  9. controller 为 null。

  10. reportTiming 给定一个 Document document报告计时document相关全局对象

  11. controller 设置为 获取 request 的结果,其中 processResponseConsumeBody 设置为以下步骤,给定一个 响应 response 和 null、失败或一个 字节序列 bodyBytes

    1. 如果 bodyBytes 是一个 字节序列,则将 response主体 设置为 bodyBytes 作为主体

      通过使用 processResponseConsumeBody,我们 提取了 整个 主体。这是为了确保预加载器从网络加载整个主体,无论预加载是否会被消费(在此时是不确定的)。此步骤然后将请求的主体重置为包含相同字节的新主体,以便其他规范可以在实际消费时读取它,尽管我们已经这样做了一次。

    2. 否则,将 response 设置为一个 网络错误

    3. unsafeEndTime 设置为 不安全共享当前时间

    4. 如果 options文档 不是 null,则调用 reportTiming 给定 options文档

    5. 如果entryon response available为null,则将entryresponse设置为response;否则,调用entryon response available并传入response

    6. 如果给定 processResponse,则调用 processResponse 使用 response

  12. commit 成为以下步骤,给定一个 Document document

    1. 如果 entry响应 不是 null,则调用 reportTiming 给定 document

    2. document预加载资源的映射[key] 设置为 entry

  13. 如果 options文档 是 null,则将 options文档就绪时 设置为 commit。否则,调用 commit 给定 options文档

获取和处理这种类型的链接资源的步骤,给定一个 link 元素 el,是:

  1. 更新 el源集

  2. options 成为 从元素创建链接选项 的结果。

  3. 预加载 options,以下步骤给定一个 响应 response

    1. 如果 response网络错误,则 触发事件,命名为 error,在 el 上。否则,在 el触发事件,命名为 load

      实际浏览器行为与规范在这里不同,改变行为的可行性尚未调查。见 问题 #1142

为这种链接类型 处理链接头 的步骤,给定一个 链接处理选项 options预加载 options

privacy-policy 关键字可用于 linkaarea 元素。该关键字创建一个 超链接

privacy-policy 关键字表示引用的文档包含关于适用于当前文档的数据收集和使用实践的信息,如 Additional Link Relation Types 中更详细描述的那样。引用的文档可以是独立的隐私政策,或者是某些更通用文档的特定部分。[RFC6903]

search 关键字可用于linkaareaform 元素。该关键字创建一个 超链接

search 关键字表示引用的文档提供了一个专门用于搜索该文档及其相关资源的接口。

OpenSearch 描述文档可与link 元素和search 链接类型一起使用,以使用户代理能够自动发现搜索接口。[OPENSEARCH]

stylesheet 关键字可用于link 元素。此关键字创建一个外部资源链接,它有助于样式处理模型。此关键字是body-ok

指定的资源是一个CSS 样式表, 它描述了如何呈现文档。

Alternative_style_sheets

仅支持一个引擎。

Firefox3+Safari?Chrome1–48
OperaYesEdgeNo
Edge (旧版)?Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

如果alternate 关键字也在link 元素上指定,那么该链接是一个替代样式表;在这种情况下, title 属性必须在link 元素上指定,且其值不能为空。

stylesheet 关键字的默认资源类型是text/css

此类型的link 元素如果是由其节点文档的解析器创建的, 则被认为是隐含地潜在渲染阻塞

当带有stylesheet 关键字的link 元素的disabled 属性被设置时,禁用 关联的CSS 样式表

此类链接获取和处理的适当时机是:

怪癖:如果文档已设置为怪癖模式, 具有与外部资源的相同来源, 且外部资源的内容类型元数据不是支持的样式表类型, 则用户代理必须将其视为text/css

此类链接资源的链接资源获取设置步骤,给定一个 link元素el请求request,如下:

  1. 如果eldisabled属性被设置,则返回false。

  2. 如果el贡献了一个脚本阻塞样式表,则追加el到其节点文档脚本阻塞样式表集合

  3. 如果elmedia属性的值 与环境匹配,且el潜在渲染阻塞的, 则在el阻塞渲染

  4. 如果el当前是渲染阻塞的, 则将request渲染阻塞设置为true。

  5. 返回true。

请参见issue #968,了解使用CSSOM 获取CSS样式表算法代替 默认获取和处理链接资源算法的计划。 与此同时,任何关键子资源请求应将其 渲染阻塞设置为link元素当前是否 渲染阻塞

处理此类型的链接资源, 给定一个link元素el, 布尔值success响应response, 和字节序列bodyBytes

  1. 如果资源的内容类型元数据不是text/css,则将success设置为false。

  2. 如果el不再创建一个贡献于样式处理模型的外部资源链接,或者自从该资源被获取以来,它变得适合再次获取,那么:

    1. el节点文档脚本阻塞样式表集合中移除el

    2. 返回。

  3. 如果el有一个关联的CSS样式表移除CSS样式表

  4. 如果success为true,那么:

    1. 创建一个CSS样式表,具有以下属性:

      类型

      text/css

      位置

      responseURL列表[0]

      我们在此提供一个URL,假设w3c/csswg-drafts issue #9316将会被修复。

      所有者节点

      el

      媒体

      elmedia属性。

      这是对(此时可能不存在的)属性的引用,而不是该属性当前值的副本。CSSOM定义了当属性动态设置、更改或删除时会发生什么。

      标题

      如果el在文档树中,则为eltitle属性;否则为空字符串。

      同样,这是对属性的引用,而不是该属性当前值的副本。

      备用标志

      如果链接是一个备用样式表,并且el明确启用为false,则设置此标志;否则不设置。

      来源清洁标志

      如果资源是CORS同源,则设置;否则不设置。

      父CSS样式表
      所有者CSS规则

      null

      禁用标志

      保持默认值。

      CSS规则

      未初始化。

      这似乎不对。大概我们应该使用bodyBytes? 跟踪于issue #2997

      CSS环境编码的结果是运行以下步骤的结果:[CSSSYNTAX]

      1. 如果el有一个charset属性,从该属性的值中获取编码。如果成功,返回结果编码。[ENCODING]

      2. 否则,返回文档的字符编码[DOM]

    2. el上触发名为load的事件。

  5. 否则,el上触发名为error的事件。

  6. 如果el贡献了一个脚本阻塞样式表,则:

    1. 断言el节点文档脚本阻塞样式表集合包含el

    2. 从其节点文档脚本阻塞样式表集合中移除el

  7. 解除el的渲染阻塞。

此类链接资源的处理链接头步骤是不做任何事情。

tag 关键字可以与aarea元素一起使用。这个关键字创建一个超链接

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关键字可以与linkaarea元素一起使用。这个关键字创建一个超链接

terms-of-service关键字表示引用的文档包含关于当前文档提供者与希望使用当前文档的用户之间的协议的信息,如Additional Link Relation Types中更详细描述的那样。[RFC6903]

某些文档是文档序列的一部分。

文档序列是指每个文档可以有一个前一个兄弟文档和一个下一个兄弟文档。没有前一个兄弟文档的文档是其序列的起点,没有下一个兄弟文档的文档是其序列的终点。

一个文档可以属于多个序列。

next关键字可以与linkaareaform元素一起使用。这个关键字创建一个超链接

next关键字表示文档是一个序列的一部分,并且链接指向序列中下一个逻辑文档。

next关键字与link元素一起使用时,用户代理应该处理这些链接,就像它们使用dns-prefetchpreconnectprefetch关键字一样。用户代理希望使用哪个关键字取决于实现;例如,用户代理可能希望在节省数据、电池电量或处理能力时使用成本较低的preconnect处理模型,或者可能希望根据对类似场景中过去用户行为的启发式分析来选择一个关键字。

prev关键字可以与linkaareaform元素一起使用。这个关键字创建一个超链接

prev关键字表示文档是一个序列的一部分,并且链接指向序列中上一个逻辑文档。

同义词:出于历史原因,用户代理还必须将关键字"previous"视为prev关键字。

预定义链接类型集的扩展 可以在 现有rel值的microformats页面上注册。[MFREL]

任何人都可以随时编辑 现有rel值的microformats页面 以添加类型。扩展类型必须指定以下信息:

关键字

实际定义的值。该值不应与任何其他定义的值混淆相似(例如,仅在大小写上有所不同)。

如果该值包含U+003A冒号字符(:),则它还必须是一个 绝对URL

对...的影响 link

以下之一:

不允许
不允许在 link 元素上指定关键字。
超链接
可以在 link 元素上指定关键字;它创建一个 超链接
外部资源
可以在 link 元素上指定关键字;它创建一个 外部资源链接
对...的影响 aarea

以下之一:

不允许
不允许在 aarea 元素上指定关键字。
超链接
可以在 aarea 元素上指定关键字;它创建一个 超链接
外部资源
可以在 aarea 元素上指定关键字;它创建一个 外部资源链接
超链接注释
可以在 aarea 元素上指定关键字;它 注释由元素创建的其他超链接
对...的影响 form

以下之一:

不允许
不允许在 form 元素上指定关键字。
超链接
可以在 form 元素上指定关键字;它创建一个 超链接
外部资源
可以在 form 元素上指定关键字;它创建一个 外部资源链接
超链接注释
可以在 form 元素上指定关键字;它 注释由元素创建的其他超链接
简要描述

关键字含义的简短非规范性描述。

规范

更详细描述关键字语义和要求的链接。它可以是wiki上的另一页,也可以是链接到外部页面。

同义词

具有完全相同处理要求的其他关键字值列表。作者不应使用定义为同义词的值,它们仅用于允许用户代理支持旧版内容。任何人都可以删除未实际使用的同义词;仅那些需要与旧版内容兼容处理的名称应以这种方式注册。

状态

以下之一:

建议
关键字尚未经过广泛的同行评审和批准。有人建议它,并且正在或即将使用它。
批准
关键字已经过广泛的同行评审和批准。它有一个规范,明确定义了如何处理使用该关键字的页面,包括当它们以不正确的方式使用时。
停止使用
关键字经过广泛的同行评审后被认为不符合要求。现有页面正在使用此关键字,但新页面应避免使用。简要描述和规范条目将详细说明作者应使用的替代内容(如果有)。

如果发现关键字与现 有值冗余,则应将其移除并列为现有值的同义词。

如果关键字在一个月或更长时间内未使用或未指定,则可以从注册表中删除。

如果添加的关键字处于建议状态并发现与现有值冗余,则应将其移除并列为现有值的同义词。如果添加的关键字处于建议状态并发现有害,则应将其状态更改为停止使用。

任何人都可以随时更改状态,但应仅根据上述定义进行。

合规检查器必须使用 现有rel值的microformats页面 上提供的信息来确定值是否被允许:本规范中定义的或标记为"建议"或"批准"的值在用于其描述的元素时必须被接受,而标记为"停止使用"或未在本规范或上述页面上列出的值必须被拒绝为无效。合规检查器可以缓存此信息(例如,为了性能原因或避免使用不可靠的网络连接)。

当作者使用本规范或wiki页面未定义的新类型时,合规检查器应提议将该值添加到wiki中,详情如上所述,状态为"建议"。

现有rel值的microformats页面 中以"建议"或"批准"状态定义的扩展类型,可以按照"对...的影响"字段所述的方式与 rel 属性一起用于 linkaarea 元素。[MFREL]

4.7 编辑

insdel 元素表示对文档的编辑。

4.7.1 ins 元素

Element/ins

所有当前引擎支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别
流内容
短语内容
可感知内容
该元素可以使用的上下文
短语内容预期的位置。
内容模型
透明
在 text/html 中省略标签
两个标签都不可省略。
内容属性
全局属性
cite — 链接到引用的来源或有关编辑的更多信息
datetime — 更改的日期和(可选)时间
无障碍考虑
对于作者
对于实现者
DOM 接口
使用 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>

4.7.2 del 元素

Element/del

所有当前引擎支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别
流内容
短语内容
可感知内容
该元素可以使用的上下文
短语内容预期的位置。
内容模型
透明
在 text/html 中省略标签
两个标签都不可省略。
内容属性
全局属性
cite — 链接到引用的来源或有关编辑的更多信息
datetime — 更改的日期和(可选)时间
无障碍考虑
对于作者
对于实现者
DOM 接口
使用 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>

4.7.3 insdel 元素的公共属性

cite 属性可用于指定解释更改的文档的 URL。当该文档很长时,例如会议记录,作者被鼓励包含一个 片段,指向该文档中特定讨论更改的部分。

如果存在 cite 属性,它必须是一个 有效的 URL(可能被空格包围),用于解释更改。为了获得相应的引用链接,必须相对于元素的 节点文档 解析该属性的值。用户代理可以允许用户跟随这些引用链接,但它们主要用于私有用途(例如,由服务器端脚本收集站点编辑的统计数据),而不是为读者准备的。

datetime 属性可用于指定更改的时间和日期。

如果存在,datetime 属性的值必须是 有效的日期字符串(可选时间)

用户代理必须根据 解析日期或时间字符串 算法解析 datetime 属性。如果该算法没有返回 日期全局日期和时间,那么修改没有相关联的时间戳(该值是不符合规范的;它不是 有效的日期字符串(可选时间))。否则,修改被标记为在给定的 日期全局日期和时间 进行的。如果给定的值是 全局日期和时间,那么用户代理应该使用相关的时区偏移信息来确定展示给定日期时间的时区。

这个值可以展示给用户,但它主要是为了私有用途。

insdel 元素必须实现 HTMLModElement 接口:

HTMLModElement

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
[Exposed=Window]
interface HTMLModElement : HTMLElement {
  [HTMLConstructor] constructor();

  [CEReactions] attribute USVString cite;
  [CEReactions] attribute DOMString dateTime;
};

cite IDL 属性必须 反映 元素的 cite 内容属性。dateTime IDL 属性必须 反映 元素的 datetime 内容属性。

4.7.4 编辑和段落

本节为非规范性内容。

由于 insdel 元素不影响 段落划分,在某些没有显式 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 元素中,甚至可以使一个段落的结尾、整个第二段和第三段的开始被同一个 insdel 元素覆盖(尽管这非常混乱,并不被认为是好的做法):

<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>

然而,由于 隐含段落 的定义方式,无法使用同一个 insdel 元素来标记一个段落的结尾和下一个段落的开始。你需要使用一个(或两个)p 元素和两个 insdel 元素,例如:

<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 &lt;del&gt; element.</p>
</section>

部分因为上述的混乱,强烈建议作者始终使用 p 元素来标记所有段落,而不是使用跨越 隐含段落 边界的 insdel 元素。

4.7.5 编辑和列表

本节为非规范性内容。

olul 元素的内容模型不允许 insdel 元素作为子元素。列表总是表示所有项目,包括那些本应标记为已删除的项目。

要指示某个项目已插入或删除,可以将 insdel 元素包裹在 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>

4.7.6 编辑和表格

本节为非规范性内容。

表格模型中的元素有复杂的内容模型要求,不允许 insdel 元素,因此指示对表格的编辑可能会很困难。

要指示整行或整列已被添加或删除,可以将该行或列中每个单元格的全部内容包裹在 insdel 元素中。

这里,一个表格的行被添加了:

<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>

一般来说,没有好的方法可以指示更复杂的编辑(例如,删除一个单元格,移动所有后续单元格向上或向左)。

4.8 嵌入内容

4.8.1 picture 元素

Element/picture

支持所有当前引擎。

Firefox38+Safari9.1+Chrome38+
Opera?Edge79+
Edge (旧版)13+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLPictureElement

支持所有当前引擎。

Firefox38+Safari9.1+Chrome38+
Opera?Edge79+
Edge (旧版)13+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
分类
流内容
短语内容
嵌入内容
可感知内容
该元素可以使用的上下文
期望嵌入内容的地方。
内容模型
零个或多个 source 元素,后跟一个 img 元素,可选地混合脚本支持元素。
在 text/html 中标签省略
两个标签都不能省略。
内容属性
全局属性
无障碍考虑
作者
实施者
DOM 接口
[Exposed=Window]
interface HTMLPictureElement : HTMLElement {
  [HTMLConstructor] constructor();
};

picture 元素是一个容器,提供多种来源给其包含的 img 元素,以便作者可以声明性地控制或给用户代理提供关于使用哪个图像资源的提示,基于屏幕像素密度、视口大小、图像格式等因素。它代表其子元素。

picture 元素与类似的 videoaudio 元素有些不同。虽然它们都包含 source 元素,但当元素嵌套在 picture 元素中时,src 属性没有意义,并且资源选择算法也不同。此外,picture 元素本身不显示任何内容;它仅为其包含的 img 元素提供上下文,使其能够从多个 URLs 中选择。

4.8.2 source 元素

Element/source

支持所有当前引擎。

Firefox3.5+Safari3.1+Chrome3+
Opera?Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLSourceElement

支持所有当前引擎。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge 79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
类别:
无。
此元素可以使用的上下文:
作为 picture 元素的子元素,在 img 元素之前。
作为 媒体元素的子元素,在任何 流内容track 元素之前。
内容模型:
在 text/html 中省略标签:
结束标签
内容属性:
全局属性
type — 嵌入资源的类型
media — 适用的媒体
src (在 audiovideo 中) — 资源地址
srcset (在 picture 中) — 在不同情况下使用的图像,例如高分辨率显示器,小显示器等。
sizes (在 picture 中) — 不同页面布局的图像大小
width (在 picture 中) — 水平尺寸
height (在 picture 中) — 垂直尺寸
可访问性注意事项:
作者
实现者
DOM 接口:
[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 元素可以使用 widthheight 属性来确定其渲染尺寸和纵横比,如渲染部分所定义

type 属性指定 source set 中图像的类型,以便用户代理在不支持给定类型时跳到下一个 source 元素。

如果 未指定 type 属性,当用户代理在获取后发现不支持图像格式时,它不会选择不同的 source 元素。

source 元素有一个后续的兄弟 source 元素或 img 元素,并且指定了 srcset 属性时,必须满足以下至少一个条件:

src 属性不得存在。

source 元素的父元素是 media 元素

src 属性提供 URL媒体资源。该值必须是 有效的非空 URL(可能被空格包围)。该属性必须存在。

type 属性指定 媒体资源 的类型,以帮助用户代理在获取之前确定是否可以播放此 媒体资源。某些 MIME 类型定义的 codecs 参数可能需要指定资源的确切编码方式。[RFC6381]

在已经插入到 videoaudio 元素中的情况下动态修改 source 元素的 srctype 属性将无效。要更改正在播放的内容,只需直接在 media 元素 上使用 src 属性,可能使用 canPlayType() 方法从可用资源中选择。通常,在文档解析后手动操作 source 元素是一种不必要的复杂方法。

以下列表显示了一些如何在 codecs= MIME 参数中使用 type 属性的示例。

H.264 约束基线档次视频(主和扩展视频兼容)级别 3 和低复杂度 AAC 音频在 MP4 容器中
<source src='video.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
H.264 扩展档次视频(基线兼容)级别 3 和低复杂度 AAC 音频在 MP4 容器中
<source src='video.mp4' type='video/mp4; codecs="avc1.58A01E, mp4a.40.2"'>
H.264 主档次视频级别 3 和低复杂度 AAC 音频在 MP4 容器中
<source src='video.mp4' type='video/mp4; codecs="avc1.4D401E, mp4a.40.2"'>
H.264 '高' 档次视频(与主、基线或扩展档次不兼容)级别 3 和低复杂度 AAC 音频在 MP4 容器中
<source src='video.mp4' type='video/mp4; codecs="avc1.64001E, mp4a.40.2"'>
MPEG-4 可视简单档次级别 0 视频和低复杂度 AAC 音频在 MP4 容器中
<source src='video.mp4' type='video/mp4; codecs="mp4v.20.8, mp4a.40.2"'>
MPEG-4 高级简单档次级别 0 视频和低复杂度 AAC 音频在 MP4 容器中
<source src='video.mp4' type='video/mp4; codecs="mp4v.20.240, mp4a.40.2"'>
MPEG-4 可视简单档次级别 0 视频和 AMR 音频在 3GPP 容器中
<source src='video.3gp' type='video/3gpp; codecs="mp4v.20.8, samr"'>
Theora 视频和 Vorbis 音频在 Ogg 容器中
<source src='video.ogv' type='video/ogg; codecs="theora, vorbis"'>
Theora 视频和 Speex 音频在 Ogg 容器中
<source src='video.ogv' type='video/ogg; codecs="theora, speex"'>
单独的 Vorbis 音频在 Ogg 容器中
<source src='audio.ogg' type='audio/ogg; codecs=vorbis'>
单独的 Speex 音频在 Ogg 容器中
<source src='audio.spx' type='audio/ogg; codecs=speex'>
单独的 FLAC 音频在 Ogg 容器中
<source src='audio.oga' type='audio/ogg; codecs=flac'>
Dirac 视频和 Vorbis 音频在 Ogg 容器中
<source src='video.ogv' type='video/ogg; codecs="dirac, vorbis"'>

srcsetsizes 属性不得存在。

source HTML 元素插入步骤,给定 insertedNode,如下:

  1. 如果 insertedNode 的父元素是没有 src 属性且 networkState 值为 NETWORK_EMPTYmedia 元素,则调用该 media 元素资源选择算法

  2. 如果 insertedNode 的下一个兄弟元素是 img 元素,且其父元素是 picture 元素,则将此计为该 img 元素的 相关变动

source HTML 元素移除步骤,给定 removedNodeoldParent,如下:

  1. 如果 removedNode 的下一个兄弟元素是 img 元素,且 oldParentpicture 元素,则将此计为该 img 元素的 相关变动

IDL 属性 srctypesrcsetsizesmedia 必须 反映相应名称的内容属性。

如果作者不确定用户代理是否都能渲染所提供的媒体资源,作者可以监听最后一个 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>

4.8.3 img 元素

Element/img

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLImageElement

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
分类:
流内容
短语内容
嵌入内容
表单相关元素
如果该元素有一个usemap属性: 交互内容
显著内容
此元素可以使用的上下文:
嵌入内容被期望的地方。
作为picture元素的子元素,在所有source元素之后。
内容模型:
无内容
在text/html中省略标签:
没有结束标签
内容属性:
全局属性
alt — 图像不可用时的替代文本
src — 资源地址
srcset — 不同情况下使用的图像,例如高分辨率显示器、小显示器等。
sizes — 不同页面布局的图像大小
crossorigin — 元素如何处理跨域请求
usemap — 要使用的图像映射的名称
ismap — 图像是否为服务器端图像映射
width — 水平尺寸
height — 垂直尺寸
referrerpolicy — 元素发起的referrer policyfetches
decoding — 处理此图像进行展示时使用的解码提示
loading — 用于确定加载延迟
fetchpriority — 为元素发起的请求优先级设置fetches
可访问性注意事项:
如果元素具有非空的alt属性: 给作者; 给实现者
否则: 给作者; 给实现者
DOM接口:
[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 元素有一个维度属性源,初始设置为元素本身。

HTMLImageElement/src

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

Element/img#attr-srcset

支持所有当前引擎。

Firefox38+Safari8+Chrome34+
Opera?Edge79+
Edge (旧版)≤18+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

srcsrcset属性以及任何先前兄弟source元素的srcset属性(如果父元素是picture元素)给出的图像是嵌入的内容;alt属性的值为那些无法处理图像或禁用图像加载的用户提供等效内容(即它是img元素的回退内容)。

alt属性值的要求在一个单独的章节中描述。

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属性也可以存在,并且是一个srcset属性

srcset属性和src属性(如果未使用宽度描述符)为图像来源提供了源集(如果未选择source元素)。

如果srcset属性存在且有任何使用宽度描述符图像候选字符串,则sizes属性也必须存在。如果未指定srcset属性,并且loading属性处于Lazy状态,则可以使用值“auto”指定sizes属性(ASCII大小写不敏感)。sizes属性是一个sizes属性,它为源集提供源尺寸(如果未选择source元素)。

img元素允许自动大小如果:

Attributes/crossorigin

支持所有当前引擎。

Firefox8+Safari6+Chrome13+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

crossorigin属性是一个CORS设置属性。其目的是允许具有跨源访问权限的第三方网站的图像与canvas一起使用。

referrerpolicy属性是一个引用策略属性。其目的是设置在引用策略时使用的获取图像。[REFERRERPOLICY]

decoding属性表示解码此图像的首选方法。如果存在,该属性必须是一个图像解码提示。此属性的缺省值无效值都是auto状态。

HTMLImageElement/fetchPriority

FirefoxNo🔰 preview+102+
Opera?Edge102+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

fetchpriority属性是一个获取优先级属性。其目的是设置在请求优先级时使用的获取图像。

loading属性是一个延迟加载属性。其目的是指示视口外图像的加载策略。

loading属性的状态更改为Eager状态时,用户代理必须执行以下步骤:

  1. resumptionStepsimg元素的延迟加载恢复步骤

  2. 如果resumptionSteps为null,则返回。

  3. img延迟加载恢复步骤设置为null。

  4. 调用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

该图像仅在滚动到视口中时加载,不会延迟窗口的加载事件。

建议开发者在延迟加载的图像上通过widthheight属性指定首选的纵横比,即使CSS设置了图像的宽度和高度属性,以防止页面布局在图像加载后发生变化。

给定insertedNodeimgHTML元素插入步骤如下:

  1. 如果insertedNode的父元素是picture元素,那么将其视为insertedNode相关突变

给定removedNodeoldParentimgHTML元素移除步骤如下:

  1. 如果oldParentpicture元素,那么将其视为removedNode相关突变


必须避免将img元素作为布局工具使用。特别是,img元素不应被用来显示透明图像,因为这些图像通常不会传达任何意义,也很少为文档增加有用的内容。


一个 img 元素表示的内容取决于 src 属性 和 alt 属性。

如果 src 属性已设置,而 alt 属性设置为空字符串

该图片可能是装饰性的或补充内容,和文档中的其他信息重复。

如果图片是 可用的 且用户代理被配置为显示该图片,则该元素 表示 元素的图片数据。

否则,该元素 表示 无内容,可能会完全从渲染中省略。用户代理可能会通知用户有图片存在但已被省略。

如果 src 属性已设置,而 alt 属性设置为非空值

该图片是内容的关键部分;alt 属性提供了图片的文本等效或替代。

如果图片是 可用的 且用户代理被配置为显示该图片,则该元素 表示 元素的图片数据。

否则,该元素 表示alt 属性给出的文本。用户代理可能会通知用户有图片存在但已被省略。

如果 src 属性已设置,而 alt 属性未设置

该图片可能是内容的关键部分,但没有可用的文本等效物。

在符合规范的文档中,缺少 alt 属性表示图片是内容的关键部分,但在生成图片时没有可用的文本替代。

如果图片是 可用的 且用户代理被配置为显示该图片,则该元素 表示 元素的图片数据。

如果图片有一个 src 属性,其值为空字符串,则该元素 表示 无内容。

否则,用户代理应显示某种指示,表明有一张图片未被渲染,并且如果用户请求,或用户代理配置为如此,或在响应导航时需要提供上下文信息,则提供图片的标题信息,按如下方式:

  1. 如果图片有一个 title 属性,其值非空字符串,则返回该属性的值。

  2. 如果图片是 figure 元素的后代,该元素有一个子 figcaption 元素,并且忽略 figcaption 元素及其后代,如果 figure 元素没有其他 流内容 后代,除了 元素间的空白img 元素,则返回第一个这样的 figcaption 元素的内容。

  3. 返回无内容。(没有标题信息。)

如果 src 属性未设置,而 alt 属性设置为空字符串或 alt 属性完全未设置

该元素 表示 无内容。

否则

该元素 表示 alt 属性给出的文本。

alt 属性不代表建议信息。 用户代理不得以与 alt 属性 内容相同的方式展示 title 属性的内容。

用户代理可以始终为用户提供显示任何图片或阻止显示任何图片的选项。用户代理也可以应用启发式方法来帮助用户在无法看到图片时利用图片,例如,由于视觉障碍或使用没有图形能力的文本终端。这些启发式方法可以包括,例如,对图片中找到的文本进行光学字符识别(OCR)。

虽然鼓励用户代理修复缺失的 alt 属性的情况,但作者不应依赖于这种行为。有关提供文本作为图片替代的 要求 详细描述如下。

img 元素的 img 元素的内容(如果有的话)在渲染时将被忽略。


usemap 属性(如果存在)可以指示该图片有一个相关的 图片地图

ismap 属性,当用于一个是 a 元素的 后代元素上,并且该 href 属性存在时,表示该元素提供访问服务器端图片地图的功能。这影响了在相应的 a 元素上的事件处理。

ismap 属性是一个 布尔属性。 该属性不得在没有具有 a 元素且该元素 上没有 href 属性的元素上指定。

使用 usemapismap 属性可能会导致在与 source 元素及在 media 属性指定的 picture 元素一起使用时,行为可能会令人困惑。

img 元素支持 尺寸属性

HTMLImageElement/alt

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLImageElement/srcset

在所有当前引擎中支持。

Firefox38+Safari8+Chrome34+
Opera?Edge79+
Edge(旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLImageElement/sizes

在所有当前引擎中支持。

Firefox38+Safari9.1+Chrome38+
Opera?Edge79+
Edge(旧版)13+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

altsrcsrcsetsizes IDL 属性必须 反映 相应的同名内容属性。

HTMLImageElement/crossOrigin

在所有当前引擎中支持。

Firefox8+Safari6+Chrome13+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

crossOrigin IDL 属性必须 反映 crossorigin 内容属性,限制为已知值

HTMLImageElement/useMap

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

useMap IDL 属性必须 反映 usemap 内容属性。

HTMLImageElement/isMap

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

isMap IDL 属性必须 反映 ismap 内容属性。

HTMLImageElement/referrerPolicy

在所有当前引擎中支持。

Firefox50+Safari14+Chrome52+
Opera?Edge79+
Edge(旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

referrerPolicy IDL 属性必须 反映 referrerpolicy 内容属性,限制为已知值

HTMLImageElement/decoding

在所有当前引擎中支持。

Firefox63+Safari11.1+Chrome65+
Opera?Edge79+
Edge(旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

SVGImageElement/decoding

Firefox63+SafariChrome65+
Opera?Edge79+
Edge(旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

decoding IDL 属性必须 反映 decoding 内容属性,限制为已知值

HTMLImageElement/loading

在所有当前引擎中支持。

Firefox75+Safari15.4+Chrome77+
Opera?Edge79+
Edge(旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

loading IDL 属性必须 反映 loading 内容属性,限制为已知值

fetchPriority IDL 属性 必须 反映 fetchpriority 内容属性,限制为已知值

image.width [ = value ]

HTMLImageElement/width

在所有当前引擎中都受支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
image.height [ = value ]

HTMLImageElement/height

在所有当前引擎中都受支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

这些属性返回图像的实际渲染尺寸,如果尺寸未知则返回 0。

可以设置这些属性,以改变相应的内容属性。

image.naturalWidth

HTMLImageElement/naturalWidth

在所有当前引擎中都受支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
image.naturalHeight

HTMLImageElement/naturalHeight

在所有当前引擎中都受支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

这些属性返回图像的自然尺寸,如果尺寸未知则返回 0。

image.complete

HTMLImageElement/complete

在所有当前引擎中都受支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

如果图像已经完全下载,或者没有指定图像,则返回 true;否则返回 false。

image.currentSrc

HTMLImageElement/currentSrc

在所有当前引擎中都受支持。

Firefox38+Safari9.1+Chrome38+
Opera?Edge79+
Edge (旧版)13+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回图像的 绝对 URL

image.decode()

HTMLImageElement/decode

在所有当前引擎中都受支持。

Firefox68+Safari11.1+Chrome64+
Opera?Edge79+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

SVGImageElement/decode

Firefox68+SafariChrome64+
Opera?Edge79+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

该方法使用户代理对图像进行 解码,以 并行 方式进行解码, 返回一个在解码完成时会被兑现的 Promise。

如果图像无法解码,Promise 将被拒绝,并返回一个 "EncodingError" DOMException

image = new Image([ width [, height ] ])

HTMLImageElement/Image

在所有当前引擎中都受支持。

Firefox1+Safari1+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

返回一个新的 img 元素,其 widthheight 属性设置为传入相关参数的值(如果适用)。

IDL 属性 widthheight 必须返回图像的实际渲染宽度和高度,单位为 CSS 像素,如果图像正在 渲染;否则返回图像的 密度修正的自然宽度和高度,单位为 CSS 像素,如果图像具有 密度修正的自然宽度和高度 并且是 可用 但未 渲染;否则返回 0,如果图像不可 可用 或没有 密度修正的自然宽度和高度[CSS]

在设置时,这些属性必须表现得像是反映了具有相同名称的内容属性。

IDL 属性 naturalWidthnaturalHeight 必须返回图像的 密度修正的自然宽度和高度,单位为 CSS 像素,如果图像具有 密度修正的自然宽度和高度 并且是 可用,否则返回 0。 [CSS]

由于图像的 密度修正的自然宽度和高度 会考虑其元数据中指定的任何方向,naturalWidthnaturalHeight 反映了在应用任何需要的旋转以正确定位图像后的尺寸,而不管 'image-orientation' 属性的值。

complete 获取步骤如下:

  1. 如果以下任意条件为真:

    则返回 true。

  2. 返回 false。

currentSrc IDL 属性必须返回 img 元素的 当前请求当前 URL

decode() 方法在被调用时,必须执行以下步骤:

  1. 创建一个新的 promise 对象,命名为 promise

  2. 将一个微任务排入队列,以执行以下步骤:

    这是因为更新图像数据也在微任务中进行。因此,为了使以下代码正常工作

    img.src = "stars.jpg";
    img.decode();

    正确解码stars.jpg,我们需要将任何处理延迟一个微任务。

    1. 如果以下任意条件为真:

      则用 "EncodingError" DOMException 拒绝 promise

    2. 否则,并行地 等待以下任意情况发生,并执行相应的操作:

      img 元素的 节点文档 停止 完全激活
      img 元素的 当前请求 更改或被修改
      img 元素的 当前请求状态 变为 损坏

      "EncodingError" DOMException 拒绝 promise

      img 元素的 当前请求状态 变为 完全可用

      解码 图像。

      如果不需要对图像进行解码(例如,因为它是矢量图形),则用 undefined 解析 promise

      如果解码失败(例如由于图像数据无效),则用 "EncodingError" DOMException 拒绝 promise

      如果解码过程成功完成,则用 undefined 解析 promise

      用户代理应确保解码后的媒体数据保持可用,至少直到下一个成功的 更新渲染 步骤结束。这是 API 合同的重要部分,应该尽可能不被破坏。(通常,只有在低内存情况下需要驱逐解码图像数据,或当图像过大以至于无法在此期间保持解码状态时,这种情况才会被违反。)

      动画图像只有在所有帧加载完毕后才会变为 完全可用。因此,即使实现可以在此之前解码第一帧,上述步骤也不会这样做,而是等待所有帧都可用。

  3. 返回 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)。当被调用时,遗留工厂函数必须执行以下步骤:

  1. document当前的全局对象关联 Document

  2. img 为在 document创建一个元素 的结果,指定元素为 img,命名空间为 HTML 命名空间

  3. 如果提供了 width,则使用 "width" 和 widthimg 设置属性值

  4. 如果提供了 height,则使用 "height" 和 heightimg 设置属性值

  5. 返回 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>

4.8.4 图像

4.8.4.1 介绍

本节为非规范性内容。

要在 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, ...

然而,有许多情况下,作者可能希望使用多个图像资源供用户代理选择:

上述情况并不是相互排斥的。例如,将不同的资源结合使用来应对不同的设备像素比和不同的艺术方向是合理的。

虽然可以通过脚本解决这些问题,但这样做会引入一些其他问题:

考虑到这些问题,本规范引入了一些功能,以声明性的方式解决上述问题。

基于设备像素比的选择,当图像的渲染大小是固定的

srcsrcset 属性可以用于 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 描述符指定的那样。

图像的渲染大小在 widthheight 属性中给出,这使得用户代理可以在图像下载之前为其分配空间。

基于视口的选择

srcsetsizes 属性可以使用 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%)。在 视口 宽度分别为 30em50em 时,会在这些布局之间切换。

<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 属性设置了在 30em50em 处的布局断点,并声明在这些断点之间的图像尺寸为 100vw50vwcalc(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: 300px; height: 300px }
@media (min-width: 32em) { img { width: 500px; height:300px } }
@media (min-width: 45em) { img { width: 700px; height:400px } }

此示例结合了艺术方向设备像素比 基于选择。提供一个占据视口一半的横幅,有两个版本,一个用于宽屏幕,一个用于窄屏幕。

<h1>
 <picture>
  <source media="(max-width: 500px)" srcset="banner-phone.jpeg, banner-phone-HD.jpeg 2x">
  <img src="banner.jpeg" srcset="banner-HD.jpeg 2x" alt="The Breakfast Combo">
 </picture>
</h1>
基于图像格式的选择

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 元素。

4.8.4.1.1 自适应图像

本节为非规范性内容。

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: 300px; height: 150px; }
 @media (max-width: 600px) { #a { width: 100px; height: 100px; } }
</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>

或者,可以使用 widthheight 属性来为旧版用户代理提供宽度和高度,仅使用 CSS 为支持 picture 的用户代理提供样式:

<style media="(max-width: 600px)">
 #a { width: 100px; height: 100px; }
</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>
4.8.4.2 sourceimglink 元素的共同属性
4.8.4.2.1 Srcset 属性

srcset 属性 是一个在本节中定义了要求的属性。

如果存在,其值必须由一个或多个 图像候选字符串 组成,每个字符串之间用 U+002C 逗号字符 (,) 分隔。如果一个 图像候选字符串 不包含描述符且 URL 后面没有 ASCII 空白字符,则下一个 图像候选字符串(如果有的话)必须以一个或多个 ASCII 空白字符 开头。

一个 图像候选字符串 由以下组件组成,按顺序排列,并有以下列表中描述的进一步限制:

  1. 零个或多个 ASCII 空白字符

  2. 一个 有效的非空 URL,不能以 U+002C 逗号字符 (,) 开头或结尾,引用一个非交互式的、可选动画的图像资源,该资源既不是分页的也不是脚本化的。

  3. 零个或多个 ASCII 空白字符

  4. 零个或一个以下项:

  5. 零个或多个 ASCII 空白字符

对于具有相同 宽度描述符值 的元素,不能有一个 图像候选字符串,其值与另一个 图像候选字符串宽度描述符值 相同。

对于具有相同 像素密度描述符值 的元素,不能有一个 图像候选字符串,其值与另一个 图像候选字符串像素密度描述符值 相同。为了满足此要求,没有描述符的 图像候选字符串 等同于具有 1x 描述符的 图像候选字符串

如果某个元素的 图像候选字符串 指定了 宽度描述符,那么该元素的所有其他 图像候选字符串 也必须指定 宽度描述符

图像候选字符串宽度描述符 中指定的宽度必须与由该 图像候选字符串 的 URL 提供的资源中的 自然宽度 匹配(如果该资源具有 自然宽度)。

如果某个元素具有 sizes 属性,那么该元素的所有 图像候选字符串 必须指定 宽度描述符

4.8.4.2.2 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

此外,强烈建议使用 widthheight 属性或使用 CSS 指定尺寸。如果未指定尺寸,图像可能会以 300x150 的尺寸呈现,因为 sizes="auto"渲染部分 中意味着 contain-intrinsic-size: 300px 150px

<source-size-value> 提供了图像的预期布局宽度。作者可以使用 <media-condition> 指定不同环境下的不同宽度。

<source-size-value> 中不允许使用百分比,以避免混淆其相对参照。可以使用 'vw' 单位来表示相对于 视口 宽度的尺寸。

4.8.4.3 处理模型

一个 img 元素有一个 当前请求 和一个 待处理请求当前请求 初始设置为一个新的 图像请求待处理请求 初始设置为 null。

一个 图像请求 有一个 状态、一个 当前 URL 和一个 图像数据

一个 图像请求状态 是以下之一:

不可用
用户代理尚未获取任何图像数据,或已获取部分或全部图像数据但尚未解码足够的图像以获取图像尺寸。
部分可用
用户代理已获取部分图像数据,并且至少图像尺寸是可用的。
完全可用
用户代理已获取所有图像数据,并且至少图像尺寸是可用的。
损坏
用户代理已获取所有它能获取的图像数据,但无法解码图像以获取图像尺寸(例如图像已损坏,或格式不受支持,或无法获取数据)。

一个 图像请求当前 URL 初始为空字符串。

一个 图像请求图像数据 是解码后的图像数据。

当一个 图像请求状态部分可用完全可用 时,该 图像请求 被称为 可用

当一个 img 元素的 当前请求状态完全可用 并且用户代理能够无错误地解码媒体数据,则该 img 元素被称为 完全可解码

一个 图像请求状态 初始为 不可用

当一个 img 元素的 当前请求可用 时,该 img 元素提供一个 绘图源,其宽度为图像的 密度校正自然宽度(如果有),高度为图像的 密度校正自然高度(如果有),外观为图像的自然外观。


一个 img 元素被称为 使用 srcsetpicture,如果它有一个指定的 srcset 属性,或者如果它的父元素是一个 picture 元素。


每个 img 元素都有一个 最后选择的源,其初始值必须为 null。

每个 图像请求 都有一个 当前像素密度,其初始值必须为 1。

每个 图像请求 都有 首选密度校正尺寸,它要么是包含宽度和高度的结构,要么为 null。初始值必须为 null。

要确定一个 img 元素 img密度校正自然宽度和高度

  1. dim 成为 img当前请求首选密度校正尺寸

    首选密度校正尺寸 是根据图像中的元信息在 准备图像以进行展示 算法中设置的。

  2. 如果 dim 为 null,将 dim 设置为 img自然尺寸

  3. dim 的宽度设置为 dim 的宽度除以 img当前请求当前像素密度

  4. dim 的高度设置为 dim 的高度除以 img当前请求当前像素密度

  5. 返回 dim

例如,如果 当前像素密度 为 3.125,这意味着每 CSS 英寸 有 300 个设备像素,因此如果图像数据为 300x600,则它具有 96 CSS 像素 乘 192 CSS 像素密度校正自然宽度和高度

所有 imglink 元素都与一个 源集 关联。

一个 源集 是一个有序的零个或多个 图像源 和一个 源大小

一个 图像源 是一个 URL,并且可以选择地包含一个 像素密度描述符 或一个 宽度描述符

一个 源大小 是一个 <source-size-value>。当一个 源大小 具有相对于 视口 的单位时,必须相对于 img 元素的 节点文档视口 进行解释。其他单位的解释与媒体查询中相同。[MQ]


本节中的算法的 解析错误 表示输入和要求之间的非致命性不匹配。鼓励用户代理以某种方式公开 解析错误


在确定图像的类型及其是否为有效图像时,图像是否成功获取(例如,响应状态是否为 成功状态)必须被忽略。

这允许服务器返回带有错误响应的图像,并使其显示出来。

用户代理应该应用 图像嗅探规则 来确定图像的类型,并且图像的 关联内容类型头 给出 official type。如果这些规则没有应用,那么图像的类型必须是图像的 关联内容类型头 给出的类型。

用户代理不得使用 img 元素支持非图像资源(例如,其 文档元素 为 HTML 元素的 XML 文件)。用户代理不得运行嵌入图像资源中的可执行代码(例如,脚本)。用户代理只能显示多页资源的第一页(例如,PDF 文件)。用户代理不得允许资源以交互方式工作,但应尊重资源中的任何动画。

本规范没有指定支持哪些图像类型。

4.8.4.3.1 何时获取图像

默认情况下,图像会立即获取。用户代理可以为用户提供按需获取图像的选项(例如,带宽受限的用户可能会使用此选项)。

在立即获取图像时,用户代理必须在每次创建元素或发生 相关变更 时,使用 重新启动动画 标志(如果这样规定)同步地 更新图像数据

在按需获取图像时,用户代理必须在需要图像数据时(即按需) 更新图像数据,但仅在 img 元素的 当前请求状态不可用 时进行。当 img 元素经历了 相关变更 时,如果用户代理仅按需获取图像,则 img 元素的 当前请求状态 必须返回到 不可用

4.8.4.3.2 对 DOM 变更的响应

一个 img 元素的 相关变更 如下:

4.8.4.3.3 可用图像列表

每个 Document 对象必须有一个 可用图像列表。列表中的每个图像由一个元组标识,该元组包括一个 绝对 URL、一个 CORS 设置属性 模式,以及(如果模式不是 无 CORS)一个 。 每个图像还有一个 忽略更高层缓存 标志。用户代理可以在任何时候将一个 Document 对象的 可用图像列表 复制到另一个对象(例如,当 Document 被创建时,用户代理可以将其他 Document 中加载的所有图像添加到此列表),但在这样做时不得更改复制条目的键,并且必须取消设置 忽略更高层缓存 标志。用户代理也可以在任何时候从这些列表中移除图像(例如,为了节省内存)。 用户代理必须根据资源的更高层缓存语义(例如 HTTP `Cache-Control` 响应头)适当地移除 可用图像列表 中的条目,当 忽略更高层缓存 标志未设置时。

可用图像列表 旨在支持在将 src 属性更改为先前已加载的 URL 时的同步切换,并避免在同一文档中重新下载图像,即使它们不允许 HTTP 缓存。它不用于避免在先前图像仍在加载时重新下载相同的图像。

用户代理还可以将图像数据单独存储在 可用图像列表 之外。

例如,如果一个资源具有 HTTP 响应头 `Cache-Control: must-revalidate`,并且其 忽略更高层缓存 标志未设置,用户代理会从 可用图像列表 中移除它,但可以单独保留图像数据,并在服务器响应 `304 Not Modified` 状态时使用该数据。

4.8.4.3.4 解码图像

图像数据通常会被编码以减少文件大小。这意味着为了让用户代理将图像呈现到屏幕上,需要对数据进行解码。 解码 是将图像的媒体数据转换为适合屏幕呈现的位图形式的过程。请注意,这一过程相对于其他内容呈现过程可能较慢。因此,用户代理可以选择何时执行解码,以创建最佳的用户体验。

图像解码被称为同步解码如果它在完成之前阻止了其他内容的呈现。通常,这会使图像和其他内容同时原子性地呈现。然而,这种呈现会被解码所需的时间延迟。

图像解码被称为异步解码如果它不会阻止其他内容的呈现。这会使非图像内容的呈现更快。然而,直到解码完成之前,图像内容在屏幕上是缺失的。一旦解码完成,屏幕将更新为图像。

在同步和异步解码模式下,最终内容呈现到屏幕上所经过的时间相同。主要的区别在于用户代理是否在呈现最终内容之前呈现非图像内容。

为了帮助用户代理决定是否执行同步或异步解码,可以在 decoding 属性上设置在 img 元素上。decoding 属性的可能值是以下 图像解码提示 关键字:

关键字 状态 描述
sync 同步 表示希望以同步方式 解码 图像,以便与其他内容原子性地呈现。
async 异步 表示希望以异步方式 解码 图像,以避免延迟其他内容的呈现。
auto 自动 表示对解码模式没有偏好(默认值)。

解码 图像时,用户代理应尊重 decoding 属性状态所指示的偏好。如果指示的状态是 自动,则用户代理可以自由选择任何解码行为。

也可以使用 decode() 方法来控制解码行为。由于 decode() 方法独立于负责内容呈现的过程进行 解码,因此不受 decoding 属性的影响。

4.8.4.3.5 更新图像数据

此算法不能在运行并行的步骤中调用。如果用户代理需要在运行并行的步骤中调用此算法,则需要排队一个任务来实现。

当用户代理需要更新图像数据img 元素时,可能设置重新启动动画标志,可能设置可能省略事件标志,必须执行以下步骤:

  1. 如果元素的节点文档不是完全激活,则:

    1. 继续并行运行此算法。

    2. 等待直到元素的节点文档完全激活。

    3. 如果此实例之后启动了此算法的另一个实例(即使它中止且不再运行),则返回。

    4. 排队一个微任务以继续此算法。

  2. 如果用户代理无法支持图像,或其图像支持已被禁用,则中止图像请求当前请求挂起请求,设置当前请求状态不可用,设置挂起请求为null,并返回。

  3. previous URL成为当前请求当前URL

  4. selected source为null,selected pixel density为未定义。

  5. 如果元素不使用srcsetpicture并且它具有指定值不是空字符串的src属性,则将selected source设置为元素的src属性的值,并将selected pixel density设置为1.0。

  6. 将元素的最后选择的源设置为selected source

  7. 如果selected source不为null,则:

    1. urlString成为编码-解析-序列化URL的结果,给定selected source,相对于元素的节点文档

    2. 如果urlString失败,则中止这组内部步骤。

    3. key成为一个包含urlStringimg元素的crossorigin属性的模式的元组,并且,如果该模式不是No CORS,则是节点文档来源

    4. 如果可用图像列表中包含key的条目,则:

      1. 为该条目设置忽略上层缓存标志。

      2. 中止图像请求,对于当前请求待定请求

      3. 待定请求设置为null。

      4. 当前请求为一个新的图像请求,其图像数据与条目一致,且其状态完全可用

      5. 给定img准备current request进行展示

      6. 当前请求当前像素密度设置为selected pixel density

      7. 在给定img元素的情况下,将一个元素任务加入队列DOM 操作任务源,包括以下步骤:

        1. 如果重新启动动画已设置,则重新启动动画

        2. 当前请求当前 URL设置为urlString

        3. 如果可能省略事件未设置或previousURL不等于urlString,则在img元素上触发名为load的事件。

      8. 中止更新图像数据算法。

  8. 排队一个微任务来执行该算法的其余部分,允许调用此算法的任务继续。

  9. 如果此实例之后启动了此算法的另一个实例(即使它中止且不再运行),则返回。

    只有最后一个实例生效,以避免在例如依次设置srcsrcsetcrossorigin属性时出现多个请求。

  10. selected sourceselected pixel density分别为选择图像源的结果的URL和像素密度。

  11. 如果selected source为null,则:

    1. 当前请求状态设置为损坏中止图像请求当前请求挂起请求,并将挂起请求设置为null。

    2. 排队一个元素任务DOM操作任务源上,给定img元素和以下步骤:

      1. 当前请求当前URL更改为空字符串。

      2. 如果以下所有条件均为真:

        • 元素有一个src属性,或它使用srcsetpicture;并且

        • 可能省略事件未设置或previousURL不为空字符串,

        则在img元素上触发一个事件,名称为error

    3. 返回。

  12. urlString成为编码-解析-序列化URL的结果,给定selected source,相对于元素的节点文档

  13. 如果urlString失败,则:

    1. 中止图像请求当前请求挂起请求

    2. 当前请求状态设置为损坏

    3. 设置挂起请求为null。

    4. 排队一个元素任务DOM操作任务源上,给定img元素和以下步骤:

      1. 当前请求当前URL更改为selected source

      2. 如果没有设置可能省略事件previousURL不等于selected source,则在img元素上触发一个事件,名称为error

    5. 返回。

  14. 如果挂起请求不为null,并且urlString挂起请求当前URL相同,则返回。

  15. 如果urlString当前请求当前URL相同,并且当前请求状态部分可用,则中止图像请求挂起请求排队一个元素任务DOM操作任务源上,给定img元素以重启动画(如果设置了重启动画),并返回。

  16. 中止图像请求挂起请求

  17. image request设置为一个新的图像请求,其当前URLurlString

  18. 如果当前请求状态不可用损坏,则将当前请求设置为image request。否则,将挂起请求设置为image request

  19. request成为创建潜在的CORS请求的结果,给定urlString、"image",以及元素的crossorigin内容属性的当前状态。

  20. request客户端设置为元素的节点文档相关设置对象

  21. 如果元素使用srcsetpicture,则将request发起者设置为"imageset"。

  22. request引用策略设置为元素的referrerpolicy属性的当前状态。

  23. request优先级设置为元素的fetchpriority属性的当前状态。

  24. 如果img懒加载属性处于Eager状态,或禁用脚本用于img,则让delay load event为true,否则为false。

  25. 如果给定img将懒加载元素步骤返回true,则:

    1. img懒加载恢复步骤设置为从标记为获取图像的步骤开始的此算法的其余部分。

    2. 开始观察懒加载元素的交叉点用于img元素。

    3. 返回。

  26. 获取图像获取request。从该算法返回,并作为获取的处理响应的一部分运行剩余步骤,响应response

    以这种方式获得的资源(如果有)是image request图像数据。它可以是CORS-相同来源CORS-跨来源;这会影响图像与其他API的交互(例如,在画布上使用时)。

    delay load event为true时,获取图像必须延迟元素的加载事件,直到排队的任务在资源被获取后网络任务源上运行为止(定义如下)。

    不幸的是,这可以用来对用户的本地网络执行一个简单的端口扫描(特别是在结合脚本时,尽管实际上不需要脚本来执行此攻击)。用户代理可能会实施比上述描述更严格的跨来源访问控制策略来减轻此攻击,但不幸的是,这些策略通常与现有的网络内容不兼容。

  27. 尽快跳转到以下列表中的第一个适用条目:

    如果资源类型是multipart/x-mixed-replace

    下一个在图像被获取时由网络任务源排队任务必须运行以下步骤:

    1. 如果image request挂起请求,并且至少一个体被完全解码,则中止图像请求当前请求,并将挂起请求升级为当前请求

    2. 否则,如果image request挂起请求,并且用户代理能够确定image request的图像在某种致命的方式中损坏,以至于无法获取图像尺寸,则中止图像请求当前请求将挂起请求升级为当前请求,并将当前请求状态设置为损坏

    3. 否则,如果image request当前请求,其状态不可用,并且用户代理能够确定image request的图像的宽度和高度,则将当前请求状态设置为部分可用

    4. 否则,如果image request当前请求,其状态不可用,并且用户代理能够确定image request的图像在某种致命的方式中损坏,以至于无法获取图像尺寸,则将当前请求状态设置为损坏

    当图像正在获取时,由网络任务源 排队的每个任务都必须更新图像的显示,但随着每个新的主体部分的到来,如果用户代理能够确定图像的宽度和高度,则必须根据img元素 准备img元素的当前请求以供展示并替换先前的图像。一旦一个主体部分完全解码,执行以下步骤:

    1. img元素的当前请求状态设置为完全可用

    2. 如果没有设置可能省略事件previousURL不等于urlString,则在img元素上排队一个元素任务DOM操作任务源上,给定img元素以触发一个事件,名称为load

    如果资源类型和数据对应于支持的图像格式,如下所述

    下一个在图像被获取时由网络任务源排队任务必须运行以下步骤:

    1. 如果用户代理能够确定image request的图像的宽度和高度,并且image request挂起请求,则将image request状态设置为部分可用

    2. 否则,如果用户代理能够确定image request的图像的宽度和高度,并且image request当前请求为展示准备image request给定img元素,并将image request状态设置为部分可用

    3. 否则,如果用户代理能够确定image request的图像在某种致命的方式中损坏,以至于无法获取图像尺寸,并且image request挂起请求

      1. 中止图像请求当前请求挂起请求

      2. 将挂起请求升级为当前请求

      3. 当前请求状态设置为损坏

      4. 触发一个事件,名称为errorimg元素上。

    4. 否则,如果用户代理能够确定image request的图像在某种致命的方式中损坏,以至于无法获取图像尺寸,并且image request当前请求

      1. 中止图像请求image request

      2. 如果没有设置可能省略事件previousURL不等于urlString,则在img元素上触发一个事件,名称为error

    那个任务,以及每个在图像被获取时由网络任务源排队的后续任务,如果image request当前请求,必须适当地更新图像的展示(例如,如果图像是渐进式JPEG,每个数据包可以提高图像的分辨率)。

    此外,一旦资源被获取,最后一个由网络任务源排队任务必须额外运行这些步骤:

    1. 如果image request挂起请求中止图像请求当前请求将挂起请求升级为当前请求,并为展示准备image request,给定img元素。

    2. image request设置为完全可用状态。

    3. 使用键key将图像添加到可用图像列表,设置忽略更高层缓存标志。

    4. 如果 maybe omit events 未设置或 previousURL 不等于 urlString,则在 img 元素上 触发一个 名为 load 的事件。

    否则

    图像数据不是支持的文件格式;用户代理必须将image request状态设置为损坏中止图像请求当前请求挂起请求将挂起请求升级为当前请求如果image request挂起请求,然后,如果没有设置可能省略事件previousURL不等于urlString排队一个元素任务DOM操作任务源上,给定img元素以触发一个事件,名称为error

当用户代理为元素x运行上述算法时,必须从元素的节点文档到元素x保持一个强引用,即使该元素未连接

中止图像请求对于一个图像请求或空的image request,意味着运行以下步骤:

  1. 如果image request为空,则返回。

  2. 忘记image request图像数据,如果有的话。

  3. 中止任何为image request进行的获取算法实例,丢弃该算法生成的任何挂起任务。

挂起请求升级为当前请求对于img元素意味着运行以下步骤:

  1. img元素的当前请求成为挂起请求

  2. img元素的挂起请求为null。

4.8.4.3.6 为展示准备图像

为展示准备图像,对于给定的图像元素imgreq图像请求:

  1. exifTagMap为从req图像数据中获得的EXIF标签,由相关编解码器定义。[EXIF]

  2. physicalWidthphysicalHeight为从req图像数据中获得的宽度和高度,由相关编解码器定义。

  3. dimXexifTagMap标签0xA002 (PixelXDimension)的值。

  4. dimYexifTagMap标签0xA003 (PixelYDimension)的值。

  5. resXexifTagMap标签0x011A (XResolution)的值。

  6. resYexifTagMap标签0x011B (YResolution)的值。

  7. resUnitexifTagMap标签0x0128 (ResolutionUnit)的值。

  8. 如果dimXdimY不是正整数,则返回。

  9. 如果resXresY不是正浮点数,则返回。

  10. 如果resUnit不等于2 (Inch),则返回。

  11. widthFromDensityphysicalWidth的值,乘以72并除以resX

  12. heightFromDensityphysicalHeight的值,乘以72并除以resY

  13. 如果widthFromDensity不等于dimXheightFromDensity不等于dimY,则返回。

  14. 如果req图像数据CORS跨域,则将img自然尺寸设置为dimXdimY,相应地缩放img的像素数据,并返回。

  15. req首选密度校正尺寸设置为一个结构,其宽度设置为dimX,高度设置为dimY

  16. 适当地更新reqimg元素的展示。

EXIF中的分辨率相当于每英寸CSS点,因此72是根据分辨率计算大小的基础。

尚未规定如果EXIF在图像已经展示后到达的情况。见问题#4929

4.8.4.3.7 选择图像源

选择图像源,给定一个img元素el

  1. 更新el的source set

  2. 如果elsource set为空,则返回null作为URL,并返回undefined作为像素密度。

  3. 返回从 el源集合选择图像的结果。

从source set中选择图像源,给定一个source setsourceSet

  1. 如果sourceSet中的条目b与之前的条目a具有相同的关联像素密度描述符,则删除条目b。重复此步骤,直到sourceSet中的所有条目都不再具有与之前条目相同的关联像素密度描述符

  2. 实现定义的方式,从sourceSet中选择一个图像源。将其命名为selectedSource

  3. 返回selectedSource及其关联的像素密度。

4.8.4.3.8 从属性创建source set

当被要求创建一个source set,给定字符串default source、字符串srcset、字符串sizes以及元素或null的img

  1. source set为一个空的source set

  2. 如果srcset不是空字符串,则将source set设置为解析srcset的结果。

  3. source size解析sizesimg的结果。

  4. 如果default source不是空字符串,并且source set不包含具有像素密度描述符值为1的图像源,并且没有具有宽度描述符图像源,则将default source附加到source set

  5. 规范化source set的源密度。

  6. 返回source set

4.8.4.3.9 更新source set

当被要求为给定的imglink元素el更新source set时,用户代理必须执行以下操作:

  1. elsource set设置为空的source set

  2. elements为« el »。

  3. 如果el是其父节点为picture元素的img元素,则替换elements的内容为el的父节点的子元素,保留相对顺序。

  4. 如果elimg元素,则令imgel,否则为null。

  5. 对于elements中的每个child

    1. 如果childel

      1. default source为空字符串。

      2. srcset为空字符串。

      3. sizes为空字符串。

      4. 如果el是具有srcset属性的img元素,则将srcset设置为该属性的值。

      5. 否则,如果el是具有imagesrcset属性的link元素,则将srcset设置为该属性的值。

      6. 如果el是具有sizes属性的img元素,则将sizes设置为该属性的值。

      7. 否则,如果el是具有imagesizes属性的link元素,则将sizes设置为该属性的值。

      8. 如果el是具有src属性的img元素,则将default source设置为该属性的值。

      9. 否则,如果el是具有href属性的link元素,则将default source设置为该属性的值。

      10. elsource set为给定default sourcesrcsetsizesimg创建的source set的结果。

      11. 返回。

        如果ellink元素,那么elements仅包含el,因此此步骤将立即达到,算法的其余部分将不会运行。

    2. 如果child不是source元素,则继续

    3. 如果child没有srcset属性,继续到下一个子元素。

    4. 解析child的srcset属性,并将返回的source set作为source set

    5. 如果source set没有图像源继续 到下一个子元素。

    6. 如果child具有media属性,并且其值不与环境匹配继续到下一个子元素。

    7. 解析child的sizes属性,并将source setsource size设置为返回的值。

    8. 如果child具有type属性,并且其值是未知或不支持的MIME类型继续到下一个子元素。

    9. 如果child具有widthheight属性,则将el尺寸属性源设置为child。否则,将el尺寸属性源设置为el

    10. 规范化source set的源密度。

    11. elsource set设置为source set

    12. 返回。

每个img元素单独考虑其前一个兄弟source元素加上img元素本身来选择图像源,忽略任何其他(无效的)元素,包括同一个picture元素中的其他img元素,或作为相关img元素的后续兄弟的source元素。

4.8.4.3.10 解析 srcset 属性

当被要求从元素解析srcset 属性时,解析元素的srcset 属性的值如下:

  1. input为传递给此算法的值。

  2. positioninput中的指针,初始指向字符串的开头。

  3. candidates为初始为空的source set

  4. 分割循环收集position给定的input中是ASCII空白字符或U+002C 逗号字符的代码点序列。如果收集到任何U+002C 逗号字符,这是一个解析错误

  5. 如果position已超过input的末尾,返回candidates

  6. 收集position给定的input中不是ASCII空白字符的代码点序列,并将其设为url

  7. descriptors为一个新的空列表。

  8. 如果url以U+002C (,)结尾,则:

    1. url中移除所有尾随的U+002C 逗号字符。如果移除了多个字符,这是一个解析错误

    否则:

    1. 描述符分词器跳过position给定的input中的ASCII空白字符。

    2. current descriptor为空字符串。

    3. state在描述符中

    4. cposition处的字符。根据state的值执行以下操作。对于此步骤的目的,“EOF”是一个特殊字符,表示position已超过input的末尾。

      在描述符中

      根据c的值执行以下操作:

      ASCII空白字符

      如果current descriptor不为空,将current descriptor追加到descriptors中,并将current descriptor设为空字符串。将state设为在描述符之后

      U+002C 逗号 (,)

      position推进到input中的下一个字符。如果current descriptor不为空,将current descriptor追加到descriptors中。跳到标记为描述符解析器的步骤。

      U+0028 左括号 (()

      c追加到current descriptor中。将state设为在括号中

      EOF

      如果current descriptor不为空,将current descriptor追加到descriptors中。跳到标记为描述符解析器的步骤。

      其他任何值

      c追加到current descriptor中。

      在括号中

      根据c的值执行以下操作:

      U+0029 右括号 ())

      c追加到current descriptor中。将state设为在描述符中

      EOF

      current descriptor追加到descriptors中。跳到标记为描述符解析器的步骤。

      其他任何值

      c追加到current descriptor中。

      在描述符之后

      根据c的值执行以下操作:

      ASCII空白字符

      保持在此状态。

      EOF

      跳到标记为描述符解析器的步骤。

      其他任何值

      state设为在描述符中。将position设为input中的前一个字符。

      position推进到input中的下一个字符。重复此步骤。

      为了与将来的添加兼容,此算法支持多个描述符和带括号的描述符。

  9. 描述符解析器:令error

  10. width不存在

  11. density不存在

  12. future-compat-h不存在

  13. 对于descriptors中的每个描述符,执行以下列表中的相应步骤:

    如果描述符由一个有效的非负整数组成,后跟一个U+0077 拉丁小写字母W
    1. 如果用户代理不支持sizes属性,令error

      符合规范的用户代理将支持sizes属性。然而,用户代理通常在实际中以增量方式实现和发布功能。

    2. 如果widthdensity都不是不存在,则令error

    3. 应用解析非负整数的规则到描述符。如果结果为0,令error。否则,令width为结果。

    如果描述符由一个有效的浮点数组成,后跟一个U+0078 拉丁小写字母X
    1. 如果widthdensityfuture-compat-h都不是不存在,则令error

    2. 应用解析浮点数值的规则到描述符。如果结果小于0,令error。否则,令density为结果。

      如果density为0,则自然尺寸将是无限的。预计用户代理在图像渲染大小方面有其限制

    如果描述符由一个有效的非负整数组成,后跟一个U+0068 拉丁小写字母H

    这是一个解析错误

    1. 如果future-compat-hdensity都不是不存在,则令error

    2. 应用解析非负整数的规则到描述符。如果结果为0,令error。否则,令future-compat-h为结果。

    其他任何情况

    error

  14. 如果future-compat-h不是不存在width不存在,令error

  15. 如果error仍然是,则向candidates追加一个新的图像源,其URL为url,宽度为width(如果不是不存在),像素密度为density(如果不是不存在)。否则,这是一个解析错误

  16. 返回到标记为分割循环的步骤。

4.8.4.3.11 解析 sizes 属性

当被要求从一个元素element解析sizes 属性,并且有一个img元素或null img时:

  1. unparsed sizes list解析elementsizes 属性的值(或空字符串,如果属性不存在)后的结果。[CSSSYNTAX]

  2. size为null。

  3. 对于unparsed sizes list中的每个unparsed size

    1. unparsed size的末尾移除所有连续的<whitespace-token>。如果unparsed size现在为空,则这是一个解析错误继续

    2. 如果unparsed size中的最后一个组件值是一个有效的非负<source-size-value>,则将size设为其值并从unparsed size中移除该组件值。除数学函数外的任何CSS函数都是无效的。否则,这是一个解析错误继续

    3. 如果sizeauto,并且img不是null,并且img正在渲染,并且img允许自动尺寸,则将size设为img具体对象尺寸宽度,以CSS像素为单位。

      如果size仍然是auto,则它将被忽略。

    4. unparsed size的末尾移除所有连续的<whitespace-token>。如果unparsed size现在为空:

      1. 如果这不是unparsed sizes list中的最后一项,则这是一个解析错误

      2. 如果size不是auto,则返回size。否则,继续。

    5. unparsed size中的剩余组件值解析为<media-condition>。如果它未正确解析,或者它正确解析但<media-condition>的结果为false,继续。[MQ]

    6. 如果size不是auto,则返回size。否则,继续。

  4. 返回100vw

使用一个不带<media-condition>的裸<source-size-value>(作为一个<length>)作为一个不在列表末尾的<source-size-list>条目是无效的。然而,解析 算法允许它出现在<source-size-list>中的任何位置,并且如果列表中的前一个条目未被使用,则会立即接受它作为尺寸。这是为了支持将来的扩展,并防止简单的作者错误,例如最后的尾随逗号。一个裸的auto关键字被允许有其他条目跟在其后,以为遗留的用户代理提供回退。

4.8.4.3.12 规范化源密度

图像源可以有一个像素密度描述符、一个宽度描述符,或者伴随其URL没有任何描述符。规范化源集会给每个图像源一个像素密度描述符

当要求规范化源密度时,对于一个 源集合 source set,用户代理必须执行以下操作:

  1. source sizesource set源尺寸

  2. 对于source set中的每个图像源

    1. 如果图像源像素密度描述符继续到下一个图像源

    2. 否则,如果图像源宽度描述符,将宽度描述符替换为具有像素密度描述符值像素密度描述符,其值为宽度描述符值除以源尺寸,单位为x

      如果源尺寸为0,则密度将是无穷大,这会导致自然尺寸为0 x 0。

    3. 否则,给图像源一个1x像素密度描述符

4.8.4.3.13 应对环境变化

用户代理可以随时运行以下算法,以更新img元素的图像,以应对环境变化。(用户代理不需要运行此算法;例如,如果用户不再查看页面,用户代理可能会等到用户返回页面后再确定使用哪个图像,以防在此期间环境再次变化。)

用户代理特别鼓励在用户更改视口大小(例如,通过调整窗口大小或更改页面缩放),以及将img元素插入到文档中时运行此算法,以使密度校正后的自然宽度和高度匹配新的视口,并在涉及艺术指导时选择正确的图像。

  1. 等待稳定状态同步部分包括此算法的所有剩余步骤,直到算法声明同步部分结束为止。(同步部分的步骤标有⌛。)

  2. ⌛ 如果img元素没有使用srcsetpicture,其节点文档完全活动,具有资源类型为multipart/x-mixed-replace的图像数据,或挂起请求不为null,则返回。

  3. ⌛ 令selected sourceselected pixel density分别为选择图像源的URL和像素密度的结果。

  4. ⌛ 如果selected source为null,则返回。

  5. ⌛ 如果selected sourceselected pixel density与元素的最后选择的源当前像素密度相同,则返回。

  6. ⌛ 令urlString编码、解析和序列化URL的结果,给定selected source,相对于元素的节点文档

  7. ⌛ 如果urlString失败,则返回。

  8. ⌛ 令corsAttributeState为元素的crossorigin内容属性的状态。

  9. ⌛ 令originimg元素的节点文档

  10. ⌛ 令clientimg元素的节点文档相关设置对象

  11. ⌛ 令key为一个元组,包含urlStringcorsAttributeState,如果corsAttributeState不为无CORS,则包含origin

  12. ⌛ 令image request为一个新的图像请求,其当前URLurlString

  13. ⌛ 令元素的挂起请求image request

  14. 结束同步部分 并行继续其余步骤。

  15. 如果可用图像列表中包含key的条目,则将image request图像数据设置为该条目的图像数据。继续下一步。

    否则:

    1. request创建潜在的CORS请求的结果,给定urlString、"image"和corsAttributeState

    2. request客户端设置为client发起者设置为"imageset",并设置request同步标志

    3. request引用策略设置为元素的referrerpolicy属性的当前状态。

    4. request优先级设置为元素的fetchpriority属性的当前状态。

    5. response获取request的结果。

    6. 如果response不安全响应网络错误或如果图像格式不受支持(通过应用图像嗅探规则确定),或如果用户代理能够确定image request的图像以某种致命方式损坏,导致无法获取图像尺寸,或如果资源类型为multipart/x-mixed-replace,则将挂起请求设为null并中止这些步骤。

    7. 否则,response不安全响应image request图像数据。它可以是CORS-同源CORS-跨源;这会影响图像与其他API的交互(例如,在canvas上使用时)。

  16. 将元素任务排队DOM操作任务源,给定img元素和以下步骤:

    1. 如果img元素自此算法启动以来经历了相关突变,则将挂起请求设为null并中止这些步骤。

    2. img元素的最后选择的源设为selected source,将img元素的当前像素密度设为selected pixel density

    3. image request状态设为完全可用

    4. 使用key将图像添加到可用图像列表中,并设置忽略更高层缓存标志。

    5. 将挂起请求升级为当前请求

    6. 为展示准备image request给定img元素。

    7. 触发一个事件,名为load,在img元素上。

4.8.4.4 提供文字作为图像替代的要求
4.8.4.4.1 一般准则

除非另有规定,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>
4.8.4.4.3 带有替代图形表示的短语或段落:图表、图解、图形、地图、插图

有时,图形形式可以更清晰地表达某些内容,例如流程图、图解、图形或显示方向的简单地图。在这种情况下,可以使用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元素)。

4.8.4.4.4 带有替代图形表示的短语或标签:图标、标志

文档可以包含图标形式的信息。图标旨在帮助视觉浏览器用户一眼就能识别功能。

在某些情况下,图标是传达相同意义的文本标签的补充。在这些情况下,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>

此示例显示了替代文本应如何编写,以便如果图像不可用,使用文本时,文本能够无缝地融入周围的文本,就像图像从未存在过一样。

4.8.4.4.5 图形化呈现的文本

有时,图像仅由文本组成,图像的目的是传达文本本身,而不是突出用于呈现文本的实际排版效果。

在这种情况下,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!

如果字符可以达到相同的目的,则不应使用图像。只有当文本不能直接用文本表示时,例如由于装饰或没有适当的字符(如外字的情况),才应使用图像。

如果作者因为其默认系统字体不支持某个字符而想使用图像,那么网络字体比图像更好的解决方案。

4.8.4.4.6 周围文本的图形表示

在许多情况下,图像实际上只是补充,其存在只是加强了周围的文本。在这些情况下,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属性,或者使用figurefigcaption元素。在后一种情况下,图像实际上是带有替代图形表示的短语或段落,因此需要替代文本。

<!-- 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>
4.8.4.4.7 辅助图像

有时,图像对内容并非至关重要,但也不是纯装饰或完全与文本重复。在这些情况下,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>
4.8.4.4.8 纯装饰性图像,不添加任何信息

如果图像是装饰性的,但并不是特别针对页面的——例如作为整个网站设计方案的一部分——图像应该在网站的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>
4.8.4.4.11 内容的关键部分

在某些情况下,图片是内容的关键部分。例如,在一个照片画廊页面中,图片是页面的整个重点

如何为关键内容的图片提供替代文本取决于图片的来源。

一般情况

当可以提供详细的替代文本时,例如图片是杂志评论中的一系列截图的一部分,或是漫画条的一部分,或是关于该照片的博客文章中的照片,必须在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 属性可以省略,但还必须满足以下条件之一:

这种情况应保持在绝对最低限度。如果作者有可能提供真实的替代文本,那么省略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 属性的可接受理由。

4.8.4.4.12 不打算给用户显示的图像

一般来说,作者应避免将img元素用于显示图像以外的其他目的。

如果img元素用于显示图像以外的其他目的,例如作为页面浏览量统计的一部分,则alt属性必须为空字符串。

在这种情况下,widthheight属性应设置为零。

4.8.4.4.13 在电子邮件或私人文档中,打算给一个已知能查看图像的特定人

本节不适用于公开访问的文档,或其目标受众不一定为作者个人认识的人,例如网站上的文档、发送到公开邮件列表的电子邮件或软件文档。

当图像包含在针对特定且已知能够查看图像的个人的私人通信(例如HTML电子邮件)中时,alt属性可以省略。然而,即使在这种情况下,仍强烈建议作者包括替代文本(根据图像的类型,如上所述),以便在用户使用不支持图像的邮件客户端时,电子邮件仍然可以使用,或者在文档被转发给其他可能不易查看图像的用户时,文档仍然可用。

4.8.4.4.14 标记生成器的指导

标记生成器(如所见即所得的创作工具)应尽可能从用户那里获取替代文本。然而,认识到在许多情况下,这可能不可行。

对于作为链接唯一内容的图像,标记生成器应检查链接目标,以确定目标的标题或目标的URL,并使用以这种方式获得的信息作为替代文本。

对于有标题的图像,标记生成器应使用figurefigcaption元素,或title属性,来提供图像的标题。

作为最后的手段,实施者应将alt属性设置为空字符串,假设图像是纯粹的装饰性图像,不添加任何信息但仍特定于周围内容,或者完全省略alt属性,假设图像是内容的关键部分。

标记生成器可以在img元素上指定generator-unable-to-provide-required-alt属性,用于未能获取替代文本的情况,因此省略了alt属性。该属性的值必须为空字符串。包含这些属性的文档不符合规范,但合规检查器将默默忽略这一错误。

这旨在避免标记生成器因省略alt属性而被迫用更严重的错误(如提供虚假的替代文本)来替代,因为最先进的自动合规检查器无法区分虚假的替代文本和正确的替代文本。

标记生成器通常应避免使用图像本身的文件名作为替代文本。同样,标记生成器应避免从任何将同样可供呈现用户代理(例如,Web浏览器)使用的内容中生成替代文本。

这是因为一旦页面生成,它通常不会被更新,而随后读取页面的浏览器可以由用户更新,因此浏览器可能会比标记生成器在生成页面时具有更为最新和精确的启发式规则。

4.8.4.4.15 合规检查器的指导

合规检查器必须报告缺少alt属性为错误,除非符合以下列出的条件之一:

4.8.5 iframe 元素

Element/iframe

在所有当前引擎中支持。

Firefox1+Safari4+Chrome1+
Opera15+Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android14+

HTMLIFrameElement

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
类别:
流内容
短语内容
嵌入内容
交互内容
有感内容
可使用此元素的上下文:
当需要嵌入内容时。
内容模型:
在 text/html 中省略标签:
两个标签都不可省略。
内容属性:
全局属性
src — 资源地址
srcdoc — 在 iframe 中渲染的文档
name可导航内容的名称
sandbox — 嵌套内容的安全规则
allow — 应用于 iframe 内容的权限策略
allowfullscreen — 是否允许 iframe 内容使用 requestFullscreen()
width — 水平方向尺寸
height — 垂直方向尺寸
referrerpolicy — 元素发起的引用策略fetches
loading — 用于确定加载延迟
无障碍考虑:
针对作者
针对实现者
DOM 接口:
[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
};

iframe 元素 表示可导航内容

src 属性提供了该元素的 URL,该页面将被该元素的 可导航内容 包含。该属性(如果存在)必须是一个 有效的非空 URL,可能被空格包围。如果 itemprop 属性在一个 iframe 元素上指定,则 src 属性也必须被指定。

Element/iframe#attr-srcdoc

在所有当前引擎中支持。

Firefox25+Safari6+Chrome20+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android?

srcdoc 属性提供了该元素的 可导航内容 的页面内容。该属性的值用于 构建 一个 iframe srcdoc 文档,它是一个 文档,其 URL 匹配 about:srcdoc

srcdoc 属性(如果存在)必须使用 HTML 语法,由以下语法组件按给定顺序组成:

  1. 任意数量的注释ASCII 空白字符
  2. 可选的DOCTYPE
  3. 任意数量的注释ASCII 空白字符
  4. 文档元素,以html元素的形式。
  5. 任意数量的注释ASCII 空白字符

上述要求也适用于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=&quot;/gallery?mode=cover&amp;amp;page=1&quot;>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;amp;me on the next cover."></iframe>
 </article>

请注意引号必须被转义的方式(否则 srcdoc 属性会提前结束),以及在沙盒内容中提到的原始符号(例如在URL或文本中)必须双重转义的方式——一次是为了在最初解析 srcdoc 属性时保留符号,另一次是为了防止在解析沙盒内容时误解符号。

此外,请注意,由于 DOCTYPEiframe srcdoc 文档 中是可选的,而 htmlheadbody 元素有可选的开始和结束标签,并且 title 元素在 iframe srcdoc 文档 中也是可选的,所以 srcdoc 属性中的标记可以相对简洁,尽管它代表了整个文档,因为只需要在语法中字面上出现 body 元素的内容。其他元素仍然存在,但只是隐含地存在。

HTML 语法中,作者只需记住使用 U+0022 引号字符 (") 包裹属性内容,然后转义所有的 U+0026 符号 (&) 和 U+0022 引号 (") 字符,并指定 sandbox 属性,以确保内容安全嵌入。(记得在引号之前转义符号,以确保引号变成 &quot; 而不是 &amp;quot;。)

在 XML 中,U+003C 小于号字符 (<) 也需要转义。为了防止属性值规范化,一些 XML 的空白字符——特别是 U+0009 制表符 (tab)、U+000A 换行符 (LF) 和 U+000D 回车符 (CR)——也需要转义。[XML]

如果 src 属性和 srcdoc 属性同时指定,则 srcdoc 属性优先。这允许作者为不支持 srcdoc 属性的旧版用户代理提供一个后备的 URL


iframe HTML 元素插入步骤,给定 insertedNode,如下:

  1. 如果 insertedNodeshadow-including root浏览上下文 为 null,则返回。

  2. insertedNode 创建一个新的子可导航对象

  3. 如果 insertedNodesandbox 属性,则根据属性值和 insertedNodeiframe 沙盒标志集 解析沙盒指令

  4. 处理 insertedNodeiframe 属性,并将 initialInsertion 设置为 true。

iframe HTML 元素移除步骤,给定 removedNode,是 销毁子可导航对象,给定 removedNode

这在没有触发任何 unload 事件的情况下发生(该元素的 内容文档销毁,而不是卸载)。

虽然 iframe 元素在 影子树 中处理,如上所述,但其行为的其他几个方面在影子树方面没有明确规定。有关详细信息,请参见 issue #763

每当一个具有非空 可导航内容iframe 元素的 srcdoc 属性被设置、更改或移除时,用户代理必须 处理 iframe 属性

同样,每当一个具有非空 可导航内容 但没有指定 srcdoc 属性的 iframe 元素的 src 属性被设置、更改或移除时,用户代理必须 处理 iframe 属性

处理 iframe 的属性,对于元素 element,可选布尔值 initialInsertion (默认为 false):

  1. 如果 elementsrcdoc 属性已指定,则:

    1. elementcurrent navigation was lazy loaded 布尔值设为 false。

    2. 如果 will lazy load element steps 给定 element 返回 true,则:

      1. elementlazy load resumption steps 设置为从标记为 navigate to the srcdoc resource 的步骤开始的算法的其余部分。

      2. elementcurrent navigation was lazy loaded 布尔值设为 true。

      3. 启动对 element 的懒加载元素的交叉观察

      4. 返回。

    3. Navigate to the srcdoc resource导航 elementiframeframeabout:srcdoc,空字符串和 elementsrcdoc 属性的值。

      生成的 Document 必须被视为 一个 iframe srcdoc 文档

  2. 否则:

    1. url 成为给定 elementinitialInsertion 后运行共享属性处理步骤的结果。

    2. 如果 url 为 null,则返回。

    3. 如果 url 匹配 about:blankinitialInsertion 为 true,则:

      1. 运行iframe 加载事件步骤,给定 element

      2. 返回。

    4. referrerPolicy 成为 elementreferrerpolicy 内容属性的当前状态。

    5. elementcurrent navigation was lazy loaded 布尔值设为 false。

    6. 如果 will lazy load element steps 给定 element 返回 true,则:

      1. elementlazy load resumption steps 设置为从标记为 navigate 的步骤开始的算法的其余部分。

      2. elementcurrent navigation was lazy loaded 布尔值设为 true。

      3. 启动对 element 的懒加载元素的交叉观察

      4. 返回。

    7. Navigate导航 elementiframeframe,给定 urlreferrerPolicy

给定元素 element 和布尔值 initialInsertioniframeframe 元素的共享属性处理步骤如下:

  1. urlURL 记录 about:blank

  2. 如果 element 指定了 src 属性,并且其值不是空字符串,则:

    1. maybeURL编码解析 URL 的结果,给定该属性的值,相对于 element节点文档

    2. 如果 maybeURL 不是失败,则将 url 设置为 maybeURL

  3. 如果 element节点可导航包含的祖先可导航 包含一个 可导航,其 活动文档URL 等于 url,且 排除片段 设置为 true,则返回 null。

  4. 如果 url 匹配 about:blank,且 initialInsertion 为 true,则执行 URL 和历史记录更新步骤,给定 element可导航内容活动文档url

    如果 url 是类似 about:blank?foo 的内容,这是必要的。如果 url 只是纯粹的 about:blank,这将不做任何事情。

  5. 返回 url

导航到一个 iframeframe,给定一个 元素 element,一个 URL url,一个 引荐 策略 referrerPolicy,以及一个可选的字符串或 null srcdocString(默认为 null):

  1. historyHandling 为 "auto"。

  2. 如果 element内容可导航活动文档完全 加载,则将 historyHandling 设置为 "replace"。

  3. 如果 element 是一个 iframe, 则将 element待处理资源计时开始时间 设置为 当前高分辨率时间,考虑到 element节点文档相关全局对象

  4. 导航 element内容可导航url,使用 element节点 文档, 其中 historyHandling 设置为 historyHandlingreferrerPolicy 设置为 referrerPolicy,以及 documentResource 设置为 srcdocString

每个 文档 都有一个 iframe 加载中 标志和一个 静音 iframe 加载 标志。当一个 文档 被 创建时,这些标志必须被取消设置。

要运行 iframe 加载事件步骤,给定一个 iframe 元素 element

  1. 断言element内容可导航 不为 null。

  2. childDocumentelement内容可导航活动文档

  3. 如果 childDocument静音 iframe 加载 标志已设置,则 返回。

  4. 如果 element待处理资源计时开始时间 不为 null,则:

    1. globalelement节点 文档相关全局对象

    2. fallbackTimingInfo 为一个新的 获取计时信息开始时间element待处理资源计时开始时间 和其 响应 结束时间当前高分辨率时间 给定 global

    3. 标记资源计时 给定 fallbackTimingInfourl, "iframe", global,空字符串,一个新的 响应体信息,以及 0。

    4. element待处理资源计时开始时间 设置为 null。

  5. 设置 childDocumentiframe 加载中 标志。

  6. 触发一个事件 名为 loadelement

  7. 取消设置 childDocumentiframe 加载中 标志。

这与脚本一起使用时,可以用于探测本地网络 HTTP 服务器的 URL 空间。用户代理可能会实现比上述描述更严格的 跨源 访问控制策略以减轻此攻击,但不幸的是,这些策略通常与现有的网页内容不兼容。

如果某个元素类型 可能延迟加载事件,则对于该类型的每个元素 element,用户代理必须 延迟 element节点文档 的加载事件,如果 element内容可导航 非 null,并且以下任意条件为真:

如果在处理 load 事件期间, element内容可导航 再次被 导航,这将进一步 延迟加载事件

每个 iframe 元素有一个关联的 当前导航是惰性加载 布尔值,初始值为 false。它在 处理 iframe 属性 算法中设置和取消设置。

一个 iframe 元素,其 当前导航是惰性加载 布尔值为 false 可能延迟加载事件

每个 iframe 元素有一个关联的 null 或 DOMHighResTimeStamp 待处理资源计时开始时间, 初始值为 null。

如果在元素创建时,srcdoc 属性未设置,而 src 属性也未设置或已设置但其值无法被 解析,则元素的 内容可导航 将保持在 初始 about:blank 文档

如果用户 导航 离开此页面,iframe内容可导航活动 WindowProxy 对象将代理新的 Window 对象用于新的 文档 对象,但 src 属性不会改变。


name 属性(如果存在)必须是一个 有效的可导航目标名称。给定的值用于命名元素的 内容可导航,如果在创建时存在该属性。


Element/iframe#attr-sandbox

所有当前浏览器均支持。

Firefox17+Safari5+Chrome4+
Opera?Edge79+
Edge(旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

sandbox 属性在指定时,会对由 iframe 托管的任何内容启用一组额外的限制。其值必须是 无序的唯一空格分隔的标记集合,且这些标记是 ASCII 不区分大小写。允许的值包括:

当设置了该属性时,内容会被视为来自一个唯一的 不透明源,表单、脚本以及各种可能令人烦恼的 API 会被禁用,且链接被防止指向其他 可导航对象allow-same-origin 关键字使内容被视为来自其真实源,而不是强制其成为一个 不透明源allow-top-navigation 关键字允许内容 导航可遍历的可导航对象allow-top-navigation-by-user-activation 关键字行为类似,但只允许在浏览上下文的 活动窗口 具有 临时激活 时进行此类 导航allow-top-navigation-to-custom-protocols 重新启用对非 fetch 协议 的导航,允许 交给外部软件;而 allow-formsallow-modalsallow-orientation-lockallow-pointer-lockallow-popupsallow-presentationallow-scripts、 和 allow-popups-to-escape-sandbox 关键字分别重新启用表单、模态对话框、屏幕方向锁定、指针锁 API、弹出窗口、展示 API、脚本和未沙箱化的 辅助浏览上下文 的创建。allow-downloads 关键字允许内容执行下载。 [POINTERLOCK] [SCREENORIENTATION] [PRESENTATION]

allow-top-navigationallow-top-navigation-by-user-activation 关键字不能同时指定,因为这样做是多余的;在这种不符合规范的标记中,只有 allow-top-navigation 会有效。

类似地,如果指定了 allow-top-navigation-to-custom-protocols 关键字,则不能指定 allow-top-navigationallow-popups 关键字,因为这样做是多余的。

要在沙箱内容中允许 alert()confirm()prompt() 函数,必须同时指定 allow-modalsallow-same-origin 关键字,并且加载的 URL 需要与 同源,与 顶级源 相同。没有 allow-same-origin 关键字,内容总是被视为跨源的,跨源内容 无法显示简单对话框

当嵌入页面与包含 iframe 的页面具有 相同源 时,同时设置 allow-scriptsallow-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-originallow-forms 关键字,因为这是在 B 加载时 A 中的 content navigable 的状态。

一般来说,动态移除或更改 sandbox 属性是不明智的,因为这会使推测哪些内容将被允许变得相当困难。


allow 属性在指定时,决定了在 容器策略 用于 权限策略 初始化 Documentiframe内容可导航 时使用的策略。它的值必须是一个 序列化权限策略[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,请执行以下步骤:

  1. 如果 document浏览上下文 为 null,则返回 false。

  2. 如果 document 不是 完全活跃 的,则返回 false。

  3. 如果在 featuredocumentdocument 上运行 是否在文档中启用功能 的结果为 "Enabled",则返回 true。

  4. 返回 false。

由于它们仅影响 权限策略内容可导航活动文档allowallowfullscreen 属性仅在 内容可导航iframe导航 时才会生效。添加或删除这些属性对已经加载的文档没有影响。


iframe 元素支持 尺寸属性,用于嵌入内容具有特定尺寸的情况(例如广告单元具有明确的尺寸)。

iframe 元素永远不会有 回退内容,因为它将始终 创建一个新的子可导航,无论指定的初始内容是否成功使用。


referrerpolicy 属性是一个 引用来源政策属性。它的作用是设置在 处理 iframe 属性 时使用的 引用来源政策[REFERRERPOLICY]

loading 属性是一个 延迟加载属性。它的作用是指示对于视口之外的 iframe 元素的加载策略。

loading 属性的状态更改为 Eager 状态时,用户代理必须执行以下步骤:

  1. resumptionStepsiframe 元素的 延迟加载恢复步骤

  2. 如果 resumptionSteps 为 null,则返回。

  3. iframe延迟加载恢复步骤 设置为 null。

  4. 调用 resumptionSteps


iframe 元素的后代不代表任何内容。 (在不支持 iframe 元素的传统用户代理中,这些内容会被解析为可能作为回退内容的标记。)

HTML 解析器将 iframe 元素中的标记视为文本。


HTMLIFrameElement/src

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

IDL 属性 srcnamesandboxallow 必须 反映 相同名称的内容属性。

HTMLIFrameElement/srcdoc

支持所有当前的引擎。

Firefox25+Safari6+Chrome20+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

srcdoc 获取器步骤如下:

  1. attribute 为运行 通过命名空间和本地名称获取属性 的结果,参数为 null、srcdoc本地名称, 和 this

  2. 如果 attribute 为 null,则返回空字符串。

  3. 返回 attribute

srcdoc 设置器步骤如下:

  1. compliantString 为调用 获取受信任的类型符合字符串 算法的结果,参数为 TrustedHTMLthis相关全局对象、给定值、“HTMLIFrameElement srcdoc” 和 “script”。

  2. 设置属性值,参数为 thissrcdoc本地名称compliantString

受支持的标记 对于 sandboxDOMTokenList 是在 sandbox 属性中定义的允许值,并且用户代理支持的值。

allowFullscreen IDL 属性必须 反映 allowfullscreen 内容属性。

HTMLIFrameElement/referrerPolicy

所有当前引擎都支持。

Firefox50+Safari14+Chrome52+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

referrerPolicy IDL 属性必须 反映 referrerpolicy 内容 属性,仅限已知值

loading IDL 属性必须 反映 loading 内容属性,仅限已知值

HTMLIFrameElement/contentDocument

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

contentDocument 获取器的步骤是返回 内容文档

HTMLIFrameElement/contentWindow

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

contentWindow 获取器的步骤是返回 内容窗口

以下是一个使用iframe 来包含来自广告经纪人的广告的页面示例:

<iframe src="https://ads.example.com/?customerid=923513721&amp;format=banner"
        width="468" height="60"></iframe>

4.8.6 embed 元素

Element/embed

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLEmbedElement

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
分类:
流内容.
短语内容.
嵌入内容.
交互内容.
可感知内容.
此元素可用的上下文:
当需要 嵌入内容 时。
内容模型:
无内容.
在 text/html 中的标签省略:
结束标签.
内容属性:
全局属性
src — 资源的地址
type — 嵌入资源的类型
width — 水平尺寸
height — 垂直尺寸
任何其他无命名空间的属性(见正文)。
无障碍考虑:
对于作者.
对于实施者.
DOM 接口:
[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 如下:

  1. 如果另一个 任务 已排队运行 embed 元素设置步骤 给定 element,则返回。

  2. 如果 element 设置了 src 属性,则:

    1. url 成为 编码解析 URL 的结果,给定 elementsrc 属性的值,相对于 element节点文档

    2. 如果 url 失败,则返回。

    3. request 成为一个新的 请求,其 URLurl客户端element节点文档相关设置对象目的地 是 "embed",凭证模式 是 "include",模式 是 "navigate",启动类型 是 "embed",并且其 使用 URL 凭证标志 设置。

    4. 获取 request,设置 处理响应 的步骤,给定 响应 response:

      1. 如果另一个 任务 已排队运行 embed 元素设置步骤 给定 element,则返回。

      2. 如果 response 是一个 网络错误,则 触发一个事件 名为 loadelement 上,并返回。

      3. type 成为确定 内容类型 的结果,给定 elementresponse

      4. 切换 type:

        null
        1. 不显示插件element

        否则
        1. 如果 element可导航内容 为 null,则 element 创建一个新的子可导航内容

        2. 导航 element可导航内容responseURL,使用 element节点文档,设置 响应response,并设置 历史处理 为 "替换"。

          elementsrc 属性不会更新,即使 可导航内容 进一步导航到其他位置。

        3. element 现在 表示可导航内容

      获取资源必须 延迟加载事件 element节点文档

  3. 否则,不显示插件element

确定给定 embed 元素 element响应 response内容类型,运行以下步骤:

  1. 如果 element 设置了 type 属性,并且该属性的值是一个插件支持的类型,则返回 type 属性的值。

  2. 如果 response路径 组件与插件支持的模式匹配,则返回该插件可以处理的类型。

    例如,一个插件可能会说它可以处理路径组件以四个字符字符串 ".swf" 结尾的 URL。

  3. 如果 response 具有显式内容类型元数据,并且该值是插件支持的类型,则返回该值。

  4. 返回 null。

上面的算法有意允许 response 具有非 OK 状态。这允许服务器即使在错误响应中(例如,HTTP 500 内部服务器错误代码仍然可以包含插件数据)返回数据给插件。

不为 embed 元素 element 显示插件:

  1. 销毁一个子可导航内容 给定 element

  2. 显示一个指示没有找到插件的标识,作为 element 的内容。

  3. element 现在 表示 什么都没有。

embed 元素没有 回退内容;其后代将被忽略。

每当一个 embed 元素 潜在活动 变为非潜在活动时,为该元素实例化的任何插件必须被卸载。

embed 元素 可能会延迟加载事件

embed 元素支持 尺寸属性

IDL 属性 srctype 必须分别 反映 同名的内容属性。

4.8.7 object 元素

元素/object

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLObjectElement

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容.
短语内容.
嵌入内容.
列出的 表单关联元素.
可感知内容.
可以使用此元素的上下文:
期望 嵌入内容 的地方。
内容模型:
透明.
在 text/html 中省略标签:
标签均不可省略。
内容属性:
全局属性
data — 资源地址
type — 嵌入资源类型
name内容可导航 的名称
form — 将元素与 表单 元素关联
width — 水平尺寸
height — 垂直尺寸
无障碍考虑:
对于作者.
对于实现者.
DOM 接口 :
[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 元素的 DOM 操作任务源 上,运行以下步骤来重新确定 object 元素表示的内容。此任务 排队 或正在运行时,必须 延迟元素的加载事件 在其 节点文档 中。

  1. 如果用户表示希望显示此 object 元素的 后备内容 而不是元素的通常行为,那么跳转到下面标记为 后备 的步骤。

    例如,用户可以要求显示元素的 后备内容,因为该内容使用用户觉得更容易访问的格式。

  2. 如果元素有一个祖先 媒体元素,或有一个祖先 object 元素未显示其 后备内容,或者元素不在其 文档中,其 浏览上下文 为非空,或者元素的 节点文档 未完全活动,或者元素仍在 打开元素栈HTML 解析器XML 解析器 中,或者元素未 渲染,则跳转到下面标记为 后备 的步骤。

  3. 如果 data 属性存在且其值不为空字符串,则:

    1. 如果 type 属性存在且其值不是用户代理支持的类型,则用户代理可以跳过获取内容以检查其真实类型,直接跳转到下面标记为 后备 的步骤。

    2. url编码解析 URL 的结果,给定 data 属性的值,相对于元素的 节点文档

    3. 如果 url 失败,则 触发一个事件 名为 error 在元素上,然后跳转到下面标记为 后备 的步骤。

    4. request 为一个新的 请求,其 URLurl客户端 为元素的 节点文档相关设置对象目标 为 "object",凭证模式 为 "include",模式 为 "navigate",发起者类型 为 "object",并且其 使用 URL 凭证标志 被设置。

    5. 获取 request

      获取资源必须 延迟元素的加载事件 在其 节点文档 中,直到在资源被获取(在下文中定义)后由 网络任务源 排队的 任务 被执行。

    6. 如果资源尚不可用(例如,由于资源未在缓存中,因此需要通过网络请求来加载资源),则跳转到下面标记为 后备 的步骤。资源可逐步加载;用户代理可以选择在获得足够数据以开始处理资源时认为资源“可用”。

    7. 如果加载失败(例如,出现 HTTP 404 错误,DNS 错误),触发一个事件 名为 error 在元素上,然后跳转到下面标记为 后备 的步骤。

    8. 确定 resource type,如下所示:

      1. resource type 为未知。

      2. 如果用户代理配置为严格遵守此资源的 Content-Type 标头,并且资源有 关联的 Content-Type 元数据,则令 resource type 为在 资源的 Content-Type 元数据 中指定的类型,并跳转到下面标记为 处理程序 的步骤。

        这可能引入一个漏洞,其中站点试图嵌入使用特定类型的资源,但远程站点覆盖了它,并为用户代理提供了触发不同类型内容的资源,具有不同的安全特性。

      3. 运行以下列表中的适当步骤集:

        如果资源有 关联的 Content-Type 元数据
        1. binary 为假。

        2. 如果在 资源的 Content-Type 元数据 中指定的类型是 "text/plain",并且应用 文本或二进制资源判别规则 到资源的结果是资源不是 text/plain,则将 binary 设置为真。

        3. 如果在 资源的 Content-Type 元数据 中指定的类型是 "application/octet-stream",则将 binary 设置为真。

        4. 如果 binary 为假,则令 resource type 为在 资源的 Content-Type 元数据 中指定的类型,并跳转到下面标记为 处理程序 的步骤。

        5. 如果在 type 属性存在于 object 元素上,并且其值不是 application/octet-stream,则运行以下步骤:

          1. 如果属性的值是以 "image/" 开头的类型,而不是 XML MIME 类型,则令 resource type 为在 type 属性中指定的类型。

          2. 跳转到下面标记为 处理程序 的步骤。

        否则,如果资源没有 关联的 Content-Type 元数据
        1. 如果在 type 属性存在于 object 元素上,则令 tentative type 为在 type 属性中指定的类型。

          否则,令 tentative type资源的计算类型

        2. 如果 tentative type 不是 application/octet-stream,则令 resource typetentative type 并跳转到下面标记为 处理程序 的步骤。

      4. 如果应用 URL 解析器 算法到指定资源的 URL(在任何重定向之后)的结果为一个 URL 记录,其 路径 组件匹配 插件 支持的模式,则令 resource type 为该插件可以处理的类型。

        例如,插件可能会说它可以处理路径组件以四字符字符串 ".swf" 结尾的资源。

      此步骤可能会结束,或上面的子步骤之一直接跳到下一步,而 resource type 仍然未知。在这两种情况下,下一步将触发后备。

    9. 处理程序:根据以下第一个匹配的情况处理内容:

      如果 resource typeXML MIME 类型,或 resource type 不以 "image/" 开头

      如果 object 元素的 内容可导航 为 null,则 为元素创建一个新的子可导航内容

      response获取响应

      如果 responseURL匹配 about:blank,则使用元素的 节点文档导航 元素的 内容可导航responseURL历史处理 设置为 "替换"。

      data 属性不会更新如果 内容可导航 进一步 导航 到其他位置。

      object 元素 表示内容可导航

      如果 resource type 以 "image/" 开头,并且未禁用图像支持

      销毁一个子可导航内容 给定 object 元素。

      应用 图像嗅探规则 以确定图像的类型。

      object 元素 表示 指定的图像。

      如果图像无法渲染,例如因为它格式错误或格式不受支持,跳转到下面标记为 后备 的步骤。

      否则

      给定的 resource type 不受支持。跳转到下面标记为 后备 的步骤。

      如果上一步结束时 resource type 仍然未知,这就是触发的情况。

    10. 元素的内容不是 object 元素表示的一部分。

    11. 如果 object 元素不表示其 内容可导航,则在资源完全加载后,排队一个元素任务 在给定 object 元素的 DOM 操作任务源 上,触发一个事件 名为 load 在元素上。

      如果元素确实表示其 内容可导航,则在创建的 Document 完全加载后,将排队一个类似的任务。

    12. 返回。

  4. 后备object 元素 表示 元素的子元素。这是元素的 后备内容销毁一个子可导航内容 给定元素。

由于上述算法,object 元素的内容充当 后备内容,仅在引用的资源无法显示时使用(例如返回 404 错误)。这允许多个 object 元素嵌套在一起,针对具有不同能力的多个用户代理,用户代理选择它支持的第一个。

object 元素 可能延迟加载事件

form 属性用于显式关联 object 元素与其 表单所有者

object 元素支持 尺寸属性

HTMLObjectElement/data

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLObjectElement/type

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android? Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLObjectElement/name

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

IDL 属性 datatypename 各自必须 反映 同名的相应内容属性。

HTMLObjectElement/contentDocument

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

contentDocument getter 步骤是返回 this内容文档

HTMLObjectElement/contentWindow

所有当前引擎均支持。

Firefox22+Safari13+Chrome53+
Opera?Edge79+
Edge (旧版)17+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

contentWindow getter 步骤是返回 this内容窗口

willValidatevalidityvalidationMessage 属性,以及 checkValidity()reportValidity()setCustomValidity() 方法,是 约束验证 API 的一部分。form IDL 属性是元素的表单 API 的一部分。

在此示例中,使用 object 元素将 HTML 页面嵌入到另一个页面中。

<figure>
 <object data="clock.html"></object>
 <figcaption>My HTML Clock</figcaption>
</figure>

4.8.8 video 元素

Element/video

所有当前引擎均支持。

Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLVideoElement

所有当前引擎均支持。

Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+
Categories:
Flow content.
Phrasing content.
Embedded content.
如果元素具有 controls 属性:Interactive content.
Palpable content.
Contexts in which this element can be used:
在期望嵌入内容的地方。
Content model:
如果元素具有 src 属性:零个或多个 track 元素,然后是透明内容,但不能有媒体元素后代。
如果元素没有 src 属性:零个或多个 source 元素,然后是零个或多个 track 元素,然后是透明内容,但不能有媒体元素后代。
Tag omission in text/html:
标签都不可省略。
Content attributes:
全局属性
src — 资源地址
crossorigin — 处理跨域请求的方式
poster — 视频播放前显示的海报帧
preload — 提示需要缓冲多少媒体资源
autoplay — 页面加载时自动开始播放媒体资源
plays inline — 鼓励用户代理在元素的播放区域内显示视频内容
loop — 是否循环播放媒体资源
muted — 默认是否静音媒体资源
controls — 显示用户代理控件
width — 水平尺寸
height — 垂直尺寸
可访问性考虑:
针对作者.
针对实现者.
DOM 接口:
[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 元素是一个 媒体元素,其 媒体数据 显然是视频数据,可能还包括相关的音频数据。

srccrossoriginpreloadautoplayloopmuted,和 controls 属性是所有媒体元素的共同属性。

poster 属性提供一个图像文件的 URL,用户代理可以在没有视频数据时显示该图像。如果存在此属性,则必须包含一个 有效的非空 URL,可能被空格包围

如果指定的资源要被使用,那么,当元素被创建或 poster 属性被设置、更改或移除时,用户代理必须运行以下步骤来确定元素的 海报帧(无论元素的 显示海报标志 的值如何):

  1. 如果此算法的现有实例正在为此 video 元素运行,则中止该算法实例而不更改 海报帧

  2. 如果 poster 属性的值为空字符串或属性不存在,则没有 海报帧;返回。

  3. url 成为 编码解析 URL 的结果,给定 poster 属性的值,相对于元素的 节点文档

  4. 如果 url 失败,则返回。没有 海报帧

  5. request 成为一个新 请求,其 URLurl客户端 是元素的 节点文档相关设置对象目标 是 "image",启动者类型 是 "video",凭证模式 是 "include",并且 使用 URL 凭证标志 被设置。

  6. 抓取 request。这必须 延迟元素的加载事件节点文档

  7. 如果因此获得图像,则 海报帧 是该图像。否则,没有 海报帧

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

HTMLVideoElement/videoWidth

所有当前引擎均支持。

Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+
video.videoHeight

HTMLVideoElement/videoHeight

所有当前引擎均支持。

Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+

这些属性返回视频的自然尺寸,如果尺寸未知则返回0。

自然宽度自然高度媒体资源 在考虑了资源的尺寸、纵横比、净有效区、分辨率等之后的尺寸,如资源使用的格式定义的那样。如果一种非方格式没有定义如何将纵横比应用于视频数据的尺寸以获得“正确”的尺寸,那么用户代理必须通过增加一个尺寸并保持另一个不变来应用比率。

videoWidth IDL 属性必须返回 自然宽度 的视频以 CSS 像素 为单位。videoHeight IDL 属性必须返回视频的 自然高度,以 CSS 像素 为单位。如果元素的 readyState 属性为 HAVE_NOTHING,则这些属性必须返回 0。

每当 自然宽度自然高度 变化时(例如,因为选择了不同的视频轨道),如果元素的 readyState 属性不是 HAVE_NOTHING,用户代理必须 排队一个媒体元素任务媒体元素,以 触发一个名为 resize 的事件。

video 元素支持 尺寸属性

在没有相反的样式规则的情况下,视频 内容应在元素的播放区域内居中显示,以最大可能的尺寸完全适应播放区域,同时保持视频内容的纵横比。因此,如果播放区域的纵横比与视频的纵横比不匹配,视频将显示为信箱模式或柱箱模式。播放区域中不包含视频的区域不表示任何内容。

在实现 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>

4.8.9 audio 元素

Element/audio

支持所有当前引擎。

Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android3+Samsung Internet?Opera Android11+

HTMLAudioElement

支持所有当前引擎。

Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+
类别:
流内容
短语内容
嵌入内容
如果元素有一个controls属性:交互内容
如果元素有一个controls属性:可感知内容
使用此元素的上下文:
预期嵌入内容的地方。
内容模型:
如果元素有src属性:零个或多个track元素,然后透明,但没有媒体元素后代。
如果元素没有src属性:零个或多个source元素,然后零个或多个track元素,然后透明,但没有媒体元素后代。
在 text/html 中省略标签:
标签均不可省略。
内容属性:
全局属性
src — 资源地址
crossorigin — 元素如何处理跨域请求
preload — 提示媒体资源可能需要多少缓冲
autoplay — 提示媒体资源可以在页面加载时自动启动
loop — 是否循环媒体资源
muted — 是否默认静音媒体资源
controls — 显示用户代理控件
可访问性考虑:
给作者
给实现者
DOM 接口:
[Exposed=Window,
 LegacyFactoryFunction=Audio(optional DOMString src)]
interface HTMLAudioElement : HTMLMediaElement {
  [HTMLConstructor] constructor();
};

audio 元素表示声音或音频流。

内容可以放在audio元素中。用户代理不应向用户显示这些内容;它们是为不支持audio的旧版网页浏览器准备的,以便向这些旧版浏览器的用户显示如何访问音频内容的文本。

特别地,这些内容不是为了解决可访问性问题。为了使音频内容对聋人或有其他身体或认知障碍的人可访问,有多种功能可用。如果有字幕或手语视频,可以使用video元素代替audio元素播放音频,允许用户启用视觉替代。可以使用track元素和WebVTT 文件提供章节标题以帮助导航。自然,也可以通过简单地在audio元素附近的正文中链接到它们来提供转录或其他文本替代。[WEBVTT]

audio元素是一个媒体元素,其媒体数据大体上是音频数据。

srccrossoriginpreloadautoplayloopmutedcontrols 属性是所有媒体元素共有的属性

audio = new Audio([ url ])

HTMLAudioElement/Audio

支持所有当前引擎。

Firefox3.5+Safari3.1+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回一个新的audio元素,src 属性设置为传递的参数值(如果适用)。

为创建HTMLAudioElement对象提供了一个传统的工厂函数(除了 DOM 的工厂方法如createElement()外):Audio(src)。调用传统工厂函数时,必须执行以下步骤:

  1. document为当前全局对象的关联Document

  2. audio创建元素的结果,给定documentaudioHTML 命名空间

  3. 设置一个audio的属性值,使用“preload”和“auto”。

  4. 如果src被给定,则设置audio的一个属性值,使用“src”和src。(这将导致用户代理在返回之前调用对象的资源选择算法。)

  5. 返回audio

4.8.10 track 元素

Element/track

支持所有当前引擎。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android25+WebView Android?Samsung Internet?Opera Android12.1+

HTMLTrackElement

支持所有当前引擎。

Firefox31+Safari6+Chrome23+
Opera12+Edge79+
Edge(旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
类别:
无。
该元素可以使用的上下文:
作为 媒体元素的子元素,位于任何 流内容之前。
内容模型:
无内容
在 text/html 中省略标签:
结束标签
内容属性:
全局属性
kind — 文本轨道的类型
src — 资源的地址
srclang — 文本轨道的语言
label — 用户可见标签
default — 如果没有其他 文本轨道 更合适,则启用该轨道
可访问性考虑:
供作者使用
供实现者使用
DOM 接口:
[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 属性被设置时,执行以下步骤:

  1. trackURL 失败。

  2. value 为元素的 src 属性值。

  3. 如果 value 不是空字符串,则将 trackURL 设置为 编码、解析和序列化 URL 的结果,给定 value,相对于元素的 节点文档

  4. 如果 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.NONE (0)

文本轨道未加载状态。

track.LOADING (1)

文本轨道加载中状态。

track.LOADED (2)

文本轨道已加载状态。

track.ERROR (3)

文本轨道加载失败状态。

track.track

返回对应于 文本轨道TextTrack 对象。

readyState 属性必须返回对应于 文本轨道就绪状态的数值,如以下列表所定义:

NONE(数值 0)
文本轨道未加载状态。
LOADING(数值 1)
文本轨道加载中状态。
LOADED(数值 2)
文本轨道已加载状态。
ERROR(数值 3)
文本轨道加载失败状态。

track IDL 属性必须在获取时返回 文本轨道的相应 TextTrack 对象。

HTMLTrackElement/src

支持所有当前引擎。

Firefox31+Safari6+Chrome23+
Opera12+Edge79+
Edge(旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

srcsrclanglabeldefault 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 属性指定。)

4.8.11 媒体元素

HTMLMediaElement对象(在本规范中audiovideo)被简单地称为媒体元素

HTMLMediaElement

支持所有当前引擎。

Firefox3.5+Safari3.1+Chrome3+
Opera10.5+Edge79+
Edge(旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+
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 = "");
};

媒体元素属性srccrossoriginpreloadautoplayloopmutedcontrols适用于所有媒体元素。它们在本节中定义。

媒体元素用于向用户展示音频数据,或视频和音频数据。在本节中,这被称为媒体数据,因为本节同样适用于音频或视频的媒体元素

术语媒体资源用于指代完整的媒体数据集,例如完整的视频文件或完整的音频文件。

媒体资源有一个关联的来源,可以是"none"、"multiple"、"rewritten"或一个来源。最初设定为"none"。

媒体资源可以有多个音频和视频轨道。对于媒体元素媒体资源的视频数据仅为元素的videoTracks属性中当前选定的轨道(如果有)在事件循环最后一次到达步骤1时的数据,而媒体资源的音频数据则是元素的audioTracks属性中当前启用的所有轨道(如果有)在事件循环最后一次到达步骤1时混合后的结果。

audiovideo 元素都可以用于音频和视频。两者之间的主要区别是audio元素没有用于显示视觉内容(如视频或字幕)的播放区域,而video元素有。

每个媒体元素都有一个唯一的媒体元素事件任务源

排队媒体元素任务与一个媒体元素element和一系列步骤steps,请根据elementsteps媒体元素媒体元素事件任务源排队一个元素任务

4.8.11.1 错误代码

MediaError

支持所有当前的引擎。

Firefox4+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
media.error

HTMLMediaElement/error

支持所有当前的引擎。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回一个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

MediaError/code

支持所有当前的引擎。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回当前错误的错误代码,见下表。

media.error.message

MediaError/message

支持所有当前的引擎。

Firefox52+Safari15+Chrome59+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回有关遇到的错误情况的具体诊断信息。消息和消息格式在不同的用户代理之间通常并不统一。如果没有这样的消息可用,则返回空字符串。

每个MediaError对象都有一个消息,它是一个字符串,还有一个代码,它是以下之一:

MEDIA_ERR_ABORTED (数值1)
用户代理应用户请求中止了媒体资源的获取过程。
MEDIA_ERR_NETWORK (数值2)
某种类型的网络错误导致用户代理在资源已被确认为可用后停止获取媒体资源
MEDIA_ERR_DECODE (数值3)
在资源已被确认为可用后,解码媒体资源时发生了某种错误。
MEDIA_ERR_SRC_NOT_SUPPORTED (数值4)
src属性指示的媒体资源分配的媒体提供对象不适用。

创建一个MediaError,给定一个错误代码,它是上述值之一,返回一个新的MediaError对象,其代码是给定的错误代码,其消息是包含用户代理能够提供的关于错误情况原因的任何详细信息的字符串,如果用户代理无法提供这些详细信息,则为空字符串。此消息字符串不得仅包含通过提供的错误代码已经可用的信息;例如,它不得只是将代码翻译为字符串格式。如果没有比错误代码提供的更多的附加信息,则消息必须设置为空字符串。

code的获取步骤是返回this代码

message的获取步骤是返回this消息

4.8.11.2 媒体资源的位置

src内容属性在媒体元素上给出了要显示的媒体资源(视频、音频)的URL。如果存在,该属性必须包含一个有效的非空URL,可能被空格包围

如果在媒体元素上指定了itemprop属性,则必须同时指定src属性。

crossorigin内容属性在媒体元素上是一个CORS设置属性

如果创建一个带有src属性的媒体元素,用户代理必须立即调用媒体元素资源选择算法

如果设置或更改媒体元素src属性,用户代理必须调用媒体元素媒体元素加载算法。(移除src属性不会这样做,即使存在source元素。)

HTMLMediaElement/src

支持所有当前的引擎。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

src IDL 属性在媒体元素上必须反映同名的内容属性。

HTMLMediaElement/crossOrigin

支持所有当前的引擎。

Firefox22+Safari10+Chrome33+
Opera?Edge79+
Edge (旧版)13+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

crossOrigin IDL 属性必须反映crossorigin内容属性,仅限于已知值

媒体提供对象是一个可以表示媒体资源的对象,与URL分开。MediaStream对象,MediaSource对象和Blob对象都是媒体提供对象

每个媒体元素都可以有一个分配的媒体提供对象,它是一个媒体提供对象。当创建媒体元素时,它没有分配的媒体提供对象

media.srcObject [ = source ]

HTMLMediaElement/srcObject

仅在一个引擎中支持。

Firefox🔰 42+Safari11+🔰 108+
Opera?🔰 108+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

允许媒体元素被分配一个媒体提供对象

media.currentSrc

HTMLMediaElement/currentSrc

支持所有当前的引擎。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回当前URL媒体资源,如果有的话。

当没有媒体资源或没有URL时,返回空字符串。

currentSrc IDL 属性必须最初设置为空字符串。其值由下面定义的资源选择算法更改。

srcObject IDL 属性,在获取时,必须返回元素的分配的媒体提供对象,如果有的话,否则返回null。在设置时,它必须将元素的分配的媒体提供对象设置为新值,然后调用元素的媒体元素加载算法

有三种方法可以指定媒体资源srcObject IDL 属性、src内容属性和source元素。IDL 属性优先,其次是内容属性,最后是元素。

4.8.11.3 MIME 类型

媒体资源可以通过其类型来描述,特别是 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)

HTMLMediaElement/canPlayType

支持所有当前引擎。

Firefox3.5+Safari4+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

根据用户代理是否有信心播放给定类型的媒体资源,返回空字符串(否定回应)、"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 元素的

4.8.11.4 网络状态
media.networkState

HTMLMediaElement/networkState

支持所有当前引擎。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android4+Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回元素的当前网络活动状态,以下列表中的代码之一。

媒体元素与网络交互时,它们的当前网络活动由networkState属性表示。获取时,它必须返回元素的当前网络状态,该状态必须是以下值之一:

NETWORK_EMPTY(数值 0)
元素尚未初始化。所有属性都处于初始状态。
NETWORK_IDLE(数值 1)
元素的资源选择算法处于活动状态并已选择资源,但此时并未实际使用网络。
NETWORK_LOADING(数值 2)
用户代理正在积极尝试下载数据。
NETWORK_NO_SOURCE(数值 3)
元素的资源选择算法处于活动状态,但尚未找到可用的资源

资源选择算法在下文定义,描述了networkState属性何时更改值以及触发哪些事件以指示此状态的变化。

4.8.11.5 加载媒体资源
media.load()

HTMLMediaElement/load

在所有当前引擎中都支持。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

导致元素重置并开始从头选择和加载新的 媒体资源

所有 媒体元素 都具有一个 可以自动播放标志,其初始状态必须为 true,以及一个 延迟加载事件标志,其初始状态必须为 false。 当 延迟加载事件标志 为 true 时,该元素必须 延迟其文档的加载事件

当在 媒体元素 上调用 load() 方法时,用户代理必须执行 媒体元素加载算法

媒体元素 具有一个关联的布尔值 当前是否暂停,初始值为 false。

媒体元素加载算法 包含以下步骤:

  1. 将此元素的 当前是否暂停 设置为 false。

  2. 中止此元素的任何已经运行的 资源选择算法 实例。

  3. pending tasks 设为来自 媒体元素媒体元素事件任务源 的所有 任务 的列表,存在于其中一个 任务队列 中。

  4. 对于 pending tasks 中的每个任务,若其会 解决待处理的播放承诺拒绝待处理的播放承诺,立即按任务排队的顺序解决或拒绝这些承诺。

  5. pending tasks 中的每个 任务 从其 任务队列 中移除。

    基本上,当媒体元素开始加载新资源时,待处理的事件和回调会被丢弃,正在处理的承诺会被立即解决或拒绝。

  6. 如果media elementnetworkState被设置为NETWORK_LOADINGNETWORK_IDLEqueue a media element task给定media elementfire an event命名为abortmedia element上。

  7. 如果 媒体元素networkState 没有设置为 NETWORK_EMPTY,则:

    1. 排队一个媒体元素任务,给定媒体元素触发一个事件,名为emptied媒体元素上。

    2. 如果 媒体元素 的获取过程正在进行,用户代理应停止该过程。

    3. 如果 媒体元素指定的媒体提供者对象 是一个 MediaSource 对象,则 将其分离

    4. 忘记媒体元素的媒体资源特定轨道

    5. 如果 readyState 没有设置为 HAVE_NOTHING,则将其设置为该状态。

    6. 如果 paused 属性为 false,则:

      1. paused 属性设置为 true。

      2. 处理待处理的播放承诺拒绝待处理的播放承诺 ,并以结果和一个 AbortError DOMException

    7. 如果 seeking 为 true,则将其设置为 false。

    8. 当前播放位置设置为0。

      官方播放位置设置为0。

      如果这改变了官方播放位置,那么排队一个媒体元素任务,给定媒体元素触发一个事件,名为timeupdate媒体元素上。

    9. 时间轴偏移 设置为 Not-a-Number (NaN)。

    10. 更新 duration 属性为 Not-a-Number (NaN)。

      用户代理 不会 为此特定的持续时间变化触发 durationchange 事件。

  8. playbackRate 属性设置为 defaultPlaybackRate 属性的值。

  9. error 属性设置为 null,并将 可以自动播放标志 设置为 true。

  10. 调用 媒体元素资源选择算法

  11. 任何之前正在播放的 媒体资源 播放停止。

资源选择算法对于一个 媒体元素 如下所述。该算法始终作为 任务 的一部分调用,但算法的第一步之一是返回并继续运行剩余步骤 并行。此外,该算法与 事件循环 机制紧密交互;特别是,它有 同步部分(作为 事件循环 算法的一部分触发)。这些部分中的步骤标有 ⌛。

  1. 将元素的 networkState 属性设置为 NETWORK_NO_SOURCE 值。

  2. 将元素的 显示海报标志 设置为 true。

  3. 媒体元素延迟加载事件标志 设置为 true(这会 延迟加载事件)。

  4. 等待稳定状态,允许调用此算法的 任务 继续。同步部分 包含此算法的所有剩余步骤,直到算法指示 同步部分 已结束。(同步部分中的步骤标有 ⌛。)

  5. ⌛ 如果 媒体元素阻塞解析器标志 为 false,则 填充待处理文本轨道列表

  6. ⌛ 如果 媒体元素 有一个 指定的媒体提供者对象,则将 mode 设为 object

    ⌛ 否则,如果 媒体元素 没有 指定的媒体提供者对象,但有 src 属性,则将 mode 设为 attribute

    ⌛ 否则,如果 媒体元素 没有 指定的媒体提供者对象 且没有 src 属性,但有一个 source 元素子节点,则将 mode 设为 children,并将 candidate 设为第一个这样的 source 元素子节点,按 树顺序

    ⌛ 否则,媒体元素 没有 指定的媒体提供者对象,也没有 src 属性,也没有 source 元素子节点:

    1. ⌛ 将 networkState 设置为 NETWORK_EMPTY

    2. ⌛ 将元素的 延迟加载事件标志 设置为 false。这会停止 延迟加载事件

    3. 结束 同步部分 并返回。

  7. ⌛ 将 媒体元素networkState 设置为 NETWORK_LOADING

  8. 排队一个媒体元素任务,给定媒体元素触发一个事件,名为loadstart媒体元素上。

  9. 运行以下列表中的适当步骤:

    如果 modeobject
    1. ⌛ 将 currentSrc 属性设置为空字符串。

    2. 结束 同步部分,剩余步骤继续 并行

    3. 运行 资源获取算法,使用 指定的媒体提供者对象。如果该算法在不中止此算法的情况下返回,则加载失败。

    4. 媒体提供者加载失败:到达此步骤表示媒体资源加载失败。处理待处理的播放承诺排队一个媒体元素任务,让 媒体元素 使用结果运行 专用媒体源失败步骤

    5. 等待前一步排队的 任务 执行完毕。

    6. 返回。在此算法再次触发之前,元素不会尝试加载另一个资源。

    如果 modeattribute
    1. ⌛ 如果 src 属性的值为空字符串,则结束 同步部分,并跳到下面的 属性加载失败 步骤。

    2. ⌛ 将 urlRecord 设为 编码解析 URL 的结果,给定 src 属性的值,相对于 媒体元素节点文档,当 src 属性最后一次更改时。

    3. ⌛ 如果 urlRecord 不是失败,则将 currentSrc 属性设置为应用 URL 序列化器urlRecord 的结果。

    4. 结束 同步部分,剩余步骤继续 并行

    5. 如果 urlRecord 不是失败,则运行 资源获取算法,使用 urlRecord。如果该算法在不中止此算法的情况下返回,则加载失败。

    6. 属性加载失败:到达此步骤表示媒体资源加载失败或 urlRecord 失败。处理待处理的播放承诺排队一个媒体元素任务,让 媒体元素 使用结果运行 专用媒体源失败步骤

    7. 等待前一步排队的 任务 执行完毕。

    8. 返回。在此算法再次触发之前,元素不会尝试加载另一个资源。

    否则(modechildren
    1. ⌛ 将 pointer 设为由 媒体元素 的子节点列表中的两个相邻节点定义的位置,视列表的开始(列表中第一个子节点之前,如果有的话)和列表的结束(列表中最后一个子节点之后,如果有的话)为节点本身。一个节点是 pointer 之前的节点,另一个节点是 pointer 之后的节点。初始情况下,将 pointer 设为 candidate 节点和下一个节点之间的位置,如果有的话,或列表的末尾,如果它是最后一个节点。

      当节点被 插入移除媒体元素 中时,必须按以下方式更新 pointer

      如果一个新节点被 插入 到定义 pointer 的两个节点之间
      pointer 设为 pointer 之前的节点和新节点之间的位置。换句话说,在 pointer 插入发生在 pointer 之后。
      如果 pointer 之前的节点被移除
      pointer 设为 pointer 之后的节点和 pointer 之前的节点之间的位置。换句话说,pointer 相对于剩余节点不会移动。
      如果 pointer 之后的节点被移除
      pointer 设为 pointer 之前的节点和 pointer 之前的节点之后的节点之间的位置。同前一种情况一样,pointer 相对于剩余节点不会移动。

      其他变化不会影响 pointer

    2. 处理候选:如果 candidate 没有 src 属性,或其 src 属性的值为空字符串,则结束 同步部分,并跳到下面的 元素加载失败 步骤。

    3. ⌛ 如果 candidatemedia 属性,其值不 匹配环境,则结束 同步部分,并跳到下面的 元素加载失败 步骤。

    4. ⌛ 将 urlRecord 设为 编码解析 URL 的结果,给定 candidatesrc 属性的值,相对于 candidate节点文档,当 src 属性最后一次更改时。

    5. ⌛ 如果 urlRecord 失败,则结束 同步部分,并跳到下面的 元素加载失败 步骤。

    6. ⌛ 如果 candidatetype 属性,当解析为 MIME 类型(包括任何由 codecs 参数描述的编解码器,对于定义该参数的类型),表示 用户代理知道它不能渲染的类型,则结束 同步部分,并跳到下面的 元素加载失败 步骤。

    7. ⌛ 将 currentSrc 属性设置为应用 URL 序列化器urlRecord 的结果。

    8. 结束 同步部分,剩余步骤继续 并行

    9. 运行 资源获取算法,使用 urlRecord。如果该算法在不中止此算法的情况下返回,则加载失败。

    10. 元素失败排队一个媒体元素任务,给定媒体元素触发一个事件,名为errorcandidate上。

    11. 等待稳定状态同步部分 包含此算法的所有剩余步骤,直到算法指示 同步部分 已结束。(同步部分中的步骤标有 ⌛。)

    12. 忘记媒体元素的媒体资源特定轨道

    13. 找到下一个候选:将 candidate 设为 null。

    14. 搜索循环:如果 pointer 之后的节点是列表的末尾,则跳到下面的 等待 步骤。

    15. ⌛ 如果 pointer 之后的节点是一个 source 元素,将 candidate 设为该元素。

    16. ⌛ 前移 pointer,使 pointer 之前的节点现在成为 pointer 之后的节点,并且 pointer 之后的节点成为 pointer 之后节点之后的节点(如果有)。

    17. ⌛ 如果 candidate 为 null,跳回 搜索循环 步骤。否则,跳回 处理候选 步骤。

    18. 等待:将元素的 networkState 属性设置为 NETWORK_NO_SOURCE 值。

    19. ⌛ 将元素的 显示海报标志 设置为 true。

    20. 排队一个媒体元素任务,让 媒体元素 设置元素的 延迟加载事件标志 为 false。这会停止 延迟加载事件

    21. 结束 同步部分,剩余步骤继续 并行

    22. 等待直到 pointer 之后的节点是一个非列表末尾的节点。(此步骤可能永远等待。)

    23. 等待稳定状态同步部分 包含此算法的所有剩余步骤,直到算法指示 同步部分 已结束。(同步部分中的步骤标有 ⌛。)

    24. ⌛ 将元素的 延迟加载事件标志 设置回 true(这会再次 延迟加载事件,以防它尚未触发)。

    25. ⌛ 将 networkState 设置回 NETWORK_LOADING

    26. ⌛ 跳回上面的 找到下一个候选 步骤。

    专用媒体源失败步骤,带有一个承诺列表 promises 如下:

    1. error 属性设置为 创建一个 MediaError 的结果,使用 MEDIA_ERR_SRC_NOT_SUPPORTED

    2. 忘记媒体元素的媒体资源特定轨道

    3. 将元素的 networkState 属性设置为 NETWORK_NO_SOURCE 值。

    4. 将元素的 show poster 标志 设置为 true。

    5. 触发一个事件,名为error媒体元素上。

    6. 拒绝待处理的播放承诺,使用 promises 和一个 NotSupportedError DOMException

    7. 将元素的 延迟加载事件标志 设置为 false。这会停止 延迟加载事件

验证媒体响应,给定一个 响应 response、一个 媒体资源 resource,以及 "entire resource" 或一个 (number, number 或 "until end") 元组 byteRange

  1. 如果 response 是一个 网络错误, 则返回 false。

  2. 如果 byteRange 是 "entire resource",则返回 true。

  3. internalResponseresponse不安全响应

  4. 如果 internalResponse状态 为 200,则返回 true。

  5. 如果 internalResponse状态 不是 206,则返回 false。

  6. 如果从 internalResponse提取内容范围值 的结果失败,则返回 false。

    注意,提取的值不会被使用,特别是不会与 byteRange 进行比较。因此,这一步作为 `Content-Range` 头部的语法验证,但如果响应中的 `Content-Range` 值与请求中的 `Range` 值不匹配,这不被视为失败。

  7. origin 为 "rewritten" 如果 internalResponseURL 为 null; 否则 internalResponseURLorigin

  8. previousOriginresourceorigin

  9. 如果以下任何条件为真:

    则将 resourceorigin 设置为 origin

    否则,如果 responseCORS 跨源,则返回 false。

    否则,将 resourceorigin 设置为 "multiple"。

    这确保了带有范围头的透明响应不会通过与来自不同来源的其他响应拼接在一起而泄露信息。

  10. 返回 true。

用于 媒体元素 和给定的 URL 记录媒体提供者对象资源获取算法 如下:

  1. 如果算法是通过 媒体提供者对象URL 记录 被调用的,而该 blob URL 条目 是一个 blob URL 条目,其 对象 是一个 媒体提供者对象,则让 modelocal。否则,让 moderemote

  2. 如果 moderemote,则让 current media resource 为传递给该算法的 URL 记录 所给出的资源;否则,让 current media resource媒体提供者对象 所给出的资源。无论如何,current media resource 现在是元素的 媒体资源

  3. 如果有的话,从 媒体元素待处理文本轨道列表 中移除所有 媒体资源特定文本轨道

  4. 执行以下步骤列表中的适当步骤:

    如果 mode 是 remote
    1. 可以选择执行以下子步骤。如果用户代理打算不尝试获取资源,直到用户明确请求它(例如,作为实现 preload 属性的 none 关键字的一种方式),这是预期的行为。

      1. networkState 设置为 NETWORK_IDLE

      2. 排队一个媒体元素任务,给定 媒体元素,以 触发一个名为 suspend 的事件。

      3. 排队一个媒体元素任务,给定 媒体元素,以将元素的 delaying-the-load-event flag 设置为 false。这将停止 延迟加载事件

      4. 等待任务执行。

      5. 等待一个 实现定义 的事件(例如,用户请求媒体元素开始播放)。

      6. 将元素的 delaying-the-load-event flag 重新设置为 true(这再次 延迟加载事件,以防它尚未触发)。

      7. networkState 设置为 NETWORK_LOADING

    2. 如果 媒体元素audio 元素,则将 destination 设为 "audio",否则设为 "video"。

    3. request 成为 创建一个潜在的 CORS 请求 的结果,给定 current media resourceURL 记录destination媒体元素 的当前状态的 crossorigin 内容属性。

    4. requestclient 设置为 媒体元素节点文档相关设置对象

    5. request发起者类型 设置为 destination

    6. byteRange 为 "entire resource" 或一个(number,number 或 "until end")元组,表示满足 媒体数据 中缺失数据所需的字节范围。该值是 实现定义的,并可能依赖于编解码器、网络状况或其他启发式方法。用户代理可能决定完全获取资源,在这种情况下 byteRange 将为 "entire resource",从字节偏移量到结束获取资源,在这种情况下 byteRange 将为(number,"until end"),或在两个字节偏移量之间获取资源,在这种情况下 byteRange 将为表示两个偏移量的(number,number)元组。

    7. 如果 byteRange 不是 "entire resource",则:

      1. 如果 byteRange[1] 是 "until end",则 request 添加一个范围头,给定 byteRange[0]。

      2. 否则,request 添加一个范围头,给定 byteRange[0] 和 byteRange[1]。

    8. 获取 request,并设置 processResponse 为以下步骤,给定 response response

      1. global媒体元素节点文档相关全局对象

      2. updateMedia排队一个媒体元素任务,给定 媒体元素 以运行以下 媒体数据处理步骤列表中的第一个适当步骤。(为此使用一个新任务,使以下描述的工作相对于适当的 媒体元素事件任务源 发生,而不是使用 网络任务源。)

      3. processEndOfMedia 是以下步骤:如果获取过程在没有错误的情况下完成,包括解码媒体数据,并且所有数据都可供用户代理在不进行网络访问的情况下使用,那么,用户代理必须继续执行以下最后一步。这可能永远不会发生,例如在流式传输无限资源(如网络广播)时,或者资源长度超过用户代理的缓存数据能力。

      4. 如果给定 current media resourcebyteRange 验证 response 的结果为 false,则中止这些步骤。

      5. 否则,增量读取 response主体,给定 updateMediaprocessEndOfMedia、一个空算法和 global

      6. 使用以这种方式获取的 response不安全响应 内容更新 媒体数据response 可以是 CORS-same-originCORS-cross-origin;这会影响通过 API 公开的字幕,并且,对于 video 元素,当视频被绘制到画布上时,画布是否会被污染。

      媒体元素停止超时 是一个 实现定义的 时间长度,应该约为三秒。当一个正在积极尝试获取 媒体数据媒体元素 在等于 媒体元素停止超时 的时间内未能接收到任何数据时,用户代理必须 排队一个媒体元素任务,给定 媒体元素 来:

      1. 触发一个名为 stalled 的事件。

      2. 将元素的 is currently stalled 设置为 true。

      用户代理可能允许用户选择性地阻止或减慢 媒体数据 下载。当 媒体元素 的下载被完全阻止时,用户代理必须像处理它停止了一样(而不是像连接关闭了一样)。下载速度也可能会被用户代理自动限制,例如平衡与共享同一带宽的其他连接的下载。

      用户代理可以随时决定不下载更多内容,例如在缓冲一个小时媒体资源的五分钟后,等待用户决定是否播放资源,在交互式资源中等待用户输入,或者当用户导航离开页面时。当 媒体元素 的下载被暂停时,用户代理必须 排队一个媒体元素任务,给定 媒体元素,将 networkState 设置为 NETWORK_IDLE触发一个名为 suspend 的事件。如果且当资源的下载恢复时,用户代理必须 排队一个媒体元素任务,给定 媒体元素,将 networkState 设置为 NETWORK_LOADING。在这些任务排队之间,加载被暂停(因此如上所述,不会触发 progress 事件)。

      preload 属性提供了一个提示,即使在没有 autoplay 属性的情况下,作者认为建议缓冲多少。

      当用户代理决定完全暂停下载时,例如,如果它正在等待用户开始播放然后再下载任何进一步的内容,用户代理必须 排队一个媒体元素任务,给定 媒体元素,将元素的 delaying-the-load-event flag 设置为 false。这将停止 延迟加载事件

      尽管上述步骤给出了发出请求的算法,用户代理可能会使用其他方法,特别是在面对错误条件时。例如,用户代理可能会重新连接到服务器或切换到流协议。用户代理必须只在放弃尝试获取资源时才认为资源出错,并继续上述步骤的错误分支。

      为了确定 媒体资源 的格式,用户代理必须使用 专门嗅探音频和视频的规则

      在加载未暂停的情况下(见下文),每 350 毫秒(±200 毫秒)或每接收一个字节,以频率更低者为准,排队一个媒体元素任务,给定 媒体元素 以:

      1. 触发一个名为 progress 的事件。

      2. 将元素的 is currently stalled 设置为 false。

      虽然用户代理可能仍然需要网络访问才能获取 媒体资源 的部分内容,用户代理必须停留在此步骤。

      例如,如果用户代理已丢弃视频的前半部分,即使 播放已结束,用户代理仍将停留在此步骤,因为用户随时可能会回放到开始处。事实上,在这种情况下,一旦 播放已结束,用户代理最终将触发一个 suspend 事件,如前所述。

    否则(modelocal

    current media resource 描述的资源(如果有)包含 媒体数据。它是 CORS-same-origin

    如果 current media resource 是原始数据流(例如来自 File 对象),则为了确定 媒体资源 的格式,用户代理必须使用 专门嗅探音频和视频的规则。否则,如果数据流是预解码的,则格式是相关规范给出的格式。

    每当新的 current media resource 数据可用时,排队一个媒体元素任务,给定 媒体元素 以运行以下 媒体数据处理步骤列表中的第一个适当步骤。

    current media resource 永久耗尽时(例如,Blob 的所有字节已处理完),如果没有解码错误,则用户代理必须继续执行以下 最后一步。这可能永远不会发生,例如,如果 current media resourceMediaStream

    媒体数据处理步骤列表 如下:

    如果由于网络错误导致 媒体数据 无法获取,用户代理放弃尝试获取资源
    如果可以获取 媒体数据,但通过检查发现其格式不受支持,或者无法渲染

    在用户代理确定 current media resource 是否可用之前发生的 DNS 错误、HTTP 4xx 和 5xx 错误(以及其他协议的等效错误)以及其他致命网络错误,以及文件使用不受支持的容器格式或所有数据使用不受支持 的编解码器,必须导致用户代理执行以下步骤:

    1. 用户代理应取消获取过程。

    2. 中止此子算法,返回到 资源选择算法

    如果发现 媒体资源 有音轨
    1. 创建一个 AudioTrack 对象以表示音轨。

    2. 使用新的 AudioTrack 对象更新 媒体元素audioTracks 属性的 AudioTrackList 对象。

    3. enableunknown

    4. 如果 媒体资源current media resourceURL 表示启用特定的音轨集,或者如果用户代理有信息可以选择特定音轨以改善用户体验,那么:如果此音轨是要启用的音轨之一,则将 enable 设置为 true,否则将 enable 设置为 false

      这可能由 媒体片段语法 触发,但也可能由例如用户代理选择 5.1 环绕声音轨而不是立体声音轨触发。

    5. 如果 enable 仍为 unknown,则如果 媒体元素 还没有启用音轨,则将 enable 设置为 true,否则将 enable 设置为 false

    6. 如果 enabletrue,则启用此音轨,否则,不启用此音轨。

    7. 触发一个名为 addtrack 的事件,使用 TrackEvent,其 track 属性初始化为新的 AudioTrack 对象。

    如果发现 媒体资源 有视频轨道
    1. 创建一个 VideoTrack 对象以表示视频轨道。

    2. 使用新的 VideoTrack 对象更新 媒体元素videoTracks 属性的 VideoTrackList 对象。

    3. enableunknown

    4. 如果 媒体资源current media resourceURL 表示启用特定的视频轨道集,或者如果用户代理有信息可以选择特定视频轨道以改善用户体验,那么:如果这是第一个这样的视频轨道,则将 enable 设置为 true,否则将 enable 设置为 false

      这可能再次由 媒体片段语法 触发。

    5. 如果 enable 仍为 unknown,则如果 媒体元素 还没有选中的视频轨道,则将 enable 设置为 true,否则将 enable 设置为 false

    6. 如果 enabletrue,则选择此轨道并取消选择任何先前选中的视频轨道,否则,不选择此视频轨道。如果其他轨道被取消选择,则 将触发 change 事件

    7. 触发一个名为 addtrack 的事件,使用 TrackEvent,其 track 属性初始化为新的 VideoTrack 对象。

    一旦获取到足够的 媒体数据 以确定 媒体资源 的持续时间、尺寸和其他元数据

    这表明资源可用。用户代理必须遵循这些子步骤:

    1. 建立媒体时间轴 以用于 当前播放位置最早可能的位置,基于 媒体数据

    2. 根据上一步建立的 媒体时间轴,将 时间轴偏移 更新为与零时间相对应的日期和时间。如果 媒体资源 没有明确给出时间和日期,则 时间轴偏移 必须设置为非数字(NaN)。

    3. 当前播放位置官方播放位置 设置为 最早可能的位置

    4. 使用上面建立的 媒体时间轴 的最后一帧的时间(如果已知)更新 duration 属性。如果未知(例如,一个原则上无限的流),则将 duration 属性更新为正无穷大。

      用户代理 排队一个媒体元素任务,给定 媒体元素触发一个名为 durationchange 的事件。

    5. 对于 video 元素,设置 videoWidthvideoHeight 属性,并 排队一个媒体元素任务,给定 媒体元素触发一个名为 resize 的事件。

      如果尺寸随后发生变化,将触发进一步的 resize 事件。

    6. readyState 属性设置为 HAVE_METADATA

      作为将 readyState 属性设置为新值的一部分,将触发 loadedmetadata DOM 事件。

    7. jumped 为 false。

    8. 如果 媒体元素默认播放起始位置 大于零,则 seek 到该时间,并让 jumped 为 true。

    9. 媒体元素默认播放起始位置 设置为零。

    10. initial playback position 为零。

    11. 如果 媒体资源current media resourceURL 表示特定的开始时间,则将 initial playback position 设置为该时间,并且如果 jumped 仍为 false,则 seek 到该时间。

      例如,对于支持 媒体片段语法 的媒体格式,片段 可用于 指示起始位置。

    12. 如果没有 启用 的音轨,则启用一个音轨。这将 触发 change 事件

    13. 如果没有 选中的 视频轨道,则选择一个视频轨道。这将 触发 change 事件

    一旦 readyState 属性达到 HAVE_CURRENT_DATA在触发 loadeddata 事件后,将元素的 delaying-the-load-event flag 设置为 false。这将停止 延迟加载事件

    一个尝试减少网络使用的用户代理,同时仍然获取每个 媒体资源 的元数据,也将在此时停止缓冲,按照 前面描述的规则,这包括 networkState 属性切换到 NETWORK_IDLE 值并触发 suspend 事件。

    用户代理在播放之前必须确定 媒体资源 的持续时间并执行此步骤。

    一旦整个 媒体资源 已被获取(但可能在其被解码之前)

    触发一个名为 progress 的事件,给定 媒体元素

    networkState 设置为 NETWORK_IDLE触发一个名为 suspend 的事件,给定 媒体元素

    如果用户代理丢弃了任何 媒体数据,然后需要恢复网络活动以再次获取它,则用户代理必须 排队一个媒体元素任务,给定 媒体元素,将 networkState 设置为 NETWORK_LOADING

    如果用户代理可以保持 媒体资源 已加载,则算法将继续执行其 最后一步,该步骤将中止算法。

    如果连接在接收到一些 媒体数据 后中断,导致用户代理放弃尝试获取资源

    在用户代理确定 current media resource 是否可用之后发生的致命网络错误(即一旦 媒体元素readyState 属性不再是 HAVE_NOTHING)必须导致用户代理执行以下步骤:

    1. 用户代理应取消获取过程。

    2. error 属性设置为 创建一个 MediaError 的结果,并设置为 MEDIA_ERR_NETWORK

    3. 将元素的 networkState 属性设置为 NETWORK_IDLE 值。

    4. 将元素的 delaying-the-load-event flag 设置为 false。这将停止 延迟加载事件

    5. 触发一个名为 error 的事件,给定 媒体元素

    6. 中止整体 资源选择算法

    如果 媒体数据 已损坏

    在用户代理确定 current media resource 是否可用之后发生的致命解码错误(即一旦 媒体元素readyState 属性不再是 HAVE_NOTHING)必须导致用户代理执行以下步骤:

    1. 用户代理应取消获取过程。

    2. error 属性设置为 创建一个 MediaError 的结果,并设置为 MEDIA_ERR_DECODE

    3. 将元素的 networkState 属性设置为 NETWORK_IDLE 值。

    4. 将元素的 delaying-the-load-event flag 设置为 false。这将停止 延迟加载事件

    5. 触发一个事件,名为error媒体元素上。

    6. 中止整体 资源选择算法

    如果媒体数据获取过程被用户中止

    用户中止了获取过程,例如因为用户按下了“停止”按钮,则用户代理必须执行以下步骤。如果在执行这些步骤时调用了 load() 方法,则不执行这些步骤,因为上述步骤处理了那种特定类型的中止。

    1. 用户代理应取消获取过程。

    2. error 属性设置为 创建一个 MediaError 的结果,并设置为 MEDIA_ERR_ABORTED

    3. 触发一个名为 abort 的事件,给定 媒体元素

    4. 如果 媒体元素readyState 属性值等于 HAVE_NOTHING,则将元素的 networkState 属性设置为 NETWORK_EMPTY 值,将元素的 show poster flag 设置为 true,并 触发一个名为 emptied 的事件。

      否则,将元素的 networkState 属性设置为 NETWORK_IDLE 值。

    5. 将元素的 delaying-the-load-event flag 设置为 false。这将停止 延迟加载事件

    6. 中止整体 资源选择算法

    如果可以获取 媒体数据,但有非致命错误或部分使用不受支持的编解码器,导致用户代理无法完全正确地渲染内容但不妨碍播放

    服务器返回的数据 部分可用但无法最佳渲染,必须导致用户代理仅渲染它能处理的部分,忽略其余部分。

    如果发现 媒体资源 声明了用户代理支持的 媒体资源特定文本轨道

    如果 媒体数据CORS-same-origin,则使用相关数据运行 步骤以暴露媒体资源特定文本轨道

    跨源视频不暴露其字幕,因为这将允许攻击,例如恶意网站从用户内联网的机密视频中读取字幕。

  5. 最后一步:如果用户代理达到此步骤(这只有在整个资源加载并保持可用的情况下才会发生):中止整体 资源选择算法

当一个媒体元素需要忘记媒体元素的媒体资源特定轨道时,用户代理必须从媒体元素文本轨道列表中移除所有媒体资源特定文本轨道,然后清空媒体元素audioTracks属性的AudioTrackList对象,然后清空媒体元素videoTracks属性的VideoTrackList对象。作为这一过程的一部分不会触发任何事件(特别是不触发removetrack事件);可以使用调用此算法的算法触发的erroremptied事件代替。


preload 属性是一个 枚举属性,具有以下关键字和状态:

关键字 状态 简要描述
auto 自动 向用户代理暗示,用户代理可以优先考虑用户的需求而不会对服务器造成风险,包括乐观地下载整个资源。
(空字符串)
none 向用户代理暗示,作者不期望用户需要媒体资源,或者服务器希望最小化不必要的流量。此状态不提供有关在缓冲开始后如何积极下载媒体资源的暗示(例如,一旦用户点击“播放”)。
metadata 元数据 向用户代理暗示,作者不期望用户需要媒体资源,但获取资源元数据(尺寸、轨道列表、持续时间等)甚至前几帧是合理的。如果用户代理精确地不超过元数据的获取,那么 媒体元素 最终会将其 readyState 属性设置为 HAVE_METADATA;但通常会获取一些帧,它可能会是 HAVE_CURRENT_DATAHAVE_FUTURE_DATA。当媒体资源在播放时,暗示用户代理要考虑带宽稀缺,例如建议节流下载以最慢的速度获取媒体数据,同时保持连续播放。

该属性的 缺失值默认无效值默认 都是 实现定义的,尽管建议将 元数据 状态作为在减少服务器负载和提供最佳用户体验之间的折衷。

即使在 媒体资源 正在缓冲或播放时也可以更改该属性;上表中的描述应考虑到这一点。

作者可能会在用户开始播放后,将属性从 "none" 或 "metadata" 动态切换为 "auto"。例如,在有许多视频的页面上,这可能用于指示除非请求否则不下载许多视频,但一旦请求其中一个视频,则应积极下载。

preload 属性旨在向用户代理提供一个提示,关于作者认为什么会带来最佳用户体验。该属性可能会被完全忽略,例如基于用户的明确偏好或可用的连接情况。

preload IDL 属性必须 反映 同名内容属性,仅限于已知值

autoplay 属性可以覆盖 preload 属性(因为如果媒体播放,它自然首先要缓冲,不论 preload 属性给出的提示如何)。然而,同时包含这两个属性并不是错误。


media.buffered

HTMLMediaElement/buffered

所有当前引擎支持。

Firefox4+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回一个 TimeRanges 对象,该对象表示用户代理已缓冲的媒体资源的范围。

buffered 属性必须返回一个新的静态标准化 TimeRanges 对象,该对象表示用户代理在评估属性时已缓冲的媒体资源的范围(如果有)。用户代理必须准确确定可用的范围,即使对于只能通过繁琐检查确定的媒体流。

通常,这将是锚定在零点的单一范围,但如果例如用户代理在响应搜索时使用 HTTP 范围请求,则可能有多个范围。

用户代理可以丢弃先前缓冲的数据。

因此,一段时间内由 buffered 属性返回的对象范围内的时间位置,可能在稍后时间由相同属性返回的对象范围内不包括。

每次返回一个新对象是属性获取器的不良模式,仅在此固化是因为更改它的代价高昂。这不应复制到新的 API 中。

4.8.11.6 媒体资源的偏移量
media.duration

HTMLMediaElement/duration

所有当前引擎支持。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回媒体资源的长度,单位为秒,假设媒体资源的起点为零。

如果持续时间不可用,则返回 NaN。

对于无限流,返回 Infinity。

media.currentTime [ = value ]

HTMLMediaElement/currentTime

所有当前引擎支持。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回官方播放位置,以秒为单位。

可以设置,以跳到指定时间。

媒体资源有一个媒体时间线,将时间(以秒为单位)映射到媒体资源中的位置。时间线的起点是其最早定义的位置。时间线的持续时间是其最后定义的位置。

建立媒体时间线:如果媒体资源以某种方式指定了起点不是负数的显式时间线(即为每帧指定了特定的时间偏移,并为第一帧指定了零或正偏移),则媒体时间线应为该时间线。(是否可以指定时间线取决于媒体资源的格式。)如果媒体资源指定了显式的开始时间和日期,则该时间和日期应被视为媒体时间线的零点;时间线偏移量将是时间和日期,通过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属性必须,在获取时,返回媒体元素默认播放起始位置,除非该值为零,在这种情况下它必须返回元素的官方播放位置。返回值必须以秒为单位表示。在设置时,如果媒体元素readyStateHAVE_NOTHING,则必须将媒体元素默认播放起始位置设置为新值;否则,它必须将官方播放位置设置为新值,然后搜索到新值。新值必须以秒为单位解释。

如果媒体资源是流媒体资源,则用户代理可能无法在缓冲区过期后获取资源的某些部分。同样,某些媒体资源可能有一个不从零开始的媒体时间线最早可能的位置是用户代理可以再次获得的流或资源中的最早位置。这也是媒体时间线上的一个时间。

最早可能的位置在API中没有明确暴露;它对应于seekable属性的TimeRanges对象中第一个范围的开始时间(如果有的话),否则对应于当前播放位置

最早可能的位置变化时,如果当前播放位置早于最早可能的位置,用户代理必须搜索最早可能的位置;否则,如果用户代理在过去 15 到 250 毫秒内没有在元素上触发timeupdate事件,并且还没有在运行该事件的事件处理程序,则用户代理必须排队媒体元素任务,将该媒体元素给定以触发一个名为timeupdate的事件。

由于上述要求和资源获取算法中在获取媒体元数据时启动的要求,当前播放位置不能小于最早可能的位置

如果用户代理在任何时候得知音轨或视频轨道已经结束,并且所有媒体数据都对应于媒体时间线中早于最早可能位置的部分,则用户代理可以排队一个媒体元素任务,将该媒体元素给定以运行这些步骤:

  1. audioTracks属性的AudioTrackList对象或videoTracks属性的VideoTrackList对象中移除该轨道(根据需要)。

  2. 触发一个名为removetrack的事件,使用TrackEvent,在上述媒体元素AudioTrackListVideoTrackList对象上,初始化track属性为代表轨道的AudioTrackVideoTrack对象。

duration属性必须返回媒体资源媒体时间线上的结束时间,以秒为单位。如果没有可用的媒体数据,则属性必须返回 NaN 值。如果媒体资源不被认为是有界的(例如流媒体广播或没有宣布结束时间的直播活动),则属性必须返回正无穷值。

用户代理必须在播放任何媒体数据之前,并且在将readyState设置为大于或等于HAVE_METADATA之前,确定媒体资源的持续时间,即使这样做需要获取资源的多个部分。

媒体资源的长度变为已知值(例如从未知变为已知,或从先前确定的长度变为新长度)时,用户代理必须排队一个媒体元素任务,将该媒体元素给定以触发一个名为durationchange的事件(加载新媒体资源时重置持续时间不会触发此事件)。如果持续时间发生变化,使当前播放位置大于媒体资源的结束时间,则用户代理还必须搜索媒体资源的结束时间。

如果“无限”流出于某种原因结束,则持续时间将从正无穷大变为流中最后一帧或样本的时间,并触发durationchange事件。同样,如果用户代理最初估计媒体资源的持续时间而不是精确定义它,并根据新信息稍后修正估计,则持续时间会发生变化并触发durationchange事件。

某些视频文件还有一个与媒体时间线的零时间相对应的显式日期和时间,称为时间线偏移。初始时,时间线偏移必须设置为 NaN。

getStartDate()方法必须返回一个新的Date对象,表示当前的时间线偏移


loop属性是一个布尔属性,如果指定,表示媒体元素在到达媒体资源的末尾时应回到开始。

HTMLMediaElement/loop

所有当前引擎支持。

Firefox11+Safari4+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

loop IDL 属性必须反映同名内容属性。

4.8.11.7 就绪状态
media.readyState

HTMLMediaElement/readyState

所有当前引擎支持。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回一个值,该值表示元素当前相对于渲染当前播放位置的状态,从以下列表中的代码中选择。

媒体元素有一个就绪状态,描述了它在当前播放位置准备渲染的程度。可能的值如下;任何特定时间媒体元素的就绪状态是描述元素状态的最大值:

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状态描述的所有条件,并且满足以下条件之一:

实际上,HAVE_METADATAHAVE_CURRENT_DATA之间的区别是微不足道的。真正唯一相关的区别是在将视频元素绘制到画布上时,它区分了会绘制某些内容的情况(HAVE_CURRENT_DATA或更高)与不会绘制任何内容的情况(HAVE_METADATA或更低)。同样,HAVE_CURRENT_DATA(仅当前帧)和HAVE_FUTURE_DATA(至少当前帧和下一帧)之间的区别可能是微不足道的(在极端情况下,仅一个帧)。这种区别真正重要的唯一时间是页面提供“逐帧”导航接口时。

媒体元素networkState不为NETWORK_EMPTY时,其就绪状态发生变化时,用户代理必须按照以下步骤操作:

  1. 从以下列表中应用第一个适用的子步骤集:

    如果之前的就绪状态是HAVE_NOTHING,而新就绪状态是HAVE_METADATA

    排队一个媒体元素任务,将该媒体元素给定以触发一个名为loadedmetadata的事件。

    在此任务运行之前,作为事件循环机制的一部分,渲染将已更新以调整视频元素的大小(如果适用)。

    如果之前的就绪状态是HAVE_METADATA,而新就绪状态是HAVE_CURRENT_DATA或更高

    如果这是自上次调用load()算法以来首次发生这种情况,对于该媒体元素,用户代理必须排队一个媒体元素任务,给定媒体元素触发一个名为loadeddata的事件在该元素上。

    如果新就绪状态是HAVE_FUTURE_DATAHAVE_ENOUGH_DATA,则必须运行以下相关步骤。

    如果之前的就绪状态是HAVE_FUTURE_DATA或更高,而新就绪状态是HAVE_CURRENT_DATA或更低

    如果媒体元素readyState属性降至HAVE_FUTURE_DATA以下之前处于潜在播放状态,并且元素未结束播放,且播放未因错误停止因用户互动暂停因带内内容暂停,用户代理必须排队一个媒体元素任务,将该媒体元素给定以触发一个名为timeupdate的事件,并排队一个媒体元素任务,将该媒体元素给定以触发一个名为waiting的事件。

    如果之前的就绪状态是HAVE_CURRENT_DATA或更低,而新就绪状态是HAVE_FUTURE_DATA

    用户代理必须排队一个媒体元素任务,将该媒体元素给定以触发一个名为canplay的事件。

    如果元素的paused属性为 false,用户代理必须通知关于播放

    如果新就绪状态是HAVE_ENOUGH_DATA

    如果之前的就绪状态是HAVE_CURRENT_DATA或更低,用户代理必须排队一个媒体元素任务,将该媒体元素给定以触发一个名为canplay的事件,并且,如果元素的paused属性为 false,通知关于播放

    用户代理必须排队一个媒体元素任务,将该媒体元素给定以触发一个名为canplaythrough的事件。

    如果元素不符合自动播放条件,则用户代理必须中止这些子步骤。

    用户代理可以运行以下子步骤:

    1. paused属性设置为 false。
    2. 如果元素的显示海报标志为 true,将其设置为 false 并运行时间前进步骤。
    3. 排队一个媒体元素任务,将该元素给定以触发一个名为play的事件。
    4. 通知关于播放

    或者,如果元素是视频元素,用户代理可以开始观察元素是否与视口相交。当元素开始与视口相交时,如果元素仍然符合自动播放条件,运行上述子步骤。可选地,当元素停止与视口相交时,如果可自动播放标志仍然为真并且自动播放属性仍然指定,运行以下子步骤:

    1. 运行内部暂停步骤并将可自动播放标志设置为真。
    2. 排队一个媒体元素任务,将该元素给定以触发一个名为pause的事件。

    随着元素开始或停止与视口相交,播放和暂停的子步骤可以多次运行,只要可自动播放标志为真。

    用户代理不需要支持自动播放,建议用户代理尊重用户对该问题的偏好。建议作者使用自动播放属性而不是使用脚本强制视频播放,以便允许用户在需要时覆盖行为。

媒体元素的就绪状态可能会不连续地在这些状态之间跳跃。例如,媒体元素的状态可以直接从HAVE_METADATA跳到HAVE_ENOUGH_DATA,而不经过HAVE_CURRENT_DATAHAVE_FUTURE_DATA状态。

readyState IDL 属性在获取时必须返回上述描述的值,表示媒体元素的当前就绪状态。

autoplay属性是一个布尔属性。当存在时,用户代理(如本文中描述的算法所述)将自动开始播放媒体资源,只要它可以在不停止的情况下进行。

建议作者使用自动播放属性,而不是使用脚本触发自动播放,因为这允许用户在不需要时覆盖自动播放,例如使用屏幕阅读器时。作者还被鼓励考虑完全不使用自动播放行为,而是让用户代理等待用户显式启动播放。

HTMLMediaElement/autoplay

所有当前引擎支持。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

autoplay IDL 属性必须反映同名内容属性。

4.8.11.8 播放媒体资源
media.paused

HTMLMediaElement/paused

在所有当前引擎中支持。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

如果播放已暂停,则返回 true;否则返回 false。

media.ended

HTMLMediaElement/ended

在所有当前引擎中支持。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

如果播放已达到 媒体资源 的结束,则返回 true。

media.defaultPlaybackRate [ = value ]

HTMLMediaElement/defaultPlaybackRate

在所有当前引擎中支持。

Firefox20+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回默认的播放速率,用于用户未快进或倒退媒体时的播放。

可以设置此属性来更改默认的播放速率。

默认速率对播放没有直接影响,但如果用户切换到快进模式,当他们返回到正常播放模式时,预计播放速率将恢复为默认播放速率。

media.playbackRate [ = value ]

HTMLMediaElement/playbackRate

在所有当前引擎中支持。

Firefox20+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回当前的播放速率,其中 1.0 为正常速度。

可以设置此属性来改变播放速率。

media.preservesPitch

HTMLMediaElement/preservesPitch

Firefox101+Safari🔰 4+Chrome86+
Opera?Edge86+
Edge (旧版)?Internet Explorer没有
Firefox Android?Safari iOS🔰 4+Chrome Android?WebView Android?Samsung Internet?Opera Android?

如果使用了保持音调算法,当 playbackRate 不等于 1.0 时返回 true。默认值为 true。

可以设置为 false,使 媒体资源 的音频音调随 playbackRate 改变。这对审美和性能方面都有帮助。

media.played

返回一个 TimeRanges 对象,表示用户代理已播放的 媒体资源 的范围。

media.play()

HTMLMediaElement/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+

paused 属性设置为 false,如果需要的话,加载 媒体资源 并开始播放。如果播放已经结束,将从头开始重新播放。

media.pause()

HTMLMediaElement/pause

所有当前引擎均支持。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

paused 属性设置为 true,必要时加载 媒体资源

paused 属性表示 媒体元素 是否处于暂停状态。该属性初始值必须为 true。

如果 媒体元素readyState 属性处于 HAVE_NOTHING 状态、HAVE_METADATA 状态,或 HAVE_CURRENT_DATA 状态,或者如果该元素已被 用户交互暂停因带内内容暂停,则该媒体元素被称为 被阻塞的媒体元素

媒体元素paused 属性为 false,且元素没有 结束播放、播放没有 因错误停止,且元素不是 被阻塞的媒体元素 时,该媒体元素被称为 可能正在播放

如果 waiting DOM 事件 可能会触发,当一个 可能正在播放 的元素因其 readyState 属性的值变为低于 HAVE_FUTURE_DATA 时。

当以下所有条件都满足时,媒体元素 被认为是 符合自动播放条件

如果用户代理和系统允许在当前上下文中播放媒体,则 媒体元素 被认为是 允许播放

例如,用户代理可能只在 媒体元素Window 对象具有 临时激活 时允许播放,但可以做出例外,允许在 静音 时播放。

当以下条件满足时,媒体元素 被认为是 播放结束

ended 属性必须返回 true,如果在 事件循环 到达 步骤 1 时,媒体元素 处于 播放结束 状态且播放方向为向前,否则返回 false。

当以下条件满足时,媒体元素 被认为是 由于错误停止

元素的 readyState 属性为 HAVE_METADATA 或更高,并且用户代理在处理 媒体数据 时遇到 非致命错误,并且由于该错误,无法在 当前播放位置 播放内容。

媒体元素paused 属性为 false,且 readyState 属性为 HAVE_FUTURE_DATAHAVE_ENOUGH_DATA 时,并且用户代理已到达需要用户进行选择的 媒体资源 的一个点,以继续播放,则媒体元素被认为是 因用户交互暂停

一个 媒体元素 可以同时具有 播放结束因用户交互暂停 状态。

当一个 媒体元素 处于 可能播放 状态并且因 因用户交互暂停 而停止播放时,用户代理必须 排队一个媒体元素任务,以便 媒体元素 触发一个名为 timeupdate 的事件。

媒体元素paused 属性为 false,且 readyState 属性为 HAVE_FUTURE_DATAHAVE_ENOUGH_DATA 时,且用户代理已暂停 媒体资源 的播放,以播放时间上锚定到该资源且长度不为零的内容,或播放时间上锚定到该媒体资源的一段但长度大于该段的内容时,媒体元素被认为是 因带内内容暂停

一个 媒体元素 被认为是 因带内内容暂停 的一个例子是当用户代理正在播放来自外部 WebVTT 文件的 音频描述 时,而为某个提示生成的合成语音的时间长于 文本轨道提示开始时间文本轨道提示结束时间 之间的时间。


当前播放位置 达到 媒体资源 的末尾时,且 播放方向 为前向,用户代理必须遵循以下步骤:

  1. 如果 媒体元素 指定了 loop 属性,则 跳转最早可能的位置 并返回。

  2. 如上所述,ended IDL 属性将在 事件循环 返回到 步骤 1 时开始返回 true。

  3. 排队一个媒体元素任务,给定 媒体元素 和以下步骤:

    1. 触发一个事件,名为 timeupdate,在 媒体元素 上。

    2. 如果 媒体元素 已经 播放结束,且 播放方向 为前向,并且 paused 为 false,则:

      1. paused 属性设置为 true。

      2. 触发一个事件,名为 pause,在 媒体元素 上。

      3. 获取挂起的播放承诺拒绝挂起的播放承诺,结果和 AbortError DOMException

    3. 触发一个事件,名为 ended,在 媒体元素 上。

当前播放位置 达到 最早可能的位置媒体资源 时,如果 播放方向 为后向,则用户代理仅需 排队一个媒体元素任务,给定 媒体元素,以 触发一个事件,事件名为 timeupdate

这里的“达到”并不意味着 当前播放位置 必须在正常播放过程中发生变化;它也可以通过 跳转 进行变化。


defaultPlaybackRate 属性给出 媒体资源 播放的期望速度,作为其固有速度的倍数。该属性是可变的:在获取时必须返回最后设置的值,如果尚未设置则返回 1.0;在设置时,属性必须设置为新值。

用户代理在 向用户暴露用户界面 时使用 defaultPlaybackRate

playbackRate 属性给出有效的播放速率,即 媒体资源 播放的速度,作为其固有速度的倍数。如果它不等于 defaultPlaybackRate,则意味着用户正在使用诸如快进或慢动作播放等功能。该属性是可变的:在获取时必须返回最后设置的值,如果尚未设置则返回 1.0;在设置时,用户代理必须遵循以下步骤:

  1. 如果给定值不被用户代理支持,则抛出 NotSupportedError DOMException

  2. playbackRate 设置为新值,如果元素处于 可能正在播放 状态,则更改播放速度。

defaultPlaybackRateplaybackRate 属性值发生变化(无论是由脚本设置还是由用户代理直接更改,例如响应用户控制时),用户代理必须 排队一个媒体元素任务,给定 媒体元素,以 触发一个事件,事件名为 ratechange,在 媒体元素 上。用户代理必须平滑地处理属性更改,不能引入任何可感知的间隙或静音。

preservesPitch 的获取步骤是,如果在播放期间应用了保持音高的算法,则返回 true。设置步骤是相应地开启或关闭保持音高的算法,而不引入任何可感知的间隙或静音。默认情况下,必须启用这种保持音高的算法(即,获取器将初始返回 true)。


played 属性必须返回一个新的静态 规范化的 TimeRanges 对象,该对象表示通过通常的单调递增的 当前播放位置 在正常播放期间到达的 媒体时间轴 上的范围,如果有的话,在属性被评估时。

每次返回一个新对象是一种不良的属性获取器模式,仅在这里被保留,因为改变它会很麻烦。这不应被复制到新的 API 中。


每个 媒体元素 都有一个 待处理播放承诺的列表,该列表最初必须是空的。

获取待处理播放承诺 对于一个 媒体元素,用户代理必须执行以下步骤:

  1. promises 成为一个空的承诺列表。

  2. 媒体元素待处理播放承诺的列表 复制到 promises

  3. 清空 媒体元素待处理播放承诺的列表

  4. 返回 promises

解决待处理播放承诺 对于一个 媒体元素 和一个承诺列表 promises,用户代理必须用未定义值解决 promises 中的每个承诺。

拒绝待处理播放承诺 对于一个 媒体元素 和一个承诺列表 promises 及一个异常名称 error,用户代理必须用 error 拒绝 promises 中的每个承诺。

通知播放状态 对于一个 媒体元素,用户代理必须执行以下步骤:

  1. 获取待处理播放承诺 并将结果赋值给 promises

  2. 排队一个媒体元素任务 给定该元素和以下步骤:

    1. 触发一个事件 名为 playing 在该元素上。

    2. 解决待处理播放承诺 使用 promises

当对一个 媒体元素 调用 play() 方法时,用户代理必须执行以下步骤。

  1. 如果 媒体元素 不被 允许播放,则返回 一个被拒绝的承诺,拒绝原因是 "NotAllowedError" DOMException

  2. 如果 媒体元素error 属性不为 null 并且其 codeMEDIA_ERR_SRC_NOT_SUPPORTED,则返回 一个被拒绝的承诺,拒绝原因是 "NotSupportedError" DOMException

    这意味着 专用媒体源失败步骤 已经执行。播放在 媒体元素加载算法 清除 error 属性之前是不可能的。

  3. promise 成为一个新的承诺,并将 promise 添加到 待处理播放承诺的列表

  4. 执行 内部播放步骤 对于 媒体元素

  5. 返回 promise

对于一个 媒体元素内部播放步骤 如下:

  1. 如果 媒体元素networkState 属性的值为 NETWORK_EMPTY,则调用 媒体元素资源选择算法

  2. 如果 播放已结束播放方向 为前向,跳转到 媒体资源的最早可能位置

    这将导致用户代理 排队一个媒体元素任务 给定该 媒体元素,以 触发一个事件 名为 timeupdate 在该 媒体元素 上。

  3. 如果 媒体元素paused 属性为真,则:

    1. paused 的值更改为假。

    2. 如果 显示海报标志 为真,则将元素的 显示海报标志 设置为假,并执行 时间流逝 步骤。

    3. 排队一个媒体元素任务,给定媒体元素触发一个事件,名为play在该元素上。

    4. 如果 媒体元素readyState 属性的值为 HAVE_NOTHINGHAVE_METADATAHAVE_CURRENT_DATA,则 排队一个媒体元素任务 给定该 媒体元素,以 触发一个事件 名为 waiting 在该元素上。

      否则,媒体元素readyState 属性的值为 HAVE_FUTURE_DATAHAVE_ENOUGH_DATA通知播放情况

  4. 否则,如果 媒体元素readyState 属性的值为 HAVE_FUTURE_DATAHAVE_ENOUGH_DATA处理待处理的播放承诺 并且 排队一个媒体元素任务 给定该 媒体元素解决待处理的播放承诺

    媒体元素已经在播放。然而,promise 可能会在排队任务执行之前被 拒绝

  5. 媒体元素可以自动播放标志 设置为假。


当调用 pause() 方法时,并且当用户代理需要暂停 媒体元素, 用户代理必须执行以下步骤:

  1. 如果 媒体元素networkState 属性的值为 NETWORK_EMPTY, 调用 媒体元素资源选择算法

  2. 执行 内部暂停步骤 对于 媒体元素

一个 媒体元素内部暂停步骤 如下:

  1. 媒体元素可以自动播放标志 设置为假。

  2. 如果 媒体元素paused 属性为假,则执行以下步骤:

    1. paused 的值更改为真。

    2. 处理待处理的播放承诺 并让 promises 为结果。

    3. 排队一个媒体元素任务 给定该 媒体元素 和以下步骤:

      1. 触发一个事件 名为 timeupdate 在该元素上。

      2. 触发一个事件 名为 pause 在该元素上。

      3. 拒绝待处理的播放承诺 使用 promises 和一个 "AbortError" DOMException

    4. 官方播放位置 设置为 当前播放位置


如果元素的 playbackRate 是正值或零, 那么 播放方向 为前进。否则,为后退。

当一个 媒体元素 处于 可能正在播放 状态并且 其 文档 是 一个 完全活动的 文档, 其 当前播放位置 必须按照元素的 playbackRate 媒体时间单位每单位时间在 媒体时间轴 的时钟上单调增加。(该规范总是将其称为 增加,但这种增加实际上可能是 减少,如果元素的 playbackRate 是负数的话。)

元素的 playbackRate 可以是 0.0,在这种情况下,当前播放位置 不会移动, 尽管播放没有被暂停(paused 不会变为真,并且 pause 事件不会触发)。

该规范没有定义用户代理如何实现适当的播放速率——根据协议和可用媒体的不同,用户代理可能会与服务器协商,让服务器以适当的速率提供媒体数据,以便(除非在速率更改与服务器更新流的播放速率之间的时间段)客户端实际上不需要丢弃或插值任何帧。

每当用户代理 提供稳定状态 时, 官方播放位置 必须设置为 当前播放位置

播放方向 为后退时, 任何相应的音频必须是 静音。当元素的 playbackRate 低到用户代理无法有效播放音频的程度时,相应的音频也必须被 静音。 如果元素的 playbackRate 不为 1.0 并且 preservesPitch 为真,则用户代理必须应用音调调整以保持音频的原始音调。否则,用户代理必须加快或减慢音频播放而不进行音调调整。

当一个 媒体元素 处于 可能正在播放 状态时,其播放的音频数据必须与 当前播放位置 同步,并且使用元素的 有效媒体音量 播放。用户代理必须播放在 事件循环 上次达到 步骤 1 时已启用的音轨数据。

当一个 媒体元素 不处于 可能正在播放 状态时,该元素的音频不得播放。

媒体元素 在未 可能正在播放 且不在 文档中 时,不得播放任何视频,但应播放任何音频组件。媒体元素不得仅仅因为所有对它的引用已被移除而停止播放;只有当媒体元素处于一种状态,无法再播放任何音频时,该元素才能被垃圾回收。

即使对一个没有明确引用的元素,仍有可能播放音频,即使该元素不再积极播放:例如,它可能已被解除暂停但仍在等待内容缓冲,或者仍在缓冲中,但有一个 suspend 事件监听器开始播放。即使是一个 媒体资源 没有音轨的媒体元素,如果它有一个更改 媒体资源 的事件监听器,也可能会再次播放音频。


每个 媒体元素 有一个 新引入提示的列表,该列表初始为空。每当一个 文本轨道提示 被添加到 提示列表 中的 文本轨道,该 提示 必须被添加到 媒体元素新引入提示的列表 中。每当一个 文本轨道 被添加到 文本轨道列表 中的 媒体元素,该 文本轨道 中的所有 提示 必须被添加到 媒体元素新引入提示的列表 中。当 媒体元素新引入提示的列表 中有新提示被添加,而该 媒体元素显示海报标志 未被设置时,用户代理必须执行 时间继续前进 步骤。

当一个 文本轨道提示 从一个在 文本轨道列表 中的 文本轨道 中被移除时,以及每当一个 文本轨道文本轨道列表 中的 媒体元素 中被移除时,如果 媒体元素显示海报标志 未被设置时,用户代理必须执行 时间继续前进 步骤。

媒体元素当前播放位置发生变化时(例如由于播放或搜索),用户代理必须运行时间向前推进步骤。为了支持依赖提示事件触发时间精度的用例,例如将字幕与视频中的镜头变化同步,用户代理应尽可能接近媒体时间轴上的位置触发提示事件,理想情况下在20毫秒内。如果在步骤运行时当前播放位置发生变化,则用户代理必须等待步骤完成,然后必须立即重新运行这些步骤。因此,这些步骤尽可能或按需运行。

如果一个迭代耗时较长,这可能会导致短时长的 提示 被跳过,因为用户代理急于 "赶上",因此这些提示不会出现在 activeCues 列表中。

时间流逝”的步骤如下:

  1. current cues 成为一个提示的列表,初始化时包含所有 提示,这些提示来自所有 隐藏显示文本轨道媒体元素(不是 禁用的),其 开始时间 小于或等于 当前播放位置,其 结束时间 大于 当前播放位置

  2. other cues 成为一个提示的列表,初始化时包含所有 提示,这些提示来自 隐藏显示文本轨道媒体元素,这些提示不在 current cues 中。

  3. last time 成为在此算法最后一次运行时的 当前播放位置,如果这不是第一次运行。

  4. 如果 当前播放位置 自上次运行此算法以来,仅通过正常播放中的单调增加发生变化,则让 missed cues 成为在 other cues 中的 提示 列表,其 开始时间 大于或等于 last time,其 结束时间 小于或等于 当前播放位置。否则,让 missed cues 成为空列表。

  5. 移除 missed cues 中的所有 提示,这些提示也在 媒体元素新引入提示列表 中,然后清空该元素的 新引入提示列表

  6. 如果时间是通过 当前播放位置 在正常播放期间的单调增加达到的,并且用户代理在过去的15到250毫秒内没有在元素上触发过 timeupdate 事件,并且仍未处理此事件的事件处理程序,则用户代理必须 排队一个媒体元素任务,要求 媒体元素 在元素上触发一个名为 timeupdate 的事件。(在其他情况下,如显式跳转,相关事件会在改变 当前播放位置 的整个过程中触发。)

    因此,事件不会触发得比约66Hz快,或者比4Hz慢(假设事件处理程序的运行时间不超过250毫秒)。鼓励用户代理根据系统负载和每次处理事件的平均成本来调整事件的频率,以便UI更新的频率不会超过用户代理在解码视频时可以舒适处理的程度。

  7. 如果 current cues 中的所有 提示 都已设置其 文本轨道提示激活标志,且 other cues 中没有 提示 设置其 文本轨道提示激活标志,并且 missed cues 为空,则返回。

  8. 如果时间是通过 当前播放位置 在正常播放期间的单调增加达到的,并且 other cues 中有 提示,这些提示设置了 文本轨道提示退出时暂停标志,并且这些提示要么设置了 文本轨道提示激活标志,要么也在 missed cues 中,则 立即 暂停 媒体元素

    在其他情况下,例如显式跳转,即使该 提示 设置了 文本轨道提示退出时暂停标志,播放也不会因为超出提示的结束时间而暂停。

  9. events 成为一个初始为空的 任务 列表。此列表中的每个 任务 将与一个 文本轨道、一个 文本轨道提示 和一个时间相关联,这些信息用于在任务排队之前对列表进行排序。

    affected tracks 成为一个初始为空的 文本轨道 列表。

    当步骤下列指示为具有时间 time文本轨道提示 target 准备一个名为 event 的事件时,用户代理必须执行以下步骤:

    1. track 为与 文本轨道提示 target 关联的 文本轨道

    2. 创建一个 任务触发一个名为 event 的事件target

    3. 将新创建的 任务 添加到 events,并与时间 time文本轨道 track文本轨道提示 target 关联。

    4. track 添加到 affected tracks

  10. 对于missed cues中的每个文本轨道提示准备一个事件,名为enter,为TextTrackCue对象设置文本轨道提示开始时间

  11. 对于每个other cues中已设置其文本轨道提示活动标志或在missed cues中的文本轨道提示准备一个事件,名为exit,为TextTrackCue对象设置文本轨道提示结束时间文本轨道提示开始时间中较晚的时间。

  12. 对于每个current cues中未设置其文本轨道提示活动标志文本轨道提示准备一个事件,名为enter,为TextTrackCue对象设置文本轨道提示开始时间

  13. 按升序对 events 中的 任务 进行排序(较早时间的任务在前)。

    进一步对 events 中具有相同时间的 任务 按这些 文本轨道提示 关联的 文本轨道提示顺序 进行排序。

    最后,对 events 中具有相同时间和相同 文本轨道提示顺序任务 进行排序,将触发 enter 事件的任务放在触发 exit 事件的任务之前。

  14. 排队一个媒体元素任务,要求 媒体元素events 中的每个 任务,按列表顺序。

  15. 文本轨道媒体元素文本轨道列表 中出现的相同顺序对 affected tracks 进行排序,并移除重复项。

  16. 对于 affected tracks 中的每个 文本轨道,按列表顺序,排队一个媒体元素任务,要求 媒体元素 触发一个名为 cuechange 的事件,事件对象为 TextTrack 对象。如果 文本轨道 有一个对应的 track 元素,则同样触发一个名为 cuechange 的事件,事件对象为 track 元素。

  17. current cues 中所有 提示文本轨道提示激活标志 设置为激活状态,并将 other cues 中所有 提示文本轨道提示激活标志 取消设置。

  18. 按照 更新文本轨道渲染的规则affected tracks 中所有 文本轨道 进行处理,这些文本轨道处于 显示 状态,并提供 文本轨道文本轨道语言 作为备用语言(如果该语言不为空)。例如,对于基于 WebVTT 的 文本轨道,使用 WebVTT 文本轨道显示更新规则[WEBVTT]

对于上述算法的目的,只有当 文本轨道提示 列在 文本轨道提示列表 中时,才被认为是属于 文本轨道,而不仅仅是与 文本轨道 相关联。

如果 媒体元素节点文档 不再是 完全活动 文档,则播放将 停止,直到文档再次变为活动状态。

媒体元素Document 中移除 时,用户代理必须执行以下步骤:

  1. 等待稳定状态,允许移除 媒体元素任务 继续进行。同步部分 包含本算法的所有剩余步骤。(同步部分的步骤用 ⌛ 标记。)

  2. ⌛ 如果 媒体元素 仍然 在文档中,则返回。

  3. ⌛ 执行 内部暂停步骤

4.8.11.9 寻找
media.seeking

如果用户代理当前正在寻找,则返回 true。

media.seekable

HTMLMediaElement/seekable

所有当前引擎均支持。

Firefox8+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回一个 TimeRanges 对象,表示用户代理能够寻找到的 媒体资源 的范围。

media.fastSeek(time)

HTMLMediaElement/fastSeek

Firefox31+Safari8+Chrome
Opera?Edge
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

尽可能快速地寻找到接近给定 time 的位置,以速度换取精度。(要精确寻找到一个时间,请使用 currentTime 属性。)

如果媒体资源尚未加载,则不执行任何操作。

seeking 属性初始值必须为 false。

fastSeek(time) 方法必须 寻找到由 time 给定的时间, 并设置 approximate-for-speed 标志。

当用户代理需要 寻找到 媒体资源中的特定 new playback position 时, 可选择设置 approximate-for-speed 标志,这意味着用户代理必须执行以下步骤。该算法与 事件循环 机制紧密交互;特别是,它具有 一个 同步部分(作为 事件循环 算法的一部分触发)。该部分的步骤用 ⌛ 标记。

  1. 媒体元素显示海报标志设置为false。

  2. 如果媒体元素readyStateHAVE_NOTHING,则返回。

  3. 如果元素的seeking IDL属性为true,则表示此算法的另一个实例正在运行。终止该算法的另一个实例,而无需等待其运行的步骤完成。

  4. seeking IDL属性设置为true。

  5. 如果搜索是响应DOM方法调用或设置IDL属性,则继续脚本。其余步骤必须并行运行。除了标有⌛的步骤外,这些步骤随时可能被另一个实例调用而中止。

  6. 如果new playback position晚于媒体资源的末尾,则将其设为媒体资源的末尾。

  7. 如果new playback position小于最早可能的位置,则将其设为该位置。

  8. 如果(可能现在已更改的)new playback position不在seekable属性提供的范围之一内,则将其设为seekable属性提供的最接近new playback position的范围中的位置。如果两个位置都满足该约束(即new playback position正好位于seekable属性中的两个范围之间),则使用最接近当前播放位置的位置。如果seekable属性中没有给定范围,则将seeking IDL属性设置为false并返回。

  9. 如果设置了approximate-for-speed标志,则调整new playback position以允许快速恢复播放。如果此步骤之前的new playback position当前播放位置之前,则调整后的new playback position也必须在当前播放位置之前。同样,如果此步骤之前的new playback position当前播放位置之后,则调整后的new playback position也必须在当前播放位置之后。

    例如,用户代理可以捕捉到附近的关键帧,以便在恢复播放之前不必花时间解码然后丢弃中间帧。

  10. 排队一个媒体元素任务,给定媒体元素触发一个事件,名为seeking在该元素上。

  11. 当前播放位置设置为new playback position

    如果媒体元素在开始搜索之前是潜在播放状态,但搜索导致其readyState属性变为低于HAVE_FUTURE_DATA的值,则将在该元素上触发一个waiting事件

    此步骤设置当前播放位置,因此可以立即触发其他条件,例如播放何时达到媒体资源的末尾的规则(处理循环的一部分逻辑),即使在用户代理实际上能够渲染该位置的媒体数据之前(如下一步所确定)。

    currentTime属性返回官方播放位置,而不是当前播放位置,因此在脚本执行之前独立于此算法进行更新。

  12. 等待用户代理确定new playback position媒体数据是否可用,并且,如果可用,则等待它解码足够的数据以播放该位置。

  13. 等待一个稳定状态同步部分包括此算法的所有剩余步骤。(同步部分中的步骤标有⌛。)

  14. ⌛ 将seeking IDL属性设置为false。

  15. ⌛ 运行时间向前推进步骤。

  16. 排队一个媒体元素任务,给定媒体元素触发一个事件,名为timeupdate在该元素上。

  17. 排队一个媒体元素任务,给定媒体元素触发一个事件,名为seeked在该元素上。


seekable 属性必须返回一个新的静态 标准化的 TimeRanges 对象,表示用户代理能够寻找到的 媒体资源 的范围(如果有的话),在评估该属性时返回。

如果用户代理可以在 媒体资源 中的任意位置进行寻找到,例如,因为这是一个简单的电影文件且用户代理和服务器支持 HTTP Range 请求,那么属性将返回一个具有一个范围的对象,该范围的开始是第一个帧的时间(最早可能的位置,通常为零),结束时间是第一个帧的时间加上 duration 属性的值(这将等于最后一个帧的时间,可能为正无穷)。

该范围可能会不断变化,例如,如果用户代理在无限流上缓存滑动窗口。这在 DVR 观看直播电视时会看到。

每次返回一个新对象是属性获取器的一个糟糕模式,只在此处被铭记,因为改变它的成本很高。这不应被复制到新的 API 中。

用户代理应采取非常宽松和乐观的寻找到视图。用户代理还应在可能的情况下缓冲最近的内容,以使寻找到过程更快。

例如,考虑一个在没有 HTTP Range 请求支持的 HTTP 服务器上提供的大型视频文件。一个浏览器 可以 实现为只缓冲当前帧和获取后续帧的数据,从不允许寻找到,除了通过重启播放来寻找到开始。但是,这将是一个不好的实现。高质量的实现将缓冲最近几分钟的内容(或更多,如果有足够的存储空间),允许用户快速跳回并重新观看令人惊讶的内容而没有任何延迟,并且如果必要的话,还会允许通过从头开始重新加载文件来进行任意寻找到,这会更慢但仍然比仅仅重启视频并全部观看一遍来获取早期未缓冲的点更方便。

媒体资源 可能是内部脚本化的或交互式的。因此,一个 媒体元素 可能以非线性的方式播放。如果发生这种情况,用户代理必须在 寻找到 算法被使用时表现得好像当前播放位置 变化 是不连续的(以便相关事件被触发)。

4.8.11.10 具有多个媒体轨道的媒体资源

一个 媒体资源 可以包含多个嵌入的音频和视频轨道。例如,除了主要的视频和音频轨道外,一个 媒体资源 还可以包含外语配音、导演评论、音频描述、备用角度或手语覆盖层。

media.audioTracks

HTMLMediaElement/audioTracks

所有当前引擎均支持。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)NoInternet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回一个 AudioTrackList 对象,表示在 媒体资源 中可用的音频轨道。

media.videoTracks

HTMLMediaElement/videoTracks

所有当前引擎均支持。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)NoInternet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回一个 VideoTrackList 对象,表示在 媒体资源 中可用的视频轨道。

媒体元素audioTracks 属性必须返回一个 live AudioTrackList 对象,表示在 媒体元素媒体资源 中可用的音频轨道。

媒体元素videoTracks 属性必须返回一个 live VideoTrackList 对象,表示在 媒体元素媒体资源 中可用的视频轨道。

每个 媒体元素 只有一个 AudioTrackList 对象和一个 VideoTrackList 对象,即使另一个 媒体资源 被加载到元素中:这些对象会被重用。(不过,AudioTrackVideoTrack 对象则不会。)

4.8.11.10.1 AudioTrackListVideoTrackList 对象

AudioTrackList

支持所有当前的引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

VideoTrackList

支持所有当前的引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

AudioTrackList

支持所有当前的引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
caniuse.com 表格

AudioTrackListVideoTrackList 接口由前面章节中定义的属性使用。

AudioTrack

支持所有当前的引擎。

Firefox🔰 33+Safari8+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

VideoTrack

支持所有当前的引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
[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

AudioTrackList/length

支持所有当前引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
media.videoTracks.length

VideoTrackList/length

支持所有当前引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回列表中的轨道数量。

audioTrack = media.audioTracks[index]
videoTrack = media.videoTracks[index]

返回指定的 AudioTrackVideoTrack 对象。

audioTrack = media.audioTracks.getTrackById(id)

AudioTrackList/getTrackById

支持所有当前引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera? Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
videoTrack = media.videoTracks.getTrackById(id)

VideoTrackList/getTrackById

支持所有当前引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回具有给定标识符的 AudioTrackVideoTrack 对象,如果没有具有该标识符的轨道,则返回 null。

audioTrack.id

AudioTrack/id

支持所有当前引擎。

Firefox🔰 33+Safari8+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
videoTrack.id

VideoTrack/id

支持所有当前引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回给定轨道的 ID。如果格式支持 片段,并且可以与 getTrackById() 方法一起使用,则这是可使用的 ID。

audioTrack.kind

AudioTrack/kind

支持所有当前引擎。

Firefox🔰 33+Safari8+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
videoTrack.kind

VideoTrack/kind

支持所有当前引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回给定轨道所属的类别。下面给出了可能的轨道类别

audioTrack.label

AudioTrack/label

支持所有当前引擎。

Firefox🔰 33+Safari8+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
videoTrack.label

VideoTrack/label

支持所有当前引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回给定轨道的标签(如果已知),否则返回空字符串。

audioTrack.language

AudioTrack/language

支持所有当前引擎。

Firefox🔰 33+Safari8+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
videoTrack.language

VideoTrack/language

支持所有当前引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回给定轨道的语言(如果已知),否则返回空字符串。

audioTrack.enabled [ = value ]

AudioTrack/enabled

支持所有当前引擎。

Firefox🔰 33+Safari8+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

如果给定轨道处于活动状态,则返回 true,否则返回 false。

可以设置,以更改轨道是否已启用。如果同时启用多个音轨,则它们会混合。

media.videoTracks.selectedIndex

VideoTrackList/selectedIndex

支持所有当前引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回当前选定轨道的索引(如果有),否则返回 −1。

videoTrack.selected [ = value ]

VideoTrack/selected

支持所有当前引擎。

Firefox🔰 33+Safari7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

如果给定轨道处于活动状态,则返回 true,否则返回 false。

可以设置,以更改轨道是否已选择。可以选择零个或一个视频轨道;在选择新轨道时,取消选择先前的轨道。

一个 AudioTrackList 对象表示一个动态列表,包含零个或多个音轨,其中零个或多个可以同时启用。每个音轨由一个 AudioTrack 对象表示。

一个 VideoTrackList 对象表示一个动态列表,包含零个或多个视频轨道,其中每次只能选择零个或一个。每个视频轨道由一个 VideoTrack 对象表示。

AudioTrackListVideoTrackList 对象中的轨道必须保持一致的顺序。如果 媒体资源的格式定义了顺序,则必须使用该顺序;否则,顺序必须是轨道在媒体资源中声明的相对顺序。使用的顺序称为列表的自然顺序

因此,这些对象中的每个轨道都有一个索引;第一个索引为 0,每个后续轨道的编号比前一个高一。 如果 媒体资源动态添加或删除音轨或视频轨道,则轨道的索引将动态更改。如果媒体资源完全更改,则所有先前的轨道将被删除并替换为新轨道。

AudioTrackList lengthVideoTrackList length 属性的获取器必须返回其对象在获取时表示的轨道数量。

支持的属性索引 AudioTrackListVideoTrackList 对象在任何时刻的支持的属性索引是从零到各自对象表示的轨道数量减一的数字(如果表示任何轨道)。如果一个 AudioTrackListVideoTrackList 对象不表示任何轨道,则它没有 支持的属性索引

对于给定索引 indexAudioTrackListVideoTrackList 对象 list确定索引属性的值,用户代理必须返回表示list 中第index个轨道的 AudioTrackVideoTrack 对象。

AudioTrackList getTrackById(id)VideoTrackList getTrackById(id) 方法必须 返回在 AudioTrackListVideoTrackList 对象(分别)中的第一个 AudioTrackVideoTrack 对象(分别),其标识符等于 id 参数的值(如上定义的列表的自然顺序)。当没有轨道与给定参数匹配时,方法必须返回 null。

AudioTrackVideoTrack 对象表示 媒体资源的特定轨道。每个轨道可以有一个标识符、类别、标签和语言。 这些轨道的各个方面在轨道的生命周期内是永久的;即使从 媒体资源AudioTrackListVideoTrackList 对象中移除这些轨道,这些方面也不会改变。

此外, AudioTrack 对象可以启用或禁用;这是音轨的启用状态。创建 AudioTrack 时,其启用状态 必须设置为 false(禁用)。 资源获取算法可以覆盖此设置。

类似地,每个 VideoTrack 对象的 VideoTrackList 对象 中可以选择一个,这就是视频轨道的选择状态。创建 VideoTrack 时,其选择状态必须设置为 false(未选择)。 资源获取算法可以覆盖此设置。

AudioTrack idVideoTrack id 属性 必须返回轨道的标识符(如果有),否则返回空字符串。如果 媒体资源的格式支持媒体片段语法,则返回的特定轨道的标识符必须与使用该标识符作为该轨道在轨道维度中的名称时相同,从而启用该轨道片段[INBAND]

例如,在 Ogg 文件中,这将是轨道的 Name 头字段。 [OGGSKELETONHEADERS]

AudioTrack kindVideoTrack kind 属性 必须返回轨道的类别(如果有),否则返回空字符串。

轨道的类别是下表第一列中根据第二列和第三列中的定义最适合该轨道的字符串,如由媒体资源中的元数据确定。表中某一行第三列中的单元格说明了该行第一列中给定类别适用的对象;某个类别仅在适用于音轨时才适用于音轨,仅在适用于视频轨道时才适用于视频轨道。类别必须仅返回 AudioTrack 对象,如果它们适用于音频,并且必须仅返回 VideoTrack 对象,如果它们适用于视频。

对于 Ogg 文件,轨道的 Role 头字段提供了相关元数据。对于 DASH 媒体资源, Role 元素传达了信息。对于 WebM,目前只有 FlagDefault 元素映射到一个值。从媒体容器到 HTML 的带内媒体资源轨道的来源有更多细节。 [OGGSKELETONHEADERS] [DASH] [WEBMCG] [INBAND]

AudioTrackkindVideoTrackkind 返回值
类别 定义 适用于... 示例
"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 labelVideoTrack label 属性必须返回轨道的标签(如果有),否则返回空字符串。 [INBAND]

AudioTrack languageVideoTrack 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 事件的任务(如果有)。

媒体时间轴上没有特定位置数据的视频轨道必须在该时间点上被解释为 透明黑色, 具有与该位置之前的最后一帧相同的尺寸,或者如果位置在该轨道的所有数据之前,则具有该轨道第一帧的尺寸。当前位置根本不存在的轨道必须被视为存在但没有数据。

例如,如果一个视频有一个在播放一个小时后才引入的轨道,并且用户选择该轨道然后返回到开始位置,则用户代理将表现得像该轨道从媒体资源的开始处开始,但只是在一小时内透明。


以下是 事件处理程序(及其对应的事件处理程序事件类型),这些处理程序必须由所有实现 AudioTrackListVideoTrackList 接口的对象支持,作为 事件处理程序 IDL 属性:

事件处理程序 事件处理程序事件类型
onchange

AudioTrackList/change_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/change_event

支持所有当前引擎。

Firefox31+Safari7+Chrome33+
Opera?Edge79+
Edge (旧版)18Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android4.4+Samsung Internet?Opera Android?

VideoTrackList/change_event

支持所有当前引擎。

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

AudioTrackList/addtrack_event

支持所有当前引擎。

Firefox🔰 33+Safari 7+Chrome🔰 37+
Opera?Edge🔰 79+
Edge (旧版)不支持Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

TextTrackList/addtrack_event

支持所有当前引擎。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

VideoTrackList/addtrack_event

支持所有当前引擎。

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
4.8.11.10.2 以声明方式选择特定的音频和视频轨道

audioTracksvideoTracks 属性允许脚本选择应该播放的轨道,但也可以通过在片段中指定特定轨道,以声明方式选择特定轨道 ,即通过指定URL媒体资源片段的格式取决于MIME类型[RFC2046] [URL]

在这个例子中,一个使用支持媒体片段语法 的格式的视频被嵌入,以便启用标记为“Alternative”的替代角度,而不是默认的视频轨道。

<video src="myvideo#track=Alternative"></video>
4.8.11.11 定时文本轨迹
4.8.11.11.1 文本轨迹模型

媒体元素可以有一组相关的文本轨迹,称为媒体元素文本轨迹列表文本轨迹按以下顺序排序:

  1. 对应于track元素子元素的文本轨迹,在媒体元素树顺序中。

  2. 使用addTextTrack()方法添加的任何文本轨迹,按添加顺序排列,最早的在前。

  3. 任何特定于媒体资源的文本轨迹文本轨迹对应于媒体资源中的数据),按媒体资源的格式规范中定义的顺序排列。

文本轨迹包括:

文本轨迹的类型

这决定了用户代理如何处理轨迹。类型由一个字符串表示。可能的字符串包括:

在对应于文本轨迹track元素的情况下,轨迹类型可以动态更改。

标签

这是一个人类可读的字符串,用于识别轨迹。

在对应于文本轨迹track元素的情况下,轨迹的标签可以动态更改。

文本轨迹标签为空字符串时,用户代理应自动从文本轨迹的其他属性(例如文本轨迹的类型和语言)生成一个适当的标签,以在其用户界面中使用。此自动生成的标签不会在API中公开。

带内元数据轨迹调度类型

这是从媒体资源中提取的一个字符串,专门用于带内元数据轨迹,以便将这些轨迹分派给文档中的不同脚本。

例如,传统电视台的网络直播,配有网页特定的互动功能,可以包含带有广告定位、游戏节目期间的问答游戏数据、体育比赛中的玩家状态、烹饪节目的食谱信息等元数据的文本轨迹。随着每个节目开始和结束,新的轨迹可能会被添加或从流中移除,当每个轨迹被添加时,用户代理可以使用此属性的值将其绑定到专用的脚本模块。

除了带内元数据文本轨迹之外,带内元数据轨迹调度类型为空字符串。如何为不同媒体格式填充此值在暴露特定媒体资源文本轨迹的步骤中进行了描述。

语言

这是一个表示文本轨迹提示语言的字符串(BCP 47语言标签)。[BCP47]

在对应于文本轨迹track元素的情况下,文本轨迹的语言可以动态更改。

准备状态

以下之一:

未加载

表示文本轨迹的提示尚未获取。

正在加载

表示文本轨迹正在加载,目前尚未遇到致命错误。解析器可能仍会向轨迹添加更多提示。

已加载

表示文本轨迹已加载且没有致命错误。

加载失败

表示文本轨迹已启用,但用户代理尝试获取它时失败(例如,URL无法解析,网络错误,未知的文本轨迹格式)。一些或所有提示可能丢失,且不会被获取。

文本轨迹的准备状态在轨迹获取过程中动态变化。

模式

以下之一:

禁用

表示文本轨迹未激活。除了在DOM中暴露轨迹之外,用户代理将忽略文本轨迹。没有提示激活,没有事件触发,用户代理不会尝试获取轨迹的提示。

隐藏

表示文本轨迹已激活,但用户代理未主动显示提示。如果尚未尝试获取轨迹的提示,用户代理将立即尝试。用户代理维护一个活跃提示的列表,并相应触发事件。

显示

表示文本轨道是活跃的。如果尚未尝试获取轨道的提示,用户代理将立即进行此尝试。用户代理正在维护一个列表,记录哪些提示是活跃的,并相应地触发事件。此外,对于类型字幕标题的文本轨道,提示适当地叠加在视频上;对于类型描述的文本轨道,用户代理以非视觉方式向用户提供提示;对于类型章节的文本轨道,用户代理提供一种机制,使用户可以通过选择提示在媒体资源中的任何一点进行导航。

一个或多个提示的列表

一个文本轨迹提示的列表,以及更新文本轨迹渲染的规则。例如,对于WebVTT,更新WebVTT文本轨迹显示的规则。[WEBVTT]

文本轨迹的提示列表可以动态更改,因为文本轨迹尚未加载或仍在加载,或由于DOM操作。

每个文本轨迹都有一个对应的TextTrack对象。


每个媒体元素都有一个待处理文本轨迹列表,该列表必须最初为空,还有一个被解析器阻塞标志,该标志必须最初为假,以及一个是否执行了自动轨迹选择标志,该标志也必须最初为假。

当用户代理需要填充待处理文本轨迹列表时,用户代理必须将元素的待处理文本轨迹列表中添加每个文本轨迹,这些文本轨迹在元素的文本轨迹列表中,其文本轨迹模式不是禁用的,并且其文本轨迹准备状态加载中

每当一个track元素的父节点发生变化时,用户代理必须从它所在的任何待处理文本轨迹列表中移除相应的文本轨迹

每当一个文本轨迹文本轨迹准备状态变为已加载加载失败时,用户代理必须从它所在的任何待处理文本轨迹列表中移除它。

当一个媒体元素HTML 解析器XML 解析器创建时,用户代理必须将该元素的被解析器阻塞标志设置为真。当一个媒体元素打开元素栈中弹出时,用户代理必须尊重用户对自动文本轨迹选择的偏好填充待处理文本轨迹列表,并将元素的被解析器阻塞标志设置为假。

当一个媒体元素待处理文本轨迹列表为空且元素的被解析器阻塞标志为假时,该媒体元素的文本轨迹被认为是准备好的

每个媒体元素都有一个待处理文本轨迹更改通知标志,该标志最初未设置。

每当一个文本轨迹,它在一个媒体元素文本轨迹列表中,其文本轨迹模式发生变化时,用户代理必须对该媒体元素执行以下步骤:

  1. 如果媒体元素待处理文本轨迹更改通知标志被设置,返回。

  2. 设置媒体元素待处理文本轨迹更改通知标志

  3. 队列一个媒体元素任务,使该媒体元素执行以下步骤:

    1. 取消设置媒体元素待处理文本轨迹更改通知标志

    2. 触发一个事件,事件名称为change,该事件发给媒体元素textTracks属性的TextTrackList对象。

  4. 如果媒体元素显示海报标志未设置,执行时间继续步骤。

本节中列出的任务源任务DOM 操作任务源


一个文本轨迹提示文本轨迹中的时间敏感数据单元,例如对于字幕和标题,表示在特定时间出现并在另一个时间消失的文本。

每个文本轨迹提示包括:

标识符

一个任意字符串。

开始时间

以秒和秒的分数表示的时间,描述提示适用的媒体数据范围的开始。

结束时间

以秒和秒的分数表示的时间,描述提示适用的媒体数据范围的结束,或者对于一个无限制文本轨迹提示,表示正无穷大。

暂停退出标志

一个布尔值,指示在达到提示适用的范围结束时是否暂停播放媒体资源

一些附加格式特定数据

根据格式的需要,包含提示的实际数据的附加字段。例如,WebVTT 有一个文本轨迹提示书写方向等。[WEBVTT]

一个无限制文本轨迹提示是一个文本轨迹提示,其文本轨迹提示结束时间设置为正无穷大。一个活跃的无限制文本轨迹提示无法通过正常播放过程中当前播放位置的单调增加变为不活动(例如,在一个没有宣布结束时间的实时事件中的章节元数据提示)。

文本轨迹提示开始时间文本轨迹提示结束时间可以为负值。(虽然当前播放位置永远不能为负值,因此完全在时间零之前的提示不能处于活动状态。)

每个文本轨迹提示都有一个对应的TextTrackCue对象(更具体地说,是一个继承自TextTrackCue的对象——例如,WebVTT提示使用VTTCue接口)。一个文本轨迹提示的内存表示可以通过此TextTrackCue API 动态更改。[WEBVTT]

一个文本轨迹提示更新文本轨迹渲染的规则相关联,这些规则由特定类型的文本轨迹提示规范定义。这些规则在表示提示的对象通过TextTrack对象的addCue()方法添加到该对象时特别使用。

此外,每个文本轨迹提示有两项动态信息:

活动标志

该标志必须最初未设置。此标志用于确保在提示变为活跃或不活跃时适当地触发事件,并确保正确的提示被渲染。

每当文本轨道提示从其文本轨道文本轨道提示列表中移除时;每当文本轨道本身从其媒体元素文本轨道列表中移除时,或其文本轨道模式更改为禁用时;以及每当媒体元素readyState更改回HAVE_NOTHING时,用户代理必须同步取消设置此标志。当对于在相关事件发生前正在显示文本轨道中的一个或多个提示以这种方式取消设置标志后,用户代理必须在为所有受影响的提示取消设置标志后,应用这些文本轨道文本轨道渲染更新规则。例如,对于基于WebVTT的文本轨道WebVTT文本轨道显示更新规则[WEBVTT]

显示状态

这作为渲染模型的一部分,用于保持提示的一致位置。它必须最初为空。每当文本轨迹提示活动标志被取消设置时,用户代理必须清空文本轨迹提示显示状态

文本轨迹提示的排序在媒体元素文本轨迹中相对彼此进行,这一排序方式如下确定:首先按照文本轨迹提示进行分组,分组的顺序与其在媒体元素文本轨迹列表中出现的顺序相同;然后,在每组内,提示必须按照其开始时间进行排序,最早的时间优先;接着,任何具有相同开始时间提示必须按照其结束时间进行排序,最晚的时间优先;最后,任何具有相同结束时间提示必须按照其最后添加到各自的文本轨迹提示列表的顺序进行排序,最旧的优先(例如,对于来自WebVTT文件的提示,这最初将是提示在文件中列出的顺序)。[WEBVTT]

4.8.11.11.2 嵌入式文本轨迹的来源

媒体资源特定文本轨迹是一个文本轨迹,对应于在媒体资源中找到的数据。

处理和渲染此类数据的规则由相关规范定义,例如,如果媒体资源是视频,则由视频格式规范定义。一些遗留格式的详细信息可以在从媒体容器中获取嵌入式媒体资源轨迹到HTML中找到。[INBAND]

媒体资源包含用户代理识别并支持作为文本轨迹的数据时,用户代理将执行暴露媒体资源特定文本轨迹的步骤,如下所示。

  1. 将相关数据与新的文本轨迹及其对应的新TextTrack对象关联。该文本轨迹媒体资源特定文本轨迹

  2. 根据相关规范定义的数据语义设置新的文本轨迹类型标签语言。如果数据中没有标签,则标签必须设置为空字符串。

  3. 文本轨迹提示列表与适用于该格式的文本轨迹渲染更新规则关联。

  4. 如果新的文本轨迹类型章节元数据,则根据媒体资源的类型设置文本轨迹嵌入式元数据轨迹分派类型,如下:

    如果媒体资源是Ogg文件
    文本轨迹嵌入式元数据轨迹分派类型必须设置为Name头字段的值。[OGGSKELETONHEADERS]
    如果媒体资源是WebM文件
    文本轨迹嵌入式元数据轨迹分派类型必须设置为CodecID元素的值。[WEBMCG]
    如果媒体资源是MPEG-2文件
    stream type为文件程序映射部分中描述文本轨迹类型的"stream_type"字段的值,解释为8位无符号整数。令length为相同部分中的"ES_info_length"字段的值,解释为动态图像和相关音频信息的通用编码中定义的整数。令descriptor bytes为"ES_info_length"字段之后的length字节。文本轨迹嵌入式元数据轨迹分派类型必须设置为stream type字节和零个或多个descriptor bytes字节的串联,使用十六进制表示,采用ASCII大写十六进制数字
    如果媒体资源是MPEG-4文件
    令第一个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字段的值,如果该字段在该盒子中缺失,则为空字符串。
  5. 用解析出的提示填充新的文本轨迹提示列表,遵循暴露提示的指南,并根据需要动态更新它。

  6. 将新的文本轨迹准备状态设置为已加载

  7. 将新的文本轨迹模式设置为与用户的偏好和相关规范要求的数据一致的模式。

    例如,如果没有其他激活的字幕,并且这是一个强制字幕轨迹(提供音频轨迹的主要语言的字幕,但仅限于实际使用另一种语言的音频),则可以在此处激活这些字幕。

  8. 将新的文本轨迹添加到媒体元素文本轨迹列表中。

  9. 触发事件,事件名称为addtrack,在媒体元素textTracks属性的TextTrackList对象上,使用TrackEvent,其中track属性初始化为文本轨迹TextTrack对象。

4.8.11.11.3 外部文本轨迹的来源

当创建一个track元素时,它必须与一个新的文本轨迹(其值设置如下所定义)及其相应的新TextTrack对象关联。

文本轨迹类型由元素的kind属性的状态确定,依据下表;对于第一列中的状态,类型是第二列中给定的字符串:

状态 字符串
Subtitles subtitles
Captions captions
Descriptions descriptions
Chapters metadata chapters
Metadata metadata

文本轨迹标签是元素的轨迹标签

文本轨迹语言是元素的轨迹语言(如果有的话),否则为空字符串。

随着kindlabelsrclang属性的设置、更改或删除,文本轨迹必须相应地更新,如上定义。

轨迹URL的更改在下面的算法中处理。

文本轨迹准备状态最初是未加载文本轨迹模式最初是禁用

文本轨迹提示列表最初为空。解析引用文件时会动态修改它。与列表关联的是适用于该格式的文本轨迹渲染更新规则;对于WebVTT,这是更新WebVTT文本轨迹显示的规则[WEBVTT]

track元素的父元素发生变化并且新父元素是媒体元素时,用户代理必须将track元素的相应文本轨迹添加到媒体元素文本轨迹列表中,然后将媒体元素任务排入队列,给定媒体元素触发一个事件,事件名为addtrack,在媒体元素textTracks属性的TextTrackList对象上,使用TrackEvent,其中track属性初始化为文本轨迹TextTrack对象。

track元素的父元素发生变化并且旧父元素是媒体元素时,用户代理必须将track元素的相应文本轨迹媒体元素文本轨迹列表中移除,然后将媒体元素任务排入队列,给定媒体元素触发一个事件,事件名为removetrack,在媒体元素textTracks属性的TextTrackList对象上,使用TrackEvent,其中track属性初始化为文本轨迹TextTrack对象。


当一个文本轨迹对应一个track元素被添加到媒体元素文本轨迹列表时,用户代理必须将媒体元素任务排入队列,给定媒体元素,按以下步骤运行媒体元素

  1. 如果元素的被解析器阻塞标志为真,则返回。

  2. 如果元素的已执行自动轨迹选择标志为真,则返回。

  3. 尊重用户对自动文本轨迹选择的偏好

当用户代理需要为媒体元素尊重用户对自动文本轨迹选择的偏好时,用户代理必须运行以下步骤:

  1. subtitlescaptions执行自动文本轨迹选择

  2. descriptions执行自动文本轨迹选择

  3. 如果在媒体元素文本轨迹列表中有任何文本轨迹,其文本轨迹类型chaptersmetadata,并且其对应的track元素设置了default属性,其文本轨迹模式设置为禁用,则将所有此类轨迹的文本轨迹模式设置为隐藏

  4. 将元素的已执行自动轨迹选择标志设置为真。

当上述步骤要求为一个或多个文本轨迹类型执行自动文本轨迹选择时,意味着运行以下步骤:

  1. candidates媒体元素文本轨迹列表中,文本轨迹的类型是传递给算法的类型之一(如果有),按文本轨迹列表中给定的顺序。

  2. 如果candidates为空,则返回。

  3. 如果candidates中的任何文本轨迹文本轨迹模式设置为显示,则返回。

  4. 如果用户根据其文本轨迹类型文本轨迹语言文本轨迹标签表达了希望启用candidates中的轨迹的意愿,则将其文本轨迹模式设置为显示

    例如,用户可以设置浏览器偏好,如“我希望在任何可能的情况下启用法语字幕”,或者“如果有标题中包含‘评论’的字幕轨迹,启用它”,或者“如果有音频描述轨迹可用,启用一个,最好是瑞士德语,但如果没有,则启用标准瑞士德语或标准德语”。

    否则,如果candidates中有任何文本轨迹,其对应track元素设置了default属性,并且其文本轨迹模式设置为禁用,则将第一个这样的轨迹的文本轨迹模式设置为显示

当一个文本轨迹对应一个track元素经历以下任何情况时,用户代理必须启动track处理模型,用于该文本轨迹及其track元素:

当用户代理启动track处理模型时,为文本轨迹及其track元素,它必须运行以下算法。此算法与事件循环机制密切互动;特别是,它有一个同步部分(在事件循环算法的一部分触发)。该部分的步骤标有⌛。

  1. 如果此算法的另一个实例已经在为该文本轨迹及其track元素运行,则返回,让另一个算法处理该元素。

  2. 如果文本轨迹文本轨迹模式未设置为隐藏显示,则返回。

  3. 如果文本轨迹track元素没有一个媒体元素作为父元素,则返回。

  4. 在允许导致这些步骤运行的情况下,并行运行剩余步骤。

  5. 顶部等待稳定状态同步部分包括以下步骤。(同步部分的步骤标有⌛。)

  6. ⌛将文本轨迹准备状态设置为加载中

  7. ⌛令URLtrack元素的轨迹URL

  8. ⌛如果track元素的父元素是媒体元素,则令corsAttributeState为父媒体元素crossorigin内容属性的状态。否则,令corsAttributeState无CORS

  9. 结束同步部分并行继续剩余步骤。

  10. 如果URL不为空字符串,则:

    1. request创建一个潜在的CORS请求的结果,给定URL、“track”和corsAttributeState,并设置同源回退标志

    2. request客户端设置为track元素的节点文档相关设置对象

    3. request启动器类型设置为“track”。

    4. 获取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元素上。

  11. 等待,直到文本轨迹准备状态不再设置为加载中

  12. 等待,直到轨迹URL不再等于URL,同时文本轨迹模式设置为隐藏显示

  13. 跳到标记为顶部的步骤。

每当track元素的src属性被设置、更改或删除时,用户代理必须立即清空该元素的文本轨迹文本轨迹提示列表。(这也会导致上面的算法停止从以前给定的URL获取的资源中添加提示,如果有的话。)

4.8.11.11.4 在各种格式中暴露提示的指南作为文本轨迹提示

特定格式的文本轨迹提示如何解释,以便由HTML用户代理进行处理,由该格式定义。在缺乏此类规范的情况下,本节提供了一些限制,以便实现可以尝试一致地暴露这些格式。

为了支持文本轨迹模型, 每个定时数据单元被转换为一个 文本轨迹提示。 当 格式的特性与文本轨迹提示的 方面在本规范中没有定义时,实现必须 确保映射与上述文本轨迹提示的 方面的定义一致,并符合以下限制:

文本轨迹提示标识符

如果格式没有明显的类似物,应设置为空字符串。

文本轨迹提示退出时暂停标志

应设置为false。

4.8.11.11.5 文本轨道 API

TextTrackList

在所有当前引擎中都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
[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

HTMLMediaElement/textTracks

在所有当前引擎中都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet1.0+Opera Android12.1+

返回与 媒体元素(例如 track 元素)关联的 文本轨道 的数量。这是 媒体元素文本轨道列表中的文本轨道数量。

media.textTracks[ n ]

返回表示 n文本轨道TextTrack 对象,位于 媒体元素文本轨道列表中。

textTrack = media.textTracks.getTrackById(id)

TextTrackList/getTrackById

在所有当前引擎中都支持。

Firefox31+Safari8+Chrome33+
Opera?Edge79+
Edge (旧版)18Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回具有给定标识符的 TextTrack 对象,如果没有该标识符的轨道,则返回 null。

TextTrackList 对象表示一个动态更新的 文本轨道 列表,按给定的顺序排列。

textTracks 属性的 媒体元素 必须 返回一个 TextTrackList 对象,表示 TextTrack 对象 作为 文本轨道媒体元素文本轨道列表 中,顺序与 文本轨道列表 中的顺序相同。

TextTrackList/length

在所有当前引擎中都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

length 属性的 TextTrackList 对象必须返回列表中 文本轨道 的数量,该列表由 TextTrackList 对象表示。

一个 TextTrackList 对象在任何时刻的 支持的属性索引 是从零到 文本轨道 数量减一(如果有的话)的数字。如果列表中没有 文本轨道,则没有 支持的属性索引

确定一个索引属性的值 在给定索引 index 的情况下,用户代理必须返回在 TextTrackList 对象表示的列表中第 index文本轨道

getTrackById(id) 方法必须 返回 TextTrack 对象中第一个其 id IDL 属性返回的值等于 id 参数值的轨道。当没有轨道与给定的参数匹配时,该方法必须返回 null。


TextTrack

在所有当前引擎中支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android31+Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
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 对象, 该对象还会被添加到 媒体元素文本轨道列表 中。

textTrack.kind

TextTrack/kind

在所有当前引擎中都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 文本轨道类型 字符串。

textTrack.label

TextTrack/label

在所有当前引擎中都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 文本轨道标签,如果存在,否则返回空字符串(表示可能需要从对象的其他属性生成自定义标签,如果对象暴露给用户)。

textTrack.language

TextTrack/language

在所有当前引擎中都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 文本轨道语言 字符串。

textTrack.id

TextTrack/id

在所有当前引擎中都支持。

Firefox31+Safari8+Chrome33+
Opera?Edge79+
Edge (旧版)18Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回给定轨道的 ID。

对于带内轨道,这是可以与 片段 一起使用的 ID(如果格式支持 媒体片段语法),并且可以与 getTrackById() 方法一起使用。

对于与 TextTrack 对象对应的 track 元素,这是 track 元素的 ID。

textTrack.inBandMetadataTrackDispatchType

TextTrack/inBandMetadataTrackDispatchType

Firefox31+Safari8+Chrome不支持
Opera?Edge不支持
Edge (旧版)不支持Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回 文本轨道带内元数据调度类型 字符串。

textTrack.mode [ = value ]

TextTrack/mode

在所有当前引擎中都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android31+Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 文本轨道模式,表示为以下列表中的一个字符串:

"disabled"

文本轨道禁用 模式。

"hidden"

文本轨道隐藏 模式。

"showing"

文本轨道显示 模式。

可以设置来更改模式。

textTrack.cues

TextTrack/cues

在所有当前引擎中都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 文本轨道提示列表,作为 TextTrackCueList 对象。

textTrack.activeCues

TextTrack/activeCues

在所有当前引擎中都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android31+Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回一个包含当前活动的 文本轨道提示文本轨道提示列表TextTrackCueList 对象。

textTrack.addCue(cue)

TextTrack/addCue

在所有当前引擎中都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

将给定提示添加到 textTrack文本轨道提示列表 中。

textTrack.removeCue(cue)

TextTrack/removeCue

在所有当前引擎中都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

textTrack文本轨道提示列表 中删除给定提示。

媒体元素addTextTrack(kind, label, language) 方法被调用时,必须运行以下步骤:

  1. 创建一个新的 TextTrack 对象。

  2. 创建一个与新对象对应的新 文本轨道,并将其 文本轨道类型 设置为 kind,其 文本轨道标签 设置为 label,其 文本轨道语言 设置为 language,其 文本轨道就绪状态 设置为 文本轨道已加载 状态,其 文本轨道模式 设置为 文本轨道隐藏 模式,其 文本轨道提示列表 设置为空列表。

    最初,文本轨道提示列表 与任何 更新文本轨道渲染的规则 无关。当向其中添加 文本轨道提示 时, 文本轨道提示列表 永久设置其规则。

  3. 将新 文本轨道 添加到 媒体元素文本轨道列表 中。

  4. 排队一个媒体元素任务,给定 媒体元素触发一个事件,该事件名为 addtrack,并在 媒体元素textTracks 属性的 TextTrackList 对象上, 使用 TrackEvent, 其 track 属性初始化为新 文本轨道TextTrack 对象。

  5. 返回新的 TextTrack 对象。


kind 属性必须返回 文本轨道类型,该 文本轨道TextTrack 对象表示。

label 属性必须返回 文本轨道标签,该 文本轨道TextTrack 对象表示。

language 属性必须返回 文本轨道语言,该 文本轨道TextTrack 对象表示。

id 属性返回轨道的标识符(如果有的话),否则返回空字符串。对于与 track 元素对应的轨道,轨道的标识符是元素的 id 属性的值(如果有的话)。对于带内轨道,轨道的标识符由 媒体资源 指定。如果 媒体资源 是支持 媒体片段语法 的格式,返回的特定轨道的标识符必须与作为此类 片段 轨道维度的轨道名称时会启用该轨道的标识符相同。

inBandMetadataTrackDispatchType 属性必须返回 文本轨道带内元数据调度类型,该 文本轨道TextTrack 对象表示。

mode 属性在获取时,必须返回与 文本轨道模式 相对应的字符串,该 文本轨道TextTrack 对象表示,如下列表所定义:

"disabled"
文本轨道禁用 模式。
"hidden"
文本轨道隐藏 模式。
"showing"
文本轨道显示 模式。

在设置时,如果新值不等于属性当前返回的值,则必须按如下步骤处理新值:

如果新值是 "disabled"

文本轨道模式 设置为 文本轨道,由 TextTrack 对象表示,并设置为 文本轨道禁用 模式。

如果新值是 "hidden"

文本轨道模式 设置为 文本轨道,由 TextTrack 对象表示,并设置为 文本轨道隐藏 模式。

如果新值是 "showing"

文本轨道模式 设置为 文本轨道,由 TextTrack 对象表示,并设置为 文本轨道显示 模式。

如果 文本轨道模式文本轨道,由 TextTrack 对象表示,不是 文本轨道禁用 模式,则 cues 属性必须返回一个 实时的 TextTrackCueList 对象,该对象表示 文本轨道提示列表 的子集,列表中的 文本轨道TextTrack 对象表示,其 结束时间 发生在脚本开始时的 最早可能位置 或之后,按 文本轨道提示顺序 排列。否则,必须返回 null。对于每个 TextTrack 对象,当返回一个对象时,每次都必须返回相同的 TextTrackCueList 对象。

脚本开始时的最早可能位置 是上次 事件循环 达到步骤 1 时的 最早可能位置

如果 文本轨道模式文本轨道,由 TextTrack 对象表示,不是 文本轨道禁用 模式,则 activeCues 属性必须返回一个 实时的 TextTrackCueList 对象,该对象表示 文本轨道提示列表 的子集,列表中的 文本轨道TextTrack 对象表示,其 脚本开始时的活动标志已设置,按 文本轨道提示顺序 排列。否则,必须返回 null。对于每个 TextTrack 对象,当返回一个对象时,每次都必须返回相同的 TextTrackCueList 对象。

如果 文本轨道提示脚本开始时活动标志已设置,则表示其 文本轨道提示活动标志 在上次 事件循环 达到 步骤 1 时已设置。


addCue(cue) 方法在 TextTrack 对象中被调用时,必须运行以下步骤:

  1. 如果 文本轨道提示列表 还没有任何关联的 更新文本轨道渲染的规则,则将 文本轨道提示列表 与适用于 cue更新文本轨道渲染的规则 相关联。

  2. 如果 文本轨道提示列表 关联的 更新文本轨道渲染的规则 与适用于 cue更新文本轨道渲染的规则 不相同,则抛出 "InvalidStateError" DOMException

  3. 如果给定的 cue文本轨道提示列表 中,则将 cue 从该 文本轨道提示列表 中移除。

  4. cue 添加到 TextTrack 对象的 文本轨道文本轨道提示列表 中。

removeCue(cue) 方法在 TextTrack 对象中被调用时,必须运行以下步骤:

  1. 如果给定的 cue 不在 TextTrack 对象的 文本轨道文本轨道提示列表 中,则抛出 "NotFoundError" DOMException

  2. TextTrack 对象的 文本轨道文本轨道提示列表 中移除 cue

在这个例子中,使用一个 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();
}

TextTrackCueList

Support in all current engines.

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
[Exposed=Window]
interface TextTrackCueList {
  readonly attribute unsigned long length;
  getter TextTrackCue (unsigned long index);
  TextTrackCue? getCueById(DOMString id);
};
cuelist.length

返回列表中 提示 的数量。

cuelist[index]

返回列表中索引为 index文本轨提示。这些提示按 文本轨提示顺序 排序。

cuelist.getCueById(id)

返回第一个具有id文本轨道提示(按文本轨道提示顺序)。

如果没有提示具有给定的标识符或参数为空字符串,则返回null。

A TextTrackCueList 对象表示按给定顺序动态更新的 文本轨提示 列表。

TextTrackCueList/length

所有当前引擎都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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.

TextTrackCueList/getCueById

所有当前引擎都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

The getCueById(id) 方法,当 传入的参数不是空字符串时,必须返回列表中第一个标识符为 id文本轨提示,如果有的话,否则返回 null。如果参数为空字符串,则该方法必须返回 null。


TextTrackCue

所有当前引擎都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
[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

返回该文本轨道提示所属的TextTrack对象(如果有),否则返回null。

cue.id [ = value ]

返回文本轨道提示标识符

可设置。

cue.startTime [ = value ]

返回文本轨道提示开始时间,单位为秒。

可设置。

cue.endTime [ = value ]

返回文本轨道提示结束时间,单位为秒。

对于无界文本轨道提示返回正无穷大。

可设置。

cue.pauseOnExit [ = value ]

如果文本轨道提示退出时暂停标志被设置,则返回true,否则返回false。

可设置。

TextTrackCue/track

所有当前引擎都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

获取时,track属性必须返回TextTrack对象,该对象表示TextTrackCue对象表示的文本轨道提示在其提示列表中找到的文本轨道。如果没有,则返回null。

TextTrackCue/id

所有当前引擎都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

获取时,id属性必须返回TextTrackCue对象表示的文本轨道提示文本轨道提示标识符。设置时,必须将文本轨道提示标识符设置为新值。

TextTrackCue/startTime

所有当前引擎都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

获取时,startTime属性必须返回TextTrackCue对象表示的文本轨道提示文本轨道提示开始时间,单位为秒。设置时,必须将文本轨道提示开始时间设置为新值,解释为秒;然后,如果TextTrackCue对象的文本轨道提示在其文本轨道提示列表中,并且该文本轨道媒体元素文本轨道列表中,并且媒体元素显示海报标志未设置,则为该媒体元素运行时间推进步骤。

TextTrackCue/endTime

所有当前引擎都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

获取时,endTime属性必须返回TextTrackCue对象表示的文本轨道提示文本轨道提示结束时间,单位为秒或正无穷大。设置时,如果新值是负无穷大或NaN(非数值),则抛出TypeError异常。否则,必须将文本轨道提示结束时间设置为新值。然后,如果TextTrackCue对象的文本轨道提示在其文本轨道提示列表中,并且该文本轨道媒体元素文本轨道列表中,并且媒体元素显示海报标志未设置,则为该媒体元素运行时间推进步骤。

TextTrackCue/pauseOnExit

所有当前引擎都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

获取时,pauseOnExit属性必须返回true,如果TextTrackCue对象表示的文本轨道提示文本轨道提示退出时暂停标志已设置;否则返回false。设置时,如果新值为true,则必须设置文本轨道提示退出时暂停标志;否则必须取消设置。

4.8.11.11.6 文本轨道API对象的事件处理程序

以下是必须由所有实现TextTrackList接口的对象支持的事件处理程序及其相应的事件处理程序事件类型,作为事件处理程序IDL属性支持:

事件处理程序 事件处理程序事件类型
onchange change
onaddtrack addtrack
onremovetrack removetrack

以下是必须由所有实现TextTrack接口的对象支持的事件处理程序及其相应的事件处理程序事件类型,作为事件处理程序IDL属性支持:

事件处理程序 事件处理程序事件类型
oncuechange

TextTrack/cuechange_event

所有当前引擎都支持。

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

TextTrackCue/enter_event

所有当前引擎都支持。

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

TextTrackCue/exit_event

所有当前引擎都支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
exit
4.8.11.11.7 元数据文本轨道的最佳实践

本节为非规范性内容。

文本轨道可以用于存储与媒体数据相关的数据,用于交互或增强视图。

例如,显示体育直播的页面可以包含当前比分的信息。假设一个机器人比赛正在直播,图像可以覆盖分数,如下所示:

为了使得比分显示在用户任意快进视频时都能正确渲染,元数据文本轨道提示需要根据比分的适当长度设置。例如,在上面的框架中,可能会有一个持续整个比赛时间的提示,给出比赛编号,一个提示持续到蓝方联盟的分数变化,一个提示持续到红方联盟的分数变化。如果视频只是现场直播流,右下角的时间可能会根据当前视频时间自动派生,而不是基于提示。然而,如果视频只是精彩片段,那么这些时间也可能会在提示中给出。

以下显示了在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事件是有速率限制的。)

4.8.11.12 通过URL识别轨道类型

需要使用URL来识别AudioTrackVideoTrackkindkindIDL属性的其他规范或格式,或者识别文本轨道类型,必须使用about:html-kindURL

4.8.11.13 用户界面

controls属性是一个布尔属性。 如果存在,则表示作者没有提供脚本控制器,希望用户代理提供自己的一套控制。

如果存在该属性,或者该脚本已禁用媒体元素,则用户代理应当向用户展示一个用户界面。这个用户界面应当包括开始播放、暂停播放、跳转到内容中任意位置(如果内容支持任意跳转)、更改音量、更改隐藏字幕或嵌入手语轨道的显示、选择不同音轨或打开音频描述、以及以更适合用户的方式显示媒体内容(例如全屏视频或在独立的可调整大小的窗口中)。其他控制也可以提供。

即使没有该属性,用户代理也可以提供控制来影响媒体资源的播放(例如播放、暂停、跳转、轨道选择和音量控制),但这些功能不应干扰页面的正常渲染。例如,这些功能可以在媒体元素的上下文菜单、平台媒体键或遥控器中提供。用户代理可以通过如上所述向用户展示一个用户界面来实现这一点(就像存在controls属性一样)。

如果用户代理通过在媒体元素上显示控件来向用户展示用户界面,则用户代理应当在用户与此界面交互时抑制任何用户交互事件。(例如,如果用户点击视频的播放控件,不会同时向页面上的元素触发mousedown事件等)。

如果可能(特别是用于开始、停止、暂停和继续播放、跳转、更改播放速率、快进或倒退、列出、启用和禁用文本轨道、以及静音或更改音量),用户代理暴露的用户界面功能必须根据上述DOM API实现,以确保例如所有相同的事件触发。

诸如快进或倒退的功能必须仅通过更改playbackRate属性(而不是defaultPlaybackRate属性)来实现。

跳转必须根据跳转媒体元素媒体时间轴中的请求位置来实现。对于跳转到任意位置会很慢的媒体资源,用户代理应当在响应用户操作近似位置界面(如跳转条)时使用approximate-for-speed标志。

HTMLMediaElement/controls

所有当前引擎支持。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

controlsIDL属性必须反映同名的内容属性。


media.volume [ = value ]

HTMLMediaElement/volume

所有当前引擎支持。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS🔰3+Chrome Android?WebView Android 37+Samsung Internet?Opera Android12.1+

返回当前播放音量,范围为0.0到1.0,其中0.0是最安静的,1.0是最响亮的。

可以设置以更改音量。

如果新值不在0.0到1.0的范围内,则抛出"IndexSizeError"DOMException

media.muted [ = value ]

HTMLMediaElement/muted

所有当前引擎支持。

Firefox3.5+Safari3.1+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

如果音频被静音,返回true,覆盖volume属性;如果volume属性被尊重,返回false。

可以设置,以更改音频是否被静音。

媒体元素具有一个播放音量,范围为0.0(静音)到1.0(最响亮)。最初,音量应为1.0,但用户代理可以在每个站点或其他情况下记住上次设置的值,因此音量可能从其他值开始。

volumeIDL属性必须返回播放音量的任何音频部分的媒体元素。在设置时,如果新值在0.0到1.0范围内(包括),则媒体元素播放音量必须设置为新值。如果新值不在0.0到1.0范围内(包括),则在设置时,必须抛出"IndexSizeError"DOMException

媒体元素也可以静音。如果有任何东西将元素静音,则它是静音的。(例如,当播放方向是向后时,元素被静音。)

mutedIDL属性必须返回最后设置的值。当创建媒体元素时,如果元素指定了一个muted内容属性,则mutedIDL属性应设置为true;否则,用户代理可以将值设置为用户的首选值(例如记住上次设置的值)。当mutedIDL属性设置为true时,媒体元素必须静音

每当volumemutedIDL属性返回的值之一发生变化时,用户代理必须队列一个媒体元素任务给定媒体元素触发一个事件,命名为volumechange媒体元素上。然后,如果媒体元素允许播放,用户代理必须为媒体元素运行内部暂停步骤

用户代理有一个关联的音量锁定(布尔值)。其值是实现定义的,决定是否播放音量生效。

元素的有效媒体音量确定如下:

  1. 如果用户已指示用户代理覆盖元素的音量,则返回用户所需的音量。

  2. 如果用户代理的音量锁定为true,则返回系统音量。

  3. 如果元素的音频输出被静音,则返回零。

  4. volume播放音量媒体元素的音频部分,范围为0.0(静音)到1.0(最响亮)。

  5. 返回volume,相对于0.0到1.0的范围解释,0.0为静音,1.0为最响亮的设置,中间的值增加响度。范围不必是线性的。最响亮的设置可以低于系统的最大可能设置;例如用户可以设置最大音量。

muted内容属性在媒体元素上是一个布尔属性,控制媒体资源的音频输出的默认状态,可能会覆盖用户偏好。

HTMLMediaElement/defaultMuted

所有当前引擎支持。

Firefox11+Safari6+Chrome15+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

defaultMutedIDL属性必须反映muted内容属性。

此属性没有动态效果(它只控制元素的默认状态)。

这个视频(广告)会自动播放,但为了避免打扰用户,它在没有声音的情况下播放,并允许用户打开声音。如果没有用户交互,用户代理可以暂停视频。

<video src="adverts.cgi?kind=video" controls autoplay loop muted></video>
4.8.11.14 时间范围

TimeRanges

所有当前引擎支持。

Firefox4+Safari3.1+Chrome6+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

实现TimeRanges接口的对象表示一系列时间范围(期间)。

[Exposed=Window]
interface TimeRanges {
  readonly attribute unsigned long length;
  double start(unsigned long index);
  double end(unsigned long index);
};
media.length

TimeRanges/length

所有当前引擎支持。

Firefox4+Safari3.1+Chrome6+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回对象中的范围数。

time = media.start(index)

TimeRanges/start

所有当前引擎支持。

Firefox4+Safari3.1+Chrome6+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回给定索引的范围的开始时间。

如果索引超出范围,则抛出"IndexSizeError" DOMException

time = media.end(index)

TimeRanges/end

所有当前引擎支持。

Firefox4+Safari3.1+Chrome6+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回给定索引的范围的结束时间。

如果索引超出范围,则抛出"IndexSizeError" DOMException

lengthIDL属性必须返回对象所表示的范围数。

start(index)方法必须返回对象所表示的第index个范围的开始位置,以该对象覆盖的时间轴开始测量的秒数。

end(index)方法必须返回对象所表示的第index个范围的结束位置,以该对象覆盖的时间轴开始测量的秒数。

如果以大于或等于对象表示的范围数的index参数调用这些方法,则必须抛出"IndexSizeError" DOMException

当一个TimeRanges对象被称为标准化TimeRanges对象时,它所表示的范围必须遵守以下标准:

换句话说,此类对象中的范围是有序的,不重叠且不接触(相邻范围折叠成一个更大的范围)。范围可以是空的(仅引用时间上的一个时刻),例如,在用户代理丢弃整个媒体资源的情况下,指示当前仅缓冲一个帧,当媒体元素暂停时。

一个TimeRanges对象中的范围必须是包含的。

因此,一个范围的结束等于后续相邻(接触但不重叠)范围的开始。同样,覆盖整个以零为锚点的时间轴的范围的开始将等于零,结束将等于时间轴的持续时间。

媒体元素bufferedseekableplayedIDL属性返回的对象使用的时间轴必须是该元素的媒体时间轴

4.8.11.15 TrackEvent接口

TrackEvent

所有当前引擎支持。

Firefox27+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
[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

TrackEvent/track

所有当前引擎支持。

Firefox27+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回事件相关的轨道对象(TextTrackAudioTrack, 或 VideoTrack)。

track属性必须返回它初始化时的值。它代表事件的上下文信息。

4.8.11.16 事件摘要

本节为非规范性内容。

媒体元素上触发以下事件,作为上述处理模型的一部分:

事件名称 接口 触发时机... 前提条件
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

HTMLMediaElement/abort_event

所有当前引擎支持。

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_EMPTYNETWORK_IDLE,取决于何时中止下载。
error

HTMLMediaElement/error_event

所有当前引擎支持。

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_EMPTYNETWORK_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()方法)。 networkStateNETWORK_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 用户代理尝试获取媒体数据,但数据意外未到达。 networkStateNETWORK_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 seekingIDL属性已更改为true,且用户代理已开始寻找新位置。
seeked

HTMLMediaElement/seeked_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 seekingIDL属性已更改为false,当前播放位置已更改。
ended

HTMLMediaElement/ended_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 播放已停止,因为到达媒体资源的末端。 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

HTMLMediaElement/play_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()方法返回后或autoplay属性导致播放开始时触发。 paused新为false。
pause

HTMLMediaElement/pause_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 元素已暂停。在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 defaultPlaybackRateplaybackRate属性刚刚更新。
resize Event videoWidthvideoHeight属性之一或两者刚刚更新。 媒体元素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 在获取媒体数据时发生错误或资源类型不是支持的媒体格式。

以下事件会在AudioTrackListVideoTrackListTextTrackList对象上触发:

事件名称 接口 触发时机
change

AudioTrackList/change_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/change_event

所有当前引擎支持。

Firefox31+Safari7+Chrome33+
Opera?Edge79+
Edge (旧版)18Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android4.4+Samsung Internet?Opera Android?

VideoTrackList/change_event

所有当前引擎支持。

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

AudioTrackList/addtrack_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/addtrack_event

所有当前引擎支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android?

VideoTrackList/addtrack_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 轨道已添加到轨道列表中。
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 轨道已从轨道列表中移除。

以下事件在TextTrack对象和track元素上触发:

事件名称 接口 触发时机
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+

TextTrack/cuechange_event

所有当前引擎支持。

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

TextTrackCue/enter_event

所有当前引擎支持。

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

TextTrackCue/exit_event

所有当前引擎支持。

Firefox31+Safari6+Chrome23+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
Event 提示已停止活动。
4.8.11.17 安全和隐私考量

videoaudio元素的主要安全和隐私影响来自跨源嵌入媒体的能力。威胁可以从两个方向流动:从恶意内容到受害页面,以及从恶意页面到受害内容。


如果受害页面嵌入恶意内容,威胁在于内容可能包含脚本代码,试图与嵌入内容的Document交互。为避免这种情况,用户代理必须确保内容无法访问嵌入页面。在使用DOM概念的媒体内容的情况下,嵌入的内容必须被视为在其自己无关的顶级可遍历中。

例如,如果在video元素中嵌入一个SVG动画,用户代理不会给予它访问外部页面DOM的权限。从SVG资源中的脚本视角来看,SVG文件将显得处于一个没有父级的单独顶级可遍历中。


如果恶意页面嵌入受害内容,威胁在于嵌入页面可能会从内容中获取其本不会访问的信息。API确实暴露了一些信息:媒体的存在、其类型、其持续时间、其大小及其主机的性能特征。这些信息已经可能带来问题,但实际上可以通过img元素获取到差不多的信息,因此被认为是可以接受的。

然而,如果用户代理进一步暴露内容中的元数据,如字幕,则可能获得显著更敏感的信息。因此,只有在视频资源使用CORS时才暴露这些信息。crossorigin属性允许作者启用CORS。[FETCH]

没有这个限制,攻击者可能会欺骗在企业网络内运行的用户访问一个试图从企业内联网泄露位置加载视频的网站。如果这样的影片包含新产品的机密计划,那么能够读取字幕将造成严重的机密泄露。

4.8.11.18 使用媒体元素的作者的最佳实践

本节为非规范性内容。

在小型设备(如机顶盒或手机)上播放音视频资源通常受到设备硬件资源有限的限制。例如,一个设备可能只支持同时播放三个视频。因此,当媒体元素media elements播放完毕时,通过非常谨慎地移除对该元素的所有引用并允许其被垃圾回收,或者更好的方法是将元素的src属性设置为空字符串,来释放资源。如果设置了srcObject,则将srcObject设置为null。

同样地,当播放速率不完全是1.0时,硬件、软件或格式限制可能会导致视频帧丢失和音频断断续续或静音。

4.8.11.19 实现媒体元素的最佳实践

本节为非规范性内容。

实现media element API的各个方面的准确程度被认为是实现质量问题。

例如,在实现buffered属性时,报告已缓冲范围的精确程度取决于用户代理检查数据的仔细程度。由于API以时间报告范围,但数据是以字节流获取的,因此接收可变比特率流的用户代理可能只能通过实际解码所有数据来确定精确时间。然而,用户代理不需要这样做;他们可以返回估计值(例如基于到目前为止看到的平均比特率),这些估计值会随着更多信息的出现而进行修正。

作为一般规则,用户代理应保守而非乐观。例如,报告所有内容都已缓冲但实际上并没有缓冲完全是有害的。

另一个实现质量问题是当编解码器仅设计用于前向播放(例如关键帧很少且间隔很远,并且中间帧仅具有前一帧的增量)时,反向播放视频。用户代理可能会表现不佳,例如只显示关键帧;然而,更好的实现会做更多的工作,从而表现得更好,例如实际前向解码视频部分,存储完整帧,然后反向播放这些帧。

同样,实现可以随时丢弃缓冲数据(没有要求用户代理在媒体元素的生命周期内保留所有获取的媒体数据),这也是实现质量问题:有足够资源的用户代理被鼓励保留所有数据,因为这可以提供更好的用户体验。例如,如果用户在观看直播,用户代理可以只允许用户观看直播视频;然而,更好的用户代理会缓冲所有内容,并允许用户浏览早期材料,暂停,前后播放等。


当一个media element暂停时被从文档中移除并且在事件循环到达步骤1之前未重新插入,实现资源受限的用户代理被鼓励利用这个机会释放所有由media element使用的硬件资源(如视频平面、网络资源和数据缓冲区)。(用户代理仍需跟踪播放位置等,以防以后重新开始播放。)

4.8.12 map 元素

Element/map

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge(旧版)12+Internet Explorer支持
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLMapElement

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
分类:
流内容.
短语内容.
有形内容.
该元素可以使用的上下文:
在预期短语内容的地方。
内容模型:
透明.
在 text/html 中省略标签:
两者标签都不可省略。
内容属性:
全局属性
name — 用于从 usemap 属性引用图像地图的名称
无障碍考虑:
作者参考.
实现者参考.
DOM 接口:
[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>

4.8.13 area 元素

Element/area

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge(旧版)12+Internet Explorer支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLAreaElement

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
分类:
流内容.
短语内容.
该元素可以使用的上下文:
在预期短语内容的地方,但仅当有一个 map 元素祖先时。
内容模型:
无内容.
在 text/html 中省略标签:
没有 结束标签.
内容属性:
全局属性
alt — 当图像不可用时使用的替代文本
coords — 在图像地图中创建形状的坐标
shape — 在图像地图中创建形状的类型
href — 超链接的地址
target — 用于导航超链接的可导航目标
download — 是否下载资源而不是导航到它,如果是,则为其文件名
ping — 要 ping 的 URL
rel — 文档中包含超链接的位置与目标资源之间的关系
referrerpolicy — 元素发起的获取的引用策略
无障碍考虑:
如果元素有 href 属性:作者参考实现者参考
否则:作者参考实现者参考
DOM 接口:
[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 元素必须有一个 map 元素祖先。

如果 area 元素具有 href 属性,那么 area 元素表示一个 超链接。在这种情况下,alt 属性必须存在。它指定超链接的文本。其值必须是这样的文本:当与图像地图的其他超链接文本以及图像的替代文本一起呈现时,但没有图像本身时,向用户提供与超链接使用其形状应用于图像时相同类型的选择。如果同一 图像地图 中有另一个 area 元素指向相同的资源,并且其 alt 属性不为空,则该属性可以留空。

如果 area 元素没有 href 属性,则该元素表示的区域不可选择,并且必须省略 alt 属性。

在这两种情况下,shapecoords 属性指定该区域。

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 元素的 hreftargetdownloadping 属性决定了链接的跟随方式。rel 属性可用于向用户指示在用户跟随链接之前目标资源的可能性质。

targetdownloadpingrelreferrerpolicy 属性必须省略,如果没有 href 属性。

如果 itemprop 属性在 area 元素上指定,则还必须指定 href 属性。

HTMLAreaElement/rel

所有当前引擎都支持。

Firefox30+Safari9+Chrome54+
Opera?Edge79+
Edge(旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

ID属性 altcoordsshapetargetdownloadpingrel,必须 反映同名的相应内容属性。

HTMLAreaElement/relList

所有当前引擎都支持。

Firefox30+Safari9+Chrome65+
Opera41+Edge79+
Edge(旧版)18Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

ID属性 relList 必须 反映 rel 内容属性。

HTMLAreaElement/referrerPolicy

所有当前引擎都支持。

Firefox50+Safari14.1+Chrome52+
Opera?Edge79+
Edge(旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

ID属性 referrerPolicy 必须 反映 referrerpolicy 内容属性,仅限于已知值

4.8.14 图像映射

4.8.14.1 编写

图像映射允许将图像上的几何区域与超链接关联起来。

图像(以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>
4.8.14.2 处理模型

如果img元素有指定usemap属性,用户代理必须按如下方式处理:

  1. 使用解析哈希名称引用的规则解析该属性的值为指向map元素,并以该元素为上下文节点。这将返回一个元素(map)或null。

  2. 如果返回null,则返回。该图像并未关联到图像映射。

  3. 否则,用户代理必须收集所有作为map后代的area元素。将这些元素称为areas

获取形成图像映射的area元素列表(areas)后,交互式用户代理必须以两种方式之一处理该列表。

如果用户代理打算显示img元素表示的文本,则必须使用以下步骤。

  1. 删除areas中所有没有href属性的area元素。

  2. 删除areas中所有没有alt属性或alt属性值为空字符串的area元素,如果areas中有另一个具有相同href属性值且具有非空alt属性的area元素。

  3. 每个剩余的areas中的area元素都代表一个超链接。这些超链接应以与img的文本相关的方式提供给用户。

    在这种情况下,用户代理可以以areaimg元素没有指定alt属性或其alt属性为空字符串或其他不可见文本的方式表示这些元素,使用一种实现定义的方式来指示缺少适当的作者提供的文本。

如果用户代理打算显示图像并允许与图像进行交互以选择超链接,则图像必须与一组从areas中的area元素中获取的层叠形状关联,以相反的树顺序(即map中最后指定的area元素是最底层的形状,map中的第一个元素,在树顺序中,是最顶层的形状)。

每个areas中的area元素必须按如下方式处理以获得叠加在图像上的形状:

  1. 找到该元素的shape属性所代表的状态。

  2. 使用解析浮点数列表的规则解析该元素的coords属性(如果存在),并将结果设为coords列表。如果属性不存在,则将coords列表设为空列表。

  3. 如果coords列表中的项目数少于当前状态下area元素的最小数量,则形状为空;返回。

    状态 最小项目数
    圆形状态 3
    默认状态 0
    多边形状态 6
    矩形状态 4
  4. 根据以下列表中与shape属性的状态相对应的条目,检查coords列表中的多余项目:

    圆形状态
    丢弃列表中第三个项目以后的任何项目。
    默认状态
    丢弃列表中的所有项目。
    多边形状态
    如果项目数为奇数,则丢弃最后一个项目。
    矩形状态
    丢弃列表中第四个项目以后的任何项目。
  5. 如果shape属性代表矩形状态,并且列表中的第一个数字大于第三个数字,则交换这两个数字。

  6. 如果shape属性代表矩形状态,并且列表中的第二个数字大于第四个数字,则交换这两个数字。

  7. 如果shape属性代表圆形状态,并且列表中的第三个数字小于或等于零,则形状为空;返回。

  8. 现在,由元素表示的形状是下面列表中与shape属性状态对应的条目所描述的形状:

    圆形状态

    xcoords列表中的第一个数字,y为第二个数字,r为第三个数字。

    该形状是一个圆,其中心点距离图像左边缘xCSS像素,距离图像上边缘yCSS像素,半径为rCSS像素

    默认状态

    形状是一个完全覆盖整个图像的矩形。

    多边形状态

    xicoords中的第2i个条目,yicoords中的第2i+1个条目(coords中的第一个条目索引为0)。

    coordinates为(xi, yi),以CSS像素为单位,从图像左上角开始测量,对于所有i的整数值,从0到N/2-1,其中Ncoords中的条目数。

    该形状是一个多边形,其顶点由coordinates给出,其内部通过奇偶规则确定。[GRAPHICS]

    矩形状态

    x1coords中的第一个数字,y1为第二个数字,x2为第三个数字,y2为第四个数字。

    该形状是一个矩形,其左上角由坐标(x1, y1)给出,右下角由坐标(x2, y2)给出,这些坐标以CSS像素为单位,从图像的左上角测量。

    由于历史原因,坐标必须相对于显示后的图像解释,即CSS 'width''height'属性(或者,对于非CSS浏览器,图像元素的widthheight属性——CSS浏览器将这些属性映射到上述CSS属性)。

    浏览器缩放功能和使用CSS或SVG应用的变换不会影响坐标。

根据上述算法与一组层叠形状关联的图像的指针设备交互,必须首先将相关的用户交互事件发送到指针设备指示的点覆盖的最顶层形状(如果有),或者发送到图像元素本身(如果没有形状覆盖该点)。用户代理还可以允许选择和激活代表超链接的单个area元素(例如使用键盘)。

由于map元素(及其area元素)可以与多个img元素关联,因此area元素可能对应于文档的多个可聚焦区域

图像映射是实时的;如果DOM发生变化,用户代理必须像重新运行图像映射算法一样处理 。

4.8.15 MathML

HTML/HTML5/HTML5_Parser#Inline_SVG_and_MathML_support

支持所有当前引擎。

Firefox4+Safari5.1+Chrome7+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android5+Safari iOS5+Chrome Android18+WebView Android3+Samsung Internet1.0+Opera Android12+

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>

4.8.16 SVG

HTML/HTML5/HTML5_Parser#Inline_SVG_and_MathML_support

支持所有当前引擎。

Firefox37+Safari11.1+Chrome7+
Opera15+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android37+Safari iOS11.3+Chrome Android18+WebView Android4.4+Samsung Internet4+Opera Android15+

SVG svg 元素属于 嵌入内容, 短语内容, 流内容, 和 可感知内容 类别,用于本规范中的内容模型。

SVG foreignObject 元素包含来自 HTML 命名空间的元素时,这些元素都必须是 流内容

HTML 文档中的 SVG title 元素的内容模型是 短语内容。 (这进一步限制了SVG 2中的要求。)

SVG 元素的语义由 SVG 2其他适用的规范定义。 [SVG]


doc = iframe.getSVGDocument()
doc = embed.getSVGDocument()
doc = object.getSVGDocument()

返回 Document 对象,当 iframe, embed, 或 object 元素用于嵌入 SVG 时。

getSVGDocument() 方法的步骤如下:

  1. document 成为 this内容文档

  2. 如果 document 非空,并且因为 页面加载处理模型针对 XML 文件部分创建了它,因为在 资源的计算类型导航算法中是 image/svg+xml,那么返回 document

  3. 返回 null。

4.8.17 尺寸属性

作者要求:在 imgiframeembedobjectvideosource 元素上, 当其父元素是 picture 元素时, 以及当其 type 属性处于 图片按钮状态时, input 元素, 可以指定 widthheight 属性, 以给出元素视觉内容的尺寸(分别是宽度和高度,相对于输出媒介的标称方向),单位为 CSS 像素。如果指定了这些属性,它们的值必须是有效的非负整数

给定的指定尺寸可能与资源本身指定的尺寸不同,因为资源的分辨率可能与 CSS 像素分辨率不同。(在屏幕上,CSS 像素 的分辨率是 96ppi,但一般来说,CSS 像素分辨率取决于阅读距离。)如果同时指定了两个属性,则必须满足以下陈述之一:

target ratio 是资源的 自然宽度自然高度 的比率。specified widthspecified height 分别是 widthheight 属性的值。

如果相关资源没有 自然宽度自然高度,则必须省略这两个属性。

如果两个属性都为0,这表示该元素不打算用于用户(例如,它可能是一个用于计数页面浏览量的服务的一部分)。

尺寸属性不应用于拉伸图像。

用户代理要求:用户代理应使用这些属性 作为渲染的提示

HTMLObjectElement/width

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLObjectElement/height

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

widthheight IDL 属性在 iframeembedobjectsourcevideo 元素上 必须 反映相应的内容属性。

对于 iframeembedobject, IDL 属性是 DOMString; 对于 videosource, IDL 属性是 unsigned long

对于 imginput 元素, 相应的 IDL 属性在这些各自元素的部分中定义,因为它们更具体地与这些元素的其他行为相关。

4.9 表格数据

4.9.1 table 元素

Element/table

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLTableElement

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容
可感知内容
此元素可以使用的上下文:
预期出现流内容的地方。
内容模型:
按此顺序:可选的caption元素,随后零个或多个colgroup元素,随后可选的thead元素,随后零个或多个tbody元素或一个或多个tr元素,随后可选的tfoot元素,可选地夹杂一个或多个脚本支持元素
在text/html中的标签省略:
标签均不可省略。
内容属性:
全局属性
无障碍考虑:
对于作者
对于实现者
DOM接口:
[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 可能是布局表格
使用不符合规范的 cellspacingcellpadding 属性,值为 0 可能是布局表格
使用 captiontheadth 元素 可能是非布局表格
使用 headersscope 属性 可能是非布局表格
使用不符合规范的 border 属性,值为非0 可能是非布局表格
使用 CSS 设置的显式可见边框 可能是非布局表格
使用 summary 属性 不是一个好的指标(历史上,布局表格和非布局表格都设置了这个属性)

以上建议很可能是错误的。强烈建议实现者提供反馈,详细说明他们尝试创建布局表格检测启发式方法的经验。

如果一个 table 元素有一个(不符合规范的)summary 属性,并且用户代理未将其分类为布局表格,则用户代理可以向用户报告该属性的内容。


table.caption [ = value ]

HTMLTableElement/caption

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回表格的 caption 元素。

可设置,以替换 caption 元素。

caption = table.createCaption()

HTMLTableElement/createCaption

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

确保表格有一个 caption 元素,并返回它。

table.deleteCaption()

HTMLTableElement/deleteCaption

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

确保表格没有 caption 元素。

table.tHead [ = value ]

HTMLTableElement/tHead

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回表格的 thead 元素。

可设置,以替换 thead 元素。如果新值不是 thead 元素,则抛出 "HierarchyRequestError" DOMException

thead = table.createTHead()

HTMLTableElement/createTHead

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

确保表格有一个 thead 元素,并返回它。

table.deleteTHead()

HTMLTableElement/deleteTHead

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

确保表格没有 thead 元素。

table.tFoot [ = value ]

HTMLTableElement/tFoot

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回表格的 tfoot 元素。

可设置,以替换 tfoot 元素。如果新值不是 tfoot 元素,则抛出 "HierarchyRequestError" DOMException

tfoot = table.createTFoot()

HTMLTableElement/createTFoot

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

确保表格有一个 tfoot 元素,并返回它。

table.deleteTFoot()

HTMLTableElement/deleteTFoot

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

确保表格没有 tfoot 元素。

table.tBodies

HTMLTableElement/tBodies

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回一个 HTMLCollection,包含表格的 tbody 元素。

tbody = table.createTBody()

HTMLTableElement/createTBody

支持所有当前引擎。

Firefox25+Safari6+Chrome20+
Opera?Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

创建一个 tbody 元素,将其插入表格中,并返回它。

table.rows

HTMLTableElement/rows

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回一个 HTMLCollection,包含表格的 tr 元素。

tr = table.insertRow([ index ])

HTMLTableElement/insertRow

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera10+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

创建一个 tr 元素,必要时同时创建 tbody,按给定的位置将其插入表格中,并返回 tr

位置相对于表中的行。默认省略参数时,索引 -1 相当于插入到表格末尾。

如果给定位置小于 -1 或大于行数,则抛出 "IndexSizeError" DOMException

table.deleteRow(index)

HTMLTableElement/deleteRow

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

移除表中给定位置的 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) 方法时,根据表格状态执行以下操作:

如果 index 小于 -1 或大于 rows 集合中的元素数量:
必须抛出 "IndexSizeError" DOMException
如果 rows 集合中没有元素,且 table 中没有 tbody 元素:
必须 表格创建 一个 tbody 元素,然后 表格创建 一个 tr 元素,然后将 tr 元素追加到 tbody 元素中,然后将 tbody 元素追加到 table 元素中,最后返回 tr 元素。
如果 rows 集合中没有元素:
必须 表格创建 一个 tr 元素,将其追加到表格中的最后一个 tbody 元素中,并返回 tr 元素。
如果 index 为 -1 或等于 rows 集合中的项目数量:
必须 表格创建 一个 tr 元素,并将其追加到 rows 集合中的最后一个 tr 元素的父节点。然后,必须返回新创建的 tr 元素。
否则:
必须 表格创建 一个 tr 元素,将其插入到 rows 集合中的第 indextr 元素之前,并返回新创建的 tr 元素。

当调用 deleteRow(index) 方法时,用户代理必须执行以下步骤:

  1. 如果 index 小于 -1 或大于等于 rows 集合中的元素数量,则抛出 "IndexSizeError" DOMException

  2. 如果 index 为 -1,则 移除 rows 集合中的最后一个元素,或如果集合为空,则不执行任何操作。

  3. 否则,移除 rows 集合中的第 index 个元素。

这是一个将表格用于标记数独谜题的示例。请注意,缺少标题,这在这样的表格中是没有必要的。

<style>
 #sudoku { border-collapse: collapse; border: solid thick; }
 #sudoku colgroup, table#sudoku tbody { border: solid medium; }
 #sudoku td { border: solid thin; height: 1.4em; width: 1.4em; 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>
4.9.1.1 描述表格的技巧

对于不仅仅由第一行和第一列包含标题的单元格网格组成的表格,以及任何读者可能难以理解内容的表格,作者应包括介绍表格的解释信息。这些信息对所有用户都有用,但对无法看到表格的用户尤其有用,例如屏幕阅读器用户。

这样的解释信息应介绍表格的目的,概述其基本单元格结构,突出任何趋势或模式,并一般性地教用户如何使用表格。

例如,以下表格:

具有正面和负面特征的表格
负面 特征 正面
悲伤 心情 快乐
失败 成绩 通过

...可能需要描述说明表格的布局方式,比如“特征在第二列给出,负面在左列,正面在右列”。

有多种方法可以包含这些信息,例如:

用散文形式描述,围绕表格
<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>
在表格旁边,位于figurefigcaption
<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>
4.9.1.2 表格设计技巧

良好的表格设计是使表格更具可读性和可用性的关键。

在视觉媒体中,提供列和行边框以及交替的行背景可以非常有效地使复杂表格更具可读性。

对于包含大量数字内容的表格,使用等宽字体可以帮助用户看到模式,特别是在用户代理不渲染边框的情况下。(不幸的是,由于历史原因,不渲染表格边框是一种常见的默认设置。)

在语音媒体中,可以通过在读取单元格内容之前报告相应的标题,以及允许用户以网格方式导航表格,而不是按源顺序串行化整个表格的内容,来区分表格单元格。

鼓励作者使用CSS来实现这些效果。

用户代理在页面未使用CSS且表格未被分类为布局表格时,建议使用这些技术渲染表格。

4.9.2 caption 元素

Element/caption

Support in all current engines.

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLTableCaptionElement

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
无。
使用此元素的上下文:
作为table元素的第一个子元素。
内容模型:
流内容,但没有table元素的后代。
在text/html中省略标签:
如果caption元素后面没有紧接着ASCII空白注释,则可以省略caption元素的结束标签
内容属性:
全局属性
无障碍考虑:
针对作者
针对实现者
DOM接口:
[Exposed=Window]
interface HTMLTableCaptionElement : HTMLElement {
  [HTMLConstructor] constructor();

  // also has obsolete members
};

caption元素代表其父元素(如果有父元素且该父元素是table元素)的table元素的标题。

caption元素参与表格模型

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。

这个表格显示了掷两个六面骰子得到的总分。第一行表示第一个骰子的值,第一列表示第二个骰子的值。总分在对应两个骰子值的单元格中给出。

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

4.9.3 colgroup 元素

Element/colgroup

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLTableColElement

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
分类:
无。
此元素可以使用的上下文:
作为 table 元素的子元素,在任何 caption 元素之后,并且在任何 theadtbodytfoottr 元素之前。
内容模型:
如果 span 属性存在:无内容
如果 span 属性不存在:零个或多个 coltemplate 元素。
在 text/html 中的标签省略:
如果 colgroup 元素内的第一个元素是 col 元素,并且该元素之前没有紧跟另一个 colgroup 元素(其结束标签已省略),则可以省略 开始标签。(如果元素为空,则不能省略)。
如果 colgroup 元素后没有紧跟 ASCII 空白字符注释,则可以省略 结束标签
内容属性:
全局属性
span — 元素跨越的列数
无障碍考虑:
作者指南
实现者指南
DOM 接口:
[Exposed=Window]
interface HTMLTableColElement : HTMLElement {
  [HTMLConstructor] constructor();

  [CEReactions] attribute unsigned long span;

  // also has obsolete members
};

colgroup 元素 表示 在其父 table 元素中(一组或多组)列。

如果 colgroup 元素不包含 col 元素,那么该元素可以指定一个 span 内容属性,其值必须是一个 有效的非负整数,大于零且小于等于 1000。

colgroup 元素及其 span 属性参与 表格模型

span IDL 属性必须 反映 相同名称的内容属性。它的值 被限制在 [1, 1000] 范围内,其 默认值 是 1。

4.9.4 col 元素

Element/col

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
分类:
无。
此元素可以使用的上下文:
作为 colgroup 元素的子元素,该元素没有 span 属性。
内容模型:
无内容
在 text/html 中的标签省略:
没有 结束标签
内容属性:
全局属性
span — 元素跨越的列数
无障碍考虑:
作者指南
实现者指南
DOM 接口:
使用 HTMLTableColElement,如在 colgroup 元素中定义的那样。

如果 col 元素有一个父元素,而该父元素是一个 colgroup 元素,该元素本身有一个父元素是一个 table 元素,则该 col 元素 表示colgroup 中的一列或多列。

该元素可以指定一个 span 内容属性,其值必须是一个 有效的非负整数,大于零且小于或等于 1000。

col 元素及其 span 属性参与 表格模型

4.9.5 tbody 元素

元素/tbody

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLTableSectionElement

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
无。
此元素可使用的上下文:
作为 table 元素的子元素,在任何 captioncolgroupthead 元素之后,但前提是没有 tr 元素是 table 元素的子元素。
内容模型:
零个或多个 tr支持脚本 元素。
text/html 中的标签省略:
如果 tbody 元素中的第一个元素是 tr 元素,并且该元素前面没有省略了结束标签的 tbodytheadtfoot 元素,则可以省略 开始标签。(如果元素是空的,则不能省略。)
如果 tbody 元素后面紧跟着一个 tbodytfoot 元素,或者父元素中没有更多内容,则可以省略 结束标签
内容属性:
全局属性
无障碍考虑:
作者
实现者
DOM 接口:
[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 接口也用于 theadtfoot 元素。

tbody 元素 表示一个 ,它由父 table 元素的数据主体组成,如果 tbody 元素有一个父元素并且它是一个 table

tbody 元素参与 表模型

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) 方法必须按如下方式操作:

  1. 如果 index 小于 -1 或大于 rows 集合中的元素数量,则抛出 "IndexSizeError" DOMException

  2. table row 成为 创建元素的结果,给定此元素的 节点文档trHTML 命名空间

  3. 如果 index 为 -1 或等于 rows 集合中的项目数量,则将 table row 附加 到该元素。

  4. 否则,将 table row 插入 作为该元素的子元素,紧挨着 tr 集合中的第 index 个元素之前。

  5. 返回 table row

deleteRow(index) 方法在调用时必须按如下操作:

  1. 如果 index 小于 -1 或大于等于 rows 集合中的元素数量,则抛出 "IndexSizeError" DOMException

  2. 如果 index 为 -1,则从此元素中 移除 rows 集合中的最后一个元素,或者如果 rows 集合为空,则不执行任何操作。

  3. 否则,从此元素中 rows 集合中 index 位置的元素 移除

4.9.6 thead 元素

元素/thead

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
无。
此元素可使用的上下文:
作为 table 元素的子元素,在任何 captioncolgroup 元素之后,在任何 tbodytfoottr 元素之前,但前提是没有其他 thead 元素是 table 元素的子元素。
内容模型:
零个或多个 tr支持脚本 元素。
text/html 中的标签省略:
如果 thead 元素后面紧跟着一个 tbodytfoot 元素,则可以省略 结束标签
内容属性:
全局属性
无障碍考虑:
作者
实现者
DOM 接口:
使用 HTMLTableSectionElement,如 tbody 元素中定义的。

thead 元素 表示由列标签(表头)和任何辅助非表头单元格组成的 ,前提是 thead 元素有一个父元素并且它是一个 table

thead 元素参与 表模型

这个例子展示了 thead 元素的使用。注意在 thead 元素中同时使用了 thtd 元素:第一行是表头,第二行是如何填写表格的说明。

<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>

4.9.7 tfoot 元素

元素/tfoot

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
无。
此元素可使用的上下文:
作为 table 元素的子元素,在任何 captioncolgrouptheadtbodytr 元素之后,但前提是没有其他 tfoot 元素是 table 元素的子元素。
内容模型:
零个或多个 tr支持脚本 元素。
text/html 中的标签省略:
如果父元素中没有更多内容,则可以省略 tfoot 元素的 结束标签
内容属性:
全局属性
无障碍考虑:
作者
实现者
DOM 接口:
使用 HTMLTableSectionElement,如 tbody 元素中定义的。

tfoot 元素 表示由列摘要(表尾)组成的 ,前提是 tfoot 元素有一个父元素并且它是一个 table

tfoot 元素参与 表模型

4.9.8 tr 元素

元素/tr

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLTableRowElement

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
无。
此元素可使用的上下文:
作为 thead 元素的子元素。
作为 tbody 元素的子元素。
作为 tfoot 元素的子元素。
作为 table 元素的子元素,在任何 captioncolgroupthead 元素之后,但前提是没有 tbody 元素是 table 元素的子元素。
内容模型:
零个或多个 tdth支持脚本 元素。
text/html 中的标签省略:
如果 tr 元素后面紧跟着另一个 tr 元素,或者父元素中没有更多内容,则可以省略 结束标签
内容属性:
全局属性
无障碍考虑:
作者
实现者
DOM 接口:
[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 元素参与 表模型

tr.rowIndex

HTMLTableRowElement/rowIndex

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回该行在表格 rows 列表中的位置。

如果该元素不在表格中,则返回 −1。

tr.sectionRowIndex

返回该行在表格节的 rows 列表中的位置。

如果该元素不在表格节中,则返回 −1。

tr.cells

返回一个 HTMLCollection,其中包含该行的 tdth 元素。

cell = tr.insertCell([ index ])

HTMLTableRowElement/insertCell

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

创建一个 td 元素,将其插入到表格行中的给定位置,并返回 td

位置相对于行中的单元格。如果省略参数,默认值 -1 等同于插入到行的末尾。

如果给定的位置小于 -1 或大于单元格数量,则抛出 "IndexSizeError" DOMException

tr.deleteCell(index)

移除行中给定位置的 tdth 元素。

位置相对于行中的单元格。索引 -1 等同于删除行的最后一个单元格。

如果给定的位置小于 -1 或大于最后一个单元格的索引,或者如果没有单元格,则抛出 "IndexSizeError" DOMException

rowIndex 属性必须,如果该元素有一个父 table 元素,或者一个父 tbodytheadtfoot 元素和一个 祖父 table 元素,返回该 tr 元素在该 table 元素的 rows 集合中的索引。如果没有这样的 table 元素,则属性必须返回 -1。

sectionRowIndex 属性必须,如果该元素有一个父 tabletbodytheadtfoot 元素,返回该 tr 元素在父元素的 rows 集合中的索引(对于表格,这是 HTMLTableElementrows 集合;对于表格节,这是 HTMLTableSectionElementrows 集合)。如果没有这样的父元素,则属性必须返回 -1。

cells 属性必须返回一个根植于该 tr 元素的 HTMLCollection,其过滤器仅匹配作为该元素子元素的 tdth 元素。

insertCell(index) 方法必须按如下方式操作:

  1. 如果 index 小于 -1 或大于 cells 集合中的元素数量,则抛出 "IndexSizeError" DOMException

  2. table cell 成为 创建一个元素 的结果,给定此 tr 元素的 节点文档tdHTML 命名空间

  3. 如果 index 等于 -1 或等于 cells 集合中的项目 数量,则将 table cell 附加 到该 tr 元素。

  4. 否则,将 table cell 插入 作为该 tr 元素的子元素,紧挨着 tdth 元素在 cells 集合中的第 index 个元素之前。

  5. 返回 table cell

deleteCell(index) 方法必须按如下方式操作:

  1. 如果 index 小于 -1 或大于等于 cells 集合中的元素数量,则抛出 "IndexSizeError" DOMException

  2. 如果 index 为 -1,则从其父元素中 移除 cells 集合中的最后一个元素,或者如果 cells 集合为空,则不执行任何操作。

  3. 否则,从其父元素中 cells 集合中的第 index 个元素 移除

4.9.9 td 元素

元素/td

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLTableCellElement

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
无。
此元素可使用的上下文:
作为 tr 元素的子元素。
内容模型:
流内容
text/html 中的标签省略:
如果 td 元素后面紧跟着另一个 tdth 元素,或者父元素中没有更多内容,则可以省略 结束标签
内容属性:
全局属性
colspan — 单元格跨越的列数
rowspan — 单元格跨越的行数
headers — 该单元格的表头单元格
无障碍考虑:
作者
实现者
DOM 接口:
[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 元素 表示表格中的数据 单元格

td 元素及其 colspanrowspanheaders 属性参与 表模型

用户代理,尤其是在非视觉环境中或在显示表格为二维网格不切实际的情况下,可能会在渲染单元格内容时为用户提供单元格的上下文;例如,给出其在 表模型 中的位置,或列出单元格的表头单元格(由 分配表头单元格的算法 确定)。当列出单元格的表头单元格时,用户代理可以使用这些表头单元格上的 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>

4.9.10 th 元素

元素/th

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
无。
此元素可使用的上下文:
作为 tr 元素的子元素。
内容模型:
流内容,但没有 headerfooter分节内容标题内容的后代元素。
text/html 中的标签省略:
如果 th 元素后面紧跟着一个 tdth 元素,或父元素中没有更多内容,则可以省略 结束标签
内容属性:
全局属性
colspan — 单元格跨越的列数
rowspan — 单元格跨越的行数
headers — 该单元格的表头单元格
scope — 指定表头单元格应用于哪些单元格
abbr — 在其他上下文中引用该单元格时使用的替代标签
无障碍考虑:
作者
实现者
DOM 接口:
使用 HTMLTableCellElement,如 td 元素所定义。

th 元素 表示表格中的一个表头 单元格

th 元素可以指定一个 scope 内容属性。

scope 属性是一个 枚举属性,具有以下关键字和状态:

关键字 状态 简短描述
row row 表头单元格适用于同一行中的一些后续单元格。
col column 表头单元格适用于同一列中的一些后续单元格。
rowgroup row group 表头单元格适用于行组中的所有剩余单元格。
colgroup column group 表头单元格适用于列组中的所有剩余单元格。

属性的 缺失值默认无效值默认 都是 自动 状态。(在此状态下,表头单元格适用于基于上下文选择的一组单元格。)

如果元素未锚定在 行组 中,则 th 元素的 scope 属性不得处于 行组 状态;如果元素未锚定在 列组 中,则不得处于 列组 状态。

th 元素可以指定一个 abbr 内容属性。其值必须是表头单元格的替代标签,用于在其他上下文中引用该单元格(例如在描述适用于数据单元格的表头单元格时)。它通常是完整表头单元格的缩写形式,但也可以是扩展形式,或只是不同的措辞。

th 元素及其 colspanrowspanheadersscope 属性参与 表模型

以下示例展示了 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 的表头适用于其行组中的所有单元格,除了第一列中的单元格。

剩余的表头仅适用于它们右侧的单元格。

4.9.11 tdth元素的共有属性

tdth元素可以有一个colspan内容属性,该属性的值必须是大于零且小于或等于1000的有效非负整数

tdth元素还可以有一个rowspan内容属性,该属性的值必须是小于或等于65534的有效非负整数。对于该属性,值为零表示单元格将跨越行组中的所有剩余行。

这些属性分别给出了单元格要跨越的列数和行数。如表模型描述的那样,这些属性不得用于重叠单元格。


tdth元素可以有一个headers内容属性。如果指定了headers属性,其值必须包含一个字符串,该字符串由唯一的空格分隔的标记组成,这些标记的值必须是与tdth元素(如表模型所定义)在同一表中的th元素的ID。

具有ID idth元素被认为是同一表中所有具有headers属性且其值包含该ID的tdth元素直接目标。如果存在一个元素C,它本身被元素B作为目标,而AC直接作为目标,则元素A被认为是被元素B作为目标

th元素不得自目标自身。

colspanrowspanheaders属性参与表模型


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属性必须反映相同名称的内容属性。

4.9.12 处理模型

各种表格元素及其内容属性共同定义了表模型

一个表格由在二维网格上的对齐单元格组成,具有坐标(x, y)。网格是有限的,并且是空的或有一个或多个槽。如果网格有一个或多个槽,则x坐标始终在范围0 ≤ x < xwidth y坐标始终在范围0 ≤ y < yheight 内。如果xwidthyheight之一或两者为零,则该表为空(没有槽)。表对应于table元素。

一个单元格是锚定在槽(cellx, celly)上的一组槽,并具有特定的widthheight,使单元格覆盖所有具有坐标(x, y)的槽,其中cellxx < cellx+width cellyy < 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 < xwidthgroupy ≤ y < groupy+height。行组对应于 tbodytheadtfoot 元素。并非每一行都必须在一个行组中。

列组是一组锚定在位置 (groupx, 0) 具有特定 width,使得列组覆盖所有坐标 (x, y) 的槽,其中 groupx ≤ x < groupx+width0 ≤ y < yheight。列组对应于 colgroup 元素。并非每一列都必须在一个列组中。

行组不能相互重叠。同样,列组也不能相互重叠。

一个单元格不能覆盖两个或多个行组的槽。然而,一个单元格可以位于多个列组中。一个单元格的所有槽要么是零个,要么是一个行组的一部分,并且是零个或多个列组的一部分。

除了单元格行组列组表格可以有一个caption 元素与之关联。这为表格提供了标题或说明。

表模型错误是指由table元素及其后代表示的数据错误。文档中不应有表模型错误。

4.9.12.1 表格的形成

为了确定哪些元素对应于与table元素关联的表格中的哪些槽,确定表格的尺寸(xwidthyheight),以及确定是否存在表模型错误,用户代理必须使用以下算法:

  1. xwidth为零。

  2. yheight为零。

  3. pending tfoot元素tfoot元素的列表,初始为空。

  4. the table为由table元素表示的表格xwidthyheight变量给出了the table的尺寸。the table最初是空的。

  5. 如果table元素没有子元素,则返回the table(它将是空的)。

  6. 将第一个caption元素子元素与table元素关联起来。如果没有这样的子元素,那么它没有关联的caption元素。

  7. current elementtable元素的第一个子元素。

    如果算法中的某个步骤需要将current element 推进到table的下一个子元素,而没有这样的下一个子元素,那么用户代理必须跳到算法结尾附近标记为end的步骤。

  8. current element不是以下元素之一时,将current element 推进table的下一个子元素:

  9. 如果current elementcolgroup,请按照以下子步骤进行:

    1. 列组:根据下面的适当情况处理current element

      如果current element有任何col元素子元素

      按照以下步骤进行:

      1. xstart的值为xwidth

      2. current columncolgroup元素的第一个col元素子元素。

      3. :如果current column col元素具有span属性,则使用解析非负整数的规则解析其值。

        如果解析结果不是错误或零,则令span为该值。

        否则,如果col元素没有span属性,或者尝试解析属性的值导致错误或零,则令span为1。

        如果span大于1000,则令其为1000。

      4. xwidth增加span

      5. the table中的最后span列对应于current column col元素。

      6. 如果current column不是colgroup元素的最后一个col元素子元素,则令current columncolgroup元素的下一个col元素子元素,并返回到标记为的步骤。

      7. 让所有从 x=xstartx=xwidth-1 的最后 the table 中形成一个新的 列组,锚定在位置 (xstart, 0),宽度为 xwidth-xstart,对应于 colgroup 元素。

      如果current element没有col元素子元素
      1. 如果colgroup元素具有span属性,则使用解析非负整数的规则解析其值。

        如果解析结果不是错误或零,则令span为该值。

        否则,如果colgroup元素没有span属性,或者尝试解析属性的值导致错误或零,则令span为1。

        如果span大于1000,则令其为1000。

      2. xwidth增加span

      3. the table中的最后span列形成一个新的列组,以xwidth-span为锚点,宽度为span,对应于colgroup元素。

    2. 推进 current elementtable的下一个子元素。

    3. current element不是以下元素之一时,将current element 推进table的下一个子元素:

    4. 如果current elementcolgroup元素,跳到上面标记为列组的步骤。

  10. ycurrent为零。

  11. list of downward-growing cells为空列表。

  12. :当current element不是以下元素之一时,将current element 推进table的下一个子元素:

  13. 如果current elementtr,则运行行处理算法,将current element 推进table的下一个子元素,并返回到标记为的步骤。

  14. 运行行组结束算法

  15. 如果current elementtfoot,则将该元素添加到pending tfoot元素列表中,将current element 推进table的下一个子元素,并返回到标记为的步骤。

  16. 当前元素current elementtheadtbody

    运行行组处理算法

  17. current element 推进table的下一个子元素。

  18. 返回到标记为的步骤。

  19. 结束:对于pending tfoot元素列表中的每个tfoot元素,按树顺序运行行组处理算法

  20. 如果the table中存在仅包含没有被锚定到它们的单元,那么这是一个表模型错误

  21. 返回the table

上面的步骤集中调用的行组处理算法是:

  1. ystart的值为yheight

  2. 对于作为正在处理的元素的子元素的每个tr元素,按树顺序运行行处理算法

  3. 如果 yheight > ystart,那么让所有从 y=ystarty=yheight-1 的最后 the table 中形成一个新的 行组,锚定在坐标 (0, ystart) 的位置,高度为 yheight-ystart,对应于正在处理的元素。

  4. 运行行组结束算法

当上述算法要求用户代理运行行组结束算法时,用户代理必须遵循以下步骤:

  1. ycurrent小于yheight时,执行以下步骤:

    1. 运行向下生长的单元算法

    2. ycurrent增加1。

  2. 清空list of downward-growing cells

上述算法调用的行处理算法是:

  1. 如果yheight等于ycurrent,则将yheight增加1。(ycurrent从不大于yheight。)

  2. xcurrent为0。

  3. 运行向下生长的单元算法

  4. 如果正在处理的tr元素没有tdth元素子元素,则将ycurrent增加1,中止此步骤集,并返回到上面的算法。

  5. current cell为正在处理的tr元素中的第一个tdth元素子元素。

  6. 单元格:当xcurrent小于xwidth且坐标为(xcurrent, ycurrent)的槽已经有单元格分配给它时,将xcurrent增加1。

  7. 如果xcurrent等于xwidth,则将xwidth增加1。(xcurrent从不大于xwidth。)

  8. 如果current cellcolspan属性,则解析该属性的值,并令colspan为结果。

    如果解析该值失败或返回零,或者该属性不存在,则令colspan为1。

    如果colspan大于1000,则令其为1000。

  9. 如果current cellrowspan属性,则解析该属性的值,并令rowspan为结果。

    如果解析该值失败或该属性不存在,则令rowspan为1。

    如果rowspan大于65534,则令其为65534。

  10. 如果rowspan为零且table元素的节点文档未设置为怪癖模式,则令cell grows downward为真,并将rowspan设置为1。否则,令cell grows downward为假。

  11. 如果xwidth < xcurrent+colspan,则令xwidthxcurrent+colspan

  12. 如果yheight < ycurrent+rowspan,则令yheightycurrent+rowspan

  13. 让坐标为(x, y)的槽覆盖由新单元c覆盖,其锚点为(xcurrent, ycurrent),宽度为colspan,高度为rowspan,对应于current cell元素。

    如果current cell元素是th元素,则让这个新单元c为一个标题单元格;否则,让它为一个数据单元格。

    要确定哪些标题单元格适用于current cell元素,请使用下一节中描述的分配标题单元格的算法

    如果涉及的任何槽已经有单元覆盖,则这是一个表模型错误。那些槽现在有两个重叠的单元。

  14. 如果cell grows downward为真,则将元组{c, xcurrent, colspan}添加到list of downward-growing cells

  15. xcurrent增加colspan

  16. 如果current cell是正在处理的tr元素中的最后一个tdth元素子元素,则将ycurrent增加1,中止此步骤集,并返回到上面的算法。

  17. current cell为正在处理的tr元素中的下一个tdth元素子元素。

  18. 返回到标记为单元格的步骤。

当上述算法要求用户代理运行向下生长的单元算法时,用户代理必须对list of downward-growing cells中的每个{cell, cellx, width}元组,如果有,将单元cell扩展,以便它还覆盖坐标为(x, ycurrent)的槽,其中cellx ≤ x < cellx+width

4.9.12.2 在数据单元格和标题单元格之间形成关系

每个单元格可以分配零个或多个标题单元格。将标题单元格分配算法分配给单元格principal cell的过程如下。

  1. header list为空单元格列表。

  2. 令(principalx, principaly)为principal cell锚定的槽的坐标。

  3. 如果principal cell指定了headers属性
    1. principal cellheaders属性值并按ASCII空白字符分割,得到id list

    2. 对于id list中的每个令牌,如果文档中第一个ID等于该令牌的元素是同一表格中的单元格,并且该单元格不是principal cell,则将该单元格添加到header list

    如果principal cell没有指定headers属性
    1. principalwidthprincipal cell的宽度。

    2. principalheightprincipal cell的高度。

    3. 对于从principalyprincipaly+principalheight-1的每个y值,运行扫描和分配标题单元格的内部算法,使用principal cellheader list、初始坐标(principalx, y)和增量Δx=−1Δy=0

    4. 对于从principalxprincipalx+principalwidth-1的每个x值,运行扫描和分配标题单元格的内部算法,使用principal cellheader list、初始坐标(x, principaly)和增量Δx=0Δy=−1

    5. 如果principal cell锚定在一个行组中,则将所有在同一行组中锚定并且x坐标小于或等于principalx+principalwidth-1且y坐标小于或等于principaly+principalheight-1的行组标题单元格添加到header list中。

    6. 如果principal cell锚定在一个列组中,则将所有在同一列组中锚定并且x坐标小于或等于principalx+principalwidth-1且y坐标小于或等于principaly+principalheight-1的列组标题单元格添加到header list中。

  4. header list中移除所有空单元格

  5. header list中移除所有重复项。

  6. 如果principal cellheader list中,则将其移除。

  7. header list中的标题分配给principal cell

扫描和分配标题单元格的内部算法,给定一个principal cell、一个header list、初始坐标(initialx, initialy)和Δx和Δy增量,过程如下:

  1. x等于initialx

  2. y等于initialy

  3. opaque headers为空单元格列表。

  4. 如果principal cell是一个标题单元格

    in header block为true,并令headers from current header block为包含principal cell的单元格列表。

    否则

    in header block为false,并令headers from current header block为空单元格列表。

  5. 循环:将x增加Δx;将y增加Δy

    对于此算法的每次调用,Δx和Δy中的一个将为-1,另一个将为0。

  6. 如果xy小于0,则中止此内部算法。

  7. 如果没有单元格覆盖槽(x, y),或者有多个单元格覆盖槽(x, y),则返回到标记为循环的子步骤。

  8. current cell为覆盖槽(x, y)的单元格。

  9. 如果current cell是一个标题单元格
    1. 设置in header block为true。

    2. current cell添加到headers from current header block中。

    3. blocked为false。

    4. 如果Δx为0

      如果在opaque headers列表中有任何单元格锚定的x坐标与current cell相同,且宽度与current cell相同,则令blocked为true。

      如果current cell不是列标题,则令blocked为true。

      如果Δy为0

      如果在opaque headers列表中有任何单元格锚定的y坐标与current cell相同,且高度与current cell相同,则令blocked为true。

      如果current cell不是行标题,则令blocked为true。

    5. 如果blocked为false,则将current cell添加到header list中。

    如果current cell是一个数据单元格且in header block为true

    设置in header block为false。将headers from current header block中的所有单元格添加到opaque headers列表中,并清空headers from current header block列表。

  10. 返回到标记为循环的步骤。

锚定在坐标(x, y)、宽度为width、高度为height的槽上的标题单元格,如果符合以下任一条件,则称为列标题

锚定在坐标(x, y)、宽度为width、高度为height的槽上的标题单元格,如果符合以下任一条件,则称为行标题

如果其scope属性处于列组状态,则该标题单元格称为列组标题

如果其scope属性处于行组状态,则该标题单元格称为行组标题

如果单元格不包含任何元素,并且其子文本内容(如果有的话)仅由ASCII空白字符组成,则称为空单元格

4.9.13 示例

本节为非规范性内容。

以下显示了如何标记《史密森物理表,第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&nbsp;mm or 2&nbsp;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>

该表可能如下所示:

规格值:铸件,ASTM A27-16年,B类;* P最大值0.06;S最大值0.05。
等级。 屈服点。 极限抗拉强度 延伸率。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%

4.10 表单

Element#Forms

所有当前引擎均支持。

Firefox4+Safari4+Chrome61+
Opera52+Edge79+
Edge (旧版)16+Internet Explorer10+
Firefox Android5+Safari iOS3.2+Chrome Android61+WebView Android61+Samsung Internet8.0+Opera Android47+

4.10.1 介绍

本节为非规范性内容。

表单是网页的一个组件,包含表单控件,如文本框、按钮、复选框、范围选择器或颜色选择器控件。用户可以与这些表单进行交互,提供数据,然后可以将这些数据发送到服务器进行进一步处理(例如返回搜索或计算的结果)。在许多情况下,不需要客户端脚本,尽管提供了一个API,以便脚本可以增强用户体验或将表单用于提交数据到服务器以外的目的。

编写表单包括几个步骤,这些步骤可以按任何顺序执行:编写用户界面、实现服务器端处理以及配置用户界面与服务器通信。

4.10.1.1 编写表单的用户界面

本节为非规范性内容。

为了简单介绍,我们将创建一个披萨订购表单。

任何表单都从一个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来询问送货时间。许多这些表单控件都有属性来精确控制可以指定的值;在这种情况下,特别感兴趣的三个属性是minmaxstep。这些设置了最小时间、最大时间和允许值之间的间隔(以秒为单位)。这家披萨店只在上午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>
4.10.1.2 实现表单的服务器端处理

本节为非规范性内容。

编写服务器端处理器的具体细节不在本规范范围内。为了介绍的目的,我们假设https://pizza.example.com/order.cgi上的脚本配置为接受使用application/x-www-form-urlencoded格式的提交,期望在HTTP POST主体中发送以下参数:

custname
顾客的姓名
custtel
顾客的电话号码
custemail
顾客的电子邮件地址
size
披萨尺寸,值可以是smallmediumlarge
topping
一种配料,每选一个配料就指定一次,允许的值是baconcheeseonionmushroom
delivery
请求的送货时间
comments
送货说明
4.10.1.3 配置表单与服务器通信

本节为非规范性内容。

表单提交通过多种方式暴露给服务器,最常见的是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=
4.10.1.4 客户端表单验证

Form_validation

Support in all current engines.

Firefox4+Safari5+Chrome4+
Opera≤12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android≤37+Samsung Internet?Opera Android≤12.1+

本节为非规范性内容。

表单可以进行注释,以便用户代理在表单提交之前检查用户的输入。服务器仍然需要验证输入是否有效(因为恶意用户可以轻松绕过表单验证),但这允许用户避免仅由服务器检查用户输入所带来的等待。

最简单的注释是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事件。这对于显示表单问题的摘要很有用,因为通常浏览器本身只会一次报告一个问题。

4.10.1.5 启用客户端自动填充表单控件

本节为非规范性内容。

一些浏览器尝试通过自动填充表单控件来帮助用户,而不是每次都让用户重新输入他们的信息。例如,一个请求用户电话号码的字段可以自动填充用户的电话号码。

为了帮助用户代理实现这一点,可以使用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>
4.10.1.6 改善移动设备上的用户体验

本节为非规范性内容。

某些设备,特别是那些带有虚拟键盘的设备,可以为用户提供多种输入模式。例如,当输入信用卡号码时,用户可能只希望看到数字键(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>
4.10.1.7 字段类型、自动填充字段名称和输入模式之间的区别

本节为非规范性内容。

typeautocompleteinputmode属性看起来似乎很相似。例如,在这三种情况下,字符串“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"部分对用户代理是透明的;用户代理无法从这些部分猜测出两个名字分别应为日语和英语。

除了关于typeautocomplete的选择外,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>
4.10.1.8 日期、时间和数字格式

本节是非规范性的。

在这个披萨配送的例子中,时间的格式是“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或提交之前将其转换回“在线传输”格式。

这样,页面和服务器上的脚本可以以一致的方式处理时间、日期和数字,而不需要支持几十种不同的格式,同时仍能满足用户的需求。

另请参见有关表单控件本地化的实现说明

4.10.2 类别

主要是由于历史原因,本节中的元素除了通常的类别,如流内容短语内容交互内容外,还属于几个重叠(但稍有不同)的类别。

许多元素是表单关联元素,这意味着它们可以有一个表单所有者

表单关联元素分为几个子类别:

列出的元素

表示在 form.elementsfieldset.elements API 中列出的元素。这些元素还具有一个 form 内容属性,以及相应的 form IDL 属性,允许作者指定明确的 表单所有者

可提交的元素

表示在 form 元素提交时,可用于构建输入项列表的元素。

某些可提交的元素,取决于其属性,可能是按钮。下面的内容定义了元素何时为按钮。有些按钮是特定的提交按钮

可重置的元素

表示当 form 元素重置时,会受到影响的元素。

自动大写和自动更正继承的元素

表示从其表单所有者继承autocapitalizeautocorrect属性的元素。

一些元素,并非所有元素都是表单关联元素,被归类为可标记元素。这些是可以与label元素关联的元素。

4.10.3 form 元素

Element/form

Support in all current engines.

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLFormElement

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
类别:
流内容.
可感知内容.
此元素可用的上下文:
当预期为流内容时.
内容模型:
流内容, 但没有 form 元素的后代.
text/html中的标签省略:
没有标签可以省略.
内容属性:
全局属性
accept-charset — 用于 表单提交的字符编码
action — 用于 URL 表单提交
autocomplete — 表单控件自动填充功能的默认设置
enctype — 用于条目列表编码类型 表单提交
method — 用于 表单提交 的变体
name — 在document.formsAPI中的表单名称
novalidate — 绕过表单控件验证 表单提交
target导航 表单提交
rel
无障碍考虑:
对于作者.
对于实现者.
DOM接口:
[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-8ASCII大小写不敏感匹配。[ENCODING]

name属性表示formforms集合中的名称。该值不能是空字符串,并且该值在其所在的form元素集合中必须是唯一的。

autocomplete属性是一个枚举属性,具有以下关键字和状态:

关键字 状态 简要描述
on on 表单控件将默认其自动填充字段名称设置为"on"。
off off 表单控件将默认其自动填充字段名称设置为"off"。

属性的缺省值无效值默认均为on状态。

actionenctypemethodnovalidate,以及target属性是表单提交属性

rel属性在form元素上控制元素创建的链接类型。属性的值必须是无序的唯一空格分隔的标记集合。允许的关键字及其含义定义在前面的章节中。

rel支持的标记是HTML链接类型中定义的关键字,这些关键字允许在form元素上使用,影响处理模型,并且由用户代理支持。可能的支持的标记noreferrernoopener,以及openerrel支持的标记只能包括用户代理实现处理模型的列表中的标记。

form.elements

HTMLFormElement/elements

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android? Samsung Internet?Opera Android10.1+

返回表单中的<form>元素控件(出于历史原因,不包括图像按钮)的HTMLFormControlsCollection

form.length

HTMLFormElement/length

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回表单中表单控件的数量(出于历史原因,不包括图像按钮)。

form[index]

返回表单中的第index个元素(出于历史原因,不包括图像按钮)。

form[name]

返回具有给定IDname的表单控件(如果有多个,则返回表单控件的RadioNodeList);如果没有,则返回具有给定ID的img元素。

一旦使用特定名称引用了某个元素,即使元素的实际IDname发生变化,只要元素仍在中,该名称仍可用于引用该元素。

如果有多个匹配项,则返回包含所有这些元素的RadioNodeList对象。

form.submit()

HTMLFormElement/submit

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

提交表单,绕过交互约束验证,并且不会触发submit事件。

form.requestSubmit([ submitter ])

HTMLFormElement/requestSubmit

Support in all current engines.

Firefox75+Safari16+Chrome76+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

请求提交表单。与submit()不同,此方法包括交互约束验证和触发submit事件,这两者都可以取消提交。

可以使用submitter参数指向特定的提交按钮,其formactionformenctypeformmethodformnovalidate,以及formtarget属性可以影响提交。此外,在构建提交的条目列表时将包括提交者;通常按钮会被排除。

form.reset()

HTMLFormElement/reset

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

重置表单。

form.checkValidity()

如果表单的控件全部有效,则返回true;否则返回false。

form.reportValidity()

如果表单的控件全部有效,则返回true;否则返回false,并通知用户。

autocomplete IDL属性必须反映同名内容属性,仅限于已知值

HTMLFormElement/name

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

namerel IDL属性必须反映同名内容属性。

HTMLFormElement/acceptCharset

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

acceptCharset IDL属性必须反映accept-charset内容属性。

relList IDL属性必须反映rel内容属性。


elements IDL属性必须返回一个以HTMLFormControlsCollection为根的form元素的,其过滤器匹配其表单所有者form元素的列出元素,但出于历史原因,必须从此特定集合中排除input元素,其type属性处于图像按钮状态。

length IDL属性必须返回elements集合所代表的节点数量

在任何时刻支持的属性索引是由elements属性返回的对象在该时刻支持的索引。

确定索引属性的值对于form元素,用户代理必须返回item方法在elements集合上返回的值,当使用给定的索引作为其参数调用时。


每个form元素都有一个称为过去名称映射的名称到元素的映射。它用于在控件更改名称时持久化其名称。

支持的属性名称由以下算法获得的名称组成,按照从该算法获得的顺序:

  1. sourced names为一个最初为空的有序元组列表,由字符串、元素、来源组成,其中来源可以是idname,或past,如果来源是past,则还有一个年龄。

  2. 对于其表单所有者form元素的每个列出元素 candidate,但出于历史原因,排除input元素,其type属性处于图像按钮状态:

    1. 如果candidateid属性,则添加一个条目到sourced names,其中该id属性的值作为字符串,candidate作为元素,并将id作为来源。

    2. 如果candidatename属性,则添加一个条目到sourced names,其中该name属性的值作为字符串,candidate作为元素,并将name作为来源。

  3. 对于其表单所有者form元素的每个img元素 candidate

    1. 如果candidateid属性,则添加一个条目到sourced names,其中该id属性的值作为字符串,candidate作为元素,并将id作为来源。

    2. 如果candidatename属性,则添加一个条目到sourced names,其中该name属性的值作为字符串,candidate作为元素,并将name作为来源。

  4. 对于过去名称映射中的每个条目past entry,将一个条目添加到sourced names,其中past entry的名称作为字符串,past entry的元素作为元素,将past作为来源,并且past entry过去名称映射中存在的时间长度作为年龄。

  5. 按每个元组的元素条目的树顺序排序sourced names,将相同元素的条目排序为先按id,然后按name,最后按past,并按相同元素和来源的条目按其年龄排序,最老的排在前面。

  6. 删除sourced names中名称为空字符串的条目。

  7. 删除sourced names中与前面条目名称相同的条目。

  8. 按相对顺序返回sourced names中的名称列表。

确定命名属性的值name对于form元素,用户代理必须运行以下步骤:

  1. candidates成为一个实时RadioNodeList对象,包含所有列出元素,其表单所有者form元素,并且具有等于nameid属性或name属性,但出于历史原因,排除其type属性处于图像按钮状态的input元素,按树顺序排序。

  2. 如果candidates为空,让candidates成为一个实时RadioNodeList对象,包含所有img元素,其表单所有者form元素,并且具有等于nameid属性或name属性,按树顺序排序。

  3. 如果candidates为空,并且nameform元素的过去名称映射中的一个条目的名称:返回与该名称相关联的对象在该映射中。

  4. 如果candidates包含多个节点,则返回candidates

  5. 否则,candidates只包含一个节点。在form元素的过去名称映射中添加一个从namecandidates中的节点的映射,替换具有相同名称的先前条目(如果有)。

  6. 返回candidates中的节点。

如果在form元素的过去名称映射中列出的元素更改了表单所有者,则必须从该映射中删除其条目。


submit()方法步骤是从submit()方法设置为true的状态下提交this

requestSubmit(submitter)方法在调用时,必须执行以下步骤:

  1. 如果submitter不为null,则:

    1. 如果submitter不是提交按钮,则抛出TypeError

    2. 如果submitter表单所有者不是该form元素,则抛出"NotFoundError"DOMException

  2. 否则,将submitter设置为该form元素。

  3. 提交form元素,来自submitter

reset()方法在调用时,必须执行以下步骤:

  1. 如果form元素标记为重置锁定,则返回。

  2. 标记form元素为重置锁定

  3. 重置form元素。

  4. 取消标记form元素的重置锁定

如果调用了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>

4.10.4 label 元素

Element/label

支持所有当前的引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLLabelElement

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
分类:
流内容
短语内容
交互内容
感知内容
此元素可使用的上下文:
期望 短语内容 的地方。
内容模型:
短语内容,但无后代 可标记元素,除非它是元素的 标记控件,并且无后代 label 元素。
在 text/html 中省略标签:
两个标签都不可省略。
内容属性:
全局属性
for — 将标签与表单控件关联
无障碍考虑:
作者使用
实现者使用
DOM 接口:
[Exposed=Window]
interface HTMLLabelElement : HTMLElement {
  [HTMLConstructor] constructor();

  readonly attribute HTMLFormElement? form;
  [CEReactions] attribute DOMString htmlFor;
  readonly attribute HTMLElement? control;
};

label 元素 表示用户界面中的一个标题。标题可以与特定的表单控件关联,称为 label 元素的 标记控件,可以使用 for 属性,或通过将表单控件放在 label 元素内来实现。

除以下规则另有规定外,label 元素没有 标记控件

Attributes/for

支持所有当前的引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

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

HTMLLabelElement/control

支持所有当前的引擎。

Firefox4+Safari5.1+Chrome6+
Opera12.1+Edge79+
Edge (旧版)18Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+

返回与此元素关联的表单控件。

label.form

HTMLLabelElement/form

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回与此元素关联的表单控件的 表单所有者

如果没有则返回 null。

HTMLLabelElement/htmlFor

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

htmlFor IDL 属性必须 反映 for 内容属性。

control IDL 属性必须返回 label 元素的 标记控件,如果有的话,否则返回 null。

form IDL 属性必须执行以下步骤:

  1. 如果 label 元素没有 标记控件,则返回 null。

  2. 如果 label 元素的 标记控件 不是 表单关联元素,则返回 null。

  3. 返回 label 元素的 标记控件表单所有者(仍然可以是 null)。

form IDL 属性与 label 元素上的 form IDL 属性不同,label 元素没有 form 内容属性。


control.labels

HTMLButtonElement/labels

支持所有当前的引擎。

Firefox56+Safari5.1+Chrome6+
Opera12.1+Edge79+
Edge (旧版)18Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android3+ Samsung Internet?Opera Android12.1+

HTMLInputElement/labels

支持所有当前的引擎。

Firefox56+Safari5+Chrome6+
Opera12.1+Edge79+
Edge (旧版)18Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+

HTMLMeterElement/labels

支持所有当前的引擎。

Firefox56+Safari6+Chrome6+
Opera12.1+Edge79+
Edge (旧版)18Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLOutputElement/labels

支持所有当前的引擎。

Firefox56+Safari5.1+Chrome9+
Opera12.1+Edge79+
Edge (旧版)18Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+

HTMLProgressElement/labels

支持所有当前的引擎。

Firefox56+Safari6+Chrome6+
Opera12.1+Edge79+
Edge (旧版)18Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLSelectElement/labels

支持所有当前的引擎。

Firefox56+Safari5.1+Chrome6+
Opera12.1+Edge79+
Edge (旧版)18Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+

HTMLTextAreaElement/labels

支持所有当前的引擎。

Firefox56+Safari5.1+Chrome6+
Opera12.1+Edge79+
Edge (旧版)18Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+

返回与表单控件关联的所有 NodeList

可标记元素 和所有 input 元素都有一个 live NodeList 对象,表示按 树序排列的 label 元素列表,其 标记控件 是相应的元素。不是 表单关联的自定义元素可标记元素labels IDL 属性和 labels IDL 属性,在获取时,必须返回该 NodeList 对象,并且必须始终返回相同的值,除非此元素是 input 元素,其 type 属性处于 隐藏 状态,则它必须返回 null。

ElementInternals/labels

支持所有当前的引擎。

Firefox98+Safari16.4+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

表单关联的自定义元素 没有 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>

4.10.5 input 元素

Element/input

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android1+Samsung Internet?Opera Android12.1+

Element/input

HTMLInputElement

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+
类别:
流内容.
短语内容.
如果 type 属性 不是 隐藏 状态: 交互内容.
如果 type 属性不是 隐藏状态:列出的可标记的可提交的可重置的,以及自动大写和自动更正继承的 与表单关联的元素
如果 type 属性是隐藏状态:列出的可提交的可重置的,以及自动大写和自动更正继承的 与表单关联的元素
如果 type 属性 不是 隐藏 状态: 显著内容.
该元素可用于的上下文:
期望 短语内容 的地方。
内容模型:
.
在 text/html 中标签省略:
结束标签.
内容属性:
全局属性
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 属性在 按钮 状态: 供作者使用; 供实现者使用.
DOM 接口:
[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() 方法,以及 inputchange 事件 适用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 对象转换为字符串的 算法,这些算法被 maxminstepvalueAsDatevalueAsNumber,以及 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 checkednessdirty checkedness flag 必须在元素创建时初始化为 false,并且在用户以更改 checkedness 的方式与控件交互时必须设置为 true。

Element/input#checked

所有当前浏览器均支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

checked 内容属性是一个 布尔属性,用于指定 checkedness(选中状态)为 input 元素的默认值。当添加 checked 内容属性时,如果控件没有 脏选中状态,用户代理必须将该元素的 checkedness 设置为 true;当移除 checked 内容属性时,如果控件没有 脏选中状态,用户代理必须将该元素的 checkedness 设置为 false。

重置算法 适用于 input 元素,需将其 用户有效性脏值标志脏选中状态标志 恢复为 false,将元素的 设置为 value 内容属性的值(如果存在),否则为空字符串,将元素的 checkedness 设置为 true(如果元素具有 checked 内容属性)或 false(如果没有),清空 选定的文件 列表,然后调用 值清理算法,如果 type 属性的当前状态定义了一个。

每个 input 元素可以是 可变的。除非另有说明,input 元素始终是 可变的。同样,除非另有说明,用户代理不应允许用户修改元素的 选中状态

input 元素被 禁用 时,它不是 可变的

readonly 属性在某些情况下(例如,Date 状态,但不是 Checkbox 状态)也可以阻止 input 元素变为 可变的

对于 input 元素,克隆步骤 必须将节点被克隆的 脏值标志选中状态脏选中状态标志 从被克隆的节点传播到副本。

对于 input 元素,给定 event激活行为 包括以下步骤:

  1. 如果 element 不是 可变的,且不在 Checkbox 状态下,也不在 Radio 状态下,则返回。

  2. 运行 elementinput 激活行为(如果有),否则不做任何操作。

  3. element 上运行 弹出目标属性激活行为

请记住,元素的 激活行为 适用于用户发起的激活以及合成激活(例如,通过 el.click())。用户代理也可能对给定控件有特定的行为——这些行为在此未指定——这些行为仅由真正的用户发起的激活触发。一个常见的选择是 在适用的情况下显示选择器。与此相对,input 激活行为 仅在特殊的历史情况下(例如 文件上传颜色 状态)显示选择器。

传统预激活行为 适用于 input 元素,包括以下步骤:

  1. 如果该元素的 type 属性在 Checkbox 状态 中,则将该元素的 选中状态 设置为相反的值(即如果为 false 则设置为 true,如果为 true 则设置为 false),并将该元素的 indeterminate IDL 属性设置为 false。

  2. 如果该元素的 type 属性在 Radio Button 状态 中,则获取该元素所在的 单选按钮组 中选中状态为 true 的元素的引用(如果有),然后将该元素的 选中状态 设置为 true。

传统取消激活行为 适用于 input 元素,包括以下步骤:

  1. 如果该元素的 type 属性在 Checkbox 状态 中,则将该元素的 选中状态 和该元素的 indeterminate IDL 属性恢复到在 传统预激活行为 运行之前的值。

  2. 如果该元素的 type 属性在 Radio Button 状态 中,则如果在 传统预激活行为 中获取的引用元素仍在当前元素的 单选按钮组 中(如果有),则将该元素的 选中状态 设置为 true;否则,如果没有这样的元素,或该元素不再在当前元素的 单选按钮组 中,或者当前元素不再有 单选按钮组,则将该元素的 选中状态 设置为 false。


input 元素首次创建时,该元素的渲染和行为必须设置为定义的 type 属性状态的渲染和行为,并且如果有定义,则必须调用 值清理算法

input 元素的 type 属性状态发生变化时,用户代理必须执行以下步骤:

  1. 如果元素的 type 属性的先前状态将 value IDL 属性设置为 value 模式,并且元素的 不是空字符串,且元素的 type 属性的新状态将 value IDL 属性设置为 default 模式或 default/on 模式,则将元素的 value 内容属性设置为元素的

  2. 否则,如果元素的 type 属性的先前状态将 value IDL 属性设置为 value 模式以外的任何模式,且元素的 type 属性的新状态将 value IDL 属性设置为 value 模式,则将元素的 设置为 value 内容属性的值(如果有),否则为空字符串,然后将控件的 脏值标志 设置为 false。

  3. 否则,如果元素的 type 属性的先前状态将 value IDL 属性设置为 filename 模式以外的任何模式,且元素的 type 属性的新状态将 value IDL 属性设置为 filename 模式,则将元素的 设置为空字符串。

  4. 更新元素的渲染和行为为新状态的渲染和行为。

  5. 发出类型变化信号。特别是,Radio Button 状态使用此信号。

  6. 如果为 type 属性的新状态定义了值清理算法,则调用 值清理算法

  7. 如果 setRangeText() 之前对元素应用了 应用,则让 previouslySelectable 为 true,否则为 false。

  8. 如果 setRangeText() 现在对元素 应用,则让 nowSelectable 为 true,否则为 false。

  9. 如果 previouslySelectable 为 false 且 nowSelectable 为 true,则将元素的 文本输入光标位置 设置为文本控件的开始位置,并将其选择方向 设置 为 "none"。


name 属性表示元素的名称。 dirname 属性控制元素的 方向性 的提交方式。 disabled 属性用于使控件不可交互,并防止其值被提交。 form 属性用于显式地将 input 元素与其 表单拥有者 关联。 autocomplete 属性控制用户代理如何提供自动填充行为。

HTMLInputElement#indeterminate

所有当前引擎的支持情况。

Firefox3.6+Safari3+Chrome1+
Opera≤12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android≤12.1+
caniuse.com 表格

indeterminate IDL 属性必须最初设置为 false。获取时,必须返回最后设置的值。设置时,必须设置为新值。除了改变 复选框 控件的外观外,没有其他效果。

HTMLInputElement/multiple

所有当前引擎的支持情况。

Firefox3.6+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

acceptaltmaxminmultiplepatternplaceholderrequiredsizesrcstep IDL 属性必须 反映 同名的内容属性。dirName IDL 属性必须 反映 dirname 内容属性。readOnly IDL 属性必须 反映 readonly 内容 属性。defaultChecked IDL 属性必须 反映 checked 内容属性。defaultValue IDL 属性必须 反映 value 内容属性。

type IDL 属性必须 反映 同名的内容属性,仅限于已知值maxLength IDL 属性必须 反映 maxlength 内容属性,仅限于非负数minLength IDL 属性必须 反映 minlength 内容属性,仅限于非负数

IDL 属性 widthheight 必须返回图像的渲染宽度和 高度,单位为 CSS 像素,如果图像 正在渲染;否则返回图像的 自然宽度和高度,单位为 CSS 像素,如果图像 可用 但未 渲染;否则返回 0, 如果图像不可 可用。当 input 元素的 type 属性不在 图像按钮 状态时,则没有图像 可用[CSS]

设置时,它们必须表现得好像它们 反映 同名的内容属性。

willValidatevalidity, 和 validationMessage IDL 属性,以及 checkValidity()reportValidity(), 和 setCustomValidity() 方法,都是 约束验证 API 的一部分。labels IDL 属性提供元素的 label 列表。 select()selectionStartselectionEndselectionDirectionsetRangeText(), 和 setSelectionRange() 方法和 IDL 属性公开元素的文本选择。disabledform, 和 name IDL 属性是元素表单 API 的一部分。

4.10.5.1 type 属性的状态
4.10.5.1.1 隐藏 状态(type=hidden

Element/input/hidden

支持所有当前的浏览器引擎。

Firefox1+Safari1+Chrome1+
Opera2+Edge79+
Edge(传统版)12+Internet Explorer
Firefox AndroidSafari iOSChrome AndroidWebView AndroidSamsung InternetOpera Android

当一个 input 元素的 type 属性处于 隐藏 状态时,本节中的规则适用。

input 元素 表示 一个不打算由用户检查或操作的值。

约束验证:如果一个 input 元素的 type 属性处于 隐藏 状态时,它被 排除于约束验证之外

如果 name 属性存在且其值是与 "_charset_" 进行 ASCII 不区分大小写 匹配的,那么元素的 value 属性必须被省略。

autocompletedirname 内容属性 适用于 该元素。

value IDL 属性 适用于 该元素,并且处于 默认 模式。

以下内容属性不得被指定,并且 不适用于 该元素: accept, alt, checked, 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, list, selectionStart, selectionEnd, selectionDirection, valueAsDate, 和 valueAsNumber IDL 属性; select(), setRangeText(), setSelectionRange(), stepDown(), 和 stepUp() 方法。

以下事件 inputchange 不适用

4.10.5.1.2 文本 (type=text) 状态和 搜索 状态 (type=search)

Element/input/search

在所有当前引擎中支持。

Firefox4+Safari5+Chrome5+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Element/input/text

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

input 元素的 type 属性为 文本 状态或 搜索 状态时,本节中的规则适用。

input 元素 表示 一个单行纯文本编辑控件 用于该元素的

文本状态和搜索状态的主要区别在于样式:在那些将搜索控件与普通文本控件区分开来的平台上,搜索状态可能会使控件的外观与平台的搜索控件一致,而不是像普通文本控件那样呈现。

如果元素是 可变的,其 应该可以被用户编辑。用户代理不能允许 用户在元素的 中插入 U+000A 换行符 (LF) 或 U+000D 回车符 (CR) 字符。

如果元素是 可变的,用户代理应允许用户更改元素的书写方向,将其设置为从左到右的书写 方向或从右到左的书写方向。如果用户这样做,用户代理必须运行以下步骤:

  1. 如果用户选择了从左到右的书写方向,则将元素的 dir 属性设置为 "ltr" ;如果用户选择了从右到左的书写方向,则设置为 "rtl"。

  2. 在用户交互任务源 中排队一个元素任务,给定 元素以 触发名为 input 的事件,并将 bubblescomposed 属性初始化为 true。

如果指定了 value 属性,则其值中不得包含 U+000A 换行符 (LF) 或 U+000D 回车符 (CR) 字符。

值清理算法 如下 中剥离换行符。

以下常见的 input 元素内容 属性、IDL 属性和方法 适用于 该元素: autocomplete, dirname, list, maxlength, minlength, pattern, placeholder, readonly, required, 和 size 内容属性; listselectionStartselectionEndselectionDirection、 和 value IDL 属性; select()setRangeText()、 和 setSelectionRange() 方法。

value IDL 属性 处于 模式。

inputchange 事件 适用

以下内容属性不得指定且 不适用 于元素: acceptaltcheckedformactionformenctypeformmethodformnovalidateformtargetheightmaxminmultiplepopovertargetpopovertargetactionsrcstep、 和 width

以下 IDL 属性和方法 不适用 于元素: checkedfilesvalueAsDate、 和 valueAsNumber IDL 属性; stepDown()stepUp() 方法。

4.10.5.1.3 电话状态 (type=tel)

Element/input/tel

Support in all current engines.

FirefoxYesSafari4+Chrome3+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS3+Chrome Android18+WebView Android37+Samsung Internet?Opera Android11+

input 元素的 type 属性处于 Telephone 状态时,本节规则适用。

input 元素 代表 一个用于编辑电话号码的控件,该电话号码在元素的 value 中给出。

如果该元素是 可变的,其 value 应该是用户可编辑的。用户代理可以更改用户输入的 的间距,并在谨慎情况下更改标点符号。用户代理不得允许用户在元素的 value 中插入 U+000A 换行符 (LF) 或 U+000D 回车符 (CR) 字符。

value 属性(如果指定)必须具有不包含 U+000A 换行符 (LF) 或 U+000D 回车符 (CR) 字符的值。

值净化算法 如下:从 value删除换行符

URLEmail 类型不同,Telephone 类型不强制执行特定的语法。这是有意为之;实际上,电话号码字段往往是自由格式的字段,因为存在多种有效的电话号码。需要强制执行特定格式的系统建议使用 pattern 属性或 setCustomValidity() 方法来挂钩客户端验证机制。

以下常见的 input 元素内容 属性、IDL 属性和方法 适用于 该元素: autocompletedirnamelistmaxlengthminlengthpatternplaceholderreadonlyrequired, 和 size 内容属性; listselectionStartselectionEndselectionDirection, 和 value IDL 属性; select()setRangeText(), 和 setSelectionRange() 方法。

value IDL 属性处于 value 模式。

inputchange 事件 适用

以下内容属性不得指定并且 不适用 于该元素: acceptaltcheckedformactionformenctypeformmethodformnovalidateformtargetheightmaxminmultiplepopovertargetpopovertargetactionsrcstep, 和 width

以下 IDL 属性和方法 不适用于 该元素: checkedfilesvalueAsDate, 和 valueAsNumber IDL 属性; stepDown()stepUp() 方法。

4.10.5.1.4 URL 状态 (type=url)

Element/input/url

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

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 属性和方法 适用于 该元素: autocompletedirnamelistmaxlengthminlengthpatternplaceholderreadonlyrequired, 和 size 内容属性; listselectionStartselectionEndselectionDirection, 和 value IDL 属性; select()setRangeText(), 和 setSelectionRange() 方法。

value IDL 属性处于 value 模式。

inputchange 事件 适用

以下内容属性不得指定并且 不适用 于该元素: acceptaltcheckedformactionformenctypeformmethodformnovalidateformtargetheightmaxminmultiplepopovertargetpopovertargetactionsrcstep, 和 width

以下 IDL 属性和方法 不适用于 该元素: checkedfilesvalueAsDate, 和 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-parsinghttps://streams.spec.whatwg.org/,那么渲染结果可能如下所示:

一个文本框,左侧有一个图标,接着是文本"spec.w"和一个光标,右侧有一个下拉按钮;下面是一个包含六个URL列表的下拉框,左侧是URL,前四个URL右侧有灰色标签;下拉框右侧有一个滚动条,指示还有更多值可用。

此示例中的前四个URL由与用户输入文本匹配的作者指定列表中的四个URL组成,并以某种实现定义的方式排序(可能根据用户引用这些URL的频率)。请注意,UA利用了这些值是URL的知识,使用户可以省略方案部分并对域名进行智能匹配。

最后两个URL(以及可能更多的URL,根据滚动条指示有更多值可用)是用户代理的会话历史数据中的匹配项。这些数据不会提供给页面DOM。在这种特殊情况下,UA没有提供这些值的标题。

4.10.5.1.5 电子邮件 状态 (type=email)

Element/input/email

所有当前引擎支持。

Firefox1+Safari5+Chrome5+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android11+

input 元素的 type 属性处于 电子邮件 状态时,本节的规则适用。

电子邮件 状态的操作方式取决于是否指定了 multiple 属性。

当元素上未指定 multiple 属性时

input 元素 表示 用于编辑元素的 value 中给定的电子邮件地址的控件。

如果元素是 可变的,用户代理应允许用户更改其 value 表示的电子邮件地址。用户代理可以允许用户将 value 设置为不是 有效电子邮件地址 的字符串。用户代理应以与期望用户提供单个电子邮件地址一致的方式行事。用户代理应允许用户将 value 设置为空字符串。用户代理不得允许用户在 value 中插入 U+000A 换行符 (LF) 或 U+000D 回车符 (CR) 字符。用户代理可以转换 value 以进行显示和编辑;特别是,用户代理应将 value 中域标签的 punycode 转换为显示中的 IDN,反之亦然。

约束验证:当用户界面表示用户代理无法转换为 punycode 的输入时,控件 遭受错误输入

value 属性(如果指定且不为空)必须具有单个 有效电子邮件地址 的值。

值清理算法 如下:从中去除换行符,然后从去除前导和尾随的 ASCII 空白

约束验证:当元素的 value 既不是空字符串也不是单个 有效电子邮件地址 时,元素 遭受类型不匹配

当元素上指定了 multiple 属性时

input 元素 表示 用于添加、删除和编辑元素的 中给定的电子邮件地址的控件。

如果元素是 可变的,用户代理应允许用户添加、删除和编辑其 表示的电子邮件地址。用户代理可以允许用户将 列表中的任何单个值设置为不是 有效电子邮件地址 的字符串,但不得允许用户将任何单个值设置为包含 U+002C 逗号(,)、U+000A 换行符(LF)或 U+000D 回车符(CR)字符的字符串。用户代理应允许用户删除元素的 中的所有地址。用户代理可以转换 以进行显示和编辑;特别是,用户代理应将 中域标签的 punycode 转换为显示中的 IDN,反之亦然。

约束验证:当用户界面描述的情况是某个单独的值包含 U+002C 逗号(,)或表示用户代理无法转换为 punycode 的输入时,控件 遭受错误输入

每当用户更改元素的 时,用户代理必须运行以下步骤:

  1. latest values 成为元素的 的副本。

  2. latest values 中的每个值中 删除前导和尾随的 ASCII 空白字符

  3. 将元素的 设置为 latest values 中所有值的连接结果,每个值之间用单个 U+002C 逗号字符(,)分隔,保持列表的顺序。

value 属性(如果指定)必须具有 有效电子邮件地址列表 的值。

值清理算法 如下

  1. 按逗号拆分 元素的,从每个结果的令牌中去除前导和尾随的 ASCII 空白(如果有的话),并使元素的成为(可能为空的)结果令牌列表,保持原始顺序。

  2. 将元素的 设置为元素的 的连接结果,每个值之间用单个 U+002C 逗号字符(,)分隔,保持列表的顺序。

约束验证:当元素的 不是 有效电子邮件地址列表 时,元素 遭受类型不匹配

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 属性和方法 适用于 该元素: autocompletedirnamelistmaxlengthminlengthmultiplepatternplaceholderreadonlyrequired, 和 size 内容属性; list, 和 value IDL 属性; select() 方法。

value IDL 属性处于 value 模式。

inputchange 事件 适用于 该元素。

以下内容属性不得指定并且 不适用于 该元素: acceptaltcheckedformactionformenctypeformmethodformnovalidateformtargetheightmaxminpopovertargetpopovertargetactionsrcstep, 和 width

以下 IDL 属性和方法 不适用于 该元素: checkedfilesselectionStartselectionEndselectionDirectionvalueAsDate, 和 valueAsNumber IDL 属性; setRangeText()setSelectionRange()stepDown(), 和 stepUp() 方法。

4.10.5.1.6 密码 状态 (type=password)

Element/input/password

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera2+Edge79+
Edge (旧版)12+Internet Explorer2+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

input 元素的 type 属性处于 密码 状态时,本节的规则适用。

input 元素 表示 一个用于编辑 元素的 value 的单行纯文本编辑控件。用户代理应遮蔽该值以防止其他人看到。

如果元素是 可变的,其 value 应可由用户编辑。用户代理不得允许 用户在 value 中插入 U+000A 换行符(LF)或 U+000D 回车符(CR)。

如果指定了 value 属性,则其值不得包含 U+000A 换行符(LF)或 U+000D 回车符(CR)。

值清理算法 如下:从 value去除换行符

以下常见的 input 元素内容 属性、IDL 属性和方法 适用于 该元素: autocompletedirnamemaxlengthminlengthpatternplaceholderreadonlyrequired, 和 size 内容属性; selectionStartselectionEndselectionDirection, 和 value IDL 属性; select()setRangeText(), 和 setSelectionRange() 方法。

value IDL 属性处于 value 模式。

inputchange 事件 适用

以下内容属性不得指定,且 不适用于 该元素: acceptaltcheckedformactionformenctypeformmethodformnovalidateformtargetheightlistmaxminmultiplepopovertargetpopovertargetactionsrcstep, 和 width

以下 IDL 属性和方法 不适用于 该元素: checkedfileslistvalueAsDate, 和 valueAsNumber IDL 属性; stepDown(), 和 stepUp() 方法。

4.10.5.1.7 日期 状态 (type=date)

Element/input/date

支持所有当前引擎。

Firefox57+Safari14.1+Chrome20+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+

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 属性和方法 适用于该元素: autocompletelistmaxminreadonlyrequired, 和 step 内容属性; listvaluevalueAsDate, 和 valueAsNumber IDL 属性; select()step Down(), 和 stepUp() 方法。

value IDL 属性处于 value 模式。

inputchange 事件 适用

以下内容属性不得指定且不适用于该元素: acceptaltcheckeddirnameformactionformenctypeformmethodformnovalidateformtargetheightmaxlengthminlengthmultiplepatternplaceholderpopovertargetpopovertargetactionsrc, 和 width

以下 IDL 属性和方法 不适用于 该元素: checkedselectionStartselectionEnd, 和 selectionDirection IDL 属性; setRangeText(), 和 setSelectionRange() 方法。

4.10.5.1.8 月份 状态 (type=month)

Element/input/month

在所有当前引擎中都支持。

Firefox不支持Safari不支持Chrome20+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android18+Safari iOS支持Chrome Android?WebView Android?Samsung Internet?Opera Android?

当一个 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 属性和方法 适用于 该元素: autocompletelistmaxminreadonlyrequired, 和 step 内容属性; listvaluevalueAsDate, 和 valueAsNumber IDL 属性; select()stepDown(), 和 stepUp() 方法。

value IDL 属性的模式为 value

inputchange 事件 适用

以下内容属性不得指定,并且 不适用 于该元素: acceptaltcheckeddirnameformactionformenctypeformmethodformnovalidateformtargetheightmaxlengthminlengthmultiplepatternplaceholderpopovertargetpopovertargetactionsizesrc, 和 width

以下 IDL 属性和方法 不适用 于该元素: checkedfilesselectionStartselectionEnd, 和 selectionDirection IDL 属性; setRangeText(), 和 setSelectionRange() 方法。

4.10.5.1.9 状态 (type=week)

Element/input/week

Firefox不支持Safari不支持Chrome20+
Opera11+Edge79+
旧版 Edge12+Internet Explorer不支持
Firefox Android18+Safari iOS未知Chrome Android未知WebView Android未知Samsung Internet未知Opera Android未知

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 属性和方法 适用于 该元素: autocompletelistmaxminreadonlyrequiredstep 内容属性; listvaluevalueAsDatevalueAsNumber IDL 属性; select()stepDown()stepUp() 方法。

value IDL 属性的模式为 value

inputchange 事件 适用

以下内容属性不得指定且 不适用于 该元素: acceptaltcheckeddirnameformactionformenctypeformmethodformnovalidateformtargetheightmaxlengthminlengthmultiplepatternplaceholderpopovertargetpopovertargetactionsizesrcwidth

以下 IDL 属性和方法 不适用于 该元素: checkedfilesselectionStartselectionEndselectionDirection IDL 属性; setRangeText()setSelectionRange() 方法。

4.10.5.1.10 时间 状态 (type=time)

Element/input/time

支持所有当前引擎。

Firefox57+Safari14.1+Chrome20+
Opera10+Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

input 元素的 type 属性处于 时间 状态时,本节中的规则适用。

input 元素 表示 一个控件,用于将元素的 设置为表示特定 时间 的字符串。

如果该元素是 可变的,用户代理应允许用户更改其 时间,如通过从中 解析时间 获得的 。用户代理不得允许用户将 设置为非空字符串,除非该字符串是 有效时间字符串。如果用户代理提供用户界面以选择 时间,则 必须设置为表示用户选择的 有效时间字符串。用户代理应允许用户将 设置为空字符串。

约束验证:当用户界面描述的输入无法由用户代理转换为 有效时间字符串 时,该控件 存在错误输入

请参阅 介绍部分,讨论日期、时间和数字表单控件的输入格式与提交格式的区别,以及有关表单控件本地化的 实现注意事项

如果指定并且不为空,value 属性必须具有 有效时间字符串 的值。

值净化算法 如下:如果元素的 不是 有效时间字符串,则将其设置为空字符串。

表单控件 具有周期性领域

如果指定,min 属性必须具有 有效时间字符串 的值。max 属性如果指定,必须具有 有效时间字符串 的值。

step 属性以秒为单位表示。步长比例因子 是 1000(将秒转换为毫秒,正如其他算法中所使用的那样)。默认步长 为 60 秒。

当元素 存在步长不匹配 时,用户代理可以将元素的 四舍五入到最接近的 时间,使该元素不会 存在步长不匹配

将字符串转换为数字的算法 如下:如果 解析 字符串 input 的时间出现错误,则返回错误;否则,返回从午夜到解析出的 时间 的毫秒数。

将数字转换为字符串的算法 如下:返回一个 有效时间字符串,表示从午夜开始后 input 毫秒的 时间

将字符串转换为 Date 对象的算法 如下:如果 解析 字符串 input 的时间出现错误,则返回错误;否则,返回一个 新的 Date 对象,表示 UTC 时间 1970-01-01 的解析 时间

Date 对象转换为字符串的算法 如下:返回一个 有效时间字符串,表示由 input 表示的 UTC 时间组件。

以下常见 input 元素内容属性、IDL 属性和方法 适用于 该元素: autocompletelistmaxminreadonlyrequiredstep 内容属性; listvaluevalueAsDatevalueAsNumber IDL 属性; select()stepDown()stepUp() 方法。

value IDL 属性处于 模式。

inputchange 事件 适用

以下内容属性不得指定并且 不适用 于该元素: acceptaltcheckeddirnameformactionformenctypeformmethodformnovalidateformtargetheightmaxlengthminlengthmultiplepatternplaceholderpopovertargetpopovertargetactionsizesrcwidth

以下 IDL 属性和方法 不适用 于该元素: checkedfilesselectionStartselectionEndselectionDirection IDL 属性; setRangeText()setSelectionRange() 方法。

4.10.5.1.11 本地日期和时间 状态 (type=datetime-local)

Element/input/datetime-local

所有当前引擎均支持。

Firefox93+Safari14.1+Chrome20+
Opera11+Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+

input 元素的 type 属性处于 本地日期和时间 状态时,本节中的规则适用。

input 元素 表示 用于将元素的 设置为表示 本地日期和时间 的字符串的控件,没有时区偏移信息。

如果元素是 可变的,用户代理应允许用户更改其 日期和时间,如从中 解析出。用户代理不得允许用户将 设置为非空字符串,该字符串不是 有效的规范化本地日期和时间字符串。如果用户代理提供选择 本地日期和时间 的用户界面,则 必须设置为表示用户选择的 有效的规范化本地日期和时间字符串。用户代理应允许用户将 设置为空字符串。

约束验证:当用户界面描述的输入无法转换为 有效的规范化本地日期和时间字符串 时,控件 遇到错误输入

请参阅 引言部分 讨论日期、时间和数字表单控件的输入格式和提交格式之间的差异,以及 实现说明 以了解表单控件的本地化。

如果指定且非空,value 属性必须具有 有效的本地日期和时间字符串 值。

值清理算法 如下:如果元素的 有效的本地日期和时间字符串,则将其设置为表示相同日期和时间的 有效的规范化本地日期和时间字符串;否则,将其设置为空字符串。

如果指定,min 属性必须具有 有效的本地日期和时间字符串 值。max 属性如果指定,必须具有 有效的本地日期和时间字符串 值。

step 属性以秒为单位表示。步长比例因子 为 1000(将秒转换为算法中使用的毫秒)。默认步长 为 60 秒。

当元素 遇到步长不匹配 时,用户代理可以将元素的 舍入到最近的 本地日期和时间,该日期和时间不导致元素 遇到步长不匹配

将字符串转换为数字的算法,给定一个字符串 input,如下:如果 input 解析日期和时间 结果出错,则返回错误;否则,返回从 1970-01-01 凌晨到解析出的 本地日期和时间 的毫秒数,忽略闰秒。

将数字转换为字符串的算法,给定一个数字 input,如下:返回表示从 1970-01-01 凌晨 input 毫秒后的日期和时间的 有效规范化本地日期和时间字符串

请参阅 历史日期的说明日期 状态部分。

以下常见 input 元素内容属性、IDL 属性和方法适用于该元素: autocompletelistmaxminreadonlyrequiredstep 内容属性; listvaluevalueAsNumber IDL 属性; select()stepDown()stepUp() 方法。

value IDL 属性处于 value 模式。

inputchange 事件 适用

以下内容属性不得指定且 不适用 于元素: acceptaltcheckeddirnameformactionformenctypeformmethodformnovalidateformtargetheightmaxlengthminlengthmultiplepatternplaceholderpopovertargetpopovertargetactionsizesrcwidth

以下 IDL 属性和方法 不适用于 元素: checkedfilesselectionStartselectionEndselectionDirectionvalueAsDate 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>
4.10.5.1.12 数字 状态 (type=number)

Element/input/number

在所有当前引擎中均支持。

Firefox29+Safari5.1+Chrome7+
Opera?Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

input 元素的 type 属性处于 数字 状态时,本节的规则适用。

input 元素 表示 一个用于将元素的 设置为表示数字的字符串的控件。

如果该元素是 可变的,用户代理应允许用户更改其 所代表的数字,依据的是应用 解析浮点数值的规则。用户代理不得允许用户将 设置为非空但不是 有效浮点数 的字符串。如果用户代理提供了选择数字的用户界面,则 必须设置为表示用户选择的数字的 最佳表示。用户代理应允许用户将 设置为空字符串。

约束验证:当用户界面描述的输入无法转换为 有效浮点数 时,控件 遇到错误输入

本规范未定义用户代理应使用的用户界面;建议用户代理供应商考虑什么最能满足其用户的需求。例如,在波斯或阿拉伯市场中的用户代理可能支持波斯和阿拉伯数字输入(将其转换为上述描述的提交格式)。同样,为罗马市场设计的用户代理可能会以罗马数字而不是十进制显示值;或者(更现实地)为法国市场设计的用户代理可能会在千位之间显示撇号,在小数点前显示逗号,并允许用户以这种方式输入值,内部将其转换为上述描述的提交格式。

如果指定且非空,value 属性必须具有 有效浮点数 值。

值清理算法 如下:如果元素的 不是 有效浮点数,则将其设置为空字符串。

如果指定,min 属性必须具有 有效浮点数 值。max 属性如果指定,必须具有 有效浮点数 值。

步长比例因子 为 1。默认步长 为 1(仅允许用户选择整数,除非 步长基数 具有非整数值)。

当元素 遇到步长不匹配 时,用户代理可以将元素的 四舍五入到最接近的不会 步长不匹配 的数。如果有两个这样的数字,建议用户代理选择最接近正无穷的那个。

将字符串转换为数字的算法 如下:如果将 input 应用于 解析浮点数值的规则 结果出错,则返回错误;否则,返回结果数值。

将数字转换为字符串的算法 如下:返回一个表示 input有效浮点数

以下通用 input 元素内容属性、IDL 属性和方法 适用于 该元素: autocompletelistmaxminplaceholderreadonlyrequiredstep 内容属性; listvaluevalueAsNumber IDL 属性; select()stepDown()stepUp() 方法。

value IDL 属性处于 value 模式。

inputchange 事件 适用

以下内容属性不得指定且 不适用 于该元素: acceptaltcheckeddirnameformactionformenctypeformmethodformnovalidateformtargetheightmaxlengthminlengthmultiplepatternpopovertargetpopovertargetactionsizesrcwidth

以下 IDL 属性和方法 不适用 于该元素: checkedfilesselectionStartselectionEndselectionDirectionvalueAsDate 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 可能是正确的选择(可能带有 inputmodepattern 属性)。

4.10.5.1.13 范围状态(type=range)

Element/input/range

Support in all current engines.

Firefox23+Safari3.1+Chrome4+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android52+Safari iOS5+Chrome Android57+WebView Android4.4+Samsung Internet?Opera Android11+

input 元素的type 属性处于范围状态时,本节的规则适用。

input 元素表示一个用于设置元素的 为一个表示数字的字符串的控件,但前提是精确值并不重要,从而使得用户代理可以提供比 数字状态更简单的界面。

如果元素是可变的,用户代理应允许用户更改其 ,如通过将 解析浮点数值的规则 应用于其获取。用户代理不得允许用户将值设置为非 有效浮点数的字符串。如果用户代理提供了用于选择数字的用户界面,则值必须设置为表示用户选择的 最佳浮点数表示的值。用户代理不得允许用户将值设置为空字符串。

约束验证:当用户界面描述的输入用户代理无法转换为 有效浮点数时,控件 存在错误输入

如果指定了value 属性,则其值必须是 有效浮点数

值净化算法如下:如果元素的 不是 有效浮点数,则将其设置为 最佳浮点数表示默认值

默认值是最小值 加上最小值和最大值之间差的一半,除非最大值小于最小值,此时默认值为最小值。

当元素存在下溢时,用户代理必须将元素的 设置为最小值的 最佳浮点数表示

当元素存在上溢时,如果最大值不小于最小值,用户代理必须将元素的 设置为表示最大值的 有效浮点数

当元素存在步长不匹配时,用户代理必须将元素的 舍入到满足以下条件的最接近的数字,该数字不会使元素 存在步长不匹配,且大于或等于最小值,并且如果最大值不小于最小值,则该值小于或等于最大值。如果有两个符合这些条件的数字,则用户代理必须使用最接近正无穷的那个数字。

例如,标记 <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: 75px; width: 49px; background: #D5CCBB; color: black; }

...可能渲染为:

A vertical slider control whose primary color is black and whose background color is beige, with the slider having five tick marks, one long one at each extremity, and three short ones clustered around the midpoint.

请注意用户代理如何根据样式表指定的高度和宽度属性的比例确定控件的方向。颜色同样从样式表中得出。然而,刻度标记是从标记中派生的。特别是,step 属性未影响刻度标记的位置,用户代理决定只使用作者指定的完成值,然后在极端位置添加更长的刻度标记。

还请注意无效值++50被忽略了。

另一个示例,请考虑以下标记片段:

<input name=x type=range min=100 max=700 step=9.09090909 value=509.090909>

用户代理可以以多种方式显示,例如:

As a dial.

或者,或者:

As a long horizontal slider with tick marks.

用户代理可以根据样式表中给定的尺寸选择显示哪一个。这将允许它在保持刻度标记相同分辨率的同时显示不同的宽度。

最后,这里是带有两个标记值的范围控件示例:

<input type="range" name="a" list="a-values">
<datalist id="a-values">
<option value="10" label="Low">
<option value="90" label="High">
</datalist>

使用使控件垂直绘制的样式,它可能如下所示:

A vertical slider control with two tick marks, one near the top labeled 'High', and one near the bottom labeled 'Low'.

在这种状态下,即使在用户输入期间,范围和步长约束也会被强制执行,并且无法将值设置为空字符串。

如果指定了min 属性,则其值必须是有效浮点数。默认最小值为0。如果指定了max 属性,则其值必须是有效浮点数。默认最大值为100。

步长比例因子为1。默认步长为1(仅允许整数,除非min 属性具有非整数值)。

将字符串转换为数字的算法如下:如果将 解析浮点数值的规则 应用于输入结果出现错误,则返回错误;否则,返回结果数字。

将数字转换为字符串的算法如下:返回表示输入的 最佳浮点数表示 的字符串。

以下常见input 元素内容属性、IDL属性和方法适用于该元素: autocomplete, list, max, min, 和 step 内容属性; list, value, 和 valueAsNumber IDL属性; stepDown()stepUp() 方法。

value IDL属性处于value模式。

inputchange 事件适用

以下内容属性不得指定且不适用该元素: 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() 方法。

4.10.5.1.14 颜色状态 (type=color)

Element/input/color

在所有当前引擎中支持。

Firefox29+Safari12.1+Chrome20+
Opera12+Edge79+
Edge (旧版)14+Internet Explorer不支持
Firefox Android🔰 27+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

input 元素的type 属性为 颜色状态时,本节的规则适用。

input 元素表示表示一个颜色井控件,用于设置元素的 为表示简单颜色的字符串。

在这种状态下,总是有一个选定的颜色,无法将值设置为空字符串。

如果该元素是可变的,用户代理应允许用户更改其所表示的颜色,如通过将解析简单颜色值的规则应用于其值来获得的颜色。用户代理不得允许用户将设置为不符合有效的小写简单颜色的字符串。如果用户代理提供了用于选择颜色的用户界面,则必须设置为用户选择的颜色,使用序列化简单颜色值的规则的结果。用户代理不得允许用户将设置为空字符串。

对于这样的元素element输入激活行为显示选择器(如果适用)

约束验证:当用户界面描述了用户代理无法转换为有效的小写简单颜色的输入时,该控件 遇到了错误输入

如果指定且不为空,value 属性必须具有有效的简单颜色值。

值清理算法如下:如果元素的是一个有效的简单颜色, 则将其设置为元素的值转换为ASCII小写后的值; 否则,将其设置为字符串"#000000"。

以下常见input 元素内容属性和IDL属性适用于该元素: autocompletelist 内容属性; listvalue IDL属性; select() 方法。

value IDL属性处于value模式。

inputchange 事件适用

以下内容属性不得指定并且不适用该元素: acceptaltcheckeddirnameformactionformenctypeformmethodformnovalidateformtargetheightmaxmaxlengthminminlengthmultiplepatternplaceholderpopovertargetpopovertargetactionreadonlyrequiredsizesrcstep, 和 width

以下IDL属性和方法不适用该元素: checkedfilesselectionStartselectionEndselectionDirectionvalueAsDate, 和 valueAsNumber IDL属性; setRangeText()setSelectionRange()stepDown(), 和 stepUp() 方法。

4.10.5.1.15 复选框状态 (type=checkbox)

Element/input/checkbox

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

input 元素的type 属性为复选框状态时,本节的规则适用。

input 元素表示一个双状态控件,代表元素的选中状态。如果元素的选中状态为真,则控件表示一个正向选择;如果为假,则表示一个负向选择。如果元素的不确定 IDL属性设置为真,则控件的选择应被遮蔽,仿佛控件处于第三种不确定状态。

即使元素的不确定 IDL属性设置为真,控件也从来不是一个真正的三态控件。不确定 IDL属性仅提供第三种状态的外观。

输入激活行为如下:

  1. 如果该元素未连接,则返回。

  2. 触发 一个名为input 的事件在该元素上,并初始化bubblescomposed 属性为真。

  3. 触发 一个名为change 的事件在该元素上,并初始化bubbles 属性为真。

约束验证:如果该元素是必填的,并且其选中状态为假,则该元素缺失

input.indeterminate [ = value ]

设置时,覆盖复选框 控件的渲染,使当前值不可见。

以下常见input 元素内容属性和IDL属性适用该元素: checked, 和 required 内容属性; checkedvalue IDL属性。

value IDL属性处于默认/打开模式。

inputchange 事件适用

以下内容属性不得指定并且不适用该元素: acceptaltautocompletedirnameformactionformenctypeformmethodformnovalidateformtargetheightlistmaxmaxlengthminminlengthmultiplepatternplaceholderpopovertargetpopovertargetactionreadonlysizesrcstep, 和 width

以下IDL属性和方法不适用该元素: fileslistselectionStartselectionEndselectionDirectionvalueAsDate, 和 valueAsNumber IDL属性; select()setRangeText()setSelectionRange()stepDown(), 和 stepUp() 方法。

4.10.5.1.16 单选按钮状态 (type=radio)

元素/input/radio

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

input 元素的 type 属性为 单选按钮状态时,本节中的规则适用。

input 元素表示 一个控件,当与其他 input 元素结合使用时,形成一个单选按钮组,其中只有一个控件可以将其选中状态设置为 true。如果元素的选中状态为 true,则控件表示组中的选定控件;如果为 false,则表示组中未选定的控件。

包含 input 元素a单选按钮组 还包含所有其他满足以下条件的 input 元素 b

一个 中不能包含一个 input 元素,其 单选按钮组 中仅包含该元素。

当发生以下任何现象时,如果元素的 选中状态在发生后为 true,则同一 单选按钮组 中所有其他元素的 选中状态必须设置为 false:

输入激活行为是执行以下步骤:

  1. 如果元素未连接,则返回。

  2. 触发一个事件 名为 input 在元素上,bubblescomposed 属性初始化为 true。

  3. 触发一个事件名为 change 在元素上,bubbles 属性初始化为 true。

约束验证:如果单选按钮组中的元素必需,并且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 属性 适用于该元素: checkedrequired 内容属性; checkedvalue IDL 属性。

value IDL 属性处于模式 default/on

inputchange 事件 适用于该元素。

以下内容属性不得指定,并且不适用于该元素: 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 属性和方法不适用于该元素: fileslistselectionStartselectionEndselectionDirectionvalueAsDate, 和 valueAsNumber IDL 属性; select()setRangeText()setSelectionRange()stepDown(), 和 stepUp() 方法。

4.10.5.1.17 文件上传 状态 (type=file)

Element/input/file

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+

input 元素的 type 属性处于 文件上传 状态时,本节中的规则适用。

input 元素 表示 一个已选择的文件列表,每个文件包括一个文件名、一个文件类型和一个文件主体(文件内容)。

文件名不得包含 路径组件,即使用户选择了整个目录层次结构或来自不同目录的多个同名文件也是如此。路径组件,对于 文件上传 状态而言,是指由 U+005C 反斜杠字符(\)分隔的文件名部分。

除非设置了 multiple 属性,否则所选文件列表中不得超过一个文件。

对于这样的元素 element输入激活行为 是为 element 显示选择器(如果适用)

如果元素是 可变 的,用户代理应该允许用户通过其他方式更改文件列表,例如,通过拖放添加或删除文件。当用户这样做时,用户代理必须 更新元素的文件选择

如果元素不是 可变 的,用户代理不得允许用户更改元素的选择。

更新元素的文件选择,请执行以下步骤:

  1. 在给定 element 的用户交互任务源上排队一个元素任务,并执行以下步骤:

    1. 更新 element已选择文件,以便它表示用户的选择。

    2. 触发一个事件,事件名称为 input,在 input 元素上触发,并将 bubblescomposed 属性初始化为 true。

    3. 触发一个事件,事件名称为 change,在 input 元素上触发,并将 bubbles 属性初始化为 true。

约 束验证:如果元素是 必需 的,并且已选择文件列表为空,则该元素 缺少


Attributes/accept

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

Element/input#attr-accept

所有当前引擎支持。

Firefox37+Safari11.1+Chrome26+
Opera15+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android37+Safari iOS11.3+Chrome Android26+WebView Android4.4+Samsung Internet1.5+Opera Android15+

accept 属性可用于向用户代理提供接受文件类型的提示。

如果指定,该属性必须由一组逗号分隔的标记组成,每个标记必须是以下之一的 ASCII 不区分大小写 的匹配项:

字符串 "audio/*"
表示接受音频文件。
字符串 "video/*"
表示接受视频文件。
字符串 "image/*"
表示接受图像文件。
没有参数的有效 MIME 类型字符串
表示接受指定类型的文件。
第一个字符是 U+002E FULL STOP 字符 (.) 的字符串
表示接受具有指定文件扩展名的文件。

标记不得是其他标记的 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 属性的要求,数据也可能不符合预期格式。

Element/input/file

由于历史原因,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 属性 适用于 该元素: acceptmultiple, 和 required 内容属性; filesvalue IDL 属性; select() 方法。

value IDL 属性处于 文件名 模式。

inputchange 事件 适用

以下内容属性不得指定,并且 不适用于 该元素: altautocompletecheckeddirnameformactionformenctypeformmethodformnovalidateformtargetheightlistmaxmaxlengthminminlengthpatternpopovertargetpopovertargetactionplaceholderreadonlysizesrcstep, 和 width

元素的 value 属性必须省略。

以下 IDL 属性和方法 不适用于 该元素: checkedlistselectionStartselectionEndselectionDirectionvalueAsDate, 和 valueAsNumber IDL 属性; setRangeText()setSelectionRange()stepDown(), 和 stepUp() 方法。

4.10.5.1.18 提交按钮 状态 (type=submit)

Element/input/submit

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

input 元素的 type 属性处于 提交按钮 状态时,本节中的规则适用。

(This is a tracking vector.) input 元素 表示 一个按钮,当激活时,提交表单。如果该元素有 value 属性, 按钮的标签必须是该属性的值;否则,必须是一个 实现定义 的字符串,意思是“提交”或类似的。 该 元素是一个 按钮, 具体来说是一个 提交按钮

由于默认标签是 实现定义 的,并且按钮的宽度通常取决于按钮的标签,按钮的宽度可能会泄露一些指纹信息。这些信息很可能与用户代理的身份和用户的区域设置密切相关。

元素的 输入激活行为 给定 event 如下:

  1. 如果元素没有 表单所有者,则返回。

  2. 如果元素的 节点文档 不是 完全激活的,则返回。

  3. 提交 元素的 表单所有者 从元素中,用户参与度 设置为 event用户导航参与度

formactionformenctypeformmethodformnovalidate, 和 formtarget 属性是 表单提交的属性

formnovalidate 属性可以用来制作不会触发约束验证的提交按钮。

以下常见的 input 元素内容属性和 IDL 属性 适用于 该元素: dirnameformactionformenctypeformmethodformnovalidateformtargetpopovertarget, 和 popovertargetaction 内容 属性; value IDL 属性。

value IDL 属性处于 默认 模式。

以下内容属性不得指定并且 不适用于 元素: acceptaltautocompletecheckedheightlistmaxmaxlengthminminlengthmultiplepatternplaceholderreadonlyrequiredsizesrcstep, 和 width

以下 IDL 属性和方法 不适用于 该元素: checkedfileslistselectionStartselectionEndselectionDirectionvalueAsDate, 和 valueAsNumber IDL 属性; select()setRangeText()setSelectionRange()stepDown(), 和 stepUp() 方法。

inputchange 事件 不适用

4.10.5.1.19 图像按钮 状态 (type=image)

Element/input/image

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

input 元素的 type 属性处于 图像按钮 状态时,本节中的规则适用。

input 元素 表示 一个图像,用户可以从中选择一个坐标并提交表单,或者作为按钮提交表单。该元素是一个 按钮,具体来说是一个 提交按钮

坐标通过发送两个元素条目到服务器来提交表单,这两个条目源自控件的名称,但名称末尾附加了 ".x" 和 ".y",分别对应坐标的 xy 组件。


Element/input#src

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

图像由 src 属性提供。src 属性必须存在,并且必须包含一个 有效的非空URL,可能被空格包围,引用一个非交互、可选动画、非分页或非脚本的图像资源。

当发生以下事件时

除非用户代理不支持图像,或其图像支持已被禁用,或用户代理仅按需获取图像,或 src 属性的值为空字符串,否则请执行以下步骤:

  1. url编码解析 URL 的结果,给定 src 属性的值,相对于元素的 节点文档

  2. 如果 url 解析失败,则返回。

  3. request 为一个新的 请求,其 URLurl客户端 是元素的 节点文档相关设置对象目的地 为 "image",发起类型 为 "input", 凭据模式 为 "include",并且其 使用URL凭据标志 被设置。

  4. 获取 request,设置 processResponseEndOfBody 为 以下步骤,给定 响应 response

    1. 如果下载成功并且图像 可用将元素任务加入队列用户交互任务源,给定 input 元素,以 触发一个事件,名称为 load,在 input 元素上。

    2. 否则,如果获取过程失败且没有从远程服务器收到响应,或者完成但图像不是有效或支持的图像,则 将元素任务加入队列用户交互任务源,给定 input 元素,以 触发一个事件,名称为 error,在 input 元素上。

获取图像必须 延迟加载事件,直到资源被获取后由 网络任务源排队的 任务 已运行。

如果图像成功获取,没有网络错误,并且图像的类型是支持的图像类型,并且该类型的图像是有效的,则该图像被认为是 可用的。如果在图像完全下载之前这是真的,那么在图像获取期间由 任务 队列的每个任务必须适当更新图像的呈现。

用户代理应应用 图像嗅探规则 来确定图像的类型,图像的 相关的内容类型标头 给出官方类型。如果不应用这些规则,则图像的类型必须是由图像的 相关内容类型标头 给出的类型。

用户代理不得支持非图像资源作为 input 元素。用户代理不得运行嵌入在图像资源中的可执行代码。用户代理只能显示多页资源的第一页。用户代理不得允许资源以交互方式运行,但应尊重资源中的任何动画。


Element/input#alt

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

alt 属性为无法使用图像的用户和用户代理提供按钮的文本标签。alt 属性必须存在,并且必须包含一个非空字符串,给出在图像不可用时适合的等效按钮标签。

input 元素支持 尺寸属性


如果 src 属性已设置,并且图像 可用 且用户代理配置为显示该图像, 则元素 表示 一个从由 src 属性指定的图像中选择一个 坐标 的控件。在这种情况下,如果该元素是 可变的,则用户代理应允许用户选择此 坐标

否则,元素 表示 一个提交按钮,其标签由 alt 属性的值给出。

元素的 输入激活行为 给定 event 如下:

  1. 如果元素没有 表单所有者,则返回。

  2. 如果元素的 节点文档 不是 完全激活的,则返回。

  3. 如果用户在显式选择坐标时激活控件,则将元素的 选定坐标 设置为该坐标。

    这只有在上述条件下才可能,当元素 表示 一个用于选择此类坐标的控件。即便如此,用户可能在未显式选择坐标的情况下激活控件。

  4. 提交 元素的 表单所有者,从元素中,用户参与度 设置为 event用户导航参与度

元素的 选定坐标x 组件和 y 组件组成。它最初为 (0, 0)。这些坐标表示相对于元素图像边缘的位置,坐标空间具有向右的正 x 方向和向下的正 y 方向。

x 组件必须是一个 有效的整数,表示范围内的数 −(borderleft+paddingleft) ≤ xwidth+borderright+paddingright,其中 width 是图像的渲染宽度,borderleft 是图像左侧的边框宽度,paddingleft 是图像左侧的填充宽度,borderright 是图像右侧的边框宽度,paddingright 是图像右侧的填充宽度,所有尺寸均以 CSS 像素 为单位。

y 组件必须是一个 有效的整数,表示范围内的数 −(bordertop+paddingtop) ≤ yheight+borderbottom+paddingbottom,其中 height 是图像的渲染高度,bordertop 是图像上方的边框宽度,paddingtop 是图像上方的填充宽度,borderbottom 是图像下方的边框宽度,paddingbottom 是图像下方的填充宽度,所有尺寸均以 CSS 像素 为单位。

缺少边框或填充时,其宽度为零 CSS 像素


formactionformenctypeformmethodformnovalidate, 和 formtarget 属性是 表单提交的属性

image.width [ = value ]
image.height [ = value ]

这些属性返回图像的实际渲染尺寸,如果尺寸未知,则返回 0。

它们可以设置,以更改相应的内容属性。

以下常见的 input 元素内容属性和 IDL 属性 适用于 该元素: altformactionformenctypeformmethodformnovalidateformtargetheightpopovertargetpopovertargetactionsrc, 和 width 内容属性; value IDL 属性。

value IDL 属性处于 默认 模式。

以下内容属性不得指定并且 不适用于 元素: acceptautocompletecheckeddirnamelistmaxmaxlengthminminlengthmultiplepatternplaceholderreadonlyrequiredsize, 和 step

元素的 value 属性必须省略。

以下 IDL 属性和方法 不适用于 该元素: checkedfileslistselectionStartselectionEndselectionDirectionvalueAsDate, 和 valueAsNumber IDL 属性; select()setRangeText()setSelectionRange()stepDown(), 和 stepUp() 方法。

inputchange 事件 不适用

此状态的许多行为与 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"。

(在此示例中,假设对于看不到地图的用户,他们只会看到一个标有“显示位置列表”的按钮,点击该按钮将导致服务器显示一个位置列表以供选择,而不是地图。)

4.10.5.1.20 重置按钮 状态 (type=reset)

Element/input/reset

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

input 元素的 type 属性处于 重置按钮 状态时,本节中的规则适用。

input 元素 表示 一个按钮,当激活时,重置表单。如果元素有 value 属性,按钮的标签必须是该属性的值;否则,必须是一个实现定义的字符串,表示“重置”或类似的意思。该元素是一个 按钮

由于默认标签是实现定义的,并且按钮的宽度通常取决于按钮的标签,按钮的宽度可能会泄露一些可用于指纹识别的信息。这些信息很可能与用户代理的身份和用户的区域设置密切相关。

元素的 输入激活行为 如下:

  1. 如果元素没有 表单所有者,则返回。

  2. 如果元素的 节点文档 不是 完全激活的,则返回。

  3. 重置 元素的 表单所有者

约束验证:该元素 不受约束验证 影响。

value IDL 属性 适用于 该元素,并且处于 默认 模式。

以下常见的 input 元素内容属性 适用于 该元素: popovertargetpopovertargetaction

以下内容属性不得指定,并且 不适用于 该元素: acceptaltautocompletecheckeddirnameformactionformenctypeformmethodformnovalidateformtargetheightlistmaxmaxlengthminminlengthmultiplepatternplaceholderreadonlyrequiredsizesrcstep, 和 width

以下 IDL 属性和方法 不适用于 该元素: checkedfileslistselectionStartselectionEndselectionDirectionvalueAsDate, 和 valueAsNumber IDL 属性; select()setRangeText()setSelectionRange()stepDown(), 和 stepUp() 方法。

inputchange 事件 不适用

4.10.5.1.21 按钮 状态 (type=button)

Element/input/button

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

input 元素的 type 属性处于 按钮 状态时,本节中的规则适用。

input 元素 表示 一个没有默认行为的按钮。必须在 value 属性中提供按钮的标签,尽管它可以是空字符串。如果元素具有 value 属性,按钮的标签必须是该属性的值;否则,必须是空字符串。该元素是一个 按钮

该元素没有 输入激活行为

约束验证:该元素 不受约束验证 影响。

value IDL 属性 适用于 该元素,并且处于 默认 模式。

以下常见的 input 元素内容属性 适用于 该元素: popovertargetpopovertargetaction

以下内容属性不得指定,并且 不适用于 该元素: acceptaltautocompletecheckeddirnameformactionformenctypeformmethodformnovalidateformtargetheightlistmaxmaxlengthminminlengthmultiplepatternplaceholderreadonlyrequiredsizesrcstep, 和 width

以下 IDL 属性和方法 不适用于 该元素: checkedfileslistselectionStartselectionEndselectionDirectionvalueAsDate, 和 valueAsNumber IDL 属性; select()setRangeText()setSelectionRange()stepDown(), 和 stepUp() 方法。

inputchange 事件 不适用

4.10.5.2 关于表单控件本地化的实现说明

本节是非规范性的。

在日期、时间和数字控件中显示给用户的格式与用于表单提交的格式无关。

鼓励浏览器使用用户界面,按照input 元素的 语言 或用户首选语言的习惯显示日期、时间和数字。使用页面的语言将确保与页面提供的数据保持一致。

例如,如果一个美国英语页面声称 Cirque De Soleil 演出将在 02/03 上演,但用户的浏览器配置为使用英国英语区域,票务购买日期选择器中只显示 03/02 的日期,这对用户来说会非常困惑。使用页面的语言至少可以确保日期在所有地方都以相同的格式显示。(当然,仍然存在用户可能迟到一个月的风险,但对于这种文化差异,我们能做的也只有这么多了……)

4.10.5.3 常见的 input 元素属性

这些属性仅当 input 元素的 type 属性处于其定义声明该属性 适用 的状态时才适用。当一个属性不适用于 input 元素时,用户代理必须忽略该属性,不论以下的要求和定义如何。

4.10.5.3.1 maxlengthminlength 属性

Attributes/maxlength

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Attributes/minlength

支持所有当前引擎。

Firefox51+Safari10.1+Chrome40+
Opera?Edge79+
Edge (旧版)17+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Attributes/maxlength

支持所有当前引擎。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
caniuse.com 表格

maxlength 属性当 适用 时,是一个 表单控件的 maxlength 属性

Element/input#attr-minlength

支持所有当前引擎。

Firefox51+Safari10.1+Chrome40+
Opera27+Edge79+
Edge (旧版)17+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

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>
4.10.5.3.2 size 属性

size 属性 指定在视觉呈现中,用户代理在用户编辑元素的value时允许用户看到的字符数量。

size 属性(如果指定)必须具有一个值, 该值是一个大于零的有效的非负整数

如果存在该属性,则必须使用解析非负整数的规则解析其值,如果结果是一个大于零的数字,则用户代理 应确保至少有这么多字符可见。

size IDL 属性仅限于大于零的正数,并且具有默认值为20。

4.10.5.3.3 readonly 属性

Attributes/readonly

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

Attributes/readonly

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

Attributes/readonly

支持所有当前引擎。

Firefox1+Safari≤4+Chrome1+
Opera≤12.1+Edge79+
Edge (旧版)12+Internet Explorer≤6+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android≤12.1+

readonly 属性是一个布尔属性,它控制用户是否可以编辑 表单控件。一旦指定,该元素就不可

约束验证:如果readonly 属性在input 元素上指定,则该元素将被排除在约束验证之外

disabledreadonly 之间的区别在于只读控件仍然可以 使用,而禁用的控件在启用之前通常不能作为控件使用。这在本规范的其他地方有更详细的说明,带有规范要求引用了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>
4.10.5.3.4 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>

为了避免是否需要单选按钮组的混淆,建议作者在组中的所有单选按钮上指定属性。事实上,一般来说,建议作者避免在一开始没有任何初始选中控件的单选按钮组,因为用户无法返回到这种状态,因此通常被认为是较差的用户界面。

4.10.5.3.5 multiple 属性

Attributes/multiple

所有当前引擎均支持。

Firefox3.6+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

Element/input#attr-multiple

所有当前引擎均支持。

Firefox3.6+Safari4+Chrome2+
Opera≤12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android≤37+Samsung Internet?Opera Android≤12.1+

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>
4.10.5.3.6 pattern 属性

Attributes/pattern

所有当前引擎均支持。

Firefox4+Safari5+Chrome4+
Opera≤12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android≤37+Samsung Internet?Opera Android≤12.1+

Attributes/pattern

所有当前引擎均支持。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

pattern 属性指定了表单控件的 或者当 multiple 属性 适用 且已设置时,控件的 应该匹配的正则表达式。

如果指定,该属性的值必须符合JavaScript Pattern[+UnicodeSetsMode, +N] 生成。

如果<input>元素存在,input元素的 已编译的模式正则表达式 是一个JavaScript RegExp对象。其确定方式如下:

  1. 如果元素没有指定pattern属性,则返回空。元素没有已编译的模式正则表达式

  2. pattern成为元素的pattern属性的值。

  3. regexpCompletion成为 RegExpCreate(pattern, "v")。

  4. 如果 regexpCompletion异常完成,则返回空。元素没有 已编译的模式正则表达式

    建议用户代理在开发者控制台记录此错误,以帮助调试。

  5. anchoredPattern成为字符串 "^(?:",后接pattern,后接")$"。

  6. 返回!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措辞为错误已必然发生。

4.10.5.3.7 minmax 属性

Attributes/max

所有当前引擎均支持。

Firefox16+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

Attributes/min

所有当前引擎均支持。

Firefox16+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

某些表单控件可以应用明确的约束,限制用户可提供的值的范围。通常,这样的范围是线性且连续的。然而,表单控件可以具有周期性域,在这种情况下,表单控件的最大可能范围是有限的,作者可以在此范围内指定跨越边界的明确范围。

具体来说,type=time控件的最大范围是午夜到午夜(24小时),作者可以设置连续线性范围(例如从晚上9点到晚上11点)和跨越午夜的不连续范围(例如从晚上11点到凌晨1点)。

minmax 属性表示元素的允许值范围。

它们的语法由定义type属性当前状态的部分定义。

如果元素具有min属性,并且将min属性的值应用于将字符串转换为数字的算法的结果是一个数字,那么该数字就是元素的最小值;否则,如果type属性的当前状态定义了默认最小值,那么这就是最小值;否则,元素没有最小值

min属性还定义了步进基准

如果元素具有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">
4.10.5.3.8 step 属性

Attributes/step

所有当前引擎均支持。

Firefox16+Safari5+Chrome5+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

step 属性通过限制允许值来指示预期(并要求)的的粒度。定义type属性当前状态的部分还定义了默认步进步进比例因子,在某些情况下还定义了默认步进基准,这些在处理属性时如下所述。

如果指定,step属性必须具有有效的浮点数值,该值解析为大于零的数字,或必须具有与字符串"any"的ASCII大小写不敏感匹配的值。

该属性为元素提供了允许值步进,如下所示:

  1. 如果该属性不适用,则没有允许值步进

  2. 否则,如果该属性不存在,则允许值步进默认步进乘以步进比例因子

  3. 否则,如果属性值与字符串"any"的ASCII大小写不敏感匹配,则没有允许值步进

  4. 否则,如果解析浮点数值的规则应用于属性值时返回错误、零或小于零的数字,则允许值步进默认步进乘以步进比例因子

  5. 否则,允许值步进解析浮点数值的规则应用于属性值时返回的数字乘以步进比例因子

步进基准是以下算法返回的值:

  1. 如果元素具有min内容属性,并且将min内容属性的值应用于将字符串转换为数字的算法的结果不是错误,则返回该结果。

  2. 如果元素具有value内容属性,并且将value内容属性的值应用于将字符串转换为数字的算法的结果不是错误,则返回该结果。

  3. 如果对于给定其type属性状态的元素定义了默认步进基准,则返回它。

  4. 返回零。

约束验证:当元素具有允许值步进,并且将元素的应用于将字符串转换为数字的算法的结果是一个数字,并且该数字减去步进基准不是允许值步进的整数倍时,元素步进不匹配

以下范围控件仅接受0到1范围内的值,并允许该范围内的256步:

<input name=opacity type=range min=0 max=1 step=0.00392156863>

以下控件允许选择一天中的任何时间,精度可以达到任意程度(例如千分之一秒或更高):

<input name=favtime type=time step=any>

通常,时间控件的精度限制为一分钟。

4.10.5.3.9 list 属性

Element/input#list

所有当前引擎均支持。

Firefox4+Safari12.1+Chrome20+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android4.4.3+Samsung Internet?Opera Android12.1+

list 属性用于标识列出建议用户的预定义选项的元素。

如果存在,其值必须是同一中的datalist元素的ID

建议来源元素中第一个具有与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属性不适用

当用户选择一个建议时,input元素的必须设置为所选建议的,就像用户自己编写了该值一样。

如果元素的type属性处于Email状态,并且元素指定了multiple属性

当用户选择一个建议时,用户代理必须向input元素的添加一个新条目,该条目的值是所选建议的,或者将现有条目更改为所选建议的,就像用户自己添加或编辑了一个条目一样。具体的行为取决于用户界面的实现定义方式。


如果list属性不适用,则没有建议来源元素

此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元素产生任何影响。

4.10.5.3.10 placeholder 属性

Element/input#placeholder

所有当前引擎均支持。

Firefox4+Safari4+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

Element/input#attr-placeholder

所有当前引擎均支持。

Firefox4+Safari4+Chrome3+
Opera≤12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android≤37+Samsung Internet?Opera Android≤12.1+

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="&#x202B;رقم الهاتف 1&#x202E;">
<input name=t2 type=tel placeholder="&#x202B;رقم الهاتف 2&#x202E;">

为了稍微更清楚一点,下面是使用数字字符引用而不是内联阿拉伯语的相同示例:

<input name=t1 type=tel placeholder="&#x202B;&#1585;&#1602;&#1605; &#1575;&#1604;&#1607;&#1575;&#1578;&#1601; 1&#x202E;">
<input name=t2 type=tel placeholder="&#x202B;&#1585;&#1602;&#1605; &#1575;&#1604;&#1607;&#1575;&#1578;&#1601; 2&#x202E;">
4.10.5.4 通用 input 元素 API
input.value [ = value ]

返回表单控件的当前

可以设置以更改值。

如果控件是文件上传控件且设置为非空字符串,则抛出"InvalidStateError" DOMException

input.checked [ = value ]

返回表单控件的当前checkedness

可以设置以更改checkedness

input.files [ = files ]

FileList

Support in all current engines.

Firefox3+Safari4+Chrome2+
Opera11.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11.1+

HTMLInputElement/files

Support in all current engines.

Firefox3+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer🔰 10+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回一个列出表单控件所选文件的FileList 对象。

如果控件不是文件控件,则返回null。

可以设置为FileList 对象,以更改表单控件的选定文件。 例如,作为拖放操作的结果。

input.valueAsDate [ = value ]

返回一个表示表单控件的Date 对象(如果适用);否则返回null。

可以设置以更改值。

如果控件不是基于日期或时间的,则抛出"InvalidStateError" DOMException

input.valueAsNumber [ = value ]

返回一个表示表单控件的的数字(如果适用);否则返回NaN。

可以设置以更改值。将其设置为NaN将把基础值设置为空字符串。

如果控件既不是基于日期或时间的也不是数字的,则抛出"InvalidStateError" DOMException

input.stepUp([ n ])

HTMLInputElement/stepUp

Firefox🔰 16+Safari5+Chrome5+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
input.stepDown([ n ])

HTMLInputElement/stepDown

Firefox🔰 16+Safari5+Chrome5+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

更改表单控件的,以step属性中的值乘以nn的默认值为1。

如果控件既不是基于日期或时间的也不是数字的,或step属性的值为"any",则抛出"InvalidStateError" DOMException

input.list

返回由datalist属性指示的list元素。

input.showPicker()

显示适用于input的任何适用的选择器UI,以便用户可以选择一个值。(如果没有为给定控件实现选择器UI,则此方法不执行任何操作。)

如果input不是可变的,则抛出"InvalidStateError" DOMException

如果在没有临时用户激活的情况下调用,则抛出"NotAllowedError" DOMException

如果input位于跨域iframe内,则抛出"SecurityError" DOMException,除非input处于文件上传颜色状态。

value IDL属性允许脚本操作input 元素。该属性处于以下模式之一,定义其行为:

value

在获取时,返回元素的当前

在设置时:

  1. oldValue为元素的

  2. 将元素的设置为新值。

  3. 将元素的脏值标志设置为true。

  4. 如果元素的type属性的当前状态定义了值消毒算法,则调用值消毒算法

  5. 如果应用值消毒算法后,元素的oldValue不同,且元素有文本输入光标位置,则将文本输入光标位置移动到文本控件的末尾,取消选中的文本并重置选择方向为"none"。

default

在获取时,如果元素有value内容属性,则返回该属性的值;否则返回空字符串。

在设置时,将元素的value内容属性的值设置为新值。

default/on

在获取时,如果元素有value内容属性,则返回该属性的值;否则返回字符串"on"。

在设置时,将元素的value内容属性的值设置为新值。

filename

在获取时,返回字符串"C:\fakepath\",后跟所选文件列表中第一个文件的名称(如果有);如果列表为空,则返回空字符串。

在设置时,如果新值为空字符串,则清空所选文件列表;否则抛出"InvalidStateError" DOMException

这个“假路径”要求是历史上的一个遗憾事故。有关更多信息,请参见文件上传状态部分的示例

由于文件列表中的文件名中不允许有路径组件,因此"\fakepath\"不能被误认为是路径组件。


checked IDL属性允许脚本操作input 元素的checkedness。在获取时,它必须返回元素的当前 checkedness;在设置时,它必须将元素的checkedness设置为新值,并将元素的脏checkedness标志设置为true。


files IDL属性允许脚本访问元素的选定文件

在获取时,如果IDL属性适用,则必须返回一个表示当前选定文件FileList对象。必须返回相同的对象,直到选定文件列表发生变化。 如果IDL属性不适用,则必须返回null。[FILEAPI]

在设置时,必须运行这些步骤:

  1. 如果IDL属性不适用或给定值为null,则返回。

  2. 用给定值替换元素的选定文件


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)方法, 在调用时,必须运行以下算法:

  1. 如果stepDown()stepUp()方法不适用,如input元素的type属性的当前状态定义的那样,则抛出"InvalidStateError" DOMException

  2. 如果元素没有允许的值步长,则抛出"InvalidStateError" DOMException

  3. 如果元素有一个最小值和一个最大值,并且最小值大于最大值,则返回。

  4. 如果元素有一个最小值和一个最大值,并且没有大于或等于 元素的最小值且小于或等于元素的最大值的值,在从步长基数中减去时,是允许的值步长的整数倍,则返回。

  5. 如果将字符串转换为数字的算法应用于由元素的给出的字符串时没有产生错误,则令 value为该算法的结果。否则,令value为零。

  6. valueBeforeSteppingvalue

  7. 如果从步长基数中减去value不是允许的值步长的整数倍,则将value设置为最近的值,在从步长基数中减去时,是允许的值步长的整数倍,且小于 value,如果调用的方法是stepDown() 方法,且大于value,否则。

    否则(从步长基数中减去value是允许的值步长的整数倍):

    1. n为参数。

    2. delta为允许的值步长乘以n

    3. 如果调用的方法是stepDown() 方法,则取delta的相反数。

    4. value 为将delta加到value的结果。

  8. 如果元素有一个最小值,且value小于该最小值,则将 value设置为从步长基数中减去时,是允许的值步长的整数倍的最小值,且大于或等于 minimum

  9. 如果元素有一个最大值,且value大于该最大值,则 将value设置为从步长基数中减去时,是允许的值步长的整数倍的最大值,且小于或等于 maximum

  10. 如果调用的方法是stepDown()方法且value大于valueBeforeStepping,或调用的方法是stepUp()方法且value小于valueBeforeStepping,则返回。

    这确保了在以下示例中,在input元素上调用stepUp()方法不会更改该元素的

    <input type=number value=1 max=0>
  11. value as string为运行定义该状态的将数字转换为字符串的算法,以获取value的结果。

  12. 将元素的设置为value as string


list IDL属性必须返回当前的建议源元素(如果有),否则返回null。


HTMLInputElement/showPicker

Support in all current engines.

Firefox101+Safari16+Chrome99+
Opera?Edge99+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLInputElement showPicker()HTMLSelectElement showPicker() 方法步骤如下:

  1. 如果this不是可变的,则抛出 "InvalidStateError" DOMException

  2. 如果this相关设置对象来源this 相关设置对象顶级来源不是同一来源,且 thisselect元素,或者 thistype属性不在文件上传状态或颜色状态,则抛出 "SecurityError" DOMException

    文件颜色输入因历史原因而免于此检查:它们的输入激活行为也显示了它们的选择器,从未受到来源检查的保护。

  3. 如果this相关全局对象没有临时激活,则抛出"NotAllowedError" DOMException

  4. 如果thisselect元素,且this渲染,则抛出"NotSupportedError" DOMException

  5. 显示选择器,如果适用,用于this

要为inputselect元素element显示选择器,如果适用,请执行以下步骤:

  1. 如果element相关全局对象没有临时激活,则返回。

  2. 如果 element 不是 可变的,则返回。

  3. 消耗用户激活,给定element相关全局对象

  4. 如果elementinput元素,并且elementtype属性处于文件上传状态,则并行运行这些步骤:

    1. 可选地,等待直到此算法的任何先前执行终止。

    2. 向用户显示一个提示,要求用户指定一些文件。如果multiple属性未设置在element上,则不能选择多个文件;否则,可以选择任意数量的文件。文件可以来自文件系统或动态创建,例如,从连接到用户设备的相机拍摄的照片。

    3. 等待用户做出选择。

    4. 如果用户在未更改选择的情况下关闭了提示,则在用户交互任务源排队一个元素任务,给定element触发一个事件,名为cancelelement上,bubbles属性初始化为true。

    5. 否则,更新文件选择element

    与所有用户界面规范一样,用户代理在解释这些要求时有很大的自由度。上述文本意味着用户要么取消提示,要么更改选择;其中一个肯定会成立。但是,标准并未强制将这些可能性映射到具体的用户界面元素。例如,用户代理可能将点击“取消”按钮时的操作解释为选择零文件,从而触发inputchange事件。或者,它可能将此类点击解释为未更改选择的取消,从而触发cancel事件。同样,重新选择之前选择的相同文件是否计为取消或更改选择取决于用户代理的解释。

  5. 否则,用户代理应显示任何相关的用户界面,用于选择element的值,就像用户与控件交互时通常会显示一样。(如果element没有应用此类用户界面,则此步骤不执行任何操作。)

    如果显示了此类用户界面,则它必须尊重规范中关于element行为的相关部分的要求,给定其type属性状态。(例如,各种部分描述了对生成的字符串的限制。)

    此步骤可以有副作用,例如关闭以前由此算法显示的其他选择器。(如果这关闭了文件选择器,则根据上述内容,这将导致触发inputchange事件,或cancel事件。)

    截至本文撰写时,典型的浏览器实现显示此类选择器用户界面:

    然而,此步骤的目的是触发任何选择器用户界面实现。因此,例如,如果用户代理实现了密码状态的密码选择器用户界面,则调用此方法时,预期会显示该密码输入的选择器用户界面。

4.10.5.5 常见事件行为

inputchange事件适用时(这适用于所有input控件,除了按钮和那些type属性处于隐藏状态的控件),会触发这些事件以指示用户已与控件进行交互。每当用户修改控件的数据时,input事件就会触发。当值被提交时,change事件会触发,如果控件失去焦点时也是如此。在所有情况下,input事件会先于对应的change事件(如果有的话)触发。

input元素有定义的输入激活行为时,如果这些事件适用,则触发这些事件的规则在上方定义type属性状态的部分中给出。(这适用于所有input控件,其type属性处于复选框状态、单选按钮状态或文件上传状态。)

对于没有定义输入激活行为但这些事件适用input元素,如果用户界面涉及交互操作和明确的提交操作,当用户更改元素的时,用户代理必须在input元素上排队一个元素任务,在input元素上触发一个名为input的事件,bubblescomposed属性初始化为true;每当用户提交更改时,用户代理必须在input元素上排队一个元素任务,将其用户有效性设置为true,并在input元素上触发一个名为change的事件,bubbles属性初始化为true。

一个涉及交互操作和提交操作的用户界面的例子是使用滑块的范围控件。当用户使用指点设备拖动控件的旋钮时,每当位置变化时会触发input事件,而只有当用户松开旋钮提交到特定值时才会触发change事件。

对于没有定义输入激活行为但这些事件适用input元素,如果用户界面涉及明确的提交操作但没有中间操作,每当用户提交对元素的更 改时,用户代理必须在input元素上首先触发一个名为input的事件,bubblescomposed属性初始化为true,然后在input元素上触发一个名为change的事件,bubbles属性初始化为true。

一个有提交操作的用户界面的例子是由单个按钮组成的颜色控件,该按钮弹出一个颜色轮:如果只有在对话框关闭时值才会改变,则这就是明确的提交操作。另一方面,如果操作控件时颜色会交互地改变,则可能没有提交操作。

另一个有提交操作的用户界面的例子是允许用户输入文本和从下拉日历中选择日期的日期控件:虽然文本输入可能没有明确的提交步骤,但从下拉日历中选择日期然后关闭下拉框则是提交操作。

对于没有定义输入激活行为但这些事件适用input元素,每当用户在没有明确提交操作的情况下导致元素的变化时,用户代理必须在input元素上排队一个元素任务,触发一个名为input的事件,bubblescomposed属性初始化为true。相应的change事件(如果有)将在控件失去焦点时触发。

用户更改元素的例子包括用户在文本控件中输入、粘贴新值或撤销编辑。某些用户交互不会导致值更改,例如在空文本控件中按“删除”键,或用与剪贴板中完全相同的文本替换控件中的某些文本。

用户用键盘操作并聚焦的范围控件(滑块)是用户更改元素而无需提交步骤的另一个例子。

对于仅触发input事件的任务,用户代理可能会等待用户交互的适当间隙再排队这些任务;例如,用户代理可以等待用户在100毫秒内未按键,以便在用户暂停时而不是每次按键时触发事件。

当用户代理要代表用户更改input元素的时(例如作为表单预填充功能的一部分),用户代理必须在input元素上排队一个元素任务,首先相应地更新,然后在input元素上触发一个名为input的事件,bubblescomposed属性初始化为true,然后在input元素上触发一个名为change的事件,bubbles属性初始化为true。

这些事件不会响应脚本对表单控件值的更改而触发。(这是为了更容易地响应用户操作控件来更新表单控件的值,而不必过滤脚本自身的更改以避免无限循环。)

当浏览器在导航期间作为状态恢复的一部分更改表 单控件的值时,这些事件也不会触发。

4.10.6 button 元素

Element/button

Support in all current engines.

Firefox1+Safari4+Chrome1+
Opera15+Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android14+

HTMLButtonElement

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
分类:
流内容
短语内容
交互内容
列出的可标记的可提交的,以及自动大写和自动更正继承的 与表单关联的元素
可感知内容
元素可使用的上下文:
在需要短语内容的地方。
内容模型:
短语内容,但不能有交互内容后代,且不能有指定tabindex属性的后代。
text/html中的标签省略:
两者都不能省略。
内容属性:
全局属性
disabled — 表单控件是否禁用
form — 将元素与表单元素关联
formaction — 用于表单提交URL
formenctype — 用于表单提交条目列表编码类型
formmethod — 用于表单提交的变体
formnovalidate — 跳过表单提交的表单控件验证
formtarget — 用于表单提交导航对象
name — 用于表单提交form.elements API中的元素名称
popovertarget — 目标弹出元素的切换、显示或隐藏
popovertargetaction — 指示目标弹出元素是切换、显示还是隐藏
type — 按钮类型
value — 用于表单提交的值
可访问性考虑:
面向作者
面向实现者
DOM接口:
[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;

button 元素表示由其内容标记的按钮。

该元素是一个按钮

type 属性控制按钮激活时的行为。它是一个枚举属性,具有以下关键字和状态:

关键字 状态 简要描述
submit 提交按钮 提交表单。
reset 重置按钮 重置表单。
button 按钮 无操作。

属性的缺失值默认值无效值默认值均为提交按钮状态。

如果type属性为提交按钮状态,则该元素是一个特定的提交按钮

约束验证: 如果type属性为重置按钮状态或按钮状态,则该元素不参与约束验证

button 元素 element 激活行为给定event如下:

  1. 如果element禁用的,则返回。

  2. 如果element节点文档完全激活,则返回。

  3. 如果element有一个表单所有者,则根据elementtype属性的状态进行切换,然后:

    提交按钮

    提交element表单所有者,来自element用户参与设置为event用户导航参与

    重置按钮

    重置element表单所有者

    按钮

    无操作。

  4. 运行弹出目标属性激活行为给定element

form属性用于显式关联button元素与其表单所有者name属性表示元素的名称。disabled属性用于使控件不可交互并防止其值被提交。formaction, formenctype, formmethod, formnovalidate, 和 formtarget表单提交的属性

formnovalidate属性可用于制作不触发约束验证的提交按钮。

formaction, formenctype, formmethod, formnovalidate, 和 formtarget如果元素的type属性不处于提交按钮状态,则不得指定。

value属性为表单提交目的提供元素的值。元素的是其value属性的值(如果有),否则为空字符串。

按钮(及其值)仅在按钮本身用于启动表单提交时才包含在表单提交中。


value IDL属性必须反映同名内容属性。

type 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>

4.10.7 select 元素

Element/select

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera2+Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android4+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

HTMLSelectElement

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera2+Edge79+
Edge (旧版)12+Internet Explorer1+
Firefox Android4+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+
类别:
流内容.
短语内容.
交互内容.
列出的可标记的可提交的可重置的,以及自动大写和自动更正继承的 与表单关联的元素
明显内容.
该元素可用的上下文:
在需要短语内容的地方。
内容模型:
零个或多个option, optgroup, hr, 和脚本支持元素。
在text/html中省略标签:
标签不可省略。
内容属性:
全局属性
autocomplete — 表单自动填充功能的提示
disabled — 表单控件是否禁用
form — 将元素与form元素关联
multiple — 是否允许多个值
name — 用于表单提交的元素名称,并在form.elements API中使用
required — 控件是否必需用于表单提交
size — 控件的大小
无障碍考虑:
如果元素有multiple属性或size属性且值大于1: 作者; 实现者
否则: 作者; 实现者
DOM接口:
[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 元素表示一个用于从一组选项中选择的控件。

Attributes/multiple

所有当前引擎支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

multiple 属性是一个 布尔属性。如果存在该属性,则 select 元素表示一个从 选项列表中选择零个或多个选项的控件。如果该属性不存在,则 select 元素表示一个从 选项列表中选择一个选项的控件。

Attributes/size

所有当前引擎支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

size 属性表示要显示给用户的选项数量。size 属性(如果指定)必须具有一个大于零的 有效非负整数 值。

display size 是应用 解析非负整数的规则 的结果,如果该值成功解析。如果解析失败或者 size 属性不存在,那么元素的显示大小为 4(如果存在 multiple 内容属性),否则为 1。

list of options 由所有的 option 元素组成,这些元素是 select 元素的子元素,或者是 optgroup 元素的子元素,并按 树形顺序排列。

Attributes/required

所有当前引擎支持。

Firefox4+Safari5.1+Chrome10+
Opera?Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

required 属性是一个 布尔属性。当指定时,用户在提交表单之前必须选择一个值。

如果一个 select 元素指定了 required 属性,没有指定 multiple 属性,并且 显示大小 为 1;如果第一个 option 元素的 为空字符串,并且该 option 元素的父节点是 select 元素(而不是 optgroup 元素),那么该 optionselect 元素的 占位符标签选项

如果一个 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,是运行以下步骤:

  1. 如果 elementmultiple 属性不存在,并且 element显示大小 为 1,并且 element选项列表 中没有 option 元素的 选中状态 设为 true,则将 选中状态 设为第一个 树形顺序 中的 option 元素(如果有)为 true,然后返回。

  2. 如果 elementmultiple 属性不存在,并且 element选项列表中的两个或多个 option 元素的 选中状态设置为 true,则将树顺序中除最后一个 选项列表选中状态设置为 true 的所有 option 元素的 选中状态设置为 false。

option HTML 元素插入步骤,给定 insertedNode,如下:

  1. 如果 insertedNode 的父节点是 select 元素,或者 insertedNode 的父节点是一个 optgroup 元素,其父节点是 select 元素,则运行该 select 元素的 选中状态设置算法

option HTML 元素移除步骤,给定 removedNodeoldParent,如下:

  1. 如果 oldParentselect 元素,或者 oldParent 是一个 optgroup 元素,其父节点是 select 元素,则运行该 select 元素的 选中状态设置算法

optgroup HTML 元素移除步骤,给定 removedNodeoldParent,如下:

  1. 如果 oldParentselect 元素并且 removedNode 有一个 option 子元素,则运行 oldParent选中状态设置算法

如果 option 元素在 选项列表请求重置,则运行该 select 元素的 选中状态设置算法

如果 multiple 属性存在,并且该元素未被 禁用,则用户代理应允许用户 切换 选中状态option 元素在其 选项列表 中的状态,这些元素本身未被 禁用。在此元素被 切换(通过点击、菜单命令或其他机制)之前,并在相关用户交互事件排队之前(例如在相关 click 事件之前),用户代理必须更改 选中状态(从 true 到 false 或从 false 到 true),将该元素的 脏状态 设为 true,并且用户代理必须 发送 select 更新通知

当用户代理要发送select更新通知时,在用户交互任务源排队一个元素任务,给定select元素以运行这些步骤:

  1. select 元素的 用户有效性 设为 true。
  2. 触发一个事件,名为inputselect元素上,bubblescomposed属性初始化为true。

  3. 触发一个事件,名为changeselect元素上,bubbles属性初始化为true。

重置算法 对于 select 元素 selectElement 如下:

  1. selectElement用户有效性 设为 false。

  2. 对于每个 optionElementselectElement选项列表 中:

    1. 如果 optionElementselected 属性,则将 optionElement选中状态 设为 true;否则设为 false。

    2. optionElement脏状态 设为 false。

  3. 运行 选中状态设置算法 给定 selectElement

form 属性用于显式关联 select 元素与其 表单所有者name 属性表示元素的名称。disabled 属性用于使控件不可交互并防止其值被提交。autocomplete 属性控制用户代理如何提供自动填充行为。

未被 禁用select 元素是 可变 的。

select.type

HTMLSelectElement/type

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera2+Edge79+
Edge (旧版)12+Internet Explorer1+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

返回 "select-multiple" 如果该元素有 multiple 属性,否则返回 "select-one"。

select.options

HTMLSelectElement/options

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 HTMLOptionsCollection选项列表

select.length [ = value ]

返回 选项列表 中的元素数。

当设置为较小的数字时,截断 option 元素的数量在 select

当设置为较大的数字时,向 select 中添加新的空白 option 元素。

element = select.item(index)

HTMLSelectElement/item

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
select[index]

返回 选项列表 中索引为 index 的项目。这些项目按 树顺序 排序。

element = select.namedItem(name)

HTMLSelectElement/namedItem

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 IDnamename 的第一个项目从 选项列表

如果找不到具有该 ID 的元素,则返回 null。

select.add(element [, before ])

HTMLSelectElement/add

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

在由 before 指定的节点之前插入 element

before 参数可以是一个数字,在这种情况下 element 被插入到该数字的项目之前,或者 选项列表 中的一个元素,在这种情况下 element 被插入到该元素之前。

如果省略 before,为 null,或超出范围的数字,则 element 将被添加到列表的末尾。

如果 element 是要插入的元素的祖先,此方法将抛出 "HierarchyRequestError" DOMException

select.selectedOptions

HTMLSelectElement/selectedOptions

Support in all current engines.

Firefox26+Safari6+Chrome19+
Opera9+Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

返回 HTMLCollection 选项的 选项列表

select.selectedIndex [ = value ]

HTMLSelectElement/selectedIndex

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回第一个选中项的索引,如果有的话,否则为 -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 集合上的同名方法一样。

HTMLSelectElement/remove

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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 的情况下也是如此。

multiplerequiredsize IDL 属性必须 反映同名的内容属性。size IDL 属性的 默认值 为 0。

出于历史原因,size IDL 属性的默认值不会返回实际使用的大小,在没有 size 内容属性的情况下,实际大小取决于 multiple 属性的存在情况,要么是 1 要么是 4。

willValidatevalidityvalidationMessage IDL 属性,以及 checkValidity()reportValidity()setCustomValidity() 方法是 约束验证 API 的一部分。labels IDL 属性提供了元素的 label 列表。disabledformname 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
  …

4.10.8 datalist 元素

Element/datalist

Firefox🔰 4+Safari12.1+Chrome20+
Opera9.5+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android🔰 79+Safari iOS?Chrome Android33+WebView Android?Samsung Internet?Opera Android?

HTMLDataListElement

Support in all current engines.

Firefox4+Safari12.1+Chrome20+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android4.4.3+Samsung Internet?Opera Android12.1+
类别:
流内容.
短语内容.
此元素可使用的上下文:
需要短语内容的地方。
内容模型:
可以是短语内容。
或者:零个或多个option和脚本支持元素。
在text/html中省略标签:
两端标签均不可省略。
内容属性:
全局属性
无障碍考虑事项:
作者指南.
实现者指南.
DOM接口:
[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 元素祖先,则该元素被禁止约束验证

4.10.9 optgroup 元素

Element/optgroup

支持所有当前的引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
旧版 Edge12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLOptGroupElement

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
旧版 Edge12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
分类:
无。
此元素可使用的上下文:
作为 select 元素的子元素。
内容模型:
零个或多个 option脚本支持的 元素。
text/html 中的标签省略:
optgroup 元素的 结束标签 可省略, 如果 optgroup 元素紧跟另一个 optgroup 元素、紧跟一个 hr 元素,或父元素中没有更多内容时。
内容属性:
全局属性
disabled — 是否禁用表单控件
label — 用户可见的标签
可访问性注意事项:
作者指南
实现者指南
DOM 接口:
[Exposed=Window]
interface HTMLOptGroupElement : HTMLElement {
  [HTMLConstructor] constructor();

  [CEReactions] attribute boolean disabled;
  [CEReactions] attribute DOMString label;
};

The optgroup 元素表示具有相同标签的一组 option 元素。

该元素的 option 元素组由 optgroup 元素的子元素组成。

select 元素中显示 option 元素时,用户代理应将这些组的 option 元素视为彼此相关,并与其他 option 元素分开。

Attributes/disabled

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

disabled 属性是一个 布尔属性,可用于 禁用一组 option 元素。

label 属性必须指定。其值给出了该组的名称,用于用户界面。用户代理应在为 option 元素组在 select 元素中进行标记时使用此属性的值。

disabledlabel 属性必须 反映各自的内容属性。

没有办法选择 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>

4.10.10 option 元素

元素/option

在所有当前引擎中都支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLOptionElement

在所有当前引擎中都支持。

Firefox1+Safari1.2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
无。
此元素可使用的上下文:
作为 select 元素的子元素。
作为 datalist 元素的子元素。
作为 optgroup 元素的子元素。
内容模型:
如果元素有 label 属性和 value 属性: 无内容
如果元素有 label 属性但没有 value 属性: 文本
如果元素没有 label 属性并且不是 datalist 元素的子元素: 文本,但不包括 元素间的空白
如果元素没有 label 属性并且是 datalist 元素的子元素: 文本
在 text/html 中的标签省略:
如果 option 元素紧跟在另一个 option 元素之后,或紧跟在一个 optgroup 元素之后,或紧跟在一个 hr 元素之后,或者父元素中没有更多内容,则可以省略 option 元素的 结束标签
内容属性:
全局属性
disabled — 表单控件是否被禁用
label — 用户可见的标签
selected — 该选项是否默认被选中
value — 用于 表单提交的值
可访问性考虑:
供作者使用
供实施者使用
DOM 接口:
[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

在所有当前引擎中都支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

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

返回元素在其 select 元素的 options 列表中的索引。

option.form

返回元素的 form 元素(如果有),否则返回 null。

option.text

textContent相同, 只是空格会被折叠且 script 元素会被跳过。

option = new Option([ text [, value [, defaultSelected [, selected ] ] ] ])

HTMLOptionElement/Option

在所有当前引擎中都支持。

Firefox1+Safari1.2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回一个 新的 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 元素的后代,按 树顺序,排除任何是其自身的 scriptSVG 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)。调用传统工厂函数时,必须执行以下步骤:

  1. document当前全局对象关联 Document

  2. option创建元素的结果,给定 documentoptionHTML 命名空间

  3. 如果 text 不为空字符串,则向 option 追加一个新的 文本 节点,其数据为 text

  4. 如果提供了 value,则为 option 设置一个属性值,使用 "value" 和 value

  5. 如果 defaultSelected 为 true,则为 option 设置一个属性值,使用 "selected" 和空字符串。

  6. 如果 selected 为 true,则将 option选中状态设置为 true;否则,将其 选中状态设置为 false(即使 defaultSelected 为 true)。

  7. 返回 option

4.10.11 textarea 元素

元素/textarea

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLTextAreaElement

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer5+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+
类别:
流内容.
短语内容.
交互内容.
列出的可标记的可提交的可重置的,以及自动大写和自动更正继承的 与表单关联的元素
可感知内容.
该元素可用于的上下文:
期望 短语内容 的地方。
内容模型:
文本.
在 text/html 中省略标签:
两个标签都不能省略。
内容属性:
全局属性
autocomplete — 表单自动填充特性的提示
cols — 每行的最大字符数
dirname — 用于发送元素的方向性的表单控件名称在表单提交
disabled — 表单控件是否禁用
form — 将元素与 表单元素关联
maxlength — 值的最大 长度
minlength — 值的最小 长度
name — 用于 表单提交form.elements API 中使用的元素名称
placeholder — 要放置在表单控件中的用户可见标签
readonly — 是否允许用户编辑值
required — 控件是否为 表单提交 所必需
rows — 要显示的行数
wrap — 表单控件的值在 表单提交时如何换行
可访问性注意事项:
作者.
实现者.
DOM 接口:
[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" ] &amp;&amp; return

...</textarea>

约束验证: 如果 readonly 属性在 textarea 元素上指定,则该元素 被禁止约束验证.

textarea 元素是 可变的 如果它既不是 禁用的 也没有指定 readonly 属性。

textarea可变的时,其原始值应该可供用户编辑:用户代理应允许用户编辑、插入和删除文本,以及以U+000A LINE FEED (LF)字符的形式插入和删除换行符。任何时候用户导致元素的原始值发生变化,用户代理必须在用户交互任务源上排队一个给定 textarea 元素的元素任务以触发一个名为 input 的事件,事件发生在 textarea 元素,bubblescomposed 属性初始化为 true。用户代理可以在用户交互中找到合适的休息时间再排队该任务;例如,用户代理可以等待用户在100毫秒内未按下任何键,以便仅在用户暂停时触发事件,而不是每次按键时连续触发事件。

textarea 元素的 脏值标志 必须在用户与控件交互以更改 原始值 时设为 true。

克隆步骤 对于 textarea 元素必须传播被克隆节点的 原始值脏值标志 到副本。

重置算法 对于 textarea 元素是将 用户有效性 设置为 false,将 脏值标志 重置为 false,并将元素的 原始值 设置为其 子文本内容

textarea 元素从 开放元素堆栈 中弹出时用户代理必须调用元素的 重置算法

如果元素是 可变的, 用户代理应该允许用户改变元素的书写方向,将其设置为从左到右或从右到左。如果用户这样做,用户代理必须执行以下步骤:

  1. 将元素的 dir 属性设置为 "ltr" 如果用户选择从左到右的书写方向,并且 "rtl" 如果用户选择从右到左的书写方向。

  2. 排队一个元素任务用户交互任务源上,给定textarea元素去触发一个事件,名为inputtextarea元素上,bubblescomposed属性初始化为true。

cols 属性指定每行的预期最大字符数。如果 cols 属性已指定,其值必须是大于零的有效非负整数。如果将 解析非负整数的规则 应用于属性的值结果为一个大于零的数字,则元素的字符宽度即为该值;否则,其值为20。

用户代理可以使用 textarea 元素的 字符宽度 作为对用户的提示,例如让控件的宽度为该字符数。在视觉渲染中,用户代理应该在渲染时将用户的输入换行,使每行的宽度不超过这个字符数。

rows 属性指定要显示的行数。如果 rows 属性已指定,其值必须是大于零的 有效非负整数。如果将 解析非负整数的规则 应用于属性的值结果为一个大于零的数字,则元素的 字符高度即为该值;否则,其值为2。

视觉用户代理应将控件的高度设置为 字符高度 所指定的行数。

wrap 属性是一个 枚举属性,具有以下关键字和状态:

关键字 状态 简要描述
soft 文本在提交时不换行(虽然仍然可以在渲染中换行)。
hard 用户代理应插入换行符以确保文本在提交时换行。

属性的 缺失值默认值无效值默认值 均为 状态。

如果元素的 wrap 属性处于 状态,则必须指定 cols 属性。

由于历史原因,元素的值在三种不同用途上以三种不同方式进行规范化。原始值 是最初设置的值。它不进行规范化。API 值 是在 value IDL 属性中使用的值,在 textLength IDL 属性中使用的值,以及由 maxlengthminlength 内容属性使用的值。它被规范化为换行符使用 U+000A 换行符 (LF) 字符。最后,有 ,在此规范中的表单提交和其他处理模型中使用。它被规范化为 API 值,并且如果根据元素的 wrap 属性需要,还会插入额外的换行符以在给定宽度处换行文本。

获取元素 API 值 的算法是返回元素的 原始值,并 规范化换行符

元素的 被定义为元素的 API 值 应用 textarea 换行转换 的结果。textarea 换行转换 是以下算法,对字符串应用:

  1. 如果元素的 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 属性必须 反映相同名称的相应内容属性。colsrows 属性 仅限于正数且有回退值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 值。在设置时,必须执行以下步骤:

  1. oldAPIValue 是此元素的 API 值

  2. 将此元素的 原始值 设置为新值。

  3. 将此元素的 脏值标志 设为 true。

  4. 如果新的 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>

4.10.12 output 元素

Element/output

所有当前引擎均支持。

Firefox4+Safari7+Chrome10+
Opera11+Edge79+
Edge (旧版)18Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+

HTMLOutputElement

所有当前引擎均支持。

Firefox4+Safari5.1+Chrome9+
Opera12.1+Edge79+
Edge (旧版)14+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+
分类:
流内容.
短语内容.
列出的可标记的可重置的,以及自动大写和自动更正继承的 与表单关联的元素
可感知内容
此元素可使用的上下文:
预期为短语内容的地方。
内容模型:
短语内容.
在 text/html 中标签省略:
两个标签都不可省略。
内容属性:
全局属性
for — 指定计算结果的控制项
form — 将元素与form元素关联
name — 在form.elements API 中使用的元素名称。
无障碍考虑:
对作者.
对实现者.
DOM接口:
[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元素对比,后者适用于引用先前运行的其他程序的输出。

Attributes/for

所有当前引擎均支持。

Firefox4+Safari7+Chrome10+
Opera11+Edge79+
Edge (旧版)18Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+

for内容属性允许在计算结果和表示计算输入值的元素之间建立明确关系。for属性(如果指定)必须包含一个无序的唯一空格分隔标记集,其中每个标记都必须具有同一中某个元素的ID值。

form属性用于显式地将output元素与其表单所有者关联。name属性表示元素的名称。output元素与表单关联,以便可以从表单控件的事件处理程序中轻松引用;表单提交时元素的值本身不会提交。

元素有一个默认值覆盖(null或字符串)。最初它必须为null。

元素的默认值由以下步骤确定:

  1. 如果此元素的默认值覆盖不为null,则返回它。

  2. 返回此元素的后代文本内容

重置算法对于output元素是执行以下步骤:

  1. 字符串全部替换此元素内的默认值

  2. 将此元素的默认值覆盖设置为null。

output.value [ = value ]

返回元素的当前值。

可以设置以更改值。

output.defaultValue [ = value ]

返回元素的当前默认值。

可以设置以更改默认值。

output.type

返回字符串"output"。

value getter步骤是返回元素的后代文本内容

value setter步骤是:

  1. 元素的默认值覆盖设置为其默认值

  2. 用给定的值字符串替换元素内。

defaultValue getter步骤是运行元素的默认值

defaultValue setter步骤是:

  1. 如果元素的默认值覆盖为null,则用给定的值字符串替换元素内并返回。

  2. 元素的默认值覆盖设置为给定的值。

type getter步骤是返回"output"。

htmlFor IDL属性必须反映for内容属性。

willValidate, validity, 和validationMessage IDL属性,以及checkValidity(), reportValidity(), 和setCustomValidity()方法是约束验证API的一部分。labels IDL属性提供了元素的label列表。formname 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>

4.10.13 progress 元素

Element/progress

支持所有当前引擎。

Firefox6+Safari6+Chrome6+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android11+

HTMLProgressElement

支持所有当前引擎。

Firefox6+Safari6+Chrome6+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容.
短语内容.
可标记元素.
可感知内容.
此元素可用于的上下文:
在期望 短语内容 的地方。
内容模型:
短语内容,但不能有 progress 元素的后代。
在 text/html 中的标签省略:
两个标签都不能省略。
内容属性:
全局属性
value — 元素的当前值
max — 范围的上限
无障碍考虑:
针对作者.
针对实现者.
DOM 接口:
[Exposed=Window]
interface HTMLProgressElement : HTMLElement {
  [HTMLConstructor] constructor();

  [CEReactions] attribute double value;
  [CEReactions] attribute double max;
  readonly attribute double position;
  readonly attribute NodeList labels;
};

progress 元素 表示 任务的完成进度。 进度要么是不确定的,表示正在取得进展但不清楚任务完成前还需做多少工作(例如,因为任务在等待远程主机响应),要么是一个在零到最大值范围内的数字,表示已完成的工作比例。

Attributes/max

支持所有当前引擎。

Firefox6+Safari6+Chrome6+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS7+Chrome Android?WebView Android?Samsung Internet?Opera Android11+

有两个属性决定了元素所表示的当前任务完成情况。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() 方法将由页面上的其他代码调用,以在任务进展时更新实际进度条。)

valuemax 属性存在时,其值必须是 有效的浮点数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。

labels IDL 属性提供了元素的 label 列表。

4.10.14 meter 元素

元素/meter

支持所有当前引擎。

Firefox16+Safari6+Chrome6+
Opera11+Edge79+
Edge (旧版)18Internet Explorer不支持
Firefox Android?Safari iOS10.3+Chrome Android?WebView Android不支持Samsung Internet?Opera Android11+

HTMLMeterElement

支持所有当前引擎。

Firefox16+Safari6+Chrome6+
Opera11+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+
分类:
流内容
短语内容
可标记元素
可感知内容
该元素可使用的上下文:
在需要 短语内容 的地方。
内容模型:
短语内容,但不能有 meter 元素的后代。
text/html 中的标签省略:
两个标签都不能省略。
内容属性:
全局属性
value — 元素的当前值
min — 范围的下限
max — 范围的上限
low — 低范围的高限
high — 高范围的低限
optimum — 仪表的最佳值
无障碍考虑:
对于作者
对于实现者
DOM 接口:
[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 元素也不表示任意范围内的标量值——例如,用它来报告重量或高度是错误的,除非有已知的最大值。

有六个属性决定了元素表示的仪表的语义。

属性/max

支持所有当前引擎。

Firefox16+Safari6+Chrome6+
Opera11+Edge79+
Edge (旧版)18Internet Explorer不支持
Firefox Android?Safari iOS10.3+Chrome Android?WebView Android不支持Samsung Internet?Opera Android11+

属性/min

支持所有当前引擎。

Firefox16+Safari6+Chrome6+
Opera11+Edge79+
Edge (旧版)18Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android不支持Samsung Internet?Opera Android11+

min 属性指定范围的下限,max 属性指定范围的上限。value 属性指定仪表指示的“测量”值。

其他三个属性可用于将仪表的范围分段为“低”、“中”和“高”部分,并指示哪部分是“最佳”部分。low 属性指定被认为是“低”部分的范围,high 属性指定被认为是“高”部分的范围。optimum 属性给出了“最佳”的位置;如果它高于“高”值,则表示值越高越好;如果它低于“低”值,则表示值越低越好,自然地,如果它介于两者之间,则表示高值和低值都不是好的。

作者要求: 必须指定 value 属性。valueminlowhighmaxoptimum 属性在存在时,必须具有 有效的浮点数 值。

此外,这些属性的值还有进一步的约束:

valuevalue 属性的数值。

如果指定了 min 属性,则 minimum 为该属性的值;否则,设为零。

如果指定了 max 属性,则 maximum 为该属性的值;否则,设为 1.0。

以下不等式必须成立,如适用:

如果未指定最小值或最大值,则假定范围为 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>

用户代理要求: 用户代理必须解析 minmaxvaluelowhighoptimum 属性,使用 解析浮点数值的规则

然后,用户代理必须使用所有这些数字来获得仪表上的六个点的值,如下所示。(这些值的计算顺序很重要,因为某些值引用了较早的值。)

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>

可能呈现如下:

<meter> 元素显示为不同长度的内联绿色条。

用户代理可以结合 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 内容属性必须设置为该字符串。

labels IDL 属性提供元素的 label 列表。

以下示例显示了仪表如何回退到本地化或漂亮的文本。

<p>Disk usage: <meter min=0 value=170261928 max=233257824>170 261 928 bytes used
out of 233 257 824 bytes available</meter></p>

4.10.15 fieldset 元素

Element/fieldset

支持所有当前引擎。

Firefox1+Safari4+Chrome1+
Opera15+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android14+

HTMLFieldSetElement

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
流内容
列出的,以及自动大写和自动更正继承的 与表单关联的元素
可感知内容
该元素可以使用的上下文:
期望流内容的地方。
内容模型:
可选的一个legend元素,后跟流内容
在 text/html 中省略标签:
两个标签都不能省略。
内容属性:
全局属性
disabled — 是否禁用后代表单控件,除了任何在legend内部的控件
form — 将该元素与form元素关联
name — 用于form.elements API 中使用的元素名称。
可访问性考虑:
对作者的建议
对实现者的建议
DOM 接口:
[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

支持所有当前引擎。

Firefox4+Safari6+Chrome20+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

disabled属性,当被指定时,会使fieldset元素的所有表单控件后代(不包括fieldset元素的第一个legend元素子代,如果有的话)禁用

如果满足以下任何条件,fieldset元素就是禁用字段集

form属性用于显式地将fieldset元素与其表单所有者关联。name属性表示元素的名称。

fieldset.type

返回字符串 "fieldset"。

fieldset.elements

返回元素中的表单控件的HTMLCollection

disabled IDL属性必须反映同名的内容属性。

type IDL属性必须返回字符串"fieldset"。

elements IDL属性必须返回一个HTMLCollection,它以fieldset元素为根,其过滤器匹配列出的元素

willValidatevalidity,和validationMessage属性,以及checkValidity()reportValidity(),和setCustomValidity()方法,都是约束验证API的一部分。formnameIDL属性是元素的表单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>

4.10.16 legend 元素

Element/legend

所有当前引擎支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLLegendElement

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
类别:
无。
此元素可使用的上下文:
作为fieldset元素的第一个子元素。
内容模型:
短语内容,可选地与标题内容混合。
在text/html中省略标签:
标签不可省略。
内容属性:
全局属性
无障碍考虑:
作者
实现者
DOM 接口:
[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。

4.10.17 表单控件基础设施

4.10.17.1 表单控件的值

大多数表单控件都有一个和一个选中状态。(后者仅用于input 元素。)这些用于描述用户如何与控件进行交互。

控件的是其内部状态。因此,它可能与用户的当前输入不匹配。

例如,如果用户在一个预期为数字的数字字段中输入单词“three”,用户的输入将是字符串“three”,但控件的将保持不变。或者,如果用户在电子邮件字段中输入电子邮件地址“  awesome@example.com”(前导空格),用户的输入将是字符串“  awesome@example.com”,但浏览器的电子邮件字段UI可能会将其转换为没有前导空格的awesome@example.com”。

inputtextarea 元素有一个脏值标志。 这用于跟踪和默认值之间的交互。如果为false,镜像默认值。如果为true,则忽略默认值。

inputtextareaselect 元素有一个 用户有效性布尔值。它最初设置为false。

为了定义约束验证在input 元素的multiple 属性中的行为,input 元素 也可以有单独定义的s

为了定义maxlengthminlength 属性的行为,以及其他特定于 textarea 元素的API,所有具有的表单控件也有一个获取API值的算法。默认情况下,此算法只是简单地返回控件的

select 元素没有; 使用的是其option 元素的选中状态

4.10.17.2 可变性

表单控件可以被指定为可变的

这决定了(通过本规范中依赖于元素是否被指定为可变的定义和要求)用户是否可以修改表单控件的选中状态,或者控件是否可以自动预填充。

4.10.17.3 控件和表单的关联

与表单关联的元素可以与form元素有关系,这称为元素的表单所有者。如果与表单关联的元素未与form元素关联,则其表单所有者为null。

与表单关联的元素有一个关联的解析器插入标志

Element/input#form

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

Attributes#attr-form

Support in all current engines.

Firefox1+Safari≤4+Chrome1+
Opera≤12.1+Edge79+
Edge (旧版)12+Internet Explorer≤6+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android≤12.1+

与表单关联的元素默认与其最近的祖先form元素相关联(如下所述),但是,如果它是列表,则可以指定一个form属性来覆盖此关联。

此功能允许作者解决嵌套form元素的支持缺乏问题。

如果列出的与表单关联的元素指定了form属性,则该属性的值必须是该元素树中某个form元素的ID

本节中的规则因以下事实而变得复杂:尽管符合规范的文档或永远不会包含嵌套的form元素,但完全有可能(例如,使用执行DOM操作的脚本)生成具有此类嵌套元素的。这些规则还因HTML解析器中的规则而复杂化,这些规则由于历史原因,可能导致与表单关联的元素与不是其祖先的form元素相关联。

当创建与表单关联的元素时,其表单所有者必须初始化为null(无所有者)。

与表单关联的元素要与表单关联时,其表单所有者必须设置为该表单。

列出的与表单关联的元素form属性被设置、更改或删除时,用户代理必须重置该元素的表单所有者

当一个列表表单关联元素有一个form属性,并且树中任何元素的ID发生变化时,用户代理必须重置表单关联元素的表单所有者。

当一个列表表单关联元素有一个form属性,并且具有ID的元素被插入移出文档时,用户代理必须重置表单关联元素的表单所有者。

表单所有者也会被HTML标准的插入步骤移除步骤重置。

重置表单所有者,请执行以下步骤:与表单关联的元素element

  1. 取消设置element解析器插入标志

  2. 如果以下所有条件均为真:

    则返回。

  3. element表单所有者设置为null。

  4. 如果element列表,具有form内容属性,并且是连接的,则:

    1. 如果element中第一个元素(按树顺序),其ID与elementform内容属性的值相同,且是form元素,则将element与该form元素关联

  5. 否则,如果element有一个祖先form元素,则将element与最近的此类祖先form元素关联

在以下不合格的代码片段中

...
 <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"元素。在这一点上,节点看到它们的祖先链发生变化,因此解析器所做的所有“魔术”关联都会重置为正常的祖先关联。

不过,此示例是一个不合格的文档,因为嵌套form元素违反了内容模型,并且</form>标签存在解析错误

element.form

HTMLObjectElement/form

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLSelectElement/form

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android? Samsung Internet?Opera Android12.1+

返回元素的表单所有者

如果没有,则返回null。

列出的与表单关联的元素(除了与表单关联的自定义元素)有一个form IDL属性,获取时必须返回元素的表单所有者,如果没有则返回null。

ElementInternals/form

Support in all current engines.

Firefox98+Safari16.4+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

与表单关联的自定义元素没有form IDL属性。相反,它们的ElementInternals对象有一个form IDL属性。获取时,如果目标元素不是与表单关联的自定义元素,则必须抛出DOMException的“"NotSupportedError"”。否则,必须返回元素的表单所有者,如果没有则返回null。

4.10.18 表单控件通用的属性

4.10.18.1 表单控件命名:name 属性

Element/input#name

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

name 内容属性给出了表单控件的名称,用于表单提交form元素的elements对象。如果指定了该属性,则其值不能是空字符串或isindex

许多用户代理在历史上对名称为isindex的表单中第一个文本控件实现了特殊支持,本规范先前也定义了相关的用户代理要求。然而,一些用户代理随后删除了该特殊支持,并且相关要求已从本规范中删除。因此,为了避免在遗留用户代理中的问题性重新解释,不再允许使用isindex名称。

isindex外,name的任何非空值都是允许的。对名称_charset_ASCII不区分大小写匹配是特殊的:如果用作没有value属性的隐藏控件的名称,则在提交期间,value属性会自动获得一个值,该值包含提交字符编码。

name IDL属性必须反映name内容属性。

DOM篡改是安全问题的常见原因。避免在name内容属性中使用内置表单属性的名称。

在此示例中,input元素覆盖了内置的method属性:

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属性。

4.10.18.2 提交元素的方向性:dirname 属性

Element/input#dirname

Support in all current engines.

Firefox116+Safari6+Chrome17+
Opera12.1+Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

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
4.10.18.3 限制用户输入长度:maxlength 属性

表单控件 maxlength 属性,由 dirty value flag 控制,声明了用户可以输入的字符数限制。字符数使用 长度 测量,并且在 textarea 元素的情况下,所有换行符被规范化为一个字符(与 CRLF 对不同)。

如果一个元素指定了其 表单控件 maxlength 属性,该属性的值必须是一个 有效的非负整数。如果指定了该属性并将其值应用于 解析非负整数的规则 得到了一个数字,那么该数字就是元素的 最大允许值长度。如果省略了该属性或解析其值时出现错误,那么就没有 最大允许值长度

约束验证:如果一个元素有 最大允许值长度,其 dirty value flag 为 true,其 最近一次由用户编辑更改(而不是脚本更改),并且该元素的 长度 大于元素的 最大允许值长度,那么该元素 过长

用户代理可以防止用户使元素的 API 值 设置为一个长度大于该元素的 最大允许值长度 的值。

textarea 元素的情况下,API 值 是不同的。特别是,在检查 换行规范化 之前会应用 最大允许值长度(而不会应用 textarea 包装转换)。

4.10.18.4 设置最小输入长度要求: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>
4.10.18.5 启用和禁用表单控件:disabled 属性

Attributes/disabled

支持所有当前的引擎。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge(旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Attributes/disabled

支持所有当前的引擎。

Firefox4+Safari6+Chrome20+
Opera12+Edge79+
Edge(旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

Attributes/disabled

支持所有当前的引擎。

Firefox1+Safari1+Chrome1+
Opera?Edge79+
Edge(旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Attributes/disabled

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge(旧版)12+Internet Explorer6+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

disabled 内容属性是一个布尔属性

disabled 属性用于option 元素和 disabled 属性用于 optgroup 元素是分别定义的。

如果以下任何一种情况为真,则表单控件是禁用的:

如果表单控件被禁用,则必须防止在用户交互任务源排队的任何 click 事件被分派到该元素上。

约束验证:如果元素是 禁用 的,它将 不受约束验证的限制

HTMLButtonElement/disabled

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLSelectElement/disabled

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera9+Edge79+
Edge(旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

disabled IDL 属性必须反映disabled 内容属性。

4.10.18.6 表单提交属性

Element/form#Attributes_for_form_submission

支持所有当前的引擎。

Firefox4+Safari10.1+Chrome10+
Opera?Edge79+
Edge(旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android?

表单提交属性 可以在 form 元素和 提交按钮(表示提交表单的按钮的元素,例如其 input 元素的 type 属性处于 提交按钮 状态)上指定。

可在 form 元素上指定的 表单提交属性actionenctypemethodnovalidatetarget

可在 提交按钮上指定的相应 表单提交属性formactionformenctypeformmethodformnovalidateformtarget。当省略时,它们默认为 form 元素上指定的相应属性的值。


Element/input#formaction

支持所有当前的引擎。

Firefox4+Safari5+Chrome9+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+

actionformaction 内容属性(如果指定)必须具有 有效的非空URL(可能被空格包围) 值。

元素的 action 是该元素的 formaction 属性的值(如果该元素是 提交按钮 并且具有此属性),或其 表单所有者action 属性的值(如果有),否则为空字符串。


Element/input#formmethod

支持所有当前的引擎。

Firefox4+Safari5+Chrome9+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+

methodformmethod 内容属性是 枚举属性,具有以下关键字和状态:

关键字 状态 简要描述
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>

Element/input#formenctype

支持所有当前引擎。

Firefox4+ Safari5+ Chrome9+
Opera12.1+ Edge79+
Edge (旧版)12+ Internet Explorer10+
Firefox Android? Safari iOS? Chrome Android? WebView Android3+ Samsung Internet? Opera Android12.1+

enctypeformenctype 内容属性是 枚举属性,具有以下关键字和状态:

该属性的 缺失值默认值无效值默认值 均为 application/x-www-form-urlencoded 状态。

formenctype 属性没有 缺失值默认值,其 无效值默认值application/x-www-form-urlencoded 状态。

元素的 enctype 是这三种状态之一。如果元素是 提交按钮 并具有 formenctype 属性,则该元素的 enctype 是该属性的状态;否则,它是其 表单所有者enctype 属性的状态。


Element/input#formtarget

支持所有当前的引擎。

Firefox4+Safari5+Chrome9+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12.1+

targetformtarget 内容属性(如果指定)必须具有 有效的可导航目标名称或关键字 值。


Element/input#formnovalidate

支持所有当前的引擎。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

novalidateformnovalidate 内容属性是 布尔属性。如果存在,它们表示表单在提交时不进行验证。

元素的 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>

HTMLFormElement/action

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLFormElement/target

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLFormElement/method

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLFormElement/enctype

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer6+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLFormElement/encoding

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge(旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

action IDL 属性必须 反映 同名内容属性,除非获取时内容属性缺失或其值为空字符串,则必须返回元素的 节点文档URLtarget IDL 属性必须 反映 同名内容属性。methodenctype IDL 属性必须 反映 同名内容属性,限于仅已知值encoding IDL 属性必须 反映 enctype 内容属性,限于仅已知值noValidate IDL 属性必须 反映 novalidate 内容属性。formAction IDL 属性必须 反映 formaction 内容属性,除非获取时内容属性缺失或其值为空字符串,则必须返回元素的 节点文档URLformEnctype IDL 属性必须 反映 formenctype 内容属性,限于仅已知值formMethod IDL 属性必须 反映 formmethod 内容属性,限于仅已知值formNoValidate IDL 属性必须 反映 formnovalidate 内容属性。formTarget IDL 属性必须 反映 formtarget 内容属性。

4.10.18.7 自动填充
4.10.18.7.1 自动填充表单控件: autocomplete 属性

Attributes/autocomplete

支持所有当前的引擎。

Firefox4+Safari6+Chrome14+
Opera12.1+Edge79+
Edge(旧版)不支持Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

用户代理有时具有帮助用户填写表单的功能,例如根据之前的用户输入预填用户的地址。autocomplete 内容属性可用于提示用户代理如何或是否提供此类功能。

此属性有两种使用方式。当处于自动填充期望模式时, autocomplete 属性描述用户期望输入的内容。当处于自动填充锚模式时, autocomplete 属性描述给定值的意义。

input 元素上,其 type 属性为hidden状态时, autocomplete 属性处于自动填充锚模式。 在其他情况下,它处于自动填充期望模式

当处于自动填充期望模式时, autocomplete 属性(如指定)必须具有一个值,该值是由空格分隔的标记集合,其组成如下: 要么是单个标记,与字符串"off"进行ASCII不区分大小写匹配; 要么是单个标记,与字符串"on"进行ASCII不区分大小写匹配; 或者是自动填充详细标记

当处于自动填充锚模式时, autocomplete 属性(如指定)必须具有一个值,该值是由空格分隔的标记集合组成,只包含自动填充详细标记 (即不允许使用"on"和"off"关键字)。

自动填充详细标记如下所示,按给定顺序排列:

  1. 可选标记,其前八个字符与字符串"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>
  2. 可选标记,与以下字符串之一进行ASCII不区分大小写匹配:

  3. 以下两种选择之一:

  4. 可选标记,与字符串"webauthn"进行ASCII不区分大小写匹配,表示用户代理应在用户与表单控件交互时显示通过条件中介可用的公共密钥凭证webauthn仅对inputtextarea元素有效。

如前所述,属性和其关键字的含义取决于该属性所佩戴的斗篷。

佩戴自动填充预期斗篷时...

"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 namesurname 自由格式文本,无换行符 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 namesurname 自由格式文本,无换行符 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 元素
URL
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级)之前。建议作者提供 符合国家惯例的表单(根据用户更改国家来隐藏、显示和重新排列字段)。

4.10.18.7.2 处理模型

每个具有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"。

这些值是通过运行以下算法定义的:

  1. 如果元素没有autocomplete属性,则跳到标有默认的步骤。

  2. tokens为将属性的值按ASCII空格分割的结果分割字符串上的空格

  3. 如果tokens为空,则跳到标有默认的步骤。

  4. indextokens中最后一个标记的索引。

  5. fieldtokens中的第index个标记。

  6. categorymaximum tokens对设置为根据field确定字段类别的结果确定字段类别

  7. 如果category为null,则跳到标有默认的步骤。

  8. 如果tokens中的标记数大于maximum tokens,则跳到标有默认的步骤。

  9. 如果category为Off或Automatic,但元素的autocomplete属性穿着自动填充锚披风,则跳到标有默认的步骤。

  10. 如果category为Off,则令元素的自动填充字段名为字符串"off",令其自动填充提示集为空,并令其IDL暴露的自动填充值为字符串"off"。然后,返回。

  11. 如果category为Automatic,则令元素的自动填充字段名为字符串"on",令其自动填充提示集为空,并令其IDL暴露的自动填充值为字符串"on"。然后,返回。

  12. scope tokens为空列表。

  13. hint tokens为空集。

  14. credential type为null。

  15. IDL value的值与field相同。

  16. 如果category为Credential,并且tokens中的第index个标记是"webauthn"的ASCII大小写不敏感匹配ASCII大小写不敏感,则运行以下子步骤:

    1. credential type设置为"webauthn"。

    2. 如果tokens中的第index个标记是第一个条目,则跳到标有完成的步骤。

    3. index减一。

    4. 根据tokens中的第index个标记,将categorymaximum tokens对设置为确定字段类别的结果确定字段类别

    5. 如果category不是Normal且category不是Contact,则跳到标有默认的步骤。

    6. 如果index大于maximum tokens减一(即,如果剩余标记的数量大于maximum tokens),则跳到标有默认的步骤。

    7. IDL value设置为tokens中的第index个标记、一个U+0020空格字符和之前IDL value值的串联。

  17. 如果tokens中的第index个标记是第一个条目,则跳到标有完成的步骤。

  18. index减一。

  19. 如果category为Contact,并且tokens中的第index个标记是以下列表中的字符串之一的ASCII大小写不敏感匹配ASCII大小写不敏感,则运行以下子步骤:

    子步骤如下:

    1. contact为上面列表中的匹配字符串。

    2. contact插入到scope tokens的开头。

    3. contact添加到hint tokens中。

    4. IDL valuecontact、一个U+0020空格字符和之前IDL value值的串联。

    5. 如果tokens中的第index个条目是第一个条目,则跳到标有完成的步骤。

    6. index减一。

  20. 如果tokens中的第index个标记是以下列表中的字符串之一的ASCII大小写不敏感匹配ASCII大小写不敏感,则运行以下子步骤:

    子步骤如下:

    1. mode为上面列表中的匹配字符串。

    2. mode插入到scope tokens的开头。

    3. mode添加到hint tokens中。

    4. IDL valuemode、一个U+0020空格字符和之前IDL value值的串联。

    5. 如果tokens中的第index个条目是第一个条目,则跳到标有完成的步骤。

    6. index减一。

  21. 如果tokens中的第index个条目不是第一个条目,则跳到标有默认的步骤。

  22. 如果tokens中的第index个标记的前八个字符不是section-字符串的ASCII大小写不敏感匹配ASCII大小写不敏感,则跳到标有默认的步骤。

  23. sectiontokens中的第index个标记,转换为ASCII小写

  24. section插入到scope tokens的开头。

  25. IDL valuesection、一个U+0020空格字符和之前IDL value值的串联。

  26. 完成:令元素的自动填充提示集hint tokens

  27. 令元素的非自动填充凭证类型credential type

  28. 令元素的自动填充范围scope tokens

  29. 令元素的自动填充字段名field

  30. 令元素的IDL暴露的自动填充值IDL value

  31. 返回。

  32. 默认:令元素的IDL暴露的自动填充值为空字符串,其自动填充提示集自动填充范围为空。

  33. 如果元素的autocomplete属性穿着自动填充锚披风,则令元素的自动填充字段名为空字符串并返回。

  34. form为元素的表单拥有者,如果有的话,否则为null。

  35. 如果form不为null且formautocomplete属性处于off状态,则令元素的自动填充字段名为"off"。

    否则,令元素的自动 填充字段名为"on"。

确定字段的类别,给定field

  1. 如果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
  2. 否则,将maximum tokenscategory设为该行第二列和第三列中的值。

  3. 返回categorymaximum 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的条目复制到列表顶部,使界面看起来如下:

同一个下拉控件,字母顺序的国家列表,但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日,则可能会尝试以稍微不同的值预填以下控件,这些值都源自该信息:

<input name=b type=month autocomplete="bday">
2012-07 月份状态只接受月份/年份组合,丢弃了日期。(注意此示例不合规,因为bday自动填充字段名称不允许使用月份状态。)
<select name=c autocomplete="bday">
 <option>Jan
 <option>Feb
 ...
 <option>Jul
 <option>Aug
 ...
</select>
July 用户代理从列表选项中选择月份,或通过注意到有十二个选项并选择第七个,或通过识别某个字符串(如"Jul"三个字符后跟换行符和空格)与月份名称(July)在用户代理支持的某种语言中的名称接近,或通过其他类似机制。
<input name=a type=number min=1 max=12 autocomplete="bday-month">
7 用户代理将"July"转换为范围1..12内的月份数字,如字段。
<input name=a type=number min=0 max=11 autocomplete="bday-month">
6 用户代理将"July"转换为范围0..11内的月份数字,如字段。
<input name=a type=number min=1 max=11 autocomplete="bday-month">
用户代理不填充该字段,因为无法很好地猜测表单期望的内容。

用户代理可以允许用户覆盖元素的自动填充字段名称,例如将其从"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暴露的自动填充值,并在设置时,必须反映同名内容属性。

4.10.19 文本控件选择的 API

inputtextarea 元素定义了处理其选择的若干属性和方法。它们的共享算法在此定义。

element.select()

选择文本控件中的所有内容。

element.selectionStart [ = value ]

返回选择的起始偏移。

可以设置,以改变选择的起始位置。

element.selectionEnd [ = value ]

返回选择的结束偏移。

可以设置,以改变选择的结束位置。

element.selectionDirection [ = value ]

返回选择的当前方向。

可以设置,以改变选择的方向。

可能的值是 "forward", "backward" 和 "none"。

element.setSelectionRange(start, end [, direction])

HTMLInputElement/setSelectionRange

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

更改选择以覆盖给定方向的子字符串。如果省略方向,将重置为平台默认值(none 或 forward)。

element.setRangeText(replacement [, start, end [, selectionMode ] ])

HTMLInputElement/setRangeText

支持所有当前引擎。

Firefox27+Safari7+Chrome24+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

用新文本替换一段文本。如果没有提供 startend 参数,则假定范围为选择内容。

最后一个参数确定替换文本后如何设置选择。可能的值是:

"select"
选择新插入的文本。
"start"
将选择移动到插入文本之前。
"end"
将选择移动到插入文本之后。
"preserve"
尝试保留选择。这是默认值。

所有 input 元素和 所有 textarea 元素,无论是否 被渲染,始终具有 选择文本输入光标位置,以控件的 相关值 的偏移量来衡量。初始状态必须由控件开头的 文本输入光标 组成。

对于 input 元素,这些 API 必须对元素的 进行操作。对于 textarea 元素,这些 API 必须对元素的 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 适用的元素的 相关值 发生变化时,运行以下步骤:

  1. 如果元素有 选择

    1. 如果选择的开始现在超过了 相关值 的结尾,将其设置为 相关值 的结尾。

    2. 如果选择的结束现在超过了 相关值 的结尾,将其设置为 相关值 的结尾。

    3. 如果用户代理不支持空选择,并且选择的开始和结束都指向 相关值 的结尾,那么改为将元素的 文本输入光标位置 设置为 相关值 的结尾,移除任何选择。

  2. 否则,元素必须有 文本输入光标位置。如果它现在超过了 相关值 的结尾,将其设置为 相关值 的结尾。

在某些情况下,当 相关值 发生变化时,规范的其他部分也会修改 文本输入光标位置,不仅仅是上述的夹紧步骤。例如,参见 value 设置器 textarea

尽可能使用 设置选择范围 算法来实现 inputtextarea 元素中更改 文本选择 的用户界面功能,以便所有相同的事件都能触发。

inputtextarea 元素的 选择 具有 选择方向,即 "forward", "backward" 或 "none"。选择方向的确切含义取决于平台。此方向在用户操作选择时设置。初始 选择方向 必须是 "none"(如果平台支持该方向),否则为 "forward"。

要将元素的选择方向设置为给定方向,请更新元素的 选择方向 为给定方向;如果方向是 "none" 且平台不支持该方向,则将元素的 选择方向 更新为 "forward"。

在 Windows 上,方向表示插入点相对于选择的位置:"forward" 选择在选择末尾有插入点,而 "backward" 选择在选择开始处有插入点。Windows 没有 "none" 方向。

在 Mac 上,方向表示在用户使用 Shift 修饰键调整选择大小时,选择的哪一端受到影响:“forward”方向表示选择的末端被修改,而“backward”方向表示选择的起始端被修改。"none" 方向是 Mac 的默认方向,它表示尚未选择特定方向。用户在首次调整选择时,基于使用的方向键隐式地设置方向。

HTMLInputElement/select

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLInputElement/select

select() 方法调用时,必须执行以下步骤:

  1. 如果此元素是 input 元素,并且 select() 不适用 于此元素,或对应的控件没有可选择的文本,则返回。

    例如,在某些用户代理中,<input type=color> 作为颜色选择器而不是接受十六进制颜色代码的文本控件呈现时,将没有可选择的文本,因此忽略对方法的调用。

  2. 设置选择范围 为 0 和无限大。

selectionStart 属性的 getter 必须执行以下步骤:

  1. 如果此元素是 input 元素,并且 selectionStart 不适用 于此元素,则返回 null。

  2. 如果没有 选择,则返回 代码单元 偏移量到 相关值 中紧随其后的字符。

  3. 返回 代码单元 偏移量到 相关值 中紧随其后的字符。

selectionStart 属性的 setter 必须执行以下步骤:

  1. 如果此元素是 input 元素,并且 selectionStart 不适用 于此元素,则抛出 "InvalidStateError" DOMException

  2. end 为此元素的 selectionEnd 属性的值。

  3. 如果 end 小于给定值,则将 end 设置为给定值。

  4. 设置选择范围 为给定值、end 和此元素的 selectionDirection 属性的值。

selectionEnd 属性的 getter 必须执行以下步骤:

  1. 如果此元素是 input 元素,并且 selectionEnd 不适用 于此元素,则返回 null。

  2. 如果没有 选择,则返回 代码单元 偏移量到 相关值 中紧随其后的字符。

  3. 返回 代码单元 偏移量到 相关值 中紧随其后的字符。

selectionEnd 属性的 setter 必须执行以下步骤:

  1. 如果此元素是 input 元素,并且 selectionEnd 不适用 于此元素,则抛出 "InvalidStateError" DOMException

  2. 设置选择范围 为此元素的 selectionStart 属性的值、给定值和此元素的 selectionDirection 属性的值。

selectionDirection 属性的 getter 必须执行以下步骤:

  1. 如果此元素是 input 元素,并且 selectionDirection 不适用 于此元素,则返回 null。

  2. 返回此元素的 选择方向

selectionDirection 属性的 setter 必须执行以下步骤:

  1. 如果此元素是 input 元素,并且 selectionDirection 不适用 于此元素,则抛出 "InvalidStateError" DOMException

  2. 设置选择范围 为此元素的 selectionStart 属性的值、此元素的 selectionEnd 属性的值和给定值。

setSelectionRange(start, end, direction) 方法调用时,必须执行以下步骤:

  1. 如果此元素是 input 元素,并且 setSelectionRange() 不适用 于此元素,则抛出 "InvalidStateError" DOMException

  2. 设置选择范围startenddirection

要用整数或 null start、整数或 null 或特殊值 infinity end 和可选字符串 direction 设置选择范围,运行以下步骤:

  1. 如果 start 为 null,则将 start 设为 0。

  2. 如果 end 为 null,则将 end 设为 0。

  3. 将文本控件的 选择 设置为 代码单元 序列,开始于 start 位置的代码单元,并结束于 (end-1) 位置的代码单元。大于文本控件 长度 的参数(包括特殊值 infinity)必须视为指向文本控件的末尾。如果 end 小于或等于 start,则选择的开始和结束都必须放置在 end 偏移字符之前。在没有空选择概念的用户代理中,这必须将光标设置在 end 偏移字符之前。

  4. 如果 direction相同 于 "backward" 或 "forward",或如果没有给出 direction 参数,则将 direction 设为 "none"。

  5. 设置文本控件的选择方向direction

  6. 如果前面的步骤导致修改了文本控件的 选择(无论是范围还是 方向),则 队列元素任务 给定元素,触发名为 select 的事件,并将 bubbles 属性初始化为 true。

setRangeText(replacement, start, end, selectMode) 方法调用时,必须执行以下步骤:

  1. 如果此元素是 input 元素,并且 setRangeText() 不适用 于此元素,则抛出 "InvalidStateError" DOMException

  2. 将此元素的 脏值标志 设置为 true。

  3. 如果方法只有一个参数,则让 startend 具有 selectionStart 属性和 selectionEnd 属性的值。

    否则,让 startend 具有第二个和第三个参数的值。

  4. 如果 start 大于 end,则抛出 "IndexSizeError" DOMException

  5. 如果 start 大于文本控件 长度相关值,则将其设置为文本控件 长度相关值

  6. 如果 end 大于文本控件 长度相关值,则将其设置为文本控件 长度相关值

  7. selection startselectionStart 属性的当前值。

  8. selection endselectionEnd 属性的当前值。

  9. 如果 start 小于 end,则删除元素 代码单元 的序列,从 start 位置开始,到 (end-1) 位置结束。

  10. 将第一个参数的值插入文本控件的 相关值,紧靠 start 位置的 代码单元 之前。

  11. new length 为第一个参数值的 长度

  12. new endstartnew length 的和。

  13. 运行以下步骤列表中的适当子步骤:

    如果第四个参数的值是 "select"

    selection startstart

    selection endnew end

    如果第四个参数的值是 "start"

    selection startselection endstart

    如果第四个参数的值是 "end"

    selection startselection endnew end

    如果第四个参数的值是 "preserve"
    如果方法只有一个参数
    1. old lengthend 减去 start

    2. deltanew length 减去 old length

    3. 如果 selection start 大于 end,则将其增加 delta。 (如果 delta 为负,即新文本比旧文本短,则这将 减少 selection start 的值。)

      否则:如果 selection start 大于 start,则将其设置为 start。 (如果选择的开始在替换的文本中间,则将选择的开始对齐到新文本的开始。)

    4. 如果 selection end 大于 end,则以同样的方式增加 delta

      否则:如果 selection end 大于 start,则将其设置为 new end。 (如果选择的结束在替换的文本中间,则将选择的结束对齐到新文本的结束。)

  14. 设置选择范围selection startselection end

setRangeText() 方法使用以下枚举:

enum SelectionMode {
  "select",
  "start",
  "end",
  "preserve" // default
};

要获取当前选定的文本,只需以下 JavaScript 代码:

var selectionText = control.value.substring(control.selectionStart, control.selectionEnd);

...其中 controlinputtextarea 元素。

要在文本控件的开头添加一些文本,同时保持文本选择,必须保留这三个属性:

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);

...其中 controlinputtextarea 元素。

4.10.20 约束

4.10.20.1 定义

可提交元素约束验证候选者,除非某个条件将其 排除在约束验证之外。(例如,如果某个元素具有 datalist 元素祖先,则该元素 被排除在约束验证之外。)

元素可以定义 自定义有效性错误消息。最初,元素的 自定义有效性错误消息 必须设置为空字符串。当其值不是空字符串时,元素 存在自定义错误。可以使用 setCustomValidity() 方法设置,除了 表单关联自定义元素表单关联自定义元素 可以通过其 ElementInternals 对象的 setValidity() 方法设置 自定义有效性错误消息。当向用户提示控件问题时,用户代理应使用 自定义有效性错误消息

元素可以有各种约束方式。以下是表单控件可能处于的 有效性状态 列表,使控件在约束验证中无效。(以下定义是非规范性的;本规范的其他部分更精确地定义了每个状态适用或不适用的情况。)

缺失

当控件没有 但具有 required 属性时(input requiredtextarea required);或 select 元素和 单选按钮组 控件的更复杂规则,如其部分中所述。

setValidity() 方法将 valueMissing 标志设置为 true 用于 表单关联自定义元素 时。

类型不匹配

当允许任意用户输入的控件的 语法不正确时(电子邮件URL)。

setValidity() 方法将 typeMismatch 标志设置为 true 用于 表单关联自定义元素 时。

模式不匹配

当控件的 不满足 模式 属性时。

setValidity() 方法将 patternMismatch 标志设置为 true 用于 表单关联自定义元素 时。

过长

当控件的 对于 表单控件 maxlength 属性 来说太长时(input maxlengthtextarea maxlength)。

setValidity() 方法将 tooLong 标志设置为 true 用于 表单关联自定义元素 时。

过短

当控件的 对于 表单控件 minlength 属性 来说太短时(input minlengthtextarea minlength)。

setValidity() 方法将 tooShort 标志设置为 true 用于 表单关联自定义元素 时。

下溢

当控件的 不是空字符串且低于 min 属性时。

setValidity() 方法将 rangeUnderflow 标志设置为 true 用于 表单关联自定义元素 时。

上溢

当控件的 不是空字符串且高于 max 属性时。

setValidity() 方法将 rangeOverflow 标志设置为 true 用于 表单关联自定义元素 时。

步长不匹配

当控件的不符合step属性所给出的规则时。

setValidity()方法为表单关联的自定义元素设置stepMismatch标志为true时。

输入错误

当控件输入不完整且用户代理认为用户不应在当前状态下提交表单时。

setValidity() 方法将 badInput 标志设置为 true 用于 表单关联自定义元素 时。

自定义错误

当控件的 自定义有效性错误消息(由元素的 setCustomValidity() 方法或 ElementInternalssetValidity() 方法设置)不是空字符串时。

即使元素 禁用,元素仍可能存在这些状态;因此,即使在提交期间验证表单时不会向用户显示问题,这些状态也可以在 DOM 中表示。

如果元素不存在上述任何 有效性状态,则元素 满足其约束条件

4.10.20.2 约束验证

当用户代理需要对 静态验证约束 进行 form 元素 form 时, 必须执行以下步骤,这些步骤将返回 肯定 结果(表单中的所有控件都有效)或 否定 结果(存在无效控件),以及一个(可能为空的)无效元素列表,并且这些元素没有脚本声明其责任:

  1. controls成为所有可提交元素的列表,其表单所有者form,按树顺序排列。

  2. invalid controls成为一个初始为空的元素列表。

  3. controls中的每个元素field,按树顺序

    1. 如果field不是约束验证候选者,则转到下一个元素。

    2. 否则,如果field满足其约束条件,则转到下一个元素。

    3. 否则,将field添加到invalid controls

  4. 如果 invalid controls 为空,则返回 肯定 结果。

  5. unhandled invalid controls成为一个初始为空的元素列表。

  6. invalid controls中的每个元素field,按树顺序

    1. notCanceled成为在field触发一个事件(名为invalid),cancelable属性初始化为true。

    2. 如果notCanceled为true,则将field添加到unhandled invalid controls

  7. 返回 否定 结果,并附带 unhandled invalid controls 列表中的元素。

如果用户代理要交互验证表单元素form的约束,则用户代理必须运行以下步骤:

  1. 静态验证form的约束,如果结果为负面,则让unhandled invalid controls成为返回的元素列表。

  2. 如果结果为正面,则返回该结果。

  3. 向用户报告unhandled invalid controls中至少一个元素的约束问题。

  4. 返回负面结果。

4.10.20.3 约束验证 API
element.willValidate

HTMLObjectElement/willValidate

在所有当前引擎中都受支持。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

如果元素在表单提交时会被验证,则返回 true;否则返回 false。

element.setCustomValidity(message)

HTMLObjectElement/setCustomValidity

在所有当前引擎中都受支持。

Firefox4+Safari5.1+Chrome10+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

HTMLSelectElement/setCustomValidity

在所有当前引擎中都受支持。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

设置一个自定义错误,使元素无法通过验证。给定的消息是报告问题时显示给用户的消息。

如果参数是空字符串,则清除自定义错误。

element.validity.valueMissing

ValidityState/valueMissing

在所有当前引擎中都受支持。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

如果元素没有值但这是一个必需字段,则返回 true;否则返回 false。

element.validity.typeMismatch

如果元素的值不符合正确的语法,则返回 true;否则返回 false。

element.validity.patternMismatch

如果元素的值不匹配提供的模式,则返回 true;否则返回 false。

element.validity.tooLong

ValidityState/tooLong

在所有当前引擎中都受支持。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android64+Safari iOS5+Chrome Android?WebView Android4+Samsung Internet?Opera Android12.1+

如果元素的值超过了提供的最大长度,则返回 true;否则返回 false。

element.validity.tooShort

ValidityState/tooShort

在所有当前引擎中都受支持。

Firefox51+Safari10+Chrome40+
Opera?Edge79+
Edge (旧版)17+Internet Explorer没有
Firefox Android64+Safari iOS?Chrome Android?WebView Android67+Samsung Internet?Opera Android?

如果元素的值(如果不是空字符串)短于提供的最小长度,则返回 true;否则返回 false。

element.validity.rangeUnderflow

如果元素的值低于提供的最小值,则返回 true;否则返回 false。

element.validity.rangeOverflow

如果元素的值高于提供的最大值,则返回 true;否则返回 false。

element.validity.stepMismatch

如果元素的值不符合 step 属性规定的规则,则返回 true;否则返回 false。

element.validity.badInput

ValidityState/badInput

所有当前引擎均支持。

Firefox29+Safari7+Chrome25+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android64+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

如果用户在用户界面中提供的输入,用户代理无法转换为值,则返回 true;否则返回 false。

element.validity.customError

如果元素有自定义错误,则返回 true;否则返回 false。

element.validity.valid

如果元素的值没有有效性问题,则返回 true;否则返回 false。

valid = element.checkValidity()

HTMLInputElement/checkValidity

所有当前引擎均支持。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

HTMLObjectElement/checkValidity

所有当前引擎均支持。

Firefox4+Safari5.1+Chrome10+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

HTMLSelectElement/checkValidity

所有当前引擎均支持。

Firefox4+Safari5+Chrome4+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

如果元素的值没有有效性问题,则返回 true;否则返回 false。在后一种情况下,会在元素上触发一个 invalid 事件。

valid = element.reportValidity()

HTMLFormElement/reportValidity

所有当前引擎均支持。

Firefox49+Safari10.1+Chrome40+
Opera?Edge79+
Edge (旧版)17+Internet Explorer没有
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLInputElement/reportValidity

所有当前引擎均支持。

Firefox49+Safari10.1+Chrome40+
Opera?Edge79+
Edge (旧版)17+Internet Explorer没有
Firefox Android64+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

如果元素的值没有有效性问题,则返回 true;否则返回 false,触发一个 invalid 事件,并且(如果事件没有被取消)将问题报告给用户。

element.validationMessage

HTMLObjectElement/validationMessage

所有当前引擎均支持。

Firefox4+Safari5.1+Chrome10+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回如果检查元素的有效性时显示给用户的错误消息。

willValidate 属性的 getter 必须在以下情况下返回 true:如果该元素是一个 约束验证的候选,否则返回 false(即,如果有任何条件 阻止它进行约束验证)。

ElementInternals/willValidate

所有当前引擎均支持。

Firefox98+Safari16.4+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

willValidate 属性在 ElementInternals 接口上获取时,如果 目标元素 不是一个 与表单关联的自定义元素,则必须抛出一个 "NotSupportedError" DOMException。否则,如果 目标元素 是一个 约束验证的候选,则必须返回 true,否则返回 false。

HTMLInputElement/setCustomValidity

所有当前引擎均支持。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

setCustomValidity(error) 方法的步骤是:

  1. error 设置为对 规范化换行符 后的 error 结果。

  2. 自定义有效性错误消息 设置为 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>

HTMLObjectElement/validity

所有当前引擎均支持。

Firefox4+Safari5.1+Chrome10+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

validity 属性的 getter 必须返回一个 ValidityState 对象,表示此元素的 有效性状态。该对象是 实时 的。

ElementInternals/validity

所有当前引擎均支持。

Firefox98+Safari16.4+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

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

ValidityState/typeMismatch

所有当前引擎均支持。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

控制项 存在类型不匹配

patternMismatch

ValidityState/patternMismatch

所有当前引擎均支持。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

控制项 存在模式不匹配

tooLong

控制项 存在过长的问题

tooShort

控制项 存在过短的问题

rangeUnderflow

ValidityState/rangeUnderflow

所有当前引擎均支持。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

控制项 存在下溢的问题

rangeOverflow

ValidityState/rangeOverflow

所有当前引擎均支持。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

控制项 存在上溢的问题

stepMismatch

ValidityState/stepMismatch

所有当前引擎均支持。

Firefox4+Safari5+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

控制项 存在步长不匹配的问题

badInput

控制项 存在错误输入的问题

customError

控制项 存在自定义错误

valid

其他条件均不成立。

检查有效性步骤 对于元素 element 的步骤如下:

  1. 如果 element约束验证候选 且不满足 其约束,则:

    1. 触发一个事件 名为 invalidelement 上,带有 cancelable 属性初始化为 true(尽管取消没有效果)。

    2. 返回 false。

  2. 返回 true。

checkValidity() 方法在调用时,必须在该元素上运行 检查有效性步骤

ElementInternals/checkValidity

所有当前引擎均支持。

Firefox98+Safari16.4+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

checkValidity() 方法必须运行以下步骤:

  1. element 成为此 ElementInternals目标元素

  2. 如果 element 不是 与表单关联的自定义元素,则抛出 "NotSupportedError" DOMException

  3. element 上运行 检查有效性步骤

报告有效性步骤 对于元素 element 的步骤如下:

  1. 如果 element约束验证候选 且不满足 其约束,则:

    1. report 成为 触发一个事件 的结果,事件名称为 invalidelement 上,带有 cancelable 属性初始化为 true。

    2. 如果 report 为 true,则将此元素的约束问题报告给用户。在将约束问题报告给用户时,用户代理可以为 element 运行聚焦步骤,并且可以更改文档的滚动位置,或执行其他操作以引起用户对 element 的注意。如果 element 同时存在多个问题,用户代理可以报告多个约束违规。

    3. 返回 false。

  2. 返回 true。

reportValidity() 方法在调用时,必须在该元素上运行 报告有效性步骤

ElementInternals/reportValidity

所有当前引擎均支持。

Firefox98+Safari16.4+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

reportValidity() 方法必须运行以下步骤:

  1. element 成为此 ElementInternals目标元素

  2. 如果 element 不是 与表单关联的自定义元素,则抛出 "NotSupportedError" DOMException

  3. element 上运行 报告有效性步骤

validationMessage 属性的 getter 必须运行以下步骤:

  1. 如果该元素不是 约束验证候选 或该元素 满足其约束,则返回空字符串。

  2. 返回一个合适的本地化消息,该消息会在此是唯一具有有效性约束问题的表单控件时显示给用户。如果在这种情况下用户代理实际上不会显示文本消息(例如,它会显示图形提示),则返回一个合适的本地化消息,表达控件未满足的有效性约束。如果该元素是 约束验证候选 并且 存在自定义错误,则返回值中应包含 自定义有效性错误消息

4.10.20.4 安全性

服务器不应依赖客户端验证。恶意用户可以有意绕过客户端验证,使用旧版用户代理或不实现这些功能的自动化工具的用户也可能无意中绕过客户端验证。约束验证功能仅旨在改善用户体验,而不是提供任何形式的安全机制。

4.10.21 表单提交

4.10.21.1 介绍

本节非规范性。

当表单提交时,表单中的数据会转换为 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--
4.10.21.2 隐式提交

form 元素的 默认按钮 是在 提交按钮 中第一个按 树顺序 排列,其 表单所有者 是该 form 元素。

如果用户代理支持让用户隐式提交表单(例如,在某些平台上,当文本控件 聚焦 时按下 "Enter" 键隐式提交表单),则对于具有 默认按钮 且该按钮具有 激活行为 且未 禁用 的表单,必须导致用户代理在该 默认按钮触发一个 click 事件

网页上有些页面只有在存在隐式提交表单的方法时才可用,因此强烈建议用户代理支持这一功能。

如果表单没有 提交按钮,则隐式提交机制必须执行以下步骤:

  1. 如果表单有多个 阻止隐式提交的字段,则返回。

  2. form 元素本身提交 form 元素,userInvolvement 设置为 "activation"。

为了前段的目的,如果一个元素是一个 阻止隐式提交的字段,那么该元素是一个 form 元素的 input 元素,并且它的 表单拥有者 是该 form 元素,并且其 type 属性处于以下状态之一: 文本, 搜索, 电话, URL, 电子邮件, 密码, 日期, 月份, , 时间, 本地日期和时间, 数字

4.10.21.3 表单提交算法

每个 form 元素有一个 构建条目列表 布尔值,初始为 false。

每个 form 元素有一个 触发提交事件 布尔值,初始为 false。

要从元素 submitter(通常是按钮)提交 form 元素 form,给定一个可选的布尔值 submitted from submit() method(默认为 false)和一个可选的 用户导航参与度 userInvolvement(默认为 "none"):

  1. 如果 form 不能导航,则返回。

  2. 如果 form构建条目列表 为 true,则返回。

  3. form document 成为 form节点文档

  4. 如果 form document活动沙箱标志集 设置了其 沙箱表单浏览上下文标志,则返回。

  5. 如果 submitted from submit() 方法 为 false,则:

    1. 如果 form触发提交事件 为 true,则返回。

    2. form触发提交事件 设置为 true。

    3. 对于 form 中的每个元素 field,如果该元素是 可提交元素,其 表单所有者form,则将 field用户有效性 设置为 true。

    4. 如果 submitter 元素的 无效验证状态 为 false,则 交互式验证约束 form 并检查结果。如果结果是否定的(即约束验证得出有无效字段并且可能通知了用户),则:

      1. form触发提交事件 设置为 false。

      2. 返回。

    5. 如果 submitterform,则将 submitterButton 设为 null。否则,将 submitterButton 设为 submitter

    6. shouldContinue 成为 触发事件 结果,事件名为 submitform 上,使用 SubmitEventsubmitter 属性初始化为 submitterButtonbubbles 属性初始化为 true,cancelable 属性初始化为 true。

    7. form触发提交事件 设置为 false。

    8. 如果 shouldContinue 为 false,则返回。

    9. 如果 form 不能导航,则返回。

      不能导航 再次运行,因为触发 提交 事件可能会改变结果。

  6. encoding 成为 为表单选择编码 的结果。

  7. entry list 成为 构建条目列表 的结果,使用 formsubmitterencoding

  8. 断言entry list 不为 null。

  9. 如果 form 不能导航,则返回。

    不能导航 再次运行,因为在 构建条目列表 中触发 formdata 事件可能会改变结果。

  10. method 成为 submitter 元素的 方法

  11. 如果 method对话框,则:

    1. 如果 form 没有祖先 对话框 元素,则返回。

    2. subject 成为 form 最近的祖先 对话框 元素。

    3. result 为 null。

    4. 如果 submitter输入 元素,其 类型 属性处于 图像按钮 状态,则:

      1. 让 (x, y) 成为 选择的坐标

      2. result 设置为 x、"," 和 y 的连接。

    5. 否则,如果 submitter,则将 result 设置为该

    6. 关闭对话框 subjectresult

    7. 返回。

  12. action 成为 submitter 元素的 动作

  13. 如果 action 是空字符串,则让 action 成为 URLform document

  14. parsed action 成为 编码解析 URL 的结果,给定 action,相对于 submitter节点文档

  15. 如果 parsed action 失败,则返回。

  16. scheme 成为 方案parsed action

  17. enctype 成为 submitter 元素的 enctype

  18. formTarget 为 null。

  19. 如果 submitter 元素是 提交按钮 且其具有 formtarget 属性,则将 formTarget 设置为 formtarget 属性值。

  20. target 成为 获取元素的目标 的结果,给定 submitter表单所有者formTarget

  21. noopener 成为 获取元素的 noopener 的结果,给定 formtarget

  22. target Navigable 成为应用 选择导航的规则 的第一个返回值,给定 targetform节点导航noopener

  23. 如果 targetNavigable 为 null,则返回。

  24. historyHandling 为 "auto"。

  25. 如果 form document 等于 targetNavigable活动文档,且 form document 还没有 完全加载,则将 historyHandling 设置为 "replace"。

  26. 根据 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),它必须运行以下步骤:

    1. referrerPolicy 为空字符串。

    2. 如果 form 元素的 链接类型 包含 noreferrer 关键字,则将 referrerPolicy 设置为 "no-referrer"。

    3. 如果 form 有非 null 的 计划的导航,则将其从 任务队列 中移除。

    4. DOM 操作任务源 上排队一个元素任务,给定 form 元素和以下步骤:

      1. form计划的导航 设置为 null。

      2. 导航 targetNavigableurl,使用 form 元素的 节点文档历史处理 设置为 historyHandling用户参与度 设置为 userInvolvement引用政策 设置为 referrerPolicy文档资源 设置为 postResource,以及 表单数据条目列表 设置为 entry list

    5. form计划的导航 设置为刚排队的 任务

    行为如下:

    变更动作 URL

    pairs 成为 转换为名称值对列表 的结果,使用 entry list

    query 成为运行 application/x-www-form-urlencoded 序列化程序 的结果,使用 pairsencoding

    parsed action查询 组件设置为 query

    计划导航parsed action

    提交为实体正文

    断言methodPOST

    根据 enctype 切换:

    application/x-www-form-urlencoded

    pairs 成为 转换为名称值对列表 的结果,使用 entry list

    body 成为运行 application/x-www-form-urlencoded 序列化程序 的结果,使用 pairsencoding

    body 设置为 编码 body 的结果。

    mimeType 为 `application/x-www-form-urlencoded`。

    multipart/form-data

    body 成为运行 multipart/form-data 编码算法 的结果,使用 entry listencoding

    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

    获取动作 URL

    计划导航parsed action

    entry list 被丢弃。

    通过邮件发送头部

    pairs 成为 转换为名称值对列表 的结果,使用 entry list

    headers 成为运行 application/x-www-form-urlencoded 序列化程序 的结果,使用 pairsencoding

    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 序列化程序 的结果,使用 pairsencoding

    如果 parsed action查询 为空,则将其设置为空字符串。

    如果 parsed action查询 不是空字符串,则在其后追加一个 U+0026 AMPERSAND 字符(&)。

    parsed action查询 中追加 "body="。

    parsed action查询 中追加 body

    计划导航parsed action

4.10.21.4 构建条目列表

一个 条目列表 是一个 列表,通常代表表单的内容。一个 条目 是一个包含一个 名称(一个 标量值字符串)和一个 (可以是一个 标量值字符串 或一个 文件 对象)的元组。

为了 创建一个条目,给定一个字符串 name,一个字符串或 Blob 对象 value,以及一个可选的 标量值字符串 filename:

  1. name 转换为 标量值字符串

  2. 如果 value 是一个字符串,则将 value 转换为 标量值字符串

  3. 否则:

    1. 如果 value 不是一个 文件 对象,则将 value 设置为一个新的 文件 对象,代表相同的字节,其 name 属性值为 "blob"。

    2. 如果提供了 filename,则将 value 设置为一个新的 文件 对象,代表相同的字节,其 name 属性为 filename

    这些操作将在提供 filename 或传递的 Blob 不是 文件 对象的情况下创建一个新的 文件 对象。在这些情况下,传递的 Blob 对象的身份不会保留。

  4. 返回一个 条目,其 名称name,其 value

为了 构建条目列表,给定一个 form,一个可选的 submitter(默认为 null),和一个可选的 encoding(默认为 UTF-8):

  1. 如果 form构建条目列表 为 true,则返回 null。

  2. form构建条目列表 设置为 true。

  3. controls 成为所有 可提交的元素 的列表,其 表单所有者form,按 树顺序 排列。

  4. entry list 成为一个新的空 条目列表

  5. 对于 controls 中的每个元素 field,按 树顺序

    1. 如果以下任何一项为真:

      那么 继续

    2. 如果 field 元素是一个 input 元素,其 type 属性在 图像按钮 状态中,那么:

      1. 如果 field 元素不是 submitter,那么 继续

      2. 如果 field 元素有一个 name 属性,并且其值不是空字符串,则将 name 设为该值后加上 U+002E (.)。否则,将 name 设为空字符串。

      3. namex 设为 name 和 U+0078 (x) 的连接。

      4. namey 设为 name 和 U+0079 (y) 的连接。

      5. 让 (x, y) 成为 选择的坐标

      6. 创建一个条目,名称为 namex,值为 x,并将其 追加entry list

      7. 创建一个条目,名称为 namey,值为 y,并将其 追加entry list

      8. 继续

    3. 如果 field 是一个 表单关联自定义元素,则对 fieldentry list 执行 条目构建算法,然后 继续

    4. 如果 field 元素没有 name 属性,或者其 name 属性的值为空字符串,则 继续

    5. name 设为 field 元素的 name 属性的值。

    6. 如果 field 元素是一个 select 元素,则对 field 的每个 option 元素,在 select 元素的 选项列表 中,其 选中状态 为 true 且不是 禁用的创建一个条目,名称为 name,值为该 option 元素的 ,并将其 追加entry list

    7. 否则,如果 field 元素是一个 input 元素,其 type 属性在 复选框 状态或 单选按钮 状态中,那么:

      1. 如果 field 元素有一个 value 属性,则将 value 设为该属性的值;否则,将 value 设为字符串 "on"。

      2. 创建一个条目,名称为 name,值为 value,并将其 追加entry list

    8. 否则,如果 field 元素是一个 input 元素,其 type 属性在 文件上传 状态中,那么:

      1. 如果没有 选定的文件,则 创建一个条目,名称为 name,值为一个新的 文件 对象,其名称为空,类型为 application/octet-stream,内容为空,并将其 追加entry list

      2. 否则,对于 选定的每个文件创建一个条目,名称为 name,值为一个代表该文件的 文件 对象,并将其 追加entry list

    9. 否则,如果 field 元素是一个 input 元素,其 type 属性在 隐藏 状态中,并且 nameASCII 不区分大小写 匹配 "_charset_":

      1. charset成为encoding名称

      2. 创建一个条目,名称为 name,值为 charset,并将其 追加entry list

    10. 否则,创建一个条目,名称为 name,值为 field 元素的 ,并将其 追加entry list

    11. 如果该元素有 dirname 属性,该属性的值不是空字符串,并且该元素是 自动方向表单关联元素

      1. dirname 设为元素的 dirname 属性的值。

      2. dir 设为字符串 "ltr" 如果 元素的方向性 是 'ltr',否则(即 元素的方向性 是 'rtl'),将 dir 设为字符串 "rtl"。

      3. 创建一个条目,名称为 dirname,值为 dir,并将其 追加entry list

  6. form data 设为一个新的 FormData 对象,关联 entry list

  7. 触发一个名为 formdata 的事件在 form 上,使用 FormDataEvent,其 formData 属性初始化为 form data,其 bubbles 属性初始化为 true。

  8. form构建条目列表 设置为 false。

  9. 返回 条目列表 的克隆。

4.10.21.5 选择表单提交编码

如果用户代理需要为表单选择编码,则必须运行以下步骤:

  1. encoding 设置为文档的字符编码

  2. 如果表单元素有一个accept-charset属性,则将 encoding 设置为运行以下子步骤的返回值:

    1. input 设置为表单元素的accept-charset属性的值。

    2. candidate encoding labels 设置为按 ASCII 空白字符分割 input 的结果。

    3. candidate encodings 设置为空的字符编码列表。

    4. 对于 candidate encoding labels 中的每个 token,按顺序获取编码,如果没有失败,则将编码追加到 candidate encodings

    5. 如果 candidate encodings 为空,返回 UTF-8

    6. 返回 candidate encodings 中的第一个编码。

  3. 返回获取输出编码encoding 的结果。

4.10.21.6 将条目列表转换为名称-值对列表

application/x-www-form-urlencodedtext/plain编码算法需要一个名称-值对列表,其中的值必须是字符串,而不是值可以是文件条目列表。以下算法执行转换。

将条目列表转换为名称-值对列表,请运行以下步骤:

  1. list设置为空的名称-值对列表

  2. 对每个entryentry list

    1. name设置为entry名称,将每个 U+000D (CR) 后未跟随 U+000A (LF) 的情况,以及每个 U+000A (LF) 前未出现 U+000D (CR) 的情况替换为包含 U+000D (CR) 和 U+000A (LF) 的字符串。

    2. 如果entry文件对象,则将value设置为entry名称。否则,将value设置为entry

    3. value中的每个 U+000D (CR) 后未跟随 U+000A (LF) 的情况,以及每个 U+000A (LF) 前未出现 U+000D (CR) 的情况替换为包含 U+000D (CR) 和 U+000A (LF) 的字符串。

    4. 新名称-值对附加到list,其名称为name,值为value

  3. 返回list

4.10.21.7 URL编码的表单数据

关于application/x-www-form-urlencoded的详细信息,请参见URL[URL]

4.10.21.8 多部分表单数据

multipart/form-data编码算法,给定一个entry list entry list和一个encoding encoding,如下:

  1. 对于每个 entryentry list中:

    1. 替换entryname中每个未被U+000A (LF)跟随的U+000D (CR),以及每个未被U+000D (CR)前置的U+000A (LF),替换为一个由U+000D (CR)和U+000A (LF)组成的字符串。

    2. 如果entryvalue不是File对象,那么替换entryvalue中每个未被U+000A (LF)跟随的U+000D (CR),以及每个未被U+000D (CR)前置的U+000A (LF),替换为一个由U+000D (CR)和U+000A (LF)组成的字符串。

  2. 返回使用RFC 7578描述的规则编码entry list得到的字节序列,条件如下:[RFC7578]

有关如何解释multipart/form-data有效负载的详细信息,请参见RFC 7578。[RFC7578]

4.10.21.9 纯文本表单数据

text/plain编码算法,给定一个名称-值对列表pairs,如下:

  1. result为空字符串。

  2. 对于pairs中的每个pair

    1. pair的名称追加到result

    2. 将一个U+003D等号字符(=)追加到result

    3. pair的值追加到result

    4. 将一个U+000D回车(CR)和U+000A换行(LF)字符对追加到result

  3. 返回result

使用text/plain格式的有效负载旨在易于人类阅读。它们无法可靠地被计算机解释,因为格式存在歧义(例如,没有办法区分值中的换行符与值末尾的换行符)。

4.10.21.10 SubmitEvent 接口

SubmitEvent

支持所有当前引擎。

Firefox75+Safari15+Chrome81+
Opera?Edge81+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

SubmitEvent/SubmitEvent

支持所有当前引擎。

Firefox75+Safari15+Chrome81+
Opera?Edge81+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
[Exposed=Window]
interface SubmitEvent : Event {
  constructor(DOMString type, optional SubmitEventInit eventInitDict = {});

  readonly attribute HTMLElement? submitter;
};

dictionary SubmitEventInit : EventInit {
  HTMLElement? submitter = null;
};
event.submitter

返回触发表单提交提交按钮 的元素,或者如果提交不是由按钮触发的,则返回 null。

submitter 属性必须返回它被初始化的值。

4.10.21.11 FormDataEvent 接口

FormDataEvent/FormDataEvent

支持所有当前引擎。

Firefox72+Safari15+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

FormDataEvent

支持所有当前引擎。

Firefox72+Safari15+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
[Exposed=Window]
interface FormDataEvent : Event {
  constructor(DOMString type, FormDataEventInit eventInitDict);

  readonly attribute FormData formData;
};

dictionary FormDataEventInit : EventInit {
  required FormData formData;
};
event.formData

返回一个表示与目标 表单 关联的元素名称和值的 FormData 对象。对 FormData 对象的操作将影响要提交的表单数据。

formData 属性必须返回它被初始化的值。它表示一个与提交 表单构建条目列表 相关联的 FormData 对象。

4.10.22 重置表单

表单 元素 form重置时,执行以下步骤:

  1. reset 成为 触发名为 reset 的事件的结果,在 form 上,bubblescancelable 属性初始化为 true。

  2. 如果 reset 为 true,则调用每个 可重置元素重置算法,其 表单所有者form

每个 可重置元素 都定义其自己的 重置算法。作为这些算法的一部分对表单控件所做的更改不计为用户所做的更改(例如,不会触发 input 事件)。

4.11 交互式元素

4.11.1 details 元素

Element/details

所有当前引擎支持。

Firefox49+Safari6+Chrome12+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android49+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLDetailsElement

所有当前引擎支持。

Firefox49+Safari6+Chrome10+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android?
类别:
流内容
交互内容
可感知内容
此元素可以使用的上下文:
在预期为流内容的地方使用。
内容模型:
一个summary 元素,后跟流内容
在text/html中的标签省略:
两个标签都不能省略。
内容属性:
全局属性
name — 互斥的details 元素组的名称
open — 详情是否可见
可访问性考虑:
针对作者
针对实现者
DOM接口:
[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。

以下属性更改步骤,给定elementlocalNameoldValuevaluenamespace,适用于所有details元素:

  1. 如果namespace不为 null,则返回。

  2. 如果localNamename,则给定element确保详细信息的排他性。

  3. 如果localNameopen,则:

    1. 如果oldValuevalue之一为 null,而另一个不为 null,则为此details元素运行以下步骤,称为details notification task steps

      open属性多次连续切换时,结果任务基本上会合并为只触发一个事件。

      1. 如果oldValue为 null,则给定details元素、"closed"和"open"排队一个详细信息切换事件任务。

      2. 否则,给定details元素、"open"和"closed"排队一个详细信息切换事件任务。

    2. 如果oldValue为 null 且value不为 null,则给定element确保详细信息的排他性。

detailsHTML元素插入步骤,给定insertedNode,是:

  1. 给定insertedNode确保详细信息的排他性。

需要明确的是,这些属性更改和插入步骤也会在通过解析器插入属性或元素时运行。

为了给定一个details元素element、一个字符串oldState和一个字符串newState排队一个详细信息切换事件任务:

  1. 如果element的详细信息切换任务跟踪器不为 null,则:

    1. oldState设置为element的详细信息切换任务跟踪器的旧状态。

    2. 从其任务队列中移除element的详细信息切换任务跟踪器的任务。

    3. element的详细信息切换任务跟踪器设置为 null。

  2. 给定 DOM 操作任务源和element排队一个元素任务以运行以下步骤:

    1. element上触发一个名为toggle的事件,使用ToggleEventoldState属性初始化为oldStatenewState属性初始化为newState

    2. element的详细信息切换任务跟踪器设置为 null。

  3. element的详细信息切换任务跟踪器设置为包含刚排队任务的结构,旧状态设置为oldState

为了给定一个details元素element确保详细信息的排他性:

  1. 断言element 具有 open 属性。

  2. 如果 element 没有 name 属性,或者其 name 属性为空字符串,则返回。

  3. groupMembers 为元素列表,包含 element详情名称组中的所有元素,除了 element 本身,按照树顺序排列。

  4. 对于 groupMembers 中的每个元素 otherElement

    1. 如果 otherElement 设置了 open 属性,则:

      1. 断言otherElementgroupMembers 中唯一设置了 open 属性的元素。

      2. 移除 otherElement 上的 open 属性。

      3. 中断

为了确保详情的排他性,必要时通过关闭给定元素来实现,给定一个 details 元素 element

  1. 如果 element 没有 open 属性,则返回。

  2. 如果 element 没有 name 属性,或者其 name 属性为空字符串,则返回。

  3. groupMembers 为元素列表,包含 element详情名称组中的所有元素,除了 element 本身,按照树顺序排列。

  4. 对于 groupMembers 中的每个元素 otherElement

    1. 如果 otherElement 设置了 open 属性,则:

      1. 移除 element 上的 open 属性。

      2. 中断

HTMLDetailsElement/open

所有当前引擎支持。

Firefox49+Safari6+Chrome10+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android?

nameopenIDL属性必须反映相应的同名内容属性。

祖先详细信息揭示算法是对currentNode运行以下步骤:

  1. currentNode在平坦树中有父节点时:

    1. 如果currentNode插槽到details元素的第二个插槽中:

      1. currentNode设置为currentNode插槽到的details元素。

      2. 如果currentNode上没有设置open属性,则在currentNode上设置open属性为空字符串。

    2. 否则,将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 1s; color: black; }
 details[open] > summary { color: red; }
</style>
<details>
 <summary>Automated Status: Operational</summary>
 <p>Velocity: 12m/s</p>
 <p>Direction: North</p>
</details>

4.11.2 summary 元素

Element/summary

所有当前引擎支持。

Firefox49+Safari6+Chrome12+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android4+Samsung Internet?Opera Android?
分类:
无。
该元素可以使用的上下文:
作为details元素的第一个子元素
内容模型:
短语内容,可以与标题内容混合。
在 text/html 中省略标签:
两个标签都不可省略。
内容属性:
全局属性
可访问性考虑:
对于作者
对于实现者
DOM 接口:
使用HTMLElement

summary元素表示其父details元素的内容的摘要、标题或说明(如果有的话)。

如果以下算法返回 true,则summary元素是其父详细信息的摘要

  1. 如果这个summary元素没有父元素,则返回 false。

  2. parent为这个summary元素的父元素。

  3. 如果parent不是一个details元素,则返回 false。

  4. 如果parent的第一个summary元素子元素不是这个summary元素,则返回 false。

  5. 返回 true。

summary元素的激活行为是执行以下步骤:

  1. 如果这个summary元素不是其父详细信息的摘要,则返回。

  2. parent为这个summary元素的父元素。

  3. 如果parent上存在open属性,则将其移除。否则,将parentopen属性设置为空字符串。

    这将运行详细信息通知任务步骤

4.11.3 命令

4.11.3.1 方面

命令是菜单项、按钮和链接背后的抽象概念。一旦命令被定义,界面的其他部分可以引用相同的命令,从而允许多个访问点共享例如禁用状态等 Facets。

命令被定义为具有以下Facets

标签
用户看到的命令名称。
访问键
用户代理选择的触发命令的键组合。命令可能没有访问键。
隐藏状态
命令是否隐藏(基本上是否应在菜单中显示)。
禁用状态
命令是否相关且可以触发。
动作
触发命令将产生的实际效果。这可以是脚本事件处理程序、一个URL进行导航,或表单提交。

用户代理可以公开符合以下条件的命令

鼓励用户代理特别为具有访问键的命令执行此操作,作为向用户宣传这些键的一种方式。

例如,这些命令可以在用户代理的菜单栏中列出。

4.11.3.2 使用 a 元素定义命令

具有 a 元素和 href 属性的元素定义了一个命令

命令的标签是元素的后代文本内容

命令的访问键是元素的分配的访问键(如果有)。

如果元素具有hidden属性,则命令的隐藏状态为 true(隐藏),否则为 false。

如果元素或其某个祖先是惰性的,则命令的禁用状态为 true,否则为 false。

命令的动作触发一个 click 事件

4.11.3.3 使用 button 元素定义命令

button 元素总是定义一个命令

命令的标签访问键隐藏状态动作 Facets 是按照定义 a 元素的方式确定的(见上一节)。

如果元素或其某个祖先是惰性的,或者元素的禁用状态已设置,则命令的禁用状态为 true,否则为 false。

4.11.3.4 使用 input 元素定义命令

input 元素的 type 属性为 提交按钮重置按钮图像按钮按钮单选按钮复选框 状态时,定义了一个命令

命令的标签按如下方式确定:

即使 value 属性在 图像按钮 状态下不符合标准,该属性仍可以在存在时并且图像按钮的 alt 属性缺失时为标签的确定做出贡献。

命令的访问键是元素的分配的访问键(如果有)。

如果元素具有 hidden 属性,则命令的隐藏状态为 true(隐藏),否则为 false。

如果元素或其某个祖先是惰性的,或者元素的禁用状态已设置,则命令的禁用状态为 true,否则为 false。

命令的动作触发一个 click 事件

4.11.3.5 使用 option 元素定义命令

具有祖先 select 元素且没有 value 属性或具有非空 value 属性的 option 元素定义了一个命令

命令的标签option 元素的 label 属性的值(如果有),否则是 option 元素的后代文本内容,其中ASCII 空白字符被剥离和折叠

命令的访问键是元素的分配的访问键(如果有)。

如果元素具有 hidden 属性,则命令的隐藏状态为 true(隐藏),否则为 false。

如果元素被禁用,或者其最近的祖先 select 元素被禁用,或者它或其某个祖先是惰性的,则命令的禁用状态为 true,否则为 false。

如果 option 的最近的祖先 select 元素具有 multiple 属性,则命令的动作切换 option 元素。否则,命令的动作选择 option 元素。

4.11.3.6 使用 accesskey 属性在 legend 元素上定义命令

如果满足以下所有条件,则 legend 元素定义了一个命令

命令的标签是元素的后代文本内容

命令的访问键是元素的分配的访问键

命令的隐藏状态禁用状态动作特性与 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>
4.11.3.7 使用 accesskey 属性在其他元素上定义命令

具有 分配的访问键 的元素定义了一个命令

如果前面定义了定义命令的元素的章节之一定义了此元素定义了一个命令,那么该章节适用于此元素,而本章节不适用。否则,本章节适用于该元素。

命令的标签取决于元素。如果该元素是带标签的控件,则第一个 label 元素的后代文本内容 是该命令的标签(在 JavaScript 中,这由 element.labels[0].textContent 给出)。否则,该标签是元素的后代文本内容

命令的访问键是元素的分配的访问键

命令的隐藏状态为 true(隐藏)如果元素具有 hidden 属性,否则为 false。

命令的禁用状态为 true 如果元素或其祖先之一为惰性,否则为 false。

命令的动作是运行以下步骤:

  1. 为该元素运行聚焦步骤
  2. 在该元素上触发 click 事件

4.11.4 dialog 元素

Element/dialog

Support in all current engines.

Firefox98+Safari15.4+Chrome37+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLDialogElement

Support in all current engines.

Firefox98+Safari15.4+Chrome37+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
分类:
流内容.
此元素可以使用的上下文:
期望流内容的地方。
内容模型:
流内容.
在 text/html 中省略标签:
标签均不可省略。
内容属性:
全局属性
open — 对话框是否显示
无障碍考虑:
针对作者.
针对实现者.
DOM 接口:
[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 属性通常会隐藏对话框。但是,这样做会带来一些奇怪的附加后果:

出于这些原因,通常最好不要手动删除 open 属性。相反,使用 close() 方法关闭对话框,或使用 hidden 属性隐藏它。

tabindex 属性不得在 dialog 元素上指定。

dialog.show()

HTMLDialogElement/show

Support in all current engines.

Firefox98+Safari15.4+Chrome37+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

显示 dialog 元素。

dialog.showModal()

HTMLDialogElement/showModal

Support in all current engines.

Firefox98+Safari15.4+Chrome37+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

显示 dialog 元素并使其成为最上层的模态对话框。

此方法遵循 autofocus 属性。

dialog.close([ result ])

HTMLDialogElement/close

Support in all current engines.

Firefox98+Safari15.4+Chrome37+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

关闭 dialog 元素。

参数(如果提供)将提供返回值。

dialog.returnValue [ = result ]

HTMLDialogElement/returnValue

Support in all current engines.

Firefox98+Safari15.4+Chrome37+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回 dialog 的返回值。

可以设置,以更新返回值。

show() 方法步骤如下:

  1. 如果 this 具有 open 属性并且 is modal 标志 this 为 false,则返回。

  2. 如果 this 具有 open 属性,则抛出 "InvalidStateError" DOMException

  3. this 添加一个 open 属性,其值为空字符串。

  4. thispreviously focused element 设置为 focused 元素。

  5. hideUntil 成为运行 topmost popover ancestor 给定 this、null 和 false 的结果。

  6. 如果 hideUntil 为 null,则将 hideUntil 设置为 this节点文档

  7. 运行 hide all popovers until 给定 hideUntil、false 和 true。

  8. 运行 dialog focusing steps 给定 this

showModal() 方法步骤如下:

  1. 如果 this 具有 open 属性并且 is modal 标志 this 为 true,则返回。

  2. 如果 this 具有 open 属性,则抛出 "InvalidStateError" DOMException

  3. 如果 this连接,则抛出 "InvalidStateError" DOMException

  4. 如果 this 处于 popover 显示状态,则抛出 "InvalidStateError" DOMException

  5. this 添加一个 open 属性,其值为空字符串。

  6. is modal 标志 this 设置为 true。

  7. this节点文档模态对话框阻止 this

    这将导致 文档的聚焦区域 变为 惰性(除非当前聚焦区域是 影子包含的后代)。在这种情况下,我们将尝试找到一个更好的候选项来聚焦。

  8. 如果 this节点文档顶层 尚未 包含 this,则 添加元素到顶层 给定 this

  9. this关闭观察者 设置为 建立关闭观察者 结果,给定 this相关全局对象,包括:

  10. thispreviously focused element 设置为 focused 元素。

  11. hideUntil 成为运行 topmost popover ancestor 给定 this、null 和 false 的结果。

  12. 如果 hideUntil 为 null,则将 hideUntil 设置为 this节点文档

  13. 运行 hide all popovers until 给定 hideUntil、false 和 true。

  14. 运行 dialog focusing steps 给定 this

对话框聚焦步骤,给定一个 dialog 元素 subject,如下:

  1. control 为 null。

  2. 如果 subject 具有 autofocus 属性,则将 control 设置为 subject

  3. 如果 control 为 null,则将 control 设置为 subjectfocus delegate

  4. 如果 control 为 null,则将 control 设置为 subject

  5. 运行 focusing steps 给定 control

    如果 controlfocusable,则不会执行任何操作。这只会发生在 subject 没有 focus delegate 的情况下,并且用户代理决定 dialog 元素通常不可聚焦。在这种情况下,任何 早期修改文档的聚焦区域 将适用。

  6. topDocument 成为 controlnode navigable顶层可遍历活动文档

  7. 如果 control节点文档来源topDocument相同,则返回。

  8. 清空 topDocument自动聚焦候选项

  9. 设置 topDocument自动聚焦处理标志 为 true。

dialog HTML 元素删除步骤,给定 removedNodeoldParent,如下:

  1. 如果 removedNode关闭观察者 不为 null,则:

    1. 销毁 removedNode关闭观察者

    2. 设置 removedNode关闭观察者 为 null。

  2. 如果 removedNode节点文档顶层 包含 removedNode,则 立即从顶层删除元素 给定 removedNode

  3. 设置 removedNodeis modal 标志为 false。

close(returnValue) 方法步骤如下:

  1. 如果 returnValue 未提供,则将其设置为 null。

  2. 关闭对话框 this,带有 returnValue

当一个 dialog 元素 subject关闭 时,带有 null 或字符串 result,按以下步骤运行:

  1. 如果 subject 没有 open 属性,则返回。

  2. 删除 subjectopen 属性。

  3. 如果 subjectis modal 标志为 true,则 请求从顶层删除元素 给定 subject

  4. wasModal 成为 subjectis modal 标志的值。

  5. subjectis modal 标志设置为 false。

  6. 如果 result 不为 null,则将 returnValue 属性设置为 result

  7. 如果 subjectpreviously focused element 不为 null,则:

    1. element 成为 subjectpreviously focused element

    2. subjectpreviously focused element 设置为 null。

    3. 如果 subject节点文档文档的聚焦区域DOM 锚点影子包含的后代 element,或者 wasModal 为 true,则运行 focusing steps 给定 element;执行此步骤时不应滚动视口。

  8. 在用户交互任务源上队列一个元素任务,给定 subject 元素 触发一个事件 名为 closesubject 上。

  9. 如果 subject关闭观察者 不为 null,则:

    1. 销毁 subject关闭观察者

    2. subject关闭观察者 设置为 null。

returnValue IDL 属性,在获取时,必须返回上次设置的值。在设置时,必须设置为新值。当元素被创建时,必须设置为空字符串。

我们使用 show/close 作为 dialog 元素的动词,而不是更常见的反义词动词对,如 show/hide 或 open/close,原因如下:

此外,一项调查 表明,许多其他与 dialog 元素设计同时期的 UI 框架表明,show/close 动词对是相当常见的。

总之,事实证明某些动词的含义及其在技术环境中的使用方式意味着,显示和关闭对话框等配对操作并不总是可以用反义词表达。


每个 dialog 元素都有一个 关闭观察者,它是一个 关闭观察者 或 null,最初为 null。

每个 dialog 元素都有一个 is modal 标志。当创建一个 dialog 元素时,此标志必须设置为 false。

每个 HTML 元素 都有一个 previously focused element,它为 null 或一个元素,最初为 null。当调用 showModal()show() 时,此元素设置为当前 聚焦 元素。在运行 对话框聚焦步骤 之前。带有 popover 属性的元素在 显示弹出窗口算法 中设置为当前 聚焦 元素。


HTMLDialogElement/open

Support in all current engines.

Firefox98+Safari15.4+Chrome37+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

open IDL 属性必须 反映 open 内容属性。

此对话框包含一些小字。使用 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>

4.12 脚本

脚本允许作者为其文档添加交互性。

鼓励作者尽可能使用声明性替代脚本,因为声明性机制通常更易于维护,且许多用户禁用脚本。

例如,作者可以使用details元素来显示或隐藏部分详细信息,而不是使用脚本。

还鼓励作者使其应用程序在缺乏脚本支持的情况下也能优雅降级。

例如,如果作者在表头提供了一个链接来动态排序表格,该链接也可以在没有脚本的情况下通过向服务器请求排序后的表格来工作。

4.12.1 script 元素

Element/script

在所有当前引擎中都得到支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

HTMLScriptElement

在所有当前引擎中都得到支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
类别:
元数据内容.
流内容.
短语内容.
支持脚本的元素.
可以使用此元素的上下文:
在预期为元数据内容的地方。
在预期为短语内容的地方。
在预期为支持脚本的元素的地方。
内容模型:
如果没有 src 属性,则取决于 type 属性的值,但必须符合 脚本内容限制
如果有 src 属性,则元素必须为空或仅包含 脚本文档,且符合 脚本内容限制
在 text/html 中的标签省略:
两个标签都不能省略。
内容属性:
全局属性
src — 资源的地址
type — 脚本类型
nomodule — 防止在支持 模块脚本 的用户代理中执行
async — 在获取时执行脚本,不阻塞
defer — 延迟脚本执行
crossorigin — 元素如何处理跨源请求
integrity — 用于 子资源完整性 检查的完整性元数据 [SRI]
referrerpolicy — 元素发起的 引用政策 用于 抓取
blocking — 元素是否 可能会阻塞渲染
fetchpriority — 设置元素发起的 请求优先级
可访问性考虑:
针对作者.
针对实现者.
DOM 接口:
[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 元素允许作者在文档中包含动态脚本和数据块。该元素不 表示 用户内容。

Element/script#attr-type

在所有当前引擎中都得到支持。

Firefox1+Safari≤4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

type 属性允许自定义表示的脚本类型:

要求 数据块 必须使用 有效 MIME 类型字符串 来表示,以避免未来潜在的冲突。如果本规范未来添加额外类型的 脚本,它们将通过将 type 属性设置为非 MIME 类型的值(类似于 "module" 值表示 模块脚本)来触发。通过现在使用有效 MIME 类型字符串,您可以确保您的数据块不会 被重新解释为不同的脚本类型,即使在未来的用户代理中也是如此。

经典脚本JavaScript 模块脚本 可以内联嵌入,或者通过 src 属性从外部文件导入,如果指定则给出 URL 外部脚本资源的使用。如果 src 被指定, 它必须是一个 有效的非空 URL 可能被空格包围

内联 script 元素的内容或外部脚本资源必须符合 JavaScript 规范的 ScriptModule 生产规则,分别用于 经典脚本JavaScript 模块脚本[JAVASCRIPT]

外部脚本资源的内容对于 CSS 模块脚本 必须符合 CSS 规范的要求。 [CSS]

外部脚本资源的内容对于 JSON 模块脚本 必须符合 JSON 规范的要求。 [JSON]

用于 导入映射 的内联 script 元素的内容必须符合 导入映射编写要求

对于 导入映射 script 元素,srcasyncnomoduledefercrossoriginintegrity, 和 referrerpolicy 属性不得指定。

一个文档中不得有多个 导入映射 script 元素。

当用于包含 数据块 时,数据必须 内联嵌入,数据的格式必须通过 type 属性给出,并且 script 元素的内容必须符合所使用格式的要求。srcasyncnomoduledefercrossoriginintegrityreferrerpolicyfetchpriority 属性不得指定。

nomodule 属性是一个 布尔属性, 它防止脚本在支持 模块脚本 的用户代理中执行。 这允许在现代用户代理中选择性地执行 模块脚本 和在较旧用户代理中执行 经典脚本如下面所示nomodule 属性不得在 模块脚本 上指定(如果指定则会被忽略)。

Element/script#attr-async

在所有当前引擎中都支持。

Firefox1+Safari≤4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Element/script#attr-defer

在所有当前引擎中都支持。

Firefox3.5+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

asyncdefer 属性是 布尔属性, 表示脚本的评估方式。经典脚本 可以指定 deferasync, 但如果没有指定 src 属性,则不能指定这两个属性中的任何一个。模块脚本 可以指定 async 属性,但不能指定 defer 属性。

可以使用这些属性选择几种不同的模式,具体取决于脚本的类型。

对于 经典脚本, 如果指定了 async 属性,则经典脚本将会 与解析并行 获取, 并在脚本可用时立即评估(可能在解析完成之前)。如果没有指定 async 属性,但指定了 defer 属性,则经典脚本将会 与解析并行 获取, 并在页面完成解析时进行评估。如果没有指定这两个属性,则脚本将立即获取并评估,阻止解析直到两者都完成。

对于 模块脚本, 如果指定了 async 属性,则模块脚本及其所有依赖项将 与解析并行 获取, 并在模块脚本可用时立即进行评估(可能在解析完成之前)。否则,模块脚本及其依赖项将 与解析并行 获取,并在页面完成解析时进行评估。(defer 属性对模块脚本没有影响。)

以下是对这些内容的总结示意图:

对于<script>,解析会被获取和执行中断。对于<script defer>,获取与解析并行,执行发生在所有解析完成之后。对于<script async>,获取与解析并行,但一旦获取完成,解析会被中断以执行脚本。<script type="module">的情况类似于<script defer>,但依赖项也会被获取,而<script type="module" async>的情况类似于<script async>,但额外获取依赖项。

这些属性的具体处理细节因为主要是历史原因,涉及到许多HTML的方面,因此有些复杂。实现要求因此必须分散在规范的各个部分。下面的算法(在本节中)描述了处理的核心,但这些算法引用并被引用于HTML中 script 开始结束 标签,外部内容, 和 XMLdocument.write() 方法的规则,脚本处理等。

使用 document.write() 方法插入的 script 元素 通常 执行(通常会阻止进一步的脚本执行或HTML解析)。使用 innerHTMLouterHTML 属性插入的脚本则不会执行。

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 属性是一个 获取优先级属性。它的作用是设置在 获取 脚本时使用的 优先级

动态改变 srctypenomoduleasyncdefercrossoriginintegrityreferrerpolicyfetchpriority 属性没有直接效果;这些属性只在下面描述的特定时间使用。

IDL 属性 srctypedeferintegrityblocking, 必须分别 反映 同名的内容属性。

HTMLScriptElement/referrerPolicy

在所有当前引擎中支持。

Firefox65+Safari14+Chrome70+
Opera?Edge79+
Edge (旧版)?Internet Explorer没有
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

referrerPolicy IDL 属性必须 反映 referrerpolicy 内容属性,限制为仅已知值

fetchPriority IDL 属性必须 反映 fetchpriority 内容属性,限制为仅已知值

crossOrigin IDL 属性必须 反映 crossorigin 内容属性,限制为仅已知值

noModule IDL 属性必须 反映 nomodule 内容属性。

async 获取器步骤如下:

  1. 如果 this强制异步 为 true,则返回 true。

  2. 如果 thisasync 内容属性存在,则返回 true。

  3. 返回 false。

async 设置器步骤如下:

  1. this强制异步 设置为 false。

  2. 如果给定值为 true,则将 thisasync 内容属性设置为空字符串。

  3. 否则,移除 thisasync 内容属性。

script.text [ = value ]

返回元素的 子文本内容

可以被设置,以用给定的值替换元素的子节点。

HTMLScriptElement.supports(type)

如果给定的 type 是用户代理支持的脚本类型,则返回 true。本规范中的可能脚本类型为 "classic"、"module" 和 "importmap",但将来可能会添加其他类型。

text 属性的获取器必须返回此 script 元素的 子文本内容

text 属性的设置器必须 字符串替换 所有 用给定值替换此 script 元素的内容。

HTMLScriptElement/supports_static

支持所有当前引擎。

Firefox94+Safari16+Chrome96+
Opera?Edge96+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

supports(type) 方法的步骤是:

  1. 如果 type "classic",则返回 true。

  2. 如果 type "module",则返回 true。

  3. 如果 type "importmap",则返回 true。

  4. 返回 false。

type 参数必须与这些值完全匹配;我们不会执行 ASCII 不区分大小写 匹配。这与 type 内容属性值的处理方式以及 DOMTokenListsupports() 方法的工作方式不同,但与 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 类型,则获取将失败。

4.12.1.1 处理模型

一个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

  1. el结果设置为 result

  2. 如果el结果准备好时要运行的步骤 不为null,那么 运行它们。

  3. el结果准备好时要运行的步骤 设置为null。

  4. el延迟加载事件设置为false。


一个script 元素el隐式潜在渲染阻塞的,如果el类型是 "classic",el解析器插入的,并且 el没有asyncdefer 属性。

克隆步骤为一个script 元素el克隆到副本copy的步骤是将copy已开始设置为el已开始

当一个async 属性被添加到一个 script 元素el时,用户代理必须将el强制异步设置为false。

每当一个 script 元素 eldelaying the load event 为真时,用户代理必须 delay the load eventelpreparation-time document


给定insertedNodescriptHTML 元素后连接步骤是:

  1. 如果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已经不再连接,因此不会被准备

  2. 如果insertedNode解析器插入,则返回。

  3. 给定insertedNode准备 script 元素

script子节点更改步骤如下:

  1. 给定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元素产生了以下效果:

  1. 所有三个子节点被原子插入为outer-script的子节点;所有的插入步骤都运行,在这种情况下没有可观察的后果。
  2. outer-script子节点变更步骤运行,准备该脚本;由于其主体现在不为空,按照顺序执行两个Text节点的内容。
  3. scriptHTML 元素后连接步骤最终运行innerScript的内容。

以下属性更改步骤,给定elementlocalNameoldValuevaluenamespace,适用于所有script元素:

  1. 如果namespace不为null,则返回。

  2. 如果localNamesrc,则运行scriptHTML 元素后连接步骤,给定element

准备脚本元素,给定一个script 元素el

  1. 如果el已开始为true,那么返回。

  2. parser document成为el解析器文档

  3. el解析器 文档设置为null。

    这样做是为了当解析器插入的script 元素在解析器尝试运行它们时未能运行,例如因为它们是空的或指定了不支持的脚本语言,另一个脚本可以稍后改变它们并导致它们再次运行。

  4. 如果parser document不是null,并且el没有async 属性,那么将el强制异步设置为true。

    这样做是为了当解析器插入的script 元素在解析器尝试运行它时未能运行,但稍后在一个脚本动态更新它后被执行时,它将以异步方式执行,即使没有设置async属性。

  5. source text成为el子文本内容

  6. 如果el没有src 属性,并且source text是空字符串, 那么返回。

  7. 如果el不是连接,那么返回。

  8. 如果以下任何一项为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/"和 ellanguage 属性值的连接。

    language 属性从来不是 符合规范的,并且在存在type 属性时总是被忽略。

  9. 如果the script block's type string是一个JavaScript MIME类型本质匹配, 那么将el类型设置为"classic"。

  10. 否则,如果the script block's type string是一个ASCII不区分大小写匹配字符串"module",那么将 el类型设置为"module"。

  11. 否则,如果the script block's type string是一个ASCII不区分大小写匹配字符串"importmap",那么将 el类型设置为"importmap"。

  12. 否则,返回。(没有脚本被执行,并且el类型保持为null。)

  13. 如果parser document不是null,那么将el解析器文档设置回parser document并将el强制异步设置为false。

  14. el已开始设置为 true。

  15. el准备时间文档设置为其节点文档

  16. 如果parser document不是null,并且parser document不等于 el准备时间文档,那么返回。

  17. 如果脚本禁用对于el,那么返回。

    脚本禁用的定义意味着,包括但不限于以下脚本将不会执行:XMLHttpRequest中的脚本, responseXML文档中的脚本,DOMParser创建的文档中的脚本,由 XSLTProcessortransformToDocument功能创建的文档中的脚本,以及由脚本首先插入到使用 Document API创建的文档中的脚本。 [XHR] [DOMPARSING] [XSLTP] [DOM]

  18. 如果el有一个nomodule 内容属性 并且其类型是"classic", 那么返回。

    这意味着指定nomodule 在一个 模块脚本上没有效果;算法继续进行。

  19. 如果el没有src 内容属性,并且元素的内联行为应被内容安全策略阻止吗?算法在给定 el、"script"和 source text时返回"Blocked",那么返回。[CSP]

  20. 如果el有一个event 属性和一个for 属性,并且el类型是"classic",那么:

    1. for成为elfor 属性的值。

    2. event成为elevent 属性的值。

    3. 去除前导和尾随的ASCII空白eventfor中。

    4. 如果for不是一个ASCII不区分大小写匹配字符串 "window",那么返回。

    5. 如果event不是一个ASCII不区分大小写匹配字符串"onload"或字符串"onload()",那么 返回。

  21. 如果el有一个charset 属性,那么让 encoding成为获取编码的结果从 charset属性的值。

    如果el没有charset 属性,或如果获取编码失败,那么让encoding成为 el节点文档编码

    如果el类型是"module",那么这个编码将被忽略。

  22. classic script CORS setting成为el的当前状态的crossorigin 内容属性。

  23. module script credentials mode成为CORS设置属性凭证模式对于elcrossorigin 内容属性。

  24. cryptographic nonce成为el[[CryptographicNonce]] 内部槽的值。

  25. 如果el有一个integrity 属性, 那么让integrity metadata成为该属性的值。

    否则,让integrity metadata为空字符串。

  26. referrer policy成为el的当前状态的referrerpolicy 内容属性。

  27. fetch priority成为el的当前状态的fetchpriority 内容属性。

  28. parser metadata为"parser-inserted",如果 el解析器插入的,并且为"not-parser-inserted",如果 否则。

  29. options成为一个脚本获取选项,其加密noncecryptographic nonce完整性元数据integrity metadata解析器 元数据parser metadata凭证模式module script credentials mode引用 策略referrer policy,以及获取优先级fetch priority

  30. settings object成为el节点文档相关设置对象

  31. 如果el有一个src 内容属性,那么:

    1. 如果el类型是"importmap",那么将一个元素任务排队DOM 操作任务源上给定el触发 一个事件命名为errorel上,然后返回。

      外部import map脚本当前不支持。请参阅WICG/import-maps issue #235关于添加支持的讨论。

    2. src成为elsrc 属性的值。

    3. 如果src为空字符串,那么将一个元素任务排队DOM操作任务源上给定 el触发一个事件 命名为errorel上,然后返回。

    4. el来自外部文件 设置为true。

    5. url成为编码解析URL的结果给定 src,相对于el节点 文档

    6. 如果url是失败,那么将一个元素任务排队DOM 操作任务源上给定el触发 一个事件命名为errorel上,然后 返回。

    7. 如果el潜在渲染阻塞的,那么阻塞 渲染el上。

    8. el延迟加载 事件设置为true。

    9. 如果el当前是渲染阻塞的,那么将 options 渲染阻塞设置为true。

    10. onComplete给定result是以下步骤:

      1. 标记为 准备好 el给定result

    11. 切换el类型

      "classic"

      获取一个经典脚本给定urlsettings objectoptionsclassic script CORS settingencoding,和 onComplete

      "module"

      如果el没有integrity 属性,那么将options完整性元数据设置为 结果的 解析模块完整性 元数据给定urlsettings object

      获取一个外部模块脚本图 给定urlsettings objectoptions,和onComplete

      出于性能原因,用户代理可能会尽快开始获取经典脚本或模块图 (如上所述),一旦src 属性被设置, 而不是,期望el将变得连接(并且crossorigin 属性不会改变值在此期间)。无论如何,一旦el变得连接,加载必须 按照此步骤描述开始。如果UA执行了这样的预取,但el 从未变得连接,或者src 属性被 动态更改,或者crossorigin 属性被动态更改,那么 用户代理将不会执行获取到的脚本,获取过程将 被有效浪费。

  32. 如果el没有src 内容 属性:

    1. base URL成为el节点 文档文档 基本URL

    2. 切换el类型

      "classic"
      1. script成为结果的创建一个经典脚本使用 source textsettings objectbase URLoptions

      2. 标记为准备好el给定 script

      "module"
      1. el延迟加载 事件设置为true。

      2. 如果el潜在渲染阻塞的,那么:

        1. 阻塞渲染el上。

        2. options渲染阻塞 设置为 true。

      3. 获取一个内联模块脚本 图,给定source textbase URLsettings objectoptions,并且使用以下步骤给定result

        1. 将一个元素任务排队网络任务源 上给定el以执行以下步骤:

          1. 标记为准备好el给定 result

          在此处排队任务意味着,即使内联模块脚本没有 依赖项或同步导致解析错误,我们也不会继续 执行脚本元素 同步。

      "importmap"
      1. 如果el相关全局对象允许导入地图 是false,那么将一个元素任务排队DOM 操作任务源上给定el触发一个事件命名为errorel上,然后返回。

      2. el相关全局对象允许导入地图设置为false。

      3. result成为结果的创建一个导入地图解析结果给定source textbase URL

      4. 标记为准备好el给定 result

  33. 如果el类型是"classic"并且el有一个 src 属性,或者el类型是"module":

    1. 断言el结果 是"uninitialized"。

    2. 如果el有一个async 属性或el强制异步为true:

      1. script成为el准备时间文档将尽快执行的脚本集

      2. 附加elscript

      3. el当结果准备好时要运行的步骤设置为 以下:

        1. 执行脚本元素 el

        2. 移除elscript

    3. 否则,如果el不是 解析器插入

      1. script成为el准备时间文档将按顺序尽快执行的脚本列表

      2. 附加elscript

      3. el当结果准备好时要运行的步骤设置为 以下:

        1. 如果script[0]不是el,那么中止这些步骤。

        2. script不为空,并且script[0]的结果不是 "uninitialized"时:

          1. 执行脚本元素 script[0]。

          2. 移除script[0]。

    4. 否则,如果el有一个 defer 属性或el类型是"module":

      1. 附加el到其解析器 文档文档解析完成后将执行的脚本列表

      2. el当结果准备好时要运行的步骤设置为 以下:设置el准备好被解析器执行为true。(解析器 将处理执行脚本。)

    5. 否则:

      1. 设置el解析器文档待解析阻塞脚本el

      2. 阻止渲染el 上。

      3. elresult 准备就绪时要运行的步骤 设置为以下内容:将 elready to be parser-executed 设置为 true。(解析器将处理脚本的执行。)

  34. 否则:

    1. 断言el结果 不是"uninitialized"。

    2. 如果以下所有条件都为真:

      那么:

      1. 设置el解析器文档待解析阻塞脚本el

      2. el准备好被解析器执行为true。(解析器 将处理执行脚本。)

    3. 否则,立即执行 脚本元素el,即使其他脚本已经在执行。

每个Document有一个 待解析阻塞脚本,这是一个 script 元素或null,最初为null。

每个Document有一个 将尽快执行的脚本集,这是一个集合script 元素,最初为空。

每个Document有一个 将按顺序尽快执行的脚本列表,这是一个列表script 元素,最初 为空。

每个Document有一个 文档解析完成后将执行的脚本列表,这是一个列表script 元素,最初 为空。

如果一个script 元素阻塞一个解析器被移动到另一个 Document 在它通常会停止阻塞解析器之前,它仍然会 继续阻塞解析器,直到导致它阻塞解析器的条件不再适用(例如,如果脚本是一个待解析阻塞脚本,因为 原来的Document有一个样式表在阻塞 脚本当它被 解析,但随后脚本被移动到另一个Document 在阻塞样式 表加载之前,脚本仍然会阻塞解析器,直到样式表全部加载完成,到 那时脚本执行并且解析器被解锁)。

为了执行脚本元素给定一个 script 元素el

  1. document成为el节点文档

  2. 如果el准备时间文档不等于 document,那么返回。

  3. 解除阻塞渲染el上。

  4. 如果el结果是null,那么触发一个事件命名为errorel上,然后返回。

  5. 如果el来自外部文件为 true,或el 类型是"module",那么增加 document忽略破坏性写入计数器

  6. 切换el类型

    "classic"
    1. oldCurrentScript成为documentcurrentScript 对象最近设置的值。

    2. 如果el不是 一个影子根,那么 将documentcurrentScript 属性设置为el。否则,将其设置为null。

      这不使用在文档树中检查, 因为el可能在执行之前已从文档中移除,在这种情况下currentScript 仍然需要 指向它。

    3. 运行经典脚本给定 el结果

    4. documentcurrentScript 属性设置为 oldCurrentScript

    "module"
    1. 断言documentcurrentScript 属性为null。

    2. 运行模块脚本给定 el结果

    "importmap"
    1. 注册一个导入地图给定el相关全局 对象el结果

  7. 减少document忽略破坏性写入计数器, 如果 它在前面的步骤中增加。

  8. 如果el来自外部文件为 true,那么触发一个事件命名为 loadel上。

4.12.1.2 脚本语言

用户代理不要求支持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]

4.12.1.3 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) { ... }

这样做还可以避免另一个陷阱:由于相关的历史原因,经典脚本中的字符串"<!--"实际上被视为行注释开始,就像"//"一样。

4.12.1.4 外部脚本的内联文档

如果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>
4.12.1.5 script元素和XSLT的交互

本节为非规范性内容。

本规范未定义XSLT与script元素的交互方式。然而,在没有其他规范实际定义的情况下,以下是基于现有实现的实现指南:

前两种情况与最后一种情况的主要区别在于,前两种情况操作的是Document,而最后一种情况操作的是片段。

4.12.2 noscript 元素

Element/noscript

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
Categories:
Metadata content.
Flow content.
Phrasing content.
Contexts in which this element can be used:
head元素中的HTML文档中,如果没有祖先noscript元素。
短语内容中预期的HTML文档中,如果没有祖先noscript元素。
Content model:
脚本被禁用时,在head元素中:按任何顺序,零个或多个link元素,零个或多个style元素,和零个或多个meta元素。
脚本被禁用时,不在head元素中:透明,但不能有noscript元素的后代。
否则:符合散文中要求的文本。
Tag omission in text/html:
两者标签都不可省略。
Content attributes:
全局属性
可访问性注意事项:
对于作者
对于实现者
DOM接口:
使用HTMLElement

如果启用了脚本,则noscript元素不表示任何内容;如果禁用了脚本,则表示其子元素。它用于向支持脚本和不支持脚本的用户代理呈现不同的标记,从而影响文档的解析方式。

HTML文档中使用时,允许的内容模型如下:

head元素中,如果脚本被 禁用适用于noscript元素

noscript元素必须只包含linkstylemeta元素。

head元素中,如果启用了脚本适用于noscript元素

noscript元素必须只包含文本,但调用HTML片段解析算法,将noscript元素作为上下文元素,将文本内容作为input,必须生成一个仅包含linkstylemeta元素的节点列表,这些元素如果是noscript元素的子元素则是符合规范的,并且没有解析错误

head元素之外,如果脚本被禁用适用于noscript元素

noscript元素的内容模型是透明的,但有一个额外的限制,即noscript元素不能有noscript元素的祖先(即noscript不能嵌套)。

head元素之外,如果启用了脚本适用于noscript元素

noscript元素必须只包含文本,但文本必须是运行以下算法生成的文档符合规范,没有noscript元素和script元素,且算法的任何步骤都不会抛出异常或导致HTML解析器标记解析错误

  1. 从文档中删除每个script元素。
  2. 列出文档中每个noscript元素。对于该列表中的每个noscript元素,执行以下步骤:
    1. snoscript元素的子文本内容
    2. outerHTML属性的值设置为s。(这会导致noscript元素从文档中删除。)

所有这些转变都是必要的,因为出于历史原因,noscript元素的处理方式会根据解析器调用时是否启用了脚本而不同。

noscript元素不能在XML文档中使用。

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>

上述技术在XML文档中也很有用,因为noscript元素在那里是不允许的。

4.12.3 template 元素

Element/template

支持所有当前引擎。

Firefox22+Safari8+Chrome26+
Opera?Edge79+
Edge (旧版)13+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android支持Samsung Internet?Opera Android?

HTMLTemplateElement

支持所有当前引擎。

Firefox22+Safari8+Chrome26+
Opera?Edge79+
Edge (旧版)13+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
类别:
元数据内容.
流内容.
短语内容.
脚本支持元素.
此元素可用的上下文:
在期望元数据内容的地方。
在期望短语内容的地方。
在期望脚本支持元素的地方。
作为没有span属性的colgroup元素的子元素。
内容模型:
(详情请见例子).
在 text/html 中的标签省略:
两个标签都不能省略。
内容属性:
全局属性
shadowrootmode — 启用流式声明阴影根
shadowrootdelegatesfocus — 在声明阴影根上设置委派焦点
shadowrootclonable — 在声明阴影根上设置可克隆
shadowrootserializable — 在声明阴影根上设置可序列化
可访问性考虑:
作者参考.
实现者参考.
DOM接口:
[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片段。

在渲染中,template元素不代表任何内容。

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

HTMLTemplateElement/content

支持所有当前引擎。

Firefox22+Safari8+Chrome26+
Opera?Edge79+
Edge (旧版)13+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回模板内容(一个DocumentFragment)。

每个template元素都有一个关联的DocumentFragment对象,这是它的模板内容模板内容没有任何符合性要求。当创建一个template元素时,用户代理必须运行以下步骤以建立模板内容

  1. doc成为template元素的节点文档适当模板内容拥有文档

  2. 创建一个DocumentFragment对象,其节点文档doc,并且宿主template元素。

  3. template元素的模板内容设置为新创建的DocumentFragment对象。

一个Document doc适当模板内容拥有文档是通过以下算法返回的Document

  1. 如果doc不是由该算法创建的Document,则:

    1. 如果doc尚未有一个关联的惰性模板文档,则:

      1. new doc成为一个新的Document(其浏览上下文为空)。这对于上述步骤来说是由该算法创建的Document

      2. 如果doc是一个HTML文档,则也将new doc标记为一个HTML文档

      3. doc关联的惰性模板文档设置为new doc

    2. doc设置为doc关联的惰性模板文档

    因此,每个不是由该算法创建的Document将获得一个单独的Document作为其代理,用于拥有其所有template元素的模板内容,以便它们不在浏览上下文中,从而保持惰性(例如脚本不会运行)。与此同时,位于由该算法创建的Document对象内的template元素将重用相同的Document所有者用于其内容。

  2. 返回doc

对于template元素,采纳步骤(以nodeoldDocument为参数)如下:

  1. doc成为node节点文档适当模板内容拥有文档

    node节点文档node刚刚被采纳进入的文档对象。

  2. 采纳 node模板内容(一个DocumentFragment对象)到doc中。

content getter步骤是返回template模板内容,如果模板内容不是一个ShadowRoot节点;否则为null。

shadowRootMode IDL属性必须反映shadowrootmode内容属性,仅限于已知值

shadowRootDelegatesFocus IDL属性必须反映shadowrootdelegatesfocus内容属性。

shadowRootClonable IDL属性必须反映shadowrootclonable内容属性。

shadowRootSerializable IDL属性必须反映shadowrootserializable内容属性。


对于正在克隆到副本copytemplate元素node克隆步骤必须运行以下步骤:

  1. 如果在调用克隆算法中未设置clone children flag,则返回。

  2. copied contents成为node模板内容的所有子节点的克隆结果,document设置为copy模板内容节点文档,并且设置clone children flag

  3. 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.

4.12.3.1 template元素与XSLT和XPath的交互

本节非规范性。

本规范未定义XSLT和XPath与template元素的交互方式。但是,在没有其他规范实际定义此内容的情况下,以下是一些针对实现者的指南,旨在与本规范中描述的其他处理方式保持一致:

4.12.4 slot 元素

Element/slot

Support in all current engines.

Firefox63+Safari10+Chrome53+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLSlotElement

Support in all current engines.

Firefox63+Safari10+Chrome53+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
Categories:
流内容
短语内容
可以使用此元素的上下文:
预期短语内容的地方。
内容模型:
透明的
在text/html中省略标签:
标签不可省略。
内容属性:
全局属性
name — shadow tree slot的名称
可访问性考虑:
针对作者
针对实现者
DOM接口:
[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内容属性可以包含任何字符串值。它表示一个slotname

name属性用于分配slot给其他元素:一个带有 slot元素和一个name属性的元素创建一个命名的slot,任何具有slot属性且其值与name属性值匹配的元素会被分配到该slot中,并且slot元素是shadow tree的子元素,该shadow tree的宿主具有相应的slot属性值。

slot.name

HTMLSlotElement/name

Support in all current engines.

Firefox63+Safari10+Chrome53+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
可以用于获取和设置slotname
slot.assignedNodes()

HTMLSlotElement/assignedNodes

Support in all current engines.

Firefox63+Safari10+Chrome53+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
返回slot已分配的节点
slot.assignedNodes({ flatten: true })
返回slot已分配的节点(如果有),否则返回slot的子节点,并对其中遇到的任何slot元素进行递归处理,直到没有slot元素为止。
slot.assignedElements()

HTMLSlotElement/assignedElements

Support in all current engines.

Firefox66+Safari12.1+Chrome65+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
返回slot已分配的节点,仅限于元素。
slot.assignedElements({ flatten: true })
返回与assignedNodes({ flatten: true })相同的结果,仅限于元素。
slot.assign(...nodes)

slot手动分配的节点设置为给定的nodes

nameIDL属性必须反映相同名称的内容属性。

slot元素有手动分配的节点,这是一个由assign()设置的有序集合。该集合初始为空。

手动分配的节点集合可以使用对slottables的弱引用来实现,因为该集合不能直接从脚本访问。

assignedNodes(options)方法步骤如下:

  1. 如果options["flatten"]为false,则返回this已分配的节点

  2. 返回使用this进行查找扁平化的slottables的结果。

assignedElements(options)方法步骤如下:

  1. 如果options["flatten"]为false,则返回this已分配的节点,仅限于Element节点。

  2. 返回使用this进行查找扁平化的slottables的结果,仅限于Element节点。

HTMLSlotElement/assign

Support in all current engines.

Firefox92+Safari16.4+Chrome86+
Opera?Edge86+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

assign(...nodes)方法步骤如下:

  1. 对每个 nodethis手动分配的节点,将node手动slot分配设置为null。

  2. nodesSet设置为新的有序集合

  3. 对每个 nodesnode

    1. 如果node手动slot分配引用了一个slot,则将node从该slot手动分配的节点中移除。

    2. node手动slot分配设置为this

    3. node附加到nodesSet

  4. this手动分配的节点设置为nodesSet

  5. this运行为树分配slotables

4.12.5 canvas元素

Element/canvas

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

HTMLCanvasElement

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
类别
流内容
短语内容
嵌入内容
可感知内容
此元素可用的上下文
期望出现嵌入内容的地方。
内容模型
透明,但没有交互内容后代,除非是a元素,具有usemap属性的img元素,button元素,input元素,其type属性处于复选框单选按钮状态,input元素是按钮,以及具有multiple属性或显示大小大于1的select元素。
在text/html中的标签省略
标签均不可省略。
内容属性
全局属性
width — 水平方向尺寸
height — 垂直方向尺寸
无障碍考虑
供作者使用
供实现者使用
DOM接口
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元素有两个属性来控制元素位图的大小:widthheight。这些属性在指定时必须具有有效的非负整数值。必须使用解析非负整数的规则获得其数值。如果属性丢失,或解析其值返回错误,则必须使用默认值。width属性默认为300,height属性默认为150。

当设置widthheight属性的值时,如果canvas元素的上下文模式设置为占位符,用户代理必须抛出DOMException并保留属性值不变。

canvas元素表示嵌入内容时,其自然尺寸等于元素位图的尺寸。

用户代理必须使用由每个坐标空间单位对应一个图像数据像素组成的方形像素密度来处理canvas的位图及其渲染上下文。

canvas元素可以通过样式表任意调整大小,其位图随后将受'object-fit' CSS属性的影响。


canvas元素的位图、ImageBitmap对象的位图,以及渲染上下文的某些位图(如下面关于CanvasRenderingContext2DImageBitmapRenderingContext对象的部分所述),具有可以设置为true或false的origin-clean标志。最初,当创建canvas元素或ImageBitmap对象时,其位图的origin-clean标志必须设置为true。

canvas元素可以绑定渲染上下文。最初,它没有绑定的渲染上下文。为了跟踪是否具有渲染上下文以及是什么类型的渲染上下文,canvas还具有一个画布上下文模式,最初为none,但可以通过本规范中定义的算法更改为占位符2dbitmaprendererwebglwebgl2webgpu

当其画布上下文模式none时,canvas元素没有渲染上下文,其位图必须是透明黑色自然宽度等于元素的数值,即元素的width属性和自然高度等于元素的height属性的数值,这些值在设置、更改或删除属性时以CSS像素为单位解释并更新。

当其画布上下文模式占位符时,canvas元素没有渲染上下文。它作为OffscreenCanvas对象的占位符,并且canvas元素的内容由OffscreenCanvas对象的渲染上下文更新。

canvas元素表示嵌入内容时,它提供了一个绘画源,其宽度是元素的自然宽度,其高度是元素的自然高度,其外观是元素的位图。

每当widthheight内容属性被设置、移除、改变或冗余设置为它们已经有的值时,用户代理必须执行以下表中对应于canvas元素的上下文模式的操作。

上下文模式

操作

2d

按照步骤设置位图尺寸,以获得widthheight内容属性的数值。

webglwebgl2

按照WebGL规范中定义的行为进行。[WEBGL]

webgpu

按照WebGPU中定义的行为进行。[WEBGPU]

bitmaprenderer

如果上下文的位图模式设置为空白,运行步骤设置ImageBitmapRenderingContext的输出位图,传递canvas元素的渲染上下文。

占位符

什么也不做。

什么也不做。

HTMLCanvasElement/height

支持所有当前引擎。

Firefox1.5+Safari3+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

HTMLCanvasElement/width

支持所有当前引擎。

Firefox1.5+Safari3+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

widthheightIDL属性必须反映同名的相应内容属性,并具有相同的默认值。


context = canvas.getContext(contextId [, options ])

HTMLCanvasElement/getContext

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

返回一个在画布上绘图的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 元素的方法,当调用时,必须执行以下步骤:

  1. 如果options不是对象,则将options设置为null。

  2. options设置为转换 options为JavaScript值的结果。

  3. 运行下表中列标题与此canvas 元素的画布上下文模式匹配且行标题与contextId匹配的单元格中的步骤:

    2d bitmaprenderer webglwebgl2 webgpu 占位符
    "2d"
    1. context为运行2D上下文创建算法给定thisoptions的结果。

    2. this上下文模式设置为2d

    3. 返回context

    返回上次用相同的第一个参数调用此方法时返回的相同对象。 返回null。 返回null。 返回null。 抛出一个InvalidStateError DOMException
    "bitmaprenderer"
    1. context为运行ImageBitmapRenderingContext 创建算法给定thisoptions的结果。

    2. this上下文模式设置为bitmaprenderer

    3. 返回context

    返回null。 返回上次用相同的第一个参数调用此方法时返回的相同对象。 返回null。 返回null。 抛出一个InvalidStateError DOMException
    "webgl" 或 "webgl2",如果用户代理在其当前配置中支持WebGL功能
    1. context为遵循WebGL规范的上下文创建部分中的指令的结果。[WEBGL]

    2. 如果context为null,则返回null;否则将this上下文模式设置为webglwebgl2

    3. 返回context

    返回null。 返回null。 返回上次用相同的第一个参数调用此方法时返回的相同对象。 返回null。 抛出一个InvalidStateError DOMException
    "webgpu",如果用户 代理在其当前配置中支持WebGPU功能
    1. context为遵循WebGPU画布渲染 部分中的指令的结果。[WEBGPU]

    2. 如果context为null,则返回null;否则将 this上下文模式设置为 webgpu

    3. 返回context

    返回null。 返回null。 返回null。 返回上次用相同的第一个参数调用此方法时返回的相同对象。 抛出一个InvalidStateError DOMException
    不支持的值* 返回null。 返回null。 返回null。 返回null。 返回null。 抛出一个InvalidStateError DOMException

    * 例如,在用户代理耗尽图形硬件的能力且没有软件后备实现的情况下,“webgl” 或“webgl2”值。


url = canvas.toDataURL([ type [, quality ] ])

HTMLCanvasElement/toDataURL

Support in all current engines.

Firefox2+Safari4+Chrome2+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

返回画布中的图像的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 ] ])

HTMLCanvasElement/toBlob

Support in all current engines.

Firefox18+Safari11+Chrome50+
Opera?Edge79+
Edge (旧版)NoInternet Explorer🔰 10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

创建一个表示画布中图像的Blob 对象, 并使用该对象的句柄调用回调。

第二个参数(如果提供)控制要返回的图像类型(例如PNG或JPEG)。默认值为"image/png"; 如果给定的类型不受支持,也会使用该类型。第三个参数适用于支持可变质量的图像格式(例如"image/jpeg"), 是一个范围在0.0到1.0之间的数字,表示所需的图像质量级别。

canvas.transferControlToOffscreen()

HTMLCanvasElement/transferControlToOffscreen

Support in all current engines.

Firefox105+Safari16.4+Chrome69+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回一个新创建的OffscreenCanvas 对象,该对象使用 canvas 元素作为占位符。一旦canvas 元素变成 OffscreenCanvas 对象的占位符,它的自然大小就不能再改变,并且不能有渲染上下文。占位符画布的内容在 OffscreenCanvas相关代理事件循环更新渲染 步骤中更新。

toDataURL(type, quality)方法, 调用时,必须运行以下步骤:

  1. 如果这个canvas 元素的位图的origin-clean标志被设置为false,则抛出 SecurityError DOMException

  2. 如果这个canvas 元素的位图没有像素(即它的水平尺寸或垂直尺寸为零),则返回字符串"data:,"。(这是最短的 data: URL;它表示一个text/plain资源中的空字符串。)

  3. file成为canvas元素位图作为文件的序列化, 如果给定,则传递typequality

  4. 如果file为null,则返回"data:,"。

  5. 返回表示filedata: URL[RFC2397]

toBlob(callback, type, quality)方法,调用时,必须运行以下步骤:

  1. 如果这个canvas 元素的位图的origin-clean标志被设置为false,则抛出 SecurityError DOMException

  2. result为null。

  3. 如果这个canvas 元素的位图有像素(即,它的水平尺寸和垂直尺寸都不是零),则将result设置为这个 canvas 元素位图的副本。

  4. 并行运行这些步骤:

    1. 如果result非null,则将result设置为result序列化为文件, 并给出typequality(如果提供)。

    2. 画布blob序列化任务源上队列一个元素任务,给定canvas 元素,运行这些步骤:

      1. 如果result非null,则将result设置为一个新的 Blob 对象,在这个canvas 元素的相关领域中创建,表示result[FILEAPI]

      2. 调用 callback,使用 « result » 和 "report"。

transferControlToOffscreen()方法,调用时,必须运行以下步骤:

  1. 如果这个canvas 元素的context mode未设置为none,则抛出 InvalidStateError DOMException

  2. offscreenCanvas成为一个新的OffscreenCanvas 对象, 它的宽度和高度等于这个widthheight 内容属性的值 canvas 元素。

  3. 将这个offscreenCanvas占位符canvas元素设置为对这个canvas 元素的弱引用。

  4. 将这个canvas 元素的context mode设置为placeholder

  5. 返回offscreenCanvas

4.12.5.1 2D 渲染上下文

CanvasRenderingContext2D

所有当前引擎均支持。

Firefox1.5+Safari2+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

CanvasImageSource

CanvasGradient

所有当前引擎均支持。

Firefox1.5+Safari2+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

CanvasPattern

所有当前引擎均支持。

Firefox1.5+Safari2+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

TextMetrics

所有当前引擎均支持。

Firefox1.5+Safari4+Chrome2+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android31+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

ImageData

所有当前引擎均支持。

Firefox3.5+Safari3.1+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+
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

所有当前引擎均支持。

Firefox1.5+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回canvas元素。

attributes = context.getContextAttributes()

返回一个对象,其:

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" → thisalpha, "desynchronized" → this去同步, "colorSpace" → this色彩空间, "willReadFrequently" → this将频繁读取 ]»。


CanvasRenderingContext2D2D渲染上下文表示一个平面线性笛卡尔平面,其原点(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,其步骤如下:

  1. settings设置为options转换为字典类型CanvasRenderingContext2DSettings的结果。(这可能会引发异常)。

  2. context设置为一个新的CanvasRenderingContext2D对象。

  3. 初始化contextcanvas属性以指向target

  4. context输出位图设置为与target的位图相同(因此它们是共享的)。

  5. 设置位图尺寸targetwidthheight内容属性的数字值

  6. contextalpha设置为settings["alpha"]。

  7. context去同步设置为settings["desynchronized"]。

  8. context色彩空间设置为settings["colorSpace"]。

  9. context将频繁读取设置为settings["willReadFrequently"]。

  10. 返回context


当用户代理需要设置位图尺寸widthheight时,必须运行以下步骤:

  1. 将渲染上下文重置为默认状态

  2. 输出位图调整为新widthheight

  3. canvas设置为渲染上下文的canvas属性初始化的canvas元素。

  4. 如果canvaswidth内容属性的数字值width不同,则将canvaswidth内容属性设置为表示width的最短可能字符串,作为有效非负整数

  5. 如果canvasheight内容属性的数字值height不同,则将canvasheight内容属性设置为表示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缩放是生成高质量输出的图像平滑算法的例子。本规范并不强制要求使用特定的插值算法。

4.12.5.1.1 实现说明

本节为非规范性内容。

输出位图,当它不是由用户代理直接显示时,实现可以不更新此位图,而只是记住已应用于它的绘图操作序列,直到需要位图的实际数据(例如因为调用了drawImage()createImageBitmap()工厂方法)。在许多情况下,这将更具内存效率。

canvas元素的位图是几乎总是会在实践中需要的位图。当渲染上下文有输出位图时,它总是只是一个canvas元素位图的别名。

有时需要额外的位图,例如,当画布以不同于其自然尺寸的大小被绘制时,以启用快速绘图,或为了实现双重缓冲,以便在执行画布绘图命令时,图形更新(例如页面滚动)可以同时处理。

4.12.5.1.2 画布状态

实现CanvasState接口的对象维护一个绘图状态堆栈。绘图状态包括:

渲染上下文的位图不是绘图状态的一部分,因为它们取决于渲染上下文是否以及如何绑定到canvas元素。

实现CanvasState混入的对象具有一个上下文丢失布尔值,该值在对象创建时初始化为false。上下文丢失值在上下文丢失步骤中更新。

context.save()

CanvasRenderingContext2D/save

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

将当前状态推送到堆栈。

context.restore()

CanvasRenderingContext2D/restore

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

弹出堆栈顶部的状态,恢复上下文到该状态。

context.reset()

重置渲染上下文,包括后备缓冲区、绘图状态堆栈、路径和样式。

context.isContextLost()

如果渲染上下文丢失,则返回true。上下文丢失可能由于驱动程序崩溃、内存不足等原因发生。在这些情况下,画布会丢失其后备存储,并采取措施将渲染上下文重置为默认状态

save()方法步骤是将当前绘图状态的副本推送到绘图状态堆栈。

restore()方法步骤是弹出绘图状态堆栈顶部的条目,并重置其描述的绘图状态。如果没有保存的状态,则该方法必须不执行任何操作。

CanvasRenderingContext2D/reset

Firefox113+SafariNoChrome99+
Opera?Edge99+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

OffscreenCanvasRenderingContext2D#canvasrenderingcontext2d.reset

Firefox113+SafariNoChrome99+
Opera?Edge99+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

reset()方法步骤是将渲染上下文重置为默认状态

将渲染上下文重置为默认状态

  1. 将画布的位图清除为透明黑色

  2. 清空上下文当前默认路径中的子路径列表。

  3. 清空上下文的绘图状态堆栈。

  4. 将一切绘图状态包含的内容重置为初始值。

CanvasRenderingContext2D/isContextLost

Support in one engine only.

FirefoxNoSafariNoChrome99+
Opera?Edge99+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

isContextLost()方法步骤是返回this上下文丢失

4.12.5.1.3 线条样式
context.lineWidth [ = value ]

CanvasRenderingContext2D/lineWidth

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
styles.lineWidth [ = value ]

返回当前的线宽。

可以设置以改变线宽。非有限值大于零的值将被忽略。

context.lineCap [ = value ]

CanvasRenderingContext2D/lineCap

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
styles.lineCap [ = value ]

返回当前的线端点样式。

可以设置以改变线端点样式。

可能的线端点样式有 "butt","round",和 "square"。其他值将被忽略。

context.lineJoin [ = value ]

CanvasRenderingContext2D/lineJoin

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
styles.lineJoin [ = value ]

返回当前的线连接样式。

可以设置以改变线连接样式。

可能的线 连接样式有 "bevel","round",和 "miter"。其他值将被忽略。

context.miterLimit [ = value ]

CanvasRenderingContext2D/miterLimit

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
styles.miterLimit [ = value ]

返回当前的斜接限制比率。

可以设置以改变斜接限制比率。非有限值大于零的值将被忽略。

context.setLineDash(segments)

CanvasRenderingContext2D/setLineDash

Support in all current engines.

Firefox27+Safari7+Chrome23+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
styles.setLineDash(segments)

设置当前的线条虚线模式(用于描边)。参数是一个距离列表,表示线条开和关的交替长度。

segments = context.getLineDash()

CanvasRenderingContext2D/getLineDash

Support in all current engines.

Firefox27+Safari7+Chrome23+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
segments = styles.getLineDash()

返回当前线条虚线模式的副本。返回的数组总是有偶数个条目(即模式被规范化)。

context.lineDashOffset

CanvasRenderingContext2D/lineDashOffset

Support in all current engines.

Firefox27+Safari7+Chrome23+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
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) 方法在调用时,必须执行以下步骤:

  1. 如果 segments 中的任何值不是有限的(例如,无穷大或 NaN 值),或者任何值为负(小于零),则返回(不抛出异常;用户代理可以在开发者控制台显示消息,因为这对调试有帮助)。

  2. 如果 segments 中的元素数目为奇数,则让 segmentssegments 的两个副本的串联。

  3. 让对象的 虚线列表segments

当调用 getLineDash() 方法时,必须返回一个序列,其值为对象的 虚线列表 的值,顺序相同。

有时更改虚线图案的“相位”是有用的,例如实现“行军蚂蚁”效果。相位可以通过 lineDashOffset 属性设置。获取时,必须返回当前值。设置时,非有限值和 NaN 值必须被忽略,使值保持不变;其他值必须将当前值更改为新值。

创建实现 CanvasPathDrawingStyles 接口的对象时,lineDashOffset 属性最初的值必须为 0.0。


当用户代理 描摹路径 时,给定实现 CanvasPathDrawingStyles 接口的对象 style,必须运行以下算法。此算法返回一个新的 路径

  1. path 成为被描摹路径的副本。

  2. path 修剪所有零长度的 线段

  3. path 移除任何包含无线条的子路径(即仅有一个点的子路径)。

  4. path 中每个子路径的每个点替换为连接点(除了每个子路径的第一个点和最后一个点),这样子路径都由两个点组成(一个起点和一个终点),一条或多条线连接这些点和连接点。

  5. path 中的每个闭合子路径添加一条直的封闭线,连接最后一个点和第一个点;将最后一个点更改为连接点(从之前的最后一条线到新添加的封闭线),并将第一个点更改为连接点(从新添加的封闭线到第一条线)。

  6. 如果 style虚线列表 为空,则跳到标记为 convert 的步骤。

  7. pattern widthstyle虚线列表 所有条目的串联,以坐标空间单位表示。

  8. 对于 path 中的每个子路径 subpath,运行以下子步骤。这些子步骤在 path 中对子路径进行 活体内 突变。

    1. subpath widthsubpath 所有线条的长度,以坐标空间单位表示。

    2. offsetstylelineDashOffset 的值,以坐标空间单位表示。

    3. offset 大于 pattern width 时,将其减去 pattern width

      offset 小于零时,将其增加 pattern width

    4. 定义 L 为沿 subpath 中所有线条定义的线性坐标线,使得子路径中第一条线的起点定义为坐标 0,子路径中最后一条线的终点定义为坐标 subpath width

    5. position 为零减去 offset

    6. index 为 0。

    7. current state(其他状态为 零开)。

    8. 虚线开:让 segment lengthstyle虚线列表index 条目值。

    9. position 增加 segment length

    10. 如果 position 大于 subpath width,则结束这些子步骤并开始下一个子路径的子步骤;如果没有更多的子路径,则跳到标记为 convert 的步骤。

    11. 如果 segment length 不为零,则让 current state

    12. index 增加 1。

    13. 虚线关:让 segment lengthstyle虚线列表index 条目值。

    14. startL 上的 position 偏移。

    15. position 增加 segment length

    16. 如果 position 小于零,则跳到标记为 post-cut 的步骤。

    17. 如果 start 小于零,则让 start 为零。

    18. 如果 position 大于 subpath width,则让 endL 上的 subpath width 偏移。否则,让 endL 上的 position 偏移。

    19. 跳到第一个适当的步骤:

      如果 segment length 为零且 current state

      什么也不做,继续到下一个步骤。

      如果 current state

      end 位置的线条上剪断,并在该处放置一个点,将其切成两段子路径;移除 startend 之间的所有线段、连接点、点和子路径;并最终在 start 处放置一个没有连接线的点。

      对于绘制线帽的目的,这个点具有 方向性。方向性是原始线条在该点的方向(即当 L 在上面定义时)。

      否则

      start 位置的线条上剪断并放置一个点,将其切成两段子路径,并类似地在 end 位置的线条上剪断并放置一个点,将其切成两段子路径,然后移除 startend 之间的所有线段、连接点、点和子路径。

      如果 startend 是同一个点,则这将导致线条被切成两段并在该处插入两个点,除非该点上还有一个连接点,则必须移除该连接点。

    20. Post-cut:如果 position 大于 subpath width,则跳到标记为 convert 的步骤。

    21. 如果 segment length 大于零,则让 positioned-at-on-dash 为假。

    22. index 增加 1。如果它等于 style虚线列表 中的条目数,则让 index 为 0。

    23. 返回到标记为 虚线开 的步骤。

  9. 转换:这是将路径转换为表示其描边的新路径的步骤。

    创建一个新的 路径,描述如果长度等于 stylelineWidth 的直线沿每个子路径扫过的边缘,同时保持直线与被扫路径正交,替换每个点为满足 stylelineCap 属性所需的端点帽,如之前描述并详细说明的,并替换每个连接点为满足 stylelineJoin 类型所需的连接点,如下所定义。

    :每个点有一个与出线方向垂直的平坦边缘。这然后根据 stylelineCap 值进行补充。"butt" 值意味着不添加额外的线帽。"round" 值意味着必须在每个点的出线处添加一个直径等于 stylelineWidth 宽度的半圆。"square" 值意味着必须在每个点的出线处添加一个与点的出线方向垂直的矩形,其长度为 stylelineWidth 宽度的一半,宽度为 stylelineWidth 宽度。

    没有出线的点必须放置两个背靠背的帽,就像它实际上是由一个方向性为该点方向的无限短直线连接的两个点。

    连接:除了连接点本身,每个连接点还涉及两个额外的点,每条线各一个:在连接点半线宽远处的两个角之一,每条线垂直的方向,每个在线条最远的一侧。

    必须在所有连接点处添加一个连接这两个相对角与连接点的三角形。在连接点渲染的其他内容由 lineJoin 属性控制。上述三个值有以下含义:

    "bevel" 值意味着在连接处仅渲染上述内容。

    "round" 值意味着必须在连接处添加一个连接上述角的弧,与上述三角形相接(而非重叠),直径等于线宽,起点为连接点。

    "miter" 值意味着在连接处必须(如果可能的话,给定斜接长度)添加第二个三角形,一条线是上述两个角之间的线,与第一个三角形相接,另一条线是连接线的外边缘的延伸,直到相交而不超过斜接长度。

    斜接长度是从连接点到连接外边缘相交点的距离。斜接限制比率是斜接长度与线宽一半的最大允许比率。如果斜接长度导致斜接限制比率(由 stylemiterLimit 属性设置)被超过,则不得添加第二个三角形。

    新创建路径中的子路径必须以这样的方式排列,以便对于任何点,如果从该点绘制的半无限直线与子路径相交的次数是偶数,当且仅当从该点绘制的半无限直线与子路径相交的次数与子路径在另一个方向上的相交次数相等。

  10. 返回新创建的路径。

4.12.5.1.4 文字样式
context.font [ = value ]

CanvasRenderingContext2D/font

Support in all current engines.

Firefox3.5+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
styles.font [ = value ]

返回当前字体设置。

可以设置以更改字体。语法与 CSS 'font' 属性相同;无法解析为 CSS 字体值的值将被忽略。

相对关键字和长度是相对于 canvas 元素的字体计算的。

context.textAlign [ = value ]

CanvasRenderingContext2D/textAlign

Support in all current engines.

Firefox3.5+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
styles.textAlign [ = value ]

返回当前文本对齐设置。

可以设置以更改对齐方式。可能的值及其含义如下所示。其他值将被忽略。默认值是 "start"。

context.textBaseline [ = value ]

CanvasRenderingContext2D/textBaseline

Support in all current engines.

Firefox3.5+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
styles.textBaseline [ = value ]

返回当前基线对齐设置。

可以设置以更改基线对齐。可能的值及其含义如下所示。其他值将被忽略。默认值是 "alphabetic"。

context.direction [ = value ]

CanvasRenderingContext2D/direction

Support in all current engines.

Firefox101+Safari9+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
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]

  1. 如果 object字体样式源对象 是一个 canvas 元素,返回该元素的 节点文档

  2. 否则,object字体样式源对象 是一个 OffscreenCanvas 对象:

    1. global 成为 object相关全局对象

    2. 如果 global 是一个 Window 对象,则返回 global关联的 Document

    3. 断言global 实现了 WorkerGlobalScope

    4. 返回 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 为 c2canvas 元素,它被如下转移到一个 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' 组件被设置为使用百分比、emex 单位,或 '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.

FirefoxNoSafariNoChrome99+
Opera?Edge99+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

letterSpacing getter 步骤是返回 序列化形式 this's letter spacing

letterSpacing setter 步骤是:

  1. parsed解析 给定值作为 CSS <length> 的结果。

  2. 如果 parsed 失败,则返回。

  3. 设置 this's letter spacingparsed

CanvasRenderingContext2D/wordSpacing

Support in one engine only.

FirefoxNoSafariNoChrome99+
Opera?Edge99+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

wordSpacing getter 步骤是返回 序列化形式 this's word spacing

wordSpacing setter 步骤是:

  1. parsed解析 给定值作为 CSS <length> 的结果。

  2. 如果 parsed 失败,则返回。

  3. 设置 this's word spacingparsed

CanvasRenderingContext2D/fontKerning

Firefox104+SafariNoChrome99+
Opera?Edge99+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

fontKerning IDL 属性,在获取时,必须返回当前值。在设置时,当前值必须更改为新值。当实现 CanvasTextDrawingStyles 接口的对象被创建时,fontKerning 属性最初必须具有值 "auto"。

CanvasRenderingContext2D/fontStretch

Support in one engine only.

FirefoxNoSafariNoChrome99+
Opera?Edge99+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

fontStretch IDL 属性,在获取时,必须返回当前值。在设置时,当前值必须更改为新值。当实现 CanvasTextDrawingStyles 接口的对象被创建时,fontStretch 属性最初必须具有值 "normal"。

CanvasRenderingContext2D/fontVariantCaps

Support in one engine only.

FirefoxNoSafariNoChrome99+
Opera?Edge99+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

fontVariantCaps IDL 属性,在获取时,必须返回当前值。在设置时,当前值必须更改为新值。当实现 CanvasTextDrawingStyles 接口的对象被创建时,fontVariantCaps 属性最初必须具有值 "normal"。

CanvasRenderingContext2D/textRendering

Support in one engine only.

FirefoxNoSafariNoChrome99+
Opera?Edge99+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

textRendering IDL 属性,在获取时,必须返回当前值。在设置时,当前值必须更改为新值。当实现 CanvasTextDrawingStyles 接口的对象被创建时,textRendering 属性最初必须具有值 "auto"。

textAlign 属性允许的关键词如下:

start

对齐到文本的起始边(从左到右文本的左侧,从右到左文本的右侧)。

end

对齐到文本的结束边(从左到右文本的右侧,从右到左文本的左侧)。

left

对齐到左侧。

right

对齐到右侧。

center

对齐到中心。

textBaseline 属性允许的关键词对应于字体中的对齐点:

The top of the em square is roughly at the top of the glyphs in a font, the hanging baseline is where some glyphs like आ are anchored, the middle is half-way between the top of the em square and the bottom of the em square, the alphabetic baseline is where characters like Á, ÿ, f, and Ω are anchored, the ideographic-under baseline is where glyphs like 私 and 達 are anchored, and the bottom of the em square is roughly at the bottom of the glyphs in a font. The top and bottom of the bounding box can be far from these baselines, due to glyphs extending far outside the em square.

关键词与这些对齐点的对应关系如下:

top
em 方框的顶部
hanging
悬挂基线
middle
em 方框的中间
alphabetic
字母基线
ideographic
表意文字下基线
bottom
em 方框的底部

direction 属性允许的关键词如下:

ltr

将输入视为从左到右的文本。

rtl

将输入视为从右到左的文本。

inherit

默认为 canvas 元素或 Document 的方向性。

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 alignmentinline box。)

  1. 如果提供了 maxWidth 但其小于或等于零或等于 NaN,则返回一个空数组。

  2. text 中的所有 ASCII 空白字符 替换为 U+0020 空格字符。

  3. fonttarget 的当前字体,由该对象的 font 属性给出。

  4. 应用以下列表中的适当步骤来确定 direction 的值:

    如果 target 对象的 direction 属性的值为 "ltr"
    direction 为 'ltr'。
    如果 target 对象的 direction 属性的值为 "rtl"
    direction 为 'rtl'。
    如果 target 对象的 font style source object 是一个元素
    direction方向性 target 对象的 font style source object
    如果 target 对象的 font style source object 是一个 Document 且具有非空 document element
    direction方向性 target 对象的 font style source objectdocument element
    否则
    direction 为 'ltr'。
  5. 形成一个假设的无限宽 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

    并将所有其他属性设置为初始值。

  6. 如果提供了 maxWidth 并且假设的 inline box 在假设的 line box 中的宽度大于 maxWidth CSS 像素,则将 font 更改为具有更紧凑的字体(如果有可用的或通过对字体应用水平缩放因子可以合理地合成一个)或更小的字体,并返回到上一步。

  7. anchor pointinline box 上的一个点,并且 physical alignmentleft, right, 和 center 之一。这些变量由 textAligntextBaseline 的值确定如下:

    水平位置:

    如果 textAlignleft
    如果 textAlignstart 并且 direction 为 ltr
    如果 textAlignend 并且 direction 为 rtl
    anchor point 的水平位置为 inline box 的左边缘,并令 physical alignmentleft
    如果 textAlignright
    如果 textAlignend 并且 direction 为 ltr
    如果 textAlignstart 并且 direction 为 rtl
    anchor point 的水平位置为 inline box 的右边缘,并令 physical alignmentright
    如果 textAligncenter
    anchor point 的水平位置为 inline box 的左边缘和右边缘之间的一半,并令 physical alignmentcenter

    垂直位置:

    如果 textBaselinetop
    anchor point 的垂直位置为 第一个可用字体 的 em 方框顶部。
    如果 textBaselinehanging
    anchor point 的垂直位置为 悬挂基线第一个可用字体inline box
    如果 textBaselinemiddle
    anchor point 的垂直位置为 第一个可用字体 的 em 方框底部和顶部之间的一半。
    如果 textBaselinealphabetic
    anchor point 的垂直位置为 字母基线第一个可用字体inline box
    如果 textBaselineideographic
    anchor point 的垂直位置为 表意文字下基线第一个可用字体inline box
    如果 textBaselinebottom
    anchor point 的垂直位置为 第一个可用字体 的 em 方框底部。
  8. result 为通过从左到右迭代 inline box 中的每个字符(如果有),并为每个字符添加其在 inline box 中的形状构造的数组,并在一个坐标空间中定位,使用 CSS 像素 其原点在 anchor point

  9. 返回 resultphysical alignment 和 inline box。

4.12.5.1.5 创建路径

实现 CanvasPath 接口的对象有一个 路径路径有一个或多个子路径的列表。每个子路径由一个或多个点组成,这些点由直线或曲线 线段连接,并有一个标志指示子路径是否关闭。关闭的子路径是指子路径的最后一个点通过一条直线连接到子路径的第一个点。只有一个点的子路径在绘制路径时会被忽略。

路径有一个 需要新子路径 标志。当此标志被设置时,某些 API 会创建一个新的子路径,而不是扩展前一个子路径。当 路径 被创建时,其 需要新子路径 标志必须被设置。

当创建实现 CanvasPath 接口的对象时,其 路径 必须初始化为零个子路径。

context.moveTo(x, y)

CanvasRenderingContext2D/moveTo

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
path.moveTo(x, y)

创建一个包含给定点的新子路径。

context.closePath()

CanvasRenderingContext2D/closePath

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
path.closePath()

将当前子路径标记为关闭,并以相同的起点和终点开始一个新子路径。

context.lineTo(x, y)

CanvasRenderingContext2D/lineTo

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
path.lineTo(x, y)

将给定点添加到当前子路径,连接到先前的点通过一条直线。

context.quadraticCurveTo(cpx, cpy, x, y)

CanvasRenderingContext2D/quadraticCurveTo

Support in all current engines.

Firefox1.5+Safari3+Chrome1+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12+
path.quadraticCurveTo(cpx, cpy, x, y)

将给定点添加到当前子路径,连接到先前的点通过一条二次贝塞尔曲线并带有给定的控制点。

context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

CanvasRenderingContext2D/bezierCurveTo

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
path.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

将给定点添加到当前子路径,连接到先前的点通过一条三次贝塞尔曲线并带有给定的控制点。

context.arcTo(x1, y1, x2, y2, radius)

CanvasRenderingContext2D/arcTo

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
path.arcTo(x1, y1, x2, y2, radius)

将给定的控制点和半径的弧添加到当前子路径,通过直线连接到先前的点。

如果给定的半径为负,则抛出 "IndexSizeError" DOMException

context.arc(x, y, radius, startAngle, endAngle [, counterclockwise ])

CanvasRenderingContext2D/arc

Support in all current engines.

Firefox1.5+Safari3+Chrome1+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12+
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.

Firefox48+Safari9+Chrome31+
Opera?Edge79+
Edge (旧版)13+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
path.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle [, counterclockwise])

将点添加到子路径中,使由参数描述的椭圆的圆周的弧,从给定的起始角开始并在给定的终止角结束,按给定的方向(默认为顺时针)添加到路径中,通过直线连接到先前的点。

如果给定的半径为负,则抛出 "IndexSizeError" DOMException

context.rect(x, y, w, h)

CanvasRenderingContext2D/rect

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
path.rect(x, y, w, h)

向路径添加一个新闭合子路径,表示给定的矩形。

context.roundRect(x, y, w, h, radii)
path.roundRect(x, y, w, h, radii)

向路径添加一个新闭合子路径,表示给定的圆角矩形。radii 是一个表示矩形角的半径的列表或单个半径,以像素为单位。如果提供列表,则这些半径的数量和顺序与 CSS 'border-radius' 属性相同。单个半径的行为与仅有一个元素的列表相同。

如果 wh 都大于或等于 0,或者如果两者都小于 0,则路径按顺时针方向绘制。否则,按逆时针方向绘制。

w 为负时,圆角矩形水平翻转,这意味着通常适用于左角的半径值用于右角,反之亦然。同样,当 h 为负时,圆角矩形垂直翻转。

radii 中的值 r 为数字时,相应的角以半径 r 绘制为圆弧。

radii 中的值 r 为具有 { x, y } 属性的对象时,相应的角绘制为椭圆弧,其 xy 半径分别等于 r.xr.y

当同一边缘的两个角的 radii 之和大于边缘长度时,所有圆角矩形的 radii 都按比例因子长度 / (r1 + r2) 缩放。如果多个边缘具有此属性,则使用比例因子最小的边缘的比例因子。这与 CSS 行为一致。

如果 radii 是大小不是一、二、三或四的列表,则抛出 RangeError

如果 radii 中的值为负数,或者是 { x, y } 对象,其 xy 属性为负数,则抛出 RangeError

以下方法允许作者操作实现 路径 的对象,这些对象实现了 CanvasPath 接口。

对于实现 CanvasDrawPathCanvasTransform 接口的对象,传递给方法的点,以及这些方法添加到 当前默认路径 的结果线,必须在添加到路径之前根据 当前变换矩阵 进行变换。

moveTo(x, y) 方法在调用时,必须运行以下步骤:

  1. 如果任一参数为无限或 NaN,则返回。

  2. 创建一个以指定点为其第一个(也是唯一一个)点的新子路径。

当用户代理为 确保有一个子路径 为坐标 (x, y) 在 路径 上时,用户代理必须检查路径是否设置了其 需要新子路径 标志。如果设置了,则用户代理必须创建一个以点 (x, y) 为第一个(也是唯一一个)点的新子路径,就像调用了 moveTo() 方法一样,然后必须取消设置路径的 需要新子路径 标志。

closePath() 方法在调用时,如果对象的路径没有子路径,则不做任何操作。否则,它必须将最后一个子路径标记为关闭,创建一个新子路径,其第一个点与先前子路径的第一个点相同,最后将此新子路径添加到路径中。

如果最后一个子路径在其点列表中有多个点,则这相当于添加一条将最后一个点连接回最后一个子路径的第一个点的直线,从而“关闭”子路径。


使用以下描述的方法将新点和连接它们的线添加到子路径中。在所有情况下,这些方法只修改对象路径中的最后一个子路径。

lineTo(x, y) 方法在调用时,必须运行以下步骤:

  1. 如果任一参数为无限或 NaN,则返回。

  2. 如果对象的路径没有子路径,则 确保有一个子路径 为 (x, y)。

  3. 否则,使用一条直线将子路径中的最后一个点连接到给定点 (x, y),然后将给定点 (x, y) 添加到子路径中。

quadraticCurveTo(cpx, cpy, x, y) 方法在调用时,必须运行以下步骤:

  1. 如果任一参数为无限或 NaN,则返回。

  2. 确保有一个子路径 为 (cpx, cpy)。

  3. 使用控制点 (cpx, cpy) 将子路径中的最后一个点连接到给定点 (x, y),使用二次贝塞尔曲线。[BEZIER]

  4. 将给定点 (x, y) 添加到子路径中。

bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) 方法在调用时,必须运行以下步骤:

  1. 如果任一参数为无限或 NaN,则返回。

  2. 确保有一个子路径 为 (cp1x, cp1y)。

  3. 使用控制点 (cp1x, cp1y) 和 (cp2x, cp2y) 将子路径中的最后一个点连接到给定点 (x, y),使用三次贝塞尔曲线。[BEZIER]

  4. 将点 (x, y) 添加到子路径中。


arcTo(x1, y1, x2, y2, radius) 方法在调用时,必须运行以下步骤:

  1. 如果任一参数为无限或 NaN,则返回。

  2. 确保有一个子路径 为 (x1, y1)。

  3. 如果 radius 为负,则抛出 "IndexSizeError" DOMException

  4. 令点 (x0, y0) 为子路径中的最后一个点,通过 当前变换矩阵 的逆变换(以使其与传递给方法的点在同一坐标系中)。

  5. 如果点 (x0, y0) 等于点 (x1, y1),或者如果点 (x1, y1) 等于点 (x2, y2),或者如果 radius 为零,则将点 (x1, y1) 添加到子路径中,并通过直线将该点连接到前一个点 (x0, y0)。

  6. 否则,如果点 (x0, y0),(x1, y1) 和 (x2, y2) 全部在一条直线上,则将点 (x1, y1) 添加到子路径中,并通过直线将该点连接到前一个点 (x0, y0)。

  7. 否则,令 The Arc 为圆的周长所给出的最短弧,圆具有半径 radius,并且在点 (x0, y0) 和点 (x1, y1) 之间有一个点与该圆的半无限线相切,且在点 (x1, y1) 和点 (x2, y2) 之间有一个点与该圆的另一条半无限线相切。将点 (x0, y0) 连接到起始切点,通过一条直线添加起始切点到子路径中,然后将起始切点连接到终点切点,通过 The Arc 添加终点切点到子路径中。


arc(x, y, radius, startAngle, endAngle, counterclockwise) 方法在调用时,必须运行 椭圆方法步骤,并传递此参数、xyradiusradius、0、startAngleendAnglecounterclockwise

这使得它等效于 ellipse(),但两个半径相等且 rotation 为 0。

ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise) 方法在调用时,必须运行 椭圆方法步骤,并传递此参数、xyradiusXradiusYrotationstartAngleendAnglecounterclockwise

确定椭圆上的点步骤,给定 ellipseangle,如下:

  1. eccentricCircle 为与 ellipse 共享其原点的圆,其半径等于 ellipse 的半长轴。

  2. outerPoint 为在顺时针方向从 ellipse 的半长轴测量的 angle 角度的 eccentricCircle 的圆周上的点。

  3. chord 为在该轴与 outerPoint 之间垂直于 ellipse 的长轴的线。

  4. 返回在 chord 上穿过 ellipse 的圆周的点。

椭圆方法步骤,给定 canvasPathxyradiusXradiusYrotationstartAngleendAnglecounterclockwise,如下:

  1. 如果任一参数为无限或 NaN,则返回。

  2. 如果 radiusXradiusY 为负,则抛出 "IndexSizeError" DOMException

  3. 如果 canvasPath 的路径有任何子路径,则从子路径的最后一个点添加一条直线到弧的起点。

  4. 将弧的起点和终点添加到子路径中,并用一条弧连接它们。弧及其起点和终点定义如下:

    考虑一个椭圆,其原点在 (x, y),其长轴半径为 radiusX,短轴半径为 radiusY,并且绕其原点顺时针旋转 rotation 弧度,使其半长轴与 x 轴成 rotation 角度。

    如果 counterclockwise 为假且 endAnglestartAngle 大于或等于 ,或者如果 counterclockwise 为真且 startAngleendAngle 大于或等于 ,则弧是此椭圆的整个圆周,并且起点和终点是运行 确定椭圆上的点步骤 所得的结果,此椭圆和 startAngle

    否则,起点是运行 确定椭圆上的点步骤 所得的结果,此椭圆和 startAngle,终点是运行 确定椭圆上的点步骤 所得的结果,此椭圆和 endAngle,弧是从起点到终点的椭圆圆周的路径,逆时针方向如果 counterclockwise 为真,否则顺时针方向。由于点位于椭圆上,而不是简单的角度从零开始,弧的角度永远不会超过 弧度。

    即使弧覆盖了椭圆的整个圆周且子路径中没有其他点,除非适当调用 closePath() 方法,否则路径不会闭合。


rect(x, y, w, h) 方法在调用时,必须运行以下步骤:

  1. 如果任一参数为无限或 NaN,则返回。

  2. 创建一个仅包含四个点 (x, y), (x+w, y), (x+w, y+h), (x, y+h) 的新子路径,按该顺序,四个点通过直线连接。

  3. 将子路径标记为闭合。

  4. 创建一个以点 (x, y) 为唯一点的新子路径。

CanvasRenderingContext2D/roundRect

Support in all current engines.

Firefox112+Safari16+Chrome99+
Opera?Edge99+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

roundRect(x, y, w, h, radii) 方法步骤如下:

  1. 如果任一 xywh 为无限或 NaN,则返回。

  2. 如果 radiiunrestricted doubleDOMPointInit,则将 radii 设置为 « radii »。

  3. 如果 radii 不是大小为一、二、三或四的列表,则抛出 RangeError

  4. normalizedRadii 为一个空列表。

  5. 对于 radii 中的每个 radius

    1. 如果 radiusDOMPointInit

      1. 如果 radius["x"] 或 radius["y"] 为无限或 NaN,则返回。

      2. 如果 radius["x"] 或 radius["y"] 为负数,则抛出 RangeError

      3. 否则,将 radius 附加到 normalizedRadii

    2. 如果 radiusunrestricted double

      1. 如果 radius 为无限或 NaN,则返回。

      2. 如果 radius 为负数,则抛出 RangeError

      3. 否则,将 «[ "x" → radius, "y" → radius ]» 附加到 normalizedRadii

  6. upperLeftupperRightlowerRightlowerLeft 为 null。

  7. 如果 normalizedRadii 的大小为 4,则将 upperLeft 设置为 normalizedRadii[0],将 upperRight 设置为 normalizedRadii[1],将 lowerRight 设置为 normalizedRadii[2],并将 lowerLeft 设置为 normalizedRadii[3]。

  8. 如果 normalizedRadii 的 大小为 3,则将 upperLeft 设置为 normalizedRadii[0],将 upperRightlowerLeft 设置为 normalizedRadii[1],并将 lowerRight 设置为 normalizedRadii[2]。

  9. 如果 normalizedRadii 的大小为 2,则将 upperLeftlowerRight 设置为 normalizedRadii[0],并将 upperRightlowerLeft 设置为 normalizedRadii[1]。

  10. 如果 normalizedRadii 的大小为 1,则将 upperLeftupperRightlowerRightlowerLeft 设置为 normalizedRadii[0]。

  11. 角曲线不能重叠。按比例缩放所有半径以防止这种情况:

    1. topupperLeft["x"] + upperRight["x"]。

    2. rightupperRight["y"] + lowerRight["y"]。

    3. bottomlowerRight["x"] + lowerLeft["x"]。

    4. leftupperLeft["y"] + lowerLeft["y"]。

    5. scale 为比率 w / toph / rightw / bottomh / left 的最小值。

    6. 如果 scale 小于 1,则将 xy 成员设置为 upperLeftupperRightlowerLeftlowerRight 的当前值,乘以 scale

  12. 创建一个新子路径:

    1. 移动到点 (x + upperLeft["x"], y)。

    2. 画一条直线到点 (x + w - upperRight["x"], y)。

    3. 画一条弧到点 (x + wy + upperRight["y"])。

    4. 画一条直线到点 (x + wy + h - lowerRight["y"])。

    5. 画一条弧到点 (x + w - lowerRight["x"], y + h)。

    6. 画一条直线到点 (x + lowerLeft["x"], y + h)。

    7. 画一条弧到点 (x, y + h - lowerLeft["y"])。

    8. 画一条直线到点 (x, y + upperLeft["y"])。

    9. 画一条弧到点 (x + upperLeft["x"], y)。

  13. 将子路径标记为闭合。

  14. 创建一个以点 (x, y) 为唯一点的新子路径。

这旨在与 CSS 'border-radius' 属性的行为类似。

4.12.5.1.6 Path2D 对象

Path2D

所有当前引擎支持。

Firefox31+Safari8+Chrome36+
Opera?Edge79+
Edge (旧版)14+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Path2D 对象可用于声明路径,然后在实现 CanvasDrawPath 接口的对象上使用。除了前面章节中描述的许多 API 之外,Path2D 对象还有方法来组合路径,并将文本添加到路径中。

path = new Path2D()

Path2D/Path2D

所有当前引擎支持。

Firefox31+Safari8+Chrome36+
Opera?Edge79+
Edge (旧版)14+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

创建一个新的空的 Path2D 对象。

path = new Path2D(path)

pathPath2D 对象时,返回一个副本。

path 是一个字符串时,创建由参数描述的路径,解释为 SVG 路径数据。[SVG]

path.addPath(path [, transform ])

Path2D/addPath

所有当前引擎支持。

Firefox34+Safari9+Chrome68+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

将参数给定的路径添加到路径中。

Path2D(path) 构造函数被调用时,必须执行以下步骤:

  1. output 成为一个新的 Path2D 对象。

  2. 如果未给出 path,则返回 output

  3. 如果 pathPath2D 对象,则将 path 的所有子路径添加到 output,并返回 output。(换句话说,它返回参数的副本。)

  4. svgPath 成为根据 SVG 2 的路径数据规则解析和解释 path 的结果。[SVG]

    生成的路径可能是空的。SVG 定义了解析和应用路径数据的错误处理规则。

  5. 让 (x, y) 成为 svgPath 中的最后一个点。

  6. svgPath 中的所有子路径(如果有)添加到 output

  7. output 中创建一个新的子路径,其唯一点为 (x, y)。

  8. 返回 output


addPath(path, transform) 方法在 Path2D 对象 a 上被调用时,必须执行以下步骤:

  1. 如果 Path2D 对象 path 没有子路径,则返回。

  2. matrix 成为根据 2D 字典创建 DOMMatrix transform 的结果。

  3. 如果 matrix 的一个或多个m11 元素m12 元素m21 元素m22 元素m41 元素m42 元素是无穷大或 NaN,则返回。

  4. 创建 path 中所有子路径的副本。称此副本为 c

  5. 通过变换矩阵 matrix 变换 c 中的所有坐标和线。

  6. 让 (x, y) 成为 c 的最后一个子路径中的最后一个点。

  7. c 中的所有子路径添加到 a

  8. a 中创建一个新的子路径,其唯一点为 (x, y)。

4.12.5.1.7 变换

实现 CanvasTransform 接口的对象具有一个当前变换矩阵,以及操纵它的方法(在本节中描述)。当创建实现 CanvasTransform 接口的对象时,其变换矩阵必须初始化为单位矩阵。

当前变换矩阵在创建当前默认路径,以及在实现 CanvasTransform 接口的对象上绘制文本、形状和 Path2D 对象时应用于坐标。

变换必须以逆序执行。

例如,如果在画布上应用一个将宽度加倍的缩放变换,然后应用一个旋转变换使绘图操作旋转四分之一圈,然后在画布上绘制一个宽度是高度两倍的矩形,则实际结果将是一个正方形。

context.scale(x, y)

CanvasRenderingContext2D/scale

所有当前引擎支持。

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

更改 当前变换矩阵 以应用具有给定特征的缩放变换。

context.rotate(angle)

CanvasRenderingContext2D/rotate

所有当前引擎支持。

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

更改 当前变换矩阵 以应用具有给定特征的旋转变换。角度以弧度表示。

context.translate(x, y)

CanvasRenderingContext2D/translate

所有当前引擎支持。

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

更改 当前变换矩阵 以应用具有给定特征的平移变换。

context.transform(a, b, c, d, e, f)

CanvasRenderingContext2D/transform

所有当前引擎支持。

Firefox3+Safari3.1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

更改 当前变换矩阵 以应用如下所述的矩阵。

matrix = context.getTransform()

CanvasRenderingContext2D/getTransform

所有当前引擎支持。

Firefox70+Safari11.1+Chrome68+
Opera?Edge79+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回一个新创建的 DOMMatrix 对象,表示上下文的 当前变换矩阵 的副本。

context.setTransform(a, b, c, d, e, f)

CanvasRenderingContext2D/setTransform

所有当前引擎支持。

Firefox3+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

更改 当前变换矩阵 下文描述的参数给出的矩阵。

context.setTransform(transform)

更改 当前变换矩阵 传递的 DOMMatrix2DInit 字典表示的矩阵。

context.resetTransform()

CanvasRenderingContext2D/resetTransform

所有当前引擎支持。

Firefox36+Safari10.1+Chrome31+
Opera?Edge79+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

当前变换矩阵 重置为单位矩阵。

scale(x, y) 方法在调用时,必须运行以下步骤:

  1. 如果任一参数为无限或 NaN,则返回。

  2. 将参数描述的缩放变换添加到 当前变换矩阵x 参数表示水平方向的缩放因子,y 参数表示垂直方向的缩放因子。因子为倍数。

rotate(angle) 方法在调用时,必须运行以下步骤:

  1. 如果 angle 为无限或 NaN,则返回。

  2. 将参数描述的旋转变换添加到 当前变换矩阵angle 参数表示顺时针旋转角度,以弧度表示。

translate(x, y) 方法在调用时,必须运行以下步骤:

  1. 如果任一参数为无限或 NaN,则返回。

  2. 将参数描述的平移变换添加到 当前变换矩阵x 参数表示水平方向的平移距离,y 参数表示垂直方向的平移距离。参数以坐标空间单位表示。

transform(a, b, c, d, e, f) 方法在调用时,必须运行以下步骤:

  1. 如果任一参数为无限或 NaN,则返回。

  2. 当前变换矩阵 替换为与以下描述的矩阵相乘的结果:

    a c e
    b d f
    0 0 1

参数 a, b, c, d, ef 有时被称为 m11, m12, m21, m22, dxdym11, m21, m12, m22, dxdy。特别需要注意的是第二个和第三个参数(bc)的顺序,因为它们在不同的 API 中顺序不同,并且 API 有时使用 m12/m21 的表示法,有时使用 m21/m12 的表示法。

getTransform() 方法在调用时,必须返回一个新创建的 DOMMatrix 对象,表示上下文的 当前变换矩阵 的副本。

此返回的对象不是实时的,因此更新它不会影响 当前变换矩阵,更新 当前变换矩阵 也不会影响已经返回的 DOMMatrix

setTransform(a, b, c, d, e, f) 方法在调用时,必须运行以下步骤:

  1. 如果任一参数为无限或 NaN,则返回。

  2. 当前变换矩阵 重置为如下描述的矩阵:

    a c e
    b d f
    0 0 1

setTransform(transform) 方法在调用时,必须运行以下步骤:

  1. matrix 成为 从 2D 字典创建 DOMMatrix 的结果 transform

  2. 如果 matrix 的一个或多个m11 元素m12 元素m21 元素m22 元素m41 元素,或m42 元素是无限或 NaN,则返回。

  3. 当前变换矩阵 重置为 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

4.12.5.1.8 2D 渲染上下文的图像源

CanvasDrawImageCanvasFillStrokeStyles 接口上的某些方法将联合类型 CanvasImageSource 作为参数。

这种联合类型允许实现以下任一接口的对象用作图像源:

虽然未正式指定为这样,但 SVG image 元素预计将几乎与 img 元素实现相同。也就是说,SVG image 元素共享 img 元素的基本概念和功能。

ImageBitmap 接口可以从许多其他图像表示类型创建,包括 ImageData

要检查 image 参数的可用性,imageCanvasImageSource 对象,请执行以下步骤:

  1. 切换 image

    HTMLOrSVGImageElement

    如果 image当前请求状态损坏的,则抛出 "InvalidStateError" DOMException

    如果 image 不是 完全可解码的,则返回 bad

    如果 image 具有 自然宽度自然高度 (或两者) 等于零,则返回 bad

    HTMLVideoElement

    如果 imagereadyState 属性为 HAVE_NOTHINGHAVE_METADATA,则返回 bad

    HTMLCanvasElement
    OffscreenCanvas

    如果 image 的水平尺寸或垂直尺寸等于零,则抛出 "InvalidStateError" DOMException

    ImageBitmap
    VideoFrame

    如果 image[[Detached]] 内部槽值设置为 true,则抛出 "InvalidStateError" DOMException

  2. 返回 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。

4.12.5.1.9 填充和描边样式
context.fillStyle [ = value ]

CanvasRenderingContext2D/fillStyle

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回用于填充形状的当前样式。

可以设置,以更改填充样式

样式可以是包含 CSS 颜色的字符串,也可以是CanvasGradientCanvasPattern对象。无效值会被忽略。

context.strokeStyle [ = value ]

CanvasRenderingContext2D/strokeStyle

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回用于描边形状的当前样式。

可以设置,以更改描边样式

样式可以是包含 CSS 颜色的字符串,也可以是CanvasGradientCanvasPattern对象。无效值会被忽略。

实现CanvasFillStrokeStyles接口的对象具有属性和方法(在本节定义),用于控制对象如何处理形状。

这些对象有相关的填充样式描边样式值,这些值可以是 CSS 颜色、CanvasPatternCanvasGradient。最初,这两个值都必须是解析字符串"#000000"的结果。

当值是 CSS 颜色时,用于在位图上绘制时不得受变换矩阵的影响。

当设置为CanvasPatternCanvasGradient对象时,赋值后的对象的更改会影响形状的后续描边或填充。

fillStyle取值器步骤如下:

  1. 如果this填充样式是一个CSS颜色,那么返回该颜色的序列化,并请求HTML兼容的序列化

  2. 返回this填充样式

fillStyle设值器步骤如下:

  1. 如果给定的值是字符串,则:

    1. contextthiscanvas属性的值,如果是元素;否则为 null。

    2. parsedValue解析给定值与context的结果,如果非 null。

    3. 如果parsedValue失败,则返回。

    4. 设置this填充样式parsedValue

    5. 返回。

  2. 如果给定的值是标记为非来源干净CanvasPattern对象,则设置this来源干净标志为 false。

  3. 设置this填充样式为给定值。

strokeStyle取值器步骤如下:

  1. 如果this描边样式是一个CSS颜色,那么返回该颜色的序列化,并请求HTML兼容的序列化

  2. 返回this描边样式

strokeStyle设值器步骤如下:

  1. 如果给定的值是字符串,则:

    1. contextthiscanvas属性的值,如果是元素;否则为 null。

    2. parsedValue解析给定值与context的结果,如果非 null。

    3. 如果parsedValue失败,则返回。

    4. 设置this描边样式parsedValue

    5. 返回。

  2. 如果给定的值是标记为非来源干净CanvasPattern对象,则设置this来源干净标志为 false。

  3. 设置this描边样式为给定值。


有三种类型的渐变,线性渐变、径向渐变和锥形渐变,由实现不透明CanvasGradient接口的对象表示。

一旦创建了渐变(见下文),在渐变上放置停止点以定义颜色如何沿渐变分布。每个停止点的渐变颜色是为该停止点指定的颜色。在每个停止点之间,必须在线性插值的 RGBA 空间内找到用于该偏移量的颜色,而不预乘 alpha 值。在第一个停止点之前,颜色必须是第一个停止点的颜色。在最后一个停止点之后,颜色必须是最后一个停止点的颜色。当没有停止点时,渐变是透明黑色

gradient.addColorStop(offset, color)

CanvasGradient/addColorStop

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

在给定的偏移量处使用给定的颜色为渐变添加一个颜色停止点。0.0 是渐变一端的偏移量,1.0 是渐变另一端的偏移量。

如果偏移量超出范围,则抛出"IndexSizeError"DOMException。如果颜色无法解析,则抛出"SyntaxError"DOMException

gradient = context.createLinearGradient(x0, y0, x1, y1)

CanvasRenderingContext2D/createLinearGradient

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回表示沿由参数表示的坐标线绘制的线性渐变的CanvasGradient对象。

gradient = context.createRadialGradient(x0, y0, r0, x1, y1, r1)

CanvasRenderingContext2D/createRadialGradient

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回表示沿由参数表示的圆锥绘制的径向渐变的CanvasGradient对象。

如果任一半径为负,则抛出"IndexSizeError"DOMException异常。

gradient = context.createConicGradient(startAngle, x, y)

CanvasRenderingContext2D/createConicGradient

Support in all current engines.

Firefox112+Safari16.1+Chrome99+
Opera?Edge99+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回表示沿由参数表示的中心旋转顺时针绘制的锥形渐变的CanvasGradient对象。

addColorStop(offset, color)方法在CanvasGradient上调用时,必须运行以下步骤:

  1. 如果offset小于 0 或大于 1,则抛出"IndexSizeError"DOMException

  2. parsed color解析color的结果。

    不传递元素给解析器,因为CanvasGradient对象是canvas中立的——一个CanvasGradient对象由一个canvas创建,可以被另一个使用,因此在指定颜色时无法知道哪个是“相关元素”。

  3. 如果parsed color失败,则抛出"SyntaxError"DOMException

  4. 在渐变上添加一个新的停止点,偏移量为offset,颜色为parsed color

    如果在渐变的同一偏移量处添加多个停止点,则它们必须按添加顺序排列,第一个最接近渐变的起点,后续的每一个都在此步骤中相对于该点向终点方向无穷小地移动(实际上导致除第一个和最后一个停止点之外的所有停止点都被忽略)。

createLinearGradient(x0, y0, x1, y1)方法接受四个参数,表示渐变的起点(x0y0)和终点(x1y1)。方法在调用时,必须返回一个用指定线初始化的线性CanvasGradient

线性渐变必须以这样的方式渲染:所有在穿过起点和终点的线垂直线上的点的颜色在这些两条线相交的点上具有该点的颜色(颜色来自于上述插值和外推)。在渲染时,线性渐变中的点必须按照当前变换矩阵描述的方式进行变换。

如果x0 = x1y0 = y1,则线性渐变不绘制任何内容。

createRadialGradient(x0, y0, r0, x1, y1, r1)方法接受六个参数,前三个表示起始圆的原点(x0y0)和半径r0,后三个表示终止圆的原点(x1y1)和半径r1。这些值以坐标空间单位表示。如果r0r1为负,则必须抛出"IndexSizeError"DOMException。否则,方法在调用时,必须返回一个用指定圆初始化的径向CanvasGradient

径向渐变必须通过以下步骤渲染:

  1. 如果x0 = x1y0 = y1r0 = r1,则径向渐变不绘制任何内容。返回。

  2. 设x(ω) = (x1 - x0)ω + x0

    设y(ω) = (y1 - y0)ω + y0

    设r(ω) = (r1 - r0)ω + r0

    设在ω处的颜色为该渐变上该位置的颜色(颜色来自于上述插值和外推)。

  3. 对于所有ω值,其中r(ω) > 0,从最接近正无穷的ω值开始,到最接近负无穷的ω值结束,绘制半径为r(ω)的圆的圆周,位置为(x(ω),y(ω)),颜色为ω处的颜色,但仅在之前步骤中此渐变渲染未绘制的位图部分上绘制。

这实际上创建了一个由定义渐变的两个圆接触的圆锥,圆锥前面的部分(0.0)使用第一个停止点的颜色,圆锥后面的部分(1.0)使用最后一个停止点的颜色,圆锥外部的区域未受渐变影响(透明黑色)。

然后在渲染时,必须按照当前变换矩阵描述的方式变换结果的径向渐变。

createConicGradient(startAngle, x, y)方法接受三个参数,第一个参数startAngle表示渐变开始的角度(以弧度表示),最后两个参数(xy)表示CSS 像素中渐变的中心。方法在调用时,必须返回一个用指定中心和角度初始化的锥形CanvasGradient

它遵循与 CSS 'conic-gradient'相同的渲染规则,并且等同于 CSS 'conic-gradient(from adjustedStartAnglerad at xpx ypx, angularColorStopList)'。其中:

渐变必须仅在相关描边或填充效果要求绘制它们的地方绘制。


图案由实现不透明CanvasPattern接口的对象表示。

pattern = context.createPattern(image, repetition)

CanvasRenderingContext2D/createPattern

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回一个使用给定图像并在由repetition参数给定的方向重复的CanvasPattern对象。

repetition的允许值为repeat(两个方向)、repeat-x(仅水平)、repeat-y(仅垂直)和no-repeat(都不)。如果repetition参数为空,则使用值repeat

如果图像尚未完全解码,则不会绘制任何内容。如果图像是没有数据的画布,则抛出"InvalidStateError"DOMException

pattern.setTransform(transform)

CanvasPattern/setTransform

Support in all current engines.

Firefox33+Safari11.1+Chrome68+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

设置在填充或描边绘制操作期间渲染图案时使用的变换矩阵。

createPattern(image, repetition)方法在调用时,必须运行以下步骤:

  1. usability检查图像参数 的可用性image的结果。

  2. 如果usability为坏,则返回 null。

  3. 断言usability为好。

  4. 如果repetition为空字符串,则将其设置为"repeat"。

  5. 如果repetition等同于之一"repeat"、"repeat-x"、"repeat-y"或"no-repeat",则抛出"SyntaxError"DOMException

  6. pattern为一个新的CanvasPattern对象,图像为image,重复行为由repetition给出。

  7. 如果image不是来源干净的,则将pattern标记为不是来源干净

  8. 返回pattern

在调用createPattern()方法后,修改创建CanvasPattern对象时使用的image不得影响CanvasPattern对象呈现的图案。

图案具有变换矩阵,该矩阵控制在绘制图案时如何使用图案。最初,图案的变换矩阵必须是单位矩阵。

setTransform(transform)方法在调用时,必须运行以下步骤:

  1. matrix从 2D 字典创建DOMMatrixtransform的结果。

  2. 如果matrix的一个或多个m11 元素m12 元素m21 元素m22 元素m41 元素m42 元素为无穷大或 NaN,则返回。

  3. 将图案的变换矩阵重置为matrix

当在一个区域内渲染图案时,用户代理必须运行以下步骤来确定渲染内容:

  1. 创建一个无限的透明黑色位图。

  2. 在位图上放置图像的副本,锚定使其左上角位于坐标空间的原点,每个坐标空间单位对应图像的一个CSS 像素,然后如果重复行为为"repeat-x",则在位图上水平放置重复图像,或者如果重复行为为"repeat-y",则在位图上垂直放置重复图像,或者如果重复行为为"repeat",则在位图的所有方向上放置重复图像。

    如果原始图像数据是位图图像,则在重复区域的某一点上绘制的值是通过滤镜原始图像数据计算的。当放大时,如果imageSmoothingEnabled属性设置为 false,则必须使用最近邻插值渲染图像。否则,用户代理可以使用任何滤镜算法(例如双线性插值或最近邻)。支持多种滤镜算法的用户代理可以使用imageSmoothingQuality属性的值来指导选择滤镜算法。当这样的滤镜算法需要原始图像数据之外的像素值时,必须使用该像素的坐标相对于原始图像的尺寸进行包装的值。(即,滤镜使用“重复”行为,而不管图案的重复行为是什么。)

  3. 根据图案的变换矩阵变换生成的位图。

  4. 再次变换生成的位图,这次根据当前变换矩阵

  5. 将图案渲染区域之外的图像部分替换为透明黑色

  6. 生成的位图是要渲染的内容,具有相同的原点和相同的比例。


如果在变换矩阵为奇异时使用径向渐变或重复图案,则结果样式必须为透明黑色(否则渐变或图案将折叠为一个点或线,留下其他像素未定义)。线性渐变和实心颜色即使在变换矩阵为奇异时也总是定义所有点。

4.12.5.1.10 将矩形绘制到位图

实现CanvasRect接口的对象提供了以下方法,用于立即将矩形绘制到位图。这些方法每个都接受四个参数;前两个给出矩形左上角的xy坐标,后两个分别给出矩形的宽度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.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

将给定矩形内的所有像素清除为透明黑色

context.fillRect(x, y, w, h)

CanvasRenderingContext2D/fillRect

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

使用当前填充样式将给定矩形绘制到位图上。

context.strokeRect(x, y, w, h)

CanvasRenderingContext2D/strokeRect

Support in all current engines.

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

使用当前描边样式将给定矩形的外框绘制到位图上。

clearRect(x, y, w, h)方法在调用时,必须执行以下步骤:

  1. 如果任何参数是无限或NaN,则返回。

  2. pixels为在指定矩形中也与当前剪裁区域相交的像素集。

  3. pixels中的像素清除为透明黑色,擦除任何以前的图像。

如果高度或宽度为零,此方法无效,因为像素集将为空。

fillRect(x, y, w, h)方法在调用时,必须执行以下步骤:

  1. 如果任何参数是无限或NaN,则返回。

  2. 如果wh为零,则返回。

  3. 使用this填充样式绘制指定的矩形区域。

strokeRect(x, y, w, h)方法在调用时,必须执行以下步骤:

  1. 如果任何参数是无限或NaN,则返回。

  2. 采用描绘路径所描述路径的结果,使用CanvasPathDrawingStyles接口的线样式填充它,并使用this描边样式

如果wh均为零,则路径有一个子路径,只有一个点(x, y),没有线,此方法因此无效(在这种情况下,描绘路径算法返回一个空路径)。

如果wh之一为零,则路径有一个由两个点组成的子路径,坐标为(x, y)和(x+w, y+h),按该顺序连接的一条直线。

否则,路径有一个由四个点组成的子路径,坐标为(x, y),(x+w, y),(x+w, y+h),和(x, y+h),按该顺序由直线连接。

4.12.5.1.11 绘制文本到位图

CanvasRenderingContext2D

支持所有当前的引擎。

Firefox1.5+Safari2+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
context.fillText(text, x, y [, maxWidth ])

CanvasRenderingContext2D/fillText

支持所有当前的引擎。

Firefox3.5+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
context.strokeText(text, x, y [, maxWidth ])

CanvasRenderingContext2D/strokeText

支持所有当前的引擎。

Firefox3.5+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

分别填充或描边给定位置的文本。如果提供了最大宽度,文本将根据需要缩放以适应该宽度。

metrics = context.measureText(text)

CanvasRenderingContext2D/measureText

支持所有当前的引擎 。

Firefox3.5+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回一个TextMetrics对象,包含给定文本在当前字体中的度量信息。

metrics.width

TextMetrics/width

支持所有当前的引擎。

Firefox1.5+Safari4+Chrome2+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android31+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
metrics.actualBoundingBoxLeft

TextMetrics/actualBoundingBoxLeft

支持所有当前的引擎。

Firefox74+Safari11.1+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
metrics.actualBoundingBoxRight

TextMetrics/actualBoundingBoxRight

支持所有当前的引擎。

Firefox74+Safari11.1+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
metrics.fontBoundingBoxAscent

TextMetrics/fontBoundingBoxAscent

支持所有当前的引擎。

Firefox116+Safari11.1+Chrome87+
Opera?Edge87+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
metrics.fontBoundingBoxDescent

TextMetrics/fontBoundingBoxDescent

支持所有当前的引擎。

Firefox116+Safari11.1+Chrome87+
Opera?Edge87+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
metrics.actualBoundingBoxAscent

TextMetrics/actualBoundingBoxAscent

支持所有当前的引擎。

Firefox74+Safari11.1+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
metrics.actualBoundingBoxDescent

TextMetrics/actualBoundingBoxDescent

支持所有当前的引擎。

Firefox74+Safari11.1+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
metrics.emHeightAscent

TextMetrics/emHeightAscent

支持所有当前的引擎。

🔰 74+Safari11.1+🔰 35+
Opera?🔰 79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
metrics.emHeightDescent

TextMetrics/emHeightDescent

支持所有当前的引擎。

🔰 74+Safari11.1+🔰 35+
Opera?🔰 79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
metrics.hangingBaseline

TextMetrics/hangingBaseline

🔰 74+Safari11.1+ChromeNo
Opera?EdgeNo
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
metrics.alphabeticBaseline

TextMetrics/alphabeticBaseline

🔰 74+Safari11.1+ChromeNo
Opera?EdgeNo
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
metrics.ideographicBaseline

TextMetrics/ideographicBaseline

🔰 74+Safari11.1+ChromeNo
Opera?EdgeNo
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回以下描述的度量值。

实现CanvasText接口的对象提供以下方法来渲染文本。

fillText(text, x, y, maxWidth)strokeText(text, x, y, maxWidth) 方法在指定的 (x, y) 坐标处渲染给定的 text,确保文本的宽度不会超过 maxWidth(如果指定),使用当前的fonttextAligntextBaseline 值。具体来说,当调用这些方法时,用户代理必须执行以下步骤:

  1. 如果任何参数是无限或 NaN,则返回。

  2. 运行文本准备算法,传递给它text,实现CanvasText接口的对象,以及(如果提供)maxWidth 参数。令glyphs为结果。

  3. glyphs中的所有形状向右移动x CSS 像素,向下移动y CSS 像素

  4. 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 属性

内联框的宽度,以CSS 像素为单位。(文本的前进宽度。)

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 渲染的文档片段直接渲染到画布的方法。这将优先于提供多行布局的专用方法。

4.12.5.1.12 绘制路径到画布

实现 CanvasDrawPath 接口的对象具有一个当前默认路径。只有一个当前默认路径,它不是绘图状态的一部分。当前默认路径是一个路径,如上所述。

context.beginPath()

CanvasRenderingContext2D/beginPath

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

重置当前默认路径

context.fill([ fillRule ])

CanvasRenderingContext2D/fill

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
context.fill(path [, fillRule ])

使用当前填充样式根据给定的填充规则填充当前默认路径或给定路径的子路径。

context.stroke()

CanvasRenderingContext2D/stroke

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
context.stroke(path)

使用当前描边样式对当前默认路径或给定路径的子路径进行描边。

context.clip([ fillRule ])

CanvasRenderingContext2D/clip

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
context.clip(path [, fillRule ])

进一步使用给定填充规则约束裁剪区域到当前默认路径或给定路径。

context.isPointInPath(x, y [, fillRule ])

CanvasRenderingContext2D/isPointInPath

支持所有当前引擎。

Firefox2+Safari3.1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
context.isPointInPath(path, x, y [, fillRule ])

如果给定点位于当前默认路径或给定路径的区域内,则返回true,使用给定的填充规则来确定路径内的点。

context.isPointInStroke(x, y)

CanvasRenderingContext2D/isPointInStroke

支持所有当前引擎。

Firefox19+Safari7+Chrome26+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
context.isPointInStroke(path, x, y)

如果给定点位于使用当前描边样式描边后的当前默认路径或给定路径的区域内,则返回true。

beginPath()方法步骤是清空this当前默认路径中的子路径列表,使其再次变为零子路径。

以下方法定义使用术语预期路径表示Path2D-或-null path,它的意思是path本身(如果它是Path2D对象),或是当前默认路径

预期路径Path2D对象时, 它的子路径的坐标和线条必须根据对象上实现CanvasTransform 接口时使用的方法的当前变换矩阵进行变换(不影响Path2D对象本身)。当预期路径是当前默认路径时,不受变换影响。(这是因为构建时变换已经影响了当前默认路径,所以在绘制时应用它会导致双重变换。)

fill(fillRule)方法步骤是运行填充步骤,给定this、null和fillRule

fill(path, fillRule)方法步骤是运行填充步骤,给定thispathfillRule

填充步骤,给定CanvasDrawPath contextPath2D-或-null path填充规则 fillRule,是填充所有path预期路径的子路径,使用context填充样式,并使用fillRule指示的填充规则。在填充时必须隐式关闭开放的子路径(不影响实际子路径)。

stroke()方法步骤是运行描边步骤,给定this和null。

stroke(path)方法步骤是运行描边步骤,给定thispath

描边步骤,给定CanvasDrawPath contextPath2D-或-null path,是path预期路径,使用context的线条样式,根据它的CanvasPathDrawingStylesmixin进行描边,然后使用context描边样式填充结果路径,使用非零缠绕规则

由于定义了描路径的算法,一个描边操作中的路径重叠部分被视为其联合绘制的部分。

描边样式在绘制过程中受变换影响,即使使用当前默认路径

路径在填充或描边时必须绘制而不影响当前默认路径或任何Path2D对象,并且必须受阴影效果全局透明度裁剪区域当前合成和混合操作的约束。(变换的影响如上所述,基于使用的路径而有所不同。)


clip(fillRule)方法步骤是运行裁剪步骤,给定this、null和fillRule

clip(path, fillRule)方法步骤是运行裁剪步骤,给定thispathfillRule

裁剪步骤,给定CanvasDrawPath contextPath2D-或-null path填充规则 fillRule,是通过计算context的当前裁剪区域和path预期路径描述的区域的交集来创建一个新的裁剪区域,使用fillRule指示的填充规则。计算裁剪区域时必须隐式关闭开放的子路径,不影响实际子路径。新裁剪区域替换当前裁剪区域。

当上下文初始化时,其当前裁剪区域必须设置为最大的无限表面(即默认情况下,不进行裁剪)。


isPointInPath(x, y, fillRule)方法步骤是返回运行点是否在路径中步骤的结果,给定this、null、xyfillRule

isPointInPath(path, x, y, fillRule)方法步骤是返回运行点是否在路径中步骤的结果,给定thispathxyfillRule

点是否在路径中步骤,给定CanvasDrawPath contextPath2D-或-null path、两个数字xy填充规则 fillRule,是:

  1. 如果xy 是无限或NaN,则返回false。

  2. 如果给定的xy坐标作为画布坐标空间中的坐标,不受当前变换影响,则根据fillRule指示的填充规则,该点是否位于path预期路径内,则返回true。计算路径内区域时必须隐式关闭开放的子路径,不影响实际子路径。路径本身的点必须被视为在路径内。

  3. 返回false。


isPointInStroke(x, y) 方法步骤是返回运行点是否在描边中步骤的结果,给定 this、null、xy

isPointInStroke(path, x, y)方法步骤是返回运行点是否在描边中步骤的结果,给定thispathxy

点是否在描边中步骤,给定CanvasDrawPath contextPath2D-或-null path和两个数字xy,是:

  1. 如果xy是无限或NaN,则返回false。

  2. 如果给定的xy坐标作为画布坐标空间中的坐标,不受当前变换影响,则根据描路径预期路径path,使用非零缠绕规则,并使用context的线条样式根据它的CanvasPathDrawingStyles mixin,结果路径内的点必须被视为在路径内,则返回true。

  3. 返回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>
4.12.5.1.13 绘制焦点环
context.drawFocusIfNeeded(element)

CanvasRenderingContext2D/drawFocusIfNeeded

支持所有当前引擎。

Firefox32+Safari8+Chrome37+
Opera?Edge79+
Edge (旧版)14+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

如果element处于焦点状态,则在当前默认路径周围绘制一个焦点环,遵循平台的焦点环惯例。

context.drawFocusIfNeeded(path, element)

如果element处于焦点状态,则在path周围绘制一个焦点环,遵循平台的焦点环惯例。

实现CanvasUserInterface接口的对象提供以下方法来绘制焦点环。

drawFocusIfNeeded(element) 方法步骤是根据需要绘制焦点,给定thiselementthis当前默认路径

drawFocusIfNeeded(path, element) 方法步骤是根据需要绘制焦点,给定thiselementpath

根据需要绘制焦点,给定实现CanvasUserInterfacecontext对象、元素element路径path

  1. 如果element不是焦点状态或不是contextcanvas元素的后代,则返回。

  2. 沿path绘制适当样式的焦点环,遵循平台惯例。

    某些平台只会在从键盘聚焦的元素周围绘制焦点环,而不会在从鼠标聚焦的元素周围绘制焦点环。其他平台则只在启用相关辅助功能时才会在某些元素周围绘制焦点环。此API旨在遵循这些惯例。鼓励实现基于元素聚焦方式的区分的用户代理根据触发调用的用户交互事件(如果有)来分类focus()方法驱动的焦点。

    焦点环不应受到阴影效果全局透明度当前合成和混合操作填充样式描边样式CanvasPathDrawingStylesCanvasTextDrawingStyles接口中的任何成员的影响,但应受到裁剪区域的约束。(变换的影响如上所述,基于使用的路径而有所不同。)

  3. 通知用户焦点位于预期路径给定的位置。用户代理可以等到下一次事件循环到达其更新渲染步骤时再选择通知用户。

在绘制焦点环时,用户代理不应隐式关闭预期路径中的开放子路径。

不过,这可能是一个无关紧要的问题。例如,如果焦点环被绘制为沿预期路径的点的轴对齐边界矩形,那么子路径是否关闭没有影响。本规范故意不具体规定如何绘制焦点环:用户代理应遵循其平台的本机惯例。

本节使用的“通知用户”并不意味着任何持久状态变化。例如,这可能意味着调用系统辅助功能API来通知放大工具等辅助技术,以便用户的放大镜移动到画布的给定区域。然而,它并不将路径与元素关联,或提供触觉反馈区域等。

4.12.5.1.14 绘制图像

实现CanvasDrawImage 接口的对象有drawImage()方法来绘制图像。

此方法可以使用三种不同的参数集调用:

context.drawImage(image, dx, dy)

CanvasRenderingContext2D/drawImage

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
context.drawImage(image, dx, dy, dw, dh)
context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)

将给定图像绘制到画布上。参数解释如下:

The sx and sy parameters give
the x and y coordinates of the source rectangle; the sw and sh arguments give the width and
height of the source rectangle; the dx and dy give the x and y coordinates of the destination
rectangle; and the dw and dh arguments give the width and height of the destination
rectangle.

如果图像尚未完全解码,则不会绘制任何内容。如果图像是没有数据的画布,则抛出DOMException中的"InvalidStateError"

当调用drawImage()方法时,用户代理必须执行以下步骤:

  1. 如果任何参数是无限或NaN,则返回。

  2. usability成为检查image可用性的结果。

  3. 如果usabilitybad,则返回(不绘制任何内容)。

  4. 如下建立源矩形和目标矩形:

    如果未指定,则dwdh参数必须默认为swsh的值,解释为图像中的一个CSS像素被视为输出位图坐标空间中的一个单位。如果省略sxsyswsh参数,则它们必须默认为0、0、图像像素中的图像自然宽度和图像像素中的图像自然高度。如果图像没有自然尺寸,则必须使用具体对象尺寸,如使用CSS“具体对象尺寸解析”算法确定的,指定大小既没有确定的宽度也没有确定的高度,也没有任何附加约束,对象的自然属性是image参数的属性,默认对象尺寸输出位图的尺寸。[CSSIMAGES]

    源矩形是四个点(sxsy)、(sx+swsy)、(sx+swsy+sh)、(sxsy+sh)的矩形。

    目标矩形是四个点(dxdy)、(dx+dwdy)、(dx+dwdy+dh)、(dxdy+dh)的矩形。

    当源矩形在源图像之外时,源矩形必须被裁剪到源图像,目标矩形必须按相同比例裁剪。

    当目标矩形在目标图像之外时(输出位图),落在输出位图之外的像素将被丢弃,就像目标是一个无限画布,其渲染被裁剪到输出位图的尺寸一样。

  5. 如果swsh参数之一为零,则返回。不绘制任何内容。

  6. 在应用当前变换矩阵到目标矩形后,将由源矩形指定的image参数区域绘制在渲染上下文的输出位图的目标矩形区域上。

    即使给定的尺寸为负,图像数据也必须按原始方向处理。

    当放大时,如果imageSmoothingEnabled属性设置为true,用户代理应尝试在图像缩放时应用平滑算法。支持多种过滤算法的用户代理可以使用imageSmoothingQuality属性的值来指导过滤算法的选择,当imageSmoothingEnabled属性设置为true时。否则,图像必须使用最邻近插值法进行渲染。

    本规范没有定义缩小图像时的确切算法,或当imageSmoothingEnabled属性设置为true时放大图像的确切算法。

    canvas元素绘制到自身时,绘图模型要求在绘制图像之前复制源,因此可以将canvas元素的部分复制到其自身的重叠部分。

    如果原始图像数据是位图图像,则目标矩形某点的绘制值是通过过滤原始图像数据计算的。用户代理可以使用任何过滤算法(例如双线性插值或最邻近)。当过滤算法需要原始图像数据之外的像素值时,必须使用最近的边缘像素的值。(即,过滤器使用“夹边”行为。)当过滤算法需要源矩形之外但在原始图像数据之内的像素值时,必须使用原始图像数据的值。

    因此,部分或整体缩放图像将产生相同的效果。这意味着当从单个精灵表中缩放精灵时,精灵表中的相邻图像可能会相互干扰。这可以通过确保精灵表中的每个精灵都被透明黑色边框包围来避免,或者将要缩放的精灵复制到临时canvas元素中,并从那里绘制缩放后的精灵来避免。

    图像的绘制不会影响当前路径,并且受阴影效果全局透明度裁剪区域当前合成和混合操作的约束。

  7. 如果image不是原点清洁的,则将CanvasRenderingContext2Dorigin-clean标志设置为false。

4.12.5.1.15 像素操作
imagedata = new ImageData(sw, sh [, settings])

ImageData/ImageData

支持所有当前引擎。

Firefox29+Safari8+Chrome36+
Opera?Edge79+
Edge (旧版)14+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回具有给定尺寸和由settings指示的颜色空间的ImageData对象。返回对象中的所有像素都是透明黑色

如果宽度或高度参数为零,则抛出"IndexSizeError" DOMException

imagedata = new ImageData(data, sw [, sh [, settings ] ])

使用Uint8ClampedArray参数中提供的数据,并使用给定的尺寸和由settings指示的颜色空间,返回ImageData对象。

由于数据中的每个像素由四个数字表示,因此数据的长度需要是给定宽度的四倍的倍数。如果同时提供了高度,那么长度需要正好是宽度乘以高度乘以4。

如果给定的数据和尺寸不能一致地解释,或者任一尺寸为零,则抛出"IndexSizeError" DOMException

imagedata = context.createImageData(imagedata)

返回与参数具有相同尺寸和颜色空间的ImageData对象。返回对象中的所有像素都是透明黑色

imagedata = context.createImageData(sw, sh [, settings])

CanvasRenderingContext2D/createImageData

支持所有当前引擎。

Firefox3.5+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回具有给定尺寸的ImageData对象。返回对象的颜色空间是context颜色空间,除非被settings覆盖。返回对象中的所有像素都是透明黑色

如果宽度或高度参数为零,则抛出"IndexSizeError" DOMException

imagedata = context.getImageData(sx, sy, sw, sh [, settings])

CanvasRenderingContext2D/getImageData

支持所有当前引擎。

Firefox2+Safari4+Chrome2+
Opera9.5+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

返回包含给定矩形位图图像数据的ImageData对象。返回对象的颜色空间是context颜色空间,除非被settings覆盖。

如果宽度或高度参数为零,则抛出"IndexSizeError" DOMException

imagedata.width

ImageData/width

支持所有当前引擎。

Firefox3.5+Safari3.1+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+
imagedata.height

ImageData/height

支持所有当前引擎。

Firefox3.5+Safari3.1+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

返回ImageData对象中的数据的实际尺寸,以像素为单位。

imagedata.data

ImageData/data

支持所有当前引擎。

Firefox3.5+Safari3.1+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

返回以RGBA顺序表示的、作为一维数组存储的数据,整数范围在0到255之间。

imagedata.colorSpace

返回像素的颜色空间。

context.putImageData(imagedata, dx, dy [, dirtyX, dirtyY, dirtyWidth, dirtyHeight ])

CanvasRenderingContext2D/putImageData

支持所有当前引擎。

Firefox2+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

将给定ImageData对象中的数据绘制到位图上。如果提供了脏矩形,则只绘制该矩形中的像素。

对于此方法调用,globalAlphaglobalCompositeOperation属性,以及阴影属性,都将被忽略;画布中的像素将被整个替换,没有合成、alpha混合、阴影等。

如果imagedata对象的data属性值的[[ViewedArrayBuffer]]内部插槽被分离,则抛出"InvalidStateError" DOMException

实现CanvasImageData接口的对象提供以下方法来读取和写入位图的像素数据。

new ImageData(sw, sh, settings)构造函数步骤如下:

  1. 如果swsh中的一个或两个为零,则抛出"IndexSizeError" DOMException

  2. 初始化this,给定swshsettings设置为settings

  3. this的图像数据初始化为透明黑色

new ImageData(data, sw, sh, settings)构造函数步骤如下:

  1. lengthdata中的字节数。

  2. 如果length不是四的非零整数倍,则抛出"InvalidStateError" DOMException

  3. length除以四。

  4. 如果length不是sw的整数倍,则抛出"IndexSizeError" DOMException

    在此步骤中,长度保证大于零(否则第二步会中止步骤),所以如果sw为零,此步骤将抛出异常并返回。

  5. height设为length除以sw

  6. 如果提供了sh且其值不等于height,则抛出"IndexSizeError" DOMException

  7. 初始化this,给定swshsettings设置为settings,以及source设置为data

    此步骤不会将this的数据设置为data的副本。它将其设置为传递为data的实际Uint8ClampedArray对象。

createImageData(sw, sh, settings)方法步骤如下:

  1. 如果swsh中的一个或两个为零,则抛出"IndexSizeError" DOMException

  2. newImageData为一个新的ImageData对象。

  3. 初始化newImageData,给定sw的绝对值、sh的绝对值、settings设置为settings,以及defaultColorSpace设置为this颜色空间

  4. newImageData的图像数据初始化为透明黑色

  5. 返回newImageData

createImageData(imagedata)方法步骤如下:

  1. newImageData为一个新的ImageData对象。

  2. 初始化newImageData,给定imagedatawidth属性值、imagedataheight属性值,以及defaultColorSpace设置为imagedatacolorSpace属性值。

  3. newImageData的图像数据初始化为透明黑色

  4. 返回newImageData

getImageData(sx, sy, sw, sh, settings)方法步骤如下:

  1. 如果swsh参数为零,则抛出"IndexSizeError" DOMException

  2. 如果CanvasRenderingContext2Dorigin-clean标志设置为false,则抛出"SecurityError" DOMException

  3. imageData为一个新的ImageData对象。

  4. 初始化imageData,给定swshsettings设置为settings,以及defaultColorSpace设置为this颜色空间

  5. 设源矩形为由四个点(sxsy)、(sx+swsy)、(sx+swsy+sh)、(sxsy+sh)组成的矩形。

  6. imageData的像素值设置为this输出位图中由位图坐标空间单位中源矩形指定的区域的像素,转换为imageData颜色空间,使用'相对色度'渲染意图。

  7. 将源矩形中位于输出位图之外的区域的imageData的像素值设置为透明黑色

  8. 返回imageData

初始化ImageData对象imageData,给定正整数行数rows、每行像素数pixelsPerRow、可选ImageDataSettingssettings、可选Uint8ClampedArraysource和可选PredefinedColorSpacedefaultColorSpace

ImageData/colorSpace

FirefoxNoSafari15.2+Chrome92+
Opera?Edge92+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
  1. 如果提供了source,则将imageDatadata属性初始化为source

  2. 否则(未提供source),将imageDatadata属性初始化为一个新的Uint8ClampedArray对象。Uint8ClampedArray对象必须使用新的画布像素ArrayBuffer作为其存储,并且必须有零开始偏移量和长度等于其存储长度,以字节为单位。画布像素ArrayBuffer必须具有正确的大小来存储rows × pixelsPerRow像素。

    如果画布像素ArrayBuffer无法分配,则重新抛出JavaScript引发的RangeError并返回。

  3. imageDatawidth属性初始化为pixelsPerRow

  4. imageDataheight属性初始化为rows

  5. 如果提供了settings并且settings["colorSpace"]存在,则将imageDatacolorSpace属性初始化为settings["colorSpace"]。

  6. 否则,如果提供了defaultColorSpace,则将imageDatacolorSpace属性初始化为defaultColorSpace

  7. 否则,将imageDatacolorSpace属性初始化为"srgb"。

ImageData对象是可序列化对象。它们的序列化步骤,给定valueserialized,如下:

  1. serialized.[[Data]]设置为valuedata属性值的子序列化

  2. serialized.[[Width]]设置为valuewidth属性值。

  3. serialized.[[Height]]设置为valueheight属性值。

  4. serialized.[[ColorSpace]]设置为valuecolorSpace属性值。

它们的反序列化步骤,给定serializedvalue targetRealm,如下:

  1. valuedata属性初始化为serialized.[[Data]]的子反序列化

  2. valuewidth属性初始化为serialized.[[Width]]。

  3. valueheight属性初始化为serialized.[[Height]]。

  4. valuecolorSpace属性初始化为serialized.[[ColorSpace]]。

画布像素ArrayBuffer是一个ArrayBuffer,其数据从左到右表示,从上到下逐行排列,从左上角开始,每个像素的红色、绿色、蓝色和alpha分量按顺序给出。此数组中表示的每个像素的每个分量必须在0到255的范围内,表示该分量的8位值。分量必须从0开始为左上角像素的红色分量,连续分配索引。

putImageData()方法将数据从ImageData结构写回渲染上下文的输出位图。其参数为:imagedatadxdydirtyXdirtyYdirtyWidthdirtyHeight

当省略此方法的最后四个参数时,必须假定它们的值分别为0、0、imagedata结构的width成员和imagedata结构的height成员。

调用此方法时,必须按以下步骤操作:

  1. bufferimagedatadata属性值的[[ViewedArrayBuffer]]内部插槽。

  2. 如果IsDetachedBuffer(buffer)为true,则抛出"InvalidStateError" DOMException

  3. 如果dirtyWidth为负,则设dirtyXdirtyX+dirtyWidth,并将dirtyWidth设为dirtyWidth的绝对值。

    如果dirtyHeight为负,则设dirtyYdirtyY+dirtyHeight,并将dirtyHeight设为dirtyHeight的绝对值。

  4. 如果dirtyX为负,则将dirtyWidth设为dirtyWidth+dirtyX,并将dirtyX设为零。

    如果dirtyY为负,则将dirtyHeight设为dirtyHeight+dirtyY,并将dirtyY设为零。

  5. 如果dirtyX+dirtyWidth大于imagedata参数的width属性的值,则将dirtyWidth设为该width属性的值减去dirtyX的值。

    如果dirtyY+dirtyHeight大于imagedata参数的height属性的值,则将dirtyHeight设为该height属性的值减去dirtyY的值。

  6. 如果经过这些更改后,dirtyWidthdirtyHeight为负或为零,则在不影响任何位图的情况下返回。

  7. 对于所有整数值的xy,其中dirtyXx < dirtyX+dirtyWidth dirtyYy < dirtyY+dirtyHeight ,将imagedata数据结构的画布像素ArrayBuffer中像素的四个通道复制到渲染上下文的输出位图中具有坐标(dx+xdy+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>
4.12.5.1.16 合成
context.globalAlpha [ = value ]

CanvasRenderingContext2D/globalAlpha

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回当前应用于渲染操作的全局alpha值。

可以设置,以更改全局alpha值。超出0.0到1.0范围的值将被忽略。

context.globalCompositeOperation [ = value ]

CanvasRenderingContext2D/globalCompositeOperation

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

返回当前的合成和混合操作符, 来自定义的值 在合成和混合中定义。[COMPOSITE]

可以设置,以更改当前的合成和混合操作符。 未知 值将被忽略。

实现CanvasCompositing 接口的对象有一个全局alpha值和一个当前的合成和混合操作符值,这两个值都会影响此对象上的所有绘图操作。

全局alpha值为在将形状和图像合成到输出位图之前应用的alpha值。 该值的范围是0.0(完全透明)到1.0(无额外透明度)。初始值必须为1.0。

globalAlpha getter步骤是返回 this全局alpha值。

globalAlpha setter步骤是:

  1. 如果给定值为无限、NaN或不在0.0到1.0范围内,则返回。

  2. 否则,将this全局alpha值设置为给定值。

当前的合成和混合操作符值 控制在应用全局alpha当前转换矩阵后,如何将形状和图像绘制到输出位图上。最初,它必须设置为"source-over"。

globalCompositeOperation getter 步骤是返回this当前的合成和混合操作符

globalCompositeOperation setter步骤是:

  1. 如果给定值不等同于任何<blend-mode><composite-mode>属性定义的值,则返回。[COMPOSITE]

  2. 否则,将this当前的合成和混合操作符 设置为给定值。

4.12.5.1.17 图像平滑
context.imageSmoothingEnabled [ = value ]

CanvasRenderingContext2D/imageSmoothingEnabled

支持所有当前引擎。

Firefox51+Safari9.1+Chrome30+
Opera?Edge79+
Edge (旧版)15+Internet Explorer🔰 11
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回当前是否在放大图像时平滑图像的偏好设置,具体体现在图案填充和drawImage()方法上,如果它们的像素与显示不完全对齐,则尝试平滑图像。

可以设置,以更改图像是否平滑(true)或不平滑(false)。

context.imageSmoothingQuality [ = value ]

CanvasRenderingContext2D/imageSmoothingQuality

FirefoxNoSafari9.1+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回当前的图像平滑质量偏好设置。

可以设置,以更改图像平滑的首选质量。可能的值是""、 "" 和""。 未知值将被忽略。

实现CanvasImageSmoothing 接口的对象有控制图像平滑如何执行的属性。

imageSmoothingEnabled属性,在获取时,必须返回最后设置的值。在设置时,必须设置为新值。 当实现CanvasImageSmoothing 接口的对象被创建时, 属性必须设置为true。

imageSmoothingQuality属性,在获取时,必须返回最后设置的值。在设置时,必须设置为新值。 当实现CanvasImageSmoothing 接口的对象被创建时, 属性必须设置为""。

4.12.5.1.18 阴影

实现CanvasShadowStyles 接口的对象上的所有绘图操作都受到四个全局阴影属性的影响。

context.shadowColor [ = value ]

CanvasRenderingContext2D/shadowColor

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回当前阴影颜色。

可以设置以更改阴影颜色。无法解析为CSS颜色的值将被忽略。

context.shadowOffsetX [ = value ]

CanvasRenderingContext2D/shadowOffsetX

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
context.shadowOffsetY [ = value ]

CanvasRenderingContext2D/shadowOffsetY

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回当前阴影偏移。

可以设置以更改阴影偏移。不是有限数的值将被忽略。

context.shadowBlur [ = value ]

CanvasRenderingContext2D/shadowBlur

支持所有当前引擎。

Firefox1.5+Safari2+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回当前应用于阴影的模糊级别。

可以设置以更改模糊级别。不是有限数且大于或等于零的值将被忽略。

实现CanvasShadowStyles 接口的对象具有相关联的阴影颜色,这是一个CSS颜色。 最初,它必须是透明黑色

shadowColor的getter步骤是返回序列化this阴影颜色,并请求HTML兼容的序列化

shadowColor setter步骤是:

  1. context成为thiscanvas属性的值,如果这是一个元素;否则为null。

  2. parsedValue成为使用context解析给定值的结果,如果不是null。

  3. 如果parsedValue失败,则返回。

  4. this阴影颜色设置为parsedValue

shadowOffsetXshadowOffsetY 属性分别指定阴影在水平和垂直方向上的偏移距离。它们的值是坐标空间单位。它们不受当前转换矩阵的影响。

当上下文被创建时,阴影偏移属性最初必须具有值0。

在获取时,它们必须返回当前值。在设置时,正在设置的属性必须设置为新值,除非该值为无限或NaN,在这种情况下,必须忽略新值。

shadowBlur属性指定模糊效果的级别。(单位不映射到坐标空间单位,并且不受当前转换矩阵的影响。)

当上下文被创建时,shadowBlur属性最初必须具有值0。

在获取时,属性必须返回其当前值。在设置时,属性必须设置为新值,除非该值为负、无限或NaN,在这种情况下,必须忽略新值。

仅当阴影颜色的alpha分量的不透明度分量不为零且shadowBlur不为零,或者shadowOffsetX不为零,或者 shadowOffsetY不为零时才绘制阴影。

绘制阴影时,必须按以下步骤渲染:

  1. A成为一个无限的透明黑色位图,其上已渲染了创建阴影的源图像。

  2. B成为一个无限的透明黑色位图,其坐标空间和原点与A相同。

  3. A的alpha通道复制到B,并在正x方向上偏移shadowOffsetX,在正 y方向上偏移shadowOffsetY

  4. 如果shadowBlur大于0:

    1. σshadowBlur值的一半。

    2. B执行2D高斯模糊,使用σ作为标准偏差。

    用户代理可以将σ的值限制为特定实现的最大值,以避免在高斯模糊操作期间超出硬件限制。

  5. B中每个像素的红色、绿色和蓝色分量设置为阴影颜色的红色、绿色和蓝色分量(分别)。

  6. B中每个像素的alpha分量乘以阴影颜色的alpha分量。

  7. 阴影在位图B中,并作为下面描述的绘图模型的一部分进行渲染。

如果当前的合成和混合操作符是"copy", 那么阴影实际上不会渲染(因为形状会覆盖阴影)。

4.12.5.1.19 滤镜

实现CanvasFilters 接口的对象上的所有绘图操作都受全局filter属性的影响。

context.filter [ = value ]

CanvasRenderingContext2D/filter

Firefox49+SafariNoChrome52+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回当前滤镜。

可以设置以更改滤镜。值可以是字符串"none"或可解析为<filter-value-list>的字符串。其他值将被忽略。

这些对象具有相关联的当前滤镜,这是一个字符串。最初,当前滤镜设置为字符串"none"。 每当当前滤镜的值为字符串"none"时,将禁用该上下文的滤镜。

filter getter步骤是返回 this当前滤镜

filter setter步骤是:

  1. 如果给定值是"none",则将this当前滤镜设置为"none" 并返回。

  2. parsedValue设为按照CSS语法解析给定值为<filter-value-list>的结果。如果存在任何独立于属性的样式表语法,如“inherit”或“initial”,则此解析必须返回失败。

  3. 如果parsedValue失败,则返回。

  4. this当前滤镜设置为给定值。

尽管 context.filter = "none"将禁用该上下文的滤镜, context.filter = ""context.filter = null、 和 context.filter = undefined都被视为无法解析的输入,并且当前滤镜的值保持不变。

当前滤镜值中使用的坐标被解释为一个像素等于一个SVG用户空间单位和一个画布坐标空间单位。滤镜坐标不受当前变换矩阵的影响。当前变换矩阵仅影响滤镜的输入。滤镜应用在 输出位图的坐标空间中。

当前滤镜的值是可解析为定义了使用百分比或使用'em''ex'单位长度的<filter-value-list>的字符串时,这些长度必须相对于设置该属性时 计算值'font-size'属性进行解释。如果计算值对于特定情况未定义(例如,因为字体样式源对象不是元素或没有被渲染),则相对关键字必须相对于 font属性的默认值进行解释。不支持“larger”和“smaller”关键字。

如果当前滤镜的值是可解析为引用同一文档中的SVG滤镜的<filter-value-list>的字符串,并且该SVG滤镜发生变化,则在下一次绘图操作时使用更改后的滤镜。

如果当前滤镜的值是可解析为引用外部资源文档中的SVG滤镜的<filter-value-list>的字符串,并且在调用绘图操作时尚未加载该文档,则绘图操作必须在没有滤镜的情况下继续进行。

4.12.5.1.20 使用外部定义的 SVG 滤镜

本节是非规范性的。

由于在外部定义的滤镜加载完成之前,绘图是使用滤镜值"none"进行的,因此作者可能希望在进行绘图操作之前确定此类滤镜是否已加载完成。实现这一目标的一种方法是在同一页面内的某个其他元素中加载外部定义的滤镜,该元素会发送load事件(例如,SVG use元素),并等待load事件被触发。

4.12.5.1.21 绘图模型

当绘制形状或图像时,用户代理必须按照给定的顺序执行以下步骤(或表现得像这样做):

  1. 如前几节所述,将形状或图像渲染到一个无限的透明黑色位图上,创建图像A。对于形状,必须遵守当前的填充、描边和线条样式,并且描边本身也必须受到当前变换矩阵的影响。

  2. 当前滤镜设置为"none"以外的值且其引用的所有外部定义滤镜(如果有)都在当前已加载的文档中时,则使用图像A作为当前滤镜的输入,创建图像B。如果当前滤镜是可解析为<filter-value-list>的字符串,则以与SVG相同的方式使用当前滤镜进行绘制。

    否则,让BA的别名。

  3. 绘制阴影时,使用当前阴影样式从图像B渲染阴影,创建图像C

  4. 绘制阴影时,将C中每个像素的alpha分量乘以全局alpha

  5. 绘制阴影时,使用当前的合成和混合操作符,在剪裁区域内将C复合到当前的输出位图上。

  6. B中每个像素的alpha分量乘以全局alpha

  7. 使用当前的合成和混合操作符,在剪裁区域内将B复合到当前的输出位图上。

在合成到输出位图时,超出输出位图的像素必须被丢弃。

4.12.5.1.22 最佳实践

当canvas是交互式时,作者应在元素的后备内容中包含可聚焦元素,对应canvas的每个可聚焦部分,如上面的示例

在渲染聚焦环时,为确保聚焦环具有本地聚焦环的外观,作者应使用drawFocusIfNeeded()方法,并传递要为其绘制环的元素。此方法仅在元素被聚焦时绘制聚焦环,因此可以在绘制元素时随时调用此方法,而无需先检查元素是否被聚焦。

作者应避免使用canvas元素实现文本编辑控件。这样做有很多缺点:

这是一项巨大的工作,强烈建议作者通过使用input元素、textarea元素或contenteditable属性来避免这些工作。

4.12.5.1.23 示例

本节是非规范性的。

下面是一个使用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: 200px; min-width: 380px; }
  body { height: 200px; position: relative; margin: 8px; }
  .buttons { position: absolute; bottom: 0px; left: 0px; margin: 4px; }
</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>
4.12.5.2 ImageBitmap 渲染上下文
4.12.5.2.1 介绍

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');
});
4.12.5.2.2 ImageBitmapRenderingContext 接口

ImageBitmapRenderingContext

所有当前引擎都支持。

Firefox46+Safari11.1+Chrome66+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
[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

所有当前引擎都支持。

Firefox50+Safari11.1+Chrome66+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

将底层位图数据imageBitmap传输到context,并且该位图成为canvas 元素的内容,该元素与context绑定。

context.transferFromImageBitmap(null)

context 所绑定的 canvas 元素的内容替换为一个 透明黑色 位图,其大小对应于 widthheight 属性的内容。

canvas属性必须返回对象创建时初始化的值。

ImageBitmapRenderingContext 对象有一个输出位图,它是对位图数据的引用。

一个 ImageBitmapRenderingContext 对象有一个 位图模式,它可以设置为 有效空白。值为 有效 表示上下文的 输出位图 引用通过 transferFromImageBitmap() 获取的 位图数据。值为 空白 表示上下文的 输出位图 是默认的透明位图。

一个 ImageBitmapRenderingContext 对象也有一个 alpha 标志,它可以设置为 true 或 false。当一个 ImageBitmapRenderingContext 对象的 alpha 标志设置为 false 时,上下文所绑定的 canvas 元素的内容是通过将上下文的 输出位图 复合到同样大小的 不透明黑色 位图上,并使用 source-over 合成操作符获取的。如果 alpha 标志设置为 true,则 输出位图 用作上下文所绑定的 canvas 元素的内容。[COMPOSITE]

只要能通过其他手段更有效地获得等效结果,就应省略合成到不透明黑色位图的步骤。


当用户代理需要设置ImageBitmapRenderingContext的输出位图时,使用context参数,该参数是ImageBitmapRenderingContext对象,并且有一个可选参数bitmap,该参数指的是位图数据,则必须执行以下步骤:

  1. 如果未提供bitmap参数,则:

    1. context位图模式设置为空白

    2. canvas设置为canvas元素,与context绑定。

    3. context输出位图设置为透明黑色,其自然宽度等于canvas宽度属性的数值值,这些值被解释为CSS像素

    4. context输出位图原点清除标志设置为true。

  2. 如果提供了bitmap参数,则:

    1. context位图模式设置为有效

    2. context输出位图设置为引用与bitmap相同的底层位图数据,而不进行复制。

      bitmap原点清除标志包含在context输出位图的数据中。


ImageBitmapRenderingContext创建算法,该算法传递targetoptions,包括以下步骤:

  1. options转换为字典类型ImageBitmapRenderingContextSettings的结果,得到settings。 (这可能会抛出异常。)

  2. context成为一个新的ImageBitmapRenderingContext对象。

  3. 初始化contextcanvas属性,使其指向target

  4. context输出位图设置为与target的位图相同(使它们共享)。

  5. 运行步骤以设置ImageBitmapRenderingContext的输出位图,使用context

  6. 初始化contextalpha标志为true。

  7. 处理settings的每个成员,如下所示:

    alpha
    如果为false,则将contextalpha标志设置为false。
  8. 返回context


transferFromImageBitmap(bitmap) 方法,在调用时必须执行以下步骤:

  1. bitmapContext成为ImageBitmapRenderingContext对象, 该对象上调用了transferFromImageBitmap()方法。

  2. 如果bitmap为null,则运行步骤以设置ImageBitmapRenderingContext的输出位图, 使用bitmapContext作为context参数且没有bitmap参数,然后返回。

  3. 如果bitmap[[Detached]]内部槽的值设置为true,则抛出InvalidStateErrorDOMException

  4. 运行步骤以设置ImageBitmapRenderingContext的输出位图, 使用context参数等于bitmapContextbitmap参数引用bitmap的底层位图数据

  5. bitmap[[Detached]]内部槽的值设置为true。

  6. 取消设置bitmap位图数据

4.12.5.3 OffscreenCanvas 接口

OffscreenCanvas

所有当前引擎均支持。

Firefox105+Safari16.4+Chrome69+
Opera?Edge79+
Edge (Legacy)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
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 可以触发 contextlostcontextrestored, 而 WebGL 可以触发 webglcontextlostwebglcontextrestored[WEBGL]

OffscreenCanvas 对象用于创建渲染上下文,类似于 HTMLCanvasElement, 但与 DOM 无关。这使得在 workers 中使用 canvas 渲染上下文成为可能。

OffscreenCanvas 对象可能持有一个对 占位 canvas 元素 的弱引用,该元素通常位于 DOM 中,其嵌入内容由 OffscreenCanvas 对象提供。OffscreenCanvas 对象的位图被推送到 占位 canvas 元素,作为 OffscreenCanvas相关代理事件循环更新渲染 步骤的一部分。

offscreenCanvas = new OffscreenCanvas(width, height)

OffscreenCanvas/OffscreenCanvas

在所有当前引擎中支持。

Firefox105+Safari16.4+Chrome69+
Opera?Edge79+
Edge(旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回一个新的 OffscreenCanvas 对象,该对象未链接到 占位 canvas 元素, 其位图的大小由 widthheight 参数决定。

context = offscreenCanvas.getContext(contextId [, options ])

OffscreenCanvas/getContext

在所有当前引擎中支持。

Firefox105+Safari16.4+Chrome69+
Opera?Edge79+
Edge(旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回一个用于在 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 对象内部有一个 位图,在对象创建时进行初始化。该位图的宽度和高度等于该 位图 的宽度和高度等于 widthheight 属性的值。最初,所有位图的像素都是 透明黑色

一个 OffscreenCanvas 对象可以绑定一个渲染上下文。最初,它没有绑定任何渲染上下文。为了跟踪它是否有渲染上下文以及渲染上下文的类型,OffscreenCanvas 对象还有一个 上下文模式,初始值为 ,但可以通过本规范定义的算法更改为 2dbitmaprendererwebglwebgl2webgpu分离

构造函数 OffscreenCanvas(width, height) 在调用时,必须创建一个新的 OffscreenCanvas 对象,并将其 位图 初始化为一个矩形数组, 其中包含由 widthheight 指定尺寸的 透明黑色 像素;并将其 widthheight 属性初始化为 widthheight


OffscreenCanvas 对象是 可转移的。它们的 转移步骤 给定 valuedataHolder,如下:

  1. 如果 value上下文模式 不等于 ,则抛出一个 "InvalidStateError" DOMException

  2. value上下文模式 设置为 分离

  3. widthheight 设为 value位图 的尺寸。

  4. 取消设置 value位图

  5. dataHolder 的 [[Width]] 设置为 width,将 dataHolder 的 [[Height]] 设置为 height

  6. dataHolder 的 [[PlaceholderCanvas]] 设置为对 value占位 canvas 元素 的弱引用,如果 value 有占位元素,则设置,否则为 null。

它们的 接收步骤,给定 dataHoldervalue,如下:

  1. value位图 初始化为一个矩形数组, 其中包含 透明黑色 像素,其宽度由 dataHolder 的 [[Width]] 和高度由 dataHolder 的 [[Height]] 确定。

  2. 如果 dataHolder 的 [[PlaceholderCanvas]] 不为 null,则将 value占位 canvas 元素 设置为 dataHolder 的 [[PlaceholderCanvas]](同时保持弱引用语义)。


当调用 OffscreenCanvas 对象的 getContext(contextId, options) 方法时,必须运行以下步骤:

  1. 如果 options 不是 对象,则将 options 设置为 null。

  2. options 设置为 转换 options 为 JavaScript 值的结果。

  3. 根据以下表格中与此 OffscreenCanvas 对象的 上下文模式 匹配的列标题和与 contextId 匹配的行标题,运行步骤:

    2d bitmaprenderer webglwebgl2 webgpu 分离
    "2d"
    1. context 成为给定 thisoptions 运行 offscreen 2D 上下文创建算法 的结果。

    2. this上下文模式 设置为 2d

    3. 返回 context

    返回上次使用相同第一个参数调用该方法时返回的相同对象。 返回 null。 返回 null。 返回 null。 抛出 "InvalidStateError" DOMException
    "bitmaprenderer"
    1. context 成为给定 thisoptions 运行 ImageBitmapRenderingContext 创建算法 的结果。

    2. this上下文模式 设置为 bitmaprenderer

    3. 返回 context

    返回 null。 返回上次使用相同第一个参数调用该方法时返回的相同对象。 返回 null。 返回 null。 抛出 "InvalidStateError" DOMException
    "webgl" 或 "webgl2"
    1. context 成为遵循 WebGL 规范中的上下文创建部分的说明的结果。[WEBGL]

    2. 如果 context 为 null,则返回 null;否则将 this上下文模式 设置为 webglwebgl2

    3. 返回 context

    返回 null。 返回 null。 返回上次使用相同第一个参数调用该方法时返回的相同值。 返回 null。 抛出 "InvalidStateError" DOMException
    "webgpu"
    1. context 成为遵循 WebGPUCanvas Rendering 部分中的说明的结果。 [WEBGPU]

    2. 如果 context 为 null,则返回 null;否则将 this上下文模式 设置为 webgpu

    3. 返回 context

    返回 null。 返回 null。 返回 null。 返回上次使用相同第一个参数调用该方法时返回的相同值。 抛出 "InvalidStateError" DOMException

offscreenCanvas.width [ = value ]

OffscreenCanvas/width

支持所有当前引擎。

Firefox105+Safari16.4+Chrome69+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
offscreenCanvas.height [ = value ]

OffscreenCanvas/height

支持所有当前引擎。

Firefox105+Safari16.4+Chrome69+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

这些属性返回 OffscreenCanvas 对象的 bitmap 的尺寸。

可以设置这些属性,以用指定尺寸的新 bitmap 替换现有的 透明黑色 bitmap(实际效果是调整其大小)。

如果将 widthheight 属性设置为新值或与之前相同的值,并且 OffscreenCanvas 对象的 上下文模式2d,则将渲染上下文重置为默认状态并根据 widthheight 的新值调整 OffscreenCanvas 对象的 bitmap 尺寸。

webgl” 和 “webgl2” 上下文的调整行为由 WebGL 规范定义。[WEBGL]

webgpu” 上下文的调整行为由 WebGPU 规范定义。[WEBGPU]

如果更改了 OffscreenCanvas 对象的尺寸,并且该对象有一个 占位 canvas 元素,那么占位 canvas 元素自然大小 仅会在 OffscreenCanvas相关代理事件循环渲染更新 步骤中进行更新。

promise = offscreenCanvas.convertToBlob([options])

OffscreenCanvas/convertToBlob

支持所有当前引擎。

Firefox105+Safari16.4+Chrome69+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回一个 promise,该 promise 将使用一个新的 Blob 对象,该对象表示包含 OffscreenCanvas 对象中图像的文件。

参数(如果提供)是一个控制要创建的图像文件的编码选项的字典。type 字段指定文件格式,默认值为 "image/png";如果请求的类型不受支持,则也使用该类型。如果图像格式支持可变质量(例如 "image/jpeg"),则 quality 字段是一个介于 0.0 到 1.0 之间的数字,表示所需的图像质量级别。

canvas.transferToImageBitmap()

OffscreenCanvas/transferToImageBitmap

支持所有当前引擎。

Firefox105+Safari16.4+Chrome69+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回一个新创建的 ImageBitmap 对象,其中包含 OffscreenCanvas 对象中的图像。OffscreenCanvas 对象中的图像将被新空白图像替换。

convertToBlob(options) 方法, 在调用时,必须执行以下步骤:

  1. 如果此 OffscreenCanvas 对象的 [[Detached]] 内部槽设置为 true,那么返回 一个被拒绝的 promise,其中包含一个 "InvalidStateError" DOMException

  2. 如果此 OffscreenCanvas 对象的 context mode2d 且渲染上下文的 bitmaporigin-clean 标志设置为 false,那么返回 一个被拒绝的 promise,其中包含一个 "SecurityError" DOMException

  3. 如果此 OffscreenCanvas 对象的 bitmap 没有像素(即它的水平 维度或垂直维度为零),那么返回 一个被拒绝的 promise,其中包含一个 "IndexSizeError" DOMException

  4. bitmap 成为此 OffscreenCanvas 对象的 bitmap 的副本。

  5. result 成为一个新的 promise 对象。

  6. 并行运行以下步骤:

    1. file 成为 bitmap 的文件序列化,带有 optionstypequality(如果存在)。

    2. 在元素任务队列中排队画布 blob 序列化任务源 中,给 canvas 元素执行以下步骤:

      1. 如果 file 为 null,则使用 "EncodingError" DOMException 拒绝 result

      2. 否则,使用一个新的 Blob 对象解析 result,该对象在此 OffscreenCanvas 对象的 相关领域 中创建,表示 file[FILEAPI]

  7. 返回 result

transferToImageBitmap() 方法, 在调用时,必须执行以下步骤:

  1. 如果此 OffscreenCanvas 对象的 [[Detached]] 内部槽设置为 true,那么抛出 "InvalidStateError" DOMException

  2. 如果此 OffscreenCanvas 对象的 context mode 设置为 none,那么抛出 "InvalidStateError" DOMException

  3. image 成为一个新创建的 ImageBitmap 对象,该对象引用与此 OffscreenCanvas 对象的 bitmap 相同的底层位图数据。

  4. 将此 OffscreenCanvas 对象的 bitmap 设置为引用一个新创建的 bitmap,其维度和颜色空间与之前的 bitmap 相同,并且其像素初始化为 透明黑,如果渲染上下文的 不透明黑,则初始化为不透明黑。

    这意味着如果此 OffscreenCanvas 的渲染上下文是 WebGLRenderingContext, 则 preserveDrawingBuffer 的值将无效。 [WEBGL]

  5. 返回 image

以下是所有实现 OffscreenCanvas 接口的对象必须支持的 事件处理器(及其对应的 事件处理器事件类型),作为 事件处理器IDL属性

事件处理器 事件处理器事件类型
oncontextlost contextlost
oncontextrestored contextrestored
4.12.5.3.1 离屏 2D 渲染上下文

OffscreenCanvasRenderingContext2D

支持所有当前的引擎。

Firefox105+Safari16.4+Chrome69+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
[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 对象相似,但有以下不同:

一个 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

返回 关联的 OffscreenCanvas 对象

离屏 2D 上下文创建算法,传递一个 target(一个 OffscreenCanvas 对象)和一些可选参数,包括以下步骤:

  1. 如果算法传递了一些参数,则让 arg 为第一个这样的参数。否则,让 arg 为未定义。

  2. settings arg 转换为字典类型 CanvasRenderingContext2DSettings 的结果。(这可能会抛出异常)。

  3. context 为一个新的 OffscreenCanvasRenderingContext2D 对象。

  4. 设置 context关联的 OffscreenCanvas 对象target

  5. 如果 settings["alpha"] 为 false,则设置 contextalpha 标志为 false。

  6. 设置 context颜色空间settings["colorSpace"]。

  7. 设置 context位图 为一个新创建的位图,其尺寸由 targetwidthheight 属性指定,并将 target 的位图设置为相同的位图(以便它们共享)。

  8. 如果 contextalpha 标志设置为 true,初始化 context位图 的所有像素为 透明黑色。否则,初始化像素为 不透明黑色

  9. 返回 context

建议实现短路 窗口事件循环 的图形更新步骤,以便将 占位 canvas 元素 的内容更新到显示。这可能意味着,例如,位图内容被直接复制到映射到 占位 canvas 元素 的物理显示位置的图形缓冲区。这种或类似的短路方法可以显著减少显示延迟,特别是在 OffscreenCanvasworker 事件循环 更新且 窗口事件循环 忙碌的情况下。然而,这样的捷径不能有任何脚本可观察的副作用。这意味着提交的位图仍然需要发送到 占位 canvas 元素,以防元素用作 CanvasImageSourceImageBitmapSource 或调用 toDataURL()toBlob()

canvas 属性在获取时,必须返回这个 OffscreenCanvasRenderingContext2D关联的 OffscreenCanvas 对象

4.12.5.4 色彩空间和色彩空间转换

canvas API 提供了指定画布后台存储色彩空间的机制。所有 canvas API 的默认后台存储色彩空间是 'srgb'

当将画布渲染到输出设备时,必须对画布的后台存储应用色彩空间转换。该色彩空间转换必须与对具有相同色彩空间配置文件的img元素所应用的色彩空间转换相同。

在向2D上下文绘制内容时,所有输入必须在绘制前转换上下文的色彩空间。梯度颜色停止点的插值必须在转换到上下文的色彩空间后进行。Alpha 混合必须在转换到上下文的色彩空间后进行。

不存在颜色空间未定义的 2D 上下文输入。CSS 颜色的颜色空间在 CSS Color 中定义。未指定色彩配置文件信息的图像的颜色空间假定为 'srgb',如 CSS Color未标记颜色的颜色空间 部分所指定。[CSSCOLOR]

4.12.5.5 将位图序列化为文件

当用户代理要根据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,是一个历史遗留问题。

不同的实现对“质量”可能有略微不同的解释。当未指定质量时,使用一个实现特定的默认值,该值在压缩率、图像质量和编码时间之间代表一个合理的折衷。

4.12.5.6 使用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。

在某些情况下,该标志可以被重置;例如,当更改绑定到CanvasRenderingContext2Dcanvas元素的宽度高度内容属性值时,位图被清除,其源清洁标志被重置。

当使用ImageBitmapRenderingContext时,源清洁标志的值在通过transferFromImageBitmap()方法将ImageBitmap对象传输到canvas时传播。

4.12.5.7 预乘 alpha 和 2D 渲染上下文

预乘alpha指的是一种表示图像透明度的方法,另一种是非预乘alpha。

在非预乘alpha下,像素的红、绿、蓝通道表示该像素的颜色,其alpha通道表示该像素的不透明度。

然而,在预乘alpha下,像素的红、绿、蓝通道表示该像素为图像增加的颜色量,其alpha通道表示该像素遮挡其后方的程度。

例如,假设颜色通道范围从0(关闭)到255(全强度),这些示例颜色按以下方式表示:

CSS颜色表示 预乘表示 非预乘表示 颜色描述 颜色与其他内容混合的图像
rgba(255, 127, 0, 1) 255, 127, 0, 255 255, 127, 0, 255 完全不透明的橙色 An opaque orange circle sits atop a background
rgba(255, 255, 0, 0.5) 127, 127, 0, 127 255, 255, 0, 127 半透明的黄色 A yellow circle, halfway transparent, sits atop a background
不可表示 255, 127, 0, 127 不可表示 加法半透明橙色 An orange circle somewhat brightens the background that it sits atop
不可表示 255, 127, 0, 0 不可表示 加法完全透明橙色 An orange circle completely brightens the background that it sits atop
rgba(255, 127, 0, 0) 0, 0, 0, 0 255, 127, 0, 0 完全透明(“不可见”)橙色 An empty background with nothing atop it
rgba(0, 127, 255, 0) 0, 0, 0, 0 255, 127, 0, 0 完全透明(“不可见”)蓝绿色 An empty background with nothing atop it

将颜色值从非预乘表示转换为预乘表示涉及将颜色的红、绿、蓝通道乘以其alpha通道(重新映射alpha通道的范围,使“完全透明”为0,“完全不透明”为1)。

将颜色值从预乘表示转换为非预乘表示涉及相反的操作:将颜色的红、绿、蓝通道除以其alpha通道。

由于某些颜色只能在预乘alpha下表示(例如,加法颜色),而其他颜色只能在非预乘alpha下表示(例如,持有特定红、绿、蓝值的“不可见”颜色,即使没有不透明度);而在8位整数上的除法和乘法(这是画布的颜色目前存储的方式)会导致精度损失,在不完全不透明的颜色上在预乘和非预乘alpha之间转换是有损的操作。

CanvasRenderingContext2D输出位图OffscreenCanvasRenderingContext2D位图必须使用预乘alpha表示透明颜色。

对于画布位图来说,使用预乘alpha表示颜色非常重要,因为它影响了可表示颜色的范围。虽然目前无法直接在画布上绘制加法颜色,因为CSS颜色是非预乘的,无法表示它们,但仍然可以,例如,在WebGL画布上绘制加法颜色,然后通过drawImage()方法将该WebGL画布绘制到2D画布上。

4.13 自定义元素

Using_custom_elements

在所有当前引擎中支持。

Firefox63+Safari10.1+Chrome54+
Opera?Edge79+
Edge(旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

4.13.1 简介

本节非规范性。

自定义元素为作者提供了一种构建自己完全功能的DOM元素的方法。虽然作者始终可以在文档中使用非标准元素,并在事后通过脚本或类似方法添加特定于应用程序的行为,但这种元素历来都是不合规且功能不强的。通过定义自定义元素,作者可以告知解析器如何正确构建元素以及该类元素应如何对变化做出反应。

自定义元素是“合理化平台”的更大努力的一部分,通过以低级作者暴露的可扩展性点(如自定义元素定义)来解释现有的平台特性(如HTML元素)。虽然目前自定义元素在功能和语义上都有许多限制,无法完全解释HTML现有元素的行为,但我们希望随着时间的推移能够缩小这一差距。

4.13.1.1 创建一个自主自定义元素

本节非规范性。

为了说明如何创建一个自主自定义元素,让我们定义一个封装渲染国家旗帜小图标的自定义元素。我们的目标是能够像这样使用它:

<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)
4.13.1.2 创建一个与表单关联的自定义元素

本节非规范性。

添加一个值为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。例如,将其放入formlabel中,会将my-checkbox元素与它们关联,提交form时将发送my-checkbox实现提供的数据。

<form action="..." method="...">
  <label><my-checkbox name="agreed"></my-checkbox> I read the agreement.</label>
  <input type="submit">
</form>
4.13.1.3 创建一个具有默认可访问角色、状态和属性的自定义元素

本节非规范性。

通过使用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);

请注意,与内置元素一样,这些只是默认设置,可以由页面作者使用rolearia-*属性进行覆盖:

<!-- 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元素的作者应说明其rolearia-checked值是强大的原生语义,从而不鼓励类似上述的代码。

4.13.1.4 创建一个定制的内置元素

本节非规范性。

定制内置元素是一种不同类型的自定义元素,它们的定义方式和使用方式与自主自定义元素非常不同。它们的存在是为了允许重用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" });

一般来说,所扩展的元素的名称不能仅通过查看其扩展的元素接口来确定,因为许多元素共享相同的接口(例如,qblockquote都共享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元素,不能扩展诸如bgsoundblinkisindexkeygenmulticolnextidspacer等被定义为使用HTMLUnknownElement作为其元素接口的遗留元素。

这样做的一个原因是为了未来的兼容性:如果定义了一个扩展当前未知元素(例如combobox)的定制内置元素,这将阻止本规范在未来定义一个combobox元素,因为派生的定制内置元素的消费者将依赖于其基本元素没有有趣的用户代理提供行为。

4.13.1.5 自主自定义元素的缺点

本节非规范性。

如下面所述,并且如上所述,仅定义和使用名为taco-button的元素并不意味着此类元素代表按钮。也就是说,诸如网页浏览器、搜索引擎或辅助技术等工具不会仅根据其定义的名称自动将生成的元素视为按钮。

为了向各种用户传达所需的按钮语义,同时仍使用自主自定义元素,需要采用多种技术:

考虑到这些要点,一个全功能的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现有元素之上构建具有复杂行为和语义的元素,定制内置元素将更容易开发、维护和使用。

4.13.1.6 在创建之后升级元素

本节非规范性。

由于元素定义可以随时发生,非自定义元素可以创建,然后在注册适当的定义后,变成自定义元素。我们称这个过程为将元素从普通元素“升级”为自定义元素。

升级可以实现某些场景,其中可能更希望在相关元素最初创建之后(例如由解析器创建之后)再注册自定义元素定义。它们允许对自定义元素中的内容进行渐进增强。例如,在以下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>
4.13.1.7 暴露自定义元素状态

用户代理提供的内置元素具有某些状态,这些状态可以根据用户交互和其他因素随时间变化,并通过伪类向网页作者暴露。例如,一些表单控件具有“无效”状态,通过: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>

4.13.2 自定义元素构造函数和反应的要求

在编写自定义元素构造函数时,作者必须遵守以下一致性要求:

元素创建期间,这些要求中的几个要么直接要么间接地被检查,未遵守这些要求将导致无法通过解析器或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

4.13.3 核心概念

自定义元素是一个自定义的元素。非正式地,这意味着它的构造函数和原型是由作者定义的,而不是由用户代理定义的。这种由作者提供的构造函数被称为自定义元素构造函数

可以定义两种不同类型的自定义元素

Global_attributes/is

Firefox63+SafariNoChrome67+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
  1. 自主自定义元素,定义时没有extends选项。这些类型的自定义元素的本地名称等于其定义名称

  2. 定制内置元素,定义时具有extends选项。这些类型的自定义元素的本地名称等于extends选项中传递的值,它们的定义名称用作is属性的值,因此必须是有效的自定义元素名称

自定义元素创建之后,更改is属性的值不会更改元素的行为,因为它作为元素的is保存。

自主自定义元素具有以下元素定义:

类别
流内容
短语内容
可感知内容
对于与表单关联的自定义元素列表可标记可提交,以及可重置与表单关联的元素
可使用此元素的上下文
在期望短语内容的地方。
内容模型
透明
内容属性
全局属性,除is属性外
form,对于与表单关联的自定义元素——将元素与form元素关联
disabled,对于与表单关联的自定义元素——表单控件是否被禁用
readonly,对于与表单关联的自定义元素——影响willValidate,以及自定义元素作者添加的任何行为
name,对于与表单关联的自定义元素——用于表单提交form.elementsAPI中的元素名称
任何其他无命名空间的属性(见正文)。
可访问性考虑
对于与表单关联的自定义元素作者指南实现者指南
否则:作者指南实现者指南
DOM接口
由元素的作者提供(继承自HTMLElement

自主自定义元素没有任何特殊意义:它代表它的子元素。定制内置元素继承它扩展的元素的语义。

任何对元素功能相关的无命名空间属性,只要由元素作者确定,可以指定在自主自定义元素上,只要属性名称与XML兼容并且不包含ASCII大写字母。例外是is属性,不能在自主自定义元素上指定(如果指定也没有效果)。

定制内置元素遵循基于它们扩展的元素的常规属性要求。要添加基于自定义属性的行为,请使用data-*属性。


如果元素与自定义元素定义相关联且其与表单关联字段设置为true,则自主自定义元素被称为与表单关联的自定义元素

name属性表示与表单关联的自定义元素的名称。disabled属性用于使与表单关联的自定义元素不可交互,并防止其提交值被提交。form属性用于明确将与表单关联的自定义元素与其表单所有者关联。

readonly属性的与表单关联的自定义元素指定元素禁止约束验证。用户代理不会为该属性提供任何其他行为,但自定义元素作者应尽可能使用其存在使其控件以某种适当的方式不可编辑,类似于内置表单控件上的readonly属性的行为。

约束验证:如果在与表单关联的自定义元素上指定readonly属性,则元素禁止约束验证

与表单关联的自定义元素重置算法将自定义元素回调 反应排入队列,其中元素、回调名称“formResetCallback”和空参数列表。


有效的自定义元素名称是一个字符序列name,它满足以下所有要求:

这些要求确保了有效自定义元素名称的若干目标:

除了这些限制之外,还允许使用多种名称,以最大限度地灵活应对诸如<math-α><emotion-😍>等用例。

自定义元素定义描述了一个自定义元素,包括:

名称
有效的自定义元素名称
本地名称
一个本地名称
构造函数
一个Web IDLCustomElementConstructor回调函数类型值,包装自定义元素构造函数
一个观察的属性列表
一个sequence<DOMString>
一组生命周期回调
一个映射,其键为字符串"connectedCallback"、 "disconnectedCallback"、 "adoptedCallback"、 "attributeChangedCallback"、 "formAssociatedCallback"、 "formDisabledCallback"、 "formResetCallback"和"formStateRestoreCallback"。相应的值是Web IDLFunction回调函数类型值,或null。默认情况下,每个条目的值为null。
一个构造堆栈
一个列表,初始为空,由升级元素算法和HTML元素构造函数操作。列表中的每个条目要么是元素,要么是已构造标记
一个与表单关联布尔值
如果为true,用户代理将与此自定义元素定义关联的元素视为与表单关联的自定义元素
一个禁用内部布尔值
控制attachInternals()
禁用影子布尔值
控制attachShadow()

查找自定义元素定义,给定documentnamespacelocalNameis,执行以下步骤。它们将返回自定义元素定义或null:

  1. 如果namespace不是HTML命名空间,返回null。

  2. 如果document浏览上下文为null,返回null。

  3. registry成为document相关全局对象CustomElementRegistry对象。

  4. 如果registry中存在一个自定义元素定义,其namelocal name都等于localName,则返回该自定义元素定义

  5. 如果registry中存在一个自定义元素定义,其name等于islocal name等于localName,则返回该自定义元素定义

  6. 返回null。

4.13.4 CustomElementRegistry 接口

CustomElementRegistry

支持所有当前引擎。

Firefox63+Safari10.1+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

每个 Window 对象 都与一个唯一的 CustomElementRegistry 实例关联,该实例在创建 Window 对象时分配。

自定义元素注册表与 Window 对象关联, 而不是 Document 对象,因为每个 自定义元素构造函数 都继承自 HTMLElement 接口,并且每个 Window 对象只有一个 HTMLElement 接口。

Window/customElements

支持所有当前引擎。

Firefox63+Safari10.1+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

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)

CustomElementRegistry/define

支持所有当前引擎。

Firefox63+Safari10.1+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
定义一个新的 自定义元素,将给定的名称映射到给定的构造函数 作为 自主自定义元素
window.customElements.define(name, constructor, { extends: baseLocalName })
定义一个新的 自定义元素,将给定的名称映射到给定的构造函数,作为 定制内置元素,用于由提供的 baseLocalName 标识的 元素类型。 尝试扩展自定义元素或未知元素时,将引发 "NotSupportedError" DOMException
window.customElements.get(name)

CustomElementRegistry/get

支持所有当前引擎。

Firefox63+Safari10.1+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
检索为给定名称定义的自定义元素构造函数。如果没有具有给定名称的自定义元素定义,则返回 undefined。
window.customElements.getName(constructor)
检索为给定构造函数定义的自定义元素的名称。如果没有与给定构造函数的自定义元素定义,则返回 null。
window.customElements.whenDefined(name)

CustomElementRegistry/whenDefined

支持所有当前引擎。

Firefox63+Safari10.1+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
返回一个 promise,当具有给定名称的自定义元素定义完成时,该 promise 将被兑现。如果已经定义了这样的自定义元素,则返回的 promise 将立即兑现。如果没有给定有效的自定义元素名称,则返回一个带有 SyntaxError DOMException 的被拒绝的 promise。
window.customElements.upgrade(root)

CustomElementRegistry/upgrade

支持所有当前引擎。

Firefox63+Safari12.1+Chrome68+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
尝试升级 root 的所有 shadow-including 包含后代 元素, 即使它们尚未连接。

元素定义 是将一个 自定义元素定义 添加到 CustomElementRegistry 的过程。通过 define() 方法实现。当调用时, define(name, constructor, options) 方法必须执行以下步骤:

  1. 如果 IsConstructor(constructor) 为 false,则抛出 TypeError

  2. 如果 name 不是 有效的自定义元素名称,则抛出 "SyntaxError" DOMException

  3. 如果这个 CustomElementRegistry 包含一个具有 name 名称的条目,则抛出 "NotSupportedError" DOMException

  4. 如果这个 CustomElementRegistry 包含一个具有 constructor 构造函数的条目, 则抛出 "NotSupportedError" DOMException

  5. localName 设置为 name

  6. extends 设置为 optionsextends 成员的值 ,如果不存在此类成员,则为 null。

  7. 如果 extends 不为 null,则:

    1. 如果 extends 是一个 有效的自定义元素名称,则抛出 "NotSupportedError" DOMException

    2. 如果 extendsHTML 命名空间 的元素接口为 HTMLUnknownElement (例如,如果 extends 没有 表示本规范中的元素定义),则抛出 "NotSupportedError" DOMException

    3. localName 设置为 extends

  8. 如果这个 CustomElementRegistry元素定义正在运行 标志已设置,则抛出 "NotSupportedError" DOMException

  9. 设置这个 CustomElementRegistry元素定义正在运行 标志。

  10. formAssociated 设置为 false。

  11. disableInternals 设置为 false。

  12. disableShadow 设置为 false。

  13. observedAttributes 设置为空的 sequence<DOMString>

  14. 在捕获任何异常的情况下运行以下子步骤:

    1. prototype 为 ? Get(constructor, "prototype")。

    2. 如果 Type(prototype) 不是 Object, 则抛出 TypeError 异常。

    3. lifecycleCallbacks 成为一个包含键 "connectedCallback", "disconnectedCallback","adoptedCallback" 和 "attributeChangedCallback" 的映射, 每个键的值都为 null。

    4. 对于 lifecycleCallbacks 中的每个键 callbackName,按前一步列出的顺序:

      1. callbackValue 为 ? Get(prototype, callbackName)。

      2. 如果 callbackValue 不为 undefined,则将 lifecycleCallbacks 中键为 callbackName 的条目的值设置为 callbackValue 转换为 Web IDL Function 回调类型的结果。重新抛出任何来自转换的异常。

    5. 如果键 "attributeChangedCallback" 的 lifecycleCallbacks 条目的值不为 null,则:

      1. observedAttributesIterable 为 ? Get(constructor, "observedAttributes")。

      2. 如果 observedAttributesIterable 不为 undefined,则将 observedAttributes 设置为 observedAttributesIterable 转换为 sequence<DOMString> 的结果。重新抛出任何来自转换的异常。

    6. disabledFeatures 为一个空的 sequence<DOMString>

    7. disabledFeaturesIterable 为 ? Get(constructor, "disabledFeatures")。

    8. 如果 disabledFeaturesIterable 不为 undefined,则将 disabledFeatures 设置为 disabledFeaturesIterable 转换为 sequence<DOMString> 的结果。重新抛出任何来自 转换的异常。

    9. 如果 disabledFeatures 包含 "internals",则将 disableInternals 设置为 true。

    10. 如果 disabledFeatures 包含 "shadow",则将 disableShadow 设置为 true。

    11. formAssociatedValue 为 ? Get( constructor, "formAssociated")。

    12. formAssociated 设置为 formAssociatedValue 转换为 boolean 的结果。重新抛出任何来自转换的异常。

    13. 如果 formAssociated 为 true,对于每个 "formAssociatedCallback","formResetCallback", "formDisabledCallback" 和 "formStateRestoreCallback" callbackName

      1. callbackValue 为 ? Get(prototype, callbackName)。

      2. 如果 callbackValue 不为 undefined,则将 lifecycleCallbacks 中键为 callbackName 的条目的值设置为 callbackValue 转换为 Web IDL Function 回调类型的结果。重新抛出任何来自转换的异常。

    然后,无论上述步骤是否抛出异常,都执行以下子步骤:

    1. 取消设置这个 CustomElementRegistry元素定义正在运行 标志。

    最后,如果第一组子步骤抛出了异常,则重新抛出该异常(从而终止此算法)。否则,继续进行。

  15. definition 设置为一个新的 自定义元素定义,其 名称name本地名称localName构造函数constructor观察的属性observedAttributes生命周期回调lifecycleCallbacks表单关联formAssociated禁用内部disableInternals,以及 禁用阴影disableShadow

  16. definition 添加到这个 CustomElementRegistry 中。

  17. document 为这个 CustomElementRegistry相关全局 对象关联的 Document

  18. upgrade candidates 为所有符合以下条件的元素,它们是 shadow-including 包含后代 元素, 其命名空间为 HTML 命名空间 且本地名称为 localName,按 shadow-including 树顺序 排列。另外,如果 extends 非空,则仅 包括其 is 等于 name 的元素。

  19. 对于 upgrade candidates 中的每个元素 element入队一个 自定义元素升级反应 给定 elementdefinition

  20. 如果这个 CustomElementRegistrywhen-defined promise map 包含一个键为 name 的条目:

    1. promise 为该条目的值。

    2. constructor 解决 promise

    3. 从这个 CustomElementRegistrywhen-defined promise map 中删除键为 name 的条目。

当调用时,get(name) 方法必须执行以下 步骤:

  1. 如果这个 CustomElementRegistry 包含一个具有 name 名称的条目,则返回该条目的 构造函数

  2. 否则,返回 undefined。

CustomElementRegistry/getName

Firefox116+🔰 preview+Chrome117+
Opera?Edge117+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

getName(constructor) 方法的 步骤如下:

  1. 如果这个 CustomElementRegistry 包含一个具有 constructor 构造函数的条目, 则返回该条目的 名称

  2. 返回 null。

当调用时,whenDefined(name) 方法必须执行以下步骤:

  1. 如果 name 不是一个 有效的自定义元素名称,则返回 一个 被拒绝的 promise,并带有一个 "SyntaxError" DOMException

  2. 如果这个 CustomElementRegistry 包含一个具有 name 名称的条目,则返回 一个 已解决的 promise,该 promise 的值为该条目的 构造函数

  3. map 成为这个 CustomElementRegistrywhen-defined promise map

  4. 如果 map 中不包含一个键为 name 的条目,则在 map 中创建一个键为 name 且值为一个新 promise 的条目。

  5. promise 成为 map 中键为 name 的条目的值。

  6. 返回 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) 方法必须执行 以下步骤:

  1. candidates 为一个 列表,包含所有 rootshadow-including 包含后代 元素, 按 shadow-including 树 顺序 排列。

  2. 对于 candidates 中的每个 candidate尝试 升级 candidate

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!

4.13.5 升级

为了 升级一个元素,给定输入的 自定义元素定义 definition 和一个元素 element,执行以下步骤:

  1. 如果 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" 时,此步骤将使算法提前退出。

  2. element自定义元素定义 设置为 definition

  3. element自定义元素状态 设置为 "failed"。

    升级成功后,将其设置为 "custom"。现在,我们将其设置为 "failed",以便任何重入调用都会触发上面的提前退出步骤。

  4. 对于 element属性列表 中的每个 attribute,按顺序 入队一个自定义元素回调反应element,回调名称 "attributeChangedCallback",以及包含 attribute 的本地名称、null、attribute 的值和 attribute 的命名空间的参数列表。

  5. 如果 element连接的,则 入队一个自定义元素回调反应element,回调名称 "connectedCallback",以及一个空的参数列表。

  6. element 添加到 definition构造栈 的末尾。

  7. C 成为 definition构造函数

  8. 执行以下子步骤并捕获任何异常:

    1. 如果 definition禁用 shadow 为真且 elementshadow root 非空,则抛出一个 "NotSupportedError" DOMException

      这是必要的,因为 attachShadow() 不使用 查找自定义元素定义,而 attachInternals() 使用。

    2. element自定义元素状态 设置为 "precustomized"。

    3. constructResult 成为 构造 C 的结果,没有参数。

      如果 C 不符合规范地 使用带有 [CEReactions] 扩展属性的 API,则在 C 完成并控制返回此算法之前,该算法开头入队的反应将在此步骤中执行。否则,它们将在 C 和升级过程的其余部分完成后执行。

    4. 如果 SameValue(constructResult, element) 为假, 则抛出一个 TypeError

      如果 C 在调用 super() 之前构造了相同自定义元素的另一个实例,或者如果 C 使用 JavaScript 的 return 覆盖功能从构造函数返回一个任意 HTMLElement 对象,则会发生这种情况。

    然后,无论上述步骤是否抛出异常,执行以下子步骤:

    1. definition构造栈 的末尾移除最后一个条目。

      假设 C 调用了 super()(如果它是 符合规范的,则会这样做),并且调用成功,这将是替换我们在该算法开头推送的 element已构造标记。(HTML 元素构造函数 会执行此替换。)

      如果 C 没有调用 super()(即它不 符合规范),或者 HTML 元素构造函数 中的任何步骤抛出异常,则该条目仍将是 element

    最后,如果上述步骤抛出异常,则:

    1. element自定义元素定义 设置为 null。

    2. 清空 element自定义元素反应队列

    3. 重新抛出异常(从而终止此算法)。

    如果上述步骤抛出异常,则 element自定义元素状态 将保持 "failed" 或 "precustomized"。

  9. 如果 element表单关联自定义元素,则:

    1. 重置表单所有者element。如果 element 与一个 表单 元素关联,则 入队一个自定义元素回调反应element,回调名称 "formAssociatedCallback",以及 « 与之关联的 表单 »。

    2. 如果 element禁用的,则 入队一个自定义元素回调反应element,回调名称 "formDisabledCallback" 和 « true »。

  10. element自定义元素状态 设置为 "custom"。

为了 尝试升级一个元素,给定输入的 元素 element,执行以下步骤:

  1. definition 成为 查找自定义元素定义 的结果,给定 element节点文档element 的命名空间、element 的本地名称和 elementis

  2. 如果 definition 不为 null,则 入队一个自定义元素升级反应,给定 elementdefinition

4.13.6 自定义元素反应

一个 自定义元素 能够通过运行作者代码来响应某些事件:

我们将这些反应统称为 自定义元素反应

自定义元素反应 的调用方式非常谨慎,以避免在细微操作中运行作者代码。实际上,它们会被延迟到“返回用户脚本之前”。这意味着在大多数情况下,它们似乎是同步执行的,但在复杂的复合操作(如 克隆范围 操作)中,它们将延迟到所有相关用户代理处理步骤完成后,然后作为一个批次运行。

此外,这些反应的精确排序是通过一个较为复杂的队列堆栈系统来管理的,详见下文。该系统的目的是确保 自定义元素反应 总是在触发动作的相同顺序中调用,至少在单个 自定义元素 的本地上下文中。(由于 自定义元素反应 代码可以执行自己的变更,因此不可能跨多个元素提供全局排序保证。)


每个 同源窗口代理 有一个 自定义元素反应堆栈,最初为空。同源窗口代理当前元素队列 是其 元素队列 堆栈顶部的项。堆栈中的每个项目是一个 元素队列,最初也是空的。元素队列 中的每个项目都是一个元素。(这些元素不一定是 自定义的,因为该队列也用于 升级。)

每个自定义元素反应栈都有一个关联的备用元素队列,这是一个最初为空的元素队列。在影响DOM的操作过程中,如果没有通过带有[CEReactions]装饰的API,或者没有通过解析器的为标记创建元素算法,则元素会被推入备用元素队列。一个例子是用户发起的编辑操作,它会修改可编辑元素的子元素或属性。为了防止在处理备用元素队列时发生重入,每个自定义元素反应栈还有一个处理备用元素队列的标志,最初未设置。

所有元素都有一个关联的 自定义元素反应队列,最初为空。自定义元素反应队列 中的每个项目有两种类型之一:

这在以下示意图中总结:

自定义元素反应堆栈由一个元素队列堆栈组成。放大到特定队列,我们看到它包含许多元素(在我们的示例中,<x-a>,然后是 <x-b>,然后是 <x-c>)。队列中的任何特定元素都有一个自定义元素反应队列。放大到自定义元素反应队列,我们看到它包含各种排队的反应(在我们的示例中,升级,然后属性更改,然后另一个属性更改,然后连接)。

为了 在适当的元素队列中入队一个元素,给定一个元素 element,运行以下步骤:

  1. reactionsStack 成为 element相关代理自定义元素反应堆栈

  2. 如果 reactionsStack 为空,则:

    1. element 添加到 reactionsStack备用元素 队列 中。

    2. 如果 reactionsStack处理备用元素 队列 标志已设置,则返回。

    3. 设置 reactionsStack处理备用元素 队列 标志。

    4. 排队一个 微任务 以执行以下步骤:

      1. 调用自定义元素反应reactionsStack备用元素队列 中。

      2. 取消设置 reactionsStack处理备用元素 队列 标志。

  3. 否则,将 element 添加到 element相关 代理当前元素队列 中。

为了 入队一个自定义元素回调反应,给定一个 自定义 元素 element,一个回调名称 callbackName 和一个参数列表 args,执行以下步骤:

  1. definition 成为 element自定义元素定义

  2. callback 成为 definition生命周期 回调 中 键为 callbackName 的条目的值。

  3. 如果 callback 为 null,则返回。

  4. 如果 callbackName 为 "attributeChangedCallback",则:

    1. attributeName 成为 args 的第一个元素。

    2. 如果 definition观察到的 属性 不包含 attributeName,则返回。

  5. 将一个新的 回调反应 添加到 element自定义元素 反应队列 中,使用回调函数 callback 和参数 args

  6. 将一个元素入队到 适当的元素队列,给定 element

为了 入队一个自定义元素升级反应,给定一个元素 element 和一个 自定义元素定义 definition,执行以下步骤:

  1. 将一个新的 升级反应 添加到 element自定义元素 反应队列 中,包含 自定义元素定义 definition

  2. 将一个元素入队到 适当的元素队列,给定 element

为了 调用自定义元素反应 在一个 元素队列 queue 中,执行以下步骤:

  1. queue 不是 时:

    1. element 成为 出队queue 的结果。

    2. reactions 成为 element自定义元素反应 队列

    3. 重复直到 reactions 为空:

      1. 移除 reactions 的第一个元素,并让 reaction 成为该元素。根据 reaction 的类型切换:

        升级反应

        升级 element,使用 reaction自定义元素定义

        如果这引发了异常,捕获它,并为 reaction报告,针对 reaction自定义元素定义构造函数的相应 JavaScript 对象的关联领域全局对象

        回调反应

        调用 reaction 的回调函数,使用 reaction 的参数和 "report",并将 回调此值 设置为 element


为了确保 自定义元素反应 被适当地触发,我们引入了 [CEReactions] IDL 扩展属性。它表示相关算法需要补充额外步骤,以便适当地跟踪和调用 自定义元素反应

这个 [CEReactions] 扩展属性不得带参数,不得出现在操作、属性、设置器或删除器之外。此外,它不得出现在只读属性上。

带有 [CEReactions] 扩展属性的操作、属性、设置器或删除器必须运行以下步骤来代替其描述中指定的步骤:

  1. 推入 一个新的 元素队列 到该对象的 相关代理自定义元素反应堆栈

  2. 运行原始指定的步骤,捕获任何异常。如果步骤返回一个值,则让 value 成为返回的值。如果它们引发异常,则让 exception 成为引发的异常。

  3. queue 成为 弹出 的结果,从该对象的 相关代理自定义元素反应堆栈

  4. 调用自定义元素反应queue 中。

  5. 如果原始步骤引发了异常 exception,重新引发 exception

  6. 如果原始步骤返回了值 value,返回 value

这个扩展属性的意图有些微妙。实现其目标的一种方法是说平台上的每个操作、属性、设置器和删除器都必须插入这些步骤,并允许实现者优化不必要的情况(在没有可能导致 自定义元素反应 发生的 DOM 变更时)。

然而,实际上这种不精确性可能会导致 自定义元素反应 的非互操作实现,因为某些实现可能会忘记在某些情况下调用这些步骤。相反,我们选择了显式注释所有相关 IDL 构造的方法,以确保互操作行为并帮助实现者轻松定位这些步骤所需的所有情况。

任何用户代理引入的非标准 API,如果可能修改 DOM 以导致 入队一个自定义元素回调反应入队一个 自定义元素升级反应,例如通过修改任何属性或子元素,必须也带有 [CEReactions] 属性。

在撰写本文时,已知以下非标准或尚未标准化的 API 属于此类:

4.13.7 元素内部

某些功能是为了自定义元素作者可用,但不是自定义元素使用者。这些功能由 element.attachInternals() 方法提供,该方法返回一个 ElementInternals 实例。 ElementInternals 的属性和方法允许控制用户代理提供给所有元素的内部功能。

element.attachInternals()

返回一个 ElementInternals 对象,目标为 自定义元素 element。如果 element 不是一个 自定义元素,如果 "internals" 特性在元素定义中被禁用,或者在同一个元素上调用两次,则抛出异常。

每个 HTMLElement 都有一个 附加内部(为空或一个 ElementInternals 对象),初始为空。

HTMLElement/attachInternals

Support in all current engines.

Firefox93+Safari16.4+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

attachInternals() 方法的步骤如下:

  1. 如果 thisis 不为空,则抛出 "NotSupportedError" DOMException

  2. definition 成为 查找自定义元素定义 的结果,给定 this节点文档、其命名空间、其本地名称和 null 作为 is

  3. 如果 definition 为空,则抛出 "NotSupportedError" DOMException

  4. 如果 definition禁用内部 为真,则抛出 "NotSupportedError" DOMException

  5. 如果 this附加内部 不为空,则抛出 "NotSupportedError" DOMException

  6. 如果 this自定义元素状态 不是 "precustomized" 或 "custom",则抛出 "NotSupportedError" DOMException

  7. 设置 this附加内部 为一个新的 ElementInternals 实例,其 目标元素this

  8. 返回 this附加内部

4.13.7.1 ElementInternals 接口

ElementInternals

支持所有当前引擎。

Firefox93+Safari16.4+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

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 都有一个 目标元素, 这是一个 自定义元素

4.13.7.2 Shadow 根访问
internals.shadowRoot

返回 ShadowRoot 用于 internals目标元素,如果 目标元素shadow 主机,否则为 null。

ElementInternals/shadowRoot

支持所有当前引擎。

Firefox93+Safari16.4+Chrome88+
Opera?Edge88+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

shadowRoot 获取器步骤如下:

  1. targetthis目标元素

  2. 如果 target 不是 shadow 主机,则返回 null。

  3. shadowtargetshadow 根

  4. 如果 shadow对元素内部可用 为 false,则返回 null。

  5. 返回 shadow

4.13.7.3 表单关联的自定义元素
internals.setFormValue(value)

internals目标元素状态提交值 都设置为 value

如果 value 为 null,则元素不会参与表单提交。

internals.setFormValue(value, state)

internals目标元素提交值 设置为 value,并将其 状态 设置为 state

如果 value 为 null,则元素不会参与表单提交。

internals.form

返回 internals目标元素表单所有者

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

返回一个 NodeList,包含所有与 internals目标元素 相关联的 label 元素。

每个 表单关联的自定义元素 都有一个 提交值。它用于在表单提交时提供一个或多个 条目提交值 的初始值为 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" 之一。

ElementInternals/setFormValue

支持所有当前引擎。

Firefox98+Safari16.4+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

setFormValue(value, state) 方法步骤如下:

  1. element 成为 this目标元素

  2. 如果 element 不是 表单关联的自定义元素,则抛出 "NotSupportedError" DOMException

  3. 如果value不是FormData对象,则将目标元素提交值设置为value,否则设置为value克隆条目列表

  4. 如果函数的 state 参数被省略,则将 element状态 设置为其 提交值

  5. 否则,如果 stateFormData 对象,则将 element状态 设置为 state条目列表克隆

  6. 否则,将 element状态 设置为 state


每个 表单关联的自定义元素 都有名为 valueMissingtypeMismatchpatternMismatchtooLongtooShortrangeUnderflowrangeOverflowstepMismatchcustomError 的有效性标志。它们的初始值为 false。

每个 表单关联的自定义元素 都有一个 验证消息 字符串。它的初始值为空字符串。

每个 表单关联的自定义元素 都有一个 验证锚 元素。它的初始值为 null。

ElementInternals/setValidity

支持所有当前引擎。

Firefox98+Safari16.4+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

setValidity(flags, message, anchor) 方法步骤如下:

  1. element 成为 this目标元素

  2. 如果 element 不是 表单关联的自定义元素,则抛出 "NotSupportedError" DOMException

  3. 如果 flags 包含一个或多个 true 值并且 message 未给定或为空字符串,则抛出 TypeError

  4. 对于 flags 的每个条目 flagvalue,将 element 的名为 flag 的有效性标志设置为 value

  5. 如果未给定 messageelement 的所有有效性标志均为 false,则将 element验证消息 设置为空字符串,否则设置为 message

  6. 如果 elementcustomError 有效性标志为 true,则将 element自定义有效性错误消息 设置为 element验证消息。否则,将 element自定义有效性错误消息 设置为空字符串。

  7. 如果未给定 anchor,则将 element验证锚 设置为 null。否则,如果 anchor 不是 包含影子的后代, 则抛出 "NotFoundError" DOMException。否则,将 element验证锚 设置为 anchor

ElementInternals/validationMessage

支持所有当前引擎。

Firefox98+Safari16.4+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

validationMessage getter 步骤如下:

  1. element 成为 this目标元素

  2. 如果 element 不是 表单关联的自定义元素,则抛出 "NotSupportedError" DOMException

  3. 返回 element验证消息

条目构建算法 适用于 表单关联的自定义元素,给定一个元素 element 和一个 条目列表 entry list,包括以下步骤:

  1. 如果 element提交值 是一个 列表条目,则将 element 的每个 提交值 添加到 entry list,并返回。

    在这种情况下,用户代理不会引用 name 内容属性值。 表单关联的自定义元素 的实现负责决定 条目 的名称。它们可以是 name 内容属性值,它们可以是基于 name 内容属性值的字符串,也可以与 name 内容属性无关。

  2. 如果元素没有指定 name 属性,或者其 name 属性值为空字符串,则返回。

  3. 如果元素的 提交值 不为 null,则使用 name 属性值和 提交值 创建一个条目,并将其添加到 entry list

4.13.7.4 可访问性语义
internals.role [ = value ]

设置或获取 internals目标元素的默认 ARIA 角色,除非页面作者使用 role 属性覆盖它。

internals.aria* [ = value ]

设置或获取 internals目标元素的各种默认 ARIA 状态或属性值,除非页面作者使用 aria-* 属性覆盖它们。

每个自定义元素都有一个内部内容属性映射,这是一个映射,最初为空。有关其如何影响平台可访问性 API 的信息,请参见与 ARIA 和平台可访问性 API 相关的要求部分。

4.13.7.5 自定义状态伪类
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>;
};

对于statesgetter步骤是返回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");

4.14 常见惯用法,无专用元素

4.14.1 面包屑导航

本规范未提供描述面包屑导航菜单的机器可读方式。建议作者仅在段落中使用一系列链接。可以使用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>

4.14.2 标签云

本规范未定义用于标记一组页面的关键字列表(也称为标签云)的任何特定标记。通常,建议作者使用带有明确内联计数的ul元素来标记此类列表,然后使用样式表隐藏这些计数并将其转换为表现效果,或者使用SVG。

这里包含了一个短标签云中的三个标签:

<style>
.tag-cloud > li > span { display: none; }
.tag-cloud > li { display: inline; }
.tag-cloud-1 { font-size: 0.7em; }
.tag-cloud-2 { font-size: 0.9em; }
.tag-cloud-3 { font-size: 1.1em; }
.tag-cloud-4 { font-size: 1.3em; }
.tag-cloud-5 { font-size: 1.5em; }

@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),因为顺序并不特别重要:尽管列表实际上是按字母顺序排列的,但如果按标签长度排序,它传达的信息也会相同。

这些a元素没有使用tagrel-关键词,因为它们并不代表应用于页面本身的标签;它们只是列出标签本身的索引的一部分。

4.14.3 对话

本规范没有定义用于标记对话、会议记录、聊天记录、剧本对话、即时消息日志以及其他不同参与者轮流发言的情况的特定元素。

相反,鼓励作者使用p元素和标点符号来标记对话。需要标记发言者以便样式化的作者,建议使用spanb。用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>

4.14.4 脚注

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>

对于图表或表格,脚注可以包含在相关的figcaptioncaption元素中,或在周围的文章中。

在此示例中,表格中包含有脚注的单元格,并在文章中给出脚注。使用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>

4.15 禁用元素

一个元素被称为实际禁用,如果它是以下之一:

这个定义用于确定哪些元素是可聚焦的,以及哪些元素匹配:enabled:disabled伪类

4.16 使用选择器和 CSS 匹配 HTML 元素

4.16.1 CSS 'attr()' 函数的大小写敏感性

CSS 值和单位'attr()' 函数中属性名称的大小写敏感性留给宿主语言定义。[CSSVALUES]

当将 CSS 'attr()' 函数的属性名称部分与 HTML 元素HTML 文档 中的无命名空间属性名称进行比较时,CSS 'attr()' 函数的名称部分必须首先被 转换为 ASCII 小写。当与其他属性进行比较时,函数必须根据其原始大小写进行比较。在这两种情况下,要匹配的值必须 相同(因此比较是区分大小写的)。

这与下一节中指定的 CSS 属性选择器 的名称部分比较相同。

4.16.2 选择器的大小写敏感性

选择器 将元素名称、属性名称和属性值的大小写敏感性留给宿主语言定义。[SELECTORS]

当将 CSS 元素 类型选择器HTML 元素HTML 文档 中进行比较时,CSS 元素 类型选择器 必须首先被 转换为 ASCII 小写。当与其他元素进行比较时,选择器必须根据其原始大小写进行比较。在这两种情况下,要匹配的值必须 相同(因此比较是区分大小写的)。

当将 CSS 属性选择器 的名称部分与 HTML 元素HTML 文档 中的属性名称进行比较时,CSS 属性选择器 的名称部分必须首先被 转换为 ASCII 小写。当与其他属性进行比较时,选择器必须根据其原始大小写进行比较。在这两种情况下,比较都是区分大小写的。

属性选择器HTML 元素HTML 文档 中必须将以下名称的属性的 视为 ASCII 不区分大小写

例如,选择器[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"]将在怪异模式下也将其值视为区分大小写。

4.16.3 伪类

伪类

有许多动态选择器可以与 HTML 一起使用。本节定义了这些选择器何时与 HTML 元素匹配。 [SELECTORS] [CSSUI]

:defined

:defined

在所有当前引擎中支持。

Firefox63+Safari10+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

:defined 伪类必须匹配任何已定义的元素。

:link

:link

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera3.5+Edge79+
Edge (旧版)12+Internet Explorer3+
Firefox Android?Safari iOS3.2+Chrome Android?WebView Android1.5+Samsung Internet?Opera Android?
:visited

:visited

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera3.5+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

所有具有 a 元素的 href 属性的元素,以及所有具有 area 元素的 href 属性的元素,必须匹配 :link:visited 之一。

其他规范可能会应用更具体的规则,规定这些元素如何匹配这些 伪类,以缓解某些隐私问题,这些问题适用于此要求的直接实现。

:active

:active

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera5+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

:active 伪类 被定义为匹配用户正在 激活 的元素。

为了确定某个特定元素是否被激活,以定义 :active 伪类,HTML 用户代理必须使用以下列表中的第一个相关条目。

如果该元素是 button 元素
如果该元素是 input 元素,并且其 type 属性处于 提交按钮图像按钮重置按钮按钮 状态
如果该元素是具有 href 属性的 a 元素
如果该元素是具有 href 属性的 area 元素
如果该元素是 可聚焦的 元素

如果元素 被激活,则它处于 正式激活状态

例如,如果用户通过按下空格键使用键盘按下一个 button 元素,则该元素将在接收到 keydown 事件和接收到 keyup 事件之间匹配此 伪类

如果该元素被 主动指向

该元素 被激活

一个元素在用户开始表示触发元素的激活行为的意图时处于 正式激活状态,并且在用户停止表示触发元素的激活行为的意图时,或者元素的激活行为运行完成时,或者以先到者为准。

一个元素在用户使用指示设备指示元素时,并且指示设备处于“按下”状态(例如,对于鼠标,在按下鼠标按钮和释放鼠标按钮之间;对于多点触控环境中的手指,当手指触摸显示表面时),被称为 被主动指向

根据 Selectors 中的定义,:active 还匹配被 激活 的元素的 扁平树 祖先。 [SELECTORS]

此外,任何作为当前匹配 :activelabel 元素的 标记控件 的元素也匹配 :active。 (但它不算作被 激活。)

:hover

:hover

在所有当前引擎中支持。

Firefox1+Safari2+Chrome1+
Opera4+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

:hover 伪类 被定义为匹配用户用指示设备指示的元素。在定义 :hover 伪类 时,HTML 用户代理必须将元素视为用户用指示设备指示的元素。

根据 Selectors 中的定义,:hover 还匹配被 扁平树 祖先的元素指定[SELECTORS]

此外,任何作为当前匹配 :hoverlabel 元素的 标记控件 的元素也匹配 :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" 的元素通过被 指定 匹配;labelp 元素通过 Selectors 中的扁平树祖先条件匹配; 以及 ID 为 "c" 的元素通过上述关于 标记控件 的附加条件匹配(即其 label 元素匹配 :hover)。但是,ID 为 "b" 的元素不匹配 :hover:其扁平树后代未被指定,尽管该扁平树后代匹配 :hover

:focus

:focus

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera7+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

对于 CSS :focus 伪类,一个元素具有焦点时:

:target

:target

在所有当前引擎中支持。

Firefox1+Safari1.3+Chrome1+
Opera9.5+Edge79+
Edge (旧版) 12+Internet Explorer9+
Firefox Android?Safari iOS2+Chrome Android?WebView Android2+Samsung Internet?Opera Android10.1+

对于 CSS :target 伪类文档的目标元素是包含 文档目标元素 的列表,如果它不为空,否则包含没有元素的列表。 [SELECTORS]

:popover-open

:popover-open

在所有当前引擎中支持。

Firefox🔰 114+Safari预览版+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

:popover-open 伪类 被定义为匹配任何 HTML 元素,其 popover 属性不处于 无弹出框状态,并且其 弹出框可见性状态显示 状态。

:enabled

:enabled

在所有当前引擎中支持。

Firefox1+Safari3.1+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android2+Samsung Internet?Opera Android10.1+

:enabled 伪类 必须匹配任何 buttoninputselecttextareaoptgroupoptionfieldset 元素,或未被 实际禁用表单关联自定义元素

:disabled

:disabled

在所有当前引擎中支持。

Firefox1+Safari3.1+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android2+Samsung Internet?Opera Android10.1+

:disabled 伪类 必须匹配任何被 实际禁用 的元素。

:checked

:checked

在所有当前引擎中支持。

Firefox1+Safari3.1+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android4+Safari iOS?Chrome Android18+WebView Android2+Samsung Internet?Opera Android10.1+

:checked 伪类 必须匹配以下类别中的任何元素:

:indeterminate

:indeterminate

在所有当前引擎中支持。

Firefox2+Safari3+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

:indeterminate 伪类 必须匹配以下类别中的任何元素:

:default

:default

在所有当前引擎中支持。

Firefox4+Safari5+Chrome10+
Opera10+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

:default 伪类 必须匹配以下类别中的任何元素:

:placeholder-shown

:placeholder-shown 伪类 必须匹配以下类别中的任何元素:

:valid

:valid

在所有当前引擎中支持。

Firefox4+Safari5+Chrome10+
Opera10+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

:valid 伪类 必须匹配以下类别中的任何元素:

:invalid

:invalid

在所有当前引擎中支持。

Firefox4+Safari5+Chrome10+
Opera10+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

:invalid 伪类 必须匹配以下类别中的任何元素:

:user-valid

:user-valid 伪类 必须匹配 inputtextareaselect 元素,其 用户有效性 为 true、约束验证候选,并且 满足其约束

:user-invalid

:user-invalid 伪类 必须匹配 inputtextareaselect 元素,其 用户有效性 为 true、约束验证候选,但不 满足其约束

:in-range

:in-range

在所有当前引擎中支持。

Firefox29+Safari5.1+Chrome10+
Opera11+Edge79+
Edge (旧版)13+Internet Explorer不支持
Firefox Android16+Safari iOS?Chrome Android?WebView Android2.2+Samsung Internet1.0+Opera Android11+

:in-range 伪类 必须匹配所有 候选约束验证 元素,具有范围限制,且既不 存在下溢 也不 存在上溢 的元素。

:out-of-range

:out-of-range

所有当前引擎都支持。

Firefox29+ Safari5.1+ Chrome10+
Opera11+ Edge79+
Edge (旧版)13+ Internet Explorer不支持
Firefox Android16+ Safari iOS? Chrome Android? WebView Android2.2+ Samsung Internet? Opera Android11+

:out-of-range 伪类 必须匹配作为 约束验证候选 的所有元素、具有 范围限制 并且 范围不足范围超出

:required

:required

在所有当前引擎中支持。

Firefox4+Safari5+Chrome10+
Opera10+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android4.4.3+Samsung Internet?Opera Android10.1+

:required 伪类 必须匹配以下类别中的任何元素:

:optional

:optional

在所有当前引擎中支持。

Firefox4+Safari5+Chrome10+
Opera10+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

:optional 伪类 必须匹配任何属于以下类别的元素:

:autofill

:autofill

Firefox86+Safari15+Chrome🔰 1+
Opera?Edge🔰 79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS15+Chrome Android?WebView Android?Samsung Internet?Opera Android?
:-webkit-autofill

:autofill:-webkit-autofill 伪类 必须匹配已被用户代理自动填充的 input 元素。当用户编辑自动填充字段时,这些伪类必须停止匹配。

这种自动填充可能的一种方式是通过 autocomplete 属性,但即使没有该属性,用户代理也可以进行自动填充。

:read-only

:read-only

在所有当前引擎中支持。

Firefox78+Safari4+Chrome1+
Opera9+Edge79+
Edge (旧版)13+Internet Explorer不支持
Firefox Android🔰 4+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+
:read-write

:read-write

在所有当前引擎中支持。

Firefox78+Safari4+Chrome1+
Opera9+Edge79+
Edge (旧版)13+Internet Explorer不支持
🔰 4+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

:read-write 伪类 必须匹配属于以下类别的任何元素,出于选择器的目的,这些类别被认为是 用户可变的[SELECTORS]

:read-only 伪类 必须匹配所有其他 HTML 元素

:modal

:modal 伪类 必须匹配属于以下类别的任何元素:

:dir(ltr)

:dir

Firefox49+Safari16.4+Chrome不支持
Opera?Edge不支持
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

:dir(ltr) 伪类 必须匹配所有 方向性 为 'ltr' 的元素。

:dir(rtl)

:dir(rtl) 伪类 必须匹配所有 方向性 为 'rtl' 的元素。

自定义状态伪类

:state(identifier) 伪类必须匹配所有 自定义元素,其 状态集集合条目 包含 identifier

:playing

:playing 伪类 必须匹配所有 媒体元素,其 paused 属性为假。

:paused

:paused 伪类 必须匹配所有 媒体元素,其 paused 属性为真。

:seeking

:seeking 伪类 必须匹配所有 媒体元素,其 seeking 属性为真。

:buffering

:buffering 伪类 必须匹配所有 媒体元素,其 paused 属性为假,networkState 属性为 NETWORK_LOADING,且准备状态为 HAVE_CURRENT_DATA 或更低。

:stalled

:stalled 伪类 必须匹配所有 媒体元素,其匹配 :buffering 伪类,且 当前停滞 为真。

:muted

:muted 伪类 必须匹配所有 媒体元素,其 静音

:volume-locked

:volume-locked 伪类 必须匹配所有 媒体元素,当用户代理的 音量锁定 为真时。

本规范未定义元素何时匹配 :lang() 动态 伪类,因为在 选择器 中以与语言无关的方式已足够详细地定义。[SELECTORS]

5 微数据

5.1 介绍

5.1.1 概述

本节是非规范性的。

有时候,希望用特定的机器可读标签来注释内容,例如允许通用脚本提供针对页面定制的服务,或使来自不同作者的内容能够被单一脚本一致地处理。

为此,作者可以使用本节中描述的微数据功能。微数据允许在文档中添加名称-值对的嵌套组,与现有内容并行存在。

5.1.2 基本语法

本节是非规范性的。

从高层次来看,微数据由一组名称-值对组成。每组称为项目,每个名称-值对是一个属性。项目和属性由常规元素表示。

要创建一个项目,使用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元素及其value属性。

这里使用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"。唯一的区别是,如果用户将标题从文档中拖出,在前一种情况下,该项目将包含在拖放数据中。在任何情况下,图像都不会与该项目有任何关联。

5.1.3 类型化项目

本节是非规范性的。

前一节中的示例显示了如何在不期望其微数据被重用的页面上标记信息。然而,微数据在其他作者和读者能够合作以新的方式使用标记的上下文中最有用。

为此,有必要为每个项目赋予一个类型,例如 "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列表来赋予一个项目。然而,如果两个类型不使用相同的词汇表,则不能为一个项目赋予这两个类型。

5.1.4 项目的全局标识符

本节是非规范性的。

有时候,一个项目提供了关于一个有全局标识符的话题的信息。例如,书籍可以通过其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

5.1.5 定义词汇表时选择名称

本节是非规范性的。

使用微数据意味着使用词汇表。对于某些目的,即席词汇表就足够了。对于其他情况,则需要设计一个词汇表。在可能的情况下,鼓励作者重用现有词汇表,因为这使内容重用更容易。

在设计新词汇表时,可以使用URL创建标识符,或者,对于属性,可以使用简单的单词(不带点或冒号)。对于URL,通过只使用对应作者控制页面的标识符,可以避免与其他词汇表冲突。

例如,如果Jon和Adam分别在example.comhttps://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

5.2 编码微数据

5.2.1 微数据模型

微数据模型由称为项目的名称-值对组组成。

每个组称为一个项目。每个项目可以有项目类型全局标识符(如果由项目类型指定的词汇表支持项目的全局标识符),以及一个名称-值对列表。名称-值对中的每个名称称为属性,每个属性有一个或多个。每个要么是一个字符串,要么本身就是一个名称-值对组(即一个项目)。名称相对于彼此是无序的,但如果某个特定名称有多个值,它们确实有相对顺序。

5.2.2 项目

Global_attributes/itemscope

Support in all current engines.

FirefoxYesSafariYesChromeYes
Opera?EdgeYes
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

每个HTML 元素可以指定一个itemscope属性。itemscope属性是一个布尔属性

具有itemscope属性的元素会创建一个新的项目,即一组名称-值对。


Global_attributes/itemtype

Support in all current engines.

FirefoxYesSafariYesChromeYes
Opera?EdgeYes
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

具有itemscope属性的元素可以指定一个itemtype属性,以提供该项目的类型

如果指定,itemtype属性必须具有一个值,该值是无序的一组唯一空格分隔的标记,其中没有任何标记与其他标记相同,每个标记都是有效的URL字符串,且是一个绝对URL,并且所有标记都使用相同的词汇表。属性的值必须至少有一个标记。

项目类型项目通过按ASCII空白符分割元素的itemtype属性的值获得的标记。如果itemtype属性缺失或以这种方式解析没有找到标记,则该项目被认为没有项目类型

项目类型必须都是适用规范中定义的类型,且必须都使用相同的词汇表。

除非该规范另有规定,否则作为项目类型给出的URL不应被自动取消引用。

规范可以定义其项目类型可以取消引用以提供帮助信息。例如,词汇表的作者被鼓励在给定的URL处提供有用的信息。

项目类型是不透明的标识符,用户代理不得取消引用未知的项目类型或以其他方式解构它们,以确定如何处理使用它们的项目

没有指定itemscope属性的元素不得指定itemtype属性。


当一个项目具有项目类型或它是属性时,该项目被称为类型化项目相关类型对于一个类型化项目来说是该项目项目类型,如果它有任何类型,或者是它作为属性项目相关类型


Global_attributes/itemid

Support in all current engines.

FirefoxYesSafariYesChromeYes
Opera?EdgeYes
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

具有itemscope属性和引用定义为支持项目的全局标识符的词汇表的itemtype属性的元素,也可以指定一个itemid属性,以提供该项目的全局标识符,以便它可以与网页其他地方的其他项目相关联。

如果指定,itemid属性必须具有一个有效的可能被空格包围的URL值。

全局标识符项目的其元素的itemid属性的值(如果有的话),相对于指定属性的元素的节点文档进行解析。如果itemid属性缺失或解析失败,则该项目被认为没有全局标识符

没有同时指定itemscope属性和itemtype属性的元素,不得指定itemid属性,且具有itemscope属性但其itemtype属性指定了不支持项目全局标识符的词汇表的元素,也不得指定itemid属性,如该词汇表规范所定义。

全局标识符的确切含义由词汇表的规范确定。这样的规范负责定义是否允许存在具有相同全局标识符的多个项目(无论在同一页面上还是在不同页面上),以及在处理具有相同ID的多个项目时该词汇表的处理规则是什么。


Global_attributes/itemref

Support in all current engines.

FirefoxYesSafariYesChromeYes
Opera?EdgeYes
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

具有itemscope属性的元素可以指定itemref属性,以提供额外的元素列表,以便遍历找到该项目的名称-值对。

如果指定,itemref属性必须具有一个无序的一组唯一空格分隔的标记,其中没有任何标记与其他标记相同,并且由同一中的元素ID组成。

没有指定itemscope属性的元素不得指定itemref属性。

itemref 属性不是微数据数据模型的一部分。它只是一个语法构造,旨在帮助作者在数据不遵循方便的树结构时添加注释。例如,它允许作者在表格中标记数据,以便每列定义一个单独的项目,同时将属性保留在单元格中。

此示例显示了一个用于描述模型铁路制造商产品的简单词汇表。该词汇表只有五个属性名称:

product-code
制造商目录中产品的名称。
name
产品的简要描述。
scale
“HO”、“1”或“Z”(可能带有前导或尾随空格)之一,表示产品的比例。
digital
如果存在,则为“Digital”、“Delta”或“Systems”之一(可能带有前导或尾随空格),表示产品具有给定类型的数字解码器。
track-type
对于特定轨道产品,为“K”、“M”、“C”(可能带有前导或尾随空格)之一,表示产品适用的轨道类型。

此词汇表定义了四种项目类型

https://md.example.com/loco
有引擎的滚动库存
https://md.example.com/passengers
客运滚动库存
https://md.example.com/track
轨道片
https://md.example.com/lighting
带有照明设备

使用此词汇表的每个项目可以根据产品的不同分配一个或多个这些类型。

因此,机车可以标记为:

<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>

在创建新词汇表时需要非常小心。通常,可以采取层次化的方法来处理类型,从而产生一个每个项目只有一个类型的词汇表,这通常更容易管理。

5.2.3 名称:itemprop 属性

Global_attributes/itemprop

Support in all current engines.

FirefoxYesSafariYesChromeYes
Opera?EdgeYes
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

每个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>

5.2.4

由具有itemprop属性的元素添加的名称-值对的属性值如下列表中第一个匹配的情况所示:

如果该元素也具有itemscope属性

该值是由该元素创建的项目

如果该元素是meta元素

该值是该元素的content属性的值(如果有),如果没有此属性,则为空字符串。

如果该元素是audioembediframeimgsourcetrackvideo元素

该值是根据元素的src属性的值进行编码、解析和序列化URL的结果,相对于元素的节点文档,在设置属性时,如果没有此属性或结果为失败,则为空字符串。

如果该元素是aarealink元素

该值是根据元素的href属性的值进行编码、解析和序列化URL的结果,相对于元素的节点文档,在设置属性时,如果没有此属性或结果为失败,则为空字符串。

如果该元素是object元素

该值是根据元素的data属性的值进行编码、解析和序列化URL的结果,相对于元素的节点文档,在设置属性时,如果没有此属性或结果为失败,则为空字符串。

如果该元素是data元素

该值是该元素的value属性的值(如果有),否则为空字符串。

如果该元素是meter元素

该值是该元素的value属性的值(如果有),否则为空字符串。

如果该元素是time元素

该值是该元素的datetime值

否则

该值是该元素的后代文本内容

URL属性元素aareaaudioembediframeimglinkobjectsourcetrackvideo元素。

如果属性的,如属性定义所述,是一个绝对URL,则必须使用URL属性元素来指定该属性。

这些要求仅因为属性值恰好匹配URL的语法而适用。它们仅在属性明确定义为采用此类值时才适用。

例如,关于首次登月的书可以被称为“mission:moon”。定义标题为字符串的词汇表中的“title”属性不会期望在a元素中给出标题,即使它看起来像一个URL。另一方面,如果有一个(范围非常狭窄的!)词汇表,用于“标题看起来像URL的书籍”,其中的“title”属性被定义为接受URL,那么该属性期望在a元素(或其他URL属性元素之一)中给出标题,因为上述要求。

5.2.5 将名称与项目关联

为了找到由元素root定义的项目的属性,用户代理必须运行以下步骤。这些步骤也用于标记微数据错误

  1. resultsmemorypending成为空的元素列表。

  2. 将元素root添加到memory中。

  3. 如果有的话,将root的子元素添加到pending中。

  4. 如果root具有itemref属性,按ASCII空白符分割itemref属性的值。对于每个生成的标记ID,如果root中有一个具有IDID的元素,则将第一个这样的元素添加到pending中。

  5. pending不为空时:

    1. pending中移除一个元素,并将该元素设为current

    2. 如果current已经在memory中,则存在微数据错误继续

    3. current添加到memory中。

    4. 如果current没有itemscope属性,则:将current的所有子元素添加到pending中。

    5. 如果current具有指定的itemprop属性并且具有一个或多个属性名称,则将current添加到results中。

  6. 按照树顺序results进行排序。

  7. 返回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"的项目,一个是:

work
images/house.jpeg
title
The house I found.
license
http://www.opensource.org/licenses/mit-license.php

...另一个是:

work
images/mailbox.jpeg
title
The mailbox.
license
http://www.opensource.org/licenses/mit-license.php

5.2.6 微数据和其他命名空间

目前,itemscopeitemprop和其他微数据属性仅为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 -->

5.3 示例微数据词汇表

本节中的词汇表主要用于演示如何指定词汇表,但它们本身也是可用的。

5.3.1 vCard

具有 项目类型 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-namegiven-nameadditional-namehonorific-prefixhonorific-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

提供个人或组织的昵称。

昵称是代替或附加于个人、地点或事物的描述性名称。它还可以用于指定由 fnn 属性指定的正式名称的熟悉形式。

必须是文本。

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在任意数量的名为 nickname 的属性。

photo

提供个人或组织的照片。

必须是一个绝对 URL

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在任意数量的名为 photo 的属性。

bday

提供个人或组织的出生日期。

必须是一个有效日期字符串

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在一个名为 bday 的属性。

anniversary

提供个人或组织的纪念日。

必须是一个有效日期字符串

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在一个名为 anniversary 的属性。

sex

提供个人的生物性别。

必须是以下之一:

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在一个名为 sex 的属性。

gender-identity

提供个人的性别认同。

必须是文本。

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在一个名为 gender-identity 的属性。

adr

提供个人或组织的邮寄地址。

必须是一个具有零个或多个 typepost-office-boxextended-addressstreet-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

必须是一个绝对 URL

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在任意数量的名为 impp 的属性。

lang

提供个人或组织理解的语言。

必须是有效的 BCP 47 语言标签。[BCP47]

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在任意数量的名为 lang 的属性。

tz

提供个人或组织的时区。

必须是文本,并且必须符合以下语法:

  1. 要么是 U+002B 加号字符 (+),要么是 U+002D 连字符 (-)。
  2. 一个 有效的非负整数,它恰好是两位数长,表示 00..23 范围内的一个数字。
  3. 一个 U+003A 冒号字符 (:)。
  4. 一个 有效的非负整数,它恰好是两位数长,表示 00..59 范围内的一个数字。

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在任意数量的名为 tz 的属性。

geo

提供个人或组织的地理位置。

必须是文本,并且必须符合以下语法:

  1. 可选地,要么是 U+002B 加号字符 (+),要么是 U+002D 连字符 (-)。
  2. 一个或多个 ASCII 数字
  3. 可选地*,一个 U+002E 句号字符 (.),后面跟一个或多个 ASCII 数字
  4. 一个 U+003B 分号字符 (;)。
  5. 可选地,要么是 U+002B 加号字符 (+),要么是 U+002D 连字符 (-)。
  6. 一个或多个 ASCII 数字
  7. 可选地*,一个 U+002E 句号字符 (.),后面跟一个或多个 ASCII 数字

标有星号 (*) 的可选组件应包含在内,并且应各有六位数。

值指定纬度和经度,按此顺序(即“LAT LON”顺序),以十进制度数表示。经度表示以本初子午线为界的东、西位置,分别用正实数和负实数表示。纬度表示以赤道为界的南、北位置,分别用正实数和负实数表示。

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在任意数量的名为 geo 的属性。

title

提供个人或组织的职务、职能或职位。

必须是文本。

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在任意数量的名为 title 的属性。

role

提供个人或组织的角色、职业或业务类别。

必须是文本。

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在任意数量的名为 role 的属性。

提供个人或组织的标志。

必须是一个绝对 URL

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在任意数量的名为 的属性。

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

必须是一个绝对 URL

在类型为 http://microformats.org/profile/hcard项目中,如果该项目还有一个名为 kind 的属性,其值为 "group",则可以存在任意数量的名为 member 的属性。

related

提供与另一个实体的关系。

必须是一个具有一个 url 属性和一个 rel 属性的项目

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在任意数量的名为 related 的属性。

url (inside related)

提供相关实体的 URL

必须是一个绝对 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

提供与个人或组织相关的声音文件。

必须是一个绝对 URL

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在任意数量的名为 sound 的属性。

uid

提供与个人或组织相对应的全球唯一标识符。

必须是文本。

在每个类型为 http://microformats.org/profile/hcard项目中,可以存在一个名为 uid 的属性。

url

提供与个人或组织相关的 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

代表此实体行事的其他实体。

contact
acquaintance
friend
met
worker
colleague
resident
neighbor
child
parent
sibling
spouse
kin
muse
crush
date
sweetheart
me

具有 XFN 定义的意义。[XFN]

5.3.1.1 转换为vCard

给定 文档 中的节点列表 nodes,用户代理必须运行以下算法来 提取这些节点表示的任何 vCard 数据(仅返回第一个 vCard):

  1. 如果 nodes 中没有任何节点是 ,其 项类型http://microformats.org/profile/hcard,则没有 vCard。中止算法,不返回任何内容。

  2. node 成为 nodes 中的第一个 ,其 项类型http://microformats.org/profile/hcard 的节点。

  3. output 成为空字符串。

  4. 添加一个 vCard 行,类型为 "BEGIN",值为 "VCARD" 到 output

  5. 添加一个 vCard 行,类型为 "PROFILE",值为 "VCARD" 到 output

  6. 添加一个 vCard 行,类型为 "VERSION",值为 "4.0" 到 output

  7. 添加一个 vCard 行,类型为 "SOURCE",值为文档的 URL转义的 vCard 文本字符串output

  8. 如果 title 元素 不为 null,添加一个 vCard 行,类型为 "NAME",值为 title 元素后代文本内容转义的 vCard 文本字符串output

  9. sex 成为空字符串。

  10. gender-identity 成为空字符串。

  11. 对于每个作为 项的属性的元素 element:对于每个在 属性名称 中的名称 name,运行以下子步骤:

    1. parameters 成为空的名称-值对集合。

    2. 从以下列表中运行适当的子步骤集。这些步骤将设置一个变量 value,在下一步中使用。

      如果属性的 是一个 subitemnamen
      1. value 成为空字符串。

      2. subitem 中名为 family-name 的第一个 vCard 子属性的结果附加到 value

      3. 将一个 U+003B 分号字符 (;) 附加到 value
      4. subitem 中名为 given-name 的第一个 vCard 子属性的结果附加到 value

      5. 将一个 U+003B 分号字符 (;) 附加到 value
      6. subitem 中名为 additional-name 的第一个 vCard 子属性的结果附加到 value

      7. 将一个 U+003B 分号字符 (;) 附加到 value
      8. subitem 中名为 honorific-prefix 的第一个 vCard 子属性的结果附加到 value

      9. 将一个 U+003B 分号字符 (;) 附加到 value
      10. subitem 中名为 honorific-suffix 的第一个 vCard 子属性的结果附加到 value

      如果属性的 是一个 subitemnameadr
      1. value 成为空字符串。

      2. subitem 中名为 post-office-box 的 vCard 子属性集合的结果附加到 value

      3. 将一个 U+003B 分号字符 (;) 附加到 value
      4. subitem 中名为 extended-address 的 vCard 子属性集合的结果附加到 value

      5. 将一个 U+003B 分号字符 (;) 附加到 value
      6. subitem 中名为 street-address 的 vCard 子属性集合的结果附加到 value

      7. 将一个 U+003B 分号字符 (;) 附加到 value
      8. subitem 中名为 locality 的第一个 vCard 子属性的结果附加到 value

      9. 将一个 U+003B 分号字符 (;) 附加到 value
      10. subitem 中名为 region 的第一个 vCard 子属性的结果附加到 value

      11. 将一个 U+003B 分号字符 (;) 附加到 value
      12. subitem 中名为 postal-code 的第一个 vCard 子属性的结果附加到 value

      13. 将一个 U+003B 分号字符 (;) 附加到 value
      14. subitem 中名为 country-name 的第一个 vCard 子属性的结果附加到 value

      15. 如果 subitem 中有名为 type 的属性,并且第一个此类属性的 不是 ,且其值仅由 ASCII 字母数字 组成,则添加一个名为 "TYPE" 的参数,其值为该属性的 parameters

      如果属性的 是一个 subitemnameorg
      1. value 成为空字符串。

      2. subitem 中名为 organization-name 的第一个 vCard 子属性的结果附加到 value

      3. 对于 subitem 中每个名为 organization-unit 的属性,运行以下步骤:

        1. 如果属性的 ,则跳过此属性。

        2. 将一个 U+003B 分号字符 (;) 附加到 value

        3. 将该属性的 转义的 vCard 文本字符串 的结果附加到 value

      如果属性的 是一个 subitem,其 项类型http://microformats.org/profile/hcardnamerelated
      1. value 成为空字符串。

      2. 如果 subitem 中有名为 url 的属性,并且其元素是 URL 属性元素,则将该属性的 转义的 vCard 文本字符串 的结果附加到 value,并添加一个名为 "VALUE" 且值为 "URI" 的参数到 parameters

      3. 如果 subitem 中有名为 rel 的属性,并且第一个此类属性的 不是 ,且其值仅由 ASCII 字母数字 组成,则添加一个名为 "RELATION" 且值为该属性 的参数到 parameters

      如果属性的 是一个 name 不在上述任何一种情况
      1. value 成为 subitem 中名为 value 的第一个 vCard 子属性的结果。

      2. 如果在subitem中有一个名为type的属性,并且第一个此类属性的不是,且其值仅包含ASCII 字母数字字符,则添加一个名为"TYPE"的参数,其值为该属性的parameters

      如果属性的 不是 且其 namesex

      如果这是找到的第一个此类属性,则将 sex 设置为属性的

      如果属性的 不是 且其 namegender-identity

      如果这是找到的第一个此类属性,则将 gender-identity 设置为属性的

      否则(属性的 不是
      1. value 成为属性的

      2. 如果 elementURL 属性元素 之一,则添加一个名为 "VALUE" 且值为 "URI" 的参数到 parameters

      3. 否则,如果 namebdayanniversaryvalue有效日期字符串,则添加一个名为 "VALUE" 且值为 "DATE" 的参数到 parameters

      4. 否则,如果 namerevvalue有效全球日期和时间字符串,则添加一个名为 "VALUE" 且值为 "DATE-TIME" 的参数到 parameters

      5. value 中的每个 U+005C 反斜杠字符 (\) 前面加上另一个 U+005C 反斜杠字符 (\)。

      6. value 中的每个 U+002C 逗号字符 (,) 前面加上一个 U+005C 反斜杠字符 (\)。

      7. 除非 namegeo,否则在 value 中的每个 U+003B 分号字符 (;) 前面加上一个 U+005C 反斜杠字符 (\)。

      8. 用一个 U+005C 反斜杠字符 (\) 后跟一个 U+006E 拉丁小写字母 n 字符 (n) 替换 value 中的每对 U+000D 回车 U+000A 换行字符 (CRLF)。

      9. 用一个 U+005C 反斜杠字符 (\) 后跟一个 U+006E 拉丁小写字母 n 字符 (n) 替换 value 中剩余的每个 U+000D 回车 (CR) 或 U+000A 换行 (LF) 字符。

    3. 添加一个 vCard 行,类型为 name,参数为 parameters,值为 valueoutput

  12. 如果 sexgender-identity 的值不是空字符串,添加一个 vCard 行,类型为 "GENDER",值由 sex、一个 U+003B 分号字符 (;) 和 gender-identity 连接而成到 output

  13. 添加一个 vCard 行,类型为 "END",值为 "VCARD" 到 output

当上述算法要求用户代理 添加一个 vCard 行,由类型 type,可选参数和值 value 组成到字符串 output 时,它必须运行以下步骤:

  1. line 成为空字符串。

  2. type 转换为 ASCII 大写 附加到 line

  3. 如果有任何参数,则按添加的顺序依次为每个参数运行这些子步骤:

    1. 将一个 U+003B 分号字符 (;) 附加到 line

    2. 将参数的名称附加到 line

    3. 将一个 U+003D 等号字符 (=) 附加到 line

    4. 将参数的值附加到 line

  4. 将一个 U+003A 冒号字符 (:) 附加到 line

  5. value 附加到 line

  6. maximum length 设为 75。

  7. line码点长度 大于 maximum length 时:

    1. line 的前 maximum length 个码点附加到 output

    2. line 中移除前 maximum length 个码点。

    3. 将一个 U+000D 回车字符 (CR) 附加到 output

    4. 将一个 U+000A 换行字符 (LF) 附加到 output

    5. 将一个 U+0020 空格字符附加到 output

    6. maximum length 设为 74。

  8. line 的剩余部分附加到 output

  9. 将一个 U+000D 回车字符 (CR) 附加到 output

  10. 将一个 U+000A 换行字符 (LF) 附加到 output

当上述步骤要求用户代理获取名为 subnamevCard 子属性集合 的结果时,用户代理必须运行以下步骤:

  1. value 成为空字符串。

  2. 对于 subitem 中每个名为 subname 的属性,运行以下子步骤:

    1. 如果属性的 本身是 ,则跳过此属性。

    2. 如果这是 subitem 中名为 subname 的第一个属性(忽略之前步骤跳过的任何属性),则在 value 中附加一个 U+002C 逗号字符 (,)。

    3. 将该属性的 转义的 vCard 文本字符串 的结果附加到 value

  3. 返回 value

当上述步骤要求用户代理获取名为 subname第一个 vCard 子属性 的结果时,用户代理必须运行以下步骤:

  1. 如果 subitem 中没有名为 subname 的属性,则返回空字符串。

  2. 如果 subitem 中第一个名为 subname 的属性的 ,则返回空字符串。

  3. 返回 subitem 中第一个名为 subname 的属性的 转义的 vCard 文本字符串 的结果。

当上述算法要求用户代理 转义 vCard 文本字符串 value 时,用户代理必须使用以下步骤:

  1. value 中的每个 U+005C 反斜杠字符 (\) 前面加上另一个 U+005C 反斜杠字符 (\)。

  2. value 中的每个 U+002C 逗号字符 (,) 前面加上一个 U+005C 反斜杠字符 (\)。

  3. value 中的每个 U+003B 分号字符 (;) 前面加上一个 U+005C 反斜杠字符 (\)。

  4. 用一个 U+005C 反斜杠字符 (\) 后跟一个 U+006E 拉丁小写字母 n 字符 (n) 替换 value 中的每对 U+000D 回车 U+000A 换行字符 (CRLF)。

  5. 用一个 U+005C 反斜杠字符 (\) 后跟一个 U+006E 拉丁小写字母 n 字符 (n) 替换 value 中剩余的每个 U+000D 回车 (CR) 或 U+000A 换行 (LF) 字符。

  6. 返回变更后的 value

如果输入不符合 http://microformats.org/profile/hcard 项类型定义的属性名称 的规则,此算法可能会生成无效的 vCard 输出。

5.3.1.2 示例

本节为非规范性内容。

以下是一个名为“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

5.3.2 vEvent

具有项目类型http://microformats.org/profile/hcalendar#vevent的项表示一个事件。

该词汇不支持项目的全局标识符

以下是该类型的定义属性名。它们基于互联网日历和调度核心对象规范iCalendar)中定义的词汇,可以在那里找到有关如何解释这些值的更多信息。[RFC5545]

这里只使用了iCalendar词汇中与事件相关的部分;该词汇无法表达完整的iCalendar实例。

attach

提供与事件相关的文档地址。

必须是一个绝对URL

每个具有类型http://microformats.org/profile/hcalendar#vevent中可以存在任意数量名称为attach的属性。

categories

提供事件可以分类的类别或标签的名称。

必须是文本。

每个具有类型http://microformats.org/profile/hcalendar#vevent中可以存在任意数量名称为categories的属性。

class

提供有关事件信息的访问分类。

必须是以下值之一的文本:

这只是建议性的,不能视为保密措施。

每个具有类型http://microformats.org/profile/hcalendar#vevent中可以存在一个名称为class的属性。

comment

提供有关事件的评论。

必须是文本。

每个具有类型http://microformats.org/profile/hcalendar#vevent中可以存在任意数量名称为comment的属性。

description

提供事件的详细描述。

必须是文本。

每个具有类型description中可以存在一个名称为description的属性。

geo

提供事件的地理位置。

必须是文本,并且必须符合以下语法:

  1. 可选地,一个U+002B加号字符(+)或一个U+002D连字符(-)。
  2. 一个或多个ASCII数字
  3. 可选地,一个U+002E句点字符(.),后跟一个或多个ASCII数字
  4. 一个U+003B分号字符(;)。
  5. 可选地,一个U+002B加号字符(+)或一个U+002D连字符(-)。
  6. 一个或多个ASCII数字
  7. 可选地,一个U+002E句点字符(.),后跟一个或多个ASCII数字

标有星号(*)的可选组件应包括在内,并且每个组件应有六位数字。

该值指定纬度和经度,按顺序(即“LAT LON”排序),以十进制度数表示。经度表示东、西方向的经度,分别用正或负实数表示。纬度表示北、南方向的纬度,分别用正或负实数表示。

每个具有类型http://microformats.org/profile/hcalendar#vevent中可以存在一个名称为geo的属性。

location

提供事件的地点。

必须是文本。

每个具有类型location中可以存在一个名称为location的属性。

resources

提供事件所需的资源。

必须是文本。

每个具有类型resources中可以存在任意数量名称为resources的属性。

status

提供事件的确认状态。

必须是以下值之一的文本:

每个具有类型status中可以存在一个名称为status的属性。

summary

提供事件的简短摘要。

必须是文本。

用户代理在使用该值时应将值中的U+000A换行符(LF)字符替换为U+0020空格字符。

每个具有类型summary中可以存在一个名称为summary的属性。

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

提供事件开始的日期和时间。

必须是一个有效日期字符串或一个有效的全球日期和时间字符串

每个具有类型dtstart中必须存在一个名称为dtstart的属性。

duration

提供事件的持续时间。

必须是一个有效的事件持续时间字符串

表示的持续时间是值中整数表示的所有持续时间的总和。

每个具有类型duration中可以存在一个名称为duration的属性,只要该http://microformats.org/profile/hcalendar#vevent没有名称为dtend的属性。

transp

提供事件在日历中是否被视为占用时间,以用于自由-忙碌时间搜索。

必须是以下值之一的文本:

每个具有类型transp中可以存在一个名称为transp的属性。

contact

提供事件的联系信息。

必须是文本。

每个具有类型contact中可以存在任意数量名称为contact的属性。

url

提供事件的URL

必须是一个绝对URL

每个具有类型url中可以存在一个名称为url的属性。

uid

提供与事件相对应的全球唯一标识符。

必须是文本。

每个具有类型uid中可以存在一个名称为uid的属性。

exdate

提供尽管有重复规则,但事件不发生的日期和时间。

必须是一个有效日期字符串或一个有效的全球日期和时间字符串

每个具有类型exdate中可以存在任意数量名称为exdate的属性。

rdate

提供事件重复发生的日期和时间。

必须是以下之一的文本:

每个具有类型rdate中可以存在任意数量名称为rdate的属性。

rrule

提供一个规则,用于查找事件发生的日期和时间。

必须是符合iCalendar中定义的RECUR值类型的文本。[RFC5545]

每个具有类型rrule中可以存在一个名称为rrule的属性。

created

提供事件信息首次在日历系统中创建的日期和时间。

必须是一个有效的全球日期和时间字符串

每个具有类型created中可以存在一个名称为created的属性。

last-modified

提供事件信息在日历系统中最后修改的日期和时间。

必须是一个有效的全球日期和时间字符串

每个具有类型last-modified中可以存在一个名称为last-modified的属性。

sequence

提供事件信息的修订号。

必须是一个有效的非负整数

每个具有类型sequence中可以存在一个名称为sequence的属性。

字符串是有效的事件持续时间字符串,如果它符合以下模式:

  1. 一个U+0050拉丁大写字母P字符(P)。

  2. 以下之一:

5.3.2.1 转换为 iCalendar

给定文档中的节点列表nodes,用户代理必须运行以下算法来提取由这些节点表示的任何vEvent数据

  1. 如果nodes中的任何节点都不是具有类型http://microformats.org/profile/hcalendar#vevent,则没有vEvent数据。中止算法,不返回任何内容。

  2. output为空字符串。

  3. 添加一个iCalendar行,类型为"BEGIN",值为"VCALENDAR"到output

  4. 添加一个iCalendar行,类型为"PRODID",值为表示用户代理的用户代理特定字符串到output

  5. 添加一个iCalendar行,类型为"VERSION",值为"2.0"到output

  6. 对于nodes中每个具有类型http://microformats.org/profile/hcalendar#vevent节点node,运行以下步骤:

    1. 添加一个iCalendar行,类型为"BEGIN",值为"VEVENT"到output

    2. 添加一个iCalendar行,类型为"DTSTAMP",值为表示当前日期和时间的iCalendar DATE-TIME字符串,并带有注释"VALUE=DATE-TIME",到output[RFC5545]

    3. 对于node属性元素element的每个名称name,运行以下适当的子步骤:

      如果属性的是一个

      跳过该属性。

      如果属性是dtend
      如果属性是dtstart
      如果属性是exdate
      如果属性是rdate
      如果属性是created
      如果属性是last-modified

      value是从属性的中去除所有U+002D连字符(-)和U+003A冒号(:)字符的结果。

      如果属性的是一个有效日期字符串,则添加一个iCalendar行,类型为name,值为valueoutput,并带有注释"VALUE=DATE"。

      否则,如果属性的是一个有效的全球日期和时间字符串,则添加一个iCalendar行,类型为name,值为valueoutput,并带有注释"VALUE=DATE-TIME"。

      否则,跳过该属性。

      否则

      添加一个iCalendar行,类型为name,值为属性的output

    4. 添加一个iCalendar行,类型为"END",值为"VEVENT"到output

  7. 添加一个iCalendar行,类型为"END",值为"VCALENDAR"到output

当上述算法要求用户代理添加一个iCalendar行,其由类型type,值value和可选的 注释组成,到字符串output时,它必须运行以下步骤:

  1. line为空字符串。

  2. type转换为ASCII大写,并附加到line

  3. 如果有注释:

    1. line后附加一个U+003B分号字符(;)。

    2. 将注释附加到line

  4. line后附加一个U+003A冒号字符(:)。

  5. value中的每个U+005C反斜杠字符(\)前添加另一个U+005C反斜杠字符(\)。

  6. value中的每个U+002C逗号字符(,)前添加一个U+005C反斜杠字符(\)。

  7. value中的每个U+003B分号字符(;)前添加一个U+005C反斜杠字符(\)。

  8. value中的每个U+000D回车字符(U+000A换行字符)对(CRLF)替换为一个U+005C反斜杠字符(\)后跟一个U+006E拉丁小写字母n字符(n)。

  9. value中的每个剩余的U+000D回车字符(CR)或U+000A换行字符(LF)替换为一个U+005C反斜杠字符(\)后跟一个U+006E拉丁小写字母n字符(n)。

  10. value附加到line

  11. maximum length为75。

  12. line代码点长度大于maximum length时:

    1. line的前maximum length个代码点附加到output

    2. line中移除前maximum length个代码点。

    3. output后附加一个U+000D回车字符(CR)。

    4. output后附加一个U+000A换行字符(LF)。

    5. output后附加一个U+0020空格字符。

    6. maximum length为74。

  13. 将(剩余的)line附加到output

  14. output后附加一个U+000D回车字符(CR)。

  15. output后附加一个U+000A换行字符(LF)。

如果输入不符合http://microformats.org/profile/hcalendar#vevent的类型和定义的属性名称的规则,此算法可能会生成无效的iCalendar输出。

5.3.2.2 示例

本节是非规范性的。

下面是一个使用 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>

5.3.3 许可作品

具有 项目类型 http://n.whatwg.org/work 的项代表一部作品(例如文章、图像、视频、歌曲等)。此类型主要用于允许作者包含作品的许可信息。

以下是该类型的定义属性名称

work

标识所描述的作品。

必须是绝对URL

每个具有类型 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

标识作品可用的许可证之一。

必须是绝对URL

每个具有类型 http://n.whatwg.org/work中可以存在任意数量名称为 license 的属性。

5.3.3.1 示例

本节是非规范性的。

这个示例展示了一张嵌入的图片,标题为 我的池塘,同时根据 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>

5.4 将 HTML 转换为其他格式

5.4.1 JSON

给定 Document 中的节点列表 nodes,用户代理必须运行以下算法,将这些节点中的微数据提取为 JSON 形式:

  1. result 为一个空对象。

  2. items 为一个空数组。

  3. 对于 nodes 中的每个 node,检查该元素是否是 顶级微数据项,如果是,则获取该元素的对象并将其添加到 items 中。

  4. result 添加一个名为 "items" 的条目,其值为数组 items

  5. 返回 result 序列化为 JSON 的结果,以最短的方式表示(即在标记之间没有空白,没有数字中的不必要的零,并且仅对没有专用转义序列的字符使用 Unicode 转义),并在合适的时候在数字表示中使用小写 "e"。[JSON]

该算法返回一个带有单一属性的对象,该属性是一个数组,而不是直接返回数组,以便在必要时将来可以扩展该算法。

当用户代理需要获取项的对象 item 时,可以选择传递一个元素列表 memory,它必须运行以下子步骤:

  1. result 为一个空对象。

  2. 如果没有传递 memory,则令 memory 为一个空列表。

  3. item 添加到 memory 中。

  4. 如果 item 具有任何项类型,则向 result 添加一个名为 "type" 的条目,其值为一个数组,按 itemtype 属性中指定的顺序列出 item项类型

  5. 如果 item 具有全局标识符,则向 result 添加一个名为 "id" 的条目,其值为 item全局标识符

  6. properties 为一个空对象。

  7. 对于具有一个或多个属性名称的每个元素 element,并且是 item属性中的一个,按算法返回的顺序,运行以下子步骤:

    1. valueelement属性值

    2. 如果 value,则:如果 valuememory 中,则令 value 为字符串 "ERROR"。否则,获取 value 的对象,传递 memory 的副本,然后用这些步骤返回的对象替换 value

    3. 对于 element 的每个属性名 name,运行以下子步骤:

      1. 如果 properties 中没有名为 name 的条目,则向 properties 添加一个名为 name 的条目,其值为一个空数组。

      2. value 添加到 properties 中名为 name 的条目中。

  8. result 添加一个名为 "properties" 的条目,其值为对象 properties

  9. 返回 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" ]
}
}
]
}
}
]
}

6 用户交互

6.1 hidden 属性

Global_attributes/hidden

仅在一个引擎中支持。

Firefox不支持Safari不支持Chrome102+
Opera不支持Edge102+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Global_attributes/hidden

支持所有当前引擎。

Firefox4+Safari5.1+Chrome10+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android4+Samsung Internet?Opera Android?

所有 HTML 元素 可以设置 hidden 内容属性。 hidden 属性是一个 枚举属性,具有以下关键词和状态:

关键词 状态 简要描述
hidden hidden 不会被渲染。
(空字符串)
until-found hidden until found 不会被渲染,但内容可以通过 find-in-pagefragment navigation 访问。

该属性的 缺失值默认值not hidden 状态,其 无效值默认值hidden 状态。

当一个元素具有 hidden 属性并处于 hidden 状态时,表示该元素尚未或不再与页面的当前状态直接相关,或者它用于声明将由页面其他部分重用的内容,而不是由用户直接访问。 用户代理不应渲染处于 hidden 状态的元素。此要求可以通过样式层间接实现。例如,Web 浏览器可以通过 在渲染部分建议的规则 实现这些要求。

当一个元素具有 hidden 属性并处于 hidden until found 状态时,表示该元素像 hidden 状态一样被隐藏,但元素内部的内容可以通过 find-in-pagefragment navigation 访问。当这些功能尝试滚动到目标在元素子树内时,用户代理将删除 hidden 属性以显示内容,然后再滚动到它。除了删除 hidden 属性外,还会在删除 hidden 属性之前触发一个名为 beforematch 的事件。

Web 浏览器在 hidden 属性处于 hidden until found 状态时,将使用 'content-visibility: hidden' 而不是 'display: none',如 渲染部分 中所述。

由于此属性通常使用 CSS 实现,因此也可以使用 CSS 覆盖它。例如,对所有元素应用 'display: block' 的规则将取消 hidden 状态的效果。因此,作者在编写样式表时必须小心,以确保属性仍按预期样式呈现。此外,不支持 hidden until found 状态的旧版用户代理将使用 'display: none' 而不是 'content-visibility: hidden',因此建议作者确保其样式表不会更改 hidden until found 元素的 'display' 或 'content-visibility' 属性。

由于具有 hidden 属性并处于 hidden until found 状态的元素使用 'content-visibility: hidden' 而不是 'display: none',因此 hidden until found 状态与 hidden 状态有两个不同之处:

  1. 元素需要受 布局包含 的影响,才能通过页面查找显示出来。这意味着如果处于 hidden until found 状态的元素的 'display' 值为 'none'、'contents' 或 'inline',则该元素不会被页面查找显示。

  2. 元素在 生成框 时 仍会具有一个框,这意味着边框、外边距和内边距仍会在元素周围呈现。

在以下示例中,属性用于在用户登录之前隐藏网页游戏的主屏幕:

  <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>

hidden 属性不得用于隐藏可以在其他显示中合法显示的内容。例如,使用 hidden 隐藏选项卡对话框中的面板是错误的,因为选项卡界面只是一个溢出显示——同样可以只显示一个带有滚动条的大页面上的所有表单控件。类似地,使用此属性隐藏内容只是因为一种显示是不正确的——如果某些内容被标记为 hidden,它会在所有显示中隐藏,包括例如屏幕阅读器。

自身没有 hidden 的元素不得 超链接hidden 的元素。 for 属性的 labeloutput 元素如果没有 hidden 属性,也不得引用 hidden 的元素。 在这两种情况下,这种引用会导致用户困惑。

然而,元素和脚本可以在其他上下文中引用 hidden 的元素。

例如,使用 href 属性链接到带有 hidden 属性的部分是不正确的。 如果内容不适用或不相关,则没有理由链接到它。

然而,使用 ARIA aria-describedby 属性引用隐藏的描述是可以的。 虽然隐藏描述意味着它们本身没有用处,但它们可以以某种方式编写,使它们在从它们描述的元素引用的特定上下文中有用。

类似地,具有 canvas 元素带有 hidden 属性的情况可以用作脚本图形引擎的屏外缓冲区,表单控件可以使用其 form 属性引用一个隐藏的 form 元素。

hidden 属性隐藏的部分中的元素仍然是活动的,例如,这些部分中的脚本和表单控件仍然分别执行和提交。 只有它们的展示给用户的方式发生了变化。

HTMLElement/hidden

支持所有当前引擎。

Firefox4+Safari5.1+Chrome6+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android12+

hidden 获取步骤如下:

  1. 如果 hidden 属性处于 hidden until found 状态,则返回 "until-found"。

  2. 如果设置了 hidden 属性,则返回 true。

  3. 返回 false。

hidden 设置步骤如下:

  1. 如果给定值是与 "until-found" ASCII 不区分大小写匹配的字符串, 则将 hidden 属性设置为 "until-found"。

  2. 否则,如果给定值为 false,则移除 hidden 属性。

  3. 否则,如果给定值为空字符串,则移除 hidden 属性。

  4. 否则,如果给定值为 null,则移除 hidden 属性。

  5. 否则,如果给定值为 0,则移除 hidden 属性。

  6. 否则,如果给定值为 NaN,则移除 hidden 属性。

  7. 否则,将 hidden 属性设置为空字符串。

祖先 hidden-until-found 显示算法 的步骤如下:

  1. currentNode平树 中具有父节点时:

    1. 如果 currentNode 具有 hidden 属性并处于 hidden until found 状态,则:

      1. 触发一个事件,名为beforematch, 在currentNode上。

      2. currentNode中移除hidden属性。

    2. currentNode 设置为 currentNode平树 中的父节点。

6.2 页面可见性

可遍历导航项系统可见性状态,包括其创建时的初始值,由用户代理决定。它表示,例如,浏览器窗口是否最小化,浏览器标签当前是否在后台,或者系统元素(如任务切换器)是否遮挡了页面。

当用户代理确定 系统可见性状态 对于 可遍历导航项 traversable 已更改为 newState 时,它必须执行以下步骤:

  1. navigablestraversable活动文档包含的后代导航项

  2. 对每个 navigable 进行迭代 navigables 按什么顺序?

    1. documentnavigable活动文档

    2. 用户交互任务源 上针对 document相关全局对象 更新文档的可见性状态,将 newState 应用于 document

Document 有一个 可见性状态,可以是 "hidden" 或 "visible",初始值为 "hidden"。

Document/visibilityState

支持所有当前引擎。

Firefox18+Safari7+Chrome33+
Opera20+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android4.4.3+Samsung Internet?Opera Android20+

visibilityState 获取步骤如下,返回 this可见性状态

Document/hidden

支持所有当前引擎。

Firefox18+Safari7+Chrome33+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android4.4.3+Samsung Internet?Opera Android12.1+

hidden 获取步骤如下,如果 this可见性状态 为 "hidden",则返回 true,否则返回 false。

更新 Document 的可见性状态 documentvisibilityState,请执行以下步骤:

  1. 如果 document可见性状态 等于 visibilityState,则返回。

  2. document可见性状态 设置为 visibilityState

  3. 队列 一个新的 VisibilityStateEntry,其 可见性状态visibilityState,其 时间戳当前高分辨率时间,适用于 document相关全局对象

  4. 运行 屏幕方向更改步骤,适用于 document[SCREENORIENTATION]

  5. 运行 视图转换页面可见性更改步骤,适用于 document

  6. 运行其他规范中可能定义的任何 页面可见性更改步骤,包括 可见性状态document

    规范作者最好提交 pull request,将调用直接添加到他们的规范中,而不是使用 页面可见性更改步骤 钩子,以确保跨规范调用顺序的良好定义。截至撰写本文时,以下规范已知具有 页面可见性更改步骤,它们将以未指定的顺序运行:Device Posture APIWeb NFC[DEVICEPOSTURE] [WEBNFC]

  7. document 上触发一个名为 visibilitychange 的事件,其 bubbles 属性初始化为 true。

6.2.1 VisibilityStateEntry 接口

VisibilityStateEntry

仅在一个引擎中支持。

Firefox不支持Safari不支持Chrome115+
Opera?Edge115+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

VisibilityStateEntry 接口从文档变为活跃状态起公开可见性更改。

例如,这允许页面中的 JavaScript 代码检查可见性更改与绘制时间的相关性:
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" 可见性状态

name 获取步骤如下,返回 this可见性状态

entryType 获取步骤如下,返回 "visibility-state"。

startTime 获取步骤如下,返回 this时间戳

duration 获取步骤如下,返回 0。

6.3 惰性子树

另见 inert 以了解同名属性的解释。

节点(特别是元素和文本节点)可以是惰性的。当一个节点是惰性时:

惰性节点通常不能被聚焦,用户代理不会将惰性节点暴露给无障碍 API 或辅助技术。作为命令的惰性节点将如上所述变得无法操作。

然而,用户代理可以允许用户覆盖对页面查找和文本选择的限制。

默认情况下,节点不是惰性的。

文档 document 如果 subjectdocument顶层 中最顶层的 对话框 元素,则 subject模态对话框阻塞。 当 document 被如此阻塞时,除了 subject 元素及其 平树 后代外,每个与 document 连接 的节点都必须变得 惰性

subject 还可以通过 inert 属性变为惰性,但只有在 subject 本身上指定时(即 subject 可以逃避祖先的惰性);subject扁平树 后代可以以类似方式变为惰性

对话框 元素的 showModal() 方法通过 对话框 元素添加到其 节点文档顶层,触发此机制。

6.3.2 inert 属性

Global_attributes/inert

支持所有当前引擎。

Firefox112+Safari15.5+Chrome102+
Opera?Edge102+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

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 属性的元素的后代。这将确保所有用户都能访问此文本,而惰性内容无法被任何人交互。

默认情况下,没有持久的视觉指示元素或其子树是惰性的。此类内容的适当视觉样式通常取决于上下文。例如,惰性的屏外导航面板不需要默认样式,因为其屏外位置在视觉上遮挡了内容。同样,模态 对话框 元素的背景将用作视觉上遮挡网页惰性内容的手段,而不是专门样式化惰性内容。

然而,对于许多其他情况,强烈建议作者清楚地标明文档的哪些部分是活动的,哪些是惰性的,以避免用户混淆。特别值得记住的是,并非所有用户都能同时看到页面的所有部分;例如,屏幕阅读器用户、小设备或放大镜用户,甚至使用特别小窗口的用户可能无法看到页面的活动部分,如果惰性部分没有明显标明是惰性的,可能会感到沮丧。

HTMLElement/inert

支持所有当前引擎。

Firefox112+Safari15.5+Chrome102+
Opera?Edge102+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

inert IDL 属性必须 反映 同名内容属性。

6.4 跟踪用户激活

为了防止某些可能令用户讨厌的 API 滥用(例如,打开弹出窗口或振动手机),用户代理仅在用户主动与网页交互或至少与页面交互过一次时才允许使用这些 API。这种“主动交互”状态通过本节定义的机制来维护。

6.4.1 数据模型

为了跟踪用户激活,每个 窗口 W 有两个相关的值:

用户代理还定义了一个短暂激活持续时间,这是一个常量,用于指示用户激活在某些用户激活控制的 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 没有必须使用的时间限制。

上次激活时间戳上次历史操作激活时间戳 即使在 文档 更改其完全活跃状态后(例如,在导航离开 文档 后,或导航到缓存的 文档 后)仍然保留。这意味着粘性激活状态跨越多个导航,只要相同的 文档 被重用。对于短暂激活状态,原始到期时间保持不变(即,该状态仍在从原始激活触发输入事件起的短暂激活持续时间限制内到期)。在决定是否基于粘性激活短暂激活时,考虑这一点非常重要。

6.4.2 处理模型

当用户交互在文档document中触发激活触发输入事件时,用户代理必须在调度事件之前执行以下激活通知步骤:

  1. 断言document完全活跃的。

  2. windows为«document相关全局对象»。

  3. 扩展windows,包括document的每个祖先可导航活跃窗口

  4. 扩展windows,包括document的每个后代可导航活跃窗口,过滤掉仅包含其可导航的那些documentdocument相同的。

  5. 对每个windowwindows中:

    1. window上次激活时间戳设置为当前高分辨率时间

    2. 在给定window的情况下,通知关闭观察者管理器关于用户激活

激活触发输入事件是任何其isTrusted属性为 true 且其type为以下之一的事件:

激活消耗 API在本规范和其他规范中定义,可以通过执行以下步骤来消耗用户激活,给定一个窗口W

  1. 如果W可导航为 null,则返回。

  2. topW可导航顶层可遍历

  3. navigablestop活跃文档包含的后代可导航

  4. windows为通过获取navigables中每个项目的活跃窗口构造的窗口对象的列表。

  5. 对每个windowwindows中,如果window上次激活时间戳不是正无穷大,则将window上次激活时间戳设置为负无穷大。

历史操作激活消耗 API可以通过执行以下步骤来消耗历史操作用户激活,给定一个窗口W

  1. 如果W可导航为 null,则返回。

  2. topW可导航顶层可遍历

  3. navigablestop活跃文档包含的后代可导航

  4. windows为通过获取navigables中每个项目的活跃窗口构造的窗口对象的列表。

  5. 对每个windowwindows中,将window上次历史操作激活时间戳设置为window上次激活时间戳

请注意页面中受激活通知激活消耗影响的浏览上下文集合的不对称性:激活消耗会更改(为 false)页面中所有浏览上下文的短暂激活状态,而激活通知仅更改这些浏览上下文的子集的状态。这里消耗的全面性是故意的:它防止恶意网站从单一用户激活中多次调用激活消耗 API(可能通过利用深层的iframe层次结构)。

6.4.3 受用户激活限制的API

依赖用户激活的API被分为不同的级别:

粘性激活限制API

这些API要求粘性激活状态为true,因此在第一次用户激活之前,它们是被阻止的。

短暂激活限制API

这些API要求短暂激活状态为true,但它们不会消耗它,因此在短暂状态过期之前,每次用户激活可以多次调用。

短暂激活消耗API

这些API要求短暂激活状态为true,并且每次调用时它们会消耗用户激活,以防止每次用户激活多次调用。

历史操作激活消耗API

这些API要求历史操作激活状态为true,并且每次调用时它们会消耗历史操作用户激活,以防止每次用户激活多次调用。

6.4.4 UserActivation 接口

UserActivation

FirefoxNoSafari16.4+Chrome72+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

每个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

返回窗口是否具有短暂激活

Navigator/userActivation

FirefoxNoSafari16.4+Chrome72+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

userActivation 获取步骤是返回 this相关全局对象关联 UserActivation

UserActivation/hasBeenActive

FirefoxNoSafari16.4+Chrome72+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

hasBeenActive 获取步骤是如果 this相关全局对象具有 粘性激活,则返回 true,否则返回 false。

UserActivation/hasBeenActive

FirefoxNoSafari16.4+Chrome72+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

isActive 获取步骤是如果 this相关全局对象具有 短暂激活,则返回 true,否则返回 false。

6.4.5 用户代理自动化

为了用户代理自动化和应用测试的目的,本规范为Web Driver规范定义了以下扩展命令。用户代理支持以下扩展命令是可选的。 [WEBDRIVER]

HTTP Method URI Template
POST /session/{session id}/window/consume-user-activation

远程端步骤是:

  1. window当前浏览上下文活动窗口

  2. consume为 true 如果window具有短暂激活状态;否则为 false。

  3. 如果consume为 true,则消耗用户激活window

  4. 返回带有数据consume成功

6.5 元素的激活行为

HTML中的某些元素具有激活行为,这意味着用户可以激活它们。这通常由click事件触发。

用户代理应允许用户手动触发具有激活行为的元素,例如使用键盘或语音输入,或通过鼠标点击。当用户以点击以外的方式触发具有定义的激活行为的元素时,交互事件的默认操作必须是在该元素上触发click事件

element.click()

HTMLElement/click

支持所有当前引擎。

Firefox3+Safari6+Chrome9+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android4+Safari iOS?Chrome Android?WebView Android4.4+Samsung Internet1.0+Opera Android11+

表现为元素被点击。

每个元素都有一个关联的点击进行中标志,初始状态为未设置。

click()方法必须执行以下步骤:

  1. 如果该元素是一个禁用的表单控件,则返回。

  2. 如果该元素的点击进行中标志已设置,则返回。

  3. 设置该元素的点击进行中标志

  4. 触发一个合成指针事件,名为click, 在该元素上,并设置not trusted flag

  5. 取消该元素的点击进行中标志

6.5.1 ToggleEvent 接口

ToggleEvent/ToggleEvent

支持所有当前引擎。

🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

ToggleEvent

支持所有当前引擎。

🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
[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"。

ToggleEvent/oldState

支持所有当前引擎。

🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

ToggleEvent/newState

支持所有当前引擎。

🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

oldStatenewState属性必须返回它们初始化的值。

一个切换任务跟踪器是一个结构体,包含以下内容:

任务
一个任务,触发一个ToggleEvent
旧状态
一个字符串,表示任务事件的oldState属性的值。

6.6 焦点

6.6.1 介绍

本节为非规范性内容。

HTML用户界面通常由多个交互小部件组成,例如表单控件、可滚动区域、链接、对话框、浏览器标签页等。这些小部件形成一个层次结构,其中一些(例如浏览器标签页、对话框)包含其他小部件(例如链接、表单控件)。

当使用键盘与界面交互时,键输入从系统通过交互小部件的层次结构传递到一个活跃的小部件,该小部件被称为聚焦

考虑在图形环境中运行的浏览器标签页中运行的HTML应用程序。假设该应用程序有一个包含一些文本控件和链接的页面,并且当前正在显示一个包含文本控件和按钮的模式对话框。

在这种情况下,可聚焦小部件的层次结构将包括浏览器窗口,其子节点将包括包含HTML应用程序的浏览器标签页。标签页本身将有各种链接和文本控件作为其子节点,以及对话框。对话框本身将包含文本控件和按钮作为其子节点。

在此示例中,如果聚焦的小部件是对话框中的文本控件,那么键输入将从图形系统传递到①网络浏览器,然后到②标签页,再到③对话框,最后到④文本控件。

键盘事件总是针对这个聚焦元素。

6.6.2 数据模型

当顶级遍历项可以接收来自操作系统的键盘输入时,它具有系统焦点,这些输入可能针对其活动文档的后代导航项。

当顶级遍历项的系统可见性状态为"可见",并且它具有系统焦点或与其直接相关的用户代理小部件可以接收来自操作系统的键盘输入时,它具有用户注意力。

当浏览器窗口失去焦点时,用户注意力会丧失,而系统焦点可能会被浏览器窗口中的其他系统小部件(如地址栏)占用。

当一个文档完全活动且其节点导航项的顶级遍历项具有用户注意力时,该文档是一个具有用户注意力的顶级遍历项的完全活动后代。

术语“可聚焦区域”用于指可以成为此类键盘输入目标的界面区域。可聚焦区域可以是元素、元素的部分或由用户代理管理的其他区域。

每个可聚焦区域都有一个DOM锚点,它是一个表示可聚焦区域在DOM中的位置的节点对象。(当可聚焦区域本身是一个节点时,它就是其自己的DOM锚点。)在某些API中,DOM锚点用作可聚焦区域的替代,当没有其他DOM对象可以表示可聚焦区域时使用。

下表描述了哪些对象可以是可聚焦区域。左列中的单元格描述了可以是可聚焦区域的对象;右列中的单元格描述了这些元素的DOM锚点。(跨越两列的单元格是非规范性示例。)

可聚焦区域 DOM 锚点
示例
满足以下所有条件的元素:
  • 元素的tabindex值非空,或用户代理确定该元素是可聚焦的;
  • 元素不是影子宿主,或其影子根的focus代理为false;
  • 元素未被实际禁用;
  • 元素不处于惰性状态;
  • 元素正在渲染、将渲染委托给其子元素或作为相关画布回退内容使用。
元素本身。

<iframe><dialog><input type="text">,有时<a href="">(取决于平台惯例)。

与图像地图关联的area元素的形状,该图像地图与正在渲染且不处于惰性状态的img元素关联。 img元素。

在以下示例中,area元素在每个图像上创建两个形状。第一个形状的DOM锚点是第一个img元素,第二个形状的DOM锚点是第二个img元素。

<map id=wallmap><area alt="Enter Door" coords="10,10,100,200" href="door.html"></map>
...
<img src="images/innerwall.jpeg" alt="There is a white wall here, with a door." usemap="#wallmap">
...
<img src="images/outerwall.jpeg" alt="There is a red wall here, with a door." usemap="#wallmap">
正在渲染且不处于惰性状态或禁用状态的元素的用户代理提供的子小部件。 为其创建可滚动区域的元素。

用于video元素的用户界面控件、number类型输入框中的上下按钮、details元素渲染的一部分使其可以使用键盘输入打开或关闭。

正在渲染且不处于惰性状态的元素的可滚动区域。 为其创建可滚动区域的元素。

CSS中的'overflow'属性的'scroll'值通常会创建一个可滚动区域。

具有非空浏览上下文且不处于惰性状态的文档的视口。 创建视口的文档。

iframe的内容。

由用户代理确定为可聚焦区域的任何其他元素或元素的一部分,特别是为了辅助可访问性或更好地匹配平台惯例。 元素本身。

用户代理可以使所有列表项的项目符号成为顺序可聚焦的,以便用户可以更轻松地导航列表。

同样,用户代理可以使所有带有title属性的元素顺序可聚焦,以便可以访问它们的建议信息。

导航容器(例如iframe)是一个可聚焦区域,但路由到导航容器的键事件会立即路由到其内容导航项的活动文档。同样,在顺序焦点导航中,导航容器本质上只是其内容导航项的活动文档的占位符。


每个文档中的一个可聚焦区域被指定为文档的聚焦区域。哪个控件被指定为聚焦区域会随时间变化,基于本规范中的算法。

即使文档不是完全活动的且不显示给用户,它仍然可以有一个聚焦区域。如果文档的完全活动状态发生变化,其聚焦区域将保持不变。

顶级遍历项的当前聚焦区域是通过以下算法返回的可聚焦区域或空值:

  1. 如果顶级遍历项没有系统焦点,则返回null。

  2. 将候选项设置为顶级遍历项的活动文档。

  3. 当候选项的聚焦区域是具有非空内容导航项的导航容器时:将候选项设置为该导航容器的内容导航项的活动文档。

  4. 如果候选项的聚焦区域非空,则将候选项设置为候选项的聚焦区域。

  5. 返回候选项。

顶级遍历项的当前焦点链是顶级遍历项的当前聚焦区域的焦点链(如果顶级遍历项非空),否则为空列表。

当元素是可聚焦区域的DOM锚点时,当该可聚焦区域成为顶级遍历项的当前聚焦区域时,该元素获得焦点。当元素是顶级遍历项的当前聚焦区域的可聚焦区域的DOM锚点时,它被聚焦。

可聚焦区域的焦点链是按以下方式构建的有序列表:

  1. 让输出为一个空列表。

  2. 将当前对象设置为主题。

  3. 当条件为真时:

    1. 将当前对象附加到输出。

    2. 如果当前对象是area元素的形状,则将该area元素附加到输出。

      否则,如果当前对象的DOM锚点是一个元素而不是当前对象本身,则将当前对象的DOM锚点附加到输出。

    3. 如果当前对象是可聚焦区域,则将当前对象设置为当前对象的DOM锚点的节点文档。

      否则,如果当前对象是其节点导航项的父项非空的文档,则将当前对象设置为当前对象的节点导航项的父项。

      否则,跳出循环。

  4. 返回输出。

    链从主题开始,并(如果主题是或可以是顶级遍历项的当前聚焦区域)沿焦点层次结构向上延续,直到顶级遍历项的文档。

所有作为可聚焦区域的元素都被称为可聚焦。

可聚焦区域有两种特殊类型的可聚焦性:

不可聚焦的元素不是可聚焦区域,因此既不是顺序可聚焦的,也不是点击可聚焦的。

可聚焦是关于元素是否可以通过编程方式聚焦的声明,例如通过focus()方法或autofocus属性。相比之下,顺序可聚焦和点击可聚焦决定了用户代理如何响应用户交互:分别是顺序焦点导航和作为激活行为。

用户代理可能会根据用户偏好确定一个元素不是顺序可聚焦的,即使它是可聚焦的并包含在其文档的顺序焦点导航顺序中。例如,macOS用户可以设置用户代理跳过非表单控件元素,或在使用Tab键进行顺序焦点导航时跳过链接(而不是使用Option和Tab键)。

同样,用户代理可能会确定一个元素不是点击可聚焦的,即使它是可聚焦的。例如,在某些用户代理中,点击非可编辑表单控件不会聚焦它,即用户代理已确定此类控件不是点击可聚焦的。

因此,一个元素可以是可聚焦的,但既不是顺序可聚焦的,也不是点击可聚焦的。例如,在某些用户代理中,具有负整数tabindex值的非可编辑表单控件不能通过用户交互聚焦,只能通过编程API聚焦。

当用户激活一个点击可聚焦的可聚焦区域时,用户代理必须在可聚焦区域上运行聚焦步骤,聚焦触发设置为"点击"。

注意,聚焦不是一种激活行为,即在元素上调用click()方法或调度一个合成的click事件不会使元素获得焦点。


如果节点是文档、影子宿主、插槽或处于弹出显示状态且设置了弹出调用器的元素,则该节点是焦点导航范围所有者。

每个焦点导航范围所有者都有一个焦点导航范围,这是一个元素列表。其内容如下所示:

每个元素都有一个关联的焦点导航所有者,该所有者可以是null或焦点导航范围所有者。其内容通过以下算法确定:

  1. 如果元素的父元素为null,则返回null。

  2. 如果元素的父元素是一个影子宿主,则返回元素的分配插槽。

  3. 如果元素的父元素是影子根,则返回父元素的宿主。

  4. 如果元素的父元素是文档元素,则返回父元素的节点文档。

  5. 如果元素处于弹出显示状态且设置了弹出调用器,则返回元素。

  6. 返回元素的父元素的关联焦点导航所有者。

然后,给定的焦点导航范围所有者的焦点导航范围包含所有关联焦点导航所有者是该范围所有者的元素。

焦点导航范围内元素的顺序不会影响本规范中的任何算法。只有在下文定义的tabindex有序焦点导航范围和扁平化tabindex有序焦点导航范围概念中才会变得重要。

tabindex有序焦点导航范围是一个包含可聚焦区域和焦点导航范围所有者的列表。每个焦点导航范围所有者都有一个tabindex有序焦点导航范围,其内容如下:

tabindex有序焦点导航范围内的顺序由每个元素的tabindex值确定,如下文所述。

这些规则并未给出精确的顺序,因为它们主要由“应该”声明和相对顺序组成。

扁平化tabindex有序焦点导航范围是一个包含可聚焦区域的列表。每个焦点导航范围所有者拥有一个独特的扁平化tabindex有序焦点导航范围,其内容通过以下算法确定:

  1. 让结果为范围所有者的tabindex有序焦点导航范围的克隆。

  2. 对于结果中的每个项:

    1. 如果项不是焦点导航范围所有者,则继续。

    2. 如果项不是可聚焦区域,则用该项的扁平化tabindex有序焦点导航范围中的所有项替换项。

    3. 否则,在项之后插入项的扁平化tabindex有序焦点导航范围的内容。

6.6.3 tabindex 属性

Global_attributes/tabindex

支持所有当前引擎。

Firefox1.5+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

tabindex 内容属性允许作者使元素及将该元素作为其 DOM 锚点的区域成为 可聚焦区域,允许或阻止它们成为 顺序可聚焦,并确定它们在 顺序焦点导航中的相对顺序。

“tab index”这个名字来源于使用 Tab 键在可聚焦元素之间导航的常见用法。“tabbing”指的是向前移动通过 顺序可聚焦 可聚焦区域

如果指定了 tabindex 属性,则其值必须是 有效整数。正数指定元素的 可聚焦区域顺序焦点导航顺序中的相对位置,负数表示控件不是 顺序可聚焦

开发者在为 tabindex 属性使用 0 以外的值时应谨慎,因为正确处理这种情况很复杂。

以下是对 tabindex 属性值可能行为的非规范性总结。下面的处理模型给出了更精确的规则。

省略(或非整数值)
用户代理将决定元素是否 可聚焦,如果是,还会决定它是否 顺序可聚焦点击可聚焦(或两者兼有)。
−1(或其他负整数值)
使元素 可聚焦,并表示作者希望元素 点击可聚焦 但不 顺序可聚焦。用户代理可能会忽略这种点击和顺序可聚焦性偏好,例如,按照平台惯例针对特定元素类型,或针对仅使用键盘的用户。
0
使元素 可聚焦,并表示作者希望元素同时 点击可聚焦顺序可聚焦。用户代理可能会忽略这种点击和顺序可聚焦性偏好。
正整数值
行为与 0 相同,但此外还在 tabindex-有序焦点导航范围内创建相对顺序,使具有较高 tabindex 属性值的元素排在后面。

请注意,tabindex 属性不能用于使元素不可聚焦。页面作者唯一能做到这一点的方法是 禁用 该元素,或使其 惰性


tabindex 值 是指元素的 tabindex 属性值,使用 解析整数的规则 进行解析。如果解析失败或未指定属性,则 tabindex 值 为 null。

tabindex值可聚焦区域是其DOM锚点tabindex值

元素的tabindex值必须按如下解释:

如果值为 null

用户代理应遵循平台惯例来确定元素是否应被视为 可聚焦区域,如果是,还应决定元素及其任何 可聚焦区域 是否为 顺序可聚焦,以及它们在 tabindex-有序焦点导航范围中的相对位置。如果元素是 焦点导航范围所有者,则必须将其包括在其 tabindex-有序焦点导航范围 中,即使它不是 可聚焦区域

对于同一个 焦点导航范围 的元素和 可聚焦区域,它们在 tabindex-有序焦点导航范围内的相对顺序应为 包含阴影树顺序

根据平台惯例,建议以下元素应被视为 可聚焦区域 并且 顺序可聚焦

如果值为负整数

用户代理必须将元素视为 可聚焦区域,但应将元素从任何 tabindex-有序焦点导航范围中省略。

一个有效的忽略顺序焦点导航不允许作者引导到元素的理由是,如果用户的唯一移动焦点的机制是顺序焦点导航。例如,仅使用键盘的用户无法点击负 tabindex 的文本控件,因此用户的用户代理将完全合理地允许用户无论如何都可以切换到该控件。

如果值为零

用户代理必须允许元素被视为 可聚焦区域,并且应允许元素及其作为其 DOM 锚点的任何 可聚焦区域成为 顺序可聚焦

对于同一个 焦点导航范围 的元素和 可聚焦区域,它们在 tabindex-有序焦点导航范围内的相对顺序应为 包含阴影树顺序

如果值大于零

用户代理必须允许元素被视为 可聚焦区域,并应允许元素及其作为其 DOM 锚点的任何 可聚焦区域成为 顺序可聚焦,并应将元素(在下文中称为 candidate)和上述 可聚焦区域 放置在 tabindex-有序焦点导航范围中,以便它们在同一个 焦点导航范围内的其他元素和 可聚焦区域 相对位置如下:

HTMLElement/tabIndex

支持所有当前引擎。

Firefox1+Safari3.1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)18Internet Explorer🔰 5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

tabIndex IDL 属性必须 反映 tabindex 内容属性的值。如果元素是 aareabuttonframeiframeinputobjectselecttextarea,或 SVG a 元素,或是 summary 元素是 其父详细信息的摘要,则 默认值 为 0。否则,默认值 为 -1。

基于元素类型的不同默认值是一个历史遗留问题。

6.6.4 处理模型

为了获取可聚焦区域,针对一个focusTarget(可以是一个元素,但不是可聚焦区域,或者是一个可导航元素),给定一个可选的字符串focus trigger(默认值为 "other"),运行以下列表中第一个匹配的一组步骤:

如果focusTarget是一个具有一个或多个形状的area元素,这些形状是可聚焦区域

返回第一个在树顺序中使用此图像映射的img元素对应的形状。

如果focusTarget是一个具有一个或多个可滚动区域的元素,这些区域是可聚焦区域

返回元素的第一个可滚动区域,按照平面树的先序深度优先遍历顺序。[CSSSCOPING]

如果focusTarget是其文档文档元素

返回文档视口

如果focusTarget是一个可导航元素

返回可导航元素活动文档

如果focusTarget是一个具有非空内容可导航元素可导航容器

返回可导航容器内容可导航元素活动文档

如果focusTarget是一个影宿主,其影根委派焦点为真
  1. focusedElement成为顶级可遍历元素的当前聚焦区域DOM 锚点

  2. 如果focusTargetfocusedElement包含影的包容祖先,则返回focusedElement

  3. 返回focusTarget焦点委派,给定focus trigger

对于顺序可聚焦,处理影宿主委派焦点是在构建顺序焦点导航顺序时完成的。也就是说,聚焦步骤在顺序焦点导航中不会被调用到这样的影宿主

否则

返回null。

焦点委派用于focusTarget,给定一个可选字符串focus trigger(默认值为 "other"),步骤如下:

  1. 如果focusTarget是一个影宿主,且其影根委派焦点为假,则返回null。

  2. whereToLookfocusTarget

  3. 如果whereToLook是一个影宿主,则将whereToLook设为其影根

  4. autofocusDelegatewhereToLook自动焦点委派,给定focus trigger

  5. 如果autofocusDelegate不为null,则返回autofocusDelegate

  6. 对于每个 whereToLook后代中的 descendant,按照树的顺序

    1. focusableArea为null。

    2. 如果focusTargetdialog元素,且descendant顺序可聚焦的,则将focusableArea设为descendant

    3. 否则,如果focusTarget不是dialog,且descendant可聚焦区域,则将focusableArea设为descendant

    4. 否则,将focusableArea设为获取descendant的可聚焦区域,给定focus trigger的结果。

      这一步可能会递归,即获取可聚焦区域步骤可能会返回descendant焦点委派

    5. 如果focusableArea不为null,则返回focusableArea

    这里重要的是我们没有查看包含影的子孙,而是仅查看子孙影宿主则通过上面的递归情况处理。

  7. 返回null。

上面的算法实质上返回了第一个合适的可聚焦区域,其DOM 锚点focusTarget之间的路径在任何影树边界上委派焦点。

自动焦点委派用于focusTarget,给定focus trigger,步骤如下:

  1. focusTarget的每个子孙后代,按树顺序

    1. 如果descendant没有自动焦点内容属性,则继续

    2. focusableAreadescendant,如果descendant可聚焦区域;否则,设focusableArea获取descendant的可聚焦区域,给定focus trigger的结果。

    3. 如果focusableArea为null,则继续

    4. 如果focusableArea不是可点击聚焦,且focus trigger是 "click",则继续

    5. 返回focusableArea

  2. 返回null。

聚焦步骤用于对象new focus target,这个目标可以是可聚焦区域,也可以是一个元素,但不是可聚焦区域,或者是一个可导航元素,步骤如下。这些步骤可以选择性地使用fallback target和字符串focus trigger

  1. 如果new focus target不是可聚焦区域,则将new focus target设为获取new focus target的可聚焦区域,如果传递了focus trigger

  2. 如果new focus target为null,则:

    1. 如果没有指定fallback target,则返回。

    2. 否则,将new focus target设为fallback target

  3. 如果new focus target是一个具有非空内容可导航元素可导航容器,则将new focus target设为内容可导航元素活动文档

  4. 如果new focus target是一个可聚焦区域,且其DOM 锚点惰性的,则返回。

  5. 如果new focus target顶级可遍历元素的当前聚焦区域,则返回。

  6. old chainnew focus target所在顶级可遍历元素的当前焦点链

  7. new chainnew focus target焦点链

  8. 运行焦点更新步骤,分别使用old chainnew chainnew focus target

用户代理必须立即运行 聚焦步骤,以便于 可聚焦区域可导航 candidate 在用户尝试将焦点移到 candidate 时。

对象 old focus target失焦步骤如下,old focus target 可以是 可聚焦区域或不是 可聚焦区域的元素:

  1. 如果old focus target是一个影宿主,其影根委派焦点为真,且old focus target影根包含影的包容祖先,顶级可遍历元素的当前聚焦区域的DOM 锚点,则将old focus target设为该顶级可遍历元素的当前聚焦区域

  2. 如果old focus target惰性的,则返回。

  3. 如果old focus targetarea元素,且其一个形状是顶级可遍历元素的当前聚焦区域,或者,如果old focus target是一个具有一个或多个可滚动区域的元素,且其中一个是顶级可遍历元素的当前聚焦区域,则将old focus target设为该顶级可遍历元素的当前聚焦区域

  4. old chainold focus target所在顶级可遍历元素的当前焦点链

  5. 如果old focus target不是old chain中的一个条目,则返回。

  6. 如果old focus target不是可聚焦区域,则返回。

  7. topDocumentold chain的最后一个条目。

  8. 如果topDocument节点可导航具有系统焦点,则运行聚焦步骤,用于topDocument视口

    否则,应用任何相关的特定平台的惯例,从topDocument节点可导航中移除系统焦点,并运行焦点更新步骤,给定old chain、一个空列表和null。

失焦步骤并不总是导致焦点改变,即使应用于顶级可遍历元素的当前聚焦区域。例如,如果顶级可遍历元素的当前聚焦区域是一个视口,则通常会保持其焦点,直到另一个可聚焦区域被显式聚焦,使用聚焦步骤


焦点更新步骤,给定一个old chain、一个new chain和一个new focus target,步骤如下:

  1. 如果old chain的最后一个条目和new chain的最后一个条目相同,则从old chain中弹出最后一个条目,从new chain中弹出最后一个条目,并重新执行此步骤。

  2. 对于old chain中的每个entry,按顺序运行以下子步骤:

    1. 如果entryinput元素,且change事件适用于该元素,且该元素没有定义的激活行为,且用户在控件聚焦时更改了元素的或其选定文件列表,但未提交更改(使其与控件首次聚焦时不同),则:

      1. entry用户有效性设为真。

      2. 触发一个事件,名为change,在元素上,bubbles属性初始化为真。

    2. 如果entry是一个元素,则设blur event targetentry

      如果entry是一个文档对象,则设blur event target为该文档对象的相关全局对象

      否则,设blur event target为null。

    3. 如果entryold chain的最后一个条目,且entry是一个元素,且new chain的最后一个条目也是一个元素,则设blur event targetnew chain的最后一个条目。否则,设blur event target为null。

    4. 如果blur event target不为null,则触发一个焦点事件,名为blur,在blur event target上,blur event target作为相关目标。

      在某些情况下,例如,如果entryarea元素的形状、一个可滚动区域或一个视口,则不会触发事件。

  3. 应用任何相关的特定平台 的惯例以聚焦new focus target。(例如,一些平台在焦点进入文本控件时会选择控件的内容。)

  4. new chain中的每个entry,按逆序运行以下子步骤:

    1. 如果entry可聚焦区域,且文档的聚焦区域不是entry

      1. document相关全局对象导航API在进行中的导航期间焦点改变设为真。

      2. 指定entry文档的聚焦区域

    2. 如果entry是一个元素,则设focus event targetentry

      如果entry是一个文档对象,则设focus event target为该文档对象的相关全局对象

      否则,设focus event target为null。

    3. 如果entrynew chain的最后一个条目,且entry是一个元素,且old chain的最后一个条目也是一个元素,则设related focus targetold chain的最后一个条目。否则,设related focus target为null。

    4. 如果focus event target不为null,则触发一个焦点事件,名为focus,在focus event target上,related focus target作为相关目标。

      在某些情况下,例如,如果entryarea元素的形状、一个可滚动区域或一个视口,则不会触发事件。

触发一个焦点事件,名为e,在元素t上,给定一个相关目标r触发一个事件,名为e,在t上,使用FocusEventrelatedTarget属性初始化为rview属性初始化为t节点文档相关全局对象,并设置组合标志


当一个键事件要在顶级可遍历元素中路由时,用户代理必须运行以下步骤:

  1. target area顶级可遍历元素的当前聚焦区域

  2. 断言target area不为null,因为键事件只会路由到具有系统焦点顶级可遍历元素。因此,target area是一个可聚焦区域

  3. target nodetarget areaDOM 锚点

  4. 如果target node是一个具有body 元素文档,则将target node设为该文档body 元素

    否则,如果target node是一个具有非空文档元素文档对象,则将target node设为该文档元素

  5. 如果target node不是惰性的,则:

    1. canHandle分派键事件在target node上的结果。

    2. 如果canHandle为真,则让target area处理键事件。这可能包括在target node触发一个click事件


具有焦点步骤,给定一个文档对象target,步骤如下:

  1. 如果target节点可导航顶级可遍历元素没有系统焦点,则返回false。

  2. candidatetarget节点可导航顶级可遍历元素活动文档

  3. 当为真时:

    1. 如果candidatetarget,则返回true。

    2. 如果candidate聚焦区域是一个具有非空内容可导航元素可导航容器,则将candidate设为该可导航容器内容可导航元素活动文档

    3. 否则,返回false。

6.6.5 顺序焦点导航

每个文档都有一个顺序焦点导航顺序,它对文档中的一些或全部可聚焦区域相对彼此进行排序。其内容和顺序由文档的平展的tabindex-有序焦点导航范围给出。

根据定义平展的tabindex-有序焦点导航范围的规则,顺序不一定与文档的树顺序相关。

如果一个可聚焦区域被从其文档的顺序焦点导航顺序中省略,那么通过顺序焦点导航无法到达它。

还可以有一个顺序焦点导航起点。它最初未设置。当用户指示应移动时,用户代理可以设置它。

例如,如果用户点击文档内容,用户代理可以将其设置为用户点击的位置。

要求用户代理在导航到片段时将顺序焦点导航起点设置为目标元素

当用户请求将焦点从顶级可遍历元素的当前聚焦区域移动到下一个或上一个可聚焦区域(例如按tab键的默认操作),或当用户请求首先顺序移动焦点到顶级可遍历元素时(例如从浏览器的地址栏),用户代理必须使用以下算法:

  1. starting point顶级可遍历元素的当前聚焦区域,如果用户请求从那里顺序移动焦点,或者设为顶级可遍历元素本身,如果用户请求从该顶级可遍历元素外部移动焦点。

  2. 如果定义了一个顺序焦点导航起点并且它在starting point内部,则设starting point为该顺序焦点导航起点

  3. direction向前,如果用户请求下一个控件;如果用户请求上一个控件,则为向后

    通常,按tab请求下一个控件,按shift + tab请求上一个控件。

  4. 循环:设selection mechanism顺序,如果starting point可导航元素,或者starting point在其文档的顺序焦点导航顺序中。

    否则,starting point不在其文档的顺序焦点导航顺序中;设selection mechanismDOM

  5. candidate为运行顺序导航搜索算法的结果,参数为starting pointdirectionselection mechanism

  6. 如果candidate不为null,则为candidate运行聚焦步骤并返回。

  7. 否则,取消设置顺序焦点导航起点

  8. 如果starting point顶级可遍历元素,或者是顶级可遍历元素中的可聚焦区域,用户代理应适当将焦点转移到其自身的控件(如果有),遵循direction,然后返回。

    例如,如果direction向后,则浏览器渲染区域之前的最后一个顺序可聚焦控件将是要聚焦的控件。

    如果用户代理没有顺序可聚焦控件——例如,kiosk模式的浏览器——那么用户代理可以改为重新开始这些步骤,将starting point设为顶级可遍历元素本身。

  9. 否则,starting point是一个可聚焦区域,位于子可导航元素中。将starting point设为该子可导航元素父元素,然后返回到标记为循环的步骤。

顺序导航搜索算法包含以下步骤。此算法有三个参数:starting pointdirectionselection mechanism

  1. 从下表中选择适当的单元格,并按照该单元格中的说明进行。

    适当的单元格是指列标题描述direction的列和行标题描述starting pointselection mechanism的第一行交叉的单元格。

    direction向前 direction向后
    starting point可导航元素 candidatestarting point活动文档中的第一个适合的顺序可聚焦区域,如果有的话;否则为null。 candidatestarting point活动文档中的最后一个适合的顺序可聚焦区域,如果有的话;否则为null。
    selection mechanismDOM candidatestarting point后的主文档中的第一个适合的顺序可聚焦区域,如果有的话;否则为null。 candidatestarting point前的主文档中的最后一个适合的顺序可聚焦区域,如果有的话;否则为null。
    selection mechanism顺序 candidatestarting point后的主顺序焦点导航顺序中的第一个适合的顺序可聚焦区域,如果有的话;否则为null。 candidatestarting point前的主顺序焦点导航顺序中的最后一个适合的顺序可聚焦区域,如果有的话;否则为null。

    适合的顺序可聚焦区域是其DOM锚惰性且是顺序可聚焦可聚焦区域

    主文档starting point所属的文档

    主顺序焦点导航顺序starting point所属的顺序焦点导航顺序

    主顺序焦点导航顺序是主文档的顺序焦点导航顺序,但仅在starting point在该顺序焦点导航顺序中时使用(当它不在该顺序中时,selection mechanism将为DOM)。

  2. 如果candidate是一个具有非空内容可导航元素可导航容器,则设new candidate为使用candidate内容可导航元素作为第一个参数,direction作为第二个参数,顺序作为第三个参数运行顺序导航搜索算法的结果。

    如果new candidate为null,则设starting pointcandidate,并返回到此算法的顶部。否则,设candidatenew candidate

  3. 返回candidate

6.6.6 焦点管理 API

dictionary FocusOptions {
  boolean preventScroll = false;
  boolean focusVisible;
};
documentOrShadowRoot.activeElement

Document/activeElement

Support in all current engines.

Firefox3+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

ShadowRoot/activeElement

Support in all current engines.

Firefox63+Safari10+Chrome53+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回文档中最深的元素,键事件通过或被路由到该元素。粗略地说,这就是文档中聚焦的元素。

对于此 API,当一个子可导航元素被聚焦时,它的容器在其父元素活动文档中是聚焦的。例如,如果用户将焦点移到iframe中的文本控件上,那么iframe是在activeElement API 中返回的元素,位于该iframe节点文档中。

同样,当聚焦的元素位于与documentOrShadowRoot不同的节点树中时,返回的元素将是位于与documentOrShadowRoot相同节点树中的宿主,如果documentOrShadowRoot是聚焦元素的包含阴影的祖先,否则为null。

document.hasFocus()

Document/hasFocus

Support in all current engines.

Firefox3+Safari4+Chrome2+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android?

如果键事件被路由到或通过该文档,则返回true;否则返回false。粗略地说,这对应于文档或嵌套在其中的文档被聚焦。

window.focus()

Window/focus

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android18+WebView Android?Samsung Internet?Opera Android12.1+

将焦点移到窗口的可导航元素,如果有的话。

element.focus([ { preventScroll: true } ])

HTMLElement/focus

Support in all current engines.

Firefox1.5+Safari3+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

将焦点移到该元素。

如果该元素是一个可导航容器,则将焦点移到其内容可导航元素

默认情况下,此方法还会将该元素滚动到视图中。提供preventScroll选项并将其设置为true可防止这种行为。

element.blur()

HTMLElement/blur

Support in all current engines.

Firefox1.5+Safari3+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

将焦点移到视口。不建议使用此方法;如果您想聚焦视口,请在focus()方法上调用Document文档元素

不要使用此方法隐藏焦点环,如果您发现焦点环不美观。相反,使用:focus-visible伪类覆盖'outline'属性,并提供另一种方式来显示哪个元素被聚焦。请注意,如果没有提供替代的聚焦样式,页面对于主要使用键盘导航或使用焦点轮廓帮助导航的视力减弱用户将变得非常难用。

例如,要隐藏textarea元素的轮廓并改用黄色背景来指示焦点,您可以使用:

textarea:focus-visible { outline: none; background: yellow; color: black; }

activeElement属性的getter必须运行以下步骤:

  1. candidate成为DOM anchorfocused area,属于此DocumentOrShadowRoot节点文档

  2. candidate设置为重新定向candidate到此DocumentOrShadowRoot的结果。

  3. 如果candidate不是此DocumentOrShadowRoot,则返回null。

  4. 如果candidate不是Document对象,则返回candidate

  5. 如果candidate有一个body元素,则返回该body元素

  6. 如果candidatedocument element为非null,则返回该document element

  7. 返回null。

hasFocus()方法在Document对象上调用时,必须返回以Document对象作为参数运行聚焦步骤的结果。

focus()方法在调用时,必须运行以下步骤:

  1. current为这个Window对象的可导航对象

  2. 如果current为null,则返回。

  3. 使用current运行聚焦步骤

  4. 如果current是一个顶级可遍历对象,则鼓励用户代理触发某种通知,以向用户指示页面正在尝试获取焦点。

Window/blur

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

blur()方法步骤中,不执行任何操作。

从历史上看,focus()blur()方法实际上影响了包含可导航元素的系统小部件(例如,标签或窗口)的系统级焦点,但敌对站点广泛滥用这种行为,损害用户利益。

在元素上调用的focus(options)方法,调用时,必须运行以下步骤:

  1. 如果元素被标记为焦点锁定,则返回。

  2. 将元素标记为焦点锁定

  3. 运行元素的聚焦步骤

  4. 如果optionsfocusVisible字典成员的值为true,或不存在但用户代理以实现定义的方式确定最好这样做,则指示焦点

  5. 如果optionspreventScroll字典成员的值为false,则在给定“auto”、“center”和“center”的情况下将元素滚动到视图中

  6. 将元素取消标记为焦点锁定

在元素上调用的blur()方法,调用时,应为调用该方法的元素运行失焦步骤。出于可用性原因,用户代理可以有选择性地或统一地忽略对此方法的调用。

例如,如果blur()方法被不明智地用于美学原因删除焦点环,则页面将无法使用键盘用户。忽略对此方法的调用将允许键盘用户与页面进行交互。

6.6.7 autofocus属性

autofocus内容属性允许作者指示元素在页面加载时获得焦点,使用户可以直接开始输入而无需手动聚焦主要元素。

当在autofocus属性在dialog元素内或HTML元素popover属性设置时,它将在对话框或弹出框显示时获得焦点。

autofocus属性是布尔属性

要找到给定element最近的祖先自动聚焦范围根元素

  1. 如果elementdialog元素,则返回element

  2. 如果elementpopover属性不在无弹出状态,则返回element

  3. ancestorelement

  4. ancestor父元素时:

    1. ancestor设置为ancestor父元素

    2. 如果ancestordialog元素,则返回ancestor

    3. 如果ancestorpopover属性不在无弹出状态,则返回ancestor

  5. 返回ancestor

不得有两个具有相同最近的祖先自动聚焦范围根元素的元素,它们都指定了autofocus属性。

每个Document都有一个最初为空的自动聚焦候选者 列表

每个Document都有一个最初为假的自动聚焦处理标志布尔值。

当一个指定了autofocus属性的元素被插入到文档中时,运行以下步骤:

  1. 如果用户已经表示(例如,通过开始在表单控件中输入)他们不希望更改焦点,则可选地返回。

  2. target为该元素的节点文档

  3. 如果target不是完全活跃,则返回。

  4. 如果target活跃沙箱标志集具有沙箱自动功能浏览上下文标志,则返回。

  5. 对于target祖先可导航对象的每个ancestorNavigable:如果ancestorNavigable活跃文档来源target来源不同,则返回。

  6. topDocumenttarget节点可导航对象顶级可遍历对象活跃文档

  7. 如果topDocument自动聚焦处理标志为假,则topDocument自动聚焦候选者附加该元素。

在将元素存储在自动聚焦候选者列表之前,我们不会检查元素是否是可聚焦区域,因为即使在插入时它不是可聚焦区域,它也可能在刷新自动聚焦候选者看到它时变成可聚焦的。

刷新自动聚焦候选者,请运行以下步骤:

  1. 如果topDocument自动聚焦处理标志为真,则返回。

  2. candidatestopDocument自动聚焦候选者

  3. 如果candidates为空,则返回。

  4. 如果topDocument焦点区域不是topDocument本身,或topDocument具有非null目标元素,则:

    1. 清空candidates

    2. topDocument自动聚焦处理标志设置为true。

    3. 返回。

  5. candidates为空时:

    1. elementcandidates[0]。

    2. docelement节点文档

    3. 如果doc不是完全活跃,则candidates移除element并继续。

    4. 如果doc节点可导航对象顶级可遍历对象topDocument节点可导航对象不同,则candidates中移除element并继续。

    5. 如果doc阻止脚本的样式表集不是空的,则返回。

      在这种情况下,element是当前最佳候选者,但doc尚未准备好自动聚焦。我们将在下次调用刷新自动聚焦候选者时再试。

    6. candidates中移除element

    7. inclusiveAncestorDocuments为由doc包括祖先可导航对象活跃文档组成的列表

    8. 如果在inclusiveAncestorDocuments中的任何Document具有非null目标元素,则继续。

    9. targetelement

    10. 如果target不是可聚焦区域,则将target设置为获取可聚焦区域的结果。

      自动聚焦候选者可以包含不是可聚焦区域的元素。除了在获取可聚焦区域算法中处理的特殊情况外,这可能发生,因为具有autofocus属性的非可聚焦区域元素被插入到文档中且它从未变成可聚焦的,或者因为元素是可聚焦的,但在它存储在自动聚焦候选者中时其状态发生了变化。

    11. 如果target不为null,则:

      1. 清空candidates

      2. topDocument自动聚焦处理标志设置为true。

      3. target运行聚焦步骤

这处理了文档加载期间的自动聚焦。show()showModal()方法也处理dialog元素的autofocus属性。

聚焦元素并不意味着如果浏览器窗口失去焦点,用户代理必须聚焦浏览器窗口。

Global_attributes/autofocus

仅在一个引擎中支持。

Firefox🔰 1+Safari🔰 4+Chrome79+
Opera66+Edge79+
Edge (旧版)Internet Explorer🔰 10+
Firefox Android?Safari iOS?Chrome Android?WebView Android79+Samsung Internet?Opera Android57+

autofocus IDL属性必须反映同名的内容属性。

在以下代码片段中,文本控件将在文档加载时获得焦点。

<input maxlength="256" name="q" value="" autofocus>
<input type="submit" value="Search">

autofocus属性适用于所有元素,而不仅仅是表单控件。这允许以下示例:

<div contenteditable autofocus>Edit <strong>me!</strong><div>

6.7 分配键盘快捷键

6.7.1 介绍

本节为非规范性内容。

每个可以激活或聚焦的元素都可以使用accesskey属性分配一个单一的键组合来激活它。

确切的快捷键由用户代理确定,基于用户的键盘信息、平台上已有的键盘快捷键以及页面上指定的其他快捷键,使用accesskey属性中提供的信息作为指南。

为了确保在各种输入设备上都有相关的键盘快捷键可用,作者可以在accesskey属性中提供多个备选项。

每个备选项由一个字符组成,例如字母或数字。

用户代理可以向用户提供键盘快捷键列表,但也鼓励作者这样做。accessKeyLabelIDL属性返回一个字符串,表示用户代理分配的实际键组合。

在此示例中,作者提供了一个可以使用快捷键调用的按钮。为了支持完整键盘,作者提供了"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"。

因此,一般来说,试图解析从accessKeyLabelIDL属性返回的值是不明智的。

6.7.2 accesskey 属性

Global_attributes/accesskey

所有当前引擎支持。

Firefox1+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerYes
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

所有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"。确切的字符串取决于分配的访问键是什么,以及用户代理如何表示该键组合。

6.7.3 处理模型

元素的分配访问键是从该元素的accesskey内容属性派生的键组合。最初,一个元素不得有分配访问键

每当元素的accesskey属性被设置、更改或删除时,用户代理必须通过运行以下步骤来更新元素的分配访问键

  1. 如果该元素没有accesskey属性,则跳到下面的回退步骤。

  2. 否则,按ASCII空格拆分属性的值,并将keys作为生成的标记。

  3. 依次对keys中的每个值,按属性值中出现的顺序运行以下子步骤:

    1. 如果该值不是长度恰好为一个代码点的字符串,则跳过该值的其余步骤。

    2. 如果该值不对应系统键盘上的键,则跳过该值的其余步骤。

    3. (This is a tracking vector.)如果用户代理可以找到零个或多个修饰键的组合,与对应于属性中给定值的键组合使用,则用户代理可以将该组合分配为元素的分配访问键并返回。

  4. 回退:用户代理可以选择一个键组合作为元素的分配访问键,然后返回。

  5. 如果执行到此步骤,元素没有分配访问键

一旦用户代理为元素选择并分配了访问键,除非accesskey内容属性更改或元素移至另一个Document,用户代理不应更改元素的分配访问键

当用户按下与元素的分配访问键对应的键组合时,如果元素定义了一个命令,命令的隐藏状态部分为假(可见),命令的禁用状态部分也为假(启用),该元素在具有非空浏览上下文的文档中,并且该元素及其任何祖先都没有指定hidden属性,则用户代理必须触发命令的动作

用户代理可能会以其他方式显示具有accesskey属性的元素,例如在响应特定键组合时显示的菜单中。


HTMLElement/accessKey

所有当前引擎支持。

Firefox5+Safari6+Chrome17+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

accessKey IDL属性必须反映 accesskey内容属性。

HTMLElement/accessKeyLabel

Firefox8+Safari14+ChromeNo
Opera?EdgeNo
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

accessKeyLabel IDL属性必须返回一个表示元素的分配访问键的字符串(如果有)。如果元素没有分配访问键,则IDL属性必须返回空字符串。

6.8 编辑

6.8.1 使文档区域可编辑:contenteditable 内容属性

HTMLElement/contentEditable

所有当前引擎支持。

Firefox3+Safari3+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
interface mixin ElementContentEditable {
  [CEReactions] attribute DOMString contentEditable;
  [CEReactions] attribute DOMString enterKeyHint;
  readonly attribute boolean isContentEditable;
  [CEReactions] attribute DOMString inputMode;
};

Global_attributes/contenteditable

所有当前引擎支持。

Firefox3+Safari4+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

contenteditable内容属性是一个枚举属性,具有以下关键字和状态:

关键字 状态 简要描述
true true 元素是可编辑的。
(空字符串)
false false 元素不可编辑。
plaintext-only plaintext-only 仅元素的纯文本内容可编辑;禁用富文本格式。

该属性的缺省值无效值缺省都是inherit状态。inherit状态表示元素的可编辑性基于父元素的状态。

例如,考虑一个包含表单文本区域的新文章发布页面,用户预期使用HTML编写文章:

<form method=POST>
 <fieldset>
  <legend>New article</legend>
  <textarea name=article>&lt;p>Hello world.&lt;/p></textarea>
 </fieldset>
 <p><button>Publish</button></p>
</form>

当启用脚本时,textarea元素可以使用contenteditable属性替换为富文本控件:

<form method=POST>
 <fieldset>
  <legend>New article</legend>
  <textarea id=textarea name=article>&lt;p>Hello world.&lt;/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:.2em; font-size:2em; 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

HTMLElement/isContentEditable

支持所有当前的引擎。

Firefox4+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

如果元素是可编辑的,则返回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。

6.8.2 使整个文档可编辑:designMode getter 和 setter

document.designMode [ = value ]

Document/designMode

支持所有当前的引擎。

Firefox1+Safari1.2+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

如果文档是可编辑的,则返回"on",如果不是则返回"off"。

可以设置,以改变文档的当前状态。这将使文档聚焦并重置文档中的选择。

Document对象有一个相关的设计模式启用,这是一个布尔值。它最初为false。

designMode getter步骤是:如果this设计模式启用为true,则返回"on";否则返回"off"。

designMode setter步骤如下:

  1. value转换为ASCII小写

  2. 如果value为"on"且this设计模式启用为false,则:

    1. this设计模式启用设置为true。

    2. 重置this活动范围的开始和结束边界点到this的开始位置。

    3. 聚焦步骤运行this文档元素(如果非null)。

  3. 如果value为"off",则将this设计模式启用设置为false。

6.8.3 页面编辑器的最佳实践

建议作者在'white-space'属性上设置编辑主机和通过这些编辑机制原始创建的标记,值为'pre-wrap'。默认的HTML空白处理不适用于所见即所得编辑,并且在某些极端情况下,如果'white-space'保持默认值,换行将无法正常工作。

如果使用默认的'normal'值,会出现问题,例如用户输入"yellow␣␣ball",两个单词之间有两个空格(这里用"␣"表示)。根据默认值的编辑规则'white-space' ('normal'),生成的标记将包含"yellow&nbsp; ball"或"yellow &nbsp;ball";即,在两个单词之间将有一个不间断空格以及一个常规空格。这是必要的,因为'white-space'的'normal'值要求将相邻的常规空格折叠在一起。

在前一种情况下,即使"yellow"本身可能适合行末,"yellow⍽"(这里用"⍽"表示不间断空格)可能会换行到下一行;在后一种情况下,如果换行到行首,"⍽ball"将有不间断空格的可见缩进。

'white-space'设置为'pre-wrap'时,编辑规则将只是简单地在单词之间放置两个常规空格,如果这两个单词在行末被拆分,空格将在渲染时整齐地被移除。

6.8.4 编辑API

编辑主机是指具有contenteditable属性且状态为trueplaintext-onlyHTML元素,或其设计模式启用为true的HTML元素Document

术语活动范围编辑主机可编辑的定义,作为编辑主机可编辑元素的用户界面要求,execCommand()queryCommandEnabled()queryCommandIndeterm()queryCommandState()queryCommandSupported()queryCommandValue()方法,文本选择,以及删除选择算法在execCommand中定义。[EXECCOMMAND]

6.8.5 拼写和语法检查

用户代理可以支持对可编辑文本的拼写和语法检查,无论是在表单控件中(例如textarea元素的值),还是在编辑主机中的元素(例如使用contenteditable)。

对于每个元素,用户代理必须通过默认设置或用户表达的偏好来建立默认行为。每个元素有三种可能的默认行为:

默认启用
如果其内容是可编辑的且拼写检查未通过spellcheck属性明确禁用,则会检查该元素的拼写和语法。
默认禁用
除非通过spellcheck属性明确启用,否则不会检查该元素的拼写和语法。
默认继承
元素的默认行为与其父元素相同。没有父元素的元素不能将此作为其默认行为。

Global_attributes/spellcheck

支持所有当前的引擎。

FirefoxYesSafariYesChrome9+
OperaYesEdge79+
Edge (旧版)12+Internet Explorer11
Firefox Android57+Safari iOS9.3+Chrome Android47+WebView Android?Samsung Internet?Opera Android37+

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"。


用户代理在考虑此功能的可检查文本时应仅考虑以下文本部分:

对于作为Text节点一部分的文本,与该文本相关联的元素是第一个字符的直接父元素。对于属性中的文本,是属性的元素。对于inputtextarea元素的值,是元素本身。

要确定适用元素(如上所述)中的单词、句子或其他文本部分是否启用了拼写和语法检查,用户代理必须使用以下算法:

  1. 如果用户禁用了该文本的检查,则禁用检查。
  2. 否则,如果用户强制始终启用该文本的检查,则启用检查。
  3. 否则,如果与该文本相关联的元素具有spellcheck内容属性,则:如果该属性处于true状态,则启用检查;否则,如果该属性处于false状态,则禁用检查。
  4. 否则,如果有一个祖先元素具有spellcheck内容属性且不处于默认状态,则:如果最近的这样的祖先的spellcheck内容属性处于true状态,则启用检查;否则,禁用检查。
  5. 否则,如果元素的默认行为默认启用,则启用检查。
  6. 否则,如果元素的默认行为默认禁用,则禁用检查。
  7. 否则,如果元素的父元素启用了检查,则启用检查。
  8. 否则,禁用检查。

如果某个单词/句子/文本启用了检查,用户代理应在该文本中标记拼写和语法错误。用户代理在建议拼写和语法修正时应考虑文档中给出的其他语义。用户代理可以使用元素的语言来确定使用哪些拼写和语法规则,也可以使用用户的 首选语言设置。用户代理应尽可能使用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>

本规范未定义拼写和语法检查器的用户界面。用户代理可以提供按需检查,可以在启用检查时进行持续检查,或者使用其他接口。

6.8.6 写作建议

用户代理在用户输入到可编辑区域时提供写作建议,无论是在表单控件中(例如textarea元素)还是在编辑主机中的元素。

writingsuggestions内容属性是一个枚举属性,具有以下关键字和状态:

关键字 状态 简要描述
true true 此元素应提供写作建议。
(空字符串)
false false 此元素不应提供写作建议。

该属性的缺失值默认值默认状态。默认状态表示元素应根据默认行为进行操作,可能基于父元素自身的writingsuggestions状态,如下所定义。

该属性的无效值默认值true状态。

element.writingSuggestions [ = value ]

如果用户代理要在元素的范围内提供写作建议,则返回"true";否则返回"false"。

可以设置,以覆盖默认值并设置writingsuggestions内容属性。

给定element计算写作建议值由以下步骤确定:

  1. 如果elementwritingsuggestions内容属性处于false状态,则返回"false"。

  2. 如果elementwritingsuggestions内容属性处于默认状态,element有父元素,并且element的父元素的计算写作建议值为"false",则返回"false"。

  3. 返回"true"。

writingSuggestionsgetter步骤如下:

  1. 返回this计算写作建议值

writingSuggestions IDL属性不受覆盖writingsuggestions内容属性的用户偏好的影响,因此可能不会反映实际的写作建议状态。

writingSuggestionssetter步骤如下:

  1. thiswritingsuggestions内容属性设置为给定值。


用户代理只有在运行以下算法给定element返回true时,才应在元素的范围内提供建议:

  1. 如果用户禁用了写作建议,则返回false。

  2. 如果以下条件都不成立:

    则返回false。

  3. 如果element有一个具有writingsuggestions内容属性的包含祖先,该属性不处于默认状态,且最近的此类祖先的writingsuggestions内容属性处于false状态,则返回false。

  4. 否则,返回true。

本规范未定义写作建议的用户界面。用户代理可以提供按需建议、用户输入时的持续建议、内联建议、弹出窗口中的自动填充建议,或者使用其他接口。

6.8.7 自动大写

某些输入文本的方法,例如移动设备上的虚拟键盘,以及语音输入,通常通过自动将句子的首字母大写来帮助用户(在使用这种惯例的语言中编写文本时)。实现自动大写的虚拟键盘在即将输入应自动大写的字母时,可能会自动切换为显示大写字母(但允许用户将其切换回小写)。其他类型的输入,例如语音输入,可能以一种不允许用户先进行干预的方式执行自动大写。autocapitalize属性允许作者控制这种行为。

通常实现的autocapitalize属性不会影响使用物理键盘输入时的行为。(因此,以及用户在某些情况下可以覆盖自动大写行为或在初始输入后编辑文本的能力,不应依赖该属性进行任何类型的输入验证。)

autocapitalize 属性可用于 编辑宿主上,以控制托管的可编辑区域的自动大写行为,也可用于 inputtextarea 元素上,以控制该元素输入文本时的行为,或用于 form 元素上,以控制与该 form 元素关联的所有 自动大写和自动更正继承的元素 的默认行为。

autocapitalize属性永远不会导致input元素在其type属性处于URLEmailPassword状态时启用自动大写。(此行为包含在下面的使用的自动大写提示算法中。)

自动大写处理模型基于选择以下五个自动大写提示之一,定义如下:

默认

用户代理和输入法应自行确定是否启用自动大写。

不应应用自动大写(所有字母应默认为小写)。

句子

每个句子的第一个字母应默认为大写字母;所有其他字母应默认为小写。

单词

每个单词的第一个字母应默认为大写字母;所有其他字母应默认为小写。

字符

所有字母应默认为大写。

Global_attributes/autocapitalize

支持所有当前的引擎。

Firefox111+SafariNoChrome43+
Opera?Edge79+
Edge (旧版)?Internet Explorer?
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android?

autocapitalize属性是一个枚举属性,其状态是可能的自动大写提示。属性状态指定的自动大写提示与其他考虑因素结合形成使用的自动大写提示,它通知用户代理的行为。此属性的关键字及其状态映射如下:

关键字 状态
off none
none
on sentences
sentences
words words
characters characters

该属性的缺失值默认值默认状态,其无效值默认值句子状态。

element.autocapitalize [ = value ]

返回元素的当前自动大写状态,如果尚未设置,则返回空字符串。注意,对于从form元素继承其状态的inputtextarea元素,此操作将返回form元素的自动大写状态,但对于在可编辑区域中的元素,此操作将不会返回编辑主机的自动大写状态(除非此元素实际上是编辑主机)。

可以设置,以设置autocapitalize内容属性(从而更改元素的自动大写行为)。

要计算元素element自身自动大写提示,请运行以下步骤:

  1. 如果 element 上存在 autocapitalize 内容属性,并且其值不是空字符串,则返回该属性的状态。

  2. 如果 element 是一个自动大写和自动更正继承的元素,并且有一个非空的表单所有者,则返回 element自身自动大写提示,即其表单所有者的提示。

  3. 返回 默认

autocapitalizegetter步骤如下:

  1. state成为自身自动大写提示

  2. 如果state默认,则返回空字符串。

  3. 如果state,则返回"none"。

  4. 如果state句子,则返回"sentences"。

  5. 返回与state对应的关键字值。

autocapitalizesetter步骤是将autocapitalize内容属性设置为给定值。


支持可定制自动大写行为的用户代理,如果希望允许Web开发人员控制此功能,则在元素中输入文本期间,应计算该元素的使用的自动大写提示。这将是一个描述文本输入该元素时推荐的自动大写行为的自动大写提示

用户代理或输入法可以选择在某些情况下忽略或覆盖使用的自动大写提示

元素element使用的自动大写提示是使用以下算法计算的:

  1. 如果elementinput元素,且其type属性处于URLEmailPassword状态,则返回默认

  2. 如果elementinput元素或textarea元素,则返回element自身自动大写提示

  3. 如果element编辑主机可编辑元素,则返回element自身自动大写提示

  4. 断言:此步骤永远不会被触及,因为文本输入仅在符合上述条件的元素中发生。

6.8.8 自动更正

某些文本输入方法通过在用户打字时自动更正拼写错误来帮助用户,此过程也称为自动更正。用户代理可以支持表单控件中的可编辑文本(例如 textarea 元素的值)或 编辑宿主中的元素(例如,使用 contenteditable)的自动更正。自动更正可能伴随用户界面,提示文本即将被更正或已被更正,通常在插入标点符号、空格或新段落后执行拼写错误的自动更正。autocorrect 属性允许作者控制此类行为。

autocorrect 属性可用于编辑宿主,以控制托管的可编辑区域的自动更正行为,也可用于 inputtextarea 元素,以控制插入文本时的行为,或用于 form 元素,以控制与该 form 相关联的所有 自动大写和自动更正继承的元素的默认行为。

autocorrect 属性永远不会使自动更正对 input 元素启用, 如果其 type 属性处于 URL电子邮件密码 状态之一。(该行为包含在下面的已使用自动更正状态算法中。)

autocorrect 属性是一个枚举属性,具有以下关键字和状态:

关键字 状态 简短描述
on on 允许用户代理在用户打字时自动更正拼写错误。是否在打字时自动更正拼写由用户代理决定,可能取决于元素以及用户的偏好。
(空字符串)
off off 用户代理不允许在用户打字时自动更正拼写错误。

该属性的无效值默认值缺失值默认值均为on状态。

autocorrect getter 步骤为:如果元素的 已使用自动更正状态on,则返回 true;如果已使用自动更正状态为 off,则返回 false。setter 步骤为:如果给定值为 true,则将元素的 autocorrect 属性设置为 "on";否则设置为 "off"。

要计算元素 element已使用自动更正状态,运行以下步骤:

  1. 如果 element 是一个 input 元素,并且其 type 属性处于 URL电子邮件密码状态之一,则返回 off

  2. 如果 element 上存在 autocorrect 内容属性,则返回该属性的状态。

  3. 如果 element 是一个自动大写和自动更正继承的元素,并且有一个非空的表单所有者,则返回其表单所有者autocorrect 属性状态。

  4. 返回 on

element . autocorrect

返回元素的自动更正行为。注意,对于自动大写和自动更正继承的元素,如果它们从 form 元素继承状态,那么将返回 form 元素的自动更正行为,但对于可编辑区域中的元素,不会返回 编辑宿主的自动更正行为(除非该元素实际上是 编辑宿主)。

element . autocorrect = value

更新 autocorrect 内容属性(从而更改元素的自动更正行为)。

在以下示例中,input 元素将不允许自动更正,因为它没有 autocorrect 内容属性,因此继承自 form 元素,该元素的属性为 "off"。然而,textarea 元素将允许自动更正,因为它有一个值为 "on" 的 autocorrect 内容属性。

<form autocorrect="off">
 <input type="search">
 <textarea autocorrect="on"></textarea>
</form>

6.8.9 输入模式:inputmode属性

用户代理可以在表单控件(例如textarea元素的值)或编辑主机中的元素(例如,使用contenteditable)上支持inputmode属性。

Global_attributes/inputmode

支持所有当前引擎。

Firefox95+SafariNoChrome66+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android79+Safari iOS12.2+Chrome Android?WebView Android?Samsung Internet?Opera Android?

inputmode内容属性是一个枚举属性,指定了对用户输入内容最有帮助的输入机制类型。

关键字 描述
none 用户代理不应显示虚拟键盘。此关键字适用于渲染自身键盘控件的内容。
text 用户代理应显示能够在用户本地语言中输入文本的虚拟键盘。
tel 用户代理应显示能够输入电话号码的虚拟键盘。这应包括0到9的数字键、“#”字符键和“*”字符键。在某些地区,这还可以包括字母助记标签(例如,在美国,标有“2”的键历史上还标有字母A、B和C)。
url 用户代理应显示能够在用户本地语言中输入文本的虚拟键盘,并带有帮助输入URL的键,例如“/”和“.”字符键以及快速输入域名中常见字符串(如“www.”或“.com”)的键。
email 用户代理应显示能够在用户本地语言中输入文本的虚拟键盘,并带有帮助输入电子邮件地址的键,例如“@”字符键和“.”字符键。
numeric 用户代理应显示能够输入数字的虚拟键盘。此关键字对于PIN码输入很有用。
decimal 用户代理应显示能够输入分数数字的虚拟键盘。应显示数字键和适合本地语言的格式分隔符。
search 用户代理应显示为搜索优化的虚拟键盘。

HTMLElement/inputMode

支持所有当前引擎。

Firefox95+Safari12.1+Chrome66+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android79+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

inputModeIDL属性必须反映inputmode内容属性,仅限于已知值

inputmode未指定(或处于用户代理不支持的状态)时,用户代理应确定要显示的默认虚拟键盘。应使用诸如输入typepattern属性之类的上下文信息来确定应向用户显示哪种类型的虚拟键盘。

6.8.9 输入模式:enterkeyhint属性

用户代理可以在表单控件(例如textarea元素的值)或编辑主机中的元素(例如,使用contenteditable)上支持enterkeyhint属性。

Global_attributes/enterkeyhint

支持所有当前引擎。

Firefox94+Safari13.1+Chrome77+
Opera66+Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android57+

enterkeyhint内容属性是一个枚举属性,指定虚拟键盘上回车键显示的操作标签(或图标)。这允许作者自定义回车键的显示,以便为用户提供更多帮助。

关键字 描述
enter 用户代理应显示“enter”操作的提示,通常插入新行。
done 用户代理应显示“done”操作的提示,通常表示没有更多输入,输入法编辑器(IME)将关闭。
go 用户代理应显示“go”操作的提示,通常表示将用户带到他们输入的文本目标。
next 用户代理应显示“next”操作的提示,通常将用户带到下一个接受文本的字段。
previous 用户代理应显示“previous”操作的提示,通常将用户带到上一个接受文本的字段。
search 用户代理应显示“search”操作的提示,通常将用户带到搜索结果页面。
send 用户代理应显示“send”操作的提示,通常表示将文本发送到目标。

HTMLElement/enterKeyHint

支持所有当前引擎。

Firefox94+Safari13.1+Chrome77+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android57+

enterKeyHintIDL属性必须反映enterkeyhint内容属性,仅限于已知值

enterkeyhint未指定(或处于用户代理不支持的状态)时,用户代理应确定要显示的默认操作标签(或图标)。应使用诸如inputmodetypepattern属性之类的上下文信息来确定应在虚拟键盘上显示的操作标签(或图标)。

6.9 页面内查找

6.9.1 介绍

本节定义了页面内查找 —— 一种常见的用户代理机制,允许用户在页面内容中搜索特定信息。

通过页面内查找接口提供对页面内查找功能的访问。这是一个由用户代理提供的用户界面,允许用户指定输入和搜索参数。此接口可以通过快捷方式或菜单选择出现。

页面内查找接口中的文本输入和设置的组合代表用户的查询。这通常包括用户想要搜索的文本以及可选设置(例如,仅限于整词搜索的能力)。

用户代理根据给定的查询处理页面内容,并识别出零个或多个匹配项,这些匹配项是满足用户查询的内容范围。

其中一个匹配项被标识为活动匹配项。它被高亮显示并滚动到视图中。用户可以通过使用页面内查找接口前进活动匹配项来浏览匹配项

问题 #3539 追踪了标准化当前未指定的window.find() API的页面内查找的方式。

6.9.2detailshidden=until-found的交互

当页面内查找开始搜索匹配项时,页面中所有没有设置open属性的details元素,其第二槽位的跳过内容应变得可访问,而不修改open属性,以使页面内查找能够搜索其中的内容。同样,具有hidden属性并处于hidden until found状态的所有HTML元素,其跳过内容应变得可访问,而不修改hidden属性,以使页面内查找能够搜索其中的内容。页面内查找结束后,这些details元素和具有hidden属性并处于hidden until found状态的元素应再次跳过其内容。整个过程必须同步进行(因此对用户或作者代码不可见)。[CSSCONTAIN]

当页面内查找选择新的活动匹配项时,请执行以下步骤:

  1. node成为活动匹配项中的第一个节点。

  2. 在用户交互任务源上排队一个全局任务,给定node相关全局对象来运行以下步骤:

    1. node上运行祖先详细信息揭示算法

    2. node上运行祖先隐藏直到找到揭示算法

(这是一个跟踪向量。)当页面内查找像这样自动展开details元素时,它会触发toggle事件。与页面内查找触发的单独scroll事件一样,此事件可能会被页面用来发现用户在页面内查找对话框中输入的内容。如果页面创建了一个带有当前搜索词和用户可能输入的每个下一个字符的微小可滚动区域,并且观察到浏览器滚动到哪个字符,它可以将该字符添加到搜索词中并更新可滚动区域以逐步构建搜索词。通过将每个可能的下一个匹配项包装在一个关闭的details元素中,页面可以监听toggle事件而不是scroll事件。这种攻击可以通过不对用户在页面内查找对话框中输入的每个字符进行操作来解决。

6.9.3 与选择的交互

页面内查找过程在文档的上下文中调用,可能会影响该文档的选择。具体来说,定义活动匹配项的范围可以决定当前的选择。然而,这些选择更新可能会在页面内查找过程中的不同时间发生(例如,在页面内查找接口关闭时或在活动匹配项范围变化时)。

6.10 关闭请求和关闭监视器

6.10.1 关闭请求

用户可以通过一种实现定义(并且可能是设备特定的)方式向用户代理发送关闭请求。这表示用户希望关闭当前显示在屏幕上的某些内容,如弹出窗口、菜单、对话框、选择器或显示模式。

一些示例关闭请求如下:

每当用户代理收到针对文档的潜在关闭请求时,必须在给定document相关全局对象用户交互任务源排队一个全局任务,以执行以下关闭请求步骤

  1. 如果document全屏元素不为null,则:

    1. document节点可导航顶级可遍历活动文档完全退出全屏

    2. 返回。

    不会触发任何相关事件,如keydown;它只会最终触发fullscreenchange事件。

  2. 可选地,跳到标记为替代处理的步骤。

    例如,如果用户代理检测到用户对当前网页反复拦截关闭请求感到沮丧,它可能会采取这条路径。

  3. 根据UI Events或其他相关规范,触发任何相关事件。[UIEVENTS]

    UI Events模型中,相关事件的一个示例是在用户按下键盘上的Esc键时,UI Events建议触发的keydownkeyup序列。在大多数带键盘的平台上,这被视为关闭请求,因此会触发这些关闭请求步骤

    一个在UI Events模型之外的相关事件示例是,当用户通过使用取消手势发送关闭请求时,辅助技术合成的Esckeydownkeyup序列。

  4. 如果没有触发此类事件,则event为null;否则,event为表示其中一个触发事件的事件对象。如果触发了多个事件,选择哪个是实现定义的,但如果为Esc键触发了keydownkeyup事件,用户代理必须选择keydown事件。

  5. 如果event不为null,并且其取消标志已设置,则返回。

  6. 如果document不是完全活动的,则返回。

    此步骤是必要的,因为如果event不为null,则事件监听器可能导致document不再是完全活动的。

  7. closedSomething成为在document相关全局对象处理关闭监视器的结果。

  8. 如果closedSomething为true,则返回。

  9. 替代处理:否则,没有监视到关闭请求。用户代理可以改为将此交互解释为其他操作,而不是将其解释为关闭请求。

Esc键是关闭请求的平台上,用户代理将首先触发适当初始化的keydownkeyup事件序列。如果网页开发者通过调用preventDefault()取消keyup事件,则不会发生任何进一步的操作。但如果事件未被取消触发,则用户代理将继续处理关闭监视器

在返回按钮是潜在关闭请求的平台上,没有涉及事件,因此当按下返回按钮时,用户代理将直接处理关闭监视器。如果有一个活动关闭监视器,那么它将被触发。如果没有,用户代理可以将按下返回按钮解释为另一种方式,例如作为请求按-1的增量遍历历史记录

6.10.2 关闭监视器基础设施

每个窗口都有一个关闭监视器管理器,这是一个具有以下结构

关闭监视器管理器的大部分复杂性来自防滥用保护,旨在防止开发人员禁用用户的历史记录遍历功能,对于某些平台,关闭请求回退操作是历史记录遍历的主要机制。特别是:

关闭监视器的分组设计为,如果在没有历史动作激活的情况下创建了多个关闭监视器,它们将被分组在一起,以便用户触发的关闭请求会关闭组中的所有关闭监视器。这确保了网页开发人员无法通过创建关闭监视器来拦截无限数量的关闭请求;相反,他们最多可以创建等于1+用户激活页面的次数的数量。

下次用户交互允许新组的布尔值鼓励网页开发人员以与单个用户激活相关的方式创建关闭监视器。如果没有它,每次用户激活都会增加允许的组数,即使网页开发人员没有利用这些用户激活来创建关闭监视器。简而言之:

此保护对于维护我们期望的最多创建(1 + 用户激活页面的次数)组的不变量并不重要。一个坚定的滥用者只会每次用户交互创建一个关闭监视器,将它们“存储”以供将来滥用。但是,此系统会为正常情况带来更可预测的行为,并鼓励非滥用开发人员直接响应用户交互来创建关闭监视器。

通知关闭监视器管理器用户激活给定窗口 window

  1. manager成为window关闭监视器管理器

  2. 如果manager下次用户交互允许新组为true,则递增manager允许的组数

  3. manager下次用户交互允许新组设置为false。


关闭监视器是一个具有以下结构

如果closeWatcher活动closeWatcher窗口关闭监视器管理器包含任何包含closeWatcher 的列表。


建立关闭监视器,给定窗口 window,一个步骤列表cancelAction,和一个步骤列表closeAction

  1. 断言window相关Document完全活动的

  2. closeWatcher成为一个新的关闭监视器,具有以下属性:

    窗口
    window
    取消动作
    cancelAction
    关闭动作
    closeAction
    正在运行取消动作
    false
  3. manager成为window关闭监视器管理器

  4. 如果manager大小小于manager允许的组数,则追加«closeWatcher»到manager

  5. 否则:

    1. 断言manager大小在此分支中至少为1,因为manager允许的组数始终至少为1。

    2. 追加 closeWatchermanager的最后一个

  6. manager下次用户交互允许新组设置为true。

  7. 返回closeWatcher

请求关闭一个关闭监视器 closeWatcher

  1. 如果closeWatcher 未激活,则返回true。

  2. 如果closeWatcher正在运行取消动作为true,则返回true。

  3. window成为closeWatcher窗口

  4. 如果window相关Document不是完全活动的,则返回true。

  5. 如果window关闭监视器管理器大小小于window关闭监视器管理器允许的组数,并且window具有历史动作激活,则让canPreventClose为true;否则为false。

  6. closeWatcher正在运行取消动作设置为true。

  7. shouldContinue成为运行closeWatcher取消动作给定canPreventClose的结果。

  8. closeWatcher正在运行取消动作设置为false。

  9. 如果shouldContinue为false,则:

    1. 断言canPreventClose为true。

    2. 消费历史动作用户激活给定window

    3. 返回false。

    请注意,由于这些子步骤消费历史动作用户激活请求关闭一个关闭监视器两次而没有任何中间的用户激活将导致canPreventClose在第二次为false。

  10. 关闭 closeWatcher

  11. 返回true。

关闭一个关闭监视器 closeWatcher

  1. 如果closeWatcher 未激活,则返回。

  2. 如果closeWatcher窗口相关Document不是完全活动的,则返回。

  3. 销毁 closeWatcher

  4. 运行closeWatcher关闭动作

销毁一个关闭监视器 closeWatcher

  1. manager成为closeWatcher窗口关闭监视器管理器

  2. 对于 manager中的每个group移除 closeWatchergroup

  3. 移除任何manager中的空项


处理关闭监视器给定窗口 window

  1. processedACloseWatcher为false。

  2. 如果window关闭监视器管理器不是空的:

    1. group成为window关闭监视器管理器的最后一个

    2. 对于 group中的每个closeWatcher,按相反顺序:

      1. processedACloseWatcher设置为true。

      2. shouldProceed成为请求关闭 closeWatcher的结果。

      3. 如果shouldProceed为false,则中断

  3. 如果window关闭监视器管理器允许的组数大于1,则将其减1。

  4. 返回processedACloseWatcher

6.10.3 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()

这是一个辅助工具,可以用于将取消和关闭逻辑整合到 cancelclose 事件处理程序中,通过让所有非 close request 的关闭操作调用此方法。

watcher.close()

立即触发 close 事件,然后将关闭监视器停用,如同调用 watcher.destroy()

这是一个辅助工具,可以用于触发关闭逻辑到 close 事件处理程序,跳过 cancel 事件处理程序中的任何逻辑。

watcher.destroy()

停用 watcher,使其不再接收 close 事件,并且可以构造新的独立 CloseWatcher 实例。

这是为了在相关的 UI 元素以其他方式被拆除而不是被关闭时调用。

每个 CloseWatcher 实例都有一个 内部关闭监视器,它是一个 关闭监视器

new CloseWatcher(options) 构造步骤如下:

  1. 如果 this相关全局对象关联 Document 不是 完全活动的,则抛出 "InvalidStateError" DOMException

  2. closeWatcher 成为 建立一个关闭监视器 的结果,给定 this相关全局对象,其中:

  3. 如果 options["signal"] 存在,则:

    1. 如果 options["signal"] 被 中止,则 销毁 closeWatcher

    2. 添加 以下步骤到 options["signal"]:

      1. 销毁 closeWatcher

  4. this内部关闭监视器 设置为 closeWatcher

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(),点击该按钮将触发 CloseWatchercancel 事件,从而在有未保存数据的情况下可能会要求用户确认。如果我们使用了 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() 是非常重要的。这样做是恢复“免费”未分组关闭监视器槽的唯一方法。这些在没有用户激活的情况下创建的关闭监视器对于像会话不活动超时对话框或服务器触发事件的紧急通知等情况非常有用,这些不是用户激活生成的。

6.11 拖放

HTML_Drag_and_Drop_API

所有当前引擎均支持。

Firefox3.5+Safari3.1+Chrome4+
Opera12+Edge79+
Edge (旧版)18Internet Explorer5.5+
Firefox Android4+Safari iOS2+Chrome Android18+WebView Android4.4+Samsung Internet1.5+Opera Android14+

本节定义了一种基于事件的拖放机制。

本规范未具体定义 拖放操作 实际上是什么。

在具有指针设备的可视介质上,拖动操作可以是一个 mousedown 事件的默认操作,该事件后跟一系列 mousemove 事件,而放下可以通过松开鼠标来触发。

当使用指针设备以外的输入模式时,用户可能需要明确表明他们打算执行拖放操作,分别说明他们希望拖动什么以及希望将其放置在哪里。

无论如何实现,拖放操作必须有一个起点(例如鼠标点击的位置,或选择用于拖动的元素或选择的开始),可以有任意数量的中间步骤(鼠标在拖动过程中移动经过的元素,或用户在循环浏览可能的放置点时选择的元素),并且必须有一个终点(鼠标按钮松开时上方的元素,或最终选择的元素),或被取消。终点必须是放下发生之前最后一次选择的可能的放置点(因此如果操作未取消,必须至少有一个中间步骤中的元素)。

6.11.1 介绍

本节为非规范性内容。

要使一个元素可拖动,给该元素添加一个 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>

要接受一个放置操作,放置目标必须监听以下事件:

  1. dragenter事件处理程序通过取消事件报告放置目标是否可能愿意接受放置。
  2. dragover事件处理程序通过设置与事件关联的dropEffect属性来指定将向用户显示的反馈。此事件也需要被取消。
  3. 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>

6.11.2 拖放数据存储

拖放操作所依赖的数据,称为拖放数据存储,包括以下信息:

拖放数据存储创建时,它必须初始化为其拖放数据存储项列表为空,没有拖放数据存储默认反馈,没有拖放数据存储位图拖放数据存储热点坐标,其拖放数据存储模式受保护模式,其拖放数据存储允许的效果状态为字符串"未初始化"。

6.11.3 DataTransfer接口

DataTransfer

在所有当前引擎中支持。

Firefox3.5+Safari4+Chrome3+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12+

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

在所有当前引擎中支持。

Firefox62+Safari14.1+Chrome59+
Opera?Edge79+
Edge (旧版)17+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet8.0+Opera Android44+

创建一个新的DataTransfer对象,并带有一个空的拖放数据存储

dataTransfer.dropEffect [ = value ]

DataTransfer/dropEffect

在所有当前引擎中支持。

Firefox3.5+Safari4+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回当前选择的操作类型。如果当前操作类型不是effectAllowed属性允许的操作类型之一,则操作会失败。

可以设置以更改选择的操作类型。

可能的值为"none"、"copy"、"link"和"move"。

dataTransfer.effectAllowed [ = value ]

DataTransfer/effectAllowed

在所有当前引擎中支持。

Firefox3.5+Safari4+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回要允许的操作类型。

可以在dragstart事件期间设置,以更改允许的操作。

可能的值为"none"、"copy"、"copyLink"、"copyMove"、"link"、"linkMove"、"move"、"all"和"uninitialized"。

dataTransfer.items

DataTransfer/items

在所有当前引擎中支持。

Firefox50+Safari11.1+Chrome3+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android52+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12+

返回一个DataTransferItemList对象,包含拖动数据。

dataTransfer.setDragImage(element, x, y)

DataTransfer/setDragImage

在所有当前引擎中支持。

Firefox3.5+Safari4+Chrome3+
Opera12.1+Edge79+
Edge (旧版)18Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

使用给定的元素更新拖动反馈,替换之前指定的反馈。

dataTransfer.types

DataTransfer/types

在所有当前引擎中支持。

Firefox3.5+Safari4+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回一个frozen array,列出在dragstart事件中设置的格式。此外,如果有任何文件被拖动,则其中一个类型将是字符串"Files"。

data = dataTransfer.getData(format)

DataTransfer/getData

在所有当前引擎中支持。

Firefox3.5+Safari4+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回指定的数据。如果没有此类数据,则返回空字符串。

dataTransfer.setData(format, data)

DataTransfer/setData

在所有当前引擎中支持。

Firefox3.5+Safari5+Chrome3+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android12+

添加指定的数据。

dataTransfer.clearData([ format ])

DataTransfer/clearData

在所有当前引擎中支持。

Firefox3.5+Safari4+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

移除指定格式的数据。如果省略了参数,则移除所有数据。

dataTransfer.files

DataTransfer/files

在所有当前引擎中支持。

Firefox3.6+Safari4+Chrome3+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回一个FileList对象,包含被拖动的文件(如果有)。

DataTransfer对象在拖放事件期间创建时只在这些事件被触发时有效。

DataTransfer对象在有效期间与拖放数据存储相关联。

DataTransfer对象有一个关联的types数组,它是一个FrozenArray<DOMString>,初始为空。当DataTransfer对象的拖放数据存储项列表的内容发生变化,或当DataTransfer对象不再与拖放数据存储相关联时,运行以下步骤:

  1. L为一个空序列。

  2. 如果DataTransfer对象仍然与拖放数据存储相关联,则:

    1. 对于DataTransfer对象的拖放数据存储项列表中的每个text类型项,向L中添加一项,包含该项的类型字符串

    2. 如果DataTransfer对象的拖放数据存储项列表中有任何File类型项,则向L中添加一项,包含字符串"Files"。(此值可以与其他值区分开,因为它不是小写的。)

  3. DataTransfer对象的types数组设置为从L创建冻结数组的结果。

当调用DataTransfer()构造函数时,必须返回一个新创建的DataTransfer对象,并按如下初始化:

  1. 拖放数据存储项列表设置为空列表。

  2. 拖放数据存储模式设置为读/写模式

  3. dropEffecteffectAllowed设置为"none"。

dropEffect属性控制在拖放操作期间用户得到的拖放反馈。当创建DataTransfer对象时,dropEffect属性被设置为一个字符串值。获取时,必须返回其当前值。设置时,如果新值是"none"、"copy"、"link"或"move"之一,则属性的当前值必须设置为新值。其他值必须被忽略。

effectAllowed属性在拖放处理模型中用于在dragenterdragover事件期间初始化dropEffect属性。当创建DataTransfer对象时,effectAllowed属性被设置为一个字符串值。获取时,必须返回其当前值。设置时,如果拖放数据存储模式读/写模式,并且新值是"none"、"copy"、"copyLink"、"copyMove"、"link"、"linkMove"、"move"、"all"或"uninitialized"之一,则属性的当前值必须设置为新值。否则,必须保持不变。

items属性必须返回与DataTransfer对象关联的DataTransferItemList对象。

setDragImage(image, x, y)方法必须运行以下步骤:

  1. 如果DataTransfer对象不再与拖放数据存储相关联,则返回。什么都不做。

  2. 如果拖放数据存储模式不是读/写模式,则返回。什么都不做。

  3. 如果imageimg元素,则将拖放数据存储位图设置为元素的图像(按其自然尺寸);否则,将拖放数据存储位图设置为从给定元素生成的图像(生成的确切机制目前未指定)。

  4. 拖放数据存储热点坐标设置为给定的xy坐标。

types属性必须返回此DataTransfer对象的types数组

getData(format)方法必须运行以下步骤:

  1. 如果DataTransfer对象不再与拖放数据存储相关联,则返回空字符串。

  2. 如果拖放数据存储模式保护模式,则返回空字符串。

  3. format设置为第一个参数,并转换为ASCII小写

  4. convert-to-URL为false。

  5. 如果format等于"text",则将其更改为"text/plain"。

  6. 如果format等于"url",则将其更改为"text/uri-list"并将convert-to-URL设置为true。

  7. 如果拖放数据存储项列表中没有任何text类型且类型字符串等于format的项,则返回空字符串。

  8. result拖放数据存储项列表Plain Unicode string类型且类型字符串等于format的项的数据。

  9. 如果convert-to-URL为true,则按照text/uri-list数据的适当方式解析result,然后将result设置为列表中的第一个URL(如果有),否则设置为空字符串。[RFC2483]

  10. 返回result

setData(format, data)方法必须运行以下步骤:

  1. 如果DataTransfer对象不再与拖放数据存储相关联,则返回。什么都不做。

  2. 如果拖放数据存储模式不是读/写模式,则返回。什么都不做。

  3. format设置为第一个参数,并转换为ASCII小写

  4. 如果format等于"text",则将其更改为"text/plain"。

    如果format等于"url",则将其更改为"text/uri-list"。

  5. 移除拖放数据存储项列表text类型且类型字符串等于format的项(如果有)。

  6. 拖放数据存储项列表中添加一项,该项的类型为text类型字符串等于format,数据为方法的第二个参数。

clearData(format)方法必须运行以下步骤:

  1. 如果DataTransfer对象不再与拖放数据存储相关联,则返回。什么都不做。

  2. 如果拖放数据存储模式不是读/写模式,则返回。什么都不做。

  3. 如果方法在没有参数的情况下调用,则移除拖放数据存储项列表中每个Plain Unicode string类型的项,并返回。

  4. format设置为format,并转换为ASCII小写

  5. 如果format等于"text",则将其更改为"text/plain"。

    如果format等于"url",则将其更改为"text/uri-list"。

  6. 移除拖放数据存储项列表text类型且类型字符串等于format的项(如果有)。

方法clearData()不影响是否在拖动中包含了任何文件,因此属性types的列表在调用clearData()后可能仍然不为空(如果在拖动中包含了任何文件,则仍会包含字符串"Files")。

files属性必须返回一个liveFileList序列,包含通过以下步骤找到的File对象。此外,对于给定的FileList对象和给定的底层文件,每次必须使用相同的File对象。

  1. 以空列表L开始。

  2. 如果DataTransfer对象不再与拖放数据存储相关联,则FileList为空。返回空列表L

  3. 如果拖放数据存储模式保护模式,则返回空列表L

  4. 对于拖放数据存储项列表中的每个File类型项,将该项的数据(文件,特别是其名称和内容,以及其类型)添加到列表L中。

  5. 通过这些步骤找到的文件就是列表L中的文件。

此版本的API在拖动过程中不公开文件的类型。

6.11.3.1 DataTransferItemList 接口

DataTransferItemList

支持所有当前的引擎。

Firefox50+Safari6+Chrome13+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android未知Safari iOS未知Chrome Android未知WebView Android未知Samsung Internet未知Opera Android14+

每个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

DataTransferItemList/length

支持所有当前的引擎。

Firefox50+Safari6+Chrome13+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android未知Safari iOS未知Chrome Android未知WebView Android未知Samsung Internet未知Opera Android14+

返回拖拽数据存储中的项数。

items[index]

返回代表拖拽数据存储中第index项的DataTransferItem对象。

items.remove(index)

DataTransferItemList/remove

支持所有当前的引擎。

Firefox50+Safari6+Chrome31+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android未知Safari iOS未知Chrome Android未知WebView Android未知Samsung Internet未知Opera Android14+

移除拖拽数据存储中的第index项。

items.clear()

DataTransferItemList/clear

支持所有当前的引擎。

Firefox50+Safari6+Chrome13+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android未知Safari iOS未知Chrome Android未知WebView Android未知Samsung Internet未知Opera Android14+

移除拖拽数据存储中的所有项。

items.add(data)

DataTransferItemList/add

支持所有当前的引擎。

Firefox50+Safari6+Chrome13+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android未知Safari iOS未知Chrome Android未知WebView Android未知Samsung Internet未知Opera Android14+
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()方法必须运行以下步骤:

  1. 如果DataTransferItemList对象未处于读/写模式,返回null。

  2. 跳转到以下列表中的适当步骤集:

    如果方法的第一个参数是字符串

    如果拖拽数据存储项列表中已有一项,其类型text,且其类型字符串与方法的第二个参数值相等,转换为ASCII小写,则抛出DOMException异常,"NotSupportedError"

    否则,将一项添加到拖拽数据存储项列表中,其类型text类型字符串与方法的第二个参数值相等,转换为ASCII小写,其数据为方法的第一个参数给定的字符串。

    如果方法的第一个参数是File

    添加一项到拖拽数据存储项列表中,其类型File,其类型字符串type转换为ASCII小写,其数据与File的数据相同。

  3. 确定索引属性的值,对应于新添加的项,并返回该值(新创建的DataTransferItem对象)。

remove(index)方法必须运行以下步骤:

  1. 如果DataTransferItemList对象未处于读/写模式,抛出DOMException异常,"InvalidStateError"

  2. 如果拖拽数据存储不包含第index项,则返回。

  3. 拖拽数据存储中移除第index项。

clear()方法,如果DataTransferItemList对象处于读/写模式,必须移除所有拖拽数据存储中的项。否则,不做任何操作。

6.11.3.2 DataTransferItem 接口

DataTransferItem

支持所有当前的引擎。

Firefox50+Safari5.1+Chrome11+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android4+Samsung Internet?Opera Android14+

每个 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

DataTransferItem/kind

支持所有当前的引擎。

Firefox50+Safari5.1+Chrome11+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android未知Safari iOS未知Chrome Android未知WebView Android4+Samsung Internet未知Opera Android14+

返回拖拽数据项类型之一:“string”或“file”。

item.type

DataTransferItem/type

支持所有当前的引擎。

Firefox50+Safari5.1+Chrome11+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android未知Safari iOS未知Chrome Android未知WebView Android4+Samsung Internet未知Opera Android14+

返回拖拽数据项类型字符串

item.getAsString(callback)

DataTransferItem/getAsString

支持所有当前的引擎。

Firefox50+Safari5.1+Chrome11+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android未知Safari iOS未知Chrome Android未知WebView Android4+Samsung Internet未知Opera Android14+

如果拖拽数据项类型text,则使用字符串数据作为参数调用回调函数。

file = item.getAsFile()

DataTransferItem/getAsFile

支持所有当前的引擎。

Firefox50+Safari5.1+Chrome11+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android未知Safari iOS未知Chrome Android未知WebView Android4+Samsung Internet未知Opera Android14+

返回一个 File 对象,如果拖拽数据项类型File

DataTransferItem 对象的 DataTransfer 对象关联一个拖拽数据存储且该拖拽数据存储拖拽数据存储项列表仍包含DataTransferItem对象表示的项时,DataTransferItem对象的模式拖拽数据存储模式相同。当DataTransferItem对象的DataTransfer对象没有关联一个拖拽数据存储,或DataTransferItem对象表示的项已从相关拖拽数据存储项列表中移除时,DataTransferItem对象的模式禁用模式。本节中引用的拖拽数据存储(仅在DataTransferItem对象不处于禁用模式时使用)是DataTransferItem对象的DataTransfer对象关联的拖拽数据存储

kind属性在DataTransferItem对象处于禁用模式时返回空字符串;否则,它返回以下表中第二列中给定的字符串,其中第一列中的单元格包含拖拽数据项类型

类型 字符串
文本 "string"
文件 "file"

type属性在DataTransferItem对象处于禁用模式时返回空字符串;否则,它返回拖拽数据项类型字符串

getAsString(callback)方法必须按以下步骤执行:

  1. 如果callback为null,则返回。

  2. 如果DataTransferItem对象不处于读/写模式只读模式,则返回。回调函数不会被调用。

  3. 如果拖拽数据项类型不是文本,则返回。回调函数不会被调用。

  4. 否则,队列一个任务以调用callback,传递由DataTransferItem对象表示的项的实际数据作为参数。

getAsFile()方法必须按以下步骤执行:

  1. 如果DataTransferItem对象不处于读/写模式只读模式,则返回null。

  2. 如果拖拽数据项类型不是文件,则返回null。

  3. 返回一个新的File对象,表示由DataTransferItem对象表示的项的实际数据。

6.11.4 DragEvent 接口

DragEvent/DragEvent

支持所有当前的引擎。

Firefox3.5+Safari14+Chrome46+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android未知Safari iOS不支持Chrome Android不支持WebView Android未知Samsung Internet未知Opera Android未知

DragEvent

支持所有当前的引擎。

Firefox3.5+Safari14+Chrome46+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android未知Safari iOS不支持Chrome Android不支持WebView Android未知Samsung Internet未知Opera Android未知

拖放处理模型涉及多个事件。它们都使用 DragEvent 接口。

[Exposed=Window]
interface DragEvent : MouseEvent {
  constructor(DOMString type, optional DragEventInit eventInitDict = {});

  readonly attribute DataTransfer? dataTransfer;
};

dictionary DragEventInit : MouseEventInit {
  DataTransfer? dataTransfer = null;
};
event.dataTransfer

DragEvent/dataTransfer

支持所有当前的引擎。

Firefox3.5+Safari14+Chrome46+
Opera未知Edge79+
Edge (旧版)12+Internet Explorer🔰10+
Firefox Android未知Safari iOS不支持Chrome Android不支持WebView Android未知Samsung Internet未知Opera Android未知

返回事件的 DataTransfer 对象。

尽管为了与其他事件接口保持一致,DragEvent 接口有一个构造函数,但它并不是特别有用。特别是,没有办法从脚本中创建有用的 DataTransfer 对象,因为 DataTransfer 对象在拖放过程中由浏览器协调处理和安全模型。

DragEvent 接口的 dataTransfer 属性必须返回它被初始化时的值。它表示事件的上下文信息。

当用户代理需要在某个元素上触发名为 e 的拖放事件(DND),使用特定的 拖放数据存储,并可选地带有特定的 related target,用户代理必须运行以下步骤:

  1. dataDragStoreWasChanged 为 false。
  2. 如果没有提供特定的 related target,将 related target 设置为 null。

  3. window 设置为指定目标元素的 文档 对象的相关全局对象。

  4. 如果 edragstart,则将 拖放数据存储模式 设置为 读/写模式,并将 dataDragStoreWasChanged 设置为 true。

    如果 edrop,将 拖放数据存储模式 设置为 只读模式

  5. dataTransfer 设置为一个新创建的 DataTransfer 对象,该对象与给定的 拖放数据存储 相关联。

  6. effectAllowed 属性设置为 拖放数据存储拖放数据存储允许的效果状态

  7. dropEffect 属性设置为 "none",如果 edragstartdragdragleave;如果 edropdragend,则将其设置为对应于当前拖动操作的值;否则根据 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"。

  8. event 设置为使用 DragEvent 创建事件的结果。

  9. 初始化 eventtype 属性为 ebubbles 属性为 true,view 属性为 windowrelatedTarget 属性为 related target,以及 dataTransfer 属性为 dataTransfer

  10. 如果 e 不是 dragleavedragend,则初始化 eventcancelable 属性为 true。

  11. 根据输入设备的状态初始化 event 的鼠标和键盘属性,就像它们是用户交互事件一样。

    如果没有相关的指点设备,则将 eventscreenXscreenYclientXclientYbutton 属性初始化为 0。

  12. 在指定目标元素上分派 event

  13. 拖放数据存储允许的效果状态 设置为 dataTransfereffectAllowed 属性的当前值。(它只能在 edragstart 时更改。)

  14. 如果 dataDragStoreWasChanged 为 true,则将 拖放数据存储模式 恢复为 保护模式

  15. 断开 dataTransfer拖放数据存储 的关联。

6.11.5 处理模型

当用户尝试开始拖动操作时,用户代理必须执行以下步骤。即使拖动实际上是从另一个文档或应用程序开始的,并且用户代理在拖动操作与其管理下的文档交互之前并不知道该拖动操作,用户代理也必须像执行了这些步骤一样行事。

  1. 确定正在拖动的内容,如下所示:

    如果拖动操作是在选择上调用的,那么正在拖动的是该选择。

    否则,如果拖动操作是在Document上调用的,则它是从用户尝试拖动的节点开始沿着祖先链向上的第一个具有IDL属性draggable设置为true的元素。如果没有这样的元素,那么没有任何内容被拖动;返回,拖放操作从未开始。

    否则,拖动操作是在用户代理的管理范围之外调用的。正在拖动的内容由开始拖动的文档或应用程序定义。

    img元素和具有href属性的a元素默认将其draggable属性设置为true。

  2. 创建一个拖放数据存储。本节中步骤随后触发的所有DND事件都必须使用此拖放数据存储

  3. 确定哪个DOM节点是源节点,如下所示:

    如果正在拖动的是选择,那么源节点是用户开始拖动的Text节点(通常是用户最初点击的Text节点)。如果用户没有指定特定节点,例如如果用户只是告诉用户代理开始拖动“选择”,那么源节点是包含部分选择的第一个Text节点。

    否则,如果正在拖动的是元素,那么源节点是正在拖动的元素。

    否则,源节点是另一个文档或应用程序的一部分。当本规范要求在这种情况下在源节点上调度事件时,用户代理必须遵循与该情况相关的平台特定约定。

    在拖放操作过程中,会在源节点上触发多个事件。

  4. 确定拖动节点列表,如下所示:

    如果正在拖动的是选择,那么拖动节点列表包含在树顺序中每个部分或完全包含在选择中的节点(包括其所有祖先)。

    否则,拖动节点列表仅包含源节点(如果有)。

  5. 如果正在拖动的是选择,则在拖放数据存储项目列表中添加一项,其属性设置如下:

    拖放数据项类型字符串
    "text/plain"
    拖放数据项种类
    文本
    实际数据
    选择的文本

    否则,如果正在拖动任何文件,则为每个文件在拖放数据存储项目列表中添加一项,其属性设置如下:

    拖放数据项类型字符串
    文件的MIME类型(如果已知),否则为"application/octet-stream"
    拖放数据项种类
    文件
    实际数据
    文件的内容和名称。

    目前只能从可导航外部拖动文件,例如从文件管理器应用程序。

    如果拖动是从应用程序外部开始的,用户代理必须根据正在拖动的数据适当地在拖放数据存储项目列表中添加项目,适当时遵守平台约定;但是,如果平台约定不使用 MIME类型标记拖动数据,则用户代理必须尽力尝试将类型映射到MIME类型,并且无论如何,所有拖放数据项类型字符串必须转换为ASCII小写

    用户代理还可以以其他形式(例如HTML)添加一个或多个代表选择或拖动元素的项目。

  6. 如果拖动节点列表不为空,则将这些节点中的微数据提取为JSON格式,并在拖放数据存储项目列表中添加一项,其属性设置如下:

    拖放数据项类型字符串
    application/microdata+json
    拖放数据项种类
    文本
    实际数据
    生成的JSON字符串。
  7. 运行以下子步骤:

    1. 设定urls为空列表。

    2. 对于拖动节点列表中的每个node

      如果节点是具有href属性的a元素
      根据元素的href内容属性的值,并相对于元素的节点文档,将编码解析和序列化的URL的结果添加到urls
      如果节点是具有src属性的img元素
      根据元素的src内容属性的值,并相对于元素的节点文档,将编码解析和序列化的URL的结果添加到urls
    3. 如果urls仍然为空,则返回。

    4. 设定url string为按添加顺序连接urls中的字符串,以U+000D CARRIAGE RETURN U+000A LINE FEED字符对(CRLF)分隔。

    5. 拖放数据存储项目列表中添加一项,其属性设置如下:

      拖放数据项类型字符串
      text/uri-list
      拖放数据项种类
      文本
      实际数据
      url string
  8. 根据用户代理的情况适当更新拖放数据存储默认反馈(如果用户正在拖动选择,那么选择可能是此反馈的基础;如果用户正在拖动元素,则使用该元素的渲染;如果拖动在用户代理外部开始,则使用平台约定确定拖动反馈)。

  9. 触发一个 DND 事件,名为dragstart, 在源节点上。

    如果事件被取消,则不应发生拖放操作;返回。

    由于没有注册事件监听器的事件几乎永远不会被取消,如果作者没有明确阻止,拖放操作对用户始终可用。

  10. 触发一个指针事件,在源节点上,名为pointercancel ,并按照Pointer Events的要求触发任何其他后续事件。[POINTEREVENTS]

  11. 以与平台约定一致的方式启动拖放操作,并如下所述

    拖放反馈必须从以下第一个可用来源生成:

    1. 拖放数据存储位图,如果有的话。在这种情况下,拖放数据存储热点坐标应作为将光标相对于生成的图像的位置提示。值表示从图像左侧和顶部的距离,单位为CSS像素[CSS]
    2. 拖放数据存储默认反馈

从用户代理要启动拖放操作的那一刻起,直到拖放操作结束,必须抑制设备输入事件(例如鼠标和键盘事件)。

在拖动操作期间,用户直接指示的元素称为即时用户选择。(只有元素可以被用户选择;其他节点不能作为拖放目标提供。)但是,即时用户选择不一定是当前目标元素,即当前选择用于拖放操作的元素。

即时用户选择会随着用户选择不同的元素而改变(通过指向设备指向它们,或通过其他方式选择它们)。当前目标元素会随着即时用户选择的改变而改变,基于文档中的事件监听器的结果,如下所述。

当前目标元素即时用户选择都可以为null,表示没有选择目标元素。它们也可以是其他(基于DOM的)文档或其他(非Web)程序中的元素。(例如,用户可以将文本拖动到文字处理器。)当前目标元素最初为null。

此外,还有当前拖动操作,它可以取值为"none","copy","link"和"move"。最初,其值为"none"。用户代理会根据以下步骤更新它。

从拖动操作启动的那一刻起,用户代理必须立即并且在拖动操作持续时间内每350ms(±200ms)排队执行任务,依次执行以下步骤:

  1. 如果用户代理在下一个迭代到期时仍在执行上一个迭代(如果有),则返回本次迭代(实际上是“跳过拖放操作的丢失帧”)。

  2. 触发一个DND事件,名为drag ,在源节点上。如果此事件被取消,用户代理必须将当前拖动操作设置为"none" (无拖动操作)。

  3. 如果drag事件未被取消且用户尚未结束拖放操作,请根据以下情况检查拖放操作的状态:

    1. 如果用户指示的即时用户选择与上一次迭代(或如果这是第一次迭代)不同,并且此即时用户选择当前目标元素不同,则按以下步骤更新当前目标元素

      如果新的即时用户选择为null

      当前目标元素也设置为null。

      如果新的即时用户选择在非DOM文档或应用程序中

      当前目标元素设置为即时用户选择

      否则

      触发一个DND事件,名为dragenter ,在即时用户选择上。

      如果事件被取消,则将当前目标元素设置为即时用户选择

      否则,运行以下列表中的相应步骤:

      如果即时用户选择是文本控制(例如,textarea,或input元素,其type属性处于文本状态)或编辑主机可编辑元素,并且拖放数据存储项目列表中有一个项,其拖放数据项类型字符串为"text/plain",且拖放数据项种类文本

      当前目标元素仍然设置为即时用户选择

      如果即时用户选择body元素

      保持当前目标元素不变。

      否则

      触发一个DND事件,名为dragenter ,在body元素上(如果有),或在Document 对象上(如果没有)。然后,将当前目标元素设置为body元素,无论该事件是否被取消。

    2. 如果前一步导致当前目标元素发生变化, 并且前一个目标元素不为null或不是非DOM文档的一部分,则在前一个目标元素上 触发一个名为 dragleave 的DND事件,并将新的当前目标元素作为特定的 related target

    3. 如果当前目标元素是一个DOM元素, 则在此当前目标元素触发一个名为 dragover 的DND事件。

      如果dragover事件未被取消,请运行以下列表中的适当步骤:

      如果当前目标元素是文本控制(例如,textarea,或input元素,其type属性处于文本状态)或编辑主机可编辑元素,并且拖放数据存储项目列表中有一个项,其拖放数据项类型字符串为"text/plain",且拖放数据项种类文本

      当前拖动操作设置为"copy"或"move",视平台约定而定。

      否则

      当前拖动操作重置为"none"。

      否则(如果dragover事件被取消),根据effectAlloweddropEffect属性的值设置当前拖动操作,如下表所示:

      effectAllowed dropEffect 拖动操作
      "uninitialized","copy","copyLink","copyMove",或"all" "copy" "copy"
      "uninitialized","link","copyLink","linkMove",或"all" "link" "link"
      "uninitialized","move","copyMove","linkMove",或"all" "move" "move"
      任何其他情况 "none"
    4. 否则,如果当前目标元素不是DOM元素,请使用平台特定机制确定正在执行的拖动操作(无、复制、链接或移动),并相应地设置当前拖动操作

    5. 更新拖动反馈(例如鼠标光标)以匹配当前拖动操作,如下所示:

      拖动操作 反馈
      "copy" 如果在此处释放,数据将被复制。
      "link" 如果在此处释放,数据将被链接。
      "move" 如果在此处释放,数据将被移动。
      "none" 不允许操作,在此处释放将取消拖放操作。
  4. 否则,如果用户结束了拖放操作(例如通过释放鼠标按钮在鼠标驱动的拖放界面中),或者drag事件被取消,则这将是最后一次迭代。运行以下步骤,然后停止拖放操作:

    1. 如果当前拖动操作是"none"(无拖动操作),或者如果用户通过取消操作结束了拖放操作(例如按下Escape键),或者当前目标元素为null,则拖动操作失败。运行以下子步骤:

      1. 设定dropped为false。

      2. 如果当前目标元素是一个DOM元素, 则触发一个名为 dragleave 的DND事件;否则,如果它不为空,则使用特定平台的拖动取消约定。

      3. 当前拖动操作设置为"none"。

      否则,拖动操作可能成功;运行以下子步骤:

      1. 设定dropped为true。

      2. 如果当前目标元素是DOM元素, 则在其上触发一个名为 drop 的DND事件;否则,使用平台特定的约定来指示放置。

      3. 如果事件被取消,将当前拖动操作设置为 dropEffect 属性的值,该属性属于 DragEvent 对象的 dataTransfer 对象,以上状态在事件调度完成后确定。

        否则,事件未被取消;执行事件的默认操作,具体取决于目标如下:

        如果当前目标元素是文本控制(例如,textarea,或input元素,其type属性处于文本状态)或编辑主机可编辑元素,并且拖放数据存储项目列表中有一个项,其拖放数据项类型字符串为"text/plain",且拖放数据项种类文本

        拖放数据存储项目列表中第一个具有text/plain类型字符串和文本种类的实际数据插入到文本控制、 编辑主机可编辑元素中,方式与平台特定约定一致(例如在当前鼠标光标位置插入,或在字段末尾插入)。

        否则

        当前拖动操作重置为"none"。

    2. 触发一个DND事件,命名为dragend源节点上。

    3. 运行以下列表中的适当步骤作为dragend事件的默认操作:

      如果dropped为true,当前目标元素文本控制(见下文),当前拖动操作为"move",并且拖放操作的源是完全包含在编辑主机内的DOM选择

      删除选择

      如果dropped为true,当前目标元素文本控制(见下文),当前拖动操作为"move",并且拖放操作的源是文本控制中的选择

      用户代理应从相关文本控制中删除拖动选择。

      如果dropped为false或当前拖动操作为"none"

      拖动被取消。如果平台约定规定这需要向用户表示(例如通过动画将拖动选择返回到拖放操作的源),则这样做。

      否则

      事件没有默认操作。

      为了本步骤的目的,文本控制textarea元素或input元素,其type属性处于文本搜索电话URL电子邮件密码数字状态。

鼓励用户代理考虑如何响应靠近可滚动区域边缘的拖动。例如,如果用户将链接拖动到长页面的视口底部,可能需要滚动页面,以便用户可以将链接放到页面更低的位置。

此模型与涉及的节点来自哪个Document对象无关;事件按上述描述触发,其余处理模型按上述描述运行,无论操作涉及多少文档。

6.11.6 事件总结

本节为非规范性内容。

以下事件涉及拖放模型。

事件名称 目标 是否可取消? 拖放数据存储模式 dropEffect 默认操作
dragstart

HTMLElement/dragstart_event

在所有当前引擎中支持。

Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
源节点 ✓ 可取消 读/写模式 "none" 启动拖放操作
drag

HTMLElement/drag_event

在所有当前引擎中支持。

Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
源节点 ✓ 可取消 保护模式 "none" 继续拖放操作
dragenter

HTMLElement/dragenter_event

在所有当前引擎中支持。

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

HTMLElement/dragleave_event

在所有当前引擎中支持。

Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
上一个目标元素 保护模式 "none"
dragover

HTMLElement/dragover_event

在所有当前引擎中支持。

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

HTMLElement/drop_event

在所有当前引擎中支持。

Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
当前目标元素 ✓ 可取消 只读模式 当前拖放操作 视情况而定
dragend

HTMLElement/dragend_event

在所有当前引擎中支持。

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"。

6.11.7 draggable属性

Global_attributes/draggable

在所有当前引擎中支持。

Firefox2+Safari5+Chrome4+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

所有HTML元素都可以设置draggable内容属性。draggable属性是一个枚举属性,具有以下关键字和状态:

关键字 状态 简要描述
true true 元素将是可拖动的。
false false 元素将不可拖动。

属性的缺省值无效值默认都是auto状态。auto状态使用用户代理的默认行为。

具有draggable属性的元素应当也具有title属性,以便于非视觉交互时命名元素。

element.draggable [ = value ]

如果元素是可拖动的,返回true;否则,返回false。

可以设置,以覆盖默认值并设置draggable内容属性。

draggableIDL属性,其值取决于以下描述的内容属性,控制元素是否可拖动。一般来说,只有文本选择是可拖动的,但draggableIDL属性为true的元素也会变得可拖动。

如果一个元素的draggable内容属性的状态是true,则draggableIDL属性必须返回true。

否则,如果元素的draggable内容属性的状态是false,则draggableIDL属性必须返回false。

否则,元素的draggable内容属性的状态是auto。如果该元素是img元素、object元素(表示图像),或具有href内容属性的a元素,draggableIDL属性必须返回true;否则,draggableIDL属性必须返回false。

如果draggableIDL属性设置为false,draggable内容属性必须设置为字面值"false"。如果draggableIDL属性设置为true,draggable内容属性必须设置为字面值"true"。

6.11.8 拖放模型中的安全风险

用户代理不得在DataTransfer对象在dragstart事件期间添加的数据在drop事件之前提供给脚本,否则,如果用户将敏感信息从一个文档拖动到第二个文档,过程中经过一个恶意第三文档,恶意文档可能会拦截数据。

出于同样的原因,用户代理必须认为只有用户明确结束拖动操作时才算成功——如果任何脚本结束拖动操作,必须被认为是不成功的(取消),并且drop事件不得触发。

用户代理应注意不要响应脚本操作启动拖放操作。例如,在鼠标和窗口环境中,如果脚本在用户按下鼠标按钮时移动窗口,用户代理不会认为这是启动拖动操作。这很重要,因为否则用户代理可能会在未经用户同意的情况下将数据从敏感来源拖动到恶意文档中。

用户代理应在拖动和放置时过滤潜在的活动(脚本)内容(例如HTML),使用已知安全功能的白名单。同样,相对URL应转换为绝对URL,以避免引用发生意外变化。本规范未规定如何执行此操作。

考虑一个恶意页面提供一些内容并让用户选择和拖放(或复制和粘贴)该内容到受害页面的contenteditable区域。如果浏览器不确保仅拖动安全内容,选择中的潜在不安全内容(如脚本和事件处理程序),一旦放置(或粘贴)到受害站点,便会获得受害站点的权限。这将使跨站脚本攻击成为可能。

6.12 popover 属性

Global_attributes/popover

支持所有当前引擎。

Firefox🔰 114+Safaripreview+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

所有 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 不关闭其他弹出框;不轻解散或响应关闭请求

该属性的缺省值无弹出框状态,其无效值默认手动状态。

HTMLElement/popover

支持所有当前引擎。

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
旧版Edge?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

popover IDL属性必须反映popover属性,仅限于已知值

每个HTML元素都有一个弹出框可见状态,初始为隐藏,具有以下潜在值:

Document有一个弹出框指针按下目标,这是一个HTML元素或null,初始为null。

每个HTML元素都有一个弹出框调用器,这是一个HTML元素或null,初始设置为null。

每个HTML元素都有一个弹出框显示或隐藏,这是一个布尔值,初始设置为false。

每个HTML元素有一个弹出框切换任务跟踪器,这是一个切换任务跟踪器或null,初始为null。

每个HTML元素有一个弹出框关闭监视器,这是一个关闭监视器或null,初始为null。

以下属性变化步骤,给定elementlocalNameoldValuevalue,和namespace,适用于所有HTML元素

  1. 如果namespace不为null,则返回。

  2. 如果localName不是popover,则返回。

  3. 如果element弹出框可见状态处于显示状态oldValuevalue处于不同的状态,则运行隐藏弹出框算法,给定element,true,true,和false。

element.showPopover()
通过将element添加到顶层来显示弹出框。如果elementpopover属性处于自动状态,则这也会关闭所有其他自动弹出框,除非它们是根据顶层弹出框祖先算法的element的祖先。
element.hidePopover()
通过将其从顶层移除并应用display: none来隐藏弹出框element
element.togglePopover()
如果弹出框element未显示,则此方法显示它。否则,此方法隐藏它。调用此方法后,如果弹出框打开则返回true,否则返回false。

HTMLElement/showPopover

支持所有当前引擎。

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
旧版Edge?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

showPopover()方法步骤是运行显示弹出框,给定this,true和null。

显示弹出框,给定一个HTML元素element,一个布尔值throwExceptions,以及一个HTML元素或nullinvoker

  1. 如果运行检查弹出框有效性,给定element,false,throwExceptions,和null的结果为false,则返回。

  2. document成为element节点文档

  3. 断言element弹出框调用器为null。

  4. 断言element不在document顶层中。

  5. nestedShow成为element弹出框显示或隐藏

  6. 设置element弹出框显示或隐藏为true。

  7. cleanupShowingFlag成为以下步骤:

    1. 如果nestedShow为false,则将element弹出框显示或隐藏设置为false。

  8. 如果触发名为beforetoggle的事件的结果,使用ToggleEvent,并将可取消属性初始化为true,将oldState属性初始化为"closed",并将newState属性初始化为"open"在element上为false,则运行cleanupShowingFlag并返回。

  9. 如果运行检查弹出框有效性,给定element,false,throwExceptions,和document的结果为false,则运行cleanupShowingFlag并返回。

    检查弹出框有效性再次被调用,因为触发beforetoggle事件可能会断开此元素或更改其popover属性。

  10. shouldRestoreFocus为false。

  11. 如果elementpopover属性处于自动状态,则:

    1. originalType成为elementpopover属性的值。

    2. ancestor成为运行顶层弹出框祖先算法,给定elementinvoker,和true的结果。

    3. 如果ancestor为null,则将ancestor设置为document

    4. 运行隐藏所有弹出框直到,给定ancestor,false,和非nestedShow

    5. 如果originalType不等于elementpopover属性的值,则:

      1. 如果throwExceptions为true,则抛出一个"InvalidStateError" DOMException

      2. 返回。

    6. 如果运行检查弹出框有效性,给定element,false,throwExceptions,和document的结果为false,则运行cleanupShowingFlag并返回。

      检查弹出框有效性再次被调用,因为运行隐藏所有弹出框直到以上可能触发beforetoggle事件,并且事件处理程序可能会断开此元素或更改其popover属性。

    7. 如果运行顶层自动弹出框document上的结果为null,则将shouldRestoreFocus设置为true。

      这确保了焦点仅返回到堆栈中的第一个弹出框之前的聚焦元素。

    8. element弹出框关闭监视器设置为运行建立关闭监视器的结果,给定element相关全局对象,其中:

  12. element之前聚焦的元素设置为null。

  13. originallyFocusedElement成为document文档的聚焦区域DOM锚点

  14. 将元素添加到顶层,给定element

  15. element弹出框可见状态设置为显示

  16. element弹出框调用器设置为invoker

  17. 运行弹出框聚焦步骤,给定element

  18. 如果shouldRestoreFocus为true并且elementpopover属性不在无弹出框状态,则将element之前聚焦的元素设置为originallyFocusedElement

  19. 排队一个弹出框切换事件任务,给定element,"closed",和"open"。

  20. 运行cleanupShowingFlag

排队一个弹出框切换事件任务,给定一个元素element,一个字符串oldState,和一个字符串newState

  1. 如果element弹出框切换任务跟踪器不为null,则:

    1. oldState设置为element弹出框切换任务跟踪器旧状态

    2. 从其任务队列中移除element弹出框切换任务跟踪器任务

    3. element弹出框切换任务跟踪器设置为null。

  2. 排队一个元素任务,给定DOM操作任务源element,运行以下步骤:

    1. 触发一个名为toggle的事件在element上,使用ToggleEvent,并将oldState属性初始化为oldStatenewState属性初始化为newState

    2. element弹出框切换任务跟踪器设置为null。

  3. element弹出框切换任务跟踪器设置为一个包含刚排队的任务的结构,和旧状态设置为oldState

HTMLElement/hidePopover

在所有当前引擎中支持。

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

hidePopover() 方法步骤如下:

  1. 运行隐藏弹出框算法,给定this, true,true,以及 true。

隐藏弹出框,给定一个HTML元素 element,一个布尔值focusPreviousElement,一个 布尔值fireEvents,以及一个布尔值throwExceptions

  1. 如果运行检查弹出框有效性,给定element, true,throwExceptions,和null的结果为false,则返回。

  2. document成为element节点文档

  3. nestedHide成为element弹出框显示或隐藏

  4. element弹出框显示或隐藏设置为true。

  5. 如果nestedHide为true,则将fireEvents设置为false。

  6. cleanupSteps为以下步骤:

    1. 如果nestedHide为false,则将element弹出框显示 或隐藏设置为false。

    2. 如果element弹出框关闭监视器不为null,则:

      1. 销毁element弹出框 关闭监视器

      2. element弹出框关闭监视器设置为null。

  7. 如果elementpopover 属性处于自动状态,则:

    1. 运行隐藏所有弹出框直到,给定 elementfocusPreviousElement,以及fireEvents

    2. 如果运行检查弹出框有效性,给定 element, true,和throwExceptions的结果为false,则运行cleanupSteps并 返回。

      检查弹出框有效性再次被调用,因为 运行隐藏所有弹出框直到可能已断开 element或更改其popover 属性。

  8. autoPopoverListContainsElement为true,如果document显示 自动弹出 框列表的最后一个项目是element,否则 为false。

  9. element弹出框调用器设置为null。

  10. 如果fireEvents为true:

    1. 触发一个名为beforetoggle 的事件,使用ToggleEvent, 并初始化oldState 属性为"open",newState 属性为"closed",在element上。

    2. 如果autoPopoverListContainsElement为true并且document显示 自动弹出框列表的最后一个项目不是 element,则运行隐藏所有弹出框直到,给定 elementfocusPreviousElement,以及false。

    3. 如果运行检查弹出框有效性,给定 element, true,throwExceptions,以及null的结果为false,则运行cleanupSteps并 返回。

      检查弹出框有效性再次被调用, 因为 触发beforetoggle 事件可能已断开 element或更改其popover 属性。

    4. 请求从顶层移除元素,给定 element

  11. 否则,立即从顶层移除元素,给定 element

  12. element弹出框可见状态设置为隐藏

  13. 如果fireEvents为true,则排队一个弹出框切换事件任务, 给定element,"open",和"closed"。

  14. previouslyFocusedElement成为element之前聚焦的 元素

  15. 如果previouslyFocusedElement不为null,则:

    1. element之前聚焦的元素设置为null。

    2. 如果focusPreviousElement为true,并且document文档的聚焦区域DOM锚点element阴影包含的包容性后代,则运行聚焦步骤,给定 previouslyFocusedElement;在执行此步骤时,视口不应滚动。

  16. 运行cleanupSteps

HTMLElement/togglePopover

在所有当前引擎中支持。

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

togglePopover(force) 方法步骤如下:

  1. 如果this弹出框可见状态显示,并且force未出现或 为false, 则 运行隐藏弹出框算法,给定this, true,true,和 true。

  2. 否则,如果force未出现或为true,则运行显示弹出框, 给定this,true,和null。

  3. 否则:

    1. expectedToBeShowing为true,如果this弹出框 可见状态显示;否则 为false。

    2. 运行检查弹出框有效性,给定 expectedToBeShowing,true,和 null。

  4. 如果this弹出框可见状态显示,则返回true;否则返回false。

隐藏所有弹出框直到,给定一个HTML元素文档 endpoint,一个布尔值 focusPreviousElement,以及一个布尔值fireEvents

  1. 如果endpoint是一个HTML元素并且 endpoint不在弹出框显示 状态中,则返回。

  2. document成为endpoint节点文档

  3. closeAllOpenPopovers成为一个执行以下步骤的算法:

    1. popover成为document最上层自动弹出框

    2. popover不为null时:

      1. 运行隐藏弹出框算法,给定 popoverfocusPreviousElementfireEvents,以及false。

      2. popover设置为document最上层自动弹出框

  4. 如果endpoint是一个文档, 则运行 closeAllOpenPopovers并返回。

  5. 断言endpointpopover 属性处于自动状态。

  6. repeatingHide为false。

  7. 至少执行一次以下步骤:

    1. lastToHide为null。

    2. foundEndpoint为false。

    3. 对于document的每个popover显示自动弹出框列表

      1. 如果popoverendpoint ,则将foundEndpoint设置为 true。

      2. 否则,如果foundEndpoint为true,则将lastToHide设置为 popover打破

    4. 如果foundEndpoint为false,则运行closeAllOpenPopovers并 返回。

    5. lastToHide不为null且lastToHide弹出框 可见状态显示document显示自动弹出框列表不为空时:

      1. 运行隐藏弹出框算法,给定 document显示 自动弹出框列表的最后一个元素,focusPreviousElementfireEvents,以及false。

    6. repeatingHide设置为true,如果document显示 自动弹出框 列表包含endpointdocument显示 自动弹出框 列表的最后一个元素不是endpoint,否则为false。

    7. 如果repeatingHide为true,则将fireEvents设置为false。

    并且保持执行它们直到 repeatingHide为true。

隐藏所有弹出框直到 算法在几种情况下被使用,以隐藏所有在发生某些事情时不保持打开的弹出框。例如,在轻解散弹出框期间,此算法确保我们仅关闭与用户单击的节点无关的弹出框。

要找到最上层弹出框祖先,给定一个节点 newPopoverOrTopLayerElement,一个HTML元素或 null invoker,以及一个布尔值isPopover,执行以下步骤。它们返回一个HTML 元素或null。

最上层弹出框祖先算法将返回提供的弹出框或顶层 元素的最上层(在 显示 自动弹出框列表中最新的) 祖先弹出框。弹出框可以通过多种方式相互关联,形成弹出框树。存在两条路径,通过这些路径一个弹出框(称为“子”弹出框)可以有一个最上层的祖先弹出框(称为“父”弹出框):

  1. 弹出框在节点树中彼此嵌套。在这种情况下,后代弹出框是“子”,其最上层的祖先弹出框是“父”。

  2. 调用元素(例如按钮) 具有指向弹出框的popovertarget 属性。在这种情况下, 弹出框是“子”,而调用元素所在的弹出框子树是“父”。调用者必须在弹出框中,并引用一个打开的弹出框。

在上述每个关系中,父弹出框必须严格早于 显示自动 弹出框列表中的子弹出框,否则它不会形成有效的祖先关系。这消除了非显示弹出框和自指(例如包含一个指向自身的调用元素的弹出框),并允许从连接的(可能是循环的)图构建一个格式良好的树。只有自动弹出框被考虑。

如果提供的元素是一个顶层元素,例如一个对话框 并且没有 作为弹出框显示,那么最上层弹出框祖先只会在节点树中查找第一个弹出框。

  1. 如果isPopover为true:

    1. 断言newPopoverOrTopLayerElement是一个HTML 元素

    2. 断言newPopoverOrTopLayerElementpopover 属性不在 无弹出框状态手动状态中。

    3. 断言newPopoverOrTopLayerElement弹出框可见 状态不在显示状态中。

  2. 否则:

    1. 断言invoker为null。

  3. popoverPositions成为一个空的有序映射

  4. index为0。

  5. document成为newPopoverOrTopLayerElement节点文档

  6. 对于document的每个popover显示自动弹出框列表

    1. 设置popoverPositions[popover]为 index

    2. index增加1。

  7. 如果isPopover为true,则设置 popoverPositions[newPopoverOrTopLayerElement]为index

  8. index增加1。

  9. topmostPopoverAncestor为null。

  10. checkAncestor成为一个给定candidate执行以下步骤的算法:

    1. 如果candidate为null,则返回。

    2. candidateAncestor成为运行最近包含的打开弹出框的结果,给定 candidate

    3. 如果candidateAncestor为null,则返回。

    4. candidatePosition成为 popoverPositions[candidateAncestor]。

    5. 如果topmostPopoverAncestor为null或 popoverPositions[topmostPopoverAncestor]小于 candidatePosition,则将topmostPopoverAncestor设置为 candidateAncestor

  11. 运行checkAncestor,给定newPopoverOrTopLayerElement平坦树中的父节点。

  12. 运行checkAncestor,给定invoker

  13. 返回topmostPopoverAncestor

要找到最近包含的打开弹出框,给定一个节点 node,执行以下步骤。它们返回一个HTML 元素或null。

  1. currentNode成为node

  2. currentNode不为null时:

    1. 如果currentNodepopover 属性处于 自动状态,并且currentNode弹出框可见状态显示, 则返回currentNode

    2. currentNode设置为currentNode平坦树中的父节点。

  3. 返回null。

找到最上层自动弹出框,给定一个 文档 document,执行以下步骤。它们返回一个HTML元素或 null。

  1. 如果document显示自动弹出框列表不为空,则返回 document显示自动弹出框列表的最后一个元素。

  2. 返回null。

要执行弹出框聚焦步骤,给定一个HTML 元素subject

  1. 如果subject对话框 元素,则运行对话框聚焦 步骤,给定subject并返回。

  2. 如果subject具有自动聚焦 属性,则让control成为subject

  3. 否则,让control成为自动聚焦委托, 给定subject为"other"。

  4. 如果control为null,则返回。

  5. 运行聚焦 步骤,给定control

  6. topDocument成为control活动文档,属于control节点文档浏览上下文顶级浏览上下文

  7. 如果control节点 文档来源不 是 相同topDocument来源, 则 返回。

  8. 清空topDocument自动聚焦候选者

  9. topDocument自动聚焦处理标志设置为true。

检查弹出框有效性,对于一个HTML元素 element,给定一个布尔值expectedToBeShowing,一个布尔值 throwExceptions,以及一个文档或null expectedDocument 执行以下步骤。它们抛出异常或返回一个布尔值。

  1. 如果elementpopover 属性处于 无弹出框状态,则:

    1. 如果throwExceptions为true,则抛出一个 "NotSupportedError" DOMException

    2. 返回false。

  2. 如果以下任意一项为真:

    则返回false。

  3. 如果以下任意一项为真:

    则:

    1. 如果throwExceptions为true,则抛出一个 "InvalidStateError" DOMException

    2. 返回false。

  4. 返回true。

要获取显示自动弹出框列表,对于一个 文档 document

  1. popovers为« »。

  2. 对于每个元素 element,在 document顶层: 如果elementpopover 属性处于自动状态并且element弹出框 可见状态显示,则追加elementpopovers

  3. 返回popovers

6.12.1 Popover 目标属性

按钮 可能具有以下内容属性:

如果指定,popovertarget 属性值必须是具有popover 属性的元素的ID,且在与具有popovertarget属性的按钮 相同的中。

popovertargetaction 属性是一个 枚举属性,具有以下关键字和状态:

关键字 状态 简要描述
toggle toggle 显示或隐藏目标弹出框元素。
show show 显示目标弹出框元素。
hide hide 隐藏目标弹出框元素。

属性的缺失值默认值无效值默认值都是toggle状态。

尽可能确保弹出框元素紧跟在其触发元素之后放置在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>
DOM 接口
interface mixin PopoverInvokerElement {
  [CEReactions] attribute Element? popoverTargetElement;
  [CEReactions] attribute DOMString popoverTargetAction;
};

HTMLButtonElement/popoverTargetElement

支持所有当前引擎。

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLInputElement/popoverTargetElement

支持所有当前引擎。

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

popoverTargetElement IDL 属性必须 反映 popovertarget 属性。

HTMLButtonElement/popoverTargetAction

支持所有当前引擎。

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HTMLInputElement/popoverTargetAction

支持所有当前引擎。

Firefox🔰 114+Safari17+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

popoverTargetAction IDL 属性必须 反映 popovertargetaction 属性,仅限于已知值

要运行给定 Node node弹出窗口目标属性激活行为

  1. popover 成为 node弹出窗口目标元素

  2. 如果 popover 为 null,则返回。

  3. 如果 nodepopovertargetaction 属性在 显示 状态且 popover弹出窗口可见状态显示,则返回。

  4. 如果 nodepopovertargetaction 属性在 隐藏 状态且 popover弹出窗口可见状态隐藏,则返回。

  5. 如果 popover弹出窗口可见状态显示,则运行给定 popover、 true、true 和 false 的 隐藏弹出窗口算法

  6. 否则,如果 popover弹出窗口可见状态隐藏,且运行给定 popover、 false、false 和 null 的 检查弹出窗口有效性 的结果为 true, 则运行给定 popover、false 和 node显示弹出窗口

要获取给定 Node node弹出窗口目标元素,执行以下步骤。 它们返回一个 HTML 元素 或 null。

  1. 如果 node 不是一个 按钮,则返回 null。

  2. 如果 node禁用的,则返回 null。

  3. 如果 node 有一个 表单所有者,且 node 是一个 提交按钮,则返回 null。

  4. popoverElement 成为运行 node获取 popovertarget 关联的元素 的结果。

  5. 如果 popoverElement 为 null,则返回 null。

  6. 如果 popoverElementpopover 属性在 无弹出窗口 状态,则返回 null。

  7. 返回 popoverElement

6.12.2 Popover 轻量关闭

“轻量关闭”意味着点击弹出窗口外部,且该弹出窗口的 popover 属性处于 auto 状态,将关闭该弹出窗口。这是除了这种弹出窗口响应关闭请求的方式之外的另一种方式。

轻量关闭打开的弹出窗口,给定一个 事件 event

  1. 断言eventisTrusted 属性为 true。

  2. target 成为 event目标

  3. document 成为 target节点文档

  4. topmostPopover 成为运行 最上层自动弹出窗口 给定 document 的结果。

  5. 如果 topmostPopover 为 null,则返回。

  6. 如果 event 是一个 指针事件eventtype 是 "pointerdown", 则:将 document弹出窗口pointerdown目标 设置为运行 最上层点击的弹出窗口 给定 target 的结果。

  7. 如果 event 是一个 指针事件eventtype 是 "pointerup", 则:

    1. ancestor 成为运行 最上层点击的弹出窗口 给定 target 的结果。

    2. 如果 ancestordocument弹出窗口pointerdown目标, 则将 sameTarget 设为 true。

    3. document弹出窗口pointerdown目标 设置为 null。

    4. 如果 ancestor 为 null,则将 ancestor 设置为 document

    5. 如果 sameTarget 为 true,则运行 隐藏所有弹出窗口直到 给定 ancestor,false 和 true。

轻量关闭打开的弹出窗口 将由 指针事件规范调用,当用户在页面上点击或触摸任何地方时。

要找到 最上层点击的弹出窗口,给定一个 节点 node

  1. clickedPopover 成为运行 最近的包含打开的弹出窗口 给定 node 的结果。

  2. invokerPopover 成为运行 最近的包含的目标弹出窗口 给定 node 的结果。

  3. getStackPosition 成为一个算法,给定一个 HTML 元素 popover,执行以下步骤:

    1. popoverList 成为 popover节点文档显示的自动弹出窗口列表

    2. 如果 popoverpopoverList 中,则返回 popoverListpopover 的索引 + 1。

    3. 返回 0。

  4. 如果运行 getStackPosition 给定 clickedPopover 的结果 大于运行 getStackPosition 给定 invokerPopover 的结果, 则返回 clickedPopover

  5. 返回 invokerPopover

要找到 最近的包含的目标弹出窗口 给定一个 节点 node

  1. currentNode 成为 node

  2. currentNode 不为 null 时:

    1. targetPopover 成为 currentNode弹出窗口目标元素

    2. 如果 targetPopover 不为 null 且 targetPopoverpopover 属性处于 auto 状态且 targetPopover弹出窗口可见性状态显示, 则返回 targetPopover

    3. currentNode 设置为 currentNode平面树 中的祖先节点。

7 加载网页

本节描述的功能最直接适用于网页浏览器。不过,除非另有规定,本节定义的要求确实适用于所有用户代理,无论它们是否为网页浏览器。

7.1 支持的概念

7.1.1 来源

来源是网络安全模型的基本单位。网络平台中共享来源的两个行为体被认为彼此信任并具有相同的权威。具有不同来源的行为体被认为可能是敌对的,并且在不同程度上彼此隔离。

例如,如果Example Bank的网站,托管于bank.example.com,尝试检查Example Charity的网站,托管于charity.example.org的DOM,则会引发"SecurityError"DOMException


一个来源是以下之一:

不透明来源

一个内部值,没有可以从中重建的序列化(根据来源的序列化,它被序列化为"null"),唯一有意义的操作是测试相等性。

元组来源

一个元组包括:

来源可以共享,例如在多个文档对象之间。此外,来源通常是不可变的。只有元组来源可以更改,并且只能通过document.domain API更改。

一个有效域origin是按以下步骤计算的:

  1. 如果origin不透明来源,则返回null。

  2. 如果origin不为空,则返回origin

  3. 返回origin主机

来源的序列化是通过将以下算法应用于给定的origin获得的字符串:

  1. 如果origin不透明来源,则返回"null"。

  2. 否则,将origin方案赋值给result

  3. result后添加"://"。

  4. result后添加origin主机序列化

  5. 如果origin端口不为空,在result后添加一个U+003A冒号字符(:)和origin端口序列化

  6. 返回result

("https", "xn--maraa-rta.example", null, null)的序列化结果是"https://xn--maraa-rta.example"。

以前还存在来源的Unicode序列化。然而,它从未被广泛采用。


两个来源AB,如果以下算法返回true,则称为同源

  1. 如果AB是相同的不透明来源,则返回true。

  2. 如果AB都是元组来源,并且它们的方案主机端口相同,则返回true。

  3. 返回false。

两个来源AB,如果以下算法返回true,则称为同源域

  1. 如果AB是相同的不透明来源,则返回true。

  2. 如果AB都是元组来源

    1. 如果AB方案相同,并且它们的相同且不为空,则返回true。

    2. 否则,如果AB同源,并且它们的均为空,则返回true。

  3. 返回false。

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")
7.1.1.1 站点

scheme-and-host是一个元组,包含一个方案(一个ASCII字符串)和一个主机(一个主机)。

站点是一个不透明来源或一个scheme-and-host

获取站点,给定一个来源origin,请执行以下步骤:

  1. 如果origin不透明来源,则返回origin

  2. 如果origin主机可注册域为空,则返回(origin方案, origin主机)。

  3. 返回(origin方案, origin主机可注册域)。

如果以下算法返回true,则两个站点AB,称为相同站点

  1. 如果AB是相同的不透明来源,则返回true。

  2. 如果AB不透明来源,则返回false。

  3. 如果AB方案值不同,则返回false。

  4. 如果AB主机值不相等,则返回false。

  5. 返回true。

站点的序列化是通过将以下算法应用于给定的站点site获得的字符串:

  1. 如果site不透明来源,则返回"null"。

  2. site[0]赋值给result

  3. result后添加"://"。

  4. result后添加site[1],序列化

  5. 返回result

必须从上下文中清楚地知道序列化值是站点,而不是来源,因为两者之间不一定有语法上的区别。例如,来源("https", "shop.example", null, null)和站点("https", "shop.example")具有相同的序列化:" https://shop.example"。

如果以下算法返回true,则两个来源AB称为无方案相同站点

  1. 如果AB是相同的不透明来源,则返回true。

  2. 如果AB都是元组来源,则:

    1. A主机赋值给hostA,将B主机赋值给hostB

    2. 如果hostA等于hostB,并且hostA可注册域为空,则返回true。

    3. 如果hostA可注册域等于hostB可注册域,并且非空,则返回true。

  3. 返回false。

如果以下算法返回true,则两个来源AB称为相同站点

  1. 将给定A的结果获取站点赋值给siteA

  2. 将给定B的结果获取站点赋值给siteB

  3. 如果siteAsiteB相同站点,则返回true。

  4. 返回false。

同源同源域概念不同,对于无方案相同站点相同站点,忽略端口组件。

由于在URL中解释的原因,应尽可能避免使用相同站点无方案相同站点概念,最好使用同源检查。

鉴于wildlife.museummuseumcom公共后缀,而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.")

(这里我们省略了端口组件,因为它们不被考虑。)

7.1.1.2 放宽同源限制
document.domain [ = domain ]

返回用于安全检查的当前域。

可以设置为一个去除子域的值,以改变来源,以允许相同域的其他子域页面(如果它们也这样做)相互访问。这使得同一域不同主机上的页面可以同步访问彼此的DOM。

在沙盒化的iframe中,具有不透明来源Document,以及没有浏览上下文Document,设置器会抛出"SecurityError"异常。如果crossOriginIsolatedoriginAgentCluster返回true,设置器将不起作用。

避免使用document.domain设置器。它削弱了同源政策提供的安全保护。当使用共享主机时,这尤其严重;例如,如果一个不受信任的第三方能够在同一IP地址但不同端口上托管一个HTTP服务器,那么在使用document.domain设置器后,同一个主机上两个不同站点的正常同源保护将失效,因为在比较来源时端口将被忽略。

由于这些安全陷阱,此功能正在从Web平台中逐步移除。(这是一个需要多年完成的漫长过程。)

相反,请使用postMessage()MessageChannel对象,以安全的方式跨来源通信。

domain取值器步骤如下:

  1. effectiveDomain此对象来源有效域

  2. 如果effectiveDomain为空,则返回空字符串。

  3. 返回effectiveDomain序列化

domain设置器步骤如下:

  1. 如果此对象浏览上下文为空,则抛出"SecurityError"DOMException

  2. 如果此对象活动沙盒标志集中设置了沙盒document.domain浏览上下文标志,则抛出"SecurityError"DOMException

  3. effectiveDomain此对象来源有效域

  4. 如果effectiveDomain为空,则抛出"SecurityError"DOMException

  5. 如果给定的值不是 effectiveDomain的可注册域后缀并且不等于effectiveDomain,则抛出"SecurityError"DOMException

  6. 如果周围代理代理集群是否以来源为键为真,则返回。

  7. this来源设置为解析给定值的结果。

要确定hostSuffixString 是否是 originalHost的可注册域后缀或是否等于它:

  1. 如果hostSuffixString为空字符串,则返回false。

  2. hostSuffix解析hostSuffixString的结果。

  3. 如果hostSuffix失败,则返回false。

  4. 如果hostSuffix等于 originalHost,则:

    1. 如果hostSuffixoriginalHost不是,则返回false。

      这排除了作为主机IP地址

    2. 如果hostSuffix前缀为U+002E(.)不匹配originalHost的末尾,则返回false。

    3. 如果以下任一条件为真:

      则返回false。[URL]

    4. 断言originalHost公共后缀前缀为U+002E(.)匹配hostSuffix的末尾。

  5. 返回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是一个可注册域。

7.1.2 基于源的代理集群

window.originAgentCluster

如果此Window属于一个按照本节描述的方式基于源的代理集群,则返回true。

通过安全上下文传递的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` 头可能对实现资源分配提供额外 的提示,因为用于实现跨源隔离的 `跨源打开者策略` 和 `跨源嵌入者策略` 头更多的是确保同一地址空间中的所有内容都选择进入。但是,添加它不会对作者代码产生额外的可观察效果。

7.1.3 跨源打开者策略

一个跨源打开者策略值允许在顶级浏览上下文中导航到的文档强制创建一个新的顶级浏览上下文及其对应的。可能的值是:

"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` 头,其值与跨源隔离兼容

一个跨源打开者策略由以下内容组成:

匹配跨源打开者策略值,给定一个跨源打开者策略值 A,一个 originA,一个跨源打开者策略值 B,以及一个 originB,按以下步骤操作:

  1. 如果 A 是 "unsafe-none" 且 B 也是 "unsafe-none",则返回true。

  2. 如果 A 是 "unsafe-none" 或 B 是 "unsafe-none",则返回false。

  3. 如果 ABoriginAoriginB同源,则返回true。

  4. 返回false。

7.1.3.1 头部信息

Headers/Cross-Origin-Opener-Policy

支持所有当前引擎。

Firefox79+Safari15.2+Chrome83+
OperaNoEdge83+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView AndroidNoSamsung Internet?Opera AndroidNo

一个文档打开者策略源自于 `Cross-Origin-Opener-Policy` 和 `Cross-Origin-Opener-Policy-Report-Only` HTTP 响应头。这些头部是结构化头部,其值必须是标记[STRUCTURED-FIELDS]

有效的标记值是打开者策略值。标记还可以附加参数;其中,"report-to" 参数可以有一个有效的 URL 字符串,用于标识适当的报告端点。[REPORTING]

根据下面描述的处理模型,如果此头部包含无效值,用户代理将忽略此头部。同样,如果该值无法解析为标记,用户代理也将忽略此头部。


要在给定一个响应 response 和一个环境 reservedEnvironment 的情况下获取跨源打开者策略,请按以下步骤操作:

  1. policy 成为一个新的跨源打开者策略

  2. 如果 reservedEnvironment 是一个非安全上下文,则返回 policy

  3. parsedItem 成为获取结构化字段值的结果,给定 `Cross-Origin-Opener-Policy` 和 "item" 从 response头部列表

  4. 如果 parsedItem 不为 null,则:

    1. 如果 parsedItem[0] 是 "same-origin",则:

      1. coep 成为获取跨源嵌入者策略的结果,来自 responsereservedEnvironment

      2. 如果 coep跨源隔离兼容,则将 policy设置为 "same-origin-plus-COEP"。

      3. 否则,将 policy设置为 "same-origin"。

    2. 如果 parsedItem[0] 是 "same-origin-allow-popups",则将 policy设置为 "same-origin-allow-popups"。

    3. 如果 parsedItem[1]["report-to"]存在,并且它是一个字符串,则将 policy报告端点设置为 parsedItem[1]["report-to"]。

  5. parsedItem 设置为获取结构化字段值的结果,给定 `Cross-Origin-Opener-Policy-Report-Only` 和 "item" 从 response头部列表

  6. 如果 parsedItem 不为 null,则:

    1. 如果 parsedItem[0] 是 "same-origin",则:

      1. coep 成为获取跨源嵌入者策略的结果,来自 responsereservedEnvironment

      2. 如果 coep跨源隔离兼容coep仅报告值跨源隔离兼容,则将 policy仅报告值设置为 "same-origin-plus-COEP"。

        仅报告 COOP 还考虑仅报告 COEP 来分配特殊的 "same-origin-plus-COEP" 值。这使开发者在部署 COOP 和 COEP 的顺序上有更多的自由。

      3. 否则,将 policy仅报告值设置为 "same-origin"。

    2. 如果 parsedItem[0] 是 "same-origin-allow-popups",则将 policy仅报告值设置为 "same-origin-allow-popups"。

    3. 如果 parsedItem[1]["report-to"]存在并且它是一个字符串,则将 policy仅报告端点设置为 parsedItem[1]["report-to"]。

  7. 返回 policy

7.1.3.2 由于跨源打开者策略导致的浏览上下文组切换

为了检查 COOP 值是否需要浏览上下文组切换,给定一个布尔值isInitialAboutBlank,两个 responseOriginactiveDocumentNavigationOrigin,以及两个跨域 opener 策略值 responseCOOPValueactiveDocumentCOOPValue:

  1. 如果匹配activeDocumentCOOPValueactiveDocumentNavigationOriginresponseCOOPValueresponseOrigin的结果为 true,则返回 false。

  2. 如果以下所有条件都为真:

    则返回 false。

  3. 返回 true。

为了检查强制执行仅报告 COOP 是否需要浏览上下文组切换,给定一个布尔值 isInitialAboutBlank,两个 responseOriginactiveDocumentNavigationOrigin,以及两个跨域 opener 策略 responseCOOPactiveDocumentCOOP:

  1. 如果检查 COOP 值是否需要浏览上下文组切换的结果为 false, 给定isInitialAboutBlankresponseOriginactiveDocumentNavigationOriginresponseCOOP仅报告值activeDocumentCOOPReportOnly仅报告值, 则返回 false。

    匹配仅报告策略允许网站在其所有页面上指定相同的仅报告跨域 opener 策略,并且不会因这些页面之间的导航收到违规报告。

  2. 如果检查 COOP 值是否需要浏览上下文组切换的结果为 true, 给定isInitialAboutBlankresponseOriginactiveDocumentNavigationOriginresponseCOOPactiveDocumentCOOPReportOnly仅报告值, 则返回 true。

  3. 如果检查 COOP 值是否需要浏览上下文组切换的结果为 true, 给定isInitialAboutBlankresponseOriginactiveDocumentNavigationOriginresponseCOOP仅报告值activeDocumentCOOPReportOnly, 则返回 true。

  4. 返回 false。

跨域 opener 策略执行结果是一个结构体,包含以下项目

为了执行响应的跨域 opener 策略,给定一个浏览上下文 browsingContext,一个URL responseURL,一个 responseOrigin,一个跨域 opener 策略 responseCOOP,一个跨域 opener 策略执行结果 currentCOOPEnforcementResult,以及一个引用 referrer

  1. newCOOPEnforcementResult为一个新的跨域 opener 策略执行结果,其中包含

    需要浏览上下文组切换
    currentCOOPEnforcementResult需要浏览上下文组切换
    仅因报告需要浏览上下文组切换
    currentCOOPEnforcementResult仅因报告需要浏览上下文组切换
    url
    responseURL
    origin
    responseOrigin
    跨域 opener 策略
    responseCOOP
    当前上下文是导航源
    true
  2. isInitialAboutBlankbrowsingContext活动文档是否初始about:blank

  3. 如果isInitialAboutBlank为 true 且browsingContext初始 URL为 null,则将 browsingContext初始 URL设置为 responseURL

  4. 如果检查 COOP 值是否需要浏览上下文组切换的结果为 true, 给定isInitialAboutBlankcurrentCOOPEnforcementResult跨域 opener 策略currentCOOPEnforcementResultresponseCOOPresponseOrigin,则:

    1. newCOOPEnforcementResult需要浏览上下文组切换设置为 true。

    2. 如果browsingContext浏览上下文集大小大于 1,则:

      1. 队列一个违规报告用于在导航到 COOP 响应时进行浏览上下文组切换,包括responseCOOP、 "enforce"、responseURLcurrentCOOPEnforcementResulturlcurrentCOOPEnforcementResultresponseOriginreferrer

      2. 队列一个违规报告用于在离开 COOP 响应时进行浏览上下文组切换,包括 currentCOOPEnforcementResult跨域 opener 策略、"enforce"、 currentCOOPEnforcementResulturlresponseURLcurrentCOOPEnforcementResultresponseOrigincurrentCOOPEnforcementResult当前上下文是导航源

  5. 如果检查强制执行仅报告 COOP 是否需要浏览上下文组切换的结果为 true, 给定isInitialAboutBlankresponseOrigincurrentCOOPEnforcementResultresponseCOOPcurrentCOOPEnforcementResult跨域 opener 策略, 则:

    1. result仅因报告需要浏览上下文组切换设置为 true。

    2. 如果browsingContext浏览上下文集大小大于 1,则:

      1. 队列一个违规报告用于在导航到 COOP 响应时进行浏览上下文组切换,包括responseCOOP、 "reporting"、responseURLcurrentCOOPEnforcementResulturlcurrentCOOPEnforcementResultresponseOriginreferrer

      2. 队列一个违规报告用于在离开 COOP 响应时进行浏览上下文组切换,包括 currentCOOPEnforcementResult跨域 opener 策略、"reporting"、 currentCOOPEnforcementResulturlresponseURLcurrentCOOPEnforcementResultresponseOrigincurrentCOOPEnforcementResult当前上下文是导航源

  6. 返回newCOOPEnforcementResult

为了获取用于导航响应的浏览上下文,给定一个浏览上下文 browsingContext,一个 沙箱标志集 sandboxFlags,一个跨域 opener 策略 navigationCOOP,以及一个跨域 opener 策略执行结果 coopEnforcementResult

  1. 如果browsingContext不是一个顶级浏览上下文,则 返回browsingContext

  2. 如果coopEnforcementResult需要浏览上下文组切换为 false,则:

    1. 如果coopEnforcementResult仅因报告需要浏览上下文组切换为 true,则将browsing context虚拟浏览上下文组 ID设置为一个新的唯一标识符。

    2. 返回browsingContext

  3. newBrowsingContext创建一个新的顶级浏览上下文和文档的第一个返回值。

    在这种情况下,我们将执行浏览上下文组交换。 browsingContext将不会被我们即将创建的新文档 使用。 如果它没有被其他文档使用(例如后退/前进缓存中的文档),则用户代理可能在此时销毁它

  4. 如果navigationCOOP为 "same-origin-plus-COEP", 则将 newBrowsingContext跨域隔离模式设置为"逻辑" 或"具体"。 选择由 实现定义

    在某些平台上很难提供跨域隔离能力所需的安全属性。 "具体" 允许访问它,而"逻辑" 则不允许。

  5. 如果sandboxFlags不为空,则:

    1. 断言navigationCOOP 为 "unsafe-none"。

    2. 断言newBrowsingContext弹出沙箱标志集 为空

    3. newBrowsingContext弹出沙箱标志集设置为sandboxFlags克隆

  6. 返回newBrowsingContext

7.1.3.3 报告

访问者-被访问者关系是一个枚举,用于描述发生访问的两个浏览上下文之间的关系。它可以取以下值:

访问者是打开者

访问者浏览上下文或其之一祖先是被访问者浏览上下文顶级浏览上下文打开者浏览上下文

访问者是被打开者

被访问者浏览上下文或其之一祖先是访问者浏览上下文顶级浏览上下文打开者浏览上下文

访问者浏览上下文之间,访问者浏览上下文之间,或其任何祖先之间没有打开者关系。

检查两个浏览上下文之间的访问是否应被报告,给定两个浏览上下文accessoraccessed、一个JavaScript属性名P,以及一个环境设置对象environment

  1. 如果P不是一个跨域可访问窗口属性名,则返回。

  2. 断言accessor活动文档accessed活动文档都是完全活跃

  3. accessorTopDocumentaccessor顶级浏览上下文活动文档

  4. accessorInclusiveAncestorOrigins为通过获取accessor的每个活动文档而获得的列表。

  5. accessedTopDocumentaccessed顶级浏览上下文活动文档

  6. accessedInclusiveAncestorOrigins为通过获取accessed的每个活动文档而获得的列表。

  7. 如果accessorInclusiveAncestorOrigins中的任何一个与accessorTopDocument不是同源,或者accessedInclusiveAncestorOrigins中的任何一个与accessedTopDocument不是同源,则返回。

    这避免了向具有跨域打开者策略报告的顶级框架泄露跨域iframe的信息。

  8. 如果accessor顶级浏览上下文虚拟浏览上下文组IDaccessed顶级浏览上下文虚拟浏览上下文组ID,则返回。

  9. accessorAccessedRelationship为值为的新的访问者-被访问者关系

  10. 如果accessed顶级浏览上下文打开者浏览上下文accessor或是accessor的一个祖先,则将accessorAccessedRelationship设置为访问者是打开者

  11. 如果accessor顶级浏览上下文打开者浏览上下文accessed或是accessed的一个祖先,则将accessorAccessedRelationship设置为访问者是被打开者

  12. 为访问排队违规报告,给定accessorAccessedRelationshipaccessorTopDocument打开者策略accessedTopDocument打开者策略accessor活动文档URLaccessed活动文档URLaccessor顶级浏览上下文初始URLaccessed顶级浏览上下文初始URLaccessor活动文档accessed活动文档accessor顶级浏览上下文创建时的打开者源accessed顶级浏览上下文创建时的打开者源accessorTopDocument引用accessedTopDocument引用Penvironment

对要发送报告的URL进行清理,给定一个URLurl

  1. sanitizedURLurl的副本。

  2. 设置用户名,给定sanitizedURL和空字符串。

  3. 设置密码,给定sanitizedURL和空字符串。

  4. 返回sanitizedURL序列化,并将排除片段设置为true。

在导航到COOP响应时为浏览上下文组切换排队违规报告,给定一个跨域打开者策略coop、一个字符串disposition、一个URLcoopURL、一个URLpreviousResponseURL、两个coopOriginpreviousResponseOrigin,以及一个引用referrer

  1. 如果coop报告端点为空,则返回。

  2. coopValuecoop

  3. 如果disposition为"reporting",则将coopValue设置为coop仅报告值

  4. serializedReferrer为空字符串。

  5. 如果referrer是一个URL,则将serializedReferrer设置为referrer序列化

  6. body为一个包含以下属性的新对象:

    disposition disposition
    effectivePolicy coopValue
    previousResponseURL 如果coopOriginpreviousResponseOrigin同源,这是previousResponseURL清理,否则为null。
    referrer serializedReferrer
    type "navigation-to-response"
  7. 排队body作为"coop",用于coop报告端点,使用coopURL

在从COOP响应导航时为浏览上下文组切换排队违规报告,给定一个跨域打开者策略coop、一个字符串disposition、一个URLcoopURL、一个URLnextResponseURL、两个coopOriginnextResponseOrigin,以及一个布尔值isCOOPResponseNavigationSource

  1. 如果coop报告端点为空,则返回。

  2. coopValuecoop

  3. 如果disposition为"reporting",则将coopValue设置为coop仅报告值

  4. body为一个包含以下属性的新对象:

    disposition disposition
    effectivePolicy coopValue
    nextResponseURL 如果coopOriginnextResponseOrigin同源,或者isCOOPResponseNavigationSource为true,则这是nextResponseURL清理,否则为null。
    type "navigation-from-response"
  5. 排队body作为"coop",用于coop报告端点,使用coopURL

为访问排队违规报告,给定一个访问者-被访问者关系accessorAccessedRelationship、两个跨域打开者策略accessorCOOPaccessedCOOP、四个URLaccessorURLaccessedURLaccessorInitialURLaccessedInitialURL、四个accessorOriginaccessedOriginaccessorCreatorOriginaccessedCreatorOrigin、两个引用accessorReferreraccessedReferrer、一个字符串propertyName,以及一个环境设置对象environment

  1. 如果coop报告端点为空,则返回。

  2. coopValuecoop

  3. 如果disposition为"reporting",则将coopValue设置为coop仅报告值

  4. 如果accessorAccessedRelationship访问者是打开者

    1. 为访问已打开的窗口排队违规报告,给定accessorCOOPaccessorURLaccessedURLaccessedInitialURLaccessorOriginaccessedOriginaccessedCreatorOriginpropertyNameenvironment

    2. 为从打开者的访问排队违规报告,给定accessedCOOPaccessedURLaccessorURLaccessedOriginaccessorOriginpropertyNameaccessedReferrer

  5. 否则,如果accessorAccessedRelationship访问者是被打开者

    1. 为访问打开者排队违规报告,给定accessorCOOPaccessorURLaccessedURLaccessorOriginaccessedOriginpropertyNameaccessorReferrerenvironment

    2. 为从已打开窗口的访问排队违规报告,给定accessedCOOPaccessedURLaccessorURLaccessorInitialURLaccessedOriginaccessorOriginaccessorCreatorOriginpropertyName

  6. 否则:

    1. 为访问其他窗口排队违规报告,给定accessorCOOPaccessorURLaccessedURLaccessorOriginaccessedOriginpropertyNameenvironment

    2. 为从其他窗口的访问排队违规报告,给定accessedCOOPaccessedURLaccessorURLaccessedOriginaccessorOriginpropertyName

为访问打开者排队违规报告,给定一个跨域打开者策略coop、两个URLcoopURLopenerURL、两个coopOriginopenerOrigin、一个字符串propertyName、一个引用referrer,以及一个环境设置对象environment

  1. sourceFilelineNumbercolumnNumber为触发此报告的相关脚本URL和问题位置。

  2. serializedReferrer为空字符串。

  3. 如果referrer是一个URL,则将serializedReferrer设置为referrer序列化

  4. body为一个包含以下属性的新对象:

    disposition "reporting"
    effectivePolicy coop仅报告值
    property propertyName
    openerURL 如果coopOriginopenerOrigin同源,这是openerURL清理,否则为null。
    referrer serializedReferrer
    sourceFile sourceFile
    lineNumber lineNumber
    columnNumber columnNumber
    type "access-to-opener"
  5. 排队body作为"coop",用于coop报告端点,使用coopURLenvironment

为访问已打开的窗口排队违规报告,给定一个跨域打开者策略coop、三个URLcoopURLopenedWindowURLinitialWindowURL、三个coopOriginopenedWindowOriginopenerInitialOrigin、一个字符串propertyName,以及一个环境设置对象environment

  1. sourceFilelineNumbercolumnNumber为触发此报告的相关脚本URL和问题位置。

  2. body为一个包含以下属性的新对象:

    disposition "reporting"
    effectivePolicy coop仅报告值
    property propertyName
    openedWindowURL 如果coopOriginopenedWindowOrigin同源,这是openedWindowURL清理,否则为null。
    openedWindowInitialURL 如果coopOriginopenerInitialOrigin同源,这是initialWindowURL清理,否则为null。
    sourceFile sourceFile
    lineNumber lineNumber
    columnNumber columnNumber
    type "access-to-opener"
  3. 排队body作为"coop",用于coop报告端点,使用coopURLenvironment

为访问其他窗口排队违规报告,给定一个跨域打开者策略coop、两个URLcoopURLotherURL、两个coopOriginotherOrigin、一个字符串propertyName,以及一个环境设置对象environment

  1. sourceFilelineNumbercolumnNumber为触发此报告的相关脚本URL和问题位置。

  2. body为一个包含以下属性的新对象:

    disposition "reporting"
    effectivePolicy coop仅报告值
    property propertyName
    otherURL 如果coopOriginotherOrigin同源,这是otherURL清理,否则为null。
    sourceFile sourceFile
    lineNumber lineNumber
    columnNumber columnNumber
    type "access-to-opener"
  3. 排队body作为"coop",用于coop报告端点,使用coopURLenvironment

为从打开者的访问排队违规报告,给定一个跨域打开者策略coop、两个URLcoopURLopenerURL、两个coopOriginopenerOrigin、一个字符串propertyName,以及一个引用referrer

  1. 如果coop报告端点为空,则返回。

  2. serializedReferrer为空字符串。

  3. 如果referrer是一个URL,则将serializedReferrer设置为referrer序列化

  4. body为一个包含以下属性的新对象:

    disposition "reporting"
    effectivePolicy coop仅报告值
    property propertyName
    openerURL 如果coopOriginopenerOrigin同源,这是openerURL清理,否则为null。
    referrer serializedReferrer
    type "access-to-opener"
  5. 排队body作为"coop",用于coop报告端点,使用coopURL

为从已打开窗口的访问排队违规报告,给定一个跨域打开者策略coop、三个URLcoopURLopenedWindowURLinitialWindowURL、三个coopOriginopenedWindowOriginopenerInitialOrigin,以及一个字符串propertyName

  1. 如果coop报告端点为空,则返回。

  2. body为一个包含以下属性的新对象:

    disposition "reporting"
    effectivePolicy coopValue
    property coop仅报告值
    openedWindowURL 如果coopOriginopenedWindowOrigin同源,这是openedWindowURL清理,否则为null。
    openedWindowInitialURL 如果coopOriginopenerInitialOrigin同源,这是initialWindowURL清理,否则为 null。
    type "access-to-opener"
  3. 排队body作为"coop",用于coop报告端点,使用coopURL

为从其他窗口的访问排队违规报告,给定一个跨域打开者策略coop、两个URLcoopURLotherURL、两个coopOriginotherOrigin、以及一个字符串propertyName

  1. 如果coop报告端点为空,则返回。

  2. body为一个包含以下属性的新对象:

    disposition "reporting"
    effectivePolicy coop仅报告值
    property propertyName
    otherURL 如果coopOriginotherOrigin同源,这是otherURL清理,否则为null。
    sourceFile sourceFile
    lineNumber lineNumber
    columnNumber columnNumber
    type "access-to-opener"
  3. 排队body作为"coop",用于coop报告端点,使用coopURL

7.1.4 跨域嵌入策略

Headers/Cross-Origin-Embedder-Policy

支持所有当前的引擎。

Firefox79+Safari15.2+Chrome83+
Opera?Edge83+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android86+Samsung Internet?Opera Android?

嵌入策略值是三个字符串之一,用于控制在没有资源所有者明确许可的情况下获取跨域资源。

"unsafe-none"

这是默认值。当使用此值时,可以在没有通过CORS协议或 `跨域资源策略` 头明确许可的情况下获取跨域资源。

"require-corp"

使用此值时,获取跨域资源需要服务器通过CORS协议或 `跨域资源策略` 头明确许可。

"credentialless"

使用此值时,获取跨域无CORS资源时不包含凭证。作为交换,不需要明确的`跨域资源策略` 头。其他带凭证的请求需要服务器通过CORS 协议或`跨域资源策略` 头明确许可。

在支持"credentialless" 之前,实施者强烈建议支持以下两项:

否则,这将允许攻击者利用客户端的网络位置读取非公开资源,使用跨域隔离能力

嵌入策略值与跨域隔离兼容的,如果它是"credentialless" 或"require-corp"。

嵌入策略包括:

"coep"报告类型是一个报告类型,其值 为"coep"。它对可见ReportingObserver

7.1.4.1 标头

`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"

(同样适用于Cross-Origin-Embedder-Policy-Report-Only。)


要从响应response和一个环境environment获取嵌入策略

  1. policy成为一个新的嵌入策略

  2. 如果environment是一个非安全上下文,那么返回policy

  3. parsedItem成为获取结构化字段值的结果,其中`Cross-Origin-Embedder-Policy`和"item"来自response标头列表

  4. 如果parsedItem非空且parsedItem[0]是与跨域隔离兼容

    1. policy设置为parsedItem[0]。

    2. 如果parsedItem[1]["report-to"]存在,则将policy端点设置为parsedItem[1]["report-to"]。

  5. parsedItem设置为获取结构化字段值的结果,其中`Cross-Origin-Embedder-Policy-Report-Only`和"item"来自response标头列表

  6. 如果parsedItem非空且parsedItem[0]是与跨域隔离兼容

    1. policy仅报告值设置为parsedItem[0]。

    2. 如果parsedItem[1]["report-to"]存在,则将policy仅报告端点设置为parsedItem[1]["report-to"]。

  7. 返回policy

7.1.4.2 嵌入策略检查

检查导航响应是否遵循其嵌入策略,给定一个响应response,一个可导航的对象navigable,以及一个嵌入策略responsePolicy

  1. 如果navigable不是一个子可导航对象,则返回true。

  2. parentPolicy成为navigable容器文档策略容器嵌入策略

  3. 如果parentPolicy仅报告值跨域隔离兼容,而responsePolicy不兼容,则队列一个跨域嵌入策略继承违规,参数为response,"navigation",parentPolicy仅报告端点,"reporting",和navigable容器文档相关设置对象

  4. 如果parentPolicy不与跨域隔离兼容responsePolicy跨域隔离兼容,则返回true。

  5. 队列一个跨域嵌入策略继承违规,参数为response,"navigation",parentPolicy报告端点,"enforce",和navigable容器文档相关设置对象

  6. 返回false。

检查全局对象的嵌入策略,给定一个WorkerGlobalScopeworkerGlobalScope,一个环境设置对象owner,以及一个响应response

  1. 如果workerGlobalScope不是一个DedicatedWorkerGlobalScope对象,则返回true。

  2. policy成为workerGlobalScope嵌入策略

  3. ownerPolicy成为owner策略容器嵌入策略

  4. 如果ownerPolicy仅报告值跨域隔离兼容,而policy不兼容,则队列一个跨域嵌入策略继承违规,参数为response,"worker initialization",ownerPolicy仅报告端点,"reporting" ,和owner

  5. 如果ownerPolicy不与跨域隔离兼容policy跨域隔离兼容,则返回true。

  6. 队列一个跨域嵌入策略继承违规,参数为response,"worker initialization",ownerPolicy报告端点,"enforce",和owner

  7. 返回false。

队列一个跨域嵌入策略继承违规,给定一个响应response,一个字符串type,一个字符串endpoint,一个字符串disposition,以及一个环境设置对象settings

  1. serialized成为序列化一个响应URL以用于报告的结果,参数为response

  2. body成为一个包含以下属性的新对象:

    key value
    type type
    blockedURL serialized
    disposition disposition
  3. 队列 body作为settings"coep"报告类型,发送到endpoint

7.1.5 沙盒

沙盒标志集是一个包含以下零个或多个标志的集合,这些标志用于限制可能不受信任的资源的能力:

沙盒导航浏览上下文标志

此标志防止内容导航到除沙盒浏览上下文自身之外的浏览上下文(或进一步嵌套在其内部的浏览上下文),辅助浏览上下文(受下面定义的沙盒辅助导航浏览上下文标志保护),以及顶级浏览上下文(受下面定义的无用户激活的沙盒顶级导航浏览上下文标志有用户激活的沙盒顶级导航浏览上下文标志保护)。

如果没有设置沙盒辅助导航浏览上下文标志,则在某些情况下,这些限制仍然允许弹出窗口(新的顶级浏览上下文)被打开。这些浏览上下文总是有一个允许的沙盒导航器,在创建浏览上下文时设置,允许创建它们的浏览上下文实际导航它们。(否则,沙盒导航浏览上下文标志即使它们被打开也会阻止它们被导航。)

沙盒辅助导航浏览上下文标志

此标志防止内容创建新的辅助浏览上下文,例如使用target属性或window.open()方法。

无用户激活的沙盒顶级导航浏览上下文标志

此标志防止内容导航其顶级浏览上下文防止内容关闭其顶级浏览上下文。仅当沙盒浏览上下文的活动窗口没有短暂激活时才会参考此标志。

无用户激活的沙盒顶级导航浏览上下文标志未设置时,内容可以导航其顶级浏览上下文,但其他浏览上下文仍然受沙盒导航浏览上下文标志和可能的沙盒辅助导航浏览上下文标志保护。

有用户激活的沙盒顶级导航浏览上下文标志

此标志防止内容导航其顶级浏览上下文防止内容关闭其顶级浏览上下文。仅当沙盒浏览上下文的活动窗口短暂激活时才会参考此标志。

无用户激活的沙盒顶级导航浏览上下文标志相同,此标志仅影响顶级浏览上下文;如果未设置,其他浏览上下文可能仍受其他标志保护。

沙盒来源浏览上下文标志

此标志将内容强制进入不透明来源,从而防止其访问来自同一来源的其他内容。

此标志还防止脚本读取或写入document.cookie IDL属性,并阻止访问localStorage

沙盒表单浏览上下文标志

此标志阻止表单提交

沙盒指针锁定浏览上下文标志

此标志禁用指针锁定API。[POINTERLOCK]

沙盒脚本浏览上下文标志

此标志阻止脚本执行

沙盒自动功能浏览上下文标志

此标志阻止自动触发的功能,例如自动播放视频自动聚焦表单控件

沙盒document.domain浏览上下文标志

此标志防止内容使用document.domain设置器。

沙盒传播到辅助浏览上下文标志

此标志确保任何内容创建的辅助浏览上下文继承其内容的活动沙盒标志集,从而防止内容逃离沙盒。

沙盒模态标志

此标志防止内容使用以下任何功能来生成模态对话框:

沙盒方向锁定浏览上下文标志

此标志禁用锁定屏幕方向的能力。[SCREENORIENTATION]

沙盒演示浏览上下文标志

此标志禁用演示API。[PRESENTATION]

沙盒下载浏览上下文标志

此标志防止内容启动或实例化下载,无论是通过下载超链接还是通过被作为下载处理导航

沙盒自定义协议导航浏览上下文标志

此标志防止导航到非fetch协议,并将其交给外部软件

当用户代理解析沙盒指令时,给定一个字符串input,一个沙盒标志集output,它必须运行以下步骤:

  1. 在ASCII空白字符上拆分input,以获得tokens

  2. output为空。

  3. 将以下标志添加到output中:


每个顶级浏览上下文都有一个弹出沙盒标志集,它是一个沙盒标志集。当创建浏览上下 文时,其弹出沙盒标志集必须为空。它由选择可导航规则获得导航响应的浏览上下文算法填充。

每个iframe元素都有一个iframe沙盒标志集,它是一个沙盒标志集iframe沙盒标志集中的哪些标志在任何特定时间设置,取决于iframe元素的sandbox属性。

每个Document都有一个活动沙盒标志集,它是一个沙盒标志集。当创建Document时,其活动沙盒标志集必须为空。它由导航算法填充。

每个CSP列表cspList都有CSP派生沙盒标志,它是一个沙盒标志集。它是以下算法的返回值:

  1. directives为空的有序集

  2. 对每个cspList中的策略:

    1. 如果policy处置不是"enforce",则继续

    2. 如果policy指令集包含一个名称为"sandbox"的指令,则附加该指令到directives

  3. 如果directives为空,则返回一个空的沙盒标志集

  4. directivedirectives[directives大小- 1]。

  5. 返回解析沙盒指令directive的结果。


确定创建沙盒标志对于浏览上下文browsing context,给定null或一个元素embedder,返回以下联合中存在的标志:

7.1.6 策略容器

策略容器是包含适用于DocumentWorkerGlobalScopeWorkletGlobalScope的策略的结构。它具有以下项目

将其他策略移入策略容器中。

克隆一个策略容器,给定一个策略容器policyContainer

  1. clone为一个新的策略容器

  2. 对于 policyContainerCSP列表中的每个policy附加 policy的副本到cloneCSP列表

  3. clone嵌入策略设置为policyContainer嵌入策略的副本。

  4. clone引用策略设置为policyContainer引用策略

  5. 返回clone

要确定一个URLurl是否需要将策略容器存储在历史记录中

  1. 如果urlscheme是"blob",则返回false。

  2. 如果url是本地的,则返回true。

  3. 返回false。

从提取响应创建策略容器,给定一个响应response和一个环境或null的environment

  1. 如果responseURLscheme是"blob",则返回responseURLblob URL条目环境策略容器克隆

  2. result为一个新的策略容器

  3. resultCSP列表设置为给定response解析响应的内容安全策略的结果。

  4. 如果environment非null,则将result嵌入策略设置为给定responseenvironment获取嵌入策略的结果。否则,将其设置为"unsafe-none"。

  5. result引用策略设置为给定response解析`Referrer-Policy`头的结果。[REFERRERPOLICY]

  6. 返回result

确定导航参数策略容器,给定一个responseURL和四个策略容器或null的historyPolicyContainerinitiatorPolicyContainerparentPolicyContainerresponsePolicyContainer

  1. 如果historyPolicyContainer不为null,则:

    1. 断言responseURL需要将策略容器存储在历史记录中

    2. 返回historyPolicyContainer克隆

  2. 如果responseURLabout:srcdoc,则:

    1. 断言parentPolicyContainer不为null。

    2. 返回parentPolicyContainer克隆

  3. 如果responseURL是本地的initiatorPolicyContainer不为null,则返回initiatorPolicyContainer克隆

  4. 如果responsePolicyContainer不为null,则返回responsePolicyContainer

  5. 返回一个新的策略容器

初始化worker global scope的策略容器,给定一个WorkerGlobalScopeworkerGlobalScope、一个响应response和一个环境environment

  1. 如果workerGlobalScopeURL是本地的但其scheme不是"blob":

    1. 断言workerGlobalScope所有者集大小为1。

    2. workerGlobalScope策略容器设置为workerGlobalScope所有者集[0]的相关设置对象策略容器克隆

  2. 否则,将workerGlobalScope策略容器设置为给定responseenvironment从提取响应创建策略容器的结果。

7.2.1 WindowWindowProxyLocation 对象的安全基础设施

尽管通常情况下对象不能跨访问,但如果没有一些网络依赖的遗留例外情况,网络平台就不会保持其本质。

本节使用JavaScript规范中的术语和排版约定。[JAVASCRIPT]

7.2.1.1 与 ID L的集成

执行安全检查时,使用platformObjectidentifiertype运行以下步骤:

  1. 如果platformObject不是WindowLocation对象,则返回。

  2. 对于platformObject的每个e,从CrossOriginProperties

    1. 如果SameValue(e.[[Property]], identifier)为true,则:

      1. 如果type是"method"并且e既没有[[NeedsGet]]也没有[[NeedsSet]],则返回。

      2. 否则,如果type是"getter"并且e.[[NeedsGet]]为true,则返回。

      3. 否则,如果type是"setter"并且e.[[NeedsSet]]为true,则返回。

  3. 如果IsPlatformObjectSameOrigin(platformObject)为false,则抛出"SecurityError"DOMException

7.2.1.2 共享内部槽:[[CrossOriginPropertyDescriptorMap]]

WindowLocation对象都具有[[CrossOriginPropertyDescriptorMap]]内部槽,其值最初为空映射。

[[CrossOriginPropertyDescriptorMap]]内部槽包含一个映射,映射的键是(currentGlobalobjectGlobalpropertyKey)元组,值是属性描述符,作为currentGlobal检查来自objectGlobalWindowLocation对象时对脚本可见内容的记忆化。它由CrossOriginGetOwnPropertyHelper懒惰地填充,并在以后的查找中咨询它。

用户代理应该允许映射中保存的值连同其对应的键一起被垃圾收集,只要没有任何东西引用该值的任何部分。也就是说,只要垃圾收集是不可观察的。

例如,使用const href = Object.getOwnPropertyDescriptor(crossOriginLocation, "href").set,映射中的值及其对应的键不能被垃圾收集,因为这将是可观察的。

用户代理可以进行优化,在设置document.domain时从映射中删除键值对。这是不可观察的,因为document.domain不能重新访问之前的值。

例如,在www.example.com上将document.domain设置为"example.com"意味着用户代理可以从映射中删除所有键的一部分为www.example.com的键值对,因为这再也不能成为的一部分,因此相应的值永远不能从映射中检索到。

7.2.1.3 共享抽象操作
7.2.1.3.1 CrossOriginProperties (O)
  1. 断言OLocationWindow 对象。

  2. 如果 OLocation 对象,则返回 « { [[Property]]: "href", [[NeedsGet]]: false, [[NeedsSet]]: true }, { [[Property]]: "replace" } »。

  3. 返回 « { [[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",或数组索引属性名

7.2.1.3.2 CrossOriginPropertyFallback (P)
  1. 如果 P 是 "then",%Symbol.toStringTag%%Symbol.hasInstance%,或 %Symbol.isConcatSpreadable%,则返回 PropertyDescriptor{ [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }。

  2. 抛出 "SecurityError" DOMException

7.2.1.3.3 IsPlatformObjectSameOrigin (O)
  1. 如果 当前设置对象来源O相关设置对象来源 同源域,则返回 true,否则返回 false。

此抽象操作不返回 完成记录

这里的 当前设置对象 大致对应于 "调用者",因为此检查发生在 执行上下文 进入 JavaScript 执行上下文堆栈 之前。例如,在代码 w.document 中,此步骤在 document getter 被执行为 WindowProxy w[[Get]] 算法的一部分之前调用。

7.2.1.3.4 CrossOriginGetOwnPropertyHelper (O, P)

如果此抽象操作返回 undefined 并且没有自定义行为,则调用者需要抛出 "SecurityError" DOMException。 实际上,这是通过调用者调用 CrossOriginPropertyFallback 来处理的。

  1. crossOriginKey 成为一个包含 当前设置对象O相关设置对象P 的元组。

  2. 对于每个 eCrossOriginProperties(O):

    1. 如果 SameValue(e.[[Property]], P) 为 true,则:

      1. 如果 O[[CrossOriginPropertyDescriptorMap]] 内部槽的值包含一个键为 crossOriginKey 的条目,则返回该条目的值。

      2. originalDescOrdinaryGetOwnProperty(O, P)。

      3. crossOriginDesc 为 undefined。

      4. 如果 e 的 [[NeedsGet]] 和 [[NeedsSet]] 不存在,则:

        1. valueoriginalDesc 的 [[Value]]。

        2. 如果 IsCallable(value) 为 true,则将 value 设置为在 当前领域 中创建的匿名内置函数,该函数执行与 IDL 操作 P 在对象 O 上的操作相同的步骤。

        3. crossOriginDesc 设置为 PropertyDescriptor{ [[Value]]: value, [[Enumerable]]: false, [[Writable]]: false, [[Configurable]]: true }。

      5. 否则:

        1. crossOriginGet 设置为 undefined。

        2. 如果 e 的 [[NeedsGet]] 为 true,则将 crossOriginGet 设置为在 当前领域 中创建的匿名内置函数,该函数执行与 IDL 属性 P 在对象 O 上的 getter 相同的步骤。

        3. crossOriginSet 设置为 undefined。

        4. 如果 e 的 [[NeedsSet]] 为 true,则将 crossOriginSet 设置为在 当前领域 中创建的匿名内置函数,该函数执行与 IDL 属性 P 在对象 O 上的 setter 相同的步骤。

        5. crossOriginDesc 设置为 PropertyDescriptor{ [[Get]]: crossOriginGet, [[Set]]: crossOriginSet, [[Enumerable]]: false, [[Configurable]]: true }。

      6. O[[CrossOriginPropertyDescriptorMap]] 内部槽中的值中创建一个键为 crossOriginKey 且值为 crossOriginDesc 的条目。

      7. 返回 crossOriginDesc

  3. 返回 undefined。

此抽象操作不返回 完成记录

此处生成的属性描述符是可配置的原因是为了保留 JavaScript 规范所需的 基本内部方法的不变量。 特别是,由于属性的值可以因导航而更改,因此要求属性是可配置的。(但是,请参见 tc39/ecma262 issue #672 以及该规范其他地方对此的引用,以了解我们无法保留这些不变量的情况,以兼容现有的 web 内容。)[JAVASCRIPT]

属性描述符是不可枚举的原因是为了兼容现有的 web 内容,尽管这与同源行为不匹配。详情请参见 issue #3183

7.2.1.3.5 CrossOriginGet ( O, P, Receiver )
  1. desc 为 ? O.[[GetOwnProperty]](P).

  2. 断言desc 不为 undefined。

  3. 如果 IsDataDescriptor(desc) 为 true,则返回 desc.[[Value]]。

  4. 断言IsAccessorDescriptor(desc) 为 true。

  5. getterdesc.[[Get]]。

  6. 如果 getter 为 undefined,则抛出 "SecurityError" DOMException

  7. 返回 ? Call(getter, Receiver)。

7.2.1.3.6 CrossOriginSet ( O, P, V, Receiver )
  1. desc 为 ? O.[[GetOwnProperty]](P).

  2. 断言desc 不为 undefined。

  3. 如果 desc.[[Set]] 存在且其值不为 undefined,则:

    1. 执行 ? Call(setter, Receiver, « V »)。

    2. 返回 true。

  4. 抛出 "SecurityError" DOMException

7.2.1.3.7 CrossOriginOwnPropertyKeys (O)
  1. keys 成为一个新的空 列表

  2. 对于每个 eCrossOriginProperties(O), e.[[Property]] 附加到 keys

  3. 返回 keys 和 « "then", %Symbol.toStringTag%%Symbol.hasInstance%%Symbol.isConcatSpreadable% » 的串联。

此抽象操作不返回 完成记录

7.2.2 Window 对象

Window

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+
[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/window

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
window.frames

Window/frames

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
window.self

Window/self

在所有当前引擎中支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

这些属性都返回 window

window.document

Window/document

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回与 window 关联的 Document

document.defaultView

Document/defaultView

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回与 document 关联的 Window,如果有的话,否则返回 null。

Window 对象有一个 关联的 Document,这是一个 Document 对象。它 在创建 Window 对象时设置,并且只有在从 导航初始 about:blank Document 时才会更改。

Window浏览上下文 是它的 关联 Document浏览上下文它要么是 null,要么是一个 浏览上下文

Window可导航对象可导航对象,其 活动文档Window关联 Document 的,或者如果没有这样的 可导航对象 则为 null。

windowframesself 的 getter 步骤是返回 this相关领域 的 [[GlobalEnv]] 的 [[GlobalThisValue]]。

document 的 getter 步骤是返回 this关联 Document

Window 对象关联的 Document 对象可以在一种情况下更改:当 导航 算法 为第一次加载的页面创建新的 Document 对象 时 在 浏览上下文 中。在这种特定情况下,初始 about:blank 页面的 Window 对象会被重用,并获得一个新的 Document 对象。

defaultView 的 getter 步骤是:

  1. 如果 this浏览上下文 为 null,则返回 null。

  2. 返回 this浏览上下文WindowProxy 对象。


HTMLDocument

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

由于历史原因,Window 对象还必须有一个可写的、可配置的、不可枚举的属性,名称为 HTMLDocument,其值是 Document 接口对象

7.2.2.1 打开和关闭窗口
window = window.open([ url [, target [, features ] ] ])

Window/open

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

打开一个窗口以显示url(默认为"about:blank"),并返回它。target(默认为"_blank")指定新窗口的名称。如果已经存在具有该名称的窗口,则重新使用它。features参数可以包含一个逗号分隔的标记集

"noopener"
"noreferrer"

这些行为等同于noopenernoreferrer链接类型在超链接上的行为。

"popup"

鼓励用户代理为新窗口提供一个最小的网页浏览器用户界面。(影响所有可见getter在所有BarProp对象上的行为)。

globalThis.open("https://email.example/message/CAOOOkFcWW97r8yg=SsWg7GgCmp4suVX9o85y8BvNRqMjuc5PXg", undefined, "noopener,popup");
window.name [ = value ]

Window/name

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回窗口的名称。

可以设置以更改名称。

window.close()

Window/close

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

关闭窗口。

window.closed

Window/closed

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

如果窗口已关闭,则返回 true,否则返回 false。

window.stop()

Window/stop

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)14+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

取消文档加载。

窗口打开步骤,给定一个字符串url、一个字符串target和一个字符串features,如下:

  1. 如果事件循环终止嵌套级别不为零,则返回 null。

  2. sourceDocument成为入口全局对象关联Document

  3. 如果target是空字符串,则将target设置为"_blank"。

  4. tokenizedFeatures成为标记化features的结果。

  5. noopenernoreferrer为 false。

  6. 如果tokenizedFeatures["noopener"]存在,则:

    1. noopener设置为解析tokenizedFeatures["noopener"]作为布尔特性的结果。

    2. 移除tokenizedFeatures["noopener"]。

  7. 如果tokenizedFeatures["noreferrer"]存在,则:

    1. noreferrer设置为解析tokenizedFeatures["noreferrer"]作为布尔特性的结果。

    2. 移除tokenizedFeatures["noreferrer"]。

  8. referrerPolicy为空字符串。

  9. 如果noreferrer为 true,则将noopener设置为 true,并将referrerPolicy设置为"no-referrer"。

  10. targetNavigablewindowType成为应用选择可导航对象的规则的结果,给定targetsourceDocument节点可导航对象noopener

    如果有一个用户代理支持按住 Ctrl 键点击链接以在新标签页中打开它,并且用户按住 Ctrl 键点击一个元素,其onclick处理程序使用window.open()API在iframe元素中打开页面,则用户代理可以覆盖目标浏览上下文的选择以改为目标新标签页。

  11. 如果targetNavigable为 null,则返回 null。

  12. 如果windowType为"new and unrestricted"或"new with no opener",则:

    1. targetNavigable活动浏览上下文是弹出窗口设置为检查是否请求弹出窗口的结果,给定tokenizedFeatures

    2. 设置浏览上下文功能,给targetNavigable活动浏览上下文,给定tokenizedFeatures[CSSOMVIEW]

    3. urlRecord成为about:blankURL 记录

    4. 如果url不是空字符串,则将urlRecord设置为编码解析 URL的结果,给定url,相对于入口设置对象

    5. 如果urlRecord失败,则抛出一个"SyntaxError"DOMException

    6. 如果urlRecordabout:blank匹配,则执行URL 和历史记录更新步骤,给定targetNavigable活动文档urlRecord

      这是必要的,以防url类似于about:blank?foo。如果url只是普通的about:blank,这将不会有任何作用。

    7. 否则,导航targetNavigableurlRecord,使用sourceDocument,设置referrerPolicyreferrerPolicy,并设置exceptionsEnabled为 true。

  13. 否则:

    1. 如果url不是空字符串,则:

      1. urlRecord成为编码解析 URL的结果,给定url,相对于入口设置对象

      2. 如果urlRecord失败,则抛出一个"SyntaxError"DOMException

      3. 导航targetNavigableurlRecord,使用sourceDocument,设置referrerPolicyreferrerPolicy,并设置exceptionsEnabled为 true。

    2. 如果noopener为 false,则将targetNavigable活动浏览上下文开启者浏览上下文设置为sourceDocument浏览上下文

  14. 如果noopener为 true 或windowType为"new with no opener",则返回 null。

  15. 返回targetNavigable活动WindowProxy

open(url, target, features)方法步骤是运行窗口打开步骤,给定urltargetfeatures

该方法提供了一个机制用于导航现有的浏览上下文或打开并导航一个辅助浏览上下文


标记化features参数

  1. tokenizedFeatures成为一个新的有序映射

  2. position指向features的第一个代码点。

  3. position没有超出features的末尾时:

    1. name为空字符串。

    2. value为空字符串。

    3. 收集一系列代码点,它们是features中的特性分隔符,给定position。这会跳过名称前的前导分隔符。

    4. 收集一系列代码点,它们不是features中的特性分隔符,给定position。将name设置为收集的字符,转换为 ASCII 小写

    5. name设置为规范化特性名称name的结果。

    6. position没有超出features的末尾且featuresposition处的代码点不是 U+003D (=) 时:

      1. 如果featuresposition处的代码点是 U+002C (,) 或不是特性分隔符,则中断

      2. position前进 1。

      这会跳到第一个 U+003D (=),但不会跳过 U+002C (,) 或非分隔符。

    7. 如果featuresposition处的代码点是特性分隔符

      1. position没有超出features的末尾且featuresposition处的代码点是特性分隔符时:

        1. 如果featuresposition处的代码点是 U+002C (,) ,则中断

        2. position前进 1。

        这会跳到第一个非分隔符,但不会跳过 U+002C (,)。

      2. 收集一系列代码点,它们不是特性分隔符的代码点,从features中给定position。将value设置为收集的代码点,转换为 ASCII 小写

    8. 如果name不是空字符串,则将tokenizedFeatures[name]设置为value

  4. 返回tokenizedFeatures

为了检查是否设置了窗口特性,给定tokenizedFeaturesfeatureNamedefaultValue

  1. 如果tokenizedFeatures[featureName]存在,则返回解析tokenizedFeatures[featureName]作为布尔特性的结果。

  2. 返回defaultValue

为了检查是否请求了弹出窗口,给定tokenizedFeatures

  1. 如果tokenizedFeatures空的,则返回 false。

  2. 如果tokenizedFeatures["popup"]存在,则返回解析tokenizedFeatures["popup"]作为布尔特性的结果。

  3. location成为检查是否设置了窗口特性的结果,给定tokenizedFeatures、"location"和 false。

  4. toolbar成为检查是否设置了窗口特性的结果,给定tokenizedFeatures、"toolbar"和 false。

  5. 如果locationtoolbar都为 false,则返回 true。

  6. menubar成为检查是否设置了窗口特性的结果,给定tokenizedFeatures、"menubar"和 false。

  7. 如果menubar为 false,则返回 true。

  8. resizable成为检查是否设置了窗口特性的结果,给定tokenizedFeatures、"resizable"和 true。

  9. 如果resizable为 false,则返回 true。

  10. scrollbars成为检查是否设置了窗口特性的结果,给定tokenizedFeatures、"scrollbars"和 false。

  11. 如果scrollbars为 false,则返回 true。

  12. status成为检查是否设置了窗口特性的结果,给定tokenizedFeatures、"status"和 false。

  13. 如果status为 false,则返回 true。

  14. 返回 false。

一个代码点是特性分隔符,如果它是ASCII 空白、U+003D (=) 或 U+002C (,)。

出于遗留原因,有些特性名称有别名。为了规范化特性名称name,切换name

"screenx"
返回"left"。
"screeny"
返回"top"。
"innerwidth"
返回"width"。
"innerheight"
返回"height"。
其他
返回name

为了解析布尔特性,给定一个字符串value

  1. 如果value为空字符串,则返回 true。

  2. 如果value"yes",则返回 true。

  3. 如果value"true",则返回 true。

  4. parsed成为解析value为整数的规则的结果。

  5. 如果parsed是错误,则将其设置为 0。

  6. 如果parsed为 0,则返回 false,否则返回 true。


name getter 步骤:

  1. 如果thisnavigable为 null,则返回空字符串。

  2. 返回thisnavigable目标名称

name setter 步骤:

  1. 如果thisnavigable为 null,则返回。

  2. thisnavigable活动会话历史条目文档状态导航目标名称设置为给定值。

当导航到另一个来源时,该名称将重置


close()方法步骤:

  1. thisTraversable成为thisnavigable

  2. 如果thisTraversable不是顶级遍历,则返回。

  3. 如果thisTraversable正在关闭为 true,则返回。

  4. browsingContext成为thisTraversable活动浏览上下文

  5. sourceSnapshotParams成为快照源快照参数的结果,给定 thisTraversable活动文档

  6. 如果所有以下条件都为真:

    那么:

    1. thisTraversableis closing 设置为 true。

    2. DOM 操作任务源排队一个任务关闭 thisTraversable

navigable可脚本关闭的,如果其活动浏览上下文是由脚本(而不是用户操作)创建的辅助浏览上下文,或者如果它是一个顶级遍历,其会话历史条目大小为 1。

closed getter 步骤是返回 true,如果this浏览上下文为 null 或其正在关闭为 true;否则返回 false。

stop()方法步骤:

  1. 如果thisnavigable为 null,则返回。

  2. 停止加载thisnavigable

7.2.2.2Window 对象上的索引访问
window.length

Window/length

所有当前引擎均支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回文档树子导航的数量。

window[index]

返回与指定的文档树子导航对应的WindowProxy

length getter 步骤是返回this关联的Document文档树子导航大小

通过WindowProxy对象的[[GetOwnProperty]]内部方法定义对文档树子导航的索引访问。

7.2.2.3Window 对象上的命名访问
window[name]

返回指定的元素或元素集合。

通常情况下,依赖这种方式会导致代码不稳定。随着新功能的添加,哪些ID映射到此API可能会随时间变化。例如,使用document.getElementById()document.querySelector()来代替这种方式。

Window 对象window文档树子导航目标名称属性集 是运行以下步骤的返回值:

  1. childrenwindow文档树子导航

  2. firstNamedChildren为一个空的有序集合

  3. 对于children中的每个navigable

    1. namenavigable目标名称

    2. 如果name为空字符串,则继续

    3. 如果firstNamedChildren包含一个navigable,其目标名称name,则继续

    4. navigable添加到firstNamedChildren

  4. names为一个空的有序集合

  5. 对于firstNamedChildren中的每个navigable

    1. namenavigable目标名称

    2. 如果navigable活动文档来源window相关设置对象来源相同,则name添加到names

  6. 返回names

以下例子中,假设https://elsewhere.example/设置window.name 为“spices”,当一切加载完毕后,评估window.spices将会得到undefined:

<iframe src=https://elsewhere.example.com/></iframe>
<iframe name=spices></iframe>

Window 对象支持命名属性Window 对象window支持的属性名称在任何时候由以下内容组成,按提供它们的元素的树顺序排列,忽略后来的重复项:

确定命名属性nameWindow对象window中的值,用户代理必须返回以下步骤中获得的值:

  1. objectswindow中具有名称name命名对象列表。

    至少会有一个这样的对象,因为否则算法不会被Web IDL调用

  2. 如果objects包含一个navigable,则:

    1. containerwindow关联Document后代中第一个其内容导航objects中的导航容器

    2. 返回container内容导航活动WindowProxy

  3. 否则,如果objects只有一个元素,则返回该元素。

  4. 否则,返回一个HTMLCollection,其根为window关联Document,其过滤器仅匹配window中具有名称name命名对象。(根据定义,这些都将是元素。)

Window对象window命名对象,就上述算法而言,包括以下内容:

由于Window接口具有[Global]扩展属性,其命名属性遵循命名属性对象的规则,而不是传统平台对象的规则。

window.top

Window/top

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回顶级可遍历对象WindowProxy

window.opener [ = value ]

Window/opener

所有当前引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

返回opener 浏览上下文WindowProxy

如果没有,或者已被设置为 null,则返回 null。

可以设置为 null。

window.parent

Window/parent

所有当前引擎都支持。

Firefox1+Safari1.3+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

返回父导航对象WindowProxy

window.frameElement

Window/frameElement

所有当前引擎都支持。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回可导航容器元素。

如果没有,或者在跨域情况下,则返回 null。

top获取步骤如下:

  1. 如果可导航对象为 null,则返回 null。

  2. 返回可导航对象顶级可遍历对象活动WindowProxy

opener获取步骤如下:

  1. current浏览上下文

  2. 如果current为 null,则返回 null。

  3. 如果currentopener 浏览上下文为 null,则返回 null。

  4. 返回currentopener 浏览上下文WindowProxy对象。

opener设置步骤如下:

  1. 如果给定值为 null,并且浏览上下文不为 null,则将浏览上下文opener 浏览上下文设置为 null。

  2. 如果给定值不为 null,则执行DefinePropertyOrThrow(,"opener",{ [[Value]]: 给定值,[[Writable]]: true,[[Enumerable]]: true,[[Configurable]]: true })。

window.opener设置为 null 会清除opener 浏览上下文引用。实际上,这将阻止未来的脚本访问其opener 浏览上下文Window对象。

默认情况下,脚本可以通过window.openergetter 访问其opener 浏览上下文Window对象。例如,脚本可以设置window.opener.location,使opener 浏览上下文进行导航。

parent获取步骤如下:

  1. navigable可导航对象

  2. 如果navigable为 null,则返回 null。

  3. 如果navigable父对象不为 null,则将navigable设置为navigable父对象

  4. 返回navigable活动WindowProxy

frameElement获取步骤如下:

  1. current节点可导航对象

  2. 如果current为 null,则返回 null。

  3. containercurrent容器

  4. 如果container为 null,则返回 null。

  5. 如果container节点文档来源当前设置对象来源不为同源域,则返回 null。

  6. 返回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>

element从文档中移除时,iframeWindow对应的浏览上下文置空

7.2.2.5 历史浏览器界面元素 API

由于历史原因,Window接口具有一些表示某些网络浏览器界面元素可见性的属性。

出于隐私和互操作性的原因,这些属性现在返回的值表示Window浏览上下文是否为弹出窗口属性是 true 还是 false。

每个界面元素由一个BarProp对象表示:

BarProp

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android?
[Exposed=Window]
interface BarProp {
  readonly attribute boolean visible;
};
window.locationbar.visible

Window/locationbar

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android?
window.menubar.visible

Window/menubar

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android?
window.personalbar.visible

Window/personalbar

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android?
window.scrollbars.visible

Window/scrollbars

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
window.statusbar.visible

Window/statusbar

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android?
window.toolbar.visible

Window/toolbar

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android?

如果Window不是弹出窗口,则返回true;否则返回false。

BarProp/visible

所有当前引擎均支持。

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android?

visible获取器步骤为:

  1. browsingContextthis相关全局对象浏览上下文

  2. 如果browsingContext为 null,则返回 true。

  3. 返回browsingContext顶级浏览上下文是否为弹出窗口的否定。

每个BarProp对象必须存在于每个Window对象中:

地址栏BarProp对象
历史上表示包含显示浏览器地址栏控制的用户界面元素。
菜单栏BarProp对象
历史上表示包含以菜单形式列出的命令或类似界面概念的用户界面元素。
个人栏BarProp对象
历史上表示包含用户最喜欢页面链接或类似界面概念的用户界面元素。
滚动条BarProp对象
历史上表示包含滚动机制或类似界面概念的用户界面元素。
状态栏BarProp对象
历史上表示在文档下方或后方找到的用户界面元素,通常提供有关正在进行的网络活动或用户指示设备当前指示元素的信息。
工具栏BarProp对象
历史上表示在文档上方或前方找到的用户界面元素,通常提供会话历史遍历控件(后退和前进按钮、重新加载按钮等)。

locationbar属性必须返回地址栏BarProp对象

menubar属性必须返回菜单栏BarProp对象

personalbar属性必须返回个人栏BarProp对象

scrollbars属性必须返回滚动条BarProp对象

statusbar属性必须返回状态栏BarProp对象

toolbar属性必须返回工具栏BarProp对象


由于历史原因,status属性在Window对象上,获取时必须返回最后设置的字符串,设置时必须将其设置为新值。当创建Window对象时,属性必须设置为空字符串。它不执行任何其他操作。

7.2.2.6 Window对象的脚本设置

设置窗口环境设置对象,给定一个URL creationURL,一个JavaScript执行上下文 execution context,null或一个环境 reservedEnvironment,一个URL topLevelCreationURL,和一个来源 topLevelOrigin,请执行以下步骤:

  1. realmexecution context的Realm组件的值。

  2. windowrealm全局对象

  3. settings object为一个新的环境设置对象,其算法定义如下:

    realm执行上下文

    返回execution context

    模块映射

    返回window关联Document模块映射

    API基础URL

    返回window关联Document的当前基础URL

    来源

    返回window关联Document来源

    策略容器

    返回window关联Document策略容器

    跨来源隔离能力

    如果以下两者都成立,则返回true,否则返回false:

    时间起源

    返回window关联Document加载时间信息导航开始时间

  4. 如果reservedEnvironment为非null,则:

    1. settings objectid设置为reservedEnvironmentid目标浏览上下文设置为reservedEnvironment目标浏览上下文活跃的服务worker设置为reservedEnvironment活跃的服务worker

    2. reservedEnvironmentid设置为空字符串。

      保留 环境的身份被认为已完全转移到创建的环境设置对象。从这一点起,保留的环境不再可以通过环境的id进行搜索。

  5. 否则,将settings objectid设置为一个新的唯一不透明字符串,将settings object目标浏览上下文设置为null,并将settings object活跃的服务worker设置为null。

  6. settings object创建URL设置为creationURLsettings object顶级创建URL设置为topLevelCreationURLsettings object顶级来源设置为topLevelOrigin

  7. realm的[[HostDefined]]字段设置为settings object

7.2.3 WindowProxy 特殊对象

WindowProxy 是一个包装了Window普通对象的特殊对象,通过间接方式将大多数操作传递给被包装的对象。每个浏览上下文都有一个关联的WindowProxy对象。当浏览上下文导航时,与该浏览上下文关联的Window对象会发生变化。

WindowProxy特殊对象必须使用普通的内部方法,除非明确指定了其他方式。

WindowProxy没有接口对象

每个WindowProxy对象都有一个[[Window]]内部槽,表示被包装的Window对象。

尽管WindowProxy被命名为“代理”,它并没有像真正的代理那样在其目标的内部方法上进行多态分派,这是为了在WindowProxyLocation对象之间重用机制。只要Window对象仍然是一个普通对象,这种方式是不可观察的,可以实现任意一种。

7.2.3.1 [[GetPrototypeOf]] ( )
  1. W成为[[Window]]内部槽的值。

  2. 如果IsPlatformObjectSameOrigin(W)为真,则返回!OrdinaryGetPrototypeOf(W)。

  3. 返回null。

7.2.3.2 [[SetPrototypeOf]] ( V )
  1. 返回!SetImmutablePrototype(this, V)。

7.2.3.3 [[IsExtensible]] ( )
  1. 返回true。

7.2.3.4 [[PreventExtensions]] ( )
  1. 返回false。

7.2.3.5 [[GetOwnProperty]] ( P )
  1. W成为[[Window]]内部槽的值。

  2. 如果P是一个数组索引属性名,则:

    1. index成为!ToUint32(P)。

    2. children成为W关联Document文档树子导航项

    3. value为undefined。

    4. 如果index小于children大小,则:

      1. 按升序排序children,如果navigableA容器navigableB容器更早插入到W关联Document中,则navigableA小于navigableB

      2. value设置为children[index]的活动WindowProxy

    5. 如果value是undefined,则:

      1. 如果IsPlatformObjectSameOrigin(W)为真,则返回undefined。

      2. 抛出一个"SecurityError"DOMException

    6. 返回PropertyDescriptor{ [[Value]]: value, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: true }。

  3. 如果IsPlatformObjectSameOrigin(W)为真,则返回!OrdinaryGetOwnProperty(W, P)。

    这是JavaScript规范的基本内部方法的不变性故意违反,以保持与现有网络内容的兼容性。详情见tc39/ecma262 issue #672[JAVASCRIPT]

  4. property成为CrossOriginGetOwnPropertyHelper(W, P)。

  5. 如果property不是undefined,则返回property

  6. 如果property是undefined,并且PW文档树子导航目标名称属性集合中,则:

    1. value成为W中名为P命名对象活动WindowProxy

    2. 返回PropertyDescriptor{ [[Value]]: value, [[Enumerable]]: false, [[Writable]]: false, [[Configurable]]: true }。

      属性描述符为不可枚举的原因是为了与现有网络内容兼容,尽管这与同源行为不匹配。详情见issue #3183

  7. 返回?CrossOriginPropertyFallback(P)。

7.2.3.6 [[DefineOwnProperty]] ( P, Desc )
  1. W 成为 this[[Window]] 内部槽的值。

  2. 如果 IsPlatformObjectSameOrigin(W) 为真,则:

    1. 如果 P 是一个 数组索引属性名,返回 false。

    2. 返回 ? OrdinaryDefineOwnProperty(W, P, Desc)。

      这是 JavaScript 规范的 故意违反,以保持与现有网络内容的兼容性。详情见 tc39/ecma262 issue #672[JAVASCRIPT]

  3. 抛出一个 "SecurityError" DOMException

7.2.3.7 [[Get]] ( P, Receiver )
  1. W 成为 this[[Window]] 内部槽的值。

  2. 根据当前全局对象的 当前全局对象浏览上下文W浏览上下文P 以及当前设置对象来检查是否应报告两个浏览上下文之间的访问

  3. 如果 IsPlatformObjectSameOrigin(W) 为真,则返回 ? OrdinaryGet(this, P, Receiver)。

  4. 返回 ? CrossOriginGet(this, P, Receiver)。

this 被传递而不是 W,因为 OrdinaryGetCrossOriginGet 将调用 [[GetOwnProperty]] 内部方法。

7.2.3.8 [[Set]] ( P, V, Receiver )
  1. W 成为 this[[Window]] 内部槽的值。

  2. 根据当前全局对象的 当前全局对象浏览上下文W浏览上下文P 以及当前设置对象来检查是否应报告两个浏览上下文之间的访问

  3. 如果 IsPlatformObjectSameOrigin(W) 为真,则:

    1. 如果 P 是一个 数组索引属性名,则返回 false。

    2. 返回 ? OrdinarySet(W, P, V, Receiver)。

  4. 返回 ? CrossOriginSet(this, P, V, Receiver)。

    this 被传递而不是 W,因为 CrossOriginSet 将调用 [[GetOwnProperty]] 内部方法。

7.2.3.9 [[Delete]] ( P )
  1. W 成为 this[[Window]] 内部槽的值。

  2. 如果 IsPlatformObjectSameOrigin(W) 为真,则:

    1. 如果 P 是一个 数组索引属性名,则:

      1. desc 成为 ! this.[[GetOwnProperty]](P)。

      2. 如果 desc 是 undefined,则返回 true。

      3. 返回 false。

    2. 返回 ? OrdinaryDelete(W, P)。

  3. 抛出一个 "SecurityError" DOMException

7.2.3.10 [[OwnPropertyKeys]] ( )
  1. W 成为 this[[Window]] 内部槽的值。

  2. maxProperties 成为 W关联 Document文档树子导航大小

  3. keys 成为 范围 0 到 maxProperties,不包括 maxProperties

  4. 如果 IsPlatformObjectSameOrigin(W) 为真,则返回 keysOrdinaryOwnPropertyKeys(W) 的连接。

  5. 返回 keys 和 !CrossOriginOwnPropertyKeys(W) 的连接。

7.2.4 Location 接口

Document/location

支持所有当前的引擎。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

Location

支持所有当前的引擎。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

Window/location

支持所有当前的引擎。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

每个 Window 对象都关联着一个唯一的 Location 对象实例,在创建 Window 对象时分配。

Location 异常对象是通过一系列的IDL、创建后调用JavaScript内部方法以及覆盖JavaScript内部方法定义的。由于其具有严格的安全策略,在实现这个对象时请特别小心。

要创建一个 Location 对象,请执行以下步骤:

  1. location 成为一个新的 Location 平台对象

  2. valueOf 成为 location相关领域.[[Intrinsics]].[[%Object.prototype.valueOf%]]。

  3. 执行 ! location.[[DefineOwnProperty]]("valueOf", { [[Value]]: valueOf, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })。

  4. 执行 ! location.[[DefineOwnProperty]](%Symbol.toPrimitive%, { [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })。

  5. [[DefaultProperties]] 内部槽的值设置为 location.[[OwnPropertyKeys]]()。

  6. 返回 location

添加 valueOf%Symbol.toPrimitive% 自有数据属性,以及所有 Location 的 IDL 属性都标记为 [LegacyUnforgeable],这是因为遗留代码会查阅 Location 接口,或将其字符串化,以确定 文档 URL,然后以安全敏感的方式使用它。特别是,valueOf%Symbol.toPrimitive%[LegacyUnforgeable] 字符串化防护措施确保了诸如 foo[location] = barlocation + "" 之类的代码不会被误导。

document.location [ = value ]
window.location [ = value ]

返回具有当前页面位置的 Location 对象。

可设置,以导航到另一个页面。

Document 对象的 location 获取步骤是返回 this相关全局对象Location 对象,如果 this完全活动的,否则为 null。

Window 对象的 location 获取步骤是返回 thisLocation 对象。

Location 对象提供其关联的 DocumentURL 的表示,以及 导航重新加载 关联的 可导航对象 的方法。

[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/href

所有当前的引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

Location/toString

所有当前的引擎都支持。

Firefox22+Safari1+Chrome52+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回 Location 对象的 URL。

可以设置,以导航到指定的 URL。

location.origin

Location/origin

所有当前的引擎都支持。

Firefox21+Safari5.1+Chrome8+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS?Chrome Android?WebView Android3+Samsung Internet?Opera Android?

返回 Location 对象的 URL 的来源。

location.protocol

Location/protocol

所有当前的引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer3+
Firefox Android?Safari iOS ?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 Location 对象的 URL 的方案。

可以设置,以导航到相同 URL 并更改方案。

location.host

Location/host

所有当前的引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 Location 对象的 URL 的主机和端口(如果与方案的默认端口不同)。

可以设置,以导航到相同 URL 并更改主机和端口。

location.hostname

Location/hostname

所有当前的引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 Location 对象的 URL 的主机。

可以设置,以导航到相同 URL 并更改主机。

location.port

Location/port

所有当前的引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 Location 对象的 URL 的端口。

可以设置,以导航到相同 URL 并更改端口。

location.pathname

Location/pathname

所有当前的引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 Location 对象的 URL 的路径。

可以设置,以导航到相同 URL 并更改路径。

location.search

Location/search

所有当前的引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 Location 对象的 URL 查询字符串(如果非空,包含前导的 "?")。

可以设置,以导航到相同 URL 并更改查询字符串(忽略前导的 "?")。

location.hash

Location/hash

所有当前的引擎都支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 Location 对象的 URL 片段(如果非空,包含前导的 "#")。

可以设置,以导航到相同 URL 并更改片段(忽略前导的 "#")。

location.assign(url)

Location/assign

所有当前的引擎都支持。

Firefox1+Safari3+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

导航到指定的 URL。

location.replace(url)

Location/replace

所有当前的引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

从会话历史中删除当前页面并导航到指定的 URL。

location.reload()

Location/reload

所有当前的引擎都支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

重新加载当前页面。

location.ancestorOrigins

Location/ancestorOrigins

Firefox不支持Safari6+Chrome20+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回一个 DOMStringList 对象,列出 祖先导航活动文档的来源。

A Location 对象有一个关联的相关Document,它是其相关全局对象浏览上下文活动文档,如果此Location对象的相关全局对象浏览上下文非空,否则为null。

A Location 对象有一个关联的url,它是此Location对象的相关DocumentURL,如果此Location对象的相关Document非空,否则为about:blank

A Location 对象有一个关联的祖先来源列表。当创建Location对象时,其祖先来源列表必须设置为一个DOMStringList对象,其关联列表是以下步骤生成的字符串列表:

  1. output为一个新的列表

  2. currentLocation对象的相关Document

  3. current容器文档非空时:

    1. current设置为current容器文档

    2. 附加current来源的序列化output

  4. 返回output

Location-对象导航location到一个URL url,可选地给定一个NavigationHistoryBehavior historyHandling(默认 "auto"):

  1. navigablelocation相关全局对象可导航对象

  2. sourceDocumentLocation对象的Document

  3. 如果location的相关Document尚未完全加载,并且sourceDocument没有暂时激活,则将historyHandling设置为"replace"。

  4. 导航navigableurl,使用sourceDocument,并将historyHandling设置为historyHandling

以下是href的getter步骤:

  1. 如果Location对象的相关Document非空且其origin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  2. 返回Location对象的url,序列化。

以下是href的setter步骤:

  1. 如果Location对象的相关Document为null,则返回。

  2. url为给定值的URL解析结果,相对于入口设置对象。

  3. 如果url解析失败,则抛出一个SyntaxError DOMException

  4. 导航Location对象到url

href的setter故意没有安全检查。

以下是 origin 的getter步骤:

  1. 如果Location对象的相关Document非空且其origin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  2. 返回Location对象的urlorigin的序列化结果。

以下是protocol的getter步骤:

  1. 如果Location对象的相关Document非空且其origin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  2. 返回Location对象的urlscheme,后跟":"。

以下是protocol的setter步骤:

  1. 如果Location对象的相关Document为null,则返回。

  2. 如果Location对象的相关Documentorigin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  3. copyURLLocation对象的url的副本。

  4. possibleFailure为基本URL解析给定值加上":",使用copyURL作为URL,并使用方案开始状态作为状态重写。

    由于URL解析器忽略多个连续的冒号,提供值"https:"(甚至"https::::")与提供值"https"相同。

  5. 如果possibleFailure解析失败,则抛出一个SyntaxError DOMException

  6. 如果copyURL的方案不是HTTP(S)方案,则终止这些步骤。

  7. 导航Location对象到copyURL

以下是host的getter步骤:

  1. 如果Location对象的相关Document非空且其origin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  2. urlLocation对象的url

  3. 如果url的主机为null,则返回空字符串。

  4. 如果url的端口为null,则返回url的主机,序列化。

  5. 返回url的主机,序列化,后跟":"和url的端口,序列化。

以下是host的setter步骤:

  1. 如果Location对象的相关Document为null,则返回。

  2. 如果Location对象的相关Documentorigin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  3. copyURLLocation对象的url的副本。

  4. 如果copyURL有一个不透明路径,则返回。

  5. 基本URL解析给定值,使用copyURL作为URL,并使用主机状态作为状态重写。

  6. 导航Location对象到copyURL

以下是hostname的getter步骤:

  1. 如果Location对象的相关Document非空且其origin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  2. 如果Location对象的url的主机为null,则返回空字符串。

  3. 返回Location对象的url的主机,序列化。

以下是hostname的setter步骤:

  1. 如果Location对象的相关Document为null,则返回。

  2. 如果Location对象的相关Documentorigin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  3. copyURLLocation对象的url的副本。

  4. 如果copyURL有一个不透明路径,则返回。

  5. 基本URL解析给定值,使用copyURL作为URL,并使用主机名状态作为状态重写。

  6. 导航Location对象到copyURL

以下是port的getter步骤:

  1. 如果Location对象的相关Document非空且其origin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOM Exception

  2. 如果Location对象的url的端口为null,则返回空字符串。

  3. 返回Location对象的url的端口,序列化。

以下是port的setter步骤:

  1. 如果Location对象的相关Document为null,则返回。

  2. 如果Location对象的相关Documentorigin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  3. copyURLLocation对象的url的副本。

  4. 如果copyURL不能具有用户名/密码/端口,则返回。

  5. 如果给定值为空字符串,则将copyURL的端口设置为null。

  6. 否则,基本URL解析给定值,使用copyURL作为URL,并使用端口状态作为状态重写。

  7. 导航Location对象到copyURL

以下是pathname的getter步骤:

  1. 如果Location对象的相关Document非空且其origin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  2. 返回URL路径序列化Location对象的url的结果。

以下是pathname的setter步骤:

  1. 如果Location对象的相关Document为null,则返回。

  2. 如果Location对象的相关Documentorigin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  3. copyURLLocation对象的url的副本。

  4. 如果copyURL有一个不透明路径,则返回。

  5. copyURL的路径设置为空列表。

  6. 基本URL解析给定值,使用copyURL作为URL,并使用路径开始状态作为状态重写。

  7. 导航Location对象到copyURL

以下是search的getter步骤:

  1. 如果Location对象的相关Document非空且其origin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  2. 如果Location对象的url的查询为null或空字符串,则返回空字符串。

  3. 返回"?",后跟Location对象的url的查询。

以下是search的setter步骤:

  1. 如果Location对象的相关Document为null,则返回。

  2. 如果Location对象的相关Documentorigin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  3. copyURLLocation对象的url的副本。

  4. 如果给定值为空字符串,将copyURL的查询设置为null。

  5. 否则,执行以下子步骤:

    1. input为给定值,移除单个前导"?",如果有的话。

    2. copyURL的查询设置为空字符串。

    3. 基本URL解析input,使用null,相关Document的字符编码,copyURL作为URL,并使用查询状态作为状态重写。

  6. 导航Location对象到copyURL

以下是hash的getter步骤:

  1. 如果Location对象的相关Document非空且其origin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  2. 如果Location对象的url的片段为null或空字符串,则返回空字符串。

  3. 返回"#",后跟Location对象的url的片段。

以下是hash的setter步骤:

  1. 如果Location对象的相关Document为null,则返回。

  2. 如果Location对象的相关Documentorigin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  3. copyURLLocation对象 的url的副本。

  4. input为给定值,移除单个前导"#",如果有的话。

  5. copyURL的片段设置为空字符串。

  6. 基本URL解析input,使用copyURL作为URL,并使用片段状态作为状态重写。

  7. 如果copyURL的片段是Location对象的url的片段,则返回。

    此提前返回是为了兼容已部署的内容,后者冗余设置location.hash以进行滚动。它不适用于其他片段导航机制,如location.href的setter或location.assign()

  8. 导航Location对象到copyURL

a元素和area元素的等效API不同,hash的setter不会特殊处理空字符串,以保持与已部署脚本的兼容性。


以下是assign(url)方法步骤:

  1. 如果Location对象的相关Document为null,则返回。

  2. 如果Location对象的相关Documentorigin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  3. urlRecord为URL解析给定url的结果,相对于入口设置对象。

  4. 如果urlRecord解析失败,则抛出一个SyntaxError DOMException

  5. 导航Location对象到urlRecord

以下是replace(url)方法步骤:

  1. 如果Location对象的相关Document为null,则返回。

  2. urlRecord为URL解析给定url的结果,相对于入口设置对象。

  3. 如果urlRecord解析失败,则抛出一个SyntaxError DOMException

  4. 导航Location对象到urlRecord,给定"replace"。

replace()方法故意没有安全检查。

以下是reload()方法步骤:

  1. documentLocation对象的相关Document

  2. 如果document为null,则返回。

  3. 如果documentorigin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  4. 重新加载document的节点可导航对象。


以下是ancestorOrigins的getter步骤:

  1. 如果Location对象的相关Document为null,则返回一个空列表。

  2. 如果Location对象的相关Documentorigin与入口设置对象的origin不具有相同的来源域,则抛出一个SecurityError DOMException

  3. 否则,返回Location对象的祖先来源列表。

关于ancestorOrigins属性如何工作的详细信息仍有争议,可能会改变。更多信息请参见问题#1918


如前所述,Location奇异对象出于安全目的需要额外的逻辑。Location对象必须使用普通的内部方法,除非另有明确规定。

此外,每个Location对象都有一个表示其创建时属性的[[DefaultProperties]]内部槽。

7.2.4.1 [[GetPrototypeOf]] ( )
  1. 如果IsPlatformObjectSameOrigin(this)为true,则返回OrdinaryGetPrototypeOf(this)

  2. 返回null。

7.2.4.2 [[SetPrototypeOf]] ( V )
  1. 返回SetImmutablePrototype(this, V)

7.2.4.3 [[IsExtensible]] ( )
  1. 返回true。

7.2.4.4 [[PreventExtensions]] ( )
  1. 返回false。

7.2.4.5 [[GetOwnProperty]] ( P )
  1. 如果IsPlatformObjectSameOrigin(this)为true,则:

    1. descOrdinaryGetOwnProperty(this, P)

    2. 如果this[[DefaultProperties]]内部槽包含P,则将desc[[Configurable]]设置为true。

    3. 返回desc

  2. propertyCrossOriginGetOwnPropertyHelper(this, P)

  3. 如果property不为undefined,则返回property

  4. 返回CrossOriginPropertyFallback(P)

7.2.4.6 [[DefineOwnProperty]] ( P, Desc )
  1. 如果IsPlatformObjectSameOrigin(this)为true,则:

    1. 如果this[[DefaultProperties]]内部槽包含P,则返回false。

    2. 返回OrdinaryDefineOwnProperty(this, P, Desc)

  2. 抛出一个SecurityError DOMException

7.2.4.7 [[Get]] ( P, Receiver )
  1. 如果IsPlatformObjectSameOrigin(this)为true,则返回OrdinaryGet(this, P, Receiver)

  2. 返回CrossOriginGet(this, P, Receiver)

7.2.4.8 [[Set]] ( P, V, Receiver )
  1. 如果IsPlatformObjectSameOrigin(this)为true,则返回OrdinarySet(this, P, V, Receiver)

  2. 返回CrossOriginSet(this, P, V, Receiver)

7.2.4.9 [[Delete]] ( P )
  1. 如果IsPlatformObjectSameOrigin(this)为true,则返回OrdinaryDelete(this, P)

  2. 抛出一个SecurityError DOMException

7.2.4.10 [[OwnPropertyKeys]] ( )
  1. 如果IsPlatformObjectSameOrigin(this)为true,则返回OrdinaryOwnPropertyKeys(this)

  2. 返回CrossOriginOwnPropertyKeys(this)

7.2.5 History 接口

History

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

Window/history

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
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/length

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回当前 可遍历的可导航对象的 会话历史条目的数量。

history.scrollRestoration

History/scrollRestoration

所有当前引擎支持。

Firefox46+Safari11+Chrome46+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回 活动会话历史条目滚动恢复模式

history.scrollRestoration = value

活动会话历史条目滚动恢复模式 设置为 value

history.state

History/state

所有当前引擎支持。

Firefox4+Safari6+Chrome19+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回 活动会话历史条目经典历史 API 状态,反序列化为 JavaScript 值。

history.go()

重新加载当前页面。

history.go(delta)

History/go

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

在当前 可遍历的可导航对象的 会话历史条目列表中向前或向后移动指定的步数。

零步将重新加载当前页面。

如果步数超出范围,则不执行任何操作。

history.back()

History/back

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

在当前 可遍历的可导航对象的 会话历史条目列表中向后移动一步。

如果没有前一页,则不执行任何操作。

history.forward()

History/forward

所有当前引擎支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

在当前 可遍历的可导航对象的 会话历史条目列表中向前移动一步。

如果没有下一页,则不执行任何操作。

history.pushState(data, "")

History/pushState

所有当前引擎支持。

Firefox4+Safari5+Chrome5+
Opera11.5+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android11.5+

将一个新条目添加到会话历史中,其 经典历史 API 状态设置为 data 的序列化。活动历史条目URL 将被复制并用作新条目的 URL。

(第二个参数存在是为了历史原因,不能省略;传递空字符串是传统做法。)

history.pushState(data, "", url)

将一个新条目添加到会话历史中,其 经典历史 API 状态设置为 data 的序列化,并将其 URL 设置为 url

如果当前 Document 无法将其 URL 重写url,将抛出 "SecurityError" DOMException

(第二个参数存在是为了历史原因,不能省略;传递空字符串是传统做法。)

history.replaceState(data, "")

History/replaceState

所有当前引擎支持。

Firefox4+Safari5+Chrome5+
Opera11.5+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android11.5+

活动会话历史条目经典历史 API 状态 更新为 data 的结构化克隆。

(第二个参数存在是为了历史原因,不能省略;传递空字符串是传统做法。)

history.replaceState(data, "", url)

活动会话历史条目经典历史 API 状态 更新为 data 的结构化克隆,并将其 URL 更新为 url

如果当前 Document 无法将其 URL 重写url,将抛出 "SecurityError" DOMException

(第二个参数存在是为了历史原因,不能省略;传递空字符串是传统做法。)

Document 有一个 history 对象,一个 History 对象。

history 获取器步骤是返回 this相关 Documenthistory 对象


每个 History 对象都有 state,初始值为 null。

每个 History 对象都有一个 length,一个非负整数,初始值为 0。

每个 History 对象都有一个 index,一个非负整数,初始值为 0。

虽然 index 没有直接暴露,但可以从同步导航期间 length 的变化中推断出来。事实上,这就是它的用途。

length 获取器步骤是:

  1. 如果 this相关全局对象相关 Document 不是 完全活跃,则抛出一个 "SecurityError" DOMException

  2. 返回 thislength

scrollRestoration 获取器步骤是:

  1. 如果 this相关全局对象相关 Document 不是 完全活跃,则抛出一个 "SecurityError" DOMException

  2. 返回 this节点可导航活跃会话历史条目滚动恢复模式

scrollRestoration 设置器步骤是:

  1. 如果 this相关全局对象相关 Document 不是 完全活跃,则抛出一个 "SecurityError" DOMException

  2. this节点可导航活跃会话历史条目滚动恢复模式 设置为给定值。

state 获取器步骤是:

  1. 如果 this相关全局对象相关 Document 不是 完全活跃,则抛出一个 "SecurityError" DOMException

  2. 返回 thisstate

go(delta) 方法步骤是根据给定的 delta delta traverse this

back() 方法步骤是根据给定的 -1 delta traverse this

forward() 方法步骤是根据给定的 +1 delta traverse this

根据一个给定整数 deltadelta traverse 一个 History 对象 history

  1. documenthistory相关全局对象相关 Document

  2. 如果 document 不是 完全活跃,则抛出一个 "SecurityError" DOMException

  3. 如果 delta 是 0,则 重新加载 document节点可导航,并返回。

  4. 根据 document节点可导航可遍历导航deltasourceDocument 设置为 document遍历历史

pushState(data, unused, url) 方法步骤是根据 thisdataurl 和 "push" 运行 共享历史推/替换状态步骤

replaceState(data, unused, url) 方法步骤是根据 thisdataurl 和 "replace" 运行 共享历史推/替换状态步骤

共享历史推/替换状态步骤,根据 History history,一个值 data,一个 标量值字符串 或 null 的 url,以及一个 历史处理行为 historyHandling

  1. documenthistory 的相关 Document

  2. 如果 document 不是 完全活跃,则抛出一个 "SecurityError" DOMException

  3. 可选地,返回。(例如,用户代理可能会禁止调用这些方法,这些方法是在定时器上调用的,或者从未在响应明确的用户操作触发的事件侦听器中调用,或者以 快速连续调用的方式调用的。)

  4. serializedDataStructuredSerializeForStorage(data) 的结果。重新抛出任何异常。

  5. newURLdocumentURL

  6. 如果 url 不是 null 或空字符串,则:

    1. newURL 设置为根据 编码解析一个 URL 给定 url,相对于 historyrelevant settings object

    2. 如果 newURL 是失败,则抛出一个 "SecurityError" DOMException

    3. 如果 document 不能将其 URL 重写newURL,则抛出一个 "SecurityError" DOMException

    这里的空字符串特殊情况是历史性的,并导致在比较诸如 location.href = ""(它对空字符串执行 URL 解析)与 history.pushState(null, "", "")(它绕过它)时产生不同的结果 URL。

  7. navigationhistory相关全局对象导航 API

  8. continuenavigation 上触发一个推/替换/重新加载 navigate 事件 的结果,navigationType 设置为 historyHandlingisSameDocument 设置为 true,destinationURL 设置为 newURLclassicHistoryAPIState 设置为 serializedData

  9. 如果 continue 是 false,则返回。

  10. 根据 URL 和历史更新步骤,给定 documentnewURL 运行步骤,serializedData 设置为 serializedDatahistoryHandling 设置为 historyHandling

用户代理可以限制每页添加到会话历史的状态对象数量。如果一个页面达到 实现定义的限制,用户代理必须在添加新条目后立即删除会话历史中该 Document 对象的第一个条目。(因此状态历史作为一个先进先出缓冲区用于逐出,但作为一个后进先出缓冲区用于导航。)

一个 Document document 可以将其 URL 重写 为一个 URL targetURL,如果以下算法返回 true:

  1. documentURL成为documentURL

  2. 如果targetURLdocumentURLschemeusernamepasswordhostport 组件上有所不同,则返回 false。

  3. 如果targetURLschemeHTTP(S) scheme,则返回 true。

    对于http:https:的 URL,路径查询片段的差异是允许的。

  4. 如果targetURLscheme是 "file",则:

    1. 如果targetURLdocumentURL路径组件上有所不同,则返回 false。

    2. 返回 true。

    对于file: URL,查询片段的差异是允许的。

  5. 如果targetURLdocumentURL路径组件或查询组件上有所不同,则 返回 false。

    对于其他类型的 URL,只有片段的差异是允许的。

  6. 返回 true。

documentURL 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

请注意,只有 DocumentURL 是重要的,而不是它的 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 应用为中心的方式来管理导航和历史记录条目。它是经典 locationhistory 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 实例,除了这里显示的 urlindex 属性外,还具有其他有用的属性。请注意,该数组仅包含表示当前 navigableNavigationHistoryEntry 对象,因此其内容不受 navigable containers 内的导航影响,例如 iframe,或在导航 API 本身在 iframe 中使用的情况下不受 parent navigable 的导航影响。此外,它仅包含表示相同 originsession history entriesNavigationHistoryEntry 对象,这意味着如果用户在当前来源之前或之后访问了其他来源,将不会有相应的 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() 阻止他们进行导航后不久再次尝试进行导航时。

NavigateEventintercept() 方法允许拦截导航并将其转换为同文档导航:

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;
[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当前条目 是运行以下步骤的结果:

  1. 如果 navigation 禁用了条目和事件,则返回 null。

  2. 断言navigation当前条目索引 不是 -1。

  3. 返回 navigation条目列表[navigation当前条目索引]。

如果以下步骤返回 true,则一个 Navigation navigation 禁用了条目和事件

  1. document 成为 navigation相关全局对象关联的 Document

  2. 如果 document 不是 完全活动,则返回 true。

  3. 如果 document初始 about:blank 是 true,则返回 true。

  4. 如果 document来源不透明的,则返回 true。

  5. 返回 false。

要获取 会话历史条目 sheNavigation navigation 中的 导航 API 条目索引

  1. index 设为 0。

  2. 对于 navigation条目列表中的每个 nhe

    1. 如果 nhe会话历史条目 等于 she,则返回 index

    2. index 增加 1。

  3. 返回 -1。


导航 API 中使用的一个关键类型是 NavigationType 枚举:

enum NavigationType {
 "push",
 "replace",
 "reload",
 "traverse"
};

这捕获了主要的 web 开发者可见的“导航”类型,这些类型(如在其他地方所述)并不完全对应于本标准的单一导航算法。每个值的含义如下:

"push"
对应于调用导航时,历史处理行为最终为"push",或调用history.pushState()
"replace"
对应于调用导航时,历史处理行为最终为"replace",或调用history.replaceState()
"reload"
对应于调用重新加载
"traverse"
对应于调用通过增量遍历历史

NavigationType 枚举的值空间是规范内部 历史处理行为 类型的值空间的超集。本标准的几个部分利用了这种重叠,通过将 历史处理行为 传递给期望 NavigationType 的算法。

7.2.6.4 初始化和更新条目列表

根据给定的Navigation navigation列表的新会话历史条目 newSHEs会话历史条目 initialSHE初始化新文档的导航 API 条目

  1. 断言navigation条目列表为空

  2. 断言navigation当前条目索引为-1。

  3. 如果navigation已禁用条目和事件,则返回。

  4. 对于每个newSHE中的newSHEs

    1. newNHE成为在navigation相关领域中创建的新的 NavigationHistoryEntry

    2. newNHE会话历史条目设置为newSHE

    3. 追加 newNHEnavigation条目列表

    newSHEs最初将来自获取导航 API 的会话历史条目,因此每个newSHE都将与initialSHE相同同源

  5. navigation当前条目索引设置为在navigation获取导航 API 条目索引initialSHE的结果。

根据给定的Navigation navigation列表的新会话历史条目 newSHEs会话历史条目 reactivatedSHE更新重新激活的导航 API 条目

  1. 如果navigation已禁用条目和事件,则返回。

  2. newNHEs成为一个新的空列表

  3. oldNHEs成为navigation条目列表克隆

  4. 对于每个newSHE中的newSHEs

    1. newNHE为null。

    2. 如果oldNHEs包含一个NavigationHistoryEntry matchingOldNHE,其会话历史条目newSHE,则:

      1. newNHE设置为matchingOldNHE

      2. oldNHEs中删除matchingOldNHE

    3. 否则:

      1. newNHE设置为在navigation相关领域中创建的新的 NavigationHistoryEntry

      2. newNHE会话历史条目设置为newSHE

    4. 追加 newNHEnewNHEs

    newSHEs最初将来自获取导航 API 的会话历史条目,因此每个newSHE都将与reactivatedSHE相同同源

    在此循环结束时,oldNHEs中剩余的所有NavigationHistoryEntry表示在bfcacheDocument时已被处理的会话历史条目

  5. navigation条目列表设置为newNHEs

  6. navigation当前条目索引设置为在navigation获取导航 API 条目索引reactivatedSHE的结果。

  7. navigation相关全局对象上给定的导航和遍历任务源上排队一个全局任务以运行以下步骤:

    1. 对于 oldNHEs中的每个disposedNHE

      1. 触发一个名为dispose的事件在disposedNHE上。

    我们通过一个任务延迟这些步骤,以确保dispose事件将在pageshow事件之后触发。这确保pageshow是页面在重新激活时收到的第一个事件。

    (但是,本算法的其余部分在pageshow事件触发之前运行。这确保navigation.entries()navigation.currentEntry将在任何pageshow事件处理程序期间具有正确更新的值。)

根据给定的Navigation navigation会话历史条目 destinationSHENavigationType navigationType更新同一文档导航的导航 API 条目

  1. 如果navigation已禁用条目和事件,则返回。

  2. oldCurrentNHE成为navigation当前条目

  3. disposedNHEs成为一个新的空列表

  4. 如果navigationType是"traverse",则:

    1. navigation当前条目索引设置为在navigation获取导航 API 条目索引destinationSHE的结果。

    2. 断言navigation当前条目索引不是-1。

    此算法仅针对同一文档遍历调用。跨文档遍历将改为调用初始化新文档的导航 API 条目更新重新激活的导航 API 条目

  5. 否则,如果navigationType是"push",则:

    1. navigation当前条目索引设置为navigation当前条目索引 + 1。

    2. i成为navigation当前条目索引

    3. i < navigation条目列表大小时:

      1. 追加 navigation条目列表[i]到disposedNHEs

      2. i设置为i + 1。

    4. navigation条目列表中删除disposedNHEs中的所有项。

  6. 否则,如果navigationType是"replace",则:

    1. 追加 oldCurrentNHEdisposedNHEs

  7. 如果navigationType是"push"或"replace",则:

    1. newNHE成为在navigation相关领域中创建的新的 NavigationHistoryEntry

    2. newNHE会话历史条目设置为destinationSHE

    3. navigation条目列表[navigation当前条目索引]设置为newNHE

  8. 如果navigation正在进行的API方法跟踪器不为null,则通知关于提交的条目给定navigation正在进行的API方法跟踪器navigation当前条目

    重要的是在触发disposecurrententrychange事件之前执行此操作,因为事件处理程序可能会启动另一个导航,或以其他方式更改navigation正在进行的API方法跟踪器的值。

  9. 准备运行脚本给定navigation相关设置对象

    请参阅其他导航API事件的讨论以了解我们这样做的原因。

  10. 触发一个名为currententrychange的事件在navigation上,使用NavigationCurrentEntryChangeEvent,其navigationType属性初始化为navigationType,其from初始化为oldCurrentNHE

  11. 对于 disposedNHEs中的每个disposedNHE

    1. 触发一个名为dispose的事件在disposedNHE上。

  12. navigation相关设置对象上运行脚本后清理。

在实现中,同一文档导航可能会导致会话历史条目通过从会话历史条目列表的末尾掉下来而被处理。这还未由上述算法(或本标准的任何其他部分)处理。请参阅问题 #8620以跟踪定义此类情况下正确行为的进展。

7.2.6.5 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

NavigationHistoryEntrynavigation.entries() 中的索引,或如果该条目不在导航历史条目列表中,则为 −1。

entry.sameDocument

指示此导航历史条目是否与当前的 Document 相同。例如,当条目表示片段导航或单页应用导航时,此值将为 true。

entry.getState()

返回存储在此条目中的状态的 反序列化结果,该状态是使用 navigation.navigate()navigation.updateCurrentEntry() 添加到条目中的。此状态在重新加载和会话恢复时保留。

请注意,除非状态值是原始类型,否则通常情况下 entry.getState() !== entry.getState(),因为每次都会返回一个新的反序列化结果。

此状态与经典历史 API 的 history.state 无关。

每个 NavigationHistoryEntry 都有一个关联的 会话历史条目,这是一个 会话历史条目

NavigationHistoryEntry nhekey 是通过以下算法的返回值给出的:

  1. 如果 nhe相关全局对象关联的 Document 不是 完全激活的,则返回空字符串。

  2. 返回 nhe会话历史条目导航 API key

NavigationHistoryEntry nheID 是通过以下算法的返回值给出的:

  1. 如果 nhe相关全局对象关联的 Document 不是 完全激活的,则返回空字符串。

  2. 返回 nhe会话历史条目导航 API ID

NavigationHistoryEntry nheindex 是通过以下算法的返回值给出的:

  1. 如果 nhe相关全局对象关联的 Document 不是 完全激活的,则返回 -1。

  2. 返回获取导航API条目索引的结果,其中this会话历史条目位于this相关全局对象导航API中。

url getter 的步骤为:

  1. document 成为 相关全局对象关联的 Document

  2. 如果 document 不是 完全激活的,则返回空字符串。

  3. she 成为 会话历史条目

  4. 如果 shedocument 不等于 document,并且 shedocument staterequest referrer policy 是 "no-referrer" 或 "origin",则返回 null。

  5. 返回 sheURL序列化

key getter 的步骤是返回 key

id getter 的步骤是返回 ID

index getter 的步骤是返回 index

sameDocument getter 的步骤是:

  1. document 成为 相关全局对象关联的 Document

  2. 如果 document 不是 完全激活的,则返回 false。

  3. 如果 会话历史条目document 等于 document,则返回 true,否则返回 false。

getState() 方法的步骤是:

  1. 如果 相关全局对象关联的 Document 不是 完全激活的,则返回 undefined。

  2. 返回 StructuredDeserialize(会话历史条目导航 API 状态)。重新抛出任何异常。

    这在理论上可能会抛出异常,例如尝试反序列化一个大 ArrayBuffer 时,如果没有足够的内存。

以下是 事件处理程序(及其对应的 事件处理程序事件类型),所有实现 NavigationHistoryEntry 接口的对象都必须支持这些事件处理程序,作为 事件处理程序 IDL 属性

事件处理程序 事件处理程序事件类型
ondispose dispose
7.2.6.6 历史条目列表
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() 方法步骤如下:

  1. 如果 this 已禁用条目和事件,则返回空列表。

  2. 返回 this条目列表

    请注意,由于 Web IDL 的序列类型转换规则,每次调用都会创建一个新的 JavaScript 数组对象。即 navigation.entries() !== navigation.entries()

The currentEntry getter 步骤是返回 当前条目

The updateCurrentEntry(options) 方法步骤如下:

  1. current当前条目

  2. 如果 current 为 null,则抛出 "InvalidStateError" DOMException

  3. serializedStateStructuredSerializeForStorage(options["state"]), 重抛任何异常。

  4. 设置 current会话历史条目导航 API 状态serializedState

  5. 触发名为 currententrychange 的事件, 使用 NavigationCurrentEntryChangeEvent, 其 navigationType 属性 初始化为 null,其 from 初始化为 current

The canGoBack getter 步骤如下:

  1. 如果 this 已禁用条目和事件,则返回 false。

  2. 断言: this当前条目索引 不为 -1。

  3. 如果 this当前条目索引 为 0,则返回 false。

  4. 返回 true。

The canGoForward getter 步骤如下:

  1. 如果 this 已禁用条目和事件,则返回 false。

  2. 断言: this当前条目索引 不为 -1。

  3. 如果 this当前条目索引 等于 this条目列表大小 - 1,则返回 false。

  4. 返回 true。

{ committed, finished } = navigation.navigate(url)
{ committed, finished } = navigation.navigate(url, options)

导航 当前页面到给定的 urloptions可以包含以下值:

默认情况下,这将执行完整导航(即跨文档导航,除非给定的URL仅在 片段与当前 不同)。可以使用 navigateEvent.intercept() 方法将其转换为同文档导航。

返回的承诺将如下所示:

在所有情况下,当返回的承诺兑现时,将会是 NavigationHistoryEntry 进行导航的条目。

{ committed, finished } = navigation.reload(options)

重新加载 当前页面。options可以包含infostate, 其行为如上所述。

通过使用navigateEvent.intercept() 方法可以覆盖默认执行从网络或缓存重新加载当前页面的行为。这样做将意味着此调用仅更新状态或传递相应的info, 加上执行navigate 事件处理程序认为合适的任何操作。

返回的承诺将如下所示:

{ committed, finished } = navigation.traverseTo(key)
{ committed, finished } = navigation.traverseTo(key, { info })

遍历到最近的 会话历史条目,匹配给定 keyNavigationHistoryEntryinfo 可以设置为任何值; 它将填充相应 info 属性的相应 NavigateEvent

如果到那个 会话历史条目 的遍历已经在 进行中,那么这 将返回该原始遍历的承诺,而 info 将被忽略。

返回的承诺将如下所示:

{ 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) 方法步骤如下:

  1. urlRecord 为在给定 url 的情况下,解析 URL 的结果,相对于 相关设置对象

  2. 如果 urlRecord 是失败,则返回一个 早期错误结果,用于 "SyntaxError" DOMException

  3. document相关全局对象关联 Document

  4. 如果 options["history"] 是 "push", 并且 导航必须是一个替换 给定 urlRecorddocument,则返回一个 早期错误结果 用于 一个 "NotSupportedError" DOMException

  5. stateoptions["state"], 如果它 存在;否则, undefined。

  6. serializedStateStructuredSerializeForStorage(state)。 如果这抛出一个异常,则 返回一个 早期错误结果 用于 该 异常。

    重要的是要提前执行此步骤,因为序列化可以调用Web开发人员代码,这反过来可能会更改我们在后续步骤中检查的各种内容。

  7. 如果 document 不是 完全活动,则返回一个 早期错误结果 用于 一个 "InvalidStateError" DOMException

  8. 如果 document卸载计数器 大于0,则 返回 一个 早期错误结果 用于 一个 "InvalidStateError" DOMException

  9. infooptions["info"], 如果它 存在; 否则,undefined。

  10. apiMethodTracker可能设置即将到来的非遍历API方法跟踪器的结果,给定 给定 infoserializedState

  11. 导航 document节点 可导航urlRecord 使用 document,历史处理设置为 options["history"] 和 navigationAPIState 设置为 serializedState

    location.assign() 和类似方法不同, 它们暴露在 同源域 边界之外, navigation.navigate() 只能由代码访问 具有直接同步访问 window.navigation 属性。因此,我们避免了关于归因于导航源文档的复杂情况,我们不需要处理 允许沙箱导航 检查及其随附的 exceptionsEnabled 标志。我们只是 将所有导航视为来自 Document 对应于此 Navigation 对象本身(即 document)。

  12. 如果 即将到来的非遍历 API 方法跟踪器apiMethodTracker,那么:

    如果 即将到来的非遍历 API 方法跟踪器 仍然是 apiMethodTracker,这意味着 navigate 算法在 到达 内部 navigate 事件 触发算法 之前退出了,该算法会 将即将到来的API方法跟踪器提升为正在进行

    1. 设置 即将到来的 非遍历 API 方法跟踪器 为 null。

    2. 返回一个 早期错误结果 用于 一个 "AbortError" DOMException

  13. 返回一个 导航 API 方法跟踪器派生结果, 用于 apiMethodTracker

reload(options) 方法步骤如下:

  1. document相关全局对象关联 Document

  2. serializedStateStructuredSerializeForStorage(undefined)。

  3. 如果 options["state"] 存在,则设置 serializedStateStructuredSerializeForStorage(options["state"])。 如果这抛出一个异常,则 返回一个 早期错误结果 用于 该 异常。

    重要的是要提前执行此步骤,因为序列化可以调用Web开发人员代码,这反过来可能会更改我们在后续步骤中检查的各种内容。

  4. 否则:

    1. current当前 条目

    2. 如果 current 不是null,则设置 serializedStatecurrent会话历史条目导航API状态

  5. 如果 document 不是 完全活动,则返回一个 早期错误结果 用于 一个 "InvalidStateError" DOMException

  6. 如果 document卸载计数器 大于0,则 返回 一个 早期错误结果 用于 一个 "InvalidStateError" DOMException

  7. infooptions["info"], 如果它 存在; 否则,undefined。

  8. apiMethodTracker可能设置即将到来的非遍历API方法跟踪器的结果,给定 给定 infoserializedState

  9. 重新加载 document节点 可导航,导航API状态设置为 serializedState

  10. 返回一个 导航 API 方法跟踪器派生结果, 用于 apiMethodTracker

traverseTo(key, options) 方法步骤如下:

  1. 如果 当前条目 索引 是 -1,则返回一个 早期 错误结果 用于 "InvalidStateError" DOMException

  2. 如果 条目 列表包含 一个 NavigationHistoryEntry会话 历史条目导航 API 键 等于 key,则返回一个 早期错误结果 用于 一个 "InvalidStateError" DOMException

  3. 返回的结果是 执行导航 API 遍历 给定 keyoptions

back(options) 方法步骤如下:

  1. 如果 当前条目 索引 是 -1 或 0,则返回一个 早期错误结果 用于 一个 "InvalidStateError" DOMException

  2. key条目 列表[当前条目 索引 - 1]'s 会话历史条目导航 API 键

  3. 返回的结果是 执行导航 API 遍历 给定 keyoptions

forward(options) 方法步骤如下:

  1. 如果 当前条目 索引 是 -1 或 等于 条目 列表大小 - 1,则返回一个 早期错误结果 用于 一个 "InvalidStateError" DOMException

  2. key条目 列表[当前条目 索引 + 1]'s 会话历史条目导航 API 键

  3. 返回的结果是 执行导航 API 遍历 给定 keyoptions

执行导航 API 遍历 给定 Navigation navigation、字符串 keyNavigationOptions options

  1. documentnavigation相关全局对象关联 Document

  2. 如果 document 不是 完全活动,则返回一个 早期错误结果 用于 一个 "InvalidStateError" DOMException

  3. 如果 document卸载计数器 大于0,则 返回 一个 早期错误结果 用于 一个 "InvalidStateError" DOMException

  4. current当前条目navigation

  5. 如果 key 等于 current会话历史 条目导航 API 键,则返回 «[ "committed" → 一个 解决的 承诺 current,"finished" → 一个 解决的承诺 current ]»。

  6. 如果 navigation即将到来的遍历 API 方法 跟踪器[key] 存在,则 返回 一个 导航 API 方法跟踪器派生结果 对于 navigation即将到来的遍历 API 方法跟踪器[key]。

  7. infooptions["info"], 如果它 存在; 否则,undefined。

  8. apiMethodTracker添加即将到来的遍历API方法跟踪器的结果, 给定 navigationkeyinfo

  9. navigabledocument节点 可导航

  10. traversablenavigable可遍历的 可导航

  11. sourceSnapshotParams快照源快照参数的结果, 给定 document

  12. 将以下会话历史遍历步骤附加traversable

    1. navigableSHEs获取会话历史条目的结果, 给定 navigable

    2. targetSHE会话历史条目navigableSHEs 中, 其 导航 API 键key。如果不存在这样的条目,则:

      1. 导航和遍历任务源上排队一个全局任务,给定 navigation相关全局对象, 以 拒绝完成的承诺 对于 apiMethodTracker,出现一个 "InvalidStateError" DOMException

      2. 中止这些步骤。

      如果 navigation条目 列表已过时,则 会 走这条路径 相比于 navigableSHEs,在对历史变更做出反应时,所有相关线程和进程正在同步时,可能会出现短暂的时期。

    3. 如果 targetSHEnavigable活动 会话历史条目,那么 中止这些 步骤。

      如果之前 排队 遍历已经将我们带到此 会话历史条目,则可能会发生这种情况。 在这种情况下 先前的遍历已经处理了 apiMethodTracker

    4. result应用遍历历史步骤的结果, 由 targetSHE步骤 给出 traversable,给定 sourceSnapshotParamsnavigable 和 "none"。

    5. 如果 result 是 "canceled-by-beforeunload",则 导航和遍历任务源上排队一个全局任务,给定 navigation相关全局对象拒绝完成的承诺 对于 apiMethodTracker,出现一个新的 "AbortError" DOMException 创建于 navigation相关领域

    6. 如果 result 是 "initiator-disallowed",则 导航和 遍历 任务源上排队一个全局任务,给定 navigation相关全局对象拒绝完成的承诺 对于 apiMethodTracker,出现一个新的 "SecurityError" DOMException 创建于 navigation相关领域

      result 是 "canceled-by-beforeunload" 或 "initiator-disallowed" 时, navigate 事件从未触发,中止正在进行的 导航 将是不正确的;它将导致一个 navigateerror 事件没有一个先前的 navigate 事件。

      在 "canceled-by-navigate" 的情况下,navigate 触发,但是 内部 navigate 事件触发算法 将负责 中止正在进行的 导航

  13. 返回一个 导航 API 方法跟踪器派生结果 对于 apiMethodTracker

早期错误结果 用于一个异常 e 是一个 NavigationResult 字典实例给定 «[ "committed" → 一个 被拒绝的承诺 e,"finished" → 一个 被拒绝的承诺 e ]»。

导航 API 方法跟踪器派生结果 对于 一个 导航 API 方法 跟踪器 是一个 NavigationResult 字典实例给定 «[ "committed" → apiMethodTracker已提交的承诺, "finished" → apiMethodTracker完成的承诺 ]»。

7.2.6.8 正在进行的导航跟踪

在任何给定的导航期间(广义上的导航),Navigation对象需要跟踪以下内容:

对于所有导航
状态 持续时间 解释
NavigateEvent 事件触发期间 这样如果导航在事件触发期间被取消,我们可以取消事件
事件的中止控制器 直到传递给intercept()的处理程序返回的所有承诺都已解决 这样如果导航被取消,我们可以发送中止信号
是否有新的元素被聚焦 直到传递给intercept()的处理程序返回的所有承诺都已解决 这样如果有新的元素被聚焦,焦点不会被重置
被导航到的NavigationHistoryEntry 从确定起,直到传递给intercept()的处理程序返回的所有承诺都已解决 这样我们知道用什么来解决任何committedfinished承诺
任何返回的finished承诺 直到传递给intercept()的处理程序返回的所有承诺都已解决 这样我们可以适当地解决或拒绝它
对于非"traverse"导航
状态 持续时间 解释
任何state 事件触发期间 这样我们可以更新当前条目的导航API状态,如果事件在触发后没有被取消
对于"traverse"导航
状态 持续时间 解释
任何info 直到任务被排队以触发navigate事件 这样我们可以在经过会话历史遍历队列后使用它来触发navigate
任何返回的committed承诺 直到会话历史被更新(在同一任务内) 这样我们可以适当地解决或拒绝它
是否调用了intercept() 直到会话历史被更新(在同一任务内) 这样我们可以抑制正常的滚动恢复逻辑,使用scroll选项给出的行为

我们也不能假设任何给定时间内只有一个导航请求,因为网络开发人员代码可能会这样:

const p1 = navigation.navigate(url1).finished;
const p2 = navigation.navigate(url2).finished;

也就是说,在这种情况下,我们需要确保在导航到url2的同时,我们仍然保留p1的承诺,以便我们可以拒绝它。我们不能 在第二次调用navigate()时立即移除任何正在进行的导航承诺。

我们通过将以下内容与每个Navigation关联来实现这一点:

此处未存储在导航API方法跟踪器中的状态是即使对于不是通过导航API方法启动的导航也需要跟踪的状态。

导航API方法跟踪器是一个结构体,具有以下

所有这些状态然后通过以下算法进行管理。

可能设置即将进行的非遍历API方法跟踪器,给定一个Navigation navigation,一个JavaScript值info,以及一个序列化状态-或-nullserializedState

  1. committedPromisefinishedPromise成为在navigation相关领域中创建的新承诺。

  2. 标记为已处理finishedPromise

    网络开发人员不一定关心finishedPromise被拒绝:

    • 他们可能只关心committedPromise

    • 他们可能在同一个任务内进行多次同步导航,在这种情况下,除最后一次外的所有导航都会被中止(导致其finishedPromise被拒绝)。这可能是应用程序的一个错误,但也可能只是应用程序的不同部分覆盖彼此操作的一个涌现特性。

    • 他们可能更愿意监听其他过渡失败信号而不是finishedPromise,例如navigateerror事件,或者navigation.transition.finished承诺。

    因此,我们将其标记为已处理,以确保它永远不会触发unhandledrejection事件。

  3. apiMethodTracker成为一个新的导航API方法跟踪器,具有:

    导航对象
    navigation
    null
    信息
    info
    序列化状态
    serializedState
    提交到条目
    null
    提交的承诺
    committedPromise
    完成的承诺
    finishedPromise
  4. 断言navigation即将进行的非遍历API方法跟踪器为null。

  5. 如果navigation没有禁用条目和事件,则将navigation即将进行的非遍历API方法跟踪器设置为apiMethodTracker

    如果navigation禁用条目和事件,则committedPromisefinishedPromise将永远不会实现(因为我们从未为这种Document创建一个NavigationHistoryEntry对象,所以我们没有什么可以用来解决它们);没有NavigationHistoryEntry可以应用serializedState;也没有navigate事件可以包含info。因此,我们不需要跟踪这个API方法调用。

  6. 返回apiMethodTracker

添加一个即将进行的遍历API方法跟踪器,给定一个Navigation navigation,一个字符串destinationKey,以及一个JavaScript值info

  1. committedPromisefinishedPromise成为在navigation相关领域中创建的新承诺。

  2. 标记为已处理finishedPromise

    参见前面的讨论关于为什么这样做。

  3. apiMethodTracker成为一个新的导航API方法跟踪器,具有:

    导航对象
    navigation
    destinationKey
    信息
    info
    序列化状态
    null
    提交到条目
    null
    提交的承诺
    committedPromise
    完成的承诺
    finishedPromise
  4. navigation即将进行的遍历API方法跟踪器[key]设置为apiMethodTracker

  5. 返回apiMethodTracker

将即将进行的API方法跟踪器提升为正在进行,给定一个Navigation navigation和一个字符串或nulldestinationKey

  1. 断言navigation正在进行的API方法跟踪器为null。

  2. 如果destinationKey不为null,则:

    1. 断言navigation即将进行的非遍历API方法跟踪器为null。

    2. 如果navigation即将进行的遍历API方法跟踪器[destinationKey] 存在,则:

      1. navigation正在进行的API方法跟踪器设置为navigation即将进行的遍历API方法跟踪器[destinationKey]。

      2. 移除navigation即将进行的遍历API方法跟踪器[destinationKey]。

  3. 否则:

    1. navigation正在进行的API方法跟踪器设置为navigation即将进行的非遍历API方法跟踪器

    2. navigation即将进行的非遍历API方法跟踪器设置为null。

清理一个导航API方法跟踪器 apiMethodTracker

  1. navigation成为apiMethodTracker导航对象

  2. 如果navigation正在进行的API方法跟踪器apiMethodTracker,则将navigation正在进行的API方法跟踪器设置为null。

  3. 否则:

    1. key成为apiMethodTracker

    2. 断言key不为null。

    3. 断言navigation即将进行的遍历API方法跟踪器[key] 存在

    4. 移除navigation即将进行的遍历API方法跟踪器[key]。

通知提交到条目,给定一个导航API方法跟踪器 apiMethodTracker和一个NavigationHistoryEntry nhe

  1. apiMethodTracker提交到条目设置为nhe

  2. 如果apiMethodTracker序列化状态不为null,则将nhe会话历史条目导航API状态设置为apiMethodTracker序列化状态

    如果为null,则我们通过navigation.traverseTo()遍历到nhe,这不允许更改状态。

    在此时,apiMethodTracker序列化状态不再需要。实现可能希望清除它以 避免在导航API方法跟踪器的生命周期内保持它。

  3. nhe解决apiMethodTracker提交的承诺

    在此时,apiMethodTracker提交的承诺仅在尚未返回给作者代码的情况下需要。实现可能希望清除它以避免在导航API方法跟踪器的生命周期内保持它。

解决完成的承诺,对于一个导航API方法跟踪器 apiMethodTracker

  1. 用其提交到条目解决apiMethodTracker提交的承诺

    通常,通知提交到条目先前已经在apiMethodTracker上被调用,因此这将什么都不做。然而,在某些情况下,解决完成的承诺直接被调用,在这种情况下,这一步是必要的。

  2. 用其提交到条目解决apiMethodTracker完成的承诺

  3. 清理apiMethodTracker

拒绝完成的承诺,对于一个导航API方法跟踪器 apiMethodTracker,以及一个JavaScript值exception

  1. exception拒绝apiMethodTracker提交的承诺

    如果apiMethodTracker提交的承诺先前通过通知提交到条目被解决,这将什么都不做。

  2. exception拒绝apiMethodTracker完成的承诺

  3. 清理apiMethodTracker

中止正在进行的导航,给定一个Navigation navigation和一个可选的DOMException error

  1. event成为navigation正在进行的navigate事件

  2. 断言event不为null。

  3. navigation正在进行的导航期间焦点更改设置为false。

  4. navigation正在进行的导航期间抑制正常滚动恢复设置为false。

  5. 如果未给出error,则让error成为在navigation相关领域中创建的新的"AbortError" DOMException

  6. 如果event调度标志已设置,则将event取消标志设置为true。

  7. 发送中止信号event中止控制器,给定error

  8. navigation正在进行的navigate事件设置为null。

  9. errorInfo 成为从 error提取错误信息的结果。

    例如,如果因为调用 window.stop() 达到该算法,那么这些属性可能最终会根据调用 window.stop() 的脚本行初始化。但如果是因为用户点击了停止按钮,这些属性可能最终会使用默认值,如空字符串或0。

  10. 触发一个名为 navigateerror 的事件在 navigation 上,使用 ErrorEvent,并根据 errorInfo 初始化附加属性。

  11. 如果navigation过渡不为null,则:

    1. error拒绝navigation过渡完成的承诺

    2. navigation过渡设置为null。

通知导航API关于中止导航在一个可导航对象 navigable

  1. 如果此算法正在navigable活动窗口相关代理事件循环上运行,则继续执行以下步骤。否则, navigable活动窗口上排队一个全局任务,给定导航和遍历任务源

  2. navigation成为navigable活动窗口导航API

  3. 如果navigation正在进行的navigate事件为null,则返回。

  4. 中止正在进行的导航,给定navigation

通知导航API关于子可导航对象的销毁,给定一个可导航对象 navigable

  1. 通知导航API关于中止导航navigable

  2. navigation成为navigable活动窗口导航API

  3. traversalAPIMethodTrackers成为navigation即将进行的遍历API方法跟踪器克隆

  4. 对于每个 apiMethodTrackertraversalAPIMethodTrackers中:拒绝完成的承诺,对于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,表示任何尚未到达navigatesuccessnavigateerror阶段的正在进行的导航(如果存在);如果没有这样的过渡正在进行,则为null。

由于navigation.currentEntry(以及location.href等其他属性)在导航时立即更新,此navigation.transition属性对于确定这样的导航何时尚未完全解决,根据传递给navigateEvent.intercept()的任何处理程序非常有用。

navigation.transition.navigationType

表示此过渡导航类型的"push","replace","reload"或"traverse"之一。

navigation.transition.from

此过渡来自的NavigationHistoryEntry。这对于与navigation.currentEntry进行比较很有用。

navigation.transition.finished

一个承诺,在navigatesuccess事件触发时实现,或在navigateerror事件触发时被拒绝。

每个Navigation都有一个过渡,这是一个NavigationTransition或null,初始为null。

transition获取步骤是返回this过渡

每个NavigationTransition都有一个关联的导航类型,这是一个NavigationType

每个NavigationTransition都有一个关联的来自条目,这是一个NavigationHistoryEntry

每个NavigationTransition都有一个关联的完成的承诺,这是一个承诺。

navigationType获取步骤是返回this导航类型

from获取步骤是返回this来自条目

finished获取步骤是返回this完成的承诺

[Exposed=Window]
interface NavigationActivation {
  readonly attribute NavigationHistoryEntry? from;
  readonly attribute NavigationHistoryEntry entry;
  readonly attribute NavigationType navigationType;
};
navigation.activation

NavigationActivation,包含最近一次跨文档导航的信息,即“激活”此Document的导航。

虽然navigation.currentEntryDocumentURL可以由于同一文档导航而定期更新,但navigation.activation保持不变,并且其属性仅在Document从历史中重新激活时才会更新。

navigation.activation.entry

NavigationHistoryEntry,等同于navigation.currentEntry属性在Document激活时的值。

navigation.activation.from

一个 NavigationHistoryEntry, 代表了在当前 Document 之前活跃的 Document。 如果前一个 Document 与当前文档不是同源,或是 初始 about:blank Document,那么这个值将为 null。

有些情况下,fromentry NavigationHistoryEntry 对象不适合用作 traverseTo() 方法的目标,因为它们可能不会保留在历史记录中。例如,Document 可以通过 location.replace() 或初始条目被 history.replaceState() 替换来激活。 然而,这些条目的 url 属性和 getState() 方法仍然可以访问。

navigation.activation.navigationType

push”、“replace”、“reload”或“traverse”之一,指示激活此Document的导航类型。

每个Navigation都有一个关联的activation,其值为null或NavigationActivation对象,初始值为null。

每个NavigationActivation具有:

activation获取器步骤是返回thisactivation

from获取器步骤是返回this旧条目

entry获取器步骤是返回this新条目

navigationType获取器步骤是返回this导航类型

7.2.6.10 navigate事件

导航API的一个主要功能是navigate事件。该事件在任何导航(在广义上)上触发,允许Web开发者监控此类外出导航。在许多情况下,该事件是可取消的,这允许防止导航发生。而在其他情况下,可以使用intercept()方法拦截导航并用同一文档导航替换NavigateEvent类。

7.2.6.10.1 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

值为"push"、"replace"、"reload"或"traverse",表示导航的类型。

event.destination

表示导航目标的NavigationDestination对象。

event.canIntercept

如果可以调用intercept()来拦截该导航并将其转换为同一文档导航,替换其通常行为,则为true;否则为false。

一般来说,当当前Document可以将其URL重写为目标URL时,这将为true,除了跨文档"traverse"导航,在这种情况下,它将始终为false。

event.userInitiated

如果此导航是由于用户点击a元素、提交form元素或使用浏览器UI进行导航,则为true;否则为false。

event.hashChange

对于片段导航为true;否则为false。

event.signal

如果导航被取消,例如用户按下浏览器的“停止”按钮或另一个导航中断了此导航,此AbortSignal将被中止。

预期模式是开发者将此信号传递给任何异步操作,如fetch(),作为处理此导航的一部分。

event.formData

如果此导航是代表POST表单提交的"push"或"replace"导航,则表示提交的表单条目的FormData;否则为null。

(特别是,对于重新加载"reload"或重新访问由表单提交创建的会话历史条目的"traverse"导航,这将为null。)

event.downloadRequest

表示是否请求此导航为下载,使用aarea元素的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或辅助技术向用户发出导航完成的信号。此外,还会触发navigatesuccessnavigateerror事件,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",并在事件触发时适当设置。

navigationTypedestinationcanInterceptuserInitiatedhashChangesignalformDatadownloadRequestinfo,以及hasUAVisualTransition属性必须返回其初始化的值。

intercept(options)方法步骤为:

  1. 执行共享检查,给定this

  2. 如果thiscanIntercept属性初始化为false,则抛出一个"SecurityError"DOMException

  3. 如果thisdispatch标志未设置,则抛出一个"InvalidStateError"DOMException

  4. 断言this拦截状态是"none"或"intercepted"。

  5. this拦截状态设置为"intercepted"。

  6. 如果options["handler"]存在,则将其追加this导航处理程序列表

  7. 如果options["focusReset"]存在,则:

    1. 如果this焦点重置行为不为null,并且不等于options["focusReset],则用户代理可以向控制台报告警告,指出之前调用intercept()focusReset选项被新值覆盖,并且之前的值将被忽略。

    2. this焦点重置行为设置为options["focusReset]。

  8. 如果options["scroll"]存在,则:

    1. 如果this滚动行为不为null,并且不等于options["scroll],则用户代理可以向控制台报告警告,指出之前调用intercept()scroll选项被新值覆盖,并且之前的值将被忽略。

    2. this滚动行为设置为options["scroll]。

scroll()方法步骤为:

  1. 执行共享检查,给定this

  2. 如果this拦截状态不是"committed",则抛出一个"InvalidStateError"DOMException

  3. 处理滚动行为,给定this

为了NavigateEvent event 执行共享检查:

  1. 如果event相关全局对象关联的Document不是完全活动,则抛出InvalidStateError DOMException

  2. 如果eventisTrusted属性初始化为false,则抛出SecurityError DOMException

  3. 如果event取消标志已设置,则抛出InvalidStateError DOMException

7.2.6.10.2 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

目标 NavigationHistoryEntrykey 属性的值, 如果这是一个 "traverse" 导航,否则为空字符串。

event.destination.id

目标 NavigationHistoryEntryid 属性的值, 如果这是一个 "traverse" 导航,否则为空字符串。

event.destination.index

目标 NavigationHistoryEntryindex 属性的值, 如果这是一个 "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 步骤是返回 thisURL序列化

key getter 步骤是:

  1. 如果 thisentry 为 null,则返回空字符串。

  2. 返回 thisentrykey

id getter 步骤是:

  1. 如果 thisentry 为 null,则返回空字符串。

  2. 返回 thisentryID

index getter 步骤是:

  1. 如果 thisentry 为 null,则返回 −1。

  2. 返回 thisentryindex

sameDocument getter 步骤是返回 thisis same document

getState() 方法步骤是返回 StructuredDeserialize(thisstate)。

标准的其他部分通过本节中给出的一系列包装算法触发 navigate 事件。

要在给定 会话历史条目 destinationSHE 和一个可选的 用户导航参与 userInvolvement(默认 "none")的情况下在 Navigation navigation触发 traverse navigate 事件

  1. event 成为 创建事件 的结果,给定 NavigateEvent, 在 navigation相关领域 中。

  2. event经典历史 API 状态 设置为 null。

  3. destination 成为 新的 NavigationDestination ,在 navigation相关领域 中创建。

  4. destinationURL 设置为 destinationSHEURL

  5. destinationNHE 成为 NavigationHistoryEntry ,在 navigation条目列表 中,其 会话历史条目destinationSHE,如果不存在这样的 NavigationHistoryEntry, 则为 null。

  6. 如果 destinationNHE 非 null,则:

    1. destinationentry 设置为 destinationNHE

    2. destinationstate 设置为 destinationSHEnavigation API state

  7. 否则,

    1. destinationentry 设置为 null。

    2. destinationstate 设置为 StructuredSerializeForStorage(null)。

  8. destinationis same document 设置为 true,如果 destinationSHEdocument 等于 navigation相关全局对象关联 Document; 否则为 false。

  9. 返回执行 内部 navigate 事件触发算法 的结果,给定 navigation,"traverse", eventdestinationuserInvolvement,null 和 null。

要在给定 NavigationType navigationType、一个 URL destinationURL、一个布尔值 isSameDocument、一个可选的 用户导航参与 userInvolvement (默认 "none")、一个可选的 条目 列表-或-null formDataEntryList(默认 null), 一个 可选的 序列化 状态 navigationAPIState(默认 StructuredSerializeForStorage(null)),以及一个可选的 序列化 状态-或-null classicHistoryAPIState (默认 null)的情况下在 Navigation navigation触发 push/replace/reload navigate 事件

  1. event 成为 创建事件 的结果,给定 NavigateEvent, 在 navigation相关领域 中。

  2. event经典历史 API 状态 设置为 classicHistoryAPIState

  3. destination 成为 新的 NavigationDestination ,在 navigation相关领域 中创建。

  4. destinationURL 设置为 destinationURL

  5. destinationentry 设置为 null。

  6. destinationstate 设置为 navigationAPIState

  7. destinationis same document 设置为 isSameDocument

  8. 返回执行 内部 navigate 事件触发 算法 的结果,给定 navigationnavigationTypeeventdestinationuserInvolvementformDataEntryList 和 null。

要在给定 URL destinationURL、一个 用户导航参与 userInvolvement 和一个字符串 filename 的情况下在 Navigation navigation触发下载请求 navigate 事件

  1. event 成为 创建事件 的结果,给定 NavigateEvent, 在 navigation相关领域 中。

  2. event经典历史 API 状态 设置为 null。

  3. destination 成为 新的 NavigationDestination, 在 navigation相关领域 中创建。

  4. destinationURL 设置为 destinationURL

  5. destinationentry 设置为 null。

  6. destinationstate 设置为 StructuredSerializeForStorage(null)。

  7. destinationis same document 设置为 false。

  8. 返回执行 内部 navigate 事件触发 算法 的结果,给定 navigation,"push", eventdestinationuserInvolvement、null 和 filename

内部 navigate 事件触发算法 包括以下步骤,给定 Navigation navigationNavigationType navigationTypeNavigateEvent eventNavigationDestination destination用户导航参与 userInvolvement、一个 条目 列表-或-null formDataEntryList 和一个字符串或-null downloadRequestFilename

  1. 如果 navigation 禁用条目和事件,则:

    1. 断言navigation正在进行的 API 方法追踪器 为 null。

    2. 断言navigation即将进行的非 traverse API 方法追踪器 为 null。

    3. 断言navigation即将进行的 traverse API 方法追踪器 为空

    4. 返回 true。

    这些断言成立是因为 traverseTo()back()forward() 将在禁用条目和事件时立即失败(因为没有条目可以遍历),如果我们的起点是 navigate()reload(), 那么我们就避免 设置 即将进行的非 traverse API 方法追踪器

  2. destinationKey 设置为 null。

  3. 如果 destinationentry 非 null,则将 destinationKey 设置为 destinationentrykey

  4. 断言destinationKey 不是空字符串。

  5. 给定 navigationdestinationKey将即将进行的 API 方法追踪器提升为正在进行

  6. apiMethodTracker 成为 navigation正在进行的 API 方法追踪器

  7. navigable 成为 navigation相关全局对象可导航对象

  8. document 成为 navigation相关全局对象关联 Document

  9. 如果 document 可以重写其 URLdestinationURL,并且 destinationis same document 为 true 或者 navigationType 不是 "traverse", 则将 eventcanIntercept 初始化为 true。否则,将其初始化为 false。

  10. 如果以下任一条件成立:

    则将 eventcancelable 初始化为 true。否则,将其初始化为 false。

  11. eventtype 初始化为 "navigate"。

  12. eventnavigationType 初始化为 navigationType

  13. eventdestination 初始化为 destination

  14. eventdownloadRequest 初始化为 downloadRequestFilename

  15. 如果 apiMethodTracker 不是 null,则将 eventinfo 初始化为 apiMethodTracker信息。否则,将其初始化为 undefined。

    此时 apiMethodTracker信息 不再需要,可以将其设为 null,而不是保持其在导航 API 方法 追踪器的整个生命周期中存活。

  16. eventhasUAVisualTransition 初始化为 true,如果用户代理显示了document最新 条目的缓存渲染状态。否则,将其初始化为 false。

  17. event中止控制器 设置为 新的 AbortController, 在 navigation相关领域 中创建。

  18. eventsignal 初始化为 event中止控制器 信号

  19. currentURL 设置为 documentURL

  20. 如果以下所有条件都成立:

    则将 eventhashChange 初始化为 true。否则,将其初始化为 false。

    此处的第一个条件意味着 hashChange 对于 片段导航 为 true,但对于 history.pushState(undefined, "", "#fragment") 之类的情况为 false。

  21. 如果 userInvolvement 不是 "none",则将 eventuserInitiated 初始化为 true。否则,将其初始化为 false。

  22. 如果 formDataEntryList 不是 null,则将 eventformData 初始化为 新的 FormData, 在 navigation相关领域 中创建, 与 formDataEntryList 关联。否则,将其初始化为 null。

  23. 断言navigation正在进行的 navigate 事件 为 null。

  24. navigation正在进行的 navigate 事件 设置为 event

  25. navigation在正在进行的导航期间更改焦点 设置为 false。

  26. navigation在正在进行的导航期间抑制正常滚动恢复 设置为 false。

  27. dispatchResult 成为 分发 event 的结果, 在 navigation 上。

  28. 如果 dispatchResult 为 false:

    1. 如果 navigationType 是 "traverse", 则 消耗历史动作用户激活,给定 navigation相关全局对象

    2. 如果 event中止 控制器信号中止,则 中止正在进行的导航, 给定 navigation

    3. 返回 false。

  29. endResultIsSameDocument 为 true,如果 event拦截状态 不是 "none" 或 eventdestinationis same document 为 true。

  30. 准备运行脚本,给定 navigation相关设置 对象

    这样做是为了避免JavaScript 执行上下文栈变为空, 紧接着任何 currententrychange 事件 处理程序运行,作为URL 和历史更新步骤的结果,这些步骤可能很快发生。如果此时栈变为空,则会立即执行微任务检查点, 导致各种 promise 履行处理程序与事件处理程序交错运行,并且在任何传递给 navigateEvent.intercept() 的处理程序之前运行。 这是不理想的, 因为这意味着 promise 处理程序的顺序与 currententrychange 事件处理程序的顺序与 intercept() 处理程序的顺序将取决于导航是发生在空 JavaScript 执行上下文 栈(例如,因为导航是用户发起的)还是在非空栈中(例如,因为导航是由 JavaScript API 调用引起的)。

    通过在此步骤中在栈上插入一个本来不必要的JavaScript 执行上下文, 我们实际上抑制了执行微任务检查点 算法直到以后,从而确保顺序始终是:currententrychange 事件处理程序,然后是 intercept() 处理程序,然后是 promise 处理程序。

  31. 如果 event拦截 状态 不是 "none":

    1. event拦截状态 设置为 "committed"。

    2. fromNHE 成为 当前 条目navigation

    3. 断言fromNHE 不是 null。

    4. navigation过渡 设置为 新的 NavigationTransition, 在 navigation相关领域 中创建,其 导航类型navigationType,其 来自条目fromNHE,其 完成的 promise 是在 navigation相关领域 中创建的一个新 promise。

    5. 标记 为 已处理 navigation过渡完成的 promise

      请参阅有关其他完成的 promise 的讨论 以了解为什么要这样 做。

    6. 如果 navigationType 是 "traverse", 则将 navigation在正在进行的导航期间抑制正常滚动恢复 设置为 true。

      如果 event滚动 行为 设置为 "过渡后", 则滚动 恢复将在 完成 相关 NavigateEvent 时发生。 否则,将不会有滚动恢复。也就是说, 没有通过 intercept() 拦截的导航会经过正常的滚动 恢复过程;此类导航的滚动恢复要么是手动完成的,由 Web 开发人员完成,要么是在过渡后完成的。

    7. 如果 navigationType 是 "push" 或 "replace", 则运行 URL 和历史 更新步骤,给定 documenteventdestinationURLserialiedData 设置为 event经典历史 API 状态,并且 historyHandling 设置为 navigationType

      如果 navigationType 是 "reload", 则我们将 重载 转换为 "同一文档重载",对于此类重载, URL 和历史更新步骤 不适用。 仍然会发生与导航 API 相关的事情,例如更新 活动会话 历史条目导航 API 状态,如果 这是由于调用 navigation.reload() 引起的,以及所有的 正在进行的导航跟踪

      如果 navigationType 是 "traverse", 则此事件触发作为 遍历过程的一部分, 该过程将负责执行适当的会话历史条目更新。

  32. 如果 endResultIsSameDocument 为 true:

    1. promisesList 成为空的 列表

    2. 对于每个 handlerevent导航处理程序列表

      1. 调用 handler 的结果与空 参数列表追加到 promisesList

    3. 如果 promisesList大小 为 0,则将 promisesList 设置为 « 一个以 undefined 解决的 promise »。

      在给定零个 promise 与给定≥1个 promise 时,等待所有安排其成功和失败步骤之间存在细微的时间差异。对于大多数使用 等待所有 的情况, 这并不重要。然而,对于此 API,可能会同时触发许多事件和 promise 处理程序,这种差异很容易观察到:它可能 导致事件/promise 处理程序顺序变化。(涉及的某些事件和 promise 包括:navigatesuccess / navigateerrorcurrententrychangedisposeapiMethodTracker 的 promise,以及 navigation.transition.finished 的 promise。)

    4. 等待所有 promisesList,具有以下成功步骤:

      1. 如果 event相关全局对象完全活跃,则中止这些步骤。

      2. 如果 event中止 控制器信号 中止,则中止这些步骤。

      3. 断言event 等于 navigation正在进行的 navigate 事件

      4. navigation正在进行的 navigate 事件 设置为 null。

      5. 完成 event,给定 true。

      6. 触发事件 命名为 navigatesuccessnavigation 上。

      7. 如果 apiMethodTracker 不是 null,则 解决完成的 promiseapiMethodTracker

      8. 如果 navigation过渡 不是 null,则 解析 navigation过渡完成的 promise 与 undefined。

      9. navigation过渡 设置为 null。

      并且以下失败步骤给定原因 rejectionReason

      1. 如果 event相关全局对象不是完全活动的,则中止这些步骤。

      2. 如果 event中止控制器信号中止的,则中止这些步骤。

      3. 断言event 等于 navigation正在进行的 navigate 事件

      4. navigation正在进行的 navigate 事件 设置为 null。

      5. 完成 event 给定 false。

      6. errorInfo 成为从 rejectionReason提取错误信息的结果。

      7. 触发一个事件,名为 navigateerror,在 navigation 上,使用 ErrorEvent,并根据 errorInfo 初始化附加属性。

      8. 如果 apiMethodTracker 非 null,则使用 rejectionReason拒绝完成的 promiseapiMethodTracker

      9. 如果 navigation过渡不为 null,则使用 rejectionReason 拒绝 navigation过渡完成的 promise

      10. navigation过渡设置为 null。

  33. 否则,如果 apiMethodTracker 不是 null,则 清理 apiMethodTracker

  34. 运行脚本后清理,给定 navigation相关 设置对象

    根据前述说明, 这将停止抑制任何潜在的 promise 处理程序微任务,导致它们在此时或之后运行。

  35. 如果 event拦截 状态 是 "none",则返回 true。

  36. 返回 false。

通过调用navigateEvent.intercept(), Web 开发人员可以抑制同一文档导航的正常滚动和焦点行为, 而是在稍后的时间点调用类似跨文档导航的行为。本节中的算法在这些适当的稍后时间点调用。

完成一个NavigateEvent event,给定一个布尔值 didFulfill

  1. 断言event拦截状态不是 "intercepted" 或 "finished"。

  2. 如果 event拦截 状态 是 "none",则返回。

  3. 可能重置焦点给定 event

  4. 如果 didFulfill 为 true,则 可能处理滚动行为 给定 event

  5. event拦截状态设置为 "finished"。

可能重置焦点给定一个NavigateEvent event

  1. 断言event拦截状态是 "committed" 或 "scrolled"。

  2. navigation 成为 event相关全局对象导航 API

  3. focusChanged 成为 navigation在进行中的导航期间焦点改变

  4. navigation在进行中的导航期间焦点改变设置为 false。

  5. 如果 focusChanged 为 true,则返回。

  6. 如果 event焦点重置 行为是 "manual", 则返回。

    如果它留作 null,那么我们将其视为 "after-transition", 并继续 前进。

  7. document 成为 event相关全局对象关联的Document

  8. focusTarget 成为 document自动聚焦委托

  9. 如果 focusTarget 为 null,则将 focusTarget 设置为 documentbody 元素

  10. 如果 focusTarget 为 null,则将 focusTarget 设置为 documentdocument 元素

  11. 运行 聚焦步骤focusTarget,以及 document视口作为fallback target

  12. 顺序焦点导航起点移动到 focusTarget

可能处理滚动行为给定一个NavigateEvent event

  1. 断言event拦截状态是 "committed" 或 "scrolled"。

  2. 如果 event拦截 状态是 "scrolled",则返回。

  3. 如果 event滚动行为是 "manual", 则返回。

    如果它留作 null,那么我们将其视为 "after-transition", 并继续 前进。

  4. 处理滚动行为给定 event

处理滚动行为给定一个NavigateEvent event

  1. 断言event拦截状态是 "committed"。

  2. event拦截状态设置为 "scrolled"。

  3. 如果 eventnavigationType 初始化为 "traverse" 或 "reload", 则恢复滚动位置数据, 给定 event相关全局对象可导航对象活动会话历史条目

  4. 否则:

    1. document 成为 event相关全局对象关联的 Document

    2. 如果 document指示部分是 null,则 滚动到文档的开头,给定 document[CSSOMVIEW]

    3. 否则,滚动到片段标识符,给定 document

由于其复杂性,NavigateEvent 接口有自己的专门部分

7.2.7.1 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 相同。在这种情况下,事件表明条目的内容已更改,即使我们没有移动到新条目或替换当前条目。

navigationTypefrom 属性必须返回它们初始化时的值。

7.2.7.2 PopStateEvent 接口

PopStateEvent/PopStateEvent

支持所有当前引擎。

Firefox11+Safari6+Chrome16+
Opera?Edge79+
Edge (旧版)14+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

PopStateEvent

支持所有当前引擎。

Firefox4+Safari6+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
[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

PopStateEvent/state

Support in all current engines.

Firefox4+Safari6+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回提供给pushState()replaceState()的信息的副本。

event.hasUAVisualTransition

如果用户代理在分派此事件之前执行了视觉过渡,则返回true。如果为true,最佳用户体验是作者同步更新DOM到导航后的状态。

state属性必须返回它被初始化时的值。它表示事件的上下文信息,如果所代表的状态是文档的初始状态,则为null。

hasUAVisualTransition属性必须返回它被初始化时的值。

7.2.7.3 HashChangeEvent接口

HashChangeEvent/HashChangeEvent

Support in all current engines.

Firefox11+Safari6+Chrome16+
Opera?Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HashChangeEvent

Support in all current engines.

Firefox3.6+Safari5+Chrome8+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+
[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

HashChangeEvent/oldURL

Support in all current engines.

Firefox6+Safari5.1+Chrome8+
Opera12.1+Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回先前为当前的URL会话历史条目

event.newURL

HashChangeEvent/newURL

Support in all current engines.

Firefox6+Safari5.1+Chrome8+
Opera12.1+Edge79+
Edge (旧版)12+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回现在为当前的URL会话历史条目

oldURL属性必须返回它被初始化时的值。它表示事件的上下文信息,特别是从中遍历的会话历史条目的URL。

newURL属性必须返回它被初始化时的值。它表示事件的上下文信息,特别是遍历到的会话历史条目的URL。

7.2.7.4 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

push”、“replace”、“reload”或“traverse”之一,表示即将导致页面交换的导航类型。

event.viewTransition

返回一个ViewTransition对象,该对象表示事件触发时活动的出站跨文档视图转换。如果没有此类转换,则返回null。

activation属性和viewTransition属性必须返回它们被初始化时的值。

7.2.7.5 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属性必须返回它被初始化时的值。

7.2.7.6 PageTransitionEvent 接口

PageTransitionEvent/PageTransitionEvent

Support in all current engines.

Firefox11+Safari6+Chrome16+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

PageTransitionEvent

Support in all current engines.

Firefox1.5+Safari5+Chrome4+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android?
[Exposed=Window]
interface PageTransitionEvent : Event {
  constructor(DOMString type, optional PageTransitionEventInit eventInitDict = {});

  readonly attribute boolean persisted;
};

dictionary PageTransitionEventInit : EventInit {
  boolean persisted = false;
};
event.persisted

PageTransitionEvent/persisted

Support in all current engines.

Firefox11+Safari5+Chrome4+
Opera?Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android?

对于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

cancelablebubbles的值没有意义,因为取消事件无济于事,且不可能超过窗口对象冒泡。它们被设置为true是出于历史原因。

7.2.7.7 BeforeUnloadEvent 接口

BeforeUnloadEvent

Support in all current engines.

Firefox1.5+Safari7+Chrome30+
Opera?Edge79+
Edge (旧版)?Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet3.0+Opera Android?
[Exposed=Window]
interface BeforeUnloadEvent : Event {
  attribute DOMString returnValue;
};

没有BeforeUnloadEvent特定的初始化方法。

BeforeUnloadEvent接口是一个遗留接口,它不仅允许通过取消事件来控制检查是否取消卸载,还可以通过将returnValue属性设置为空字符串以外的值来控制。作者应该使用preventDefault()方法或其他取消事件的手段,而不是使用returnValue

returnValue属性控制检查是否取消卸载的过程。当事件被创建时,该属性必须被设置为空字符串。在获取时,它必须返回最后设置的值。在设置时,该属性必须被设置为新值。

这个属性是DOMString仅仅是出于历史原因。任何除了空字符串以外的值都会被视为请求用户确认。

7.2.8 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

返回文档的id属性,如果其节点导航容器iframe元素。如果未设置或它不是iframe元素,则此值可以为null。

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对象

  1. notRestoredReasonDetails成为一个在realm中创建的新NotRestoredReasonDetails对象。

  2. notRestoredReasonDetails支持结构设置为backingStruct

  3. 返回notRestoredReasonDetails

未恢复原因详细信息是一个结构,具有以下项目

原因是一个表示页面未能从前进/后退缓存恢复的原因的字符串。该字符串是以下之一:

"fetch"
卸载时,由此文档发起的fetch仍在进行中并被取消,因此页面未处于可存储在前进/后退缓存中的稳定状态。
"navigation-failure"
创建此文档的原始导航出错,因此防止将结果错误文档存储在前进/后退缓存中。
"parser-aborted"
文档从未完成其初始HTML解析,因此防止将未完成的文档存储在前进/后退缓存中。
"websocket"
卸载时,打开的WebSocket连接被关闭,因此页面未处于可存储在前进/后退缓存中的稳定状态。[WEBSOCKETS]
"lock"
卸载时,持有的锁请求被终止,因此页面未处于可存储在前进/后退缓存中的稳定状态。[WEBLOCKS]
"masked"
文档有在跨域iframe中的子元素,并且它们阻止了前进/后退缓存;或者此文档因用户代理特定的原因无法被前进/后退缓存

NotRestoredReasons对象有一个支持结构,一个未恢复原因或null,最初为null。

NotRestoredReasons对象有一个原因数组,一个FrozenArray<NotRestoredReasonDetails>或null,最初为null。

NotRestoredReasons对象有一个子数组,一个FrozenArray<NotRestoredReasons>或null,最初为null。

src的getter步骤是返回this支持结构src

id的getter步骤是返回this支持结构id

name的getter步骤是返回this支持结构name

url的getter步骤是:

  1. 如果this支持结构URL为null,则返回null。

  2. 返回this支持结构URL序列化

reasons的getter步骤是返回this原因数组

children的getter步骤是返回this子数组

给定一个未恢复原因backingStruct和一个领域realm创建一个NotRestoredReasons对象

  1. notRestoredReasons成为一个在realm中创建的新NotRestoredReasons对象。

  2. notRestoredReasons支持结构设置为backingStruct

  3. 如果backingStruct原因为null,则将notRestoredReasons原因数组设置为null。

  4. 否则:

    1. reasonsArray成为一个空的列表

    2. 对于每个reasonbackingStruct原因

      1. 创建一个NotRestoredReasonDetails对象给定reasonrealm,并附加它到reasonsArray

    3. notRestoredReasons原因数组设置为创建一个冻结数组给定reasonsArray的结果。

  5. 如果backingStruct子元素为null,则将notRestoredReasons子数组设置为null。

  6. 否则:

    1. childrenArray成为一个空的列表

    2. 对于每个childbackingStruct子元素

      1. 创建一个NotRestoredReasons对象给定childrealm附加它到childrenArray

    3. notRestoredReasons子数组设置为创建一个冻结数组给定childrenArray的结果。

  7. 返回notRestoredReasons

未恢复原因是一个结构,具有以下项目

Document 的未恢复原因 是其 节点导航活动会话历史条目文档状态未恢复原因,如果 Document节点导航顶级可遍历;否则为 null。

7.3 文档序列的基础设施

该标准包含了几个相关的概念,用于分组文档序列。简要的、非规范性的总结如下:

大部分标准使用navigables语言工作,但某些API暴露了browsing context切换的存在,因此标准的某些部分需要以browsing contexts的形式工作。

navigable通过其活动会话历史条目向用户展示一个Document。每个navigable具有:

当前会话历史条目活动会话历史条目通常是相同的,但在以下情况下它们会不同步:


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):

  1. 断言documentState文档非null。

  2. entry成为一个新的会话历史条目,具有

    URL
    documentState文档URL
    文档状态
    documentState

    调用此算法的负责初始化entry步骤;它将保持为"pending",直到完成。

  3. 设置navigable当前会话历史条目entry

  4. 设置navigable活动会话历史条目entry

  5. 设置navigableparent

7.3.1.1 可遍历的可导航对象

可遍历的navigable是一个navigable,它还控制自身及其子navigables会话历史条目应该是当前会话历史条目活动会话历史条目

除了navigable的属性外,可遍历的navigable还具有:

要获取navigable inputNavigable可遍历的navigable

  1. navigable设为inputNavigable

  2. navigable不是一个可遍历的navigable时,将navigable设为navigable

  3. 返回navigable

7.3.1.2 顶级可遍历对象

顶级可遍历对象是一个可遍历的navigable,其父级为空。

目前,所有可遍历的navigable都是顶级可遍历对象。未来的提案设想引入非顶级的可遍历对象。

用户代理持有一个顶级可遍历对象集(一个包含顶级可遍历对象集合)。这些通常以浏览器窗口或浏览器标签页的形式呈现给用户。

获取navigable inputNavigable顶级可遍历对象的方法:

  1. navigable设为inputNavigable

  2. navigable父级不为空时,将navigable设为navigable父级

  3. 返回navigable

给定一个浏览上下文(可为空)opener、一个字符串targetName和一个可选的navigable openerNavigableForWebDriver创建一个新的顶级可遍历对象的方法:

  1. document为空。

  2. 如果opener为空,则将document设为创建一个新的顶级浏览上下文和文档的第二个返回值。

  3. 否则,将document设为创建一个新的辅助浏览上下文和文档的第二个返回值,给定opener

  4. documentState为一个新的文档状态,包含以下内容:

    文档
    document
    发起者来源
    如果opener为空,则为null;否则为document来源
    来源
    document来源
    navigable目标名称
    targetName
    about基础URL
    documentabout基础URL
  5. traversable为一个新的可遍历的navigable

  6. 初始化navigable traversable给定documentState

  7. initialHistoryEntrytraversable活动会话历史条目

  8. initialHistoryEntry步骤设为0。

  9. 附加 initialHistoryEntrytraversable会话历史条目

  10. 如果opener非空,则传统克隆一个可遍历的存储棚,给定opener顶级可遍历对象traversable[STORAGE]

  11. 附加 traversable到用户代理的顶级可遍历对象集

  12. 调用WebDriver BiDi navigable created,传入traversableopenerNavigableForWebDriver

  13. 返回traversable

给定一个URL initialNavigationURL和一个可选的POST资源(可为空)initialNavigationPostResource(默认值为空),创建一个新的顶级可遍历对象的方法:

  1. traversable设为创建一个新的顶级可遍历对象的结果,给定null和空字符串。

  2. 导航 traversableinitialNavigationURL,使用traversable活动文档,其中documentResource设为initialNavigationPostResource

    我们将这些初始导航视为traversable自己导航,这将确保所有相关的安全检查通过。

  3. 返回traversable

7.3.1.3 子导航元素

某些元素(例如,iframe元素)可以向用户展示导航元素。这些元素被称为导航容器

每个导航容器都有一个内容导航元素,它可以是一个导航元素或null。初始值为null。

一个导航元素navigable容器是其navigable导航容器,或null(如果没有这样的元素)。

一个导航元素navigable容器文档是通过执行以下步骤得到的结果:

  1. 如果navigable容器为null,则返回null。

  2. 返回navigable容器节点文档

    这等同于navigable容器包含影子的根,因为navigable容器必须是连接的

一个文档document容器文档是通过执行以下步骤得到的结果:

  1. 如果document节点导航元素为null,则返回null。

  2. 返回document节点导航元素容器文档

一个导航元素navigable是另一个导航元素potentialParent子导航元素,当navigable父级potentialParent时。我们也可以简单地说一个导航元素“是一个子导航元素”,这意味着它的父级非null。

所有子导航元素都是其容器内容导航元素

一个导航容器container内容文档是通过执行以下步骤得到的结果:

  1. 如果container内容导航元素为null,则返回null。

  2. documentcontainer内容导航元素活动文档

  3. 如果document起源container节点文档起源同源域,则返回null。

  4. 返回document

一个导航容器container内容窗口是通过执行以下步骤得到的结果:

  1. 如果container内容导航元素为null,则返回null。

  2. 返回container内容导航元素活动WindowProxy的对象。


创建一个新的子导航元素,给定一个元素element

  1. parentNavigableelement节点导航元素

  2. groupelement节点文档浏览上下文顶级浏览上下文

  3. browsingContextdocument为执行创建新的浏览上下文和文档的结果,给定element节点文档elementgroup

  4. targetName为null。

  5. 如果element有一个name内容属性,则将targetName设置为该属性的值。

  6. documentState为一个新的文档状态,其中

    document
    document
    initiator origin
    document起源
    origin
    document起源
    navigable target name
    targetName
    about base URL
    documentabout base URL
  7. navigable为一个新的导航元素

  8. 初始化导航元素navigable,给定documentStateparentNavigable

  9. element内容导航元素设置为navigable

  10. historyEntrynavigable活动会话历史条目

  11. traversableparentNavigable可遍历导航元素

  12. 将以下会话历史遍历步骤追加到traversable中:

    1. parentDocStateparentNavigable活动会话历史条目文档状态

    2. parentNavigableEntries获取的parentNavigable的会话历史条目结果。

    3. targetStepSHEparentNavigableEntries中第一个会话历史条目,其文档状态等于parentDocState

    4. historyEntry步骤设置为targetStepSHE步骤

    5. nestedHistory为一个新的嵌套历史,其idnavigableid条目列表为«historyEntry»。

    6. nestedHistory追加到parentDocState嵌套历史中。

    7. 更新导航元素创建/销毁,给定traversable

  13. 调用WebDriver BiDi导航元素创建,传入traversable

7.3.1.4 Jake 图表

一种用于可视化文档序列的方法,特别是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 图表描述了以下事件序列:

  1. 一个顶层 traversable被创建,起始 URL 为/t-a,两个子 navigables分别起始于/i-0-a/i-1-a

  2. 第一个子 navigable 被导航到另一个文档,URL 为/i-0-b

  3. 第二个子 navigable 被导航到另一个文档,URL 为/i-1-b

  4. 顶层 traversable 被导航相同的文档,其 URL 更新为/t-a#foo

  5. 顶层 traversable 被导航到另一个文档,URL 为/t-b。(请注意,这个文档当然不会携带旧文档的子 navigables。)

  6. traversable 被通过 delta 进行遍历,delta 为 -3,返回到步骤 1。

Jake 图表是可视化多个 navigables、导航和遍历交互的强大工具。它们无法捕捉所有可能的交互 —— 例如,它们仅适用于单层嵌套 —— 但我们将在本标准中使用它们来说明几个复杂的情况。

Jake 图表以其创造者 Jake Archibald 的名字命名。

在本标准的算法中,经常需要查看从给定文档开始的navigables集合。 本节包含了一组整理的算法来收集这些 navigables。

这些算法的返回值是有序的,父元素出现在子元素之前。调用者依赖于这种顺序。

文档而不是navigable开始通常更好,因为它能让调用者意识到他们是否从完全活跃文档开始。虽然非完全活跃文档确实有祖先和后代 navigables,但它们通常表现得好像没有(例如,在window.parent获取器中)。

文档document祖先 navigables按以下步骤给出:

  1. navigabledocument节点 navigable父元素

  2. ancestors为一个空列表。

  3. navigable不为 null 时:

    1. navigable添加到ancestors的开头。

    2. navigable设置为navigable父元素

  4. 返回ancestors

文档document包括自身在内的祖先 navigables按以下步骤给出:

  1. navigablesdocument祖先 navigables

  2. document节点 navigable添加到navigables的末尾。

  3. 返回navigables

文档document后代 navigables按以下步骤给出:

  1. navigables为一个新列表

  2. navigableContainers为一个列表,包含document的所有包含影子 DOM 的后代,它们是navigable 容器,按包含影子 DOM 的树顺序排序。

  3. 对于navigableContainers中的每个navigableContainer

    1. 如果navigableContainer内容 navigable为 null,则继续。

    2. 扩展navigables,包括navigableContainer内容 navigable活跃文档包括自身在内的后代 navigables

  4. 返回navigables

文档document包括自身在内的后代 navigables按以下步骤给出:

  1. navigables为« document节点 navigable »。

  2. 扩展navigables,包括document后代 navigables

  3. 返回navigables

这些后代收集算法描述的是查看后代文档对象的 DOM 树。实际上,这通常不可行,因为 DOM 树可能在调用算法的进程之外。因此,实施通常在跨进程间复制适当的树。

文档document文档树子 navigables按以下步骤给出:

  1. 如果document节点 navigable为 null,则返回空列表。

  2. navigables为一个新列表

  3. navigableContainers为一个列表,包含document的所有后代,它们是navigable 容器,按树顺序排序。

  4. 对于navigableContainers中的每个navigableContainer

    1. 如果navigableContainer内容 navigable为 null,则继续

    2. navigableContainer内容 navigable添加到navigables的末尾。

  5. 返回navigables

7.3.1.6 Navigable 销毁

销毁子 navigable,给定一个navigable 容器 container

  1. navigablecontainer内容 navigable

  2. 如果navigable为 null,则返回。

  3. container内容 navigable设置为 null。

  4. 在给定navigable的情况下,通知导航 API 关于子 navigable 销毁的情况

  5. 给定navigable活跃文档销毁文档及其后代

  6. parentDocStatecontainer节点 navigable活跃会话历史条目文档状态

  7. parentDocState嵌套历史移除嵌套历史,其ID等于navigableID

  8. traversablecontainer节点 navigable可遍历 navigable

  9. 将以下会话历史遍历步骤附加到traversable

    1. 给定traversable更新 navigable 的创建/销毁

  10. 调用WebDriver BiDi navigable 销毁,传入navigable

销毁顶级 traversable,给定一个顶级 traversabletraversable

  1. browsingContexttraversable活跃浏览上下文

  2. 对于traversable会话历史条目中的每个historyEntry,按什么顺序?:

    1. documenthistoryEntry文档

    2. 如果document不为 null,则给定document销毁文档及其后代

  3. 移除 browsingContext

  4. 从用户界面中移除traversable(例如,在标签浏览器中关闭或隐藏其标签)。

  5. 从用户代理的顶级 traversable 集合移除traversable

  6. 调用WebDriver BiDi navigable 销毁,传入traversable

用户代理可以随时销毁顶级 traversable(通常在响应用户请求时)。

关闭顶级 traversabletraversable

  1. 如果traversable正在关闭为 true,则返回。

  2. toUnloadtraversable活跃文档包括自身在内的后代 navigables

  3. 如果对于toUnload检查卸载是否被取消结果为 true,则返回。

  4. 将以下会话历史遍历步骤附加到traversable

    1. afterAllUnloads为一个算法步骤,该步骤销毁traversable

    2. 给定traversable活跃文档、null 和afterAllUnloads卸载文档及其后代

可导航对象可以被赋予目标名称,这些字符串允许某些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如下:

  1. chosen为null。

  2. windowType为“existing or none”。

  3. sandboxingFlagSetcurrentNavigable活动文档活动沙盒标志集

  4. 如果name是空字符串或ASCII大小写不敏感匹配“_self”,则将chosen设置为currentNavigable

  5. 否则,如果name是ASCII大小写不敏感匹配“_parent”,则将chosen设置为currentNavigable父级,如果有的话,否则为currentNavigable

  6. 否则,如果name是ASCII大小写不敏感匹配“_top”,则将chosen设置为currentNavigable可遍历对象

  7. 否则,如果name不是ASCII大小写不敏感匹配“_blank”,存在一个可导航对象,其目标名称与name相同,currentNavigable活动浏览上下文与该可导航对象的活动浏览上下文相熟,且用户代理确定这两个浏览上下文之间的关系足够紧密,可以相互访问,则将chosen设置为该可导航对象。如果有多个匹配的可导航对象,用户代理应以某种任意一致的方式选择一个,例如最近打开的,最近关注的或关系更密切的,并将chosen设置为它。

    这将在问题#313中更加具体。

  8. 否则,请求新建一个顶级可遍历对象,其发生情况取决于用户代理的配置和能力——由以下列表中的第一个适用选项的规则确定:

    用户代理可以通知用户已阻止弹出窗口。

    如果sandboxingFlagSet设置了沙盒辅助导航浏览上下文标志

    用户代理可以向开发者控制台报告已阻止弹出窗口。

    如果用户代理已配置在此情况下将创建一个新的顶级可遍历对象
    1. windowType设置为“new and unrestricted”。

    2. currentDocumentcurrentNavigable活动文档

    3. 如果currentDocument打开者策略是“same-origin”或“same-origin-plus-COEP”,且currentDocumentcurrentDocument相关设置对象顶级源不同源,则:

      1. noopener设置为true。

      2. name设置为“_blank”。

      3. windowType设置为“new with no opener”。

      在存在跨域起始者策略的情况下,与顶级浏览上下文的活动文档跨域的嵌套文档总是将noopener设置为true。

    4. chosen为null。

    5. targetName为空字符串。

    6. 如果name不是ASCII大小写不敏感匹配“_blank”,则将targetName设置为name

    7. 如果noopener为true,则将chosen设置为根据null、targetNamecurrentNavigable创建新顶级可遍历对象的结果。

    8. 否则:

      1. chosen设置为根据currentNavigable活动浏览上下文targetNamecurrentNavigable创建新顶级可遍历对象的结果。

      2. 如果sandboxingFlagSet设置了沙盒导航浏览上下文标志,则将chosen活动浏览上下文一个允许的沙盒导航器设置为currentNavigable活动浏览上下文

    9. 如果sandboxingFlagSet设置了沙盒传播到辅助浏览上下文标志,则sandboxingFlagSet中设置的所有标志都必须在chosen活动浏览上下文弹出沙盒标志集中设置。

    如果新创建的可导航对象chosen立即导航,则该导航将作为“替换”导航进行。

    如果用户代理已配置在此情况下将选择currentNavigable

    chosen设置为currentNavigable

    如果用户代理已配置在此情况下不查找可导航对象

    什么也不做。

    鼓励用户代理提供一种方式让用户配置用户代理始终选择currentNavigable

  9. 返回chosenwindowType

7.3.2 浏览上下文

浏览上下文是一个系列文档的编程表示,其中多个文档可以存在于一个可导航对象中。每个浏览上下文都有一个对应的WindowProxy对象,以及以下内容:

一个浏览上下文活动窗口是其WindowProxy对象的[[Window]]内部槽值。一个浏览上下文活动文档是其活动窗口关联的Document

一个浏览上下文顶级可遍历对象是其活动文档节点可导航对象顶级可遍历对象

一个浏览上下文辅助浏览上下文是其是辅助窗口为true的情况。辅助浏览上下文始终是顶级浏览上下文

尚不清楚是否需要单独的是辅助窗口概念。在问题#5680中,指出我们可以通过使用打开者浏览上下文是否为null来简化。

现代规范应避免在大多数情况下使用浏览上下文概念,除非它们处理的是浏览上下文组切换代理集群分配的细节。相反,文档可导航对象概念通常更合适。


Document的浏览上下文是一个浏览上下文或null,初始为null。

一个文档不一定有一个非null的浏览上下文。特别是,数据挖掘工具可能永远不会实例化浏览上下文。使用诸如createDocument()这样的API创建的文档从不具有非null的浏览上下文。而且,最初为一个iframe元素创建的文档,在该元素被从文档中移除后,没有关联的浏览上下文,因为该浏览上下文已被设为null

一般来说,窗口对象和文档对象之间存在一对一的映射,只要文档对象有一个非null的浏览上下文。有一个例外。当浏览上下文初始的about:blank 文档导航到另一个文档时,会出现这种情况,这将通过替换进行。

7.3.2.1 创建浏览上下文

创建一个新的浏览上下文和文档,给定null或一个文档对象creator,null或一个元素embedder,以及一个浏览上下文组group

  1. browsingContext成为一个新的浏览上下文

  2. unsafeContextCreationTime成为unsafe shared current time

  3. creatorOrigin为null。

  4. creatorBaseURL为null。

  5. 如果creator非null,则:

    1. creatorOrigin设为creatororigin

    2. creatorBaseURL设为creatordocument base URL

    3. browsingContextvirtual browsing context group ID设为creatorbrowsing contexttop-level browsing contextvirtual browsing context group ID

  6. sandboxFlags成为determining the creation sandboxing flags的结果,给定browsingContextembedder

  7. origin成为determining the origin的结果,给定about:blanksandboxFlagscreatorOrigin

  8. permissionsPolicy成为creating a permissions policy的结果,给定embedderorigin[PERMISSIONSPOLICY]

  9. agent成为obtaining a similar-origin window agent的结果,给定origingroup和false。

  10. realm execution context成为creating a new realm的结果,给定agent和以下定制内容:

  11. topLevelCreationURL成为about:blank,如果embedder为null;否则embedderrelevant settings objecttop-level creation URL

  12. topLevelOrigin成为origin,如果embedder为null;否则embedderrelevant settings objecttop-level origin

  13. Set up a window environment settings object with about:blank, realm execution context, null, topLevelCreationURL, and topLevelOrigin

  14. 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

  15. document成为新的 Document,with:

    type
    "html"
    content type
    "text/html"
    mode
    "quirks"
    origin
    origin
    browsing context
    browsingContext
    permissions policy
    permissionsPolicy
    active sandboxing flag set
    sandboxFlags
    load timing info
    loadTimingInfo
    is initial about:blank
    true
    about base URL
    creatorBaseURL
    allow declarative shadow roots
    true
  16. 如果creator非null,则:

    1. documentreferrer设为serialization of creatorURL

    2. documentpolicy container设为creatorpolicy containerclone

    3. 如果creatororiginsame origin with creatorrelevant settings objecttop-level origin,则将documentopener policy设为creatorbrowsing contexttop-level browsing contextactive documentopener policy

  17. Assert: documentURLdocumentrelevant settings objectcreation URLabout:blank

  18. document标记为ready for post-load tasks

  19. Populate with html/head/body given document

  20. Make active document

  21. Completely finish loading document

  22. 返回browsingContextdocument

创建一个新的顶级浏览上下文和文档

  1. groupdocument成为creating a new browsing context group and document的结果。

  2. 返回groupbrowsing context set[0]和document

创建一个新的辅助浏览上下文和文档,给定一个浏览上下文opener

  1. openerTopLevelBrowsingContext成为opener顶级浏览上下文活动浏览上下文

  2. group成为openerTopLevelBrowsingContext

  3. Assertgroup非null,因为navigating直接调用了此操作。

  4. browsingContextdocument成为creating a new browsing context and document的结果,使用openeractive document、null和group

  5. browsingContextis auxiliary设置为true。

  6. Append browsingContext to group

  7. browsingContextopener browsing context设置为opener

  8. browsingContextvirtual browsing context group ID设置为openerTopLevelBrowsingContextvirtual browsing context group ID

  9. browsingContextopener origin at creation设置为openeractive documentorigin

  10. 返回browsingContextdocument

确定来源,给定一个URLurl,一个sandboxing flag setsandboxFlags,以及一个origin-or-null sourceOrigin

  1. 如果sandboxFlags设置了其sandboxed origin browsing context flag,则返回一个新的opaque origin

  2. 如果url为null,则返回一个新的opaque origin

  3. 如果urlabout:srcdoc,则:

    1. AssertsourceOrigin非null。

    2. 返回sourceOrigin

  4. 如果urlmatches about:blank并且sourceOrigin非null,则返回sourceOrigin

  5. 返回urlorigin

返回sourceOrigin的情况会导致两个Document具有相同的底层origin,这意味着document.domain会影响到两个文档。

7.3.2.2 相关浏览上下文

如果以下算法返回 true,则浏览上下文potentialDescendant被称为浏览上下文potentialAncestor祖先

  1. potentialDescendantDocumentpotentialDescendant活动文档

  2. 如果potentialDescendantDocument不是完全活动的,则返回 false。

  3. ancestorBCs为通过获取potentialDescendantDocument的每个成员的活动文档浏览上下文的列表。

  4. 如果ancestorBCs包含potentialAncestor,则返回 true。

  5. 返回 false。

顶级浏览上下文是其活动文档节点可导航对象可遍历的可导航对象浏览上下文

不是必须是顶级可遍历对象

浏览上下文start顶级浏览上下文是以下算法的结果:

  1. 如果start活动文档不是完全活动的,则返回 null。

  2. navigablestart活动文档节点可导航对象

  3. navigable父级不为 null 时,将navigable设置为navigable父级

  4. 返回navigable活动浏览上下文


浏览上下文A被认为与第二个浏览上下文B熟悉的熟悉,如果以下算法返回 true:

  1. 如果A活动文档来源B活动文档来源同源,则返回 true。

  2. 如果A顶级浏览上下文B,则返回 true。

  3. 如果B是一个辅助浏览上下文,且AB打开者浏览上下文熟悉,则返回 true。

  4. 如果存在B的某个祖先浏览上下文,且其活动文档A活动文档具有相同的来源,则返回 true。

    这包括AB祖先浏览上下文的情况。

  5. 返回 false。

7.3.2.3 浏览上下文的分组

顶层浏览上下文具有一个相关的 (为 null 或 浏览上下文组)。它最初为 null。

用户代理持有一个 浏览上下文组集(一个 集合浏览上下文组)。

浏览上下文组持有一个浏览上下文集(一个 集合顶层浏览上下文)。

顶层浏览上下文会在组 被 创建时 添加到 中。所有后续添加到 中的顶层浏览上下文将 是辅助浏览上下文

浏览上下文组具有一个相关的代理集群映射(一个弱 映射,将代理集群 密钥映射到代理集群)。用户 代理负责收集代理集群,当认为它们不再被访问时。

浏览上下文组具有一个相关的历史代理集群密钥 映射,这是一个 映射,将 来源 映射到 代理集群密钥。此 映射用于通过记录先前为给定来源使用的代理集群密钥来确保 来源密钥代理集群 功能的一致性。

历史代理集群密钥映射仅在 浏览上下文组的生命周期内增加条目。

浏览上下文组具有跨源隔离模式,这是一种 跨源隔离模式。它最初 是 "none"。

跨源隔离模式 是三种可能值之一: "none","logical",或 "concrete"。

"logical" 和 "concrete" 类似。它们都用于 浏览上下文组,其中:

在某些平台上,很难提供安全属性以安全访问由 跨源隔离能力限制的 API。因此,只有"concrete" 能够授予该能力。 "logical" 用于不支持 此功能的平台,其中仍将应用跨源隔离强加的各种限制, 但不授予该能力。

创建 一个新的浏览上下文组和文档

  1. group成为一个新的 浏览上下文组

  2. group附加到用户代理的 浏览上下文组集

  3. browsingContextdocument成为 创建 新的浏览上下文和文档与 null、null 和 group 的结果。

  4. browsingContext 附加到 group

  5. 返回groupdocument

附加一个顶层浏览上下文 browsingContext到一个浏览上下文组 group

  1. browsingContext 附加到 group浏览上下文集

  2. browsingContext设置为 group

移除一个顶层浏览上下文 browsingContext

  1. 断言browsingContext 非空。

  2. group成为browsingContext

  3. browsingContext设置为 null。

  4. browsingContextgroup浏览上下文集 中移除。

  5. 如果group浏览上下文集 为空,则 group 从用户 代理的浏览上下文组集中移除。

附加移除是帮助定义 浏览 上下文组生命周期的基本操作。它们由高级创建和销毁操作调用,用于 文档浏览上下文

当没有文档 对象,其 浏览上下文等于给定的 浏览 上下文(即所有此类文档都已销毁),并且该浏览上下文WindowProxy 适合垃圾回收,那么该浏览上下文将永远不会再被访问。如果它是一个顶层浏览上下文,那么在此时用户代理必须 将其移除

7.3.3 完全活动文档

文档 d被称为完全活动,当d是一个活动文档时 的可导航 navigable,且navigable顶层可遍历navigable容器文档完全活动

由于它们与元素相关联,子 可导航总是与特定的文档,它们的容器文档,在它们的父导航中绑定在一起。用户 代理不得允许用户与子 可导航交互,如果它们的容器文档本身不是完全活动的。

以下示例说明了一个文档如何 成为其活动文档节点可导航,但不完全是 完全活动。这里a.html加载到浏览器窗口中, b-1.html开始加载到一个iframe 中,如图所示, b-2.htmlc.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.htmlb-1.htmlc.html 给出的文档都是它们各自的 活动文档节点可导航。它们也都是 完全活动 的。

点击按钮并从b-2.html加载一个新的文档到可导航 B 中后,我们有以下结果:

欢迎来到龙之咽喉。导航、会话历史和遍历会话历史是本标准中最复杂的部分之一。

基本概念似乎并不那么困难:

你可以在这里看到一些复杂的交织,遍历会引起导航(即,通过网络获取存储的 URL),导航必须与会话历史列表接口,以确保完成后用户看到的是正确的内容。但真正的问题在于各种边缘情况和交互的 web 平台功能:

在接下来的内容中,我们尝试通过将这些复杂性适当地分隔到标记的部分和算法中,并在可能的情况下给予适当的介绍词来引导读者。然而,如果你想真正理解导航和会话历史,通常的建议将是无价的。

7.4.1 会话历史

7.4.1.1 会话历史条目

会话历史条目是一个 结构,包含以下项目

要获取会话历史条目文档,返回其文档状态文档


序列化状态是表示用户界面状态的对象的序列化(通过 StructuredSerializeForStorage)。我们有时非正式地称 "状态对象",这些是作者提供的表示用户界面状态的对象,或者是通过StructuredDeserialize 反序列化序列化状态创建的对象。

页面可以通过添加 序列化状态到会话历史中。这些状态在用户(或脚本)回到历史记录时被反序列化返回给脚本,从而使作者即使在单页应用程序中也能使用 "导航" 隐喻。

序列化状态旨在用于两个主要目的:首先,存储URL中状态的预解析描述,这样在简单情况下,作者不必进行解析(尽管仍需要解析以处理用户传递的URL,因此这只是一个小优化)。其次,作者可以存储不会存储在 URL 中的状态,因为它仅适用于当前的文档实例,如果打开一个新的文档,需要重新构建这些状态。

后者的一个例子是,跟踪弹出div动画的精确坐标,以便在用户回退时,可以使其动画到相同的位置。或者,可以用它来保持指向数据缓存的指针,这些数据将根据 URL 中的信息从服务器获取,这样在前进和后退时,不必重新获取信息。


滚动恢复模式表示在遍历到条目时,用户代理是否应该恢复持久化的滚动位置(如果有)。滚动恢复模式包括以下之一:

"auto"
用户代理负责在导航时恢复滚动位置。
"manual"
页面负责恢复滚动位置,用户代理不会自动尝试这样做。
7.4.1.2 文档状态

文档状态会话历史条目中保存有关如何呈现和(如有必要)重新创建文档的状态。它包括:

用户代理可以销毁一个文档及其后代,给定具有非 null 文档文档状态,只要文档不是完全活动的。

除上述限制外,本标准未规定用户代理应何时销毁文档状态中存储的文档,或保持其缓存。


POST 资源具有:


嵌套历史具有:

这将稍后包含跨重新加载标识子可导航的方法。



会话历史中的多个连续条目可以共享相同的文档状态。当通过正常导航到达初始条目时,这种情况可能发生,并且通过history.pushState()添加以下条目。或者,它可以通过导航到片段来实现。

共享相同文档状态(因此它们只是一个特定文档的不同状态)的所有条目在结构上都是连续的。


文档具有最新条目,一个会话历史条目或 null。

这是最近由给定文档表示的条目。一个文档可以随时间表示许多会话历史条目,因为许多连续的会话历史条目可以共享相同的文档状态,如上所述。

7.4.1.3 会话历史的集中修改

为了保持唯一的真实来源,所有对可遍历导航项会话历史条目的修改都需要同步。这特别重要,因为会话历史受到所有后代导航项的影响,因此涉及多个事件循环。为此,我们使用会话历史遍历并行队列结构。

会话历史遍历并行队列并行队列非常相似。它有一个算法集,一个有序集

会话历史遍历并行队列算法集中的条目可以是算法步骤,也可以是同步导航步骤,这是涉及目标导航项导航项)的一种特殊的算法步骤。

为了将会话历史遍历步骤附加到给定算法步骤的traversablesteps附加到traversable会话历史遍历队列算法集中。

为了将涉及导航项targetNavigable的会话历史同步导航步骤附加到给定算法步骤的traversablesteps作为目标导航项targetNavigable同步导航步骤附加到traversable会话历史遍历队列算法集中。

为了启动一个新的会话历史遍历并行队列:

  1. sessionHistoryTraversalQueue为一个新的会话历史遍历并行队列

  2. 并行运行以下步骤:

    1. 当为真时:

      1. 如果sessionHistoryTraversalQueue算法集为空,则继续

      2. steps为从sessionHistoryTraversalQueue算法集出队的结果。

      3. 运行steps

  3. 返回sessionHistoryTraversalQueue

同步导航步骤算法集中标记,以允许它们有条件地“跳队列”。这是在应用历史步骤中处理的。

想象一下这个由Jake 图描述的联合会话历史:

0 1
top /a /b

并且以下代码在顶层运行:

history.back();
location.href = '#foo';

预期的结果是:

0 1 2
top /a /b /b#foo

这并不简单,因为同步导航在可观察性上赢得了比赛,而遍历在队列步骤上赢得了比赛。为了实现这个结果,发生了以下情况:

  1. history.back() 附加步骤,旨在通过一个增量为-1的遍历。

  2. location.href = '#foo'同步更改活动会话历史条目到一个新创建的条目,URL 为/b#foo,并附加同步步骤来通知中心来源关于该新条目。请注意,这还不会更新当前会话历史条目当前会话历史步骤,或会话历史条目列表;这些更新不能同步完成,而必须作为排队步骤的一部分完成。

  3. 会话历史遍历并行队列中,由history.back()排队的步骤运行:

    1. 目标历史步骤确定为 0:当前会话历史步骤(即1)加上预定的增量 -1。

    2. 我们进入主要的应用历史步骤算法。

      步骤 0 中的条目,对于/a的URL,填充文档

      同时,队列会检查同步导航步骤。由location.href设置器排队的步骤现在运行,并阻止遍历执行超出文档填充的影响(例如,卸载文档和切换活动历史条目),直到它们完成。这些步骤导致以下情况发生:

      1. 添加 URL 为/b#foo的条目,其步骤确定为 2:当前会话历史步骤(即1)加上 1。

      2. 我们完全切换到该新添加的条目,包括嵌套调用应用历史步骤。这最终通过调度诸如hashchange之类的事件,更新文档

      只有在所有这些完成之后,并且/a历史条目已经完全填充了文档之后,我们才继续应用目标步骤为 0 的历史步骤。

      此时,URL 为/b#foo文档卸载,我们完成移动到目标历史步骤0,这使得URL为/a的条目成为活动会话历史条目,0成为当前会话历史步骤

这里是另一个更复杂的例子,涉及两个不同iframe的填充比赛,以及其中一个 iframe 加载后同步导航。我们从以下设置开始:

0 1 2
top /t
frames[0] /i-0-a /i-0-b
frames[1] /i-1-a /i-1-b

然后调用history.go(-2)。然后发生以下情况:

  1. history.go(-2) 附加步骤,旨在通过一个增量为-2的遍历。运行这些步骤后:

    1. 目标步骤确定为2 + (-2) = 0。

    2. 并行地,发出请求以填充两个iframe,分别获取/i-0-a/i-1-a

      同时,队列会检查同步导航步骤。现在没有任何同步导航步骤。

    3. 在获取比赛中,获取/i-0-a的请求获胜。我们继续完成遍历对frames[0]导航项的影响的所有步骤,包括将其活动会话历史条目更新为URL为/i-0-a的条目。

    4. 在获取/i-1-a的请求完成之前,我们达到了脚本可能为新创建的文档运行的点,在frames[0]导航项活动文档中。某些脚本确实运行了:

      location.href = '#foo'

      这同步更改了frames[0]导航项的活动会话历史条目到一个新创建的条目,URL 为/i-0-a#foo,并附加同步步骤来通知中心来源关于该新条目。

      前一个例子不同,这些同步步骤不会“跳队列”并在完成/i-1-a的获取之前更新可遍历导航项。这是因为问题导航项,frames[0],已经作为遍历的一部分被更改,因此我们知道在当前会话历史步骤为2的情况下,添加新的条目作为步骤3没有意义。

    5. 一旦/i-1-a的获取最终完成,我们继续完成frames[1]导航项的更新,包括将其活动会话历史条目更新为URL为/i-1-a的条目。

    6. 现在两个导航项都完成了遍历的处理,我们将当前会话历史步骤更新为目标步骤0。

  2. 现在我们可以处理为同步导航排队的步骤:

    1. 添加URL为/i-0-a#foo的条目,其步骤确定为1:当前会话历史步骤(即0)加上1。这也清除了现有的前向历史

    2. 我们完全切换到该新添加的条目,包括调用应用历史步骤。这最终通过调度诸如hashchange之类的事件,更新文档,以及将当前会话历史步骤更新为目标步骤1。

最终结果是:

0 1
top /t
frames[0] /i-0-a /i-0-a#foo
frames[1] /i-1-a
7.4.1.4 低级别操作会话历史

本节包含在操纵会话历史时执行的各种操作。最好的理解它们的方法是查看它们的调用位置。

要获取一个可导航对象navigable会话历史条目

  1. traversable成为navigable可遍历导航对象

  2. 断言:此操作在traversable会话历史遍历队列中运行。

  3. 如果navigabletraversable,则返回traversable会话历史条目

  4. docStates成为一个空的有序集,用于存放文档状态

  5. 对于traversable的每个entry附加entry文档状态docStates

  6. 对于 docStatedocStates

    1. 对于nestedHistorydocState嵌套历史

      1. 如果nestedHistoryid等于navigableid,则返回nestedHistory条目

      2. 对于nestedHistory的每个entry附加entry文档状态docStates

  7. 断言:不会到达此步骤。

要获取给定整数targetStep可导航对象navigable会话历史条目,步骤如下:

  1. rawEntries成为获取会话历史条目的结果,用于navigable

  2. entriesForNavigationAPI成为一个新的空的列表

  3. startingIndex成为rawEntries中具有最大步骤小于或等于targetStep的会话历史条目的索引。

    参见此示例以了解为什么这是最大步骤小于或等于targetStep

  4. rawEntries[startingIndex]附加到entriesForNavigationAPI

  5. startingOrigin成为rawEntries[startingIndex]的文档状态起源

  6. istartingIndex − 1。

  7. i > 0时:

    1. 如果rawEntries[i]的文档状态起源startingOrigin不相同,则中断

    2. rawEntries[i]预先添加到entriesForNavigationAPI

    3. ii − 1。

  8. istartingIndex + 1。

  9. i < rawEntries大小时:

    1. 如果rawEntries[i]的文档状态起源startingOrigin不相同,则中断

    2. rawEntries[i]附加到entriesForNavigationAPI

    3. ii + 1。

  10. 返回entriesForNavigationAPI

清除前进会话历史可遍历导航对象navigable

  1. 断言:此操作在navigable会话历史遍历队列中运行。

  2. stepnavigable当前会话历史步骤

  3. entryLists有序集 « navigable会话历史条目 »。

  4. 对于entryListentryLists

    1. 移除每个entryList会话历史条目,其步骤大于step

    2. 对于entryList的每个entry

      1. 对于entry文档状态的每个nestedHistory附加nestedHistory条目列表entryLists

要获取作为traversable的一部分的所有已用历史步骤

  1. 断言:此操作在traversable会话历史遍历队列中运行。

  2. steps为一个空的有序集,用于存放非负整数。

  3. entryLists有序集 « traversable会话历史条目 »。

  4. 对于entryListentryLists

    1. 对于entryentryList

      1. 附加entry步骤steps

      2. 对于entry文档状态的每个nestedHistory附加nestedHistory条目列表entryLists

  5. 返回steps排序

某些操作会导致导航对象导航到新的资源。

例如,点击超链接表单提交,以及window.open()location.assign()方法都可能导致导航。

尽管在本标准中,“导航”一词专指导航算法,但这并不总是与网页开发者或用户的理解一致。例如:

在我们进入导航算法之前,我们需要建立其使用的几个重要结构。

源快照参数 结构用于捕获发起导航的文档的数据。在导航开始时进行快照,并在整个导航过程中使用。它具有以下项目

具有瞬态激活
布尔值
沙盒标志
沙盒标志集
允许下载
布尔值
抓取客户端
一个环境设置对象,仅用于作为请求客户端
源策略容器
策略容器

快照源快照参数,给定一个文档sourceDocument,返回一个新的源快照参数,其中

具有瞬态激活
如果sourceDocument相关全局对象具有瞬态激活;否则为false
沙盒标志
sourceDocument活动沙盒标志集
允许下载
如果sourceDocument活动沙盒标志集具有沙盒下载浏览上下文标志,则为false;否则为true
抓取客户端
sourceDocument相关设置对象
源策略容器
sourceDocument策略容器

目标快照参数 结构用于捕获被导航的导航对象的数据。与源快照参数类似,它在导航开始时进行快照,并在整个导航过程中使用。它具有以下项目

沙盒标志
沙盒标志集

快照目标快照参数,给定一个导航对象targetNavigable,返回一个新的目标快照参数,其中沙盒标志设置为给定targetNavigable活动浏览上下文targetNavigable容器时确定的创建沙盒标志的结果。


导航过程的很大一部分涉及确定如何创建一个新的文档,这最终在创建和初始化一个Document对象算法中完成。该算法的参数通过一个导航参数 结构进行跟踪,该结构具有以下项目

id
null或导航ID
导航对象
要导航的导航对象
请求
null或发起导航的请求
响应
最终导航到的响应(可能是网络错误
抓取控制器
null或抓取控制器
提交早期提示
null或在创建文档后接受它的算法
COOP执行结果
用于报告并可能导致浏览上下文组切换跨源开启者策略执行结果
预留环境
null或为新文档预留的环境
来源
用于新文档来源
策略容器
用于新文档策略容器
最终沙盒标志集
要强加给新文档沙盒标志集
跨源开启者策略
用于新文档跨源开启者策略
导航计时类型
一个 NavigationTimingType 用于 创建导航时序条目 为新的 文档
关于基本URL
用于填充新文档关于基本URLURL或null

一旦创建了一个导航参数结构,本标准不会对其任何项目进行变更。它们只会传递给其他算法。


导航ID是在导航过程中生成的UUID字符串。它用于与WebDriver BiDi规范进行接口,以及跟踪正在进行的导航。[WEBDRIVERBIDI]


在创建文档之后,相关的可遍历导航对象会话历史会更新。NavigationHistoryBehavior枚举用于向导航算法指示所需的会话历史更新类型。它是以下之一:

"push"
常规导航,它会添加一个新的会话历史条目,并会清除前向会话历史
"replace"
一种将替换活动会话历史条目的导航。
" auto"
默认值,它会在导航算法中很早转换为"push"或"replace"。通常它会变成"push",但在某些情况下会变成"replace"。

历史处理行为是一个NavigationHistoryBehavior,它是"push"或"replace",即已经解决了任何初始"auto"值。

导航必须是替换,如果以下任何情况为真,给定一个url和一个文档 document

其他通常但不总是强制"replace"导航的情况是:


平台的各个部分会跟踪用户是否参与了导航。用户导航参与如下之一:

"browser UI"
导航由用户通过浏览器UI机制发起。
"activation"
导航由用户通过元素的激活行为发起。
"none"
导航不是由用户发起的。

为了方便某些调用站点,用户导航参与定义为:

  1. 断言:此算法作为激活行为定义的一部分被调用。

  2. 断言event类型是"click"。

  3. 如果eventisTrusted初始化为true,则返回"激活"。

  4. 返回""。

7.4.2.2 开始导航

要将导航对象 navigable导航到一个url,使用文档 sourceDocument,可选的documentResource(默认null),可选的response(默认null),可选的exceptionsEnabled(默认false),可选的NavigationHistoryBehavior historyHandling(默认"auto"),可选的navigationAPIState(默认null),可选的formDataEntryList(默认null),可选的referrerPolicy(默认空字符串)和可选的userInvolvement(默认"none"):

  1. 如果formDataEntryList不为null,则将cspNavigationType设为"form-submission",否则设为"other"。

  2. sourceSnapshotParams设为根据sourceDocument源快照参数的快照结果。

  3. initiatorOriginSnapshot设为sourceDocument来源

  4. initiatorBaseURLSnapshot设为sourceDocument文档基本URL

  5. navigationId设为生成一个随机UUID的结果。

  6. 如果周围的代理等于navigable的活动文档的相关代理,则继续这些步骤。否则,在navigable的活动窗口上排队一个全局任务,以继续这些步骤。

  7. 如果navigable的活动文档的卸载计数器大于0,则调用WebDriver BiDi导航失败,并返回。

  8. container设为navigable的容器。

  9. 如果container是一个iframe元素并且将惰性加载元素步骤返回true,则停止观察惰性加载元素并将container的惰性加载恢复步骤设为null。

  10. 如果给定urlnavigable的活动文档导航必须是替换的,则将historyHandling设为"replace"。

  11. 如果navigable的父级不为null,则将navigable的延迟加载事件模式设为true。

  12. targetBrowsingContext设为navigable的活动浏览上下文。

  13. targetSnapshotParams设为根据navigable的目标快照参数的快照结果。

  14. 调用WebDriver BiDi导航开始,并传入targetBrowsingContext和一个新的WebDriver BiDi导航状态,其id为navigationId,状态为"pending",URL为url

  15. 如果 navigable的持续导航为"traversal",则:

    1. 调用WebDriver BiDi导航失败,并传入targetBrowsingContext和一个新的WebDriver BiDi导航状态,其id为navigationId,状态为"canceled",URL为url

    2. 返回。

  16. 设置navigable的持续导航为navigationId

  17. 如果url的方案是"javascript",则:

    1. 排队一个全局任务,在navigable的活动窗口上导航到一个javascript: URL,并传入navigableurlhistoryHandlinginitiatorOriginSnapshotcspNavigationType

    2. 返回。

  18. 如果以下所有条件都为真:

    则:

    1. navigation设为navigable的活动窗口的导航API。

    2. entryListForFiring设为formDataEntryList,如果documentResource是一个POST资源;否则为null。

    3. navigationAPIStateForFiring设为navigationAPIState,如果navigationAPIState不为null;否则,StructuredSerializeForStorage(undefined)。

    4. continue设为触发一个push/replace/reload navigate事件的结果,传入navigationnavigationType设为historyHandlingisSameDocument设为false,userInvolvement设为userInvolvementformDataEntryList设为entryListForFiringdestinationURL设为urlnavigationAPIState设为navigationAPIStateForFiring

    5. 如果continue为false,则返回。

  19. 并行运行这些步骤:

    1. unloadPromptCanceled设为检查是否取消卸载的结果,针对navigable的活动文档的包含后代导航对象。

    2. 如果unloadPromptCanceled为true,或navigable的持续导航不再为navigationId,则:

      1. 调用WebDriver BiDi导航失败,并传入targetBrowsingContext和一个新的WebDriver BiDi导航状态,其id为navigationId,状态为"canceled",URL为url

      2. 中止这些步骤。

    3. 排队一个全局任务,在navigable的活动窗口上中止一个文档及其后代。

    4. 如果url匹配about:blankabout:srcdoc,则:

      1. documentState的来源设为initiatorOriginSnapshot

      2. documentState的基本URL设为initiatorBaseURLSnapshot

    5. historyEntry设为一个新的会话历史条目,URL设为url,文档状态设为documentState

    6. navigationParams设为null。

    7. 如果response不为null:

      导航算法仅在对象和嵌入元素处理模型的一部分或处理multipart/x-mixed-replace响应的部分时提供响应。

      1. policyContainer设为确定导航参数策略容器的结果,给定响应的URL,null,源文档的策略容器的克隆,导航对象的容器文档的政策容器和null。

      2. finalSandboxFlags设为目标快照参数的沙盒标志和策略容器的CSP列表的联合。

      3. responseOrigin设为确定响应的来源的结果,给定响应的URL,最终沙盒标志和文档状态的发起者来源。

      4. coop设为一个新的跨域开启策略。

      5. coopEnforcementResult设为一个新的跨域开启策略执行结果,包含以下内容:

        URL
        响应的URL
        来源
        响应的来源
        跨域开启策略
        跨域开启策略
      6. navigationParams设为一个新的导航参数,包含以下内容:

        ID
        navigationId
        导航对象
        navigable
        请求
        null
        响应
        response
        获取控制器
        null
        提交早期提示
        null
        COOP执行结果
        coopEnforcementResult
        保留环境
        null
        来源
        responseOrigin
        政策容器
        policyContainer
        最终沙盒标志集
        finalSandboxFlags
        跨域开启策略
        coop
        导航时间类型
        "navigate"
        关于基本URL
        documentState的基本URL
    8. 尝试填充历史条目的文档,给定historyEntrynavigable,"navigate",sourceSnapshotParamstargetSnapshotParamsnavigationIdnavigationParamscspNavigationType,并将allowPOST设为true,completionSteps设为以下步骤:

      1. 附加会话历史遍历步骤到navigable的可遍历对象以完成跨文档导航,给定navigablehistoryHandlinghistoryEntry

7.4.2.3 结束导航

虽然通常的跨文档导航情况将首先进入填充会话历史条目,所有未被中止的导航最终都将调用以下算法之一。

7.4.2.3.1 通常的跨文档导航情况

完成跨文档导航,给定一个导航对象navigable历史处理行为historyHandling会话历史条目historyEntry

  1. 断言:这是在navigable可遍历导航对象会话历史遍历队列上运行。

  2. 设置navigable是否延迟load事件为false。

  3. 如果historyEntry文档为null,则返回。

    这意味着尝试填充历史条目的文档最终未创建文档,可能由于导航被后续导航取消、204 No Content响应等原因。

  4. 如果以下所有条件都为真:

    则将historyEntry文档状态导航目标名称设置为空字符串。

  5. 如果historyHandling是"replace",则将entryToReplace设为navigable活动会话历史条目;否则为null。

  6. traversable设为navigable可遍历导航对象

  7. targetStep设为null。

  8. targetEntries设为获取navigable的会话历史条目的结果。

  9. 如果entryToReplace为null,则:

    1. 清除traversable的前向会话历史。

    2. targetStep设为traversable当前会话历史步骤 + 1。

    3. historyEntry步骤设为targetStep

    4. historyEntry追加到targetEntries

    否则:

    1. 替换targetEntries中的entryToReplacehistoryEntry

    2. historyEntry步骤设为entryToReplace步骤

    3. 如果historyEntry文档状态来源entryToReplace文档状态来源相同,则将historyEntry导航API键设为entryToReplace导航API键

    4. targetStep设为traversable当前会话历史步骤

  10. 应用targetSteptraversable,给定historyHandling

7.4.2.3.2 javascript: URL 的特殊情况

javascript: URL 在问题跟踪器上有一个专用标签,记录了其规范的各种问题。

导航到 javascript: URL,给定一个 navigable targetNavigable,一个 URL url,一个 历史处理行为 historyHandling,一个 来源 initiatorOrigin,以及一个字符串 cspNavigationType

  1. 断言historyHandling 是 "replace"。

  2. targetNavigable 的正在进行的导航设置为 null。

  3. 如果 initiatorOrigintargetNavigable活动文档来源 不是 同源域,则返回。

  4. request 成为一个新的 请求,其 URLurl

    这是一个合成的 请求,仅用于连接到下一步。它永远不会触及网络。

  5. 如果根据 内容安全策略应阻止的导航请求类型 给定 requestcspNavigationType 的结果是 "Blocked",则返回。[CSP]

  6. newDocument 成为 评估 javascript: URL 的结果,给定 targetNavigableurlinitiatorOrigin

  7. 如果 newDocument 为 null,则返回。

    在这种情况下,一些 JavaScript 代码已执行,但没有创建新的 文档,所以我们不会执行导航。

  8. 断言initiatorOriginnewDocument来源

  9. entryToReplace 成为 targetNavigable活动会话历史条目

  10. oldDocState 成为 entryToReplace文档状态

  11. documentState 成为一个新的 文档状态,其中包含

    文档
    newDocument
    历史策略容器
    一个 克隆,如果 oldDocState历史策略容器 不为空;否则为 null
    请求引用
    oldDocState请求引用
    请求引用策略
    oldDocState请求引用策略 或应为传递给 导航referrerPolicy
    发起者来源
    initiatorOrigin
    来源
    initiatorOrigin
    关于基本 URL
    oldDocState关于基本 URL
    资源
    null
    是否曾被填充
    true
    可导航目标名称
    oldDocState可导航目标名称
  12. historyEntry 成为一个新的 会话历史条目,包含

    URL
    entryToReplaceURL
    文档状态
    documentState

    对于 URL,我们使用 url,即实际的 javascript: URL,这意味着 javascript: URL 永远不会存储在会话历史中,因此无法被遍历到。

  13. 附加会话历史遍历步骤targetNavigable可遍历对象,以 完成跨文档导航,与 targetNavigablehistoryHandlinghistoryEntry

评估 javascript: URL,给定一个 navigable targetNavigable,一个 URL url,和一个 来源 newDocumentOrigin

  1. urlString 成为运行 URL 序列化器url 上的结果。

  2. encodedScriptSource 成为从 urlString 中移除前导 "javascript:" 的结果。

  3. scriptSource 成为 UTF-8 解码百分比解码 encodedScriptSource 的结果。

  4. settings 成为 targetNavigable活动文档相关设置对象

  5. baseURL 成为 settingsAPI 基本 URL

  6. script 成为 创建经典脚本 的结果,给定 scriptSourcesettingsbaseURL默认脚本获取选项

  7. evaluationStatus 成为 运行经典脚本 script 的结果。

  8. result 为 null。

  9. 如果 evaluationStatus 是正常完成,并且 evaluationStatus.[[Value]] 是字符串,则将 result 设置为 evaluationStatus.[[Value]]。

  10. 否则,返回 null。

  11. response 成为一个新的 响应,包含

    URL
    targetNavigable活动文档URL
    头列表
    « (`Content-Type`,`text/html;charset=utf-8`) »
    主体
    UTF-8 编码 result作为一个主体

    编码为 UTF-8 意味着一旦 HTML 解析器解码响应主体,未配对的 代理将不会进行回传。

  12. policyContainer 成为 targetNavigable活动文档策略容器

  13. finalSandboxFlags 成为 policyContainerCSP 列表CSP 派生的沙盒标志

  14. coop 成为 targetNavigable活动文档打开策略

  15. coopEnforcementResult 成为一个新的 跨来源打开策略执行结果,包含

    url
    url
    来源
    newDocumentOrigin
    跨来源打开策略
    coop
  16. navigationParams 成为一个新的 导航参数,包含

    id
    navigationId
    navigable
    targetNavigable
    请求
    null 这将导致生成的 文档 的引用为 null;这样是否正确?
    响应
    response
    获取控制器
    null
    提交早期提示
    null
    COOP 执行结果
    coopEnforcementResult
    保留环境
    null
    来源
    newDocumentOrigin
    策略容器
    policyContainer
    最终沙盒标志集
    finalSandboxFlags
    跨来源打开策略
    coop
    导航时序类型
    "navigate"
    关于基本 URL
    targetNavigable活动文档关于基本 URL
  17. 返回 加载 HTML 文档 的结果,给定 navigationParams

7.4.2.3.3 片段导航

导航到片段,给定一个 navigable navigable,一个 URL url,一个 历史处理行为 historyHandling,一个 用户导航参与度 userInvolvement,一个 序列化状态 或 null navigationAPIState,以及一个 导航 ID navigationId

  1. navigation 成为 navigable活动窗口导航 API

  2. destinationNavigationAPIState 成为 navigable活动会话历史条目导航 API 状态

  3. 如果 navigationAPIState 不是 null,则将 destinationNavigationAPIState 设置为 navigationAPIState

  4. continue 成为 触发 push/replace/reload navigate 事件navigation 上的结果,navigationType 设置为 historyHandlingisSameDocument 设置为 true,userInvolvement 设置为 userInvolvementdestinationURL 设置为 urlnavigationAPIState 设置为 destinationNavigationAPIState

  5. 如果 continue 为 false,则返回。

  6. historyEntry 成为一个新的 会话历史条目,包含

    URL
    url
    文档状态
    navigable活动会话历史条目文档状态
    导航 API 状态
    destinationNavigationAPIState
    滚动恢复模式
    navigable活动会话历史条目滚动恢复模式

    对于使用 navigation.navigate() 执行的导航,state 选项提供的值用于新的 导航 API 状态。(如果未提供该选项的值,则会将其设置为 undefined 的序列化形式。)对于其他片段导航,包括用户发起的导航,导航 API 状态 从前一个条目继承。

    经典历史 API 状态 永远不会被继承。

  7. entryToReplace 成为 navigable活动会话历史条目,如果 historyHandling 是 "replace",否则为 null。

  8. history 成为 navigable活动文档历史对象

  9. scriptHistoryIndex 成为 history索引

  10. scriptHistoryLength 成为 history长度

  11. 如果 historyHandling 是 "push",则:

    1. history状态 设置为 null。

    2. 增加 scriptHistoryIndex

    3. scriptHistoryLength 设置为 scriptHistoryIndex + 1。

  12. navigable活动文档URL 设置为 url

  13. navigable活动会话历史条目 设置为 historyEntry

  14. 更新文档以应用历史步骤,给定 navigable活动文档historyEntry、true、scriptHistoryIndexscriptHistoryLengthhistoryHandling

    由于单次片段导航,该算法将被调用两次:一次是同步调用,其中设置最佳猜测值 scriptHistoryIndexscriptHistoryLengthhistory.state 被置为 null,并触发各种事件;另一次是异步调用,其中设置索引和长度的最终值,history.state 保持不变,并且不会触发任何事件。

  15. 滚动到片段,给定 navigable活动文档

    如果滚动失败,因为 文档 是新的且相关的 ID 尚未解析,那么第二次异步调用 更新文档以应用历史步骤 将处理滚动。

  16. traversable 成为 navigable可遍历的 navigable

  17. 附加以下会话历史同步导航步骤,涉及 navigabletraversable

    1. 完成同一文档导航,给定 traversablenavigablehistoryEntryentryToReplacehistoryHandling

    2. 调用 WebDriver BiDi 片段导航,使用 navigable活动浏览上下文 和新的 WebDriver BiDi 导航状态,其中 idnavigationIdurlurl,并且 状态 是 "完成"。

完成同一文档导航,给定一个 可遍历的 navigable traversable,一个 navigable targetNavigable,一个 会话历史条目 targetEntry,一个 会话历史条目 或 null entryToReplace,以及一个 历史处理行为 historyHandling

这被 片段导航URL 和历史更新步骤 使用,它们是唯一同步更新会话历史的算法。由于是同步的,这些算法在 顶级可遍历对象会话历史遍历队列 之外执行。这使得它们与 顶级可遍历对象当前会话历史步骤 不同步,因此该算法用于解决由于竞争条件引起的冲突。

  1. 断言:这是在 traversable会话历史遍历队列 上运行。

  2. 如果 targetNavigable活动会话历史条目 不是 targetEntry,则返回。

  3. targetStep 为 null。

  4. targetEntries 成为 获取 targetNavigable 的会话历史条目 的结果。

  5. 如果 entryToReplace 是 null,则:

    1. 清除 traversable 的前向会话历史

    2. targetStep 设置为 traversable当前会话历史步骤 + 1。

    3. targetEntry步骤 设置为 targetStep

    4. 附加 targetEntrytargetEntries

    否则:

    1. 替换 entryToReplacetargetEntrytargetEntries 中。

    2. targetEntry步骤 设置为 entryToReplace步骤

    3. targetStep 设置为 traversable当前会话历史步骤

  6. 应用推送/替换历史步骤 targetSteptraversable,给定 historyHandling

    即使对于 "replace" 导航,也会执行此操作,因为它解决了多个同步导航的竞争条件。

7.4.2.3.4 非 fetch 方案和外部软件

尝试创建非 fetch 方案文档 的输入是 非 fetch 方案导航参数 结构体。它是 导航参数 的轻量版本,仅携带与非 fetch 方案 导航情况相关的参数。它具有以下 项目

id
null 或 导航 ID
navigable
进行导航的 navigable
URL
URL
目标快照沙盒标志
导航期间存在的 目标快照参数沙盒标志
源快照具有瞬时激活
导航期间存在的 源快照参数具有瞬时激活 布尔值的副本
发起者来源

一个 来源,可能用于用户界面提示以确认调用外部软件包

这与 文档状态发起者来源 略有不同,因为 非 fetch 方案导航参数发起者来源 跟随重定向链,直到非 fetch 方案 URL。

导航时序类型
NavigationTimingType,用于 创建导航时序条目 为新的 文档

尝试创建非 fetch 方案文档,给定一个 非 fetch 方案导航参数 navigationParams

  1. url 成为 navigationParamsURL
  2. navigable 成为 navigationParamsnavigable
  3. 如果 url 将通过不影响 navigable 的机制处理,例如因为 url方案 在外部处理,则:

    1. 移交给外部软件,给定 urlnavigablenavigationParams目标快照沙盒标志navigationParams源快照具有瞬时激活,以及 navigationParams发起者来源

    2. 返回 null。

  4. 通过显示某种内联内容来处理 url,例如错误消息,因为指定的方案不是支持的协议之一,或者内联提示用户选择给定方案的 已注册处理程序。返回 显示内联内容 的结果,给定 navigablenavigationParamsidnavigationParams导航时序类型

    在使用已注册的处理程序的情况下,将调用 导航,使用新的 URL。

移交给外部软件,给定一个 URL响应 resource、一个 navigable navigable、一个 沙盒标志集 sandboxFlags、一个布尔值 hasTransientActivation,以及一个 来源 initiatorOrigin,用户代理应:

  1. 如果以下所有条件都为真:

    那么无需调用外部软件包即可返回。

    在 iframe 中导航到外部软件对用户来说可以看作是一个新弹出窗口或一个新的顶级导航。这就是为什么只有在 iframe 中指定了 allow-popupsallow-top-navigationallow-top-navigation-by-user-activationallow-top-navigation-to-custom-protocols 时才允许。

  2. 执行 resource 的适当移交,同时尝试减轻这是试图利用目标软件的风险。例如,用户代理可以提示用户确认 initiatorOrigin 是否允许调用相关的外部软件。特别是,如果 hasTransientActivation 为 false,则在没有用户确认的情况下,用户代理不应调用外部软件包。

    例如,目标软件的 URL 处理程序中可能存在漏洞,恶意页面会试图通过诱使用户点击链接来利用此漏洞。

7.4.2.4 防止导航

有几种情况可能会在导航过程的早期介入并使整个过程停止。当由于会话历史遍历导致多个可导航元素同时导航时,这尤其令人兴奋。

如果以下步骤返回 true,则 可导航元素source被沙盒允许导航第二个可导航元素target,给定源快照参数sourceSnapshotParams

  1. 如果sourcetarget,则返回 true。

  2. 如果sourcetarget的祖先,则返回 true。

  3. 如果targetsource的祖先,则:

    1. 如果target不是顶级可遍历,则返回 true。

    2. 如果sourceSnapshotParams具有瞬态激活为 true,并且sourceSnapshotParams沙盒标志带用户激活的沙盒顶级导航浏览上下文标志被设置,则返回 false。

    3. 如果sourceSnapshotParams具有瞬态激活为 false,并且sourceSnapshotParams沙盒标志不带用户激活的沙盒顶级导航浏览上下文标志被设置,则返回 false。

    4. 返回 true。

  4. 如果target顶级可遍历

    1. 如果sourcetarget一个允许的沙盒导航器,则返回 true。

    2. 如果sourceSnapshotParams沙盒标志沙盒导航浏览上下文标志被设置,则返回 false。

    3. 返回 true。

  5. 如果sourceSnapshotParams沙盒标志沙盒导航浏览上下文标志被设置,则返回 false。

  6. 返回 true。

列表可导航元素navigablesThatNeedBeforeUnload,给定一个可选的可遍历可导航元素traversable、一个可选整数targetStep和一个可选的用户导航参与或-nulluserInvolvementForNavigateEvent,运行这些步骤。它们返回 "canceled-by-beforeunload"、"canceled-by-navigate"或"continue"。

  1. documentsToFireBeforeunload成为navigablesThatNeedBeforeUnload中每个项目活动文档

  2. unloadPromptShown为 false。

  3. finalStatus为"continue"。

  4. 如果给定了traversable,则:

    1. 断言:已给定targetStepuserInvolvementForNavigateEvent

    2. targetEntry为根据traversabletargetStep获取目标历史记录项的结果。

    3. 如果targetEntry不是traversable当前会话历史记录项,并且targetEntry文档状态来源traversable当前会话历史记录项文档状态来源相同,则:

      在这种情况下,我们将在此处为traversable触发navigate事件。由于在某些情况下它可能会被取消,我们需要将其与稍后发生的其他遍历navigate事件分开处理。

      此外,因为我们希望在navigate事件之前触发beforeunload事件,这意味着我们需要在此处为traversable触发beforeunload(如果适用),而不是将其作为下面遍历documentsToFireBeforeunload的循环的一部分。

      1. 断言userInvolvementForNavigateEvent不为 null。

      2. eventsFired为 false。

      3. 如果navigablesThatNeedBeforeUnload包含traversable,则needsBeforeunload为 true;否则为 false。

      4. 如果needsBeforeunload为 true,则移除traversable活动文档documentsToFireBeforeunload中。

      5. traversable活动窗口上给定导航和遍历任务源队列一个全局任务,以执行以下步骤:

        1. 如果needsBeforeunload为 true,则:

          1. 令(unloadPromptShownForThisDocument, unloadPromptCanceledByThisDocument)为根据traversable活动文档和 false 运行触发beforeunload的步骤的结果。

          2. 如果unloadPromptShownForThisDocument为 true,则将unloadPromptShown设置为 true。

          3. 如果unloadPromptCanceledByThisDocument为 true,则将finalStatus设置为"canceled-by-beforeunload"。

        2. 如果finalStatus为"canceled-by-beforeunload",则中止这些步骤。

        3. navigationtraversable活动窗口导航 API

        4. navigateEventResult为在navigation触发遍历navigate事件的结果,给定targetEntryuserInvolvementForNavigateEvent

        5. 如果navigateEventResult为 false,则将finalStatus设置为"canceled-by-navigate"。

        6. eventsFired设置为 true。

      6. 等待eventsFired为 true。

      7. 如果finalStatus不是"continue",则返回finalStatus

  5. totalTasksdocumentsThatNeedBeforeunload大小

  6. completedTasks为 0。

  7. 对于documents的每个document,在document相关全局对象队列一个全局任务,给定导航和遍历任务源以运行步骤:

    1. 令(unloadPromptShownForThisDocument, unloadPromptCanceledByThisDocument)为根据documentunloadPromptShown运行触发beforeunload的步骤的结果。

    2. 如果unloadPromptShownForThisDocument为 true,则将unloadPromptShown设置为 true。

    3. 如果unloadPromptCanceledByThisDocument为 true,则将finalStatus设置为"canceled-by-beforeunload"。

    4. 增加completedTasks

  8. 等待completedTaskstotalTasks

  9. 返回finalStatus

触发beforeunload的步骤给定一个Documentdocument和一个布尔值unloadPromptShown如下:

  1. unloadPromptCanceled为 false。

  2. 增加document卸载计数器1。

  3. 增加document相关代理事件循环终止嵌套级别1。

  4. eventFiringResult为在document相关全局对象触发事件的结果,事件名称为beforeunload,使用BeforeUnloadEvent可取消属性初始化为 true。

  5. 减少document相关代理事件循环终止嵌套级别1。

  6. 如果以下所有条件均为 true:

    然后:

    1. unloadPromptShown设置为 true。

    2. 调用WebDriver BiDi 用户提示已打开,参数为document相关全局对象、"beforeunload"和""。

    3. 询问用户是否确认他们希望卸载文档,并在等待用户响应时暂停

      显示给用户的消息不可自定义,而是由用户代理决定的。特别是,returnValue属性的实际值被忽略。

    4. 如果用户未确认页面导航,则将unloadPromptCanceled设置为 true。

    5. 调用WebDriver BiDi 用户提示已关闭,参数为document相关全局对象,如果unloadPromptCanceled为 false 则为 true,否则为 false。

  7. 减少document卸载计数器1。

  8. 返回(unloadPromptShown, unloadPromptCanceled)。

7.4.2.5 中止导航

每个可导航元素都有一个正在进行的导航,它是一个导航 ID,"traversal",或 null,初始为 null。它用于跟踪导航中止并防止在遍历期间进行任何导航。

可导航元素navigable 设置正在进行的导航newValue

  1. 如果navigable正在进行的导航等于newValue,则返回。

  2. 通知导航 API 中止导航,给定navigable

  3. navigable正在进行的导航设置为newValue

7.4.3 重新加载和遍历

可导航元素navigable,给定一个可选的序列化状态或-nullnavigationAPIState(默认为 null)和一个可选的用户导航参与userInvolvement(默认"none"),重新加载

  1. 如果userInvolvement不是"浏览器 UI",则:

    1. navigationnavigable活动窗口导航 API

    2. destinationNavigationAPIStatenavigable活动会话历史记录项导航 API 状态

    3. 如果navigationAPIState不是 null,则将destinationNavigationAPIState设置为navigationAPIState

    4. continue为在navigation触发推送/替换/重新加载navigate事件的结果,其中navigationType设置为"reload",isSameDocument设置为 false,userInvolvement设置为userInvolvementdestinationURL设置为navigable活动会话历史记录项URLnavigationAPIState设置为destinationNavigationAPIState

    5. 如果continue为 false,则返回。

  2. navigable活动会话历史记录项文档状态重新加载挂起设置为 true。

  3. traversablenavigable可遍历可导航元素

  4. 将以下会话历史记录遍历步骤附加traversable

    1. 应用重新加载历史记录步骤traversable

给定一个可遍历可导航元素traversable、一个整数delta,和一个可选的DocumentsourceDocument按增量遍历历史记录

  1. sourceSnapshotParamsinitiatorToCheck为 null。

  2. userInvolvement为"浏览器 UI"。

  3. 如果给定了sourceDocument,则:

    1. sourceSnapshotParams设置为快照源快照参数的结果,给定sourceDocument

    2. initiatorToCheck设置为sourceDocument节点可导航元素

    3. userInvolvement设置为"none"。

  4. 将以下会话历史记录遍历步骤附加traversable

    1. allSteps获取所有使用的历史记录步骤的结果,针对traversable

    2. currentStepIndextraversable当前会话历史记录步骤allSteps中的索引。

    3. targetStepIndexcurrentStepIndex加上delta

    4. 如果allSteps[targetStepIndex]不存在,则中止这些步骤

    5. 应用遍历历史记录步骤allSteps[targetStepIndex]到traversable,给定sourceSnapshotParamsinitiatorToCheckuserInvolvement

除了导航算法之外,会话历史记录条目还可以通过另一种机制推送或替换,即URL和历史记录更新步骤。这些步骤中最著名的调用者是history.replaceState()history.pushState()API,但标准的其他部分也需要更新活动历史记录条目,并使用这些步骤来完成此操作。

URL和历史记录更新步骤,给定一个文档document,一个URLnewURL,一个可选的序列化状态或-nullserializedData(默认null),以及一个可选的历史记录处理行为historyHandling(默认"replace"),步骤如下:

  1. navigabledocument节点可导航

  2. activeEntrynavigable活动会话历史记录条目

  3. newEntry为新的会话历史记录条目,其具有

    URL
    newURL
    序列化状态
    如果serializedData不为 null,则为serializedData;否则为activeEntry经典历史记录 API 状态
    文档状态
    activeEntry文档状态
    滚动恢复模式
    activeEntry滚动恢复模式
    持久化用户状态
    activeEntry持久化用户状态
  4. 如果document是初始about:blank为 true,则将historyHandling设置为"replace"。

    这意味着在初始about:blank文档上调用pushState()的行为与调用replaceState()相同。

  5. entryToReplaceactiveEntry,如果historyHandling是"replace",否则为 null。

  6. 如果historyHandling是"push",则:

    1. 增加document历史记录对象索引

    2. document历史记录对象长度设置为其索引+1。

    这些是立即同步访问的临时最佳猜测值。

  7. 如果serializedData不为 null,则恢复历史记录对象状态,给定documentnewEntry

  8. documentURL设置为newURL

    由于这既不是导航也不是历史记录遍历,因此不会触发hashchange事件。

  9. document最新条目设置为newEntry

  10. navigable活动会话历史记录条目设置为newEntry

  11. 更新同一文档导航的导航 API 条目,给定document相关全局对象导航 APInewEntryhistoryHandling

  12. traversablenavigable可遍历可导航

  13. 将以下会话历史记录同步导航步骤附加traversable中涉及navigable

    1. 完成同一文档导航,给定traversablenavigablenewEntryentryToReplacehistoryHandling

虽然片段导航URL和历史记录更新步骤都执行同步历史记录更新,但只有片段导航包含同步调用更新文档以应用历史记录步骤URL和历史记录更新步骤在上述算法中执行一些选定的更新,省略了其他更新。这有点不幸的历史事故,通常导致Web 开发者的不满,因为这种不一致。例如,这意味着popstate事件会为片段导航触发,但不会为history.pushState()调用触发。

7.4.5 填充会话历史条目

概述中所解释的,导航遍历都涉及创建一个会话历史条目,然后尝试填充其文档成员,以便它可以在可导航中呈现。

这涉及使用已给定的响应;使用存储在会话历史条目中的srcdoc资源;或获取。该过程有多种失败模式,这些模式可能导致不做任何事情(将可导航保留在其当前的活动文档上)或导致用错误文档填充会话历史条目

为了尝试填充历史条目的文档,给定一个会话历史条目entry,一个可导航navigable,一个NavigationTimingTypenavTimingType,一个源快照参数sourceSnapshotParams,一个目标快照参数targetSnapshotParams,一个可选的导航ID或nullnavigationId(默认为null),一个可选的导航参数或nullnavigationParams(默认为null),一个可选的字符串cspNavigationType(默认为"other"),一个可选的布尔值allowPOST(默认为false),以及可选的算法步骤completionSteps(默认为一个空的算法),请执行以下步骤:

  1. 断言:这在并行运行。

  2. 断言:如果navigationParams非空,则navigationParams响应非空。

  3. currentBrowsingContextnavigable活动浏览上下文

  4. documentResourceentry文档状态资源

  5. 如果navigationParams为null,则:

    1. 如果documentResource是字符串,则将navigationParams设置为结果,从srcdoc资源创建导航参数,给定entrynavigabletargetSnapshotParamsnavigationIdnavTimingType

    2. 否则,如果以下所有条件为真:

      然后将navigationParams设置为结果,通过获取创建导航参数,给定entrynavigablesourceSnapshotParamstargetSnapshotParamscspNavigationTypenavigationIdnavTimingType

    3. 否则,如果 entryURL方案不是fetch方案,则将navigationParams设置为一个新的非fetch方案导航参数,其中包含:

      id
      navigationId
      可导航
      navigable
      URL
      entryURL
      目标快照沙盒标志
      targetSnapshotParams沙盒标志
      源快照是否有临时激活
      sourceSnapshotParams是否有临时激活
      发起者来源
      entry文档状态发起者来源
      导航时序类型
      navTimingType
  6. 在全局任务队列中排队导航和遍历任务源中,给定navigable活动窗口,以运行这些步骤:

    1. 如果navigable进行中的导航不再等于navigationId,则运行completionSteps并中止这些步骤。

    2. saveExtraDocumentState为true。

      通常,在我们最终填充entry文档状态文档的情况下,我们希望将该文档中的一些状态保存到entry中。这确保如果将来有对entry的遍历,其中其文档已被销毁,我们可以在创建新的文档时使用这些状态。

      但是,在某些特定情况下,保存状态将无济于事。在这些情况下,我们稍后在此算法中将saveExtraDocumentState设置为false。

    3. 如果navigationParams非fetch方案导航参数,则:

      1. entry文档状态文档设置为结果,运行尝试创建非fetch方案文档,给定navigationParams

        这可能导致将entry文档状态文档设置为null,例如,当移交给外部软件时。

      2. saveExtraDocumentState设置为false。

    4. 否则,如果以下任何一项为真:

      那么:

      1. entry文档状态文档设置为结果,创建没有DOM的内联内容文档,给定navigable、null和navTimingType。内联内容应向用户指示发生的错误类型。

      2. 使文档不可救,给定entry文档状态文档和"导航失败"。

      3. saveExtraDocumentState设置为false。

      4. 如果navigationParams不为null,则:

        1. 运行环境丢弃步骤,对于navigationParams保留环境

        2. 调用WebDriver BiDi导航失败,给定currentBrowsingContext和一个新的WebDriver BiDi导航状态,其idnavigationId状态是"已取消",urlnavigationParams响应URL

    5. 否则,如果navigationParams响应状态不是204且不是205,则将entry文档状态文档设置为结果,加载文档,给定navigationParamssourceSnapshotParamsentry文档状态发起者来源

      这可能导致将entry文档状态文档设置为null,例如,当移交给外部软件时。

    6. 如果entry文档状态文档非null,则:

      1. entry文档状态已填充设置为true。

      2. 如果saveExtraDocumentState为true:

        1. documententry文档状态文档

        2. entry文档状态来源设置为document来源

        3. 如果documentURL需要将策略容器存储在历史中,则:

          1. 断言navigationParams导航参数(即,不是null,也不是非fetch方案导航参数)。

          2. entry文档状态历史策略容器设置为navigationParams策略容器

      3. 如果entry文档状态请求引用是"client",并且navigationParams导航参数(即,不是null,也不是非fetch方案导航参数),则:

        1. 断言navigationParams请求不为null。

        2. entry文档状态请求引用设置为navigationParams请求引用

    7. 运行completionSteps

为了从srcdoc资源创建导航参数,给定一个会话历史条目entry,一个可导航navigable,一个目标快照参数targetSnapshotParams,一个导航ID或nullnavigationId,以及一个NavigationTimingTypenavTimingType

  1. documentResourceentry文档状态资源

  2. response为一个新的响应,其中:

    URL
    about:srcdoc
    头列表
    « (`Content-Type`,`text/html`) »
    主体
    UTF-8编码documentResource作为主体
  3. responseOrigin为结果,确定来源,给定responseURLtargetSnapshotParams沙盒标志entry文档状态来源

  4. coop为一个新的跨源打开者策略

  5. coopEnforcementResult为一个新的跨源打开者策略执行结果,其中:

    url
    responseURL
    来源
    responseOrigin
    跨源打开者策略
    coop
  6. policyContainer为结果,确定导航参数策略容器,给定responseURLentry文档状态历史策略容器、null、navigable容器文档策略容器,以及null。

  7. 返回一个新的导航参数,其中:

    id
    navigationId
    可导航
    navigable
    请求
    null
    响应
    response
    获取控制器
    null
    提交早期提示
    null
    COOP执行结果
    coopEnforcementResult
    保留环境
    null
    来源
    responseOrigin
    策略容器
    policyContainer
    最终沙盒标志集
    targetSnapshotParams沙盒标志
    跨源打开者策略
    coop
    导航时序类型
    navTimingType
    关于基础URL
    entry文档状态关于基础URL

为了通过获取创建导航参数,给定一个会话历史条目entry,一个可导航navigable,一个源快照参数sourceSnapshotParams,一个目标快照参数targetSnapshotParams,一个字符串cspNavigationType,一个导航ID或nullnavigationId,以及一个NavigationTimingTypenavTimingType,请执行以下步骤。这些步骤返回导航参数非fetch方案导航参数或null。

此算法会更改entry

  1. 断言:这在并行运行。

  2. documentResourceentry文档状态资源

  3. request为一个新的请求,其中:

    URL
    entryURL
    客户端
    sourceSnapshotParams获取客户端
    目标
    "document"
    凭证模式
    "include"
    使用URL凭证标志
    设置
    重定向模式
    "manual"
    替换客户端id
    navigable活动文档相关设置对象id
    模式
    "navigate"
    引用
    entry文档状态请求引用
    引用策略
    entry文档状态请求引用策略
  4. 如果documentResource是一个POST资源,则:

    1. request方法设置为`POST`。

    2. request主体设置为documentResource请求体

    3. 设置`Content-Type`为documentResource请求内容类型request头列表中。

  5. 如果entry文档状态重新加载挂起为true,则将request重新加载导航标志设置为true。

  6. 否则,如果entry文档状态已填充为true,则将request历史导航标志设置为true。

  7. 如果sourceSnapshotParams是否有临时激活为true,则将request用户激活设置为true。

  8. 如果navigable容器非空:

    1. 如果navigable容器具有一个浏览上下文范围来源,则将request来源设置为该浏览上下文范围来源

    2. request目标设置为navigable容器本地名称

    3. 如果sourceSnapshotParams获取客户端navigable容器文档相关设置对象,则将request发起者类型设置为navigable容器本地名称

      这确保只有容器发起的导航会报告给资源时序。

  9. response为null。

  10. responseOrigin为null。

  11. fetchController为null。

  12. coopEnforcementResult 为一个新的 跨域打开者策略执行结果,其属性为:

    url
    navigable活动文档URL
    origin
    navigable活动文档来源
    跨域打开者策略
    navigable活动文档跨域打开者策略
    当前上下文是导航源
    如果navigable活动文档来源entry文档状态发起者来源同源则为true,否则为false。
  13. finalSandboxFlags 为一个空的 沙盒标志集

  14. responsePolicyContainer 为 null。

  15. responseCOOP 为一个新的 跨域打开者策略

  16. locationURL 为 null。

  17. currentURLrequest当前URL

  18. commitEarlyHints 为 null。

  19. 当条件成立时:

    1. 如果 request保留客户端 不为 null 且 currentURL来源request保留客户端创建URL来源 不同,则:

      1. 运行 环境丢弃步骤request保留客户端

      2. request保留客户端 设置为 null。

      3. commitEarlyHints 设置为 null。

        预加载的链接来自 早期提示头 在同源重定向后保留在预加载缓存中,但在跨域重定向时会被丢弃。

    2. 如果 request保留客户端 为 null,则:

      1. topLevelCreationURLcurrentURL

      2. topLevelOrigin 为 null。

      3. 如果 navigable 不是一个 顶级遍历,则:

        1. parentEnvironmentnavigable活动文档相关设置对象

        2. topLevelCreationURL 设置为 parentEnvironment顶级创建URL

        3. topLevelOrigin 设置为 parentEnvironment顶级来源

      4. request保留客户端 设置为一个新的 环境,其 id 是一个唯一的不透明字符串,目标浏览上下文navigable活动浏览上下文创建URLcurrentURL顶级创建URLtopLevelCreationURL,且顶级来源topLevelOrigin

        创建的环境的 活动服务worker 在抓取期间如果请求URL匹配服务worker注册,则在处理抓取请求算法中设置。[SW]

    3. 如果给定 requestcspNavigationType内容安全策略应该阻止该类型的导航请求 的结果是"Blocked",则将 response 设置为 网络错误中断[CSP]

    4. response 设置为 null。

    5. 如果 fetchController 为 null,则将 fetchController 设置为 抓取 request 的结果,processEarlyHintsResponse 设置为下述 processEarlyHintsResponseprocessResponse 设置为下述 processResponseuseParallelQueue 设置为 true。

      processEarlyHintsResponse 为给定 earlyResponse 的下述算法:

      1. 如果 commitEarlyHints 为 null,则将 commitEarlyHints 设置为 处理早期提示头给定 earlyResponserequest保留客户端 的结果。

      processResponse 为给定 fetchedResponse 的下述算法:

      1. response 设置为 fetchedResponse

    6. 否则,处理下一个手动重定向fetchController

      这将在我们第一次迭代循环期间调用上述提供的 processResponse,从而设置 response

      导航手动处理重定向,因为导航是唯一关心重定向到mailto: URL等的地方。

    7. 等待直到 response 为非 null,或者 navigable正在进行的导航 变更为不再等于 navigationId

      如果发生后一个条件,则 中止 fetchController,并返回。

      否则,继续进行。

    8. 如果 request主体 为 null,则将 entry文档状态资源 设置为 null。

      抓取会在特定重定向时取消 主体

    9. responsePolicyContainer 设置为 从抓取响应创建策略容器 给定 responserequest保留客户端 的结果。

    10. finalSandboxFlags 设置为 集合并集targetSnapshotParams沙盒标志responsePolicyContainerCSP列表CSP派生沙盒标志 的结果。

    11. responseOrigin 设置为 确定来源 给定 responseURLfinalSandboxFlags,和 entry文档状态发起者来源 的结果。

      如果 response 是重定向,则 responseURL 将是导致重定向到 response位置URL 的URL;它不会是 位置URL 本身。

    12. 如果 navigable 是一个 顶级遍历,则:

      1. responseCOOP 设置为 获取跨域打开者策略 给定 responserequest保留客户端 的结果。

      2. coopEnforcementResult 设置为 执行响应的跨域打开者策略 给定 navigable活动浏览上下文responseURLresponseOriginresponseCOOPcoopEnforcementResultrequest引用者 的结果。

      3. 如果 finalSandboxFlags 不为空且 responseCOOP 不为"unsafe-none",则将 response 设置为一个适当的 网络错误中断

        这将导致网络错误,因为不能同时使用跨域打开者策略为响应提供一个干净的环境,并将导航到该响应的结果沙盒化。

    13. 如果 response 不是一个 网络错误navigable 是一个 子导航,并且执行 跨域资源策略检查 给定 navigable容器文档来源navigable容器文档相关设置对象request目标response,和 true 的结果是阻止,则将 response 设置为一个 网络错误中断

      这里我们对父导航而非navigable本身运行 跨域资源策略检查。因为我们关心嵌入内容对父上下文的同源性,而不是导航源。

    14. locationURL 设置为 response位置URL 给定 currentURL片段

    15. 如果 locationURL 为失败或 null,则 中断

    16. 断言locationURL 是一个 URL

    17. entry经典历史API状态 设置为 StructuredSerializeForStorage(null)。

    18. oldDocStateentry文档状态

    19. entry文档状态 设置为一个新的 文档状态,其属性为:

      历史策略容器
      如果它为非 null,则为 oldDocState历史策略容器克隆;否则为null
      请求引用者
      oldDocState请求引用者
      请求引用者策略
      oldDocState请求引用者策略
      发起者来源
      oldDocState发起者来源
      来源
      oldDocState来源
      about 基础URL
      oldDocStateabout 基础URL
      资源
      oldDocState资源
      曾经填充
      oldDocState曾经填充
      导航目标名称
      oldDocState导航目标名称

      对于导航情况,只有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
    20. 如果 locationURL方案 不是 HTTP(S)方案,则:

      1. entry文档状态资源 设置为 null。

      2. 中断

    21. currentURL 设置为 locationURL

    22. entryURL 设置为 currentURL

    到此循环结束时,我们将处于以下场景之一:

    • locationURL 为失败,因为无法解析的`Location`头。

    • locationURL 为 null,要么是因为 response 是一个 网络错误,要么是因为我们成功抓取了一个无`Location`头的非网络错误的HTTP(S)响应。

    • locationURL 是一个URL,其方案不是HTTP(S)。

  20. 如果 locationURL 是一个 URL,其 方案 不是 fetch 方案,则返回一个新的 非 fetch 方案导航参数,其属性为:

    id
    navigationId
    navigable
    navigable
    URL
    locationURL
    目标快照沙盒标志
    targetSnapshotParams沙盒标志
    源快照是否具有临时激活
    sourceSnapshotParams是否具有临时激活
    发起者来源
    responseOrigin
    导航计时类型
    navTimingType

    此时,request当前URL 是最后一个具有 URL 的重定向链中的 fetch 方案,在重定向到一个非 fetch 方案 URL 之前。这个 URL来源 将用于导航到非 fetch 方案 URL

  21. 如果以下任一条件成立:

    则返回 null。

    我们允许重定向到非 fetch 方案URL,但重定向到非 fetch 方案 URL 的重定向被视为网络错误。

  22. 断言locationURL 为 null 且 response 不是 网络错误

  23. resultPolicyContainer 设置为 确定导航参数策略容器给定 responseURLentry文档状态历史策略容器sourceSnapshotParams源策略容器,null和responsePolicyContainer

  24. 如果 navigable容器 是一个 iframe,且 response计时允许通过标志 已设置,则将 容器待定资源计时开始时间 设置为 null。

    如果 iframe 允许报告资源计时,则我们不需要运行其回退步骤,因为正常的报告会发生。

  25. 返回一个新的 导航参数,其属性为:

    id
    navigationId
    navigable
    navigable
    请求
    request
    响应
    response
    抓取控制器
    fetchController
    提交早期提示
    commitEarlyHints
    跨域打开者策略
    responseCOOP
    保留环境
    request保留客户端
    来源
    responseOrigin
    策略容器
    resultPolicyContainer
    最终沙盒标志集合
    finalSandboxFlags
    COOP 执行结果
    coopEnforcementResult
    导航计时类型
    navTimingType
    about 基础 URL
    entry文档状态about 基础 URL

一个元素有一个浏览上下文范围来源,如果它的 文档节点可导航 是一个 顶级可遍历对象,或者如果它的所有 文档祖先可导航对象 都有 活动文档,且这些活动文档的 来源 与该元素的 节点文档来源 相同。如果一个元素有一个 浏览上下文范围来源,那么它的值是该元素的 节点文档的来源

此定义有问题,需要调查其意图:见问题#4703

加载文档给定导航参数navigationParams源快照参数sourceSnapshotParams,和initiatorOrigin,执行以下步骤。它们返回一个文档或null。

  1. type 设置为 navigationParams计算的类型

  2. 如果用户代理已配置为使用除在可导航中渲染内容以外的某种机制来处理给定type的资源,则跳过此步骤。否则,如果type是以下类型之一:

    一个 HTML MIME 类型
    返回加载 HTML 文档的结果,给定navigationParams
    一个 XML MIME 类型,不是 明确支持的 XML MIME 类型
    返回加载 XML 文档的结果,给定navigationParamstype
    一个 JavaScript MIME 类型
    一个 JSON MIME 类型,不是 明确支持的 JSON MIME 类型
    "text/css"
    "text/plain"
    "text/vtt"
    返回加载文本文档的结果,给定navigationParamstype
    "multipart/x-mixed-replace"
    返回加载 multipart/x-mixed-replace 文档的结果,给定navigationParamssourceSnapshotParamsinitiatorOrigin
    一个支持的图像、视频或音频类型
    返回加载媒体文档的结果,给定navigationParamstype
    "application/pdf"
    "text/pdf"
    如果用户代理的PDF查看器支持为true,返回为没有DOM的内联内容创建文档的结果,给定navigationParams可导航

    否则,继续进行。

    明确支持的 XML MIME 类型 是一个 XML MIME 类型,用户代理配置为使用外部应用程序呈现内容,或者用户代理具有专用的处理规则。例如,具有内置 Atom 提要查看器的网络浏览器将被认为明确支持 application/atom+xml MIME 类型。

    明确支持的 JSON MIME 类型 是一个 JSON MIME 类型,用户代理配置为使用外部应用程序呈现内容,或者用户代理具有专用的处理规则。

    在这两种情况下,外部应用程序或用户代理将直接在navigationParams可导航内联显示内容,或将其交给外部软件。两者都在下面的步骤中进行。

  3. 否则,文档的type是这样的资源将不会影响navigationParams可导航,例如因为资源将交给外部应用程序,或者因为它是未知类型,将作为下载处理将其交给外部软件,给定navigationParams响应navigationParams可导航navigationParams最终沙盒标志集合sourceSnapshotParams是否具有临时激活,和initiatorOrigin

  4. 返回 null。

7.4.6应用历史步骤

对于导航和遍历,一旦我们确定了在会话历史中要前往的地方,很多工作都是将这一概念应用到可遍历的导航和相关的文档。对于导航,这项工作通常在过程的末尾进行;对于遍历,这是开始。

7.4.6.1更新可遍历

确保可遍历的导航最终到达正确的会话历史步骤尤其复杂,因为它可能涉及多个可遍历导航的子孙的协调,并行填充,然后同步以确保每个人对结果有相同的看法。这更复杂,因为存在同步的同文档导航与跨文档导航混合在一起,以及网页的某些相对时间预期。

改变可导航的连续状态用于在应用历史步骤算法期间存储信息,允许算法的一部分在其他部分完成后继续。它是一个结构,包含:

显示的文档
文档
目标条目
会话历史条目
可导航
可导航
仅更新
一个布尔值

尽管所有对可遍历的导航的更新最终都在同一个应用历史步骤算法中进行,每个可能的入口点都有一些小的定制:

对于给定可遍历的导航traversable可导航创建/销毁更新

  1. steptraversable当前会话历史步骤

  2. 返回将历史步骤step应用于traversable的结果,给定false、null、null、null和null。

对于给定非负整数step历史处理行为historyHandling应用推送/替换历史步骤

  1. 返回将历史步骤step应用于traversable的结果,给定false、null、null、null和historyHandling

应用推送/替换历史步骤从不传递源快照参数或发起可导航应用历史步骤。这是因为这些检查在导航算法中更早进行。

对于给定可遍历的导航traversable应用重新加载历史步骤

  1. steptraversable当前会话历史步骤

  2. 返回将历史步骤step应用于traversable的结果,给定true、null、null、null和"reload"。

应用重新加载历史步骤从不传递源快照参数或发起可导航应用历史步骤。这是因为重新加载始终被视为由navigable本身进行,即使在parent.location.reload()的情况下也是如此。

对于给定非负整数step可遍历的导航traversable,带有源快照参数sourceSnapshotParams可导航initiatorToCheck用户导航参与 userInvolvement应用遍历历史步骤

  1. 返回将历史步骤step应用于traversable的结果,给定true、sourceSnapshotParamsinitiatorToCheckuserInvolvement和"traverse"。


现在是算法本身。

对于给定非负整数step可遍历的导航traversable,带有布尔值checkForCancelation源快照参数-或-nullsourceSnapshotParams可导航-或-nullinitiatorToCheck用户导航参与-或-nulluserInvolvementForNavigateEvents导航类型-或-nullnavigationType,执行以下步骤。它们返回"initiator-disallowed"、"canceled-by-beforeunload"、"canceled-by-navigate"或"applied"。

  1. 断言:这是在traversable会话历史遍历队列中运行的。

  2. targetStep获取已用步骤的结果,给定traversablestep

  3. 如果initiatorToCheck不为null,则:

    1. 断言sourceSnapshotParams不为null。

    2. 对于每个navigable获取所有当前会话历史条目将更改或重新加载的可导航:如果initiatorToCheck被沙箱允许导航,则返回"initiator-disallowed"。

  4. navigablesCrossingDocuments获取所有可能经历跨文档遍历的可导航的结果,给定traversabletargetStep

  5. 如果checkForCancelation为true,并且检查卸载是否取消的结果不为"continue",则返回该结果。

  6. changingNavigables获取所有当前会话历史条目将更改或重新加载的可导航的结果,给定traversabletargetStep

  7. nonchangingNavigablesThatStillNeedUpdates获取所有仅需要历史对象长度/索引更新的可导航的结果,给定traversabletargetStep

  8. 对于每个changingNavigablesnavigable

    1. targetEntry获取目标历史条目的结果,给定navigabletargetStep

    2. navigable当前会话历史条目设置为targetEntry

    3. 设置正在进行的导航为"traversal"。

  9. totalChangeJobschangingNavigables大小

  10. completedChangeJobs为0。

  11. changingNavigableContinuations为一个空的队列,包含改变的可导航连续状态

    该队列用于将changingNavigables的操作分为两部分。具体来说,changingNavigableContinuations保存第二部分的数据。

  12. 对于 changingNavigables 中的每个 navigable,在 navigable活动窗口 上,根据 导航和遍历任务源 排队一个全局任务 以运行以下步骤:

    这组步骤分为两部分,以允许在文档卸载之前处理同步导航。状态存储在 changingNavigableContinuations 中用于第二部分

    1. displayedEntrynavigable活动会话历史条目

    2. targetEntrynavigable当前会话历史条目

    3. changingNavigableContinuation为一个改变的可导航连续状态,包含:

      显示的文档
      displayedEntry文档
      目标条目
      targetEntry
      可导航
      navigable
      仅更新
      false
    4. 如果displayedEntrytargetEntry,且targetEntry文档状态重新加载挂起为false,则:

      1. changingNavigableContinuation仅更新设置为true。

      2. changingNavigableContinuation加入队列changingNavigableContinuations

      3. 中止这些步骤。

      这种情况发生是由于同步导航已经更新了活动会话历史条目

    5. 切换navigationType

      "reload"

      断言targetEntry文档状态重新加载挂起为true。

      "traverse"

      断言targetEntry文档状态曾经填充为true。

      "replace"

      断言targetEntry步骤displayedEntry步骤相同,且targetEntry文档状态曾经填充为false。

      "push"

      断言targetEntry步骤displayedEntry步骤+ 1,且targetEntry文档状态曾经填充为false。

    6. oldOrigintargetEntry文档状态起源

    7. 如果以下所有条件都为真:

      则:

      1. 断言userInvolvementForNavigateEvents不为null。

      2. navigationnavigable活动窗口导航API

      3. 触发一个遍历navigate事件,给定navigationtargetEntryuserInvolvementForNavigateEvents

    8. 如果targetEntry文档为null,或者targetEntry文档状态重新加载挂起为true,则:

      1. navTimingType为"back_forward",如果targetEntry文档为null;否则为"reload"。

      2. targetSnapshotParams快照目标快照参数的结果,给定navigable

      3. potentiallyTargetSpecificSourceSnapshotParamssourceSnapshotParams

      4. 如果potentiallyTargetSpecificSourceSnapshotParams为null,则将其设置为快照源快照参数的结果,给定navigable活动文档

        在这种情况下,没有明确的遍历/重新加载来源。我们将这种情况视为navigable自己导航,但注意targetEntry的原始发起者的某些属性保留在targetEntry文档状态中,例如发起者起源引用来源,这将适当地影响导航。

      5. targetEntry文档状态重新加载挂起设置为false。

      6. allowPOSTtargetEntry文档状态重新加载挂起

      7. 并行尝试填充历史条目的文档,给定targetEntrynavigablepotentiallyTargetSpecificSourceSnapshotParamstargetSnapshotParams,带有allowPOST设置为allowPOST完成步骤,在navigable活动窗口上的导航和遍历任务源上排队一个全局任务,以执行afterDocumentPopulated

      否则,立即运行afterDocumentPopulated

      在这两种情况下,让afterDocumentPopulated为以下步骤:

      1. 如果targetEntry文档为null,则将changingNavigableContinuation仅更新设置为true。

        这意味着我们尝试填充文档,但未能成功,例如服务器返回204。

        这些类型的导航或遍历失败将不会通过任何导航API(例如,任何导航API方法跟踪器的承诺或navigateerror事件)传达给导航API。这么做会泄露跨起源情况下其他起源响应时间的信息,并且在跨起源与同起源情况下提供不同的结果被认为太过混乱。

        然而,实现可能会利用这个机会清除任何navigation.transition.finished承诺的处理程序,因为此时它们保证永远不会运行。而且,它们可能希望向控制台报告警告,如果导航API的任何部分发起了这些导航,以使网络开发人员明白为什么他们的承诺永远不会解决和事件永远不会触发。

      2. 如果targetEntry文档起源oldOrigin不同,则将targetEntry经典历史API状态设置为StructuredSerializeForStorage(null)。

        这会在起源与之前加载的targetEntry未发生重定向的情况下发生变化时清除历史状态。这可能是由于CSP沙箱标头的更改。

      3. 如果以下所有条件都为真:

        则将targetEntry文档状态导航目标名称设置为空字符串。

      4. changingNavigableContinuation加入队列changingNavigableContinuations

        此作业的其余部分稍后在此算法中运行。

  13. navigablesThatMustWaitBeforeHandlingSyncNavigation为一个空的集合

  14. completedChangeJobs不等于totalChangeJobs时:

    1. 如果traversable正在运行嵌套应用历史步骤为false,则:

      1. traversable会话历史遍历队列算法集合包含一个或多个同步导航步骤,其目标可导航不包含在navigablesThatMustWaitBeforeHandlingSyncNavigation中时:

        1. stepstraversable会话历史遍历队列算法集合中的第一个项目,它是同步导航步骤,其目标可导航不包含在navigablesThatMustWaitBeforeHandlingSyncNavigation中。

        2. traversable会话历史遍历队列算法集合中移除steps

        3. traversable正在运行嵌套应用历史步骤设置为true。

        4. 运行steps

        5. traversable正在运行嵌套应用历史步骤设置为false。

        在此遍历之前意图发生的同步导航在此点跳过队列,以便它们可以在此遍历可能卸载其文档之前加入traversable会话历史条目中的正确位置。更多细节请参阅此处

    2. changingNavigableContinuationchangingNavigableContinuations中出列的结果。

    3. 如果changingNavigableContinuation为空,则继续

    4. displayedDocumentchangingNavigableContinuation显示的文档

    5. targetEntrychangingNavigableContinuation目标条目

    6. navigablechangingNavigableContinuation可导航

    7. 让(scriptHistoryLengthscriptHistoryIndex)为获取历史对象长度和索引的结果,给定traversabletargetStep

      这些值可能已更改自上次计算以来。

    8. 附加navigablenavigablesThatMustWaitBeforeHandlingSyncNavigation

      一旦可导航到达遍历中的此点,另外排队的同步导航步骤很可能是意图在此遍历之后而不是之前发生,因此它们不再跳过队列。更多细节请参阅此处

    9. entriesForNavigationAPI获取导航API的会话历史条目的结果,给定navigabletargetStep

    10. 如果changingNavigableContinuation仅更新为true,或targetEntry文档displayedDocument,则:

      这是一个同文档导航:我们在不卸载的情况下继续。

      1. 设置正在进行的导航navigable为null。

        这允许新的导航开始,而在遍历期间它们被阻止。

      2. 排队一个全局任务navigable活动窗口 上,根据 导航和遍历任务源 以执行 afterPotentialUnloads

    11. 否则:

      1. 断言navigationType不为null。

      2. 停用文档以进行跨文档导航,给定displayedDocumentuserNavigationInvolvementtargetEntrynavigationTypeafterPotentialUnloads

    12. 在两种情况下,让afterPotentialUnloads为以下步骤:

      1. 如果changingNavigableContinuation仅更新为false,则激活历史条目targetEntry,对于navigable

      2. updateDocument为一个算法步骤,执行更新文档以应用历史步骤,给定targetEntry文档targetEntrychangingNavigableContinuation仅更新scriptHistoryLengthscriptHistoryIndexnavigationTypeentriesForNavigationAPIdisplayedEntry

      3. 如果targetEntry文档等于displayedDocument,则执行updateDocument

      4. 否则,在 targetEntry文档相关全局对象 上,根据 导航和遍历任务源 排队一个全局任务 以执行 updateDocument

      5. 递增completedChangeJobs

  15. totalNonchangingJobs大小nonchangingNavigablesThatStillNeedUpdates

    此步骤起故意等待所有先前的操作完成,因为它们包括处理同步导航,这些导航也会发布任务以更新历史长度和索引。

  16. completedNonchangingJobs为0。

  17. 让(scriptHistoryLengthscriptHistoryIndex)为获取历史对象长度和索引的结果,给定traversabletargetStep

  18. 对于 nonchangingNavigablesThatStillNeedUpdates 中的每个 navigable,在 navigable活动窗口 上,根据 导航和遍历任务源 排队一个全局任务 以运行以下步骤:

    1. documentnavigable活动文档

    2. document历史对象索引设置为scriptHistoryIndex

    3. document历史对象长度设置为scriptHistoryLength

    4. 递增completedNonchangingJobs

  19. 等待completedNonchangingJobs等于totalNonchangingJobs

  20. traversable当前会话历史步骤设置为targetStep

  21. 返回"applied"。

停用文档以进行跨文档导航,给定一个DocumentdisplayedDocument,一个用户导航参与userNavigationInvolvement,一个会话历史条目targetEntry,一个NavigationTypenavigationType和一个afterPotentialUnloads,它是一个不接收参数的算法:

  1. navigabledisplayedDocument节点可导航

  2. potentiallyTriggerViewTransition为false。

  3. isBrowserUINavigation为true,如果userNavigationInvolvement是"浏览器UI";否则为false。

  4. potentiallyTriggerViewTransition设置为调用导航是否可以触发跨文档视图转换?的结果,给定displayedDocumenttargetEntry文档navigationTypeisBrowserUINavigation

  5. 如果potentiallyTriggerViewTransition为false,则:

    1. firePageSwapBeforeUnload为以下步骤:

      1. 触发pageswap事件,给定displayedDocumenttargetEntrynavigationType和null。

    2. 设置正在进行的导航navigable为null。

      这允许新的导航开始,而在遍历期间它们被阻止。

    3. 卸载文档及其后代,给定displayedDocumenttargetEntry文档afterPotentialUnloadsfirePageSwapBeforeUnload

  6. 否则,在 navigable活动窗口 上,根据 导航和遍历任务源 排队一个全局任务 以运行以下步骤:

    1. proceedWithNavigationAfterViewTransitionCapture为以下步骤:

      1. 将以下会话历史遍历步骤附加navigable可遍历可导航

        1. 设置正在进行的导航navigable为null。

          这允许新的导航开始,而在遍历期间它们被阻止。

        2. 卸载文档及其后代,给定displayedDocumenttargetEntry文档afterPotentialUnloads

    2. viewTransition设置跨文档视图转换的结果,给定displayedDocumenttargetEntry文档navigationTypeproceedWithNavigationAfterViewTransitionCapture

    3. 触发pageswap事件,给定displayedDocumenttargetEntrynavigationTypeviewTransition

    4. 如果viewTransition为null,则运行proceedWithNavigationAfterViewTransitionCapture

      在视图转换开始的情况下,视图转换算法负责调用proceedWithNavigationAfterViewTransitionCapture

触发pageswap事件,给定一个DocumentdisplayedDocument,一个会话历史条目targetEntry,一个NavigationTypenavigationType和一个ViewTransition-或-nullviewTransition

  1. 断言:这是作为在displayedDocument相关代理事件循环上排队的一个任务的一部分运行的。

  2. navigationdisplayedDocument相关全局对象导航API

  3. activation为null。

  4. 如果以下所有条件都为真:

    则:

    1. 通过切换navigationType确定destinationEntry

      "reload"

      navigation当前条目

      "traverse"

      navigation条目列表中的NavigationHistoryEntry,其会话历史条目targetEntry

      "push"
      "replace"

      displayedDocument相关领域中的一个新的NavigationHistoryEntry,其会话历史条目设置为targetEntry

    2. activation设置为在displayedDocument相关领域中创建的一个新的新的NavigationActivation,其中

      旧条目
      navigation当前条目
      新条目
      destinationEntry
      导航类型
      navigationType

    这意味着导航期间的跨起源重定向将导致旧文档的激活为空的PageSwapEvent,除非从bfcache恢复新文档。

  5. 触发一个事件,名为pageswap,在displayedDocument相关全局对象上,使用PageSwapEvent,其激活设置为activation,其viewTransition设置为viewTransition

激活会话历史条目session history entryentry,用于navigablenavigable

  1. 保存持久化状态navigable活动会话历史条目

  2. newDocumententry文档

  3. 断言newDocument初始about:blank为false,即我们永远不会回到初始about:blankDocument,因为当我们导航离开它时,它总是被替换

  4. 设置navigable活动会话历史条目entry

  5. 激活newDocument

获取使用的步骤,给定可遍历的可导航对象traversable和一个非负整数step,执行以下步骤。它们返回一个非负整数。

  1. steps获取所有使用过的历史步骤traversable中。

  2. 返回steps中小于或等于step的最大项目

    这适用于没有step会话历史条目的情况,因为移除了navigable

获取历史对象的长度和索引,给定可遍历的可导航对象traversable和一个非负整数step,执行以下步骤。它们返回一个元组,包含两个非负整数。

  1. steps获取所有使用过的历史步骤traversable中。

  2. scriptHistoryLengthsteps大小

  3. 断言steps包含step

    假设step已通过获取使用的步骤进行调整。

  4. scriptHistoryIndexstepsteps中的索引。

  5. 返回(scriptHistoryLength, scriptHistoryIndex)。

获取所有当前会话历史条目将更改或重新加载的可导航对象,给定可遍历的可导航对象traversable和一个非负整数targetStep,执行以下步骤。它们返回一个列表,包含navigables

  1. results为一个空的列表

  2. navigablesToCheck为« traversable »。

    此列表将在下面的循环中扩展。

  3. 对每个navigablenavigablesToCheck中:

    1. targetEntry获取目标历史条目的结果,给定navigabletargetStep

    2. 如果targetEntry不是navigable当前会话历史条目targetEntry文档状态重新加载挂起为true,则附加navigableresults

    3. 如果targetEntry文档navigable文档,且targetEntry文档状态重新加载挂起为false,则扩展navigablesToChecknavigable子可导航对象

      子可导航对象添加到navigablesToCheck意味着这些可导航对象也将在此循环中被检查。只有在navigable活动文档不会在此遍历中更改时才会检查子可导航对象

  4. 返回results

获取仅需要历史对象长度/索引更新的所有可导航对象,给定可遍历的可导航对象traversable和一个非负整数targetStep,执行以下步骤。它们返回一个列表,包含navigables

其他可导航对象可能不会受到遍历的影响。例如,如果响应为204,当前活动文档将保持不变。此外,导航到204之后的“返回”操作将更改当前会话历史条目,但活动会话历史条目将已是正确的。

  1. results为一个空的列表

  2. navigablesToCheck为« traversable »。

    此列表将在下面的循环中扩展。

  3. 对每个navigablenavigablesToCheck中:

    1. targetEntry获取目标历史条目的结果,给定navigabletargetStep

    2. 如果targetEntrynavigable当前会话历史条目targetEntry文档状态重新加载挂起为false,则:

      1. 附加navigableresults

      2. 扩展navigablesToChecknavigable子可导航对象

        子可导航对象添加到navigablesToCheck意味着这些可导航对象也将在此循环中被检查。只有在navigable活动文档不会在此遍历中更改时才会检查子可导航对象

  4. 返回results

获取目标历史条目,给定navigablenavigable和一个非负整数step,执行以下步骤。它们返回一个会话历史条目

  1. entries获取会话历史条目的结果,给navigable

  2. 返回entries中具有最大值的项目,其步骤小于或等于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,但不会返回其子可导航对象。这些将被卸载,而不是遍历。

  1. results为一个空的列表

  2. navigablesToCheck为« traversable »。

    此列表将在下面的循环中扩展。

  3. 对每个navigablenavigablesToCheck中:

    1. targetEntry获取目标历史条目的结果,给定navigabletargetStep

    2. 如果targetEntry文档不是navigable文档targetEntry文档状态重新加载挂起为true,则附加navigableresults

      尽管navigable活动历史条目可以同步更改,但 新条目将始终具有相同的文档,因此访问navigable文档是可靠的。

    3. 否则,扩展navigablesToChecknavigable子可导航对象

      子可导航对象添加到navigablesToCheck意味着这些可导航对象也将在此循环中被检查。只有在navigable活动文档不会在此遍历中更改时才会检查子可导航对象

  4. 返回results

7.4.6.2 更新文档

更新历史步骤应用的文档,给定Documentdocument会话历史条目entry,布尔值doNotReactivate,整数scriptHistoryLengthscriptHistoryIndexNavigationType-或-nullnavigationType,一个可选的列表,包含会话历史条目entriesForNavigationAPI,和一个可选的会话历史条目previousEntryForActivation

  1. 如果document最新条目为null,则设documentIsNew为true;否则为false。

  2. 如果document最新条目不是entry,则设documentsEntryChanged为true;否则为false。

  3. document历史对象索引设为scriptHistoryIndex

  4. document历史对象长度设为scriptHistoryLength

  5. navigationhistory相关全局对象导航API

  6. 如果documentsEntryChanged为true,则:

    1. oldURLdocument最新条目URL

    2. document最新条目设为entry

    3. 恢复历史对象状态,给定documententry

    4. 如果documentIsNew为false,则:

      1. 断言navigationType不是null。

      2. 更新相同文档导航的导航API条目,给定navigationentrynavigationType

      3. 触发名为popstate的事件,在document相关全局对象上,使用PopStateEvent,其中state属性初始化为document历史对象状态,并且hasUAVisualTransition初始化为true,如果用户代理执行了可视化过渡,以显示document最新条目的缓存渲染状态。

      4. 恢复持久化状态,给定entry

      5. 如果oldURL片段不等于entryURL片段,则document的相关全局对象上排队一个全局任务,在DOM操作任务源触发名为hashchange的事件,在document相关全局对象上,使用HashChangeEvent,其中oldURL属性初始化为oldURL序列化值,newURL属性初始化为entryURL序列化值。

    5. 否则:

      1. 断言entriesForNavigationAPI被提供。

      2. 恢复持久化状态,给定entry

      3. 初始化新文档的导航API条目,给定navigationentriesForNavigationAPIentry

  7. 如果以下条件都为真:

    则:

    1. 如果navigation激活为null,则将navigation激活设为一个新的NavigationActivation对象,在navigation相关领域中。

    2. previousEntryIndex为在navigation获取导航API条目索引的结果,给定previousEntryForActivation

    3. 如果previousEntryIndex是非负的,则将activation旧条目设为navigation条目列表[previousEntryIndex]。

    4. 否则,如果以下条件都为真:

      则将activation旧条目设为一个新的NavigationHistoryEntry,在navigation相关领域中,其会话历史条目previousEntryForActivation

    5. activation新条目设为navigation当前条目

    6. activation导航类型设为navigationType

  8. 如果documentIsNew为true,则:

    1. 尝试滚动到片段,给定document

    2. 此时脚本可能会运行新创建的文档document

  9. 否则,如果documentsEntryChanged为false且doNotReactivate为false,则:

    1. 断言entriesForNavigationAPI被提供。

    2. 重新激活,给定documententryentriesForNavigationAPI

    documentsEntryChanged可以为false,原因之一是我们从bfcache恢复,或者我们异步完成了同步导航,这已经同步设置了document最新条目。参数doNotReactivate区分了这两种情况。

恢复历史对象状态,给定Documentdocument会话历史条目entry

  1. targetRealmdocument相关领域

  2. state结构化反序列化(entry经典历史API状态targetRealm)。如果抛出异常,捕获它并让state为null。

  3. document历史对象状态设为state

激活一个Documentdocument

  1. windowdocument相关全局对象

  2. document浏览上下文WindowProxy[[Window]]内部槽值设为window

  3. document可见性状态设为document节点导航可遍历导航系统可见性状态

  4. 排队 一个新的 VisibilityStateEntry,其 可见性状态document可见性状态,其 时间戳 为零。

  5. window相关设置对象执行准备标志设为true。

重新激活一个Documentdocument,给定会话历史条目reactivatedEntry和一个列表,包含会话历史条目entriesForNavigationAPI

此算法在documentbfcache恢复后更新,即再次完全激活之后。其他规范如果希望监视此更改为完全激活状态的变化,建议将步骤添加到此算法中,以便清楚地了解由于此更改而发生的事件顺序。

  1. 对于document中具有off自动填充字段名称的每个表单控件,调用重置算法,给定formControl

  2. 如果document暂停的计时器句柄不是

    1. 断言document暂停时间不为零。

    2. suspendDuration当前高分辨率时间减去document暂停时间

    3. activeTimersdocument相关全局对象活动计时器映射

    4. 对于document暂停计时器句柄中的每个handle,如果activeTimers[handle]存在,则增加activeTimers[handle]的值,增加suspendDuration

  3. 更新重新激活的导航API条目,给定document相关全局对象导航APIentriesForNavigationAPIreactivatedEntry

  4. 如果document当前文档就绪状态是"complete",并且document页面显示标志为false,则:

    1. document页面显示标志设为true。

    2. document已显示标志设为false。

    3. 更新文档的可见性状态为"visible"。

    4. 触发一个页面过渡事件,名为pageshow,在document相关全局对象上,带有true。

尝试滚动到片段,给定一个Documentdocument,请执行以下步骤并行

  1. 等待一个实现定义的时间。(这旨在允许用户代理在面对性能问题时优化用户体验。)

  2. document的相关全局对象上排队一个全局任务,在导航和遍历任务源上运行这些步骤:

    1. 如果document没有解析器,或其解析器已停止解析,或用户代理有理由认为用户不再感兴趣于滚动到片段,则中止这些步骤。

    2. 滚动到片段,给定document

    3. 如果document指示部分仍为null,则尝试滚动到片段,给定document

使文档不可挽救,给定一个Documentdocument和一个字符串reason

  1. details成为一个新的未恢复原因详情,其原因reason

  2. 附加 detailsdocumentbfcache 阻止详情

  3. document可挽救状态设为false。

为文档状态建立未恢复的原因,给定Documentdocument

  1. notRestoredReasonsForDocument成为一个新的未恢复原因

  2. notRestoredReasonsForDocumentURL设为documentURL

  3. 如果document节点导航容器是一个iframe元素,则:

    1. notRestoredReasonsForDocumentsrc设为document节点导航容器src属性的值。

    2. notRestoredReasonsForDocumentid设为document节点导航容器id属性的值。

    3. notRestoredReasonsForDocumentname设为document节点导航容器name属性的值。

  4. notRestoredReasonsForDocument原因设为document克隆副本bfcache阻止详情

  5. 对于document文档树子导航中的每个navigable

    1. childDocumentnavigable活动文档

    2. 为文档状态建立未恢复的原因,给定childDocument

    3. childDocument未恢复原因附加到notRestoredReasonsForDocument子级

  6. document节点导航活动会话历史条目文档状态未恢复原因设为notRestoredReasonsForDocument

为顶级可遍历及其后代建立未恢复的原因,给定顶级可遍历topLevelTraversable

  1. 为文档状态建立未恢复的原因,给定topLevelTraversable活动文档

  2. crossOriginDescendants为一个空的列表

  3. 对于topLevelTraversable活动文档后代导航中的每个childNavigable

    1. 如果childNavigable活动文档起源topLevelTraversable活动文档起源不同,则childNavigable附加到crossOriginDescendants

  4. crossOriginDescendantsPreventsBfcache为false。

  5. 对于crossOriginDescendants中的每个crossOriginNavigable

    1. reasonsForCrossOriginChildcrossOriginNavigable活动文档文档状态未恢复原因

    2. 如果reasonsForCrossOriginChild原因不为空,则将crossOriginDescendantsPreventsBfcache设为true。

    3. reasonsForCrossOriginChildURL设为null。

    4. reasonsForCrossOriginChild原因设为null。

    5. reasonsForCrossOriginChild子级设为null。

  6. 如果crossOriginDescendantsPreventsBfcache为true,则使文档不可挽救,给定topLevelTraversable活动文档和"masked"。

7.4.6.3 显示文档

一个Document有一个布尔值已显示,最初为false。它用于确保pagereveal事件在每次激活Document时触发一次(初次渲染时一次,以及每次重新激活时一次)。

显示一个Documentdocument

  1. 如果document已显示为true,则返回。

  2. document已显示设为true。

  3. transition解析跨文档视图转换的结果,针对document

  4. 触发一个事件,命名为pagereveal,在document相关全局对象上,使用PageRevealEvent,并将其viewTransition设置为transition

  5. 如果transition不为null,则:

    1. 准备运行脚本,给定 document相关设置对象

    2. 激活 transition

    3. 运行脚本后清理,给定 document相关设置对象

    激活视图转换可能会解析/拒绝承诺,因此通过包装准备/清理激活,我们确保在下一个渲染步骤之前处理这些承诺。

尽管pagereveal保证在显示页面的最新版本的第一个更新渲染步骤中触发,但用户代理可以在触发之前显示页面的缓存帧。这可以防止pagereveal处理程序的存在延迟此类缓存帧的显示。

7.4.6.4 滚动到片段

滚动到片段,给定一个Document document

  1. 如果document指示部分为null,则将document目标元素设为null。

  2. 否则,如果document指示部分文档顶部,则:

    1. document目标元素设为null。

    2. 滚动到文档的开头,针对document[CSSOMVIEW]

    3. 返回。

  3. 否则:

    1. 断言document指示部分是一个元素。

    2. target设为document指示部分

    3. document目标元素设为target

    4. 运行祖先详情显示算法,针对target

    5. 运行祖先隐藏直到找到显示算法,针对target

    6. 滚动target进入视图behavior设为“auto”,block设为“start”,inline设为“nearest”。[CSSOMVIEW]

    7. 运行聚焦步骤,针对targetDocument视口作为fallback target

    8. 移动顺序焦点导航起点target

一个Document指示部分是其URL片段所标识的部分,或如果片段未标识任何内容则为null。片段的语义在将其映射到节点时由定义Document所使用的MIME类型的规范定义(例如,片段的处理对于XML MIME类型是由RFC7303负责的)。[RFC7303]

每个Document也有一个目标元素,用于定义:target伪类并由上述算法更新。初始为null。

对于一个HTML文档 document,其指示部分是给定documentdocumentURL选择指示部分的结果。

选择指示部分,给定一个Document document和一个URL url

  1. 如果documentURL等于 url,并且排除片段设置为true,则返回null。

  2. fragment设为url片段

  3. 如果fragment是空字符串,则返回特殊值文档顶部

  4. potentialIndicatedElement设为找到的潜在指示元素的结果,给定documentfragment

  5. 如果potentialIndicatedElement不为null,则返回potentialIndicatedElement

  6. fragmentBytes设为百分比解码 fragment的结果。

  7. decodedFragment设为运行无BOM的UTF-8解码fragmentBytes上的结果。

  8. potentialIndicatedElement设为找到的潜在指示元素的结果,给定documentdecodedFragment

  9. 如果potentialIndicatedElement不为null,则返回potentialIndicatedElement

  10. 如果decodedFragment与字符串top进行ASCII不区分大小写匹配,则返回文档顶部

  11. 返回null。

找到潜在的指示元素,给定一个Document document和一个字符串fragment,运行以下步骤:

  1. 如果有一个元素在文档树中,其document并且其ID等于fragment,则返回文档树中第一个这样的元素。

  2. 如果有一个a元素在文档树中,其document并且其name属性的值等于fragment,则返回文档树中第一个这样的元素。

  3. 返回null。

7.4.6.5 持久化历史条目状态

要将持久化状态保存会话历史条目 entry

  1. 设置entry滚动位置数据,以包含entry文档的所有可恢复滚动区域的滚动位置。

  2. 可选地,更新entry持久化用户状态,以反映用户代理希望持久化的任何状态,例如表单字段的值。

要从会话历史条目 entry恢复持久化状态

  1. 如果entry滚动恢复模式是“auto”,并且entry文档相关全局对象导航API在进行中的导航期间抑制正常滚动恢复为假,则恢复滚动位置数据,给定entry

    用户代理不恢复滚动位置并不意味着滚动位置将保持在任何特定值(例如(0,0))。实际的滚动位置取决于导航类型和用户代理的特定缓存策略。因此,Web应用程序不能假定任何特定的滚动位置,而是建议将其设置为所需的值。

    如果在进行中的导航期间抑制正常滚动恢复为真,则恢复滚动位置数据可能仍会在稍后作为相关NavigateEvent完成的一部分发生,或者通过navigateEvent.scroll()方法调用。

  2. 可选地,更新entry文档及其渲染的其他方面,例如用户代理先前在entry持久化用户状态中记录的表单字段的值。

    这甚至可以包括更新dir属性,textarea元素或input元素的type属性在文本搜索电话URL电子邮件状态,如果持久化状态包括这些控件中用户输入的方向性。

    作为此过程的一部分恢复表单控件的值不会触发任何inputchange事件,但可以触发与表单相关的自定义元素formStateRestoreCallback


每个Document都有一个布尔值已被用户滚动,初始值为假。如果用户滚动文档,用户代理必须将该文档的已被用户滚动设置为真。

Document可恢复滚动区域document视口,以及所有document的可滚动区域,不包括任何可导航容器

子导航滚动恢复作为这些导航Document会话历史条目的状态恢复的一部分进行处理。

恢复滚动位置数据,给定一个会话历史条目 entry

  1. document设为entry文档

  2. 如果document已被用户滚动为真,则用户代理应返回。

  3. 用户代理应尝试使用entry滚动位置数据恢复entry文档可恢复滚动区域的滚动位置。用户代理可能会继续尝试定期执行此操作,直到document已被用户滚动变为真。

    这被表述为一种尝试,可能会重复直到成功或用户滚动,因为滚动位置数据指示的相关内容可能需要一些时间从网络加载。

    滚动恢复可能会受到滚动锚定的影响。[CSSSCROLLANCHORING]

7.5 文档生命周期

7.5.1 共享文档创建基础设施

使用以下算法之一加载文档时,我们使用以下步骤来创建并初始化一个Document对象,给定一个类型 type内容类型 contentType,以及导航参数 navigationParams

Document对象在创建新的浏览上下文和文档时也会创建;此算法从不创建这样的初始about:blank Document。此外,可以通过各种API创建无浏览上下文Document对象,例如document.implementation.createHTMLDocument()

  1. browsingContext成为navigationParams可导航对象活动浏览上下文

  2. 根据browsingContextnavigationParams最终沙盒标志集navigationParams跨源打开者策略以及navigationParamsCOOP执行结果,将browsingContext设置为获取用于导航响应的浏览上下文的结果。

    这可能会导致浏览上下文组切换,在这种情况下,browsingContext将是一个新创建的浏览上下文,而不是navigationParams可导航对象活动浏览上下文。在这种情况下,创建的WindowDocument代理将不会被使用;由于创建的Document来源是不透明的不透明,我们将在本算法稍后创建一个新的代理Window以配合新的Document

  3. permissionsPolicy成为根据navigationParams可导航对象容器navigationParams来源navigationParams响应创建权限策略的结果。[PERMISSIONSPOLICY]

    创建权限策略算法使用传递的来源。如果document.domain已被用于navigationParams可导航对象容器文档,则其来源不能与传递的来源为同源域,因为这些步骤在document创建之前运行,因此它本身尚未使用document.domain。请注意,这意味着权限策略检查比进行同源检查要不那么宽松。

    请参见下面的一些实际示例。

  4. creationURL成为navigationParams响应URL

  5. 如果navigationParams请求非空,则将creationURL设置为navigationParams请求当前URL

  6. window为空。

  7. 如果browsingContext活动文档初始about:blank为真,并且browsingContext活动文档来源navigationParams来源同源域,则将window设置为browsingContext活动窗口

    这意味着无论是初始about:blank Document,还是即将创建的新Document,它们都将共享同一个Window对象。

  8. 否则:

    1. oacHeader成为从navigationParams响应标头列表中获取“Origin-Agent-Cluster”的结构化字段值的结果。

    2. 如果oacHeader不为空且oacHeader[0]为布尔值真,则让requestsOAC为真;否则为假。

    3. 如果navigationParams保留环境是一个非安全上下文,则将requestsOAC设置为假。

    4. agent成为根据navigationParams来源browsingContextrequestsOAC获取的相似来源窗口代理的结果。

    5. 根据agent和以下自定义项创建一个新领域的结果,让realmExecutionContext成为:

      • 对于全局对象,创建一个新的Window对象。

      • 对于全局this绑定,使用browsingContextWindowProxy对象。

    6. window设置为realmExecutionContext领域组件的全局对象

    7. topLevelCreationURL成为creationURL

    8. topLevelOrigin成为navigationParams来源

    9. 如果navigable容器不为空,则:

      1. parentEnvironment成为navigable容器相关设置对象

      2. topLevelCreationURL设置为parentEnvironment顶级创建URL

      3. topLevelOrigin设置为parentEnvironment顶级来源

    10. 使用creationURLrealmExecutionContextnavigationParams保留环境topLevelCreationURLtopLevelOrigin设置窗口环境设置对象

    这通常是新Document将要创建时的情况,它将获得一个新的Window

  9. loadTimingInfo成为一个新的文档加载计时信息,其导航开始时间设置为navigationParams响应计时信息开始时间

  10. document成为一个新的Document,具有以下属性:

    类型
    type
    内容类型
    contentType
    来源
    navigationParams来源
    浏览上下文
    browsingContext
    策略容器
    navigationParams政策容器
    权限策略
    permissionsPolicy
    活动沙盒标志集
    navigationParams最终沙盒标志集
    打开者策略
    navigationParams跨源打开者策略
    加载计时信息
    loadTimingInfo
    通过跨源重定向创建
    navigationParams响应具有跨源重定向
    用于WebDriver BiDi的加载中导航ID
    navigationParamsID
    URL
    creationURL
    当前文档就绪状态
    "loading"
    关于基本URL
    navigationParams关于基本URL
    允许声明性Shadow Root
    true
  11. window关联Document设置为document

  12. Document运行CSP初始化,给定document[CSP]

  13. 如果navigationParams请求非空,则:

    1. document引用设置为空字符串。

    2. referrer成为navigationParams请求引用

    3. 如果referrerURL记录,则将document引用设置为referrer序列化

      根据Fetch,此时referrer将是一个URL记录或"no-referrer"。

  14. 如果navigationParamsfetch控制器不为空,则:

    1. fullTimingInfo成为从navigationParamsfetch控制器提取完整计时信息的结果。

    2. 如果navigationParams响应具有跨源重定向为真,则让redirectCount为0;否则让redirectCount成为navigationParams请求重定向计数

    3. 根据fullTimingInforedirectCountnavigationTimingTypenavigationParams响应服务worker计时信息以及navigationParams响应主体信息创建导航计时条目

  15. 根据navigationParams响应计时信息redirectCountnavigationParams导航计时类型navigationParams响应服务worker计时信息创建导航计时条目

  16. 如果navigationParams响应具有“刷新”标头,则:

    1. value成为标头值的等值解码

    2. 使用documentvalue运行共享声明性刷新步骤

    我们目前没有处理多个“刷新”标头的规范。这在issue #2900中被跟踪。

  17. 如果navigationParams提交早期提示不为空,则使用document调用navigationParams提交早期提示

  18. 根据documentnavigationParams响应和“pre-media处理链接标头

  19. 返回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:

  1. html创建元素的结果,给定documenthtmlHTML命名空间

  2. head创建元素的结果,给定documentheadHTML命名空间

  3. body创建元素的结果,给定documentbodyHTML命名空间

  4. html追加到document

  5. head追加到html

  6. body追加到html

7.5.2 加载 HTML 文档

为了加载HTML文档,给定导航参数 navigationParams:

  1. document成为创建和初始化Document对象的结果,给定"html"、"text/html"和 navigationParams

  2. 如果documentURLabout:blank,那么填充 html/head/body给定document

    这个特殊情况,即使是非初始 about:blank Document也被同步赋予了它们的元素节点,这是为了与部署的内容兼容。换句话说,使用空的字节序列来异步填充document的HTML解析器是不可兼容的。

  3. 否则,创建一个HTML解析器并将其与document关联。 在获取运行时,网络任务源放置在任务队列中的每个任务必须填充解析器的输入字节流以获取的字节,并使HTML解析器对输入流执行适当的处理。

    在获取运行时,网络任务源放置在任务队列中的第一个任务必须在任务被HTML解析器处理后,给定documentnavigationParams响应和"media",处理链接头

    在任何脚本执行发生之前,用户代理必须等待脚本可以在新创建的文档中运行对于document为真。

    输入字节流将字节转换为字符以供标记化器使用。此过程部分依赖于资源的实际内容类型元数据中找到的字符编码信息;计算类型不用于此目的。

    当没有更多字节可用时,用户代理必须网络任务源上给document相关全局对象排队一个全局任务,让解析器处理隐含的EOF字符,这最终导致触发load事件。

  4. 返回document

7.5.3 加载 XML 文档

当需要内联显示XML文件时,给定导航参数 navigationParams和字符串type,用户代理必须遵循XMLXML中的命名空间XML媒体类型DOM及其他相关规范中的要求,创建并初始化一个Document对象 document,给定"xml"、typenavigationParams,并返回该Document。他们还必须创建一个相应的XML解析器[XML] [XMLNS] [RFC7303] [DOM]

在撰写本文时,XML规范社区尚未实际指定XML与DOM如何交互。

网络任务源在获取过程中放置在任务队列中的第一个任务,必须在任务被XML解析器处理后,处理链接头,给定documentnavigationParams响应和"media"。

实际的HTTP头和其他元数据,而不是由本规范中的算法变更或暗示的头,必须用于根据上述规范中的规则确定字符编码。一旦确定了字符编码,文档的字符编码必须设置为该字符编码。

在任何脚本执行发生之前,用户代理必须等待脚本可以在新创建的文档中运行对于新创建的Document为真。

一旦解析完成,用户代理必须将documentWebDriver BiDi期间加载导航ID设置为null。

对于HTML文档,这将在解析完成后重置,并触发load事件。

解析过程中产生的错误信息(例如,XML命名空间格式正确性错误)可以通过修改Document来内联报告。

7.5.4 加载文本文档

加载一个文本文档,给定导航参数 navigationParams和一个字符串type

  1. document成为创建并初始化一个Document对象的结果,给定"html"、typenavigationParams

  2. document解析器不能更改模式标志设置为true。

  3. document模式设置为"no-quirks"。

  4. 创建一个HTML解析器并将其与document关联。像标记器已经发出一个标签名为“pre”的开始标签token后跟一个U+000A换行符(LF)字符一样操作,并将HTML解析器的标记器切换到PLAINTEXT状态。在获取运行时网络任务源放置在任务队列上的每个任务都必须用获取的字节填充解析器的输入字节流并使HTML解析器对输入流进行适当的处理。

    document编码必须设置为解析过程中用于解码文档的字符编码。

    在获取运行时网络任务源放置在任务队列上的第一个任务,在任务被HTML解析器处理后,必须处理链接头,给定documentnavigationParams响应和"media"。

    在任何脚本执行发生之前,用户代理必须等待脚本可以在新创建的文档中运行对于document为真。

    当没有更多的字节可用时,用户代理必须在 document相关全局对象 上根据 网络任务源 排队一个全局任务,让解析器处理隐含的 EOF 字符,这最终会触发一个 load 事件。

  5. 用户代理可以向documenthead元素添加内容,例如链接到样式表、提供脚本或为文档提供title

    特别地,如果用户代理支持RFC 3676的Format=Flowed功能,则用户代理需要应用额外的样式以使文本正确换行并处理引用功能。这可以通过例如CSS扩展来执行。

  6. 返回document

将纯文本文档的字节转换为实际字符的规则,以及将文本实际呈现给用户的规则,由资源的计算出的MIME类型(即type)的规范定义。

7.5.5 加载 multipart/x-mixed-replace 文档

加载一个 multipart/x-mixed-replace文档,给定导航参数 navigationParams源快照参数 sourceSnapshotParams, 以及来源 initiatorOrigin

  1. 使用多部分类型的规则解析navigationParams响应主体[RFC2046]

  2. firstPartNavigationParams成为navigationParams的副本。

  3. firstPartNavigationParams响应设置为一个新的响应,表示 navigationParams响应主体的多部分流的第一部分。

  4. document成为加载文档的结果,给定 firstPartNavigationParamssourceSnapshotParamsinitiatorOrigin

    对于从navigationParams响应获得的每个附加的主体部分,用户代理必须导航 document节点导航navigationParams请求URL,使用 document,将响应设置为 navigationParams响应历史处理设置为"替换"。

  5. 返回document

为了将这些主体部分作为完整的独立资源处理的算法目的,用户代理在到达紧跟在主体部分之后的边界时,必须表现得好像这些资源没有更多字节一样。

因此,每个加载的主体部分确实会触发load事件(以及 unload事件)。

7.5.6 加载媒体文档

加载媒体文档,给定navigationParams和一个字符串type

  1. document成为创建并初始化Document对象的结果,给定"html"、typenavigationParams

  2. document模式 设置为"no-quirks"。

  3. 使用html/head/body填充给定的document

  4. 将一个用于媒体的元素host element,如下所述,附加到body元素中。

  5. 将适当的属性设置为图像、视频或音频资源的地址,如下所述。

  6. 用户代理可以向documenthead元素或 host element添加内容或属性,例如链接到样式表、提供脚本、给文档一个标题或使媒体自动播放

  7. 处理链接头给定documentnavigationParams响应和"media"。

  8. 表现得好像用户代理已停止解析document

  9. 返回document

为媒体创建的元素host element是下表第二列中给出的元素,第一列描述了媒体类型。要设置的适当属性是同一行第三列给出的属性。

媒体类型 媒体的元素 适当的属性
图像 img src
视频 video src
音频 audio src

在任何脚本执行发生之前,用户代理必须等待脚本可以在新创建的文档中运行对新创建的Document为真。

7.5.7 加载没有 DOM 的内联内容文档

当用户代理创建文档以内联显示用户代理页面或 PDF 查看器时,提供一个可导航对象 navigable、一个导航 ID navigationId、一个NavigationTimingType navTimingType,用户代理应:

  1. origin成为一个新的不透明来源

  2. coop成为一个新的跨来源打开策略

  3. coopEnforcementResult成为一个新的跨来源打开策略执行结果,具有以下属性:

    url
    responseURL
    origin
    origin
    跨来源打开策略
    coop
  4. navigationParams成为一个新的导航参数,具有以下属性:

    id
    navigationId
    navigable
    navigable
    request
    null
    response
    一个新的response
    origin
    origin
    fetch controller
    null
    commit early hints
    null
    COOP 执行结果
    coopEnforcementResult
    reserved environment
    null
    政策容器
    一个新的政策容器
    最终沙盒标志集
    一个空集
    跨来源打开策略
    coop
    导航时间类型
    navTimingType
    about 基础 URL
    null
  5. document成为创建并初始化一个Document对象的结果,给定"html"、"text/html"和 navigationParams

  6. 要么将document与一个不使用正常Document渲染规则的自定义渲染关联,要么修改document,直到它代表用户代理要渲染的内容。

  7. 返回document

因为我们确保生成的Document来源不透明的, 并且生成的Document不能运行 具有访问 DOM 的脚本,这个Document的存在和属性对 Web 开发者代码是不可观察的。这意味着大多数上述值,例如 text/html类型,并不重要。 同样,navigationParams中的大多数项目没有任何可观察的效果,除了防止Document创建算法混乱,因此设置为默认值。

页面设置完成后,用户代理必须表现得好像已停止解析

7.5.8 完成加载过程

一个Document有一个完全加载时间(一个时间或空值),最初为空。

一个Document被认为是完全加载的,如果它的完全加载时间不是空值。

完全完成加载一个Document document

  1. 断言document浏览上下文不是空值。

  2. document完全加载时间设置为当前时间。

  3. container成为document节点可导航对象容器

    document初始about:blank Document在一个框架iframe的情况下,这是空值,因为在调用这个算法的浏览上下文创建时,尚未建立容器关系。(这是在创建一个新的子可导航对象的后续步骤中发生的。)

    其结果是,以下步骤什么也不做,即我们不会在这种情况下在容器元素上触发异步加载事件。相反,在处理iframe属性的特殊初始插入情况下,会触发同步加载事件。

  4. 如果container是一个iframe元素,则在container上给定iframe 加载事件步骤排队一个元素任务DOM 操作任务源

  5. 否则,如果container不是空值,则在container上给定排队一个元素任务DOM 操作任务源触发一个名为加载的事件。

7.5.9 卸载文档

一个Document有一个可回收状态,最初必须为真,还有一个页面显示标志,最初必须为假。页面显示标志用于确保脚本以一致的方式接收pageshowpagehide事件(例如,它们永远不会在没有中间pageshow事件的情况下连续接收两个pagehide事件,反之亦然)。

一个Document有一个DOMHighResTimeStamp 暂停时间,最初为0。

一个Document有一个列表暂停计时器句柄,最初为空。

事件循环有一个终止嵌套级别计数器,最初必须为0。

Document对象有一个卸载计数器,用于在以下算法运行时忽略某些操作。最初,计数器必须设置为零。

卸载一个DocumentoldDocument,给定一个可选的DocumentnewDocument

  1. 断言:这是作为oldDocument相关代理事件循环上排队的任务的一部分运行的。

  2. unloadTimingInfo成为一个新的文档卸载时间信息

  3. 如果未给出newDocument,则将unloadTimingInfo设置为空。

    在这种情况下,没有需要了解oldDocument卸载时间的新文档。

  4. 否则,如果newDocument事件循环不是oldDocument事件循环,则用户代理可能并行卸载oldDocument。在这种情况下,用户代理应将unloadTimingInfo设置为空。

    在这种情况下,newDocument的加载不受oldDocument卸载时间的影响,因此传达该时间信息没有意义。

  5. intendToKeepInBfcache为真,如果用户代理打算将oldDocument保留在会话历史条目中,以便以后用于历史遍历

    如果oldDocument不是可回收的,或者有任何后代用户代理不打算以相同方式保留的oldDocument(包括由于其缺乏可回收性),则此值必须为假。

  6. eventLoop成为oldDocument相关代理事件循环

  7. eventLoop终止嵌套级别增加1。

  8. oldDocument卸载计数器增加1。

  9. 如果intendToKeepInBfcache为假,则将oldDocument可回收状态设置为假。

  10. 如果oldDocument页面显示为真:

    1. oldDocument页面显示设置为假。

    2. 触发一个页面过渡事件,命名为pagehide,在oldDocument相关全局对象上,带有oldDocument可回收状态。

    3. 更新oldDocument的可见状态为"hidden"。

  11. 如果 unloadTimingInfo 不是 null,则将 unloadTimingInfo卸载事件开始时间 设置为 newDocument相关全局对象 给定的 当前高分辨率时间,并根据 oldDocument相关设置对象跨源隔离能力 粗化

  12. 如果 oldDocument可挽救状态 为 false,则在 oldDocument相关全局对象触发一个名为 unload 的事件,并设置 legacy target override flag

  13. 如果 unloadTimingInfo 不是 null,则将 unloadTimingInfo卸载事件结束时间 设置为 newDocument相关全局对象 给定的 当前高分辨率时间,并根据 oldDocument相关设置对象跨源隔离能力 粗化

  14. eventLoop终止嵌套级别减少1。

  15. oldDocument暂停时间设置为给定document相关全局对象当前高分辨率时间

  16. oldDocument暂停计时器句柄设置为获取的结果活动计时器的映射的键。

  17. oldDocument已被用户滚动设置为假。

  18. 运行任何为oldDocument定义的卸载文档清理步骤,以及其他适用规范定义的步骤。

  19. 如果oldDocument节点可导航对象顶级可遍历对象,则根据oldDocument节点可导航对象构建顶级可遍历对象及其后代的未恢复原因

  20. 如果oldDocument可回收状态为假,则销毁oldDocument

  21. oldDocument卸载计数器减少1。

  22. 如果给出了newDocumentnewDocument不是通过跨域重定向创建的,并且newDocument来源oldDocument来源相同,则将newDocument先前文档卸载时间设置为unloadTimingInfo

卸载文档及其后代,给定一个Documentdocument,一个可选的Document-或-nullnewDocument(默认值为null),一个可选的步骤集合afterAllUnloads,和一个可选的步骤集合firePageSwapSteps

  1. 断言:这正在document节点可导航对象可遍历可导航对象会话历史遍历队列内运行。

  2. childNavigables成为document子可导航对象

  3. numberUnloaded为0。

  4. 对于每个childNavigable以何顺序?childNavigable活动窗口上,导航和遍历任务源上排队一个全局任务以执行以下步骤:

    1. incrementUnloaded成为一个算法步骤,用于增加numberUnloaded

    2. 卸载文档及其后代给定childNavigable活动文档,null,和incrementUnloaded

  5. 等待直到numberUnloaded等于childNavigable大小

  6. document相关全局对象上,在导航和遍历任务源上排队一个全局任务,以执行以下步骤:

    1. 如果给出了firePageSwapSteps,则运行firePageSwapSteps

    2. 卸载document,如果newDocument不为空,则传递它。

    3. 如果给出了afterAllUnloads,则运行它。

本规范定义了以下卸载文档清理步骤。其他规范可以定义更多步骤。给定一个Documentdocument

  1. window成为document相关全局对象

  2. 对于每个WebSocket对象webSocket,其相关全局对象window使其消失webSocket

    如果这影响了任何WebSocket对象,则使文档不可回收,给定document和"websocket"。

  3. 对于每个WebTransport对象transport,其相关全局对象window,运行上下文清理步骤,给定transport

  4. 如果document可回收状态为假,则:

    1. 对于每个EventSource对象eventSource,其相关全局对象等于window强制关闭eventSource

    2. 清除window活动计时器映射

如果规范作者发送拉取请求以直接在其规范中添加从此处调用的步骤,而不是使用卸载文档清理步骤钩子,将更好,以确保跨规范调用顺序明确。在撰写本文时,已知以下规范具有卸载文档清理步骤,这些步骤将按未指定的顺序运行:全屏APIWeb NFCXML媒体类型WebDriver BiDi计算压力文件API媒体捕获和流画中画屏幕方向服务workerWeb锁定APIWeb音频APIWebRTC[FULLSCREEN][WEBNFC][WEBDRIVERBIDI][COMPUTEPRESSURE][FILEAPI][MEDIASTREAM][PICTUREINPICTURE][SCREENORIENTATION][SW][WEBLOCKS][WEBAUDIO][WEBRTC]

问题#8906跟踪明确这些步骤的顺序的工作。

7.5.10 销毁文档

销毁一个 Document document

  1. 断言:这是在document相关代理事件循环中排队的任务的一部分运行。

  2. 中止 document

  3. document可回收状态 设置为false。

  4. ports成为MessagePort列表,其相关全局对象关联Documentdocument

  5. 对于ports中的每个port解开 port

  6. 运行本规范和其他适用规范定义的任何document卸载文档清理步骤

  7. 从任何任务队列中删除其文档document任务(无需运行这些任务)。

  8. document浏览上下文设置为 null。

  9. document节点可导航对象活动会话历史条目文档状态文档设置为null。

  10. 每个WorkerGlobalScope对象的所有者集合移除document

  11. 对于document的每个worklet全局作用域中的workletGlobalScope终止 workletGlobalScope

即使在销毁后,在我们销毁子可导航对象的情况下,Document对象本身可能仍然可以被脚本访问。

销毁文档及其后代,给定一个Document document和一个可选的步骤集合afterAllDestruction,请按照以下步骤并行执行:

  1. 如果document不是完全活跃的,则:

    1. 使文档不可回收,给定document和"masked"。

    2. 如果document节点可导航对象顶级可遍历对象,请构建 未恢复的原因,给定document节点可导航对象

  2. childNavigables成为document子可导航对象

  3. numberDestroyed为0。

  4. 对于childNavigable的每个childNavigablechildNavigable活动窗口中,排队一个全局任务以执行以下步骤:

    1. incrementDestroyed成为一个算法步骤,它递增 numberDestroyed

    2. 销毁文档及其后代,给定childNavigable活动文档incrementDestroyed

  5. 等待直到numberDestroyed等于childNavigable大小

  6. document相关全局对象中排队一个全局任务以执行以下步骤:

    1. 销毁document

    2. 如果给定了afterAllDestruction,则运行它。

7.5.11 中止文档加载

中止一个Document document

  1. 断言:这是在document相关代理事件循环中排队的任务的一部分运行。

  2. 取消在document上下文中fetch算法的任何实例,丢弃为其排队的任何任务,并丢弃从网络收到的任何进一步数据。如果这导致了fetch算法的任何实例被取消或任何排队的任务或任何网络数据被丢弃,那么给定document和"fetch",使文档不可回收

  3. 如果 documentWebDriver BiDi 的加载期间导航 ID 不是 null,则:

    1. 调用 WebDriver BiDi 导航中止,使用 document浏览上下文 和一个新的 WebDriver BiDi 导航状态,其中 iddocument加载期间导航 ID状态 是 "canceled",以及 urldocumentURL

    2. documentWebDriver BiDi 的加载期间导航 ID 设置为 null。

  4. 如果document有一个活动解析器,则:

    1. document活动解析器被中止设置为true。

    2. 中止该解析器

    3. document可回收设置为false。

    4. 给定document和"parser-aborted",使文档不可回收

中止文档及其后代,给定一个Documentdocument

  1. 断言:这是在document相关代理事件循环中排队的任务的一部分运行。

  2. descendantNavigables成为document后代可导航对象

  3. 对于descendantNavigable的每个descendantNavigables 按什么顺序?descendantNavigable活动窗口中排队一个全局任务以执行以下步骤:

    1. 中止descendantNavigable活动文档

    2. 如果descendantNavigable活动文档可回收为false,则将document可回收设置为false。

  4. 中止document

停止加载一个可导航对象navigable

  1. document成为navigable活动文档

  2. 如果document卸载计数器为0,并且navigable正在进行的导航是一个导航ID,则设置navigable的正在进行的导航为null。

    这将导致中止navigable的任何正在进行的导航,因为在导航期间的某些点,正在进行的导航的更改将导致进一步的工作被放弃。

  3. 中止文档及其后代,给定document

通过其用户界面,用户代理还允许停止遍历,即正在进行的导航为"traversal"的情况。上述算法未考虑这一点。(另一方面,用户代理不允许window.stop()停止遍历,因此上述算法对该调用者是正确的。)参见问题#6905

7.6 `X-Frame-Options` 头部

Headers/X-Frame-Options

支持所有当前引擎。

Firefox4+Safari4+Chrome4+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox AndroidSafari iOSChrome AndroidWebView Android?Samsung Internet?Opera Android?

`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

  1. 如果navigable不是一个子导航对象,则返回true。

  2. 对于 cspList中的每个policy

    1. 如果policy处置不是`enforce`,则继续

    2. 如果policy指令集包含一个frame-ancestors指令,则返回true。

  3. rawXFrameOptions成为从response头部列表获取、解码和分割`X-Frame-Options`的结果。

  4. xFrameOptions成为一个新的集合

  5. 对于rawXFrameOptions中的每个value附加 value转换为ASCII小写,到xFrameOptions

  6. 如果xFrameOptions大小大于1,并且xFrameOptions包含`deny`、`allowall`或`sameorigin`中的任何一个,则返回false。

    这里的意图是阻止任何尝试应用`X-Frame-Options`的尝试,这些尝试试图做一些有效的事情,但看起来很困惑。

    这是遗留的`ALLOWALL`值对处理模型的唯一影响。

  7. 如果xFrameOptions大小大于1,则返回true。

    这意味着它包含多个无效值,我们将其视为完全省略了该头部。

  8. 如果xFrameOptions[0]是`deny`,则返回false。

  9. 如果xFrameOptions[0]是`sameorigin`,则:

    1. containerDocument成为navigable容器文档

    2. containerDocument不为null时:

      1. 如果containerDocument来源destinationOrigin不是同源,则返回false。

      2. containerDocument设置为containerDocument容器文档

  10. 返回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` 允许嵌入

无论这些值是以逗号分隔的单个头部值传递,还是以多个头部传递,结果都是相同的。

7.7 `Refresh` 头部

`Refresh` HTTP响应头是HTTP等价于 meta 元素,带有 http-equiv 属性,并处于 Refresh 状态。它接受 相同的值,并且工作方式大致相同。其处理模型详述于 创建并初始化一个 Document 对象

浏览器用户代理应该提供导航重新加载停止加载顶层可导航对象集合中的任何顶层可导航对象的能力。

例如,通过地址栏和重新加载/停止按钮界面。

浏览器用户代理应该提供按增量遍历顶层可导航对象集合中的任何顶层可导航对象的能力。

例如,通过后退和前进按钮,可能包括长按功能以改变增量。

建议这样的用户代理允许按大于一的增量进行遍历,以避免页面通过填充会话历史记录的虚假条目来“困住”用户。(例如,通过重复调用history.pushState()片段导航。)

一些用户代理有将单个“后退”或“前进”按钮按下转化为更大增量的启发式方法,专门用于克服此类滥用。我们正在考虑在问题#7832中指定这些启发式方法。

浏览器用户代理应该为用户提供创建一个新的顶层可导航对象的能力,给定用户提供的或用户代理确定的初始URL

例如,通过“新建标签页”或“新建窗口”按钮。

浏览器用户代理应该为用户提供任意关闭顶层可导航对象集合中的任何顶层可导航对象的能力。

例如,通过点击“关闭标签页”按钮。


浏览器用户代理可以提供用户明确导致任何可导航对象(不仅仅是一个顶层可导航对象导航重新加载停止加载的方法。

例如,通过上下文菜单。

浏览器用户代理可以提供用户销毁一个顶层可导航对象的能力。

例如,通过强制关闭包含一个或多个此类顶层可导航对象的窗口。


当用户请求重新加载重新加载活动会话历史条目文档状态资源POST资源可导航对象时,用户代理应该首先提示用户确认操作,因为否则交易(例如购买或数据库修改)可能会重复。

当用户请求重新加载重新加载可导航对象时,用户代理可以提供忽略任何缓存的机制。


上述机制发起的所有导航调用必须将userInvolvement参数设置为`browser UI`。

上述机制发起的所有重新加载调用必须将userInvolvement参数设置为`browser UI`。

上述机制发起的 所有按增量遍历历史记录调用必须不传递sourceDocument参数。


上述建议和本规范中的数据结构不旨在对用户代理如何向用户表示会话历史记录施加限制。

例如,虽然顶层可导航对象会话历史条目存储和维护为列表,并建议用户代理提供界面以按增量遍历该列表,但新型用户代理可以另外或替代地呈现树状视图,每个页面有多个“前进”页面供用户选择。

同样,虽然所有后代可导航对象的会话历史记录存储在其可导航对象中,但用户代理可以向用户呈现更细致的每个可导航对象的会话历史记录视图。


浏览器用户代理可以使用顶层浏览上下文是否弹出窗口布尔值用于以下目的:

在这两种情况下,用户代理可能还会结合用户偏好,或提供选择是否走弹出窗口路线。

为这些弹出窗口提供最小用户界面的用户代理被鼓励不要隐藏浏览器的地址栏。

8 Web 应用程序 API

8.1 脚本

8.1.1 简介

各种机制可以导致作者提供的可执行代码在文档的上下文中运行。这些机制包括但可能不限于:

8.1.2 代理和代理集群

8.1.2.1 与 JavaScript 代理形式的集成

JavaScript 定义了 代理 的概念。本节提供了该语言级别概念在 Web 平台上的映射。

从概念上讲,代理 概念是 JavaScript 代码运行的架构无关的理想化 "线程"。这种代码可以涉及多个全局对象/realm,它们可以同步访问彼此,因此需要在单个执行线程中运行。

两个 Window 对象具有相同的 代理 并不表示它们可以直接访问彼此 realm 中创建的所有对象。它们必须是 同源域;请参见 IsPlatformObjectSameOrigin

以下类型的代理存在于 Web 平台上:

相似来源窗口代理

包含各种 Window 对象,这些对象可以直接或通过使用 document.domain 彼此到达。

如果包含的 代理集群是按来源键控的 为 true,则所有 Window 对象将是 同源,可以直接彼此到达,并且 document.domain 将无操作。

两个 Window 对象即使是 同源,也可以位于不同的 相似来源窗口代理 中,例如,如果它们各自在自己的 浏览上下文组 中。

专用worker代理

包含单个 DedicatedWorkerGlobalScope

共享worker代理

包含单个 SharedWorkerGlobalScope

服务worker代理

包含单个 ServiceWorkerGlobalScope

Worklet 代理

包含单个 WorkletGlobalScope 对象。

虽然给定的 worklet 可以有多个 realm,但每个 realm 需要自己的代理,因为每个 realm 可以独立执行代码,并且与其他 realm 同时执行。

只有 共享专用worker代理 允许使用 JavaScript Atomics API 进行潜在的 阻塞

创建一个代理,给定一个布尔值 canBlock

  1. signifier 成为一个新的唯一内部值。

  2. candidateExecution 成为一个新的 候选执行

  3. agent 成为一个新的 代理,其 [[CanBlock]] 为 canBlock,[[Signifier]] 为 signifier,[[CandidateExecution]] 为 candidateExecution,并且 [[IsLockFree1]]、[[IsLockFree2]] 和 [[LittleEndian]] 设置为实现的自行决定。

  4. agent事件循环 设置为一个新的 事件循环

  5. 返回 agent

对于一个 realm realm,[[Signifier]] 为 realm.[[AgentSignifier]] 的 代理该 realm 的代理

相关代理 对于一个 平台对象 platformObjectplatformObject相关 realm代理

当前 realm 等效的代理是 周围代理

8.1.2.2 与 JavaScript 代理集群形式的集成

JavaScript 还定义了 代理集群 的概念,本标准通过在使用 获取相似来源窗口代理获取worker/worklet 代理 算法创建代理时适当地放置它们,将其映射到 Web 平台。

代理集群 概念对于定义 JavaScript 内存模型至关重要,尤其是在哪些 代理 之间可以共享 SharedArrayBuffer 对象的支持数据。

从概念上讲,代理集群 概念是将多个 "线程"(代理)分组在一起的架构无关的理想化 "进程边界"。规范定义的代理集群 通常比用户代理实现的实际进程边界更严格。通过在规范层面上执行这些理想化的划分,我们确保了 Web 开发者在共享内存方面看到的行为具有可互操作性,即使面对不同和变化的用户代理进程模型。

代理集群 关联有一个 跨源隔离模式,这是一个 跨源隔离模式。它最初是 ""。

代理集群 关联有一个 按来源键控(布尔值),最初为 false。


以下定义了 相似来源窗口代理代理集群 的分配。

代理集群键 是一个 站点元组来源。如果没有 Web 开发者操作来实现 按来源键控的代理集群,它将是一个 站点

一个等效的表述是 代理集群键 可以是 方案和主机来源

获取相似来源窗口代理,给定一个 来源 origin,一个 浏览上下文组 group 和一个布尔值 requestsOAC,运行以下步骤:

  1. site 成为 获取站点 结果,带有 origin

  2. key 设置为 site

  3. 如果 group跨源隔离模式 不是 "",则将 key 设置为 origin

  4. 否则,如果 group历史代理集群键映射[origin] 存在,则将 key 设置为 group历史代理集群键映射[origin]。

  5. 否则:

    1. 如果 requestsOAC 为 true,则将 key 设置为 origin

    2. group历史代理集群键映射[origin] 设置为 key

  6. 如果 group代理集群映射[key] 不存在,则:

    1. agentCluster 成为一个新的 代理集群

    2. agentCluster跨源隔离模式 设置为 group跨源隔离模式

    3. 如果 key 等于 origin,则将 agentCluster按来源键控 设置为 true;否则设置为 false。

    4. 添加 创建代理 的结果,给定 false,到 agentCluster

    5. group代理集群映射[key] 设置为 agentCluster

  7. 返回 group代理集群映射[key] 中包含的单个 相似来源窗口代理

这意味着每个浏览上下文代理集群中只有一个 相似来源窗口代理。(然而,专用workerworklet 代理 可能在同一个集群中。)


以下定义了所有其他类型代理的 代理集群 的分配。

获取worker/worklet 代理,给定一个 环境设置对象 或 null outside settings,一个布尔值 isTopLevel 和一个布尔值 canBlock,运行以下步骤:

  1. agentCluster 为 null。

  2. 如果 isTopLevel 为 true,则:

    1. agentCluster 设置为一个新的 代理集群

    2. agentCluster按来源键控 设置为 true。

      这些worker可以被认为是按来源键控的。然而,这并不通过任何 API 暴露(就像 originAgentCluster 对于窗口暴露来源键控性一样)。

  3. 否则:

    1. 断言outside settings 不为 null。

    2. ownerAgent 成为 outside settingsrealm代理

    3. agentCluster 设置为包含 ownerAgent 的代理集群。

  4. agent 成为 创建代理 的结果,给定 canBlock

  5. agent 添加到 agentCluster

  6. 返回 agent

获取专用/共享worker代理,给定一个 环境设置对象 outside settings 和一个布尔值 isShared,返回 获取worker/worklet 代理 的结果,给定 outside settingsisShared 和 true。

获取 worklet 代理,给定一个 环境设置对象 outside settings,返回 获取worker/worklet 代理 的结果,给定 outside settings、false 和 false。

获取服务worker代理,返回 获取worker/worklet 代理 的结果,给定 null、true 和 false。


以下全局对象对是同一个 代理集群 内的,因此可以使用 SharedArrayBuffer 实例相互共享内存:

以下全局对象对 不是 同一个 代理集群,因此不能共享内存:

8.1.3 域及其对应物

JavaScript 规范引入了 概念,表示运行脚本的全局环境。每个域都带有一个 实现定义的 全局对象;本规范的大部分内容致力于定义该全局对象及其属性。

对于 Web 规范,通常将值或算法与域/全局对象对关联是有用的。当值特定于某种类型的域时,它们直接与相关的全局对象关联,例如在 WindowWorkerGlobalScope 接口的定义中。当值在多个域中具有实用性时,我们使用 环境设置对象 概念。

最后,在某些情况下,需要在域/全局对象/环境设置对象出现之前跟踪相关值(例如,在 导航 期间)。这些值在 环境 概念中跟踪。

8.1.3.1 环境

环境 是一个对象,用于标识当前或潜在执行环境的设置(即 导航参数保留环境请求保留客户端)。环境 具有以下字段:

ID

唯一标识此 环境 的不透明字符串。

创建 URL

表示与此 环境 关联的资源位置的 URL

Window 环境设置对象 的情况下,由于 history.pushState() 等机制,该 URL 可能与其 全局对象关联的 DocumentURL 不同。

顶层创建 URL

为 null 或 URL,表示“顶层” 环境创建 URL。对于worker和 worklet 来说,它为 null。

顶层源

目前是 实现定义 的值、null,或 。对于“顶层”潜在执行环境,它为 null(即当尚无响应时);否则,它是“顶层”环境。对于专用worker或 worklet,它是其创建者的 顶层源。对于共享或服务worker,它是一个 实现定义 的值。

这在涉及沙箱、worker和 worklet 时,与 顶层创建 URL 是不同的。

目标浏览上下文

为 null 或导航请求的目标 浏览上下文

活跃服务worker

为 null 或控制 环境服务worker

执行准备就绪标志

一个标志,指示环境设置是否完成。它最初未设置。

规范可以为环境定义 环境丢弃步骤。这些步骤以 环境 作为输入。

环境丢弃步骤 仅针对少数环境运行:这些环境将永远不会变为执行就绪状态,因为它们例如未能加载。

8.1.3.2 环境设置对象

环境设置对象 是一个 环境,另外指定了以下算法:

域执行上下文

所有使用该设置对象的 JavaScript 执行上下文 共享的执行上下文,即给定 脚本 的所有脚本。当我们 运行经典脚本运行模块脚本 时,此执行上下文将成为 JavaScript 执行上下文堆栈 的顶部,在其上推入另一个特定于相关脚本的执行上下文。(此设置确保 Source Text Module RecordEvaluate 知道使用哪个域。)

模块映射

导入 JavaScript 模块时使用的 模块映射

API 基础 URL

使用此 环境设置对象 的脚本调用 API 时使用的 URL,用于 解析 URL

在安全检查中使用的

策略容器

包含用于安全检查策略的 策略容器

跨源隔离能力

表示使用此 环境设置对象 的脚本是否被允许使用需要跨源隔离的 API 的布尔值。

时间源
用作性能相关时间戳基线的数字。[HRT]

环境设置对象负责的事件循环 是其 全局对象相关代理事件循环

8.1.3.3 域、设置对象和全局对象

全局对象 是一个 JavaScript 对象,是 的 [[GlobalObject]] 字段。

在本规范中,所有 都通过创建 全局对象,这些对象要么是 WindowWorkerGlobalScope,要么是 WorkletGlobalScope 对象。

一个全局对象有一个布尔值 错误报告模式,其初始值为 false。

一个全局对象有一个未处理拒绝的 promises 弱引用集合,这是一个 集合,包含 Promise 对象,初始为空。此集合不得创建其成员的强引用,且实现可以通过实现定义的方式自由地限制其大小,例如在添加新条目时删除旧条目。

一个全局对象有一个即将通知的拒绝 promises 列表,这是一个 列表,包含 Promise 对象,初始为空。


领域全局对象环境设置对象之间始终存在1对1对1的映射关系:

创建一个新域 时,在 代理 agent 中,选择性地创建全局对象或全局 this 绑定(或两者),采取以下步骤:

  1. 执行 InitializeHostDefinedRealm(),提供创建全局对象和全局 this 绑定的自定义。

  2. realm execution context 成为 正在运行的 JavaScript 执行上下文

    这是在上一步中创建的 JavaScript 执行上下文

  3. JavaScript 执行上下文堆栈 中移除 realm execution context

  4. realm 成为 realm execution context 的 Realm 组件。

  5. 如果 agent代理集群跨源隔离模式 为 "none",则:

    1. global 成为 realm全局对象

    2. status 为 ! global.[[Delete]]("SharedArrayBuffer")。

    3. 断言status 为真。

    这是为了兼容 web 内容,未来希望可以去除。Web 开发者仍然可以通过 new WebAssembly.Memory({ shared:true, initial:0, maximum:0 }).buffer.constructor 获取构造函数。

  6. 返回 realm execution context


在整个规范中定义算法步骤时,通常需要指出要使用哪个realm——或者等价地,使用哪个全局对象环境设置对象。一般来说,至少有四种可能性:

入口
对应于启动当前运行的脚本操作的脚本:即用户代理调用进入作者代码时调用的函数或脚本。
现任
对应于堆栈上最近进入的作者函数或脚本,或最初安排当前运行回调的作者函数或脚本。
当前
对应于当前运行的函数对象,包括可能不是用 JavaScript 实现的内置用户代理函数。(它派生自 当前域。)
相关
每个 平台对象 都有一个 相关域,大致上是它创建时的 。编写算法时,可能最突出的具有重要性的 平台对象 是当前运行函数对象的 this 值。在某些情况下,可能还有其他重要的 相关域,例如任何参数的相关域。

注意 入口现任当前 概念是可无条件使用的,而 相关 概念必须应用于特定的 平台对象

现任入口 概念不应被新规范使用,因为它们过于复杂且不直观。我们正在努力从平台中删除几乎所有现有用法:有关 现任问题 #1430,有关 入口问题 #1431

一般来说,Web 平台规范应该使用应用于操作对象的 相关 概念(通常是当前方法的 this 值)。这与 JavaScript 规范不一致,在 JavaScript 规范中,通常使用 当前 作为默认值(例如,在确定 Array 构造函数应在 Array.prototype.map 中用于构造结果时)。但这种不一致在平台中已经根深蒂固,我们必须接受它。

考虑以下页面,其中 a.html 加载在浏览器窗口中,b.html 加载在 iframe 中,如图所示,c.htmld.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。由于这是不理想的,因此算法使用 相关域,从而给出上述评论中所指出的合理结果。


本节的其余部分涉及正式定义 入口现任当前相关概念。

8.1.3.3.1 入口

调用脚本的过程将把域执行上下文推入或弹出到JavaScript执行上下文堆栈中,与其他执行上下文交错在一起。

有了这个定义,我们将入口执行上下文定义为最近推入的JavaScript执行上下文堆栈中是域执行上下文的项。入口域入口执行上下文的域组件。

然后,入口设置对象环境设置对象入口域

类似地,入口全局对象全局对象入口域

8.1.3.3.2 在任

所有JavaScript执行上下文必须包含其代码评估状态的一部分,即跳过确定现任计数器值,初始值为零。在准备运行回调清理运行回调后的状态过程中,该值将增加和减少。

每个事件循环都有一个关联的备用现任设置对象堆栈,初始为空。大致来说,它用于在堆栈上没有作者代码,但作者代码负责以某种方式运行当前算法时确定现任设置对象准备运行回调清理运行回调后的状态过程会操纵此堆栈。[WEBIDL]

当使用Web IDL调用作者代码,或当HostEnqueuePromiseJob调用一个promise任务时,它们使用以下算法来跟踪确定现任设置对象的相关数据:

准备运行回调,使用环境设置对象settings

  1. settings推入备用现任设置对象堆栈

  2. context成为最上层的脚本执行上下文

  3. 如果context不是null,则增加context跳过确定现任计数器

清理运行回调后的状态,使用环境设置对象settings

  1. context成为最上层的脚本执行上下文

    这将与准备运行回调中相应调用的最上层的脚本执行上下文相同。

  2. 如果context不是null,则减少context跳过确定现任计数器

  3. 断言备用现任设置对象堆栈的最顶层条目是settings

  4. 备用现任设置对象堆栈中删除settings

这里,最上层的脚本执行上下文 JavaScript执行上下文堆栈中具有非null的ScriptOrModule组件的最顶层条目,如果JavaScript执行上下文堆栈中没有这样的条目,则为null。

有了这一切,现任设置对象被确定如下:

  1. context成为最上层的脚本执行上下文

  2. 如果context是null,或者如果context跳过确定现任计数器大于零,则:

    1. 断言备用现任设置对象堆栈不是空的。

      如果尝试从既不是调用脚本也不是Web IDL调用回调触发的算法中获取现任设置对象,此断言将失败。例如,如果尝试在事件循环中定期运行的算法中获取现任设置对象,而没有作者代码的参与,则会触发此断言。在这种情况下,无法使用现任概念。

    2. 返回备用现任设置对象堆栈的最顶层条目。

  3. 返回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.bindsetTimeout()增加了额外的间接调用。但是,答案应该是相同的:异步调用算法不应改变现任概念。

这次,结果涉及更复杂的机制:

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本身仍然被用作源文档,这决定了包括请求客户端在内的许多事项。这 可能是现任概念在网络平台上唯一合理的使用;在所有其他情况下,使用它的后果只是令人困惑,我们希望有一天能将其切换为使用当前相关概念。

8.1.3.3.3 当前

JavaScript规范定义了当前域,也称为"当前Realm记录"。[JAVASCRIPT]

然后,当前设置对象环境设置对象当前域

类似地,当前全局对象全局对象当前域

8.1.3.3.4 相关

相关域对于平台对象是其[[Realm]]字段的值。

然后,相关设置对象对于平台对象o环境设置对象相关域

类似地,相关全局对象对于平台对象o全局对象相关域

8.1.3.4 启用和禁用脚本

启用脚本是指对于环境设置对象settings,当以下所有条件为真时:

禁用脚本是指对于环境设置对象,当脚本未对其启用,即上述任何条件为假时。


启用脚本是指对于节点node,如果node节点文档浏览上下文非空,并且脚本已启用,对于node相关设置对象

禁用脚本是指当脚本未启用时,即当其节点文档浏览上下文为空或当脚本已禁用时,对于其相关设置对象

8.1.3.5 安全上下文

如果以下算法返回true,则环境environment是一个安全上下文

  1. 如果environment是一个环境设置对象,那么:

    1. globalenvironment全局对象

    2. 如果globalWorkerGlobalScope,那么:

      1. 如果global所有者集[0]的相关设置对象是一个安全上下文,则返回true。

        我们只需要检查第0项,因为它们必然都是一致的。

      2. 返回false。

    3. 如果globalWorkletGlobalScope,则返回true。

      Worklet只能在安全上下文中创建。

  2. 如果environment顶级创建URLURL是否可能可信的结果是"Potentially Trustworthy",则返回true。

  3. 返回false。

如果一个环境不是安全上下文,则它是一个非安全上下文

8.1.4 脚本处理模型

8.1.4.1 脚本

脚本是两种可能的结构之一(即经典脚本模块脚本)。所有脚本都具有以下属性:

设置对象

一个环境设置对象,其中包含与相同上下文中的其他脚本共享的各种设置。

记录

以下之一:

解析错误

一个 JavaScript 值,仅当记录为 null 时才有意义,表示相应的脚本源代码无法解析。

此值用于在创建脚本时内部跟踪立即解析错误,不应直接使用。相反,确定此脚本的“出了什么问题”时,请参考要重新抛出的错误

要重新抛出的错误

一个表示阻止评估成功的错误的 JavaScript 值。任何运行脚本的尝试都会重新抛出该错误。

这可能是脚本的解析错误,但对于模块脚本,它可能是其依赖项之一的解析错误,或解析模块说明符时产生的错误。

由于此异常值是由 JavaScript 规范提供的,我们知道它永远不会为 null,因此我们使用 null 表示没有发生错误。

获取选项
空值或脚本获取选项,其中包含与获取此脚本或其导入的模块脚本相关的各种选项。
基本 URL

空值或用于解析模块说明符的基本URL。当非空时,对于外部脚本,这将是脚本获取的 URL,对于内联脚本,则是包含文档的文档基本 URL

经典脚本是一种脚本,具有以下附加的项目

静默错误布尔值

一个布尔值,如果为 true,则表示不会提供此脚本中的错误信息。这用于静默跨域脚本的错误,因为这可能会泄露私人信息。

模块脚本是另一种脚本。它没有额外的项目

模块脚本可以分为四种类型:

由于 CSS 样式表和 JSON 文档不会导入依赖模块,并且在评估时不会抛出异常,因此获取选项基本 URL对于CSS 模块脚本JSON 模块脚本始终为 null。

活动脚本由以下算法确定:

  1. recordGetActiveScriptOrModule()。

  2. 如果record为 null,则返回 null。

  3. 返回record.[[HostDefined]]。

活动脚本概念目前仅用于import()功能,以确定用于解析相对模块说明符的基本 URL

8.1.4.2 获取脚本

本节介绍了用于获取脚本的多个算法,接收各种必要的输入,并生成经典脚本模块脚本


脚本获取选项是一个具有以下结构项目

加密 nonce

用于初始获取和获取任何导入模块的加密 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获取优先级

给定脚本获取选项originalOptionsURLurl环境设置对象settingsObject,获取后代脚本获取选项:

  1. newOptions成为originalOptions的副本。

  2. integrity为空字符串。

  3. 如果settingsObject全局对象Window对象,则将integrity设置为通过urlsettingsObject解析模块完整性元数据的结果。

  4. newOptions完整性元数据设置为integrity

  5. newOptions获取优先级设置为"auto"。

  6. 返回newOptions

给定URLurl环境设置对象settingsObject,解析模块完整性元数据:

  1. 断言settingsObject全局对象Window对象。

  2. map成为settingsObject全局对象导入映射

  3. 如果map完整性[url]不存在,则返回空字符串。

  4. 返回map完整性[url]。


以下算法中的多个可以通过 执行获取 钩子 算法进行自定义,该算法接收一个 请求、一个布尔值 isTopLevel 和一个 processCustomFetchResponse 算法。它会使用 processCustomFetchResponse 运行,并提供一个 响应 和一个空值(失败时)或一个 字节序列,该字节序列包含响应体。isTopLevel 对于所有 经典脚本 的获取为 true,并且对于初始获取 获取外部模块脚本图获取模块工作线程脚本图 时为 true,但对于通过 import 语句在整个图中遇到的获取或 import() 表达式的获取为 false。

默认情况下,不提供 执行获取 钩子 将导致以下算法简单地 获取 给定的 请求,并对 请求 和结果的 响应 进行特定算法的自定义。

要在这些特定算法的自定义之上层叠您自己的自定义,提供一个 执行获取 钩子,该钩子会修改给定的 请求获取 它,然后对结果的 响应 进行特定验证(如果验证失败,则以 网络错误 结束)。

该钩子还可以用于执行更微妙的自定义,例如保持 响应 的缓存,并避免完全执行 获取

Service Workers 是一个示例,它使用自己选项的钩子运行这些算法。 [SW]


现在是算法本身。

获取经典脚本,给定一个 URL url、一个 环境设置 对象 settingsObject、一个 脚本获取选项 options、一个 CORS 设置属性状态 corsSetting、一个 编码 encoding, 以及一个算法 onComplete,执行以下步骤。onComplete 必须是一个算法, 接受 null(失败时)或一个 经典脚本 (成功时)。

  1. request 成为 创建潜在 CORS 请求 的结果, 给定 url、"script" 和 corsSetting

  2. request客户端 设置为 settingsObject

  3. request发起者类型 设置为 "script"。

  4. 设置经典脚本请求,给定 requestoptions

  5. 获取 request,使用以下 processResponseConsumeBody 步骤,给定 响应 response 和 null、失败或一个 字节序列 bodyBytes

    response 可以是 CORS 同源CORS 跨源。这只会影响错误报告的方式。

    1. response 设置为 response不安全响应

    2. 如果以下任意条件为真:

      则运行 onComplete,给定 null,并中止这些步骤。

      由于历史原因,该算法不包括 MIME 类型检查,与本节中的其他脚本获取算法不同。

    3. potentialMIMETypeForEncoding 成为 提取 MIME 类型 的结果, 给定 response头部列表

    4. encoding 设置为 传统提取编码 的结果,给定 potentialMIMETypeForEncodingencoding

      这故意忽略了 MIME 类型本质

    5. sourceText 成为 解码 bodyBytes 为 Unicode,使用 encoding 作为回退编码。

      如果文件包含 BOM,解码 算法会覆盖 encoding

    6. 如果 responseCORS 跨源,则让 mutedErrors 为 true,否则为 false。

    7. script 成为 创建经典脚本 的结果,给定 sourceTextsettingsObjectresponseURLoptionsmutedErrorsurl

    8. 运行 onComplete,给定 script

获取经典的工作脚本

给定一个 URL url,一个 环境设置对象 fetchClient,一个 目标 destination,一个 环境设置对象 settingsObject,一个算法 onComplete,以及一个可选的 执行抓取钩子 performFetch,执行以下步骤。onComplete 必须是一个 算法,接受 null(失败时)或一个 经典脚本(成功时)。

  1. request 为一个新的 请求,其 URLurl客户端fetchClient目标destination发起者类型 为 "other", 模式 为 "same-origin",凭据模式 为 "same-origin", 解析器元数据 为 "not parser-inserted",并且其 使用 URL 凭据标志 被设置。

  2. 如果提供了 performFetch,则使用 request、true 和 processResponseConsumeBody(如下所定义)运行 performFetch

    否则,抓取 request,将 processResponseConsumeBody 设置为 processResponseConsumeBody(如下所定义)。

    在这两种情况下,给定 响应 response 和 null、失败或一个 字节序列 bodyBytesprocessResponseConsumeBody 为以下算法:

    1. response 设置为 response不安全响应

    2. 如果下列任何条件为真:

      那么运行 onComplete,给定 null,并中止这些步骤。

    3. 如果下列所有条件为真:

      那么运行 onComplete,给定 null,并中止这些步骤。

      出于历史原因,其他 抓取方案 被免除 MIME 类型检查,以便与历史网页兼容。我们可能会在未来收紧这一点;见 问题 #3255

    4. sourceTextUTF-8 解码 bodyBytes 的结果。

    5. script 为使用 sourceTextsettingsObjectresponseURL默认脚本抓取选项 创建经典脚本的结果。

    6. 运行 onComplete,给定 script

获取经典的工作脚本,给定一个 URL url,一个 环境设置对象 settingsObject,以及一个 可选的 执行 抓取钩子 performFetch,执行以下步骤。该算法在成功时返回一个 经典脚本,在失败时抛出一个异常。

  1. response 设置为 null。

  2. bodyBytes 设置为 null。

  3. request 设置为一个新的 请求,其 URLurl客户端settingsObject目标 为 "script",发起者类型 为 "other",解析器元数据 为 "not parser-inserted",并且其 使用 URL 凭据标志 被设置。

  4. 如果提供了 performFetch,则使用 requestisTopLevelprocessResponseConsumeBody(如下所定义)运行 performFetch

    否则,抓取 request,将 processResponseConsumeBody 设置为 processResponseConsumeBody(如下所定义)。

    在这两种情况下,给定 响应 res 和 null、失败或一个 字节序列 bbprocessResponseConsumeBody 为以下算法:

    1. bodyBytes 设置为 bb

    2. response 设置为 res

  5. 暂停,直到 response 不为 null。

    与本节中的其他算法不同,这里的抓取过程是同步的。

  6. response 设置为 response不安全响应

  7. 如果下列任何条件为真:

    则抛出一个 "NetworkError" DOMException

  8. sourceTextUTF-8 解码 bodyBytes 的结果。

  9. mutedErrors 如果 responseCORS 跨源,则为 true,否则为 false。

  10. script 为使用 sourceTextsettingsObjectresponseURL默认脚本抓取选项、以及 mutedErrors 创建经典脚本的结果。

  11. 返回 script

获取外部模块脚本图 给定一个 URL url,一个 环境设置对象 settingsObject,一个 脚本 获取选项 options,以及一个算法 onComplete,运行以下步骤。 onComplete 必须是一个算法, 接受 null(失败时)或一个 模块脚本 (成功时)。

  1. 禁止进一步的导入映射,给定 settingsObject

  2. 获取单个模块脚本,给定 urlsettingsObject, "script",optionssettingsObject,"client",true,以及 以下步骤给定 result

    1. 如果 result 为 null,运行 onComplete,给定 null,并中止这些步骤。

    2. 获取并链接模块脚本的后代, 给定 resultsettingsObject,"script" 和 onComplete

获取模块预加载模块脚本图,给定一个 URL url, 一个 目的地 destination,一个 环境设置对象 settingsObject,一个 脚本获取选项 options,以及一个算法 onComplete,运行以下步骤。 onComplete 必须是一个算法,接受 null(失败时)或一个 模块脚本(成功时)。

  1. 禁止进一步的导入映射,给定 settingsObject

  2. 获取单个模块脚本,给定 urlsettingsObjectdestinationoptionssettingsObject,"client",true,以及 以下步骤给定 result

    1. 运行 onComplete,给定 result

    2. 如果 result 不为 null,可选地 获取并链接模块脚本的后代, 给定 resultsettingsObjectdestination 和一个空算法。

      通常,这一步将有助于性能,因为它允许预加载将来必然会请求的模块,通过如 获取外部模块脚本图 的算法,该算法获取整个图。然而,用户代理可能希望在带宽受限的情况下,或相关的获取已经在进行中的情况下跳过它们。

获取内联模块脚本图,给定一个 字符串 sourceText,一个 URL baseURL,一个 环境设置对象 settingsObject,一个 脚本获取选项 options, 和一个算法 onComplete,运行以下步骤。 onComplete 必须是一个 算法,接受 null(失败时)或一个 模块脚本(成功时)。

  1. 禁止进一步的导入映射,给定 settingsObject

  2. script创建 JavaScript 模块脚本 的结果, 使用 sourceTextsettingsObjectbaseURLoptions

  3. 获取并链接模块脚本的后代, 给定 scriptsettingsObject,"script" 和 onComplete

获取模块工作线程脚本图 给定一个 URL url,一个 环境设置对象 fetchClient,一个 目的地 destination,一个 凭据模式 credentialsMode,一个 环境设置对象 settingsObject,以及一个算法 onComplete获取工作线程/模块工作线程脚本图,给定 urlfetchClientdestinationcredentialsModesettingsObjectonComplete

获取工作线程脚本图,给定一个 URL url,一个 环境设置对象 fetchClient,一个 目的地 destination,一个 凭据模式 credentialsMode,一个 环境设置对象 settingsObject,一个 模块响应映射 moduleResponsesMap,以及一个算法 onComplete获取工作线程/模块工作线程脚本图,给定 urlfetchClientdestinationcredentialsModesettingsObjectonComplete,以及以下 执行获取挂钩,给定 requestprocessCustomFetchResponse

  1. requestURLrequestURL

  2. 如果 moduleResponsesMap[requestURL] 为 "fetching",则 并行等待,直到该条目的值发生变化, 然后在 网络任务源排队一个任务,以继续执行以下步骤。

  3. 如果 moduleResponsesMap[requestURL] 存在,则:

    1. cachedmoduleResponsesMap[requestURL]。

    2. 使用 cached[0] 和 cached[1] 运行 processCustomFetchResponse

    3. 返回。

  4. 设置 moduleResponsesMap[requestURL] 为 "fetching"。

  5. 获取 request,将 processResponseConsumeBody 设置为以下步骤,给定 response response 和 null、失败或一个 字节序列 bodyBytes

    1. moduleResponsesMap[requestURL] 设置为 (responsebodyBytes)。

    2. 使用 responsebodyBytes 运行 processCustomFetchResponse

以下算法仅供本规范内部使用,作为 获取外部模块脚本图 或 上述其他类似概念的一部分,不应直接由其他规范使用。

该图示说明了这些算法如何与上述算法以及彼此相关:

获取外部模块脚本图 获取模块预加载模块脚本图 获取内联模块脚本图 获取模块工作线程脚本图 获取工作线程脚本图 获取工作线程/模块工作线程脚本图 获取子孙并链接模块脚本

获取工作线程/模块工作线程脚本图,给定一个 URL url,一个 环境设置对象 fetchClient,一个 目的地 destination,一个 凭据模式 credentialsMode,一个 环境设置对象 settingsObject,一个算法 onComplete,以及一个可选的 执行获取挂钩 performFetch,执行以下步骤。 onComplete 必须是一个接受 null(失败时)或一个 模块脚本(成功时)的算法。

  1. options 为一个 脚本获取选项,其 加密随机数 为空字符串,完整性元数据 为空字符串, 解析器元数据 为 "not-parser-inserted",凭据模式credentialsMode引用策略 为空字符串,以及 获取优先级 为 "auto"。

  2. 获取单个模块脚本,给定 urlfetchClientdestinationoptionssettingsObject, "client",true,以及 onSingleFetchComplete 如下定义。如果 performFetch 被给定,也将其传递。

    onSingleFetchComplete 给定 result 的算法如下:

    1. 如果 result 为 null,则运行 onComplete 给定 null,并中止这些步骤。

    2. 获取子孙并链接 result,给定 fetchClientdestinationonComplete。如果 performFetch 被给定,也将其传递。

获取子孙并链接 一个 模块脚本 moduleScript,给定一个 环境设置对象 fetchClient,一个 目的地 destination,一个算法 onComplete, 以及一个可选的 执行获取挂钩 performFetch,执行以下步骤。 onComplete 必须是一个接受 null(失败时)或一个 模块脚本(成功时)的算法。

  1. recordmoduleScript记录

  2. 如果 record 为 null,则:

    1. moduleScript错误重抛 设置为 moduleScript解析错误

    2. 执行 onComplete,给定 moduleScript

    3. 返回。

  3. state记录 { [[ParseError]]: null, [[Destination]]: destination, [[PerformFetch]]: null, [[FetchClient]]: fetchClient }。

  4. 如果给定了 performFetch,将 state.[[PerformFetch]] 设置为 performFetch

  5. loadingPromiserecord.LoadRequestedModules(state).

    此步骤将递归加载所有模块的传递依赖项。

  6. loadingPromise 完成时,执行以下步骤:

    1. 执行 record.Link()。

      此步骤将递归调用 Link,对所有模块的未链接依赖项进行操作。

      如果这引发异常,请捕获它,并将 moduleScript错误重抛 设置为该异常。

    2. 执行 onComplete,给定 moduleScript

  7. loadingPromise 被拒绝时,执行以下步骤:

    1. 如果 state.[[ParseError]] 不为 null,将 moduleScript错误重抛 设置为 state.[[ParseError]] 并执行 onComplete,给定 moduleScript

    2. 否则,执行 onComplete,给定 null。

      state.[[ParseError]] 为 null 表示 loadingPromise 因加载错误而被拒绝。

获取单个模块脚本,给定一个 URL url,一个 环境设置对象 fetchClient,一个 目的地 destination,一个 脚本获取选项 options, 一个 环境设置对象 settingsObject,一个 引用 referrer,一个可选的 模块请求记录 moduleRequest,一个布尔值 isTopLevel,一个算法 onComplete,以及一个可选的 执行获取挂钩 performFetch,执行以下步骤。 onComplete 必须是一个接受 null(失败时)或一个 模块脚本(成功时)的算法。

  1. moduleType 为 "javascript-or-wasm"。

  2. 如果给定了 moduleRequest,则将 moduleType 设置为运行 模块请求中的模块类型 步骤的结果,给定 moduleRequest

  3. 断言:运行 模块类型允许 步骤的结果,给定 moduleTypesettingsObject,为 true。否则,我们不会到达这一点,因为在检查 moduleRequest.[[Attributes]] 时,失败会在 HostLoadImportedModule获取单个导入的模块脚本 时引发。

  4. moduleMapsettingsObject模块映射

  5. 如果 moduleMap[(url, moduleType)] 是 "fetching",则等待 并行 直到该条目的值发生变化,然后 排队一个任务网络任务源 以继续执行以下步骤。

  6. 如果 moduleMap[(url, moduleType)] 存在,运行 onComplete 给定 moduleMap[(url, moduleType)], 并返回。

  7. moduleMap[(url, moduleType)] 设置为 "fetching"。

  8. request 为一个新的 请求,其 URLurl模式 为 "cors",引用referrer客户端fetchClient

  9. request目的地 设置为 运行 从模块类型获取目的地 步骤的结果, 给定 destinationmoduleType

  10. 如果 destination 为 "worker"、"sharedworker" 或 "serviceworker",并且 isTopLevel 为 true,则将 request模式 设置为 "same-origin"。

  11. request发起者类型 设置为 "script"。

  12. 设置模块脚本请求,给定requestoptions

  13. 如果给定了performFetch,运行performFetch,传递requestisTopLevel,并且按照下文定义的processResponseConsumeBody处理。

    否则,fetch request,并将processResponseConsumeBody设置为按照下文定义的processResponseConsumeBody

    在两种情况下,processResponseConsumeBody给定response response和空、失败或字节序列 bodyBytes,执行以下算法:

    response总是CORS同源

    1. 如果以下任一情况为真:

      那么设置 moduleMap[(url, moduleType)]为null,运行给定null的onComplete,并中止这些步骤。

    2. mimeType为从response头列表提取MIME类型的结果。

    3. moduleScript为null。

    4. referrerPolicy为从response解析`Referrer-Policy`头的结果。[REFERRERPOLICY]

    5. 如果referrerPolicy不是空字符串,设置options引用者策略referrerPolicy

    6. 如果mimeType本质为"application/wasm",并且moduleType为"javascript-or-wasm",那么设置moduleScript创建WebAssembly模块脚本的结果,传递bodyBytessettingsObjectresponseURLoptions

    7. 否则:

      1. sourceTextUTF-8解码 bodyBytes的结果。

      2. 如果mimeTypeJavaScript MIME类型,并且moduleType是"javascript-or-wasm",那么设置moduleScript创建JavaScript模块脚本的结果,传递sourceTextsettingsObjectresponseURLoptions

      3. 如果mimeTypeMIME类型本质为"text/css",并且moduleType为"css",那么设置moduleScript创建CSS模块脚本的结果,传递sourceTextsettingsObject

      4. 如果mimeTypeJSON MIME类型,并且moduleType是"json",那么设置moduleScript创建JSON模块脚本的结果,传递sourceTextsettingsObject

    8. 设置 moduleMap[(url, moduleType)]为moduleScript,并运行onComplete,传递moduleScript

      故意将模块映射的键设置为请求URL,而基础URL设置为响应URL。前者用于去重请求,而后者用于URL解析。

获取单个导入的模块脚本,给定一个 URL url,一个 环境设置对象 fetchClient,一个 目的地 destination,一个 脚本获取选项 options,一个 环境设置对象 settingsObject,一个 引用 referrer,一个 模块请求记录 moduleRequest,一个算法 onComplete,以及一个可选的 执行获取挂钩 performFetch,执行以下步骤。 onComplete 必须是一个接受 null(失败时)或一个 模块脚本(成功时)的算法。

  1. 断言moduleRequest.[[Attributes]] 不包含任何 记录 entry,使得 entry.[[Key]] 不是 "type",因为我们在 HostGetSupportedImportAttributes 中只要求了 "type" 属性。

  2. moduleType 为运行 模块请求中的模块类型 步骤的结果,给定 moduleRequest

  3. 如果运行 模块类型允许 步骤的结果,给定 moduleTypesettingsObject 为 false,则运行 onComplete 给定 null,并返回。

  4. 获取单个模块脚本,给定 urlfetchClientdestinationoptionssettingsObjectreferrermoduleRequest、false 和 onComplete。如果给定了 performFetch,也一并传递。

8.1.4.3 创建脚本

创建经典脚本,给定一个字符串source,一个环境设置对象settings,一个URLbaseURL,一个脚本抓取选项options,一个可选的布尔值mutedErrors(默认为false),以及一个可选的URL-或-nullsourceURLForWindowScripts(默认为null):

  1. 如果mutedErrors为true,则将baseURL设置为about:blank

    mutedErrors为true时,baseURL是脚本的CORS跨域响应URL,它不应暴露给JavaScript。因此,baseURL在此处进行了清理。

  2. 如果禁用了脚本对于settings,则将source设置为空字符串。

  3. 创建一个新的经典脚本,该算法将随后对其进行初始化。

  4. 设置script设置对象settings

  5. 设置script基本URLbaseURL

  6. 设置script抓取选项options

  7. 设置script静默错误mutedErrors

  8. 设置script解析错误待重抛错误为null。

  9. 记录经典脚本创建时间,给定scriptsourceURLForWindowScripts

  10. resultParseScript(sourcesettingsrealmscript)。

    这里将script作为最后一个参数传递,确保result.[[HostDefined]]将是script

  11. 如果result是一个错误列表,则:

    1. script解析错误待重抛错误设置为result[0]。

    2. 返回script

  12. script记录设置为result

  13. 返回script

从模块请求中获取模块类型的步骤,给定一个ModuleRequest记录moduleRequest,如下所示:

  1. moduleType为"javascript-or-wasm"。

  2. 如果moduleRequest的[[Attributes]]中有一个记录entry,且entry的[[Key]]是"type",则:

    1. 如果entry的[[Value]]是"javascript-or-wasm",则将moduleType设置为null。

      本规范在内部将"javascript-or-wasm"模块类型用于JavaScript模块脚本WebAssembly模块脚本,因此此步骤用于防止使用"javascript-or-wasm"类型属性导入模块(null的moduleType将导致模块类型允许检查失败)。

    2. 否则,将moduleType设置为entry的[[Value]]。

  3. 返回moduleType

模块类型允许的步骤,给定一个字符串moduleType和一个环境设置对象settings,如下所示:

  1. 如果moduleType不是"javascript-or-wasm"、"css"或"json",则返回false。

  2. 如果moduleType是"css",且CSSStyleSheet接口未在settingsrealm暴露,则返回false。

  3. 返回true。

从模块类型获取抓取目标的步骤,给定一个目标defaultDestination和一个字符串moduleType,如下所示:

  1. 如果moduleType是"json",则返回"json"。
  2. 如果moduleType是"css",则返回"style"。
  3. 返回defaultDestination
8.1.4.4 调用脚本

运行经典脚本,给定一个经典脚本script,以及一个可选的布尔值rethrow errors(默认为false):

  1. settingsscript设置对象

  2. 检查我们是否可以运行脚本,使用settings。如果返回"不运行",则返回NormalCompletion(空)。

  3. 记录经典脚本执行开始时间,给定script

  4. 准备运行脚本,给定settings

  5. evaluationStatus为null。

  6. 如果script待重抛错误不为null,则将evaluationStatus设置为Completion { [[Type]]: throw, [[Value]]: script待重抛错误, [[Target]]: empty }。

  7. 否则,将evaluationStatus设置为ScriptEvaluation(script记录)。

    如果ScriptEvaluation未完成,因为用户代理中止了运行中的脚本,则将evaluationStatus保持为null。

  8. 如果evaluationStatus中止完成,则:

    1. 如果rethrow errors为true且script静默错误为false,则:

      1. 在运行脚本后清理,使用settings

      2. 重抛evaluationStatus.[[Value]]。

    2. 如果rethrow errors为true且script静默错误为true,则:

      1. 在运行脚本后清理,使用settings

      2. 抛出"NetworkError" DOMException

    3. 否则,rethrow errors为false。执行以下步骤:

      1. 报告异常,由evaluationStatus.[[Value]]给出,针对script设置对象全局对象

      2. 在运行脚本后清理,使用settings

      3. 返回evaluationStatus

  9. 在运行脚本后清理,使用settings

  10. 如果evaluationStatus是正常完成,则返回evaluationStatus

  11. 如果我们到达此步骤,evaluationStatus保持为null,因为脚本在评估过程中被提前中止。返回Completion { [[Type]]: throw, [[Value]]: 一个新的"QuotaExceededError" DOMException, [[Target]]: empty }。

给定一个模块脚本script和一个可选的布尔值preventErrorReporting(默认值为false),以运行一个模块脚本

  1. settings成为script设置对象

  2. 使用settings检查是否可以运行脚本。如果返回“不要运行”,则返回已解决的promise,其值为undefined。

  3. 记录模块脚本执行开始时间,给定script

  4. 给定settings准备运行脚本

  5. evaluationPromise设置为null。

  6. 如果script要重新抛出的错误不为null,则将evaluationPromise设置为被拒绝的promise,其值为script要重新抛出的错误

  7. 否则:

    1. record成为script记录

    2. evaluationPromise设置为record.Evaluate()。

      这一步将递归地评估模块的所有依赖项。

      如果由于用户代理中止运行脚本而导致Evaluate无法完成,则将evaluationPromise设置为被拒绝的promise,其值为一个新的QuotaExceededErrorDOMException

  8. 如果preventErrorReporting为false,则在evaluationPromise被拒绝时,将reason传递给报告异常,其中reason来自script设置对象全局对象

  9. 使用settings清理运行脚本后的环境

  10. 返回evaluationPromise

检查是否可以运行脚本的步骤是给定环境设置对象settings,返回“运行”或“不要运行”。

  1. 如果settings指定的全局对象是一个Window对象,并且其Document对象不是完全激活的,则返回“不要运行”。

  2. 如果settings脚本被禁用,则返回“不要运行”。

  3. 返回“运行”。

准备运行脚本的步骤如下,给定一个环境设置对象settings

  1. settings域执行上下文压入JavaScript执行上下文栈;它现在是运行的JavaScript执行上下文

  2. settings添加到外围代理事件循环中的当前运行任务脚本评估环境设置对象集合

清理运行脚本后的步骤如下,给定一个环境设置对象settings

  1. 断言settings域执行上下文运行的JavaScript执行上下文

  2. JavaScript执行上下文栈中移除settings域执行上下文

  3. 如果JavaScript执行上下文栈现在为空,执行微任务检查点。(如果此操作运行脚本,这些算法将被重新调用。)

这些算法不是由一个脚本直接调用另一个脚本,而是可能以间接方式重新调用,例如,如果一个脚本分派了一个事件并且事件监听器已注册。

运行中的脚本是在[[HostDefined]]字段中,在ScriptOrModule组件中的脚本

8.1.4.5 终止脚本

虽然JavaScript规范未考虑这种可能性,但有时有必要终止正在运行的脚本。这将导致任何ScriptEvaluation源文本模块记录Evaluate的调用立即停止,清空JavaScript执行上下文栈,而不会触发任何常规机制,如finally块。 [JAVASCRIPT]

用户代理可能会对脚本施加资源限制,例如CPU配额、内存限制、总执行时间限制或带宽限制。当脚本超出限制时,用户代理可能会抛出"QuotaExceededError"DOMException终止脚本,不抛出异常,提示用户或限制脚本执行。

例如,以下脚本永远不会终止。用户代理可能在等待几秒后提示用户终止脚本或让其继续运行。

<script>
 while (true) { /* loop */ }
</script>

鼓励用户代理允许用户在被脚本提示时(例如使用window.alert()API)或由于脚本的行为(例如超出时间限制)时禁用脚本。

如果在脚本执行时禁用脚本,则应立即终止该脚本。

用户代理可能允许用户仅为关闭浏览上下文的目的专门禁用脚本。

例如,上述示例中提到的提示还可以为用户提供一种机制,允许其直接关闭页面,而不运行任何unload事件处理程序。

8.1.4.6 运行时脚本错误

reportError

在所有当前的引擎中支持。

Firefox93+Safari15.4+Chrome95+
Opera?Edge95+
Edge (Legacy)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
self.reportError(e)

在全局对象上为给定的值 e 派发一个error 事件,其方式与未处理的异常相同。

从 JavaScript 值 exception提取错误信息

  1. attributes 成为由 IDL 属性键控的空映射

  2. attributes[error] 设置为 exception

  3. attributes[message], attributes[filename], attributes[lineno], 和 attributes[colno] 设置为从 exception 中派生的实现定义的值。

    浏览器实现了此处或 JavaScript 规范中未指定的行为,以收集有用的值,包括在不常见的情况下(例如,eval)。未来,可能会更详细地指定这些行为。

  4. 返回 attributes

为特定的全局对象 global 和可选的布尔值 omitError(默认值为 false),报告异常 exception(它是一个 JavaScript 值):

  1. notHandled 为 true。

  2. errorInfo 成为从 exception提取错误信息的结果。

  3. script 成为通过脚本找到的 实现定义的脚本,或为 null。通常应该是正在运行的脚本(尤其是在运行经典脚本期间)。

    在不常见的情况下,实现尚未对用于确定错误是否静音的脚本实现互操作行为达成共识。

  4. 如果 script经典脚本script静音错误为 true,则将 errorInfo[error] 设置为 null,将 errorInfo[message] 设置为 "Script error.", 将 errorInfo[filename] 设置为空字符串, 将 errorInfo[lineno] 设置为 0, 并将 errorInfo[colno] 设置为 0。

  5. 如果 omitError 为 true,则将 errorInfo[error] 设置为 null。

  6. 如果 global 不在错误报告模式中,则:

    1. global错误报告模式中 设置为 true。
    2. 如果 global 实现了 EventTarget, 则将 notHandled 设置为触发一个名为 error 的事件的结果, 在 global 上,使用 ErrorEvent, 并将 cancelable 属性初始化为 true, 并根据 errorInfo 初始化附加属性。

      在事件处理程序中返回 true 会根据事件处理程序处理算法取消事件。

    3. global错误报告模式中 设置为 false。

  7. 如果 notHandled 为 true,则:

    1. errorInfo[error] 设置为 null。

    2. 如果 global 实现了 DedicatedWorkerGlobalScope, 则在 DOM 操作任务源上为 global 关联的 Worker相关全局对象排队执行这些步骤:

      1. workerObject 成为与 global 关联的 Worker 对象。

      2. notHandled 设置为触发一个名为 error 的事件的结果, 在 workerObject 上,使用 ErrorEvent, 并将 cancelable 属性初始化为 true, 并根据 errorInfo 初始化附加属性。

      3. 如果 notHandled 为 true,则为 workerObject相关全局对象,将 exception 报告给 omitError 设置为 true。

        在所有者领域中实际的 exception 值将不可用,但用户代理仍会携带足够的信息来设置消息、文件名和其他属性,并可能报告给开发人员控制台。

  8. 否则,用户代理可以将 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

在所有当前的引擎中支持。

Firefox27+Safari6+Chrome10+
Opera11+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+

接口 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。在适当情况下,它被设置为表示错误的对象(例如,在未捕获的异常情况下,设置为异常对象)。

8.1.4.7 未处理的 Promise 拒绝

Window/rejectionhandled_event

支持所有当前的引擎。

Firefox69+Safari11+Chrome49+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS11.3+Chrome Android?WebView Android?Samsung Internet?Opera Android?

除了同步的运行时脚本错误之外,脚本还可能遇到异步的 Promise 拒绝,这些拒绝通过unhandledrejectionrejectionhandled事件进行跟踪。跟踪这些拒绝是通过HostPromiseRejectionTracker抽象操作完成的,但它们的报告方式在这里定义。

要根据全局对象 global通知关于拒绝的 promises

  1. list 设为 global列表克隆,包含即将通知的拒绝 promises 列表

  2. 如果 list 为空,则返回。

  3. 清空 global即将通知的拒绝 promises 列表

  4. 排入一个全局任务DOM 操作任务源,给定 global,以运行以下步骤:

    1. 遍历 list 中的每个 promise p:

      1. 如果 p 的 [[PromiseIsHandled]] 为 true,则继续

      2. notCanceled 设为 触发一个事件名为unhandledrejection, 在 global上,使用 PromiseRejectionEvent, 其cancelable 属性初始化为 true,promise 属性初始化为 p,以及reason 属性初始化为 p 的 [[PromiseResult]]。

      3. 如果 notCanceled 为 true,则用户代理可以将 p 的 [[PromiseResult]] 报告给开发者控制台。

      4. 如果 p 的 [[PromiseIsHandled]] 为 false,则 p 追加到 global未处理拒绝的 promises 弱引用集合

PromiseRejectionEvent

支持所有当前的引擎。

Firefox69+Safari11+Chrome49+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS11.3+Chrome Android?WebView Android?Samsung Internet?Opera Android?

接口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;
};

PromiseRejectionEvent/promise

支持所有当前的引擎。

Firefox69+Safari11+Chrome49+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS11.3+Chrome Android?WebView Android?Samsung Internet?Opera Android?

属性promise必须返回其初始化的值。它表示此通知所涉及的promise。

由于 Promise<T> 类型的Web IDL转换规则总是将输入包装到一个新的promise中, promise 属性的类型改为object, 这更适合表示原始promise对象的不透明句柄。

PromiseRejectionEvent/reason

支持所有当前的引擎。

Firefox69+Safari11+Chrome49+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS11.3+Chrome Android?WebView Android?Samsung Internet?Opera Android?

属性reason必须返回其初始化的值。它表示promise被拒绝的原因。

8.1.4.8 Import map 解析结果

Import map解析结果是一个类似于结构脚本,也可以存储在script元素的结果中,但不计为其他用途的脚本。它具有以下条目

一个import map
一个import map或null。
一个待重新抛出的错误
一个JavaScript值,表示一个错误,当不为null时,将阻止使用此import map。

创建一个import map解析结果,给定一个字符串input 和一个URLbaseURL

  1. result成为一个import map解析结果,其import map为null,待重新抛出的错误为null。

  2. 解析import map字符串,给定inputbaseURL,捕获任何异常。如果抛出异常,则将result待重新抛出的错误设置为该异常。否则,将resultimport map设置为返回值。

  3. 返回result

注册一个import map,给定一个Windowglobal和一个import map解析结果result

  1. 如果 result要重新抛出的错误不为 null,则报告一个异常,由 result要重新抛出的错误global 提供,并返回。

  2. 断言global导入映射是一个空的导入映射

  3. global导入映射设置为 result导入映射

8.1.5 模块说明符解析

8.1.5.1 解析算法

解析模块说明符算法是将模块说明符字符串转换为URL的主要入口。当不涉及导入映射时,它相对简单,并简化为解析类URL模块说明符

当存在非空的导入映射时,行为会更加复杂。它会从所有适用的模块说明符映射中检查候选条目,从最具体到最不具体的作用域(回退到顶级未作用域的imports),以及从最具体到最不具体的前缀。对于每个候选条目,解析imports匹配算法将给出以下结果之一:

最终,如果通过任何候选的模块说明符映射没有找到成功的解析,解析模块说明符将抛出异常。因此,结果始终是URL或抛出的异常。

给定一个脚本或null的referringScript和一个字符串 specifier,执行解析模块说明符

  1. settingsObjectbaseURL为null。

  2. 如果referringScript不为null,则:

    1. settingsObject设置为referringScript设置对象

    2. baseURL设置为referringScript基本URL

  3. 否则:

    1. 断言:存在当前设置对象

    2. settingsObject设置为当前设置对象

    3. baseURL设置为settingsObjectAPI基本URL

  4. importMap空导入映射

  5. 如果settingsObject全局对象实现了Window,则将importMap设置为settingsObject全局对象导入映射

  6. baseURLStringbaseURL序列化

  7. asURL解析类URL模块说明符给定specifierbaseURL的结果。

  8. normalizedSpecifierasURL序列化结果,如果asURL不为null;否则为specifier

  9. 对每个 scopePrefixscopeImportsimportMap作用域中:

    1. 如果scopePrefixbaseURLString,或如果scopePrefix以U+002F (/)结尾,并且scopePrefixbaseURLString代码单元前缀,则:

      1. scopeImportsMatch解析imports匹配给定normalizedSpecifierasURLscopeImports的结果。

      2. 如果scopeImportsMatch不为null,则返回scopeImportsMatch

  10. topLevelImportsMatch解析imports匹配给定normalizedSpecifierasURLimportMapimports的结果。

  11. 如果topLevelImportsMatch不为null,则返回topLevelImportsMatch

  12. 此时,specifier未被importMap重新映射到任何内容,但它可能已转化为URL。

    如果asURL不为null,则返回asURL

  13. 抛出一个TypeError,表示specifier是一个裸说明符,但未被importMap重新映射到任何内容。

给定一个字符串 normalizedSpecifier、一个URL或null asURL和一个模块说明符映射 specifierMap,执行解析imports匹配

  1. 对每个 specifierKeyresolutionResultspecifierMap中:

    1. 如果specifierKeynormalizedSpecifier,则:

      1. 如果resolutionResult为null,则抛出一个TypeError,表示解析specifierKey被null条目阻止。

        这将终止整个解析模块说明符算法,不进行任何进一步的回退。

      2. 断言resolutionResult是一个URL

      3. 返回resolutionResult

    2. 如果以下所有条件为真:

      那么:

      1. 如果resolutionResult为null,则抛出一个TypeError,表示解析specifierKey被null条目阻止。

        这将终止整个解析模块说明符算法,不进行任何进一步的回退。

      2. 断言resolutionResult是一个URL

      3. afterPrefixnormalizedSpecifier在初始specifierKey前缀之后的部分。

      4. 断言resolutionResult序列化,以U+002F (/)结尾,如在解析期间强制。

      5. urlURL解析后的afterPrefix,使用resolutionResult

      6. 如果url失败,则抛出一个TypeError,表示解析normalizedSpecifier被阻止,因为afterPrefix部分无法相对于映射到的resolutionResultspecifierKey前缀进行URL解析。

        这将终止整个解析模块说明符算法,不进行任何进一步的回退。

      7. 断言url是一个URL

      8. 如果resolutionResult序列化不是url代码单元前缀,则抛出一个TypeError,表示解析normalizedSpecifier被阻止,因为它回溯到了其前缀specifierKey之上。

        这将终止整个解析模块说明符算法,不进行任何进一步的回退。

      9. 返回url

  2. 返回null。

    解析模块说明符算法将回退到更不具体的作用域,或“imports”,如果可能的话。

给定一个字符串 specifier和一个URL baseURL,执行解析类URL模块说明符

  1. 如果specifier /”、“./”或“../”开头,则:

    1. urlURL解析后的specifier,使用baseURL

    2. 如果url失败,则返回null。

      这种情况可能发生的一个例子是,如果specifier是“../foo”并且baseURL是一个data: URL。

    3. 返回url

    这包括specifier //”开头的情况,即,方案相对URL。因此,url可能会有与baseURL不同的主机

  2. urlURL解析后的specifier(无基本URL)。

  3. 如果url失败,则返回null。

  4. 返回url

8.1.5.2 Import maps

一个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.jsURL中获取并评估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.jsURL中获取并评估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"语句将会根据包含该语句的引用脚本所在的位置有不同的含义:

作用域的一个典型用法是允许在 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对象:

8.1.5.3 导入映射处理模型

形式上,导入映射是一个包含三个结构体

模块说明符映射是一个有序映射,其字符串,其URL或空值。

模块完整性映射是一个有序映射,其URL,其为将用于完整性元数据字符串

空导入映射是一个导入映射,其importsscopes均为空映射。


每个窗口都有一个导入映射,最初是一个空导入映射

每个窗口都有一个允许导入映射的布尔值,初始为true。

禁止进一步的导入映射,给定一个环境设置对象settingsObject

  1. global成为settingsObject全局对象

  2. 如果global没有实现窗口,则返回。

  3. global允许导入映射设置为false。

当前导入映射在任何模块加载开始后,或导入一个导入映射后,均被禁止。这些限制可能会在未来的规范修订中取消。


解析导入映射字符串,给定一个字符串input和一个URLbaseURL

  1. parsed为给定input解析JSON字符串为Infra值的结果。

  2. 如果parsed不是一个有序映射,则抛出一个TypeError,表明顶级值需要是一个JSON对象。

  3. sortedAndNormalizedImports成为一个空的有序映射

  4. 如果parsed["imports"]存在,则:

    1. 如果parsed["imports"]不是一个有序映射,则抛出一个TypeError,表明"imports"顶级键的值需要是一个JSON对象。

    2. sortedAndNormalizedImports设置为给定parsed["imports"]和baseURL排序并规范化模块说明符映射的结果。

  5. sortedAndNormalizedScopes成为一个空的有序映射

  6. 如果parsed["scopes"]存在,则:

    1. 如果parsed["scopes"]不是一个有序映射,则抛出一个TypeError,表明"scopes"顶级键的值需要是一个JSON对象。

    2. sortedAndNormalizedScopes设置为给定parsed["scopes"]和baseURL排序并规范化范围的结果。

  7. normalizedIntegrity成为一个空的有序映射

  8. 如果parsed["integrity"]存在,则:

    1. 如果parsed["integrity"]不是一个有序映射,则抛出一个TypeError,表明"integrity"顶级键的值需要是一个JSON对象。

    2. normalizedIntegrity设置为给定parsed["integrity"]和baseURL规范化模块完整性映射的结果。

  9. 如果parsed包含除"imports”、“scopes”或"integrity”之外的任何项,则用户代理应向控制台报告警告,表明导入映射中存在无效的顶级键。

    这可以帮助检测拼写错误。这不是错误,因为这会阻止将来的扩展兼容性地添加。

  10. 返回一个导入映射,其importssortedAndNormalizedImports,其scopessortedAndNormalizedScopes,其integritynormalizedIntegrity

从该解析算法生成的导入映射是高度规范化的。例如,给定一个基本URL为https://example.com/base/page.html的输入

{
"imports": {
"/app/helper": "node_modules/helper/index.mjs",
"lodash": "/node_modules/lodash-es/lodash.js"
}
}

将生成一个导入映射,其imports

«[
"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

  1. normalized成为一个空的有序映射

  2. 对每个specifierKeyvalueoriginalMap进行:

    1. normalizedSpecifierKey成为给定specifierKeybaseURL规范化说明符键的结果。

    2. 如果normalizedSpecifierKey为空,则继续

    3. 如果value不是一个字符串,则:

      1. 用户代理可以向控制台报告警告,表明地址需要是字符串。

      2. normalized[normalizedSpecifierKey]设置为空。

      3. 继续

    4. addressURL成为给定valuebaseURL解析类似URL的模块说明符的结果。

    5. 如果addressURL为空,则:

      1. 用户代理可以向控制台报告警告,表明地址无效。

      2. normalized[normalizedSpecifierKey]设置为空。

      3. 继续

    6. 如果specifierKey以U+002F(/)结尾,并且addressURL序列化结果不以U+002F(/)结尾,则:

      1. 用户代理可以向控制台报告警告,表明为说明符键specifierKey提供的地址无效;由于specifierKey以斜杠结尾,因此地址也需要以斜杠结尾。

      2. normalized[normalizedSpecifierKey]设置为空。

      3. 继续

    7. normalized[normalizedSpecifierKey]设置为addressURL

  3. 返回结果按降序排序normalized,其中条目a小于条目b,如果a代码单元小于b

排序并规范化范围,给定一个有序映射originalMap和一个URLbaseURL

  1. normalized成为一个空的有序映射

  2. 对每个scopePrefixpotentialSpecifierMaporiginalMap进行:

    1. 如果potentialSpecifierMap不是一个有序映射,则抛出一个TypeError,表明前缀为scopePrefix的范围的值需要是一个JSON对象。

    2. scopePrefixURL成为给定scopePrefixbaseURLURL解析的结果。

    3. 如果scopePrefixURL解析失败,则:

      1. 用户代理可以向控制台报告警告,表明 范围前缀URL无法解析。

      2. 继续

    4. normalizedScopePrefix成为scopePrefixURL序列化结果。

    5. normalized[normalizedScopePrefix]设置为给定potentialSpecifierMapbaseURL排序并规范化模块说明符映射的结果。

  3. 返回结果按降序排序normalized,其中条目a小于条目b,如果a代码单元小于b

在上述两个算法中,按降序排序键和范围的效果是将"foo/bar/"放在"foo/"之前。这反过来使得"foo/bar/"在模块说明符解析期间比"foo/"具有更高的优先级。

规范化模块完整性映射,给定一个有序映射originalMap

  1. normalized成为一个空的有序映射

  2. 对每个keyvalueoriginalMap进行:

    1. resolvedURL成为给定keybaseURL解析类似URL的模块说明符的结果。

      与"imports"不同,完整性映射的键被视为URL,而不是模块说明符。然而,我们使用解析类似URL的模块说明符算法禁止像foo这样的"裸"相对URL,因为它们可能被误认为是模块说明符。

    2. 如果resolvedURL为空,则:

      1. 用户代理可以向控制台报告警告,表明键解析失败。

      2. 继续

    3. 如果value不是一个字符串,则:

      1. 用户代理可以向控制台报告警告,表明完整性元数据值需要是字符串

      2. 继续

    4. normalized[resolvedURL]设置为value

  3. 返回normalized

规范化说明符键,给定一个字符串specifierKey和一个URLbaseURL

  1. 如果specifierKey为空字符串,则:

    1. 用户代理可以向控制台报告警告,表明说明符键不能为空字符串。

    2. 返回null。

  2. url成为给定specifierKeybaseURL解析类似URL的模块说明符的结果。

  3. 如果url不为空,则返回url序列化结果。

  4. 返回specifierKey

8.1.6 JavaScript 规范宿主钩子

JavaScript 规范包含许多实现定义的抽象操作,这些操作因主机环境而异。本节为用户代理主机定义了这些操作。

8.1.6.1HostEnsureCanAddPrivateElement(O)

JavaScript 包含一个实现定义HostEnsureCanAddPrivateElement(O)抽象操作。用户代理必须使用以下实现:[JAVASCRIPT]

  1. 如果OWindowProxy对象,或实现Location,则返回完成 { [[Type]]: throw, [[Value]]: 新的TypeError }。

  2. 返回NormalCompletion(unused)。

JavaScript 私有字段可以应用于任意对象。由于这可能显著复杂化特别是异类主机对象的实现,JavaScript 语言规范提供了这个挂钩,允许主机在满足主机定义标准的对象上拒绝私有字段。在 HTML 的情况下,WindowProxyLocation有复杂的语义——尤其是在导航和安全性方面——使得私有字段语义的实现具有挑战性,因此我们的实现只是拒绝这些对象。

8.1.6.2HostEnsureCanCompileStrings(realm, parameterStrings, bodyString, codeString, compilationType, parameterArgs, bodyArg)

JavaScript 包含一个实现定义HostEnsureCanCompileStrings抽象操作,由动态代码品牌检查提案重新定义。用户代理必须使用以下实现:[JAVASCRIPT] [JSDYNAMICCODEBRANDCHECKS]

  1. 执行 ? EnsureCSPDoesNotBlockStringCompilation(realm, parameterStrings, bodyString, codeString, compilationType, parameterArgs, bodyArg)。[CSP]

8.1.6.3 HostGetCodeForEval(argument)

动态代码品牌检查提案包含一个实现定义HostGetCodeForEval(argument)抽象操作。用户代理必须使用以下实现:[JSDYNAMICCODEBRANDCHECKS]

  1. 如果argumentTrustedScript对象,则返回argumentdata

  2. 否则,返回no-code。

8.1.6.4 HostPromiseRejectionTracker(promise, operation)

JavaScript 包含一个实现定义HostPromiseRejectionTracker(promise, operation)抽象操作。用户代理必须使用以下实现:[JAVASCRIPT]

  1. script 设为运行中的脚本

  2. 如果 script经典脚本script静默错误为 true,则返回。

  3. settingsObject 设为当前设置对象

  4. 如果 script 不为 null,则将 settingsObject 设为 script设置对象

  5. global 设为 settingsObject全局对象

  6. 如果 operation 是 "reject",则:

    1. promise 追加到 global即将通知的拒绝 promises 列表中。

  7. 如果 operation 是 "handle",则:

    1. 如果 global即将通知的拒绝 promises 列表包含 promise,则从该列表中移除 promise并返回。

    2. 如果 global未处理拒绝的 promises 弱引用集合包含 promise,则返回。

    3. global未处理拒绝的 promises 弱引用集合中移除 promise

    4. 排入一个全局任务DOM 操作任务源,给定 global,以触发一个事件名为rejectionhandledglobal 上,使用 PromiseRejectionEvent, 其 promise 属性初始化为 promise,以及 reason 属性初始化为 promise 的 [[PromiseResult]]。

8.1.6.5 HostSystemUTCEpochNanoseconds(global)

Temporal 提案包含一个实现定义HostSystemUTCEpochNanoseconds抽象操作。用户代理必须使用以下实现:[JSTEMPORAL]

  1. settingsObject成为global相关设置对象

  2. time成为settingsObject当前墙上时间

  3. ns成为从Unix纪元time的纳秒数,四舍五入到最接近的整数。

  4. 返回将ns限制在nsMinInstantnsMaxInstant之间的结果。

8.1.6.6 与 JavaScript 任务相关的宿主钩子

Reference/Global_Objects/Promise#Incumbent_settings_object_tracking

仅在一个引擎中支持。

Firefox50+SafariNoChromeNo
Opera?EdgeNo
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

JavaScript 规范定义了作业将在主机上安排并稍后运行,以及封装在作业中调用的JavaScript函数的JobCallback 记录。JavaScript规范包含许多实现定义的抽象操作,允许主机定义作业的调度方式和JobCallback的处理方式。HTML使用这些抽象操作通过保存和恢复承诺中的现任设置对象以及JobCallbacks中的JavaScript执行上下文跟踪现任设置对象活动脚本。本节为用户代理主机定义了这些操作。

8.1.6.6.1 HostCallJobCallback(callback, V, argumentsList)

JavaScript 包含一个实现定义HostCallJobCallback(callback, V, argumentsList)抽象操作,以便在从任务内部调用 JavaScript 回调时让主机恢复状态。用户代理必须使用以下实现:[JAVASCRIPT]

  1. incumbent settings成为callback.[[HostDefined]].[[IncumbentSettings]]。

  2. script execution context成为callback.[[HostDefined]].[[ActiveScriptContext]]。

  3. 准备运行回调,使用incumbent settings

    这会在回调运行时影响现任概念。

  4. 如果script execution context不为null,则script execution context压入JavaScript 执行上下文堆栈

    这会在回调运行时影响活动脚本

  5. result成为调用(callback.[[Callback]], V, argumentsList)的结果。

  6. 如果script execution context不为null,则script execution contextJavaScript 执行上下文堆栈中弹出。

  7. 在回调运行后清理,使用incumbent settings

  8. 返回result

8.1.6.6.2 HostEnqueueFinalizationRegistryCleanupJob(finalizationRegistry)

JavaScript 具有将对象注册到FinalizationRegistry对象的能力,以便在对象被垃圾回收时安排清理操作。JavaScript 规范包含一个实现定义HostEnqueueFinalizationRegistryCleanupJob(finalizationRegistry)抽象操作,用于安排清理操作。

清理工作的时机和发生频率在 JavaScript 规范中是实现定义的。不同用户代理可能在垃圾回收的时机和是否发生上存在差异,这会影响WeakRef.prototype.deref()方法的返回值是否为undefined,以及FinalizationRegistry清理回调是否发生。在某些流行的网络浏览器中,存在已知情况:对象虽然对 JavaScript 不可访问,但仍然会被垃圾回收器无限期保留。HTML 在执行微任务检查点算法中清理保活的WeakRef对象。作者最好不要依赖垃圾回收实现的时间细节。

清理操作不会与同步 JavaScript 执行交错发生,而是会在排队的任务中进行。用户代理必须使用以下实现:[JAVASCRIPT]

  1. global成为finalizationRegistry.[[Realm]]的全局对象

  2. JavaScript 引擎任务源上排队一个全局任务,给定global以执行以下步骤:

    1. entry成为finalizationRegistry.[[CleanupCallback]].[[Callback]].[[Realm]]的环境设置对象

    2. 检查我们是否可以运行脚本,使用entry。如果返回“不可运行”,则返回。

    3. 准备运行脚本,使用entry

      这会在清理回调运行时影响entry概念。

    4. result成为执行CleanupFinalizationRegistry(finalizationRegistry)的结果。

    5. 在脚本运行后清理,使用entry

    6. 如果 result异常完成,则报告一个异常,由 result.[[Value]] 为 global 提供。

8.1.6.6.3 HostEnqueueGenericJob(job, realm)

JavaScript 包含一个实现定义HostEnqueueGenericJob(job, realm)抽象操作,用于在特定领域执行通用作业(例如,解析因Atomics.waitAsync而生成的承诺)。用户代理必须使用以下实现:[JAVASCRIPT]

  1. global成为realm全局对象

  2. JavaScript 引擎任务源上排队一个全局任务,给定global以执行job()。

8.1.6.6.4 HostEnqueuePromiseJob(job, realm)

JavaScript 包含一个实现定义HostEnqueuePromiseJob(job, realm)抽象操作,用于调度与 Promise 相关的操作。HTML 将这些操作安排在微任务队列中。用户代理必须使用以下实现:[JAVASCRIPT]

  1. 如果realm不为null,则让job settings成为realm设置对象。否则,让job settings为null。

    如果realm不为null,则它是将运行的作者代码的领域。当jobNewPromiseReactionJob返回时,它是承诺的处理程序函数的领域。当jobNewPromiseResolveThenableJob返回时,它是then函数的领域。

    如果realm为null,则不会运行作者代码,或者作者代码保证抛出错误。对于前者,作者可能没有传递代码以运行,例如在promise.then(null, null)中。对于后者,这是因为传递了被吊销的代理。在这两种情况下,所有步骤中使用job settings的步骤都将被跳过。

    NewPromiseResolveThenableJobNewPromiseReactionJob 在代理被撤销的情况下似乎都提供了非 null 的领域(当前领域记录)。可以更新之前的文本以反映这一点。

  2. 排队一个微任务以执行以下步骤:

    1. 如果job settings不为null,则检查我们是否可以运行脚本,使用job settings。如果返回“不可运行”,则返回。

    2. 如果job settings不为null,则准备运行脚本,使用job settings

      这会在任务运行时影响entry概念。

    3. result成为job()的结果。

      job是由NewPromiseReactionJobNewPromiseResolveThenableJob返回的抽象闭包。当jobNewPromiseReactionJob返回时,承诺的处理程序函数和当jobNewPromiseResolveThenableJob返回时,then函数被包装在JobCallback 记录中。HTML 保存现任设置对象和一个JavaScript 执行上下文,用于活动脚本,在HostMakeJobCallback中恢复这些对象,在HostCallJobCallback中再次调用。

    4. 如果job settings不为null,则在脚本运行后清理,使用job settings

    5. 如果 result异常完成,则 报告一个异常,由 result.[[Value]] 为 realm全局对象提供。

      存在一个非常棘手的情况,即 HostEnqueuePromiseJob 在被调用时使用了一个 null 领域(例如,因为 Promise.prototype.then 被使用 null 处理程序调用),但作业也可能异常结束(因为 promise 能力的 resolve 或 reject 处理程序抛出异常,可能是因为这是 Promise 的一个子类,它接收提供的函数并将它们包装在抛出异常的函数中,然后再传递给传递给 Promise 超类构造函数的函数。那么应该使用哪个全局对象,考虑到当前的领域在这些步骤中的每一步可能都不同,通过使用来自另一个领域的 Promise 构造函数或 Promise.prototype.then?请参见issue #10526

8.1.6.6.5 HostEnqueueTimeoutJob(job, realm, milliseconds)

JavaScript 包含一个实现定义HostEnqueueTimeoutJob(job, milliseconds)抽象操作,用于调度一个在超时后执行的操作。HTML 使用超时后运行步骤调度这些操作。用户代理必须使用以下实现:[JAVASCRIPT]

  1. global成为realm全局对象

  2. timeoutStep成为一个算法步骤,该步骤JavaScript 引擎任务源上排队一个全局任务,给定global以执行job()。

  3. 运行超时后的步骤,给定global、“JavaScript”、millisecondstimeoutStep

8.1.6.6.6 HostMakeJobCallback(callable)

JavaScript 包含一个实现定义HostMakeJobCallback(callable)抽象操作,允许宿主在任务内部调用 JavaScript 回调时附加状态。用户代理必须使用以下实现:[JAVASCRIPT]

  1. incumbent settings成为现任设置对象

  2. active script成为活动脚本

  3. script execution context为null。

  4. 如果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()是一个内置函数,不起源于任何特定的脚本

    通过此步骤,活动脚本从上述代码传递到作业中,允许import()适当地使用原始脚本的基本 URL

    如果用户点击以下按钮,active script可以为null:

    <button onclick="Promise.resolve('import(`./example.mjs`)').then(eval)">Click me</button>

    在这种情况下,事件处理程序的 JavaScript 函数将由获取事件处理程序的当前值算法创建,该算法创建一个[[ScriptOrModule]]值为 null 的函数。因此,当承诺机制调用HostMakeJobCallback时,将没有活动脚本可传递。

    因此,当评估import()表达式时,仍然没有活动脚本。幸运的是,我们在HostLoadImportedModule中的实现通过使用当前设置对象API 基本 URL来处理这种情况。

  5. 返回JobCallback 记录 { [[Callback]]: callable, [[HostDefined]]: { [[IncumbentSettings]]: incumbent settings, [[ActiveScriptContext]]: script execution context } }。

8.1.6.7 与 JavaScript 模块系统相关的宿主钩子

JavaScript 规范定义了模块的语法,以及部分与宿主无关的处理模型。本规范定义了其余的处理模型:如何通过设置了script元素的type属性为"module"来引导模块系统,以及如何获取、解析和执行模块。[JAVASCRIPT]

尽管 JavaScript 规范中使用了“脚本”和“模块”的术语,但本规范通常使用经典脚本模块脚本,因为它们都使用了script元素。

modulePromise = import(specifier)

返回specifier标识的模块脚本的模块命名空间对象的 promise。这允许在运行时动态导入模块脚本,而不是静态使用import语句形式。specifier 将相对于活动脚本进行解析

如果给定的 specifier 无效,或者在获取或评估生成的模块图时遇到失败,返回的 promise 将被拒绝。

此语法可在经典脚本模块脚本中使用。因此,它为经典脚本世界提供了进入模块脚本世界的桥梁。

url = import.meta.url

返回活动模块脚本基础 URL

此语法只能在模块脚本中使用。

url = import.meta.resolve(specifier)

返回相对于活动脚本解析后的specifier。也就是说,这返回的是使用import(specifier)导入的 URL。

如果给定的 specifier 无效,将抛出TypeError异常。

此语法只能在模块脚本中使用。

模块映射是一个有序映射,以包含URL 记录字符串元组为键。URL 记录是模块获取时的请求 URL,字符串表示模块的类型(例如"javascript")。模块映射的值可以是模块脚本、null(用于表示获取失败),或占位符值"fetching"。模块映射用于确保在每个Documentworker中,导入的模块脚本仅被获取、解析和执行一次。

由于模块映射的键是由(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";

因此,在第二个例子中,只会发生一次获取和一次模块评估。

请注意,这种行为与共享worker通过其解析后的构造函数 URL作为键的方式相同。

由于模块类型也是模块映射键的一部分,因此以下代码将在模块映射中创建两个不同的条目(第一个的类型为"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>
8.1.6.7.1 HostGetImportMetaProperties(moduleRecord)

Reference/Operators/import.meta/resolve

Support in all current engines.

Firefox106+Safari16.4+Chrome105+
Opera?Edge105+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Reference/Operators/import.meta

Support in all current engines.

Firefox62+Safari11.1+Chrome64+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS12+Chrome Android?WebView Android?Samsung Internet?Opera Android?

JavaScript 包含一个实现定义的HostGetImportMetaProperties抽象操作。用户代理必须使用以下实现:[JAVASCRIPT]

  1. moduleScriptmoduleRecord.[[HostDefined]]。

  2. 断言moduleScript基础 URL不为 null,因为moduleScriptJavaScript 模块脚本

  3. urlStringmoduleScript基础 URL序列化后的结果。

  4. steps为以下步骤,给定参数specifier

    1. specifier设置为 ? ToString(specifier)。

    2. url为给定moduleScriptspecifier解析模块标识符的结果。

    3. 返回url序列化结果。

  5. resolveFunction为 ! CreateBuiltinFunction(steps, 1, "resolve", « »)。

  6. 返回« Record { [[Key]]: "url", [[Value]]: urlString }, Record { [[Key]]: "resolve", [[Value]]: resolveFunction } »。

8.1.6.7.2 HostGetSupportedImportAttributes()

Import Attributes提案包含一个实现定义的HostGetSupportedImportAttributes抽象操作。用户代理必须使用以下实现:[JSIMPORTATTRIBUTES]

  1. 返回« "type" »。

8.1.6.7.3 HostLoadImportedModule(referrer, moduleRequest, loadState, payload)

JavaScript 包含一个 实现定义HostLoadImportedModule 抽象操作。用户代理必须使用以下实现: [JAVASCRIPT]

  1. settingsObject当前设置对象

  2. 如果 settingsObject全局对象 实现了 WorkletGlobalScopeServiceWorkerGlobalScope 并且 loadState 是未定义的,那么:

    loadState 未定义时,当前的获取过程是由动态 import() 调用发起的,直接或加载动态导入模块的传递依赖时。

    1. completion完成记录 { [[Type]]: throw, [[Value]]: 一个新的 TypeError, [[Target]]: 空 }。

    2. 执行 FinishLoadingImportedModule(referrer, moduleRequest, payload, completion)。

    3. 返回。

  3. referencingScript 为 null。

  4. originalFetchOptions默认脚本获取选项

  5. fetchReferrer 为 "client"。

  6. 如果 referrer脚本记录循环模块记录,则:

    1. referencingScript 设置为 referrer.[[HostDefined]]。

    2. settingsObject 设置为 referencingScript设置对象

    3. fetchReferrer 设置为 referencingScript基本 URL

    4. originalFetchOptions 设置为 referencingScript获取选项

    referrer 通常是 脚本记录循环模块记录,但事件处理程序的情况除外,依据 获取事件处理程序当前值 算法。例如,给出:

    <button onclick="import('./foo.mjs')">点击我</button>

    如果发生 点击 事件,那么当 import() 表达式运行时,GetActiveScriptOrModule 将返回 null, 此操作将使用 当前领域 作为备用 referrer

  7. 如果 referrer 是一个 循环模块记录 并且 moduleRequest 等于 referrer.[[RequestedModules]] 的第一个元素,那么:

    1. 对于每个 模块请求记录 requestedreferrer.[[RequestedModules]] 中:

      1. 如果 moduleRequest.[[Attributes]] 包含一个 记录 entry 其中 entry.[[Key]] 不是 "type",那么:

        1. completion完成记录 { [[Type]]: throw, [[Value]]: 一个新的 语法错误 异常, [[Target]]: 空 }。

        2. 执行 完成加载导入模块(referrer, moduleRequest, payload, completion)。

        3. 返回。

        JavaScript 规范会重新执行此验证,但在此重复它以避免在验证失败时不必要地加载任何依赖项。

      2. 解析模块说明符,给定 referencingScriptmoduleRequest.[[Specifier]],捕获任何异常。如果它们抛出异常,则令 resolutionError 为抛出的异常。

      3. 如果前一步抛出了异常,那么:

        1. completion完成记录 { [[Type]]: throw, [[Value]]: resolutionError, [[Target]]: 空 }。

        2. 执行 完成加载导入模块(referrer, moduleRequest, payload, completion)。

        3. 返回。

      4. moduleType 为执行 模块请求的模块类型 步骤后的结果,给定 moduleRequest

      5. 如果执行 模块类型允许 步骤的结果为 false,给定 moduleTypesettingsObject,那么:

        1. completion完成记录 { [[Type]]: throw, [[Value]]: 一个新的 类型错误 异常, [[Target]]: 空 }。

        2. 执行 完成加载导入模块(referrer, moduleRequest, payload, completion)。

        3. 返回。

      此步骤实际上是在第一次调用 HostLoadImportedModule 以处理静态模块依赖列表时验证所有请求的模块说明符和类型属性,以避免任何依赖项具有静态错误时的进一步加载操作。我们将无法解析模块说明符或不支持类型属性的模块视为与无法解析的模块相同;在这两种情况下,语法问题都使得以后无法考虑链接模块。

  8. 禁止进一步导入映射,给定 settingsObject

  9. url解析模块说明符 的结果,给定 referencingScriptmoduleRequest.[[Specifier]],捕获任何异常。如果抛出异常,令 resolutionError 为抛出的异常。

  10. 如果前一步抛出了异常,那么:

    1. completion完成记录 { [[Type]]: throw, [[Value]]: resolutionError, [[Target]]: 空 }。

    2. 执行 完成加载导入模块(referrer, moduleRequest, payload, completion)。

    3. 返回。

  11. fetchOptions获取子脚本的获取选项 的结果,给定 originalFetchOptions, url, 和 settingsObject

  12. destination"script"

  13. fetchClientsettingsObject

  14. 如果 loadState 不是未定义的,那么:

    1. destination 设置为 loadState.[[Destination]]。

    2. fetchClient 设置为 loadState.[[FetchClient]]。

  15. 获取单个导入的模块脚本,给定 urlfetchClient, destination, fetchOptionssettingsObject, fetchReferrer, moduleRequest,以及 onSingleFetchComplete,如下所述。如果 loadState 不是未定义的且 loadState.[[PerformFetch]] 不是 null,则传递 loadState.[[PerformFetch]] 。

    onSingleFetchComplete 给定 moduleScript 的算法如下:

    1. completion 为 null。

    2. 如果 moduleScript 是 null,则将 completion 设置为 完成记录 { [[Type]]: throw, [[Value]]: 一个新的 TypeError, [[Target]]: 空 }。

    3. 否则,如果 moduleScript解析错误 不是 null,那么:

      1. parseErrormoduleScript解析错误

      2. completion 设置为 完成记录 { [[Type]]: throw, [[Value]]: parseError, [[Target]]: 空 }。

      3. 如果 loadState 不是未定义的且 loadState.[[ParseError]] 是 null,将 loadState.[[ParseError]] 设置为 parseError

    4. 否则,将 completion 设置为 完成记录 { [[Type]]: normal,[[Value]]: moduleScript记录,[[Target]]: 空 }。

    5. 执行 完成加载导入模块(referrer, moduleRequest, payload, completion)。

8.1.7 事件循环

8.1.7.1 定义

为了协调事件、用户交互、脚本、渲染、网络等,用户代理必须使用本节描述的事件循环。每个代理都有一个关联的事件循环,该循环对于该代理是唯一的。

相同来源窗口代理事件循环称为窗口事件循环专用worker代理共享worker代理服务worker代理事件循环称为worker事件循环Worklet 代理事件循环称为Worklet 事件循环

事件循环不一定对应于实现线程。例如,多个窗口事件循环可以在单个线程中协作调度。

但是,对于分配了 [[CanBlock]] 设置为 true 的各种worker代理,JavaScript 规范确实对其前进进度提出了要求,实际上在这些情况下需要专用的每代理线程。


事件循环有一个或多个任务队列任务队列是一个集合,由任务组成。

任务队列集合,而不是队列,因为事件循环处理模型从所选队列中获取第一个可运行的任务,而不是出队第一个任务。

微任务队列不是任务队列

任务封装了负责以下工作的算法:

事件

在特定Event对象上分发EventTarget对象通常由专门的任务完成。

并非所有事件都使用任务队列分发;许多事件在其他任务期间分发。

解析

HTML 解析器标记一个或多个字节,然后处理任何生成的标记,通常是一个任务。

回调

调用回调通常由专门的任务完成。

使用资源

当算法获取资源时,如果获取以非阻塞方式进行,则资源的一部分或全部可用后对资源的处理由任务执行。

响应 DOM 操作

某些元素具有响应 DOM 操作的任务,例如当该元素被插入到文档中时。

正式来说,任务是一个结构体,它具有以下属性:

步骤
指定任务要执行的一系列步骤。
来源
来自任务来源之一,用于分组和序列化相关任务。
文档
与任务关联的文档,对于不在窗口事件循环中的任务则为 null。
脚本评估环境设置对象集
用于在任务期间跟踪脚本评估的集合

如果任务文档为 null 或完全活跃,则该任务是可运行的

根据其来源字段,每个任务定义为来自特定的任务来源。对于每个事件循环,每个任务来源必须与特定的任务队列关联。

本质上,任务来源在标准中用于区分逻辑上不同类型的任务,用户代理可能希望在这些任务之间进行区分。任务队列由用户代理用于在给定的事件循环内合并任务来源。

例如,用户代理可以有一个任务队列用于鼠标和键盘事件(与用户交互任务来源关联),另一个队列用于所有其他任务来源。然后,使用事件循环处理模型的初始步骤中赋予的自由,它可以在四分之三的时间内优先处理键盘和鼠标事件,从而保持界面响应,但不会饿死其他任务队列。请注意,在这种设置中,处理模型仍然强制用户代理永远不会按顺序处理来自任何一个任务来源的事件。


每个事件循环都有一个当前运行的任务,它可以是任务或 null。最初,这个值为 null。它用于处理重入性。

每个事件循环都有一个微任务队列,这是一个队列,存放微任务,最初为空。微任务是指通过排队微任务算法创建的任务

每个事件循环都有一个执行微任务检查点布尔值,最初为 false。它用于防止重新进入执行微任务检查点算法。

每个窗口事件循环都有一个DOMHighResTimeStamp最后渲染机会时间,初始值为零。

每个窗口事件循环都有一个DOMHighResTimeStamp最后空闲期开始时间,初始值为零。

要获取窗口事件循环 loop同循环窗口,返回所有Window对象,其相关代理事件循环loop

8.1.7.2 排队任务

要在任务来源 source排队一个任务,执行一系列步骤steps,可选地给定一个事件循环event loop和一个文档document

  1. 如果未给定event loop,则将event loop设置为隐含事件循环

  2. 如果未给定document,则将document设置为隐含文档

  3. task为一个新的任务

  4. task步骤设置为steps

  5. task来源设置为source

  6. task文档设置为document

  7. task脚本评估环境设置对象集设置为空集合

  8. queueevent loop上与source关联的任务队列

  9. task附加到queue

未能将事件循环和文档传递给排队任务意味着依赖模棱两可且定义不清的隐含事件循环隐含文档概念。规范作者应始终传递这些值,或者使用包装算法排队全局任务排队元素任务代替。建议使用包装算法。

要在任务来源source排队全局任务,使用全局对象global和一系列步骤steps

  1. event loopglobal相关代理事件循环

  2. documentglobal关联的Document,如果globalWindow对象;否则为 null。

  3. 根据sourceevent loopdocumentsteps排队任务

要在任务来源source排队元素任务,使用元素element和一系列步骤steps

  1. globalelement相关全局对象

  2. 根据sourceglobalsteps排队全局任务

排队一个微任务,执行一系列步骤steps,可选地给定一个文档document

  1. 断言:存在一个包围代理。即,此算法不会在并行期间调用。

  2. eventLoop周围代理事件循环

  3. 如果未给定document,则将document设置为隐含文档

  4. microtask为一个新的任务

  5. microtask步骤设置为steps

  6. microtask来源设置为微任务来源

  7. microtask文档设置为document

  8. microtask脚本评估环境设置对象集设置为空集合

  9. microtask排入eventLoop微任务队列

如果在其初始执行期间旋转事件循环,则微任务可能会被移到常规任务队列中。这是唯一会咨询微任务的来源文档脚本评估环境设置对象集的情况;它们在执行微任务检查点算法中被忽略。

排队任务时的隐含事件循环是从调用算法的上下文中推导出的。通常这很明确,因为大多数规范算法只涉及单个代理(因此只有一个事件循环)。例外是涉及或指定跨代理通信的算法(例如,窗口和worker之间);对于这些情况,不得依赖于隐含事件循环概念,规范必须在排队任务时明确提供事件循环

事件循环event loop上排队任务时的隐含文档确定如下:

  1. 如果event loop不是窗口事件循环,则返回 null。

  2. 如果任务在元素的上下文中排队,则返回元素的节点文档

  3. 如果任务在浏览上下文中排队,则返回浏览上下文的活动文档

  4. 如果任务由或为脚本排队,则返回脚本的设置对象全局对象关联的Document

  5. 断言:此步骤永远不会达到,因为前面的条件之一为真。真的吗?

隐含事件循环隐含文档都定义得模糊,并且具有很大的远程操作性。希望能够删除这些,尤其是隐含文档。详见问题 #4980

8.1.7.3 处理模型

一个事件循环 必须在存在期间持续运行以下步骤:

  1. oldestTasktaskStartTime 为 null。

  2. 如果 事件循环 有一个包含至少一个 可运行任务任务队列,那么:

    1. taskQueue 成为以 实现定义的 方式选择的此类任务队列之一。

      请记住,微任务队列不是任务队列,所以它不会在此步骤中被选择。然而,一个任务队列微任务源相关联的可能会在此步骤中被选择。在这种情况下,在下一步中选择的任务最初是一个微任务,但它在旋转事件循环的一部分中被移走了。

    2. taskStartTime 设置为 不安全的共享当前时间

    3. oldestTask 设置为 taskQueue 中的第一个可运行任务,并从 taskQueue移除它。

    4. 如果 oldestTask文档 不是 null,则记录任务开始时间,给定 taskStartTimeoldestTask文档

    5. 事件循环当前运行任务 设置为 oldestTask

    6. 执行 oldestTask步骤

    7. 事件循环当前运行任务 重新设置为 null。

    8. 执行一个微任务检查点

  3. taskEndTime不安全的共享当前时间[HRT]

  4. 如果 oldestTask 不是 null,则:

    1. top-level browsing contexts 为一个空的 集合

    2. 对于 oldestTask 的每个环境设置对象 settings

      1. global 成为 settings全局对象

      2. 如果 global 不是一个 Window 对象,那么 继续

      3. 如果 global浏览上下文 为 null,则 继续

      4. tlbc 成为 global浏览上下文顶级浏览上下文

      5. 如果 tlbc 不是 null,则将其添加top-level browsing contexts 中。

    3. 报告长任务,传递 taskStartTimetaskEndTimetop-level browsing contexts,和 oldestTask

    4. 如果 oldestTask文档 不是 null,那么记录任务结束时间,给定 taskEndTimeoldestTask文档

  5. 如果这是一个 窗口事件循环,且该 事件循环任务队列 中没有 可运行任务,则:

    1. 将此 事件循环最后空闲期开始时间设置为 不安全的共享当前时间

    2. computeDeadline 成为以下步骤:

      1. deadline 成为此 事件循环最后空闲期开始时间加上50。

        未来50ms的上限是为了确保在人的感知阈值内响应新的用户输入。

      2. hasPendingRenders 为 false。

      3. 对于此相同循环窗口的每个 windowInSameLoop

        1. 如果 windowInSameLoop动画帧回调映射不是空的,或者用户代理认为 windowInSameLoop 可能有待处理的渲染更新,则将 hasPendingRenders 设置为 true。

        2. timerCallbackEstimates 成为获取值的结果,来自 windowInSameLoop活动定时器映射

        3. 对于 timerCallbackEstimates 的每个 timeoutDeadline,如果 timeoutDeadline 小于 deadline,则将 deadline 设置为 timeoutDeadline

      4. 如果 hasPendingRenders 为 true,则:

        1. nextRenderDeadline 成为此 事件循环最后渲染机会时间加上(1000 除以当前刷新率)。

          刷新率可以是硬件或实现特定的。对于60Hz的刷新率,nextRenderDeadline 将大约在 最后渲染机会时间 之后 16.67ms。

        2. 如果 nextRenderDeadline 小于 deadline,则返回 nextRenderDeadline

      5. 返回 deadline

    3. 对于此相同循环窗口的每个 win,对 win 执行 开始一个空闲期算法, 并返回调用 computeDeadline 的结果,时间粗化,给定 win相关设置对象跨源隔离能力[REQUESTIDLECALLBACK]

  6. 如果这是一个 worker事件循环,则:

    1. 如果此 事件循环代理的单个 领域全局对象 是一个 支持的 DedicatedWorkerGlobalScope 对象,且用户代理认为此时更新其渲染是有益的,那么:

      1. now 成为当前高分辨率时间,给定 DedicatedWorkerGlobalScope[HRT]

      2. 运行动画帧回调,为此 DedicatedWorkerGlobalScope, 传递 now 作为时间戳。

      3. 更新该专用worker的渲染以反映当前状态。

      类似于 更新渲染窗口事件循环中的注释,用户代理可以确定专用worker中的渲染频率。

    2. 如果此 事件循环任务队列中没有 任务,并且 WorkerGlobalScope 对象的关闭标志为 true,则销毁 事件循环,中止这些步骤,并恢复运行worker的步骤,如下面的Web worker部分中所述。

一个 窗口事件循环 eventLoop 也必须 运行以下步骤,并行,只要它存在:

  1. 等待至少有一个 可导航对象,其 活动文档相关代理事件循环eventLoop,并且可能有一个 渲染机会

  2. eventLoop最后渲染机会时间 设置为 不安全的共享当前时间

  3. 对于每个有 渲染机会navigable,在 渲染任务源排队全局任务,给定 navigable活动窗口更新渲染

    这可能会导致冗余调用更新渲染。然而,这些调用将没有可观察到的效果,因为根据不必要的渲染步骤,不会有必要的渲染。实现可以引入进一步的优化,例如仅在任务尚未排队时才排队此任务。但是,请注意,与任务相关的文档可能在任务处理之前变得不活跃。

    1. frameTimestamp 成为 eventLoop最后渲染机会时间

    2. docs 成为所有 完全活跃的 Document 对象,相关代理事件循环eventLoop,按任意顺序排序,但必须满足以下条件:

      在下面的步骤中,遍历 docs 时,每个 Document 必须按列表中的顺序进行处理。

    3. 过滤不可渲染的文档:从 docs 中移除任何 Document 对象 doc,如果满足以下任何条件:

      我们必须在这里检查渲染机会,除了在并行步骤中检查渲染机会,因为某些共享相同事件循环的文档可能不会在同一时间拥有 渲染机会

    4. 不必要的渲染:从 docs 中移除任何 Document 对象 doc,如果以下所有条件都为真:

    5. docs 中移除所有用户代理认为出于其他原因最好跳过更新渲染的 Document 对象。

      标记为过滤不可渲染的文档的步骤防止用户代理在无法向用户展示新内容时更新渲染。

      标记为不必要的渲染的步骤防止用户代理在没有新内容绘制时更新渲染。

      此步骤允许用户代理防止以下步骤因其他原因运行,例如确保某些任务在彼此之后立即执行,只插入微任务检查点 (而不插入,例如动画帧回调)。具体来说,用户代理可能希望将定时器回调合并在一起,而没有中间渲染更新。

    6. 对于 docs 中的每个 doc揭示 doc

    7. 对于 docs 中的每个 doc,如果其 节点导航顶级可遍历对象,则刷新自动聚焦候选项

    8. 对于 docs 中的每个 doc运行调整大小步骤

    9. 对于 docs 中的每个 doc运行滚动步骤

    10. 对于 docs 中的每个 doc评估媒体查询并报告更改

    11. 对于 docs 中的每个 doc更新动画并发送事件,传递 相对高分辨率时间 给定 frameTimestampdoc相关全局对象 作为时间戳。

    12. 对于 docs 中的每个 doc运行全屏步骤

    13. 对于 docs 中的每个 doc,如果用户代理检测到与 CanvasRenderingContext2DOffscreenCanvasRenderingContext2D 关联的备份存储丢失,则必须为每个 context 运行 上下文丢失步骤

      1. canvas 成为 contextcanvas 属性的值,如果 contextCanvasRenderingContext2D, 或者是 关联的 OffscreenCanvas 对象,如果 context 不是。

      2. context上下文丢失设置为 true。

      3. 将渲染上下文重置为默认状态给定 context

      4. shouldRestore 成为 触发一个名为 contextlost 的事件的结果,在 canvas 上,cancelable 属性初始化为 true。

      5. 如果 shouldRestore 为 false,则中止这些步骤。

      6. 尝试通过使用 context 的属性创建一个备份存储并将其与 context 关联来恢复 context。如果失败,则中止这些步骤。

      7. context上下文丢失设置为 false。

      8. 触发一个事件,名为 contextrestored,在 canvas 上。

    14. 对于 docs 中的每个 doc运行动画帧回调,传递相对高分辨率时间,给定 frameTimestampdoc相关全局对象 作为时间戳。

    15. unsafeStyleAndLayoutStartTime不安全的共享当前时间

    16. 对于 docs 中的每个 doc

      1. resizeObserverDepth 为 0。

      2. 当条件成立时:

        1. 重新计算样式并更新 doc 的布局。

        2. hadInitialVisibleContentVisibilityDetermination 为 false。

        3. 对于每个具有 ‘auto’ 使用值的元素 ‘content-visibility’

          1. 如果 element与视口的接近度尚未确定且未与用户相关,则设置 checkForInitialDetermination 为 true。否则,设置 checkForInitialDetermination 为 false。

          2. 确定 与视口的接近度 对于 element

          3. 如果 checkForInitialDetermination 为 true 且 element 现在 与用户相关,则将 hadInitialVisibleContentVisibilityDetermination 设置为 true。

        4. 如果 hadInitialVisibleContentVisibilityDetermination 为 true,则继续

          此步骤的意图是使初始视口接近度确定(立即生效)在此循环的先前步骤中进行的样式和布局计算中反映出来。除首次外的接近度确定将在下一个渲染机会时生效。[CSSCONTAIN]

        5. 在深度 resizeObserverDepth 收集活动调整大小观察

        6. 如果 doc 有活动调整大小观察

          1. 设置 resizeObserverDepth广播活动调整大小观察给定 doc 的结果。

          2. 继续
        7. 否则,中断
      3. 如果 doc 有跳过的调整大小观察,则 传递调整大小循环错误给定 doc

    17. 对于 docs 中的每个 doc,如果 doc聚焦区域 不是 可聚焦区域,则 为 doc视口运行 聚焦步骤,并设置 doc相关全局对象导航API正在进行的导航期间聚焦已更改 为 false。

      例如,这可能发生是因为某个元素添加了 hidden 属性,导致它停止 被渲染。它也可能发生在 输入 元素上,当该元素被禁用时。

      这将 通常触发 模糊 事件,并可能触发 更改 事件。

      除了此异步修复外,如果文档的聚焦区域被移除,还存在同步修复。这一个不会触发 模糊更改 事件。

    18. 对于 docs 中的每个 doc执行待定的过渡操作

    19. 对于 docs 中的每个 doc运行更新交叉观察步骤,传递 相对高分辨率时间 给定 nowdoc相关全局对象 作为时间戳。

    20. 对于 docs 中的每个 doc记录渲染时间,给定 unsafeStyleAndLayoutStartTime

    21. 对于 docs 中的每个 doc标记绘制时间

    22. 对于 docs 中的每个 doc,更新 doc 及其节点导航 的渲染或用户界面以反映当前状态。

    23. 对于 docs 中的每个 doc处理顶层移除给定 doc

一个 可导航对象 有一个渲染机会,如果用户代理当前能够将 可导航对象 的内容展示给用户,考虑到硬件刷新率限制和用户代理为了性能原因进行的节流,但即使内容不在视口内,也会认为内容是可展示的。

一个 可导航对象渲染机会 是基于硬件限制(如显示刷新率)和其他因素(如页面性能或其 活动文档可见性状态 为 "visible")确定的。渲染机会通常以固定的间隔发生。

本规范不强制要求采用任何特定的模型来选择渲染机会。但例如,如果浏览器试图达到 60Hz 的刷新率,那么渲染机会最多会在每秒 60 次(约 16.7 毫秒)的时间间隔内发生。如果浏览器发现某个 可导航对象 无法维持此速率,它可能会降至该可导航对象每秒 30 次渲染机会,而不是偶尔丢帧。同样,如果某个 可导航对象 不可见,则用户代理可能会决定将该页面降至每秒 4 次甚至更少的渲染机会。


当用户代理要执行微任务检查点时:

  1. 如果 事件循环正在执行微任务检查点 为真,则返回。

  2. 事件循环正在执行微任务检查点 设置为 true。

  3. 事件循环微任务队列为空时:

    1. oldestMicrotask 成为出队的结果,从事件循环微任务队列

    2. 事件循环当前正在运行的任务 设置为 oldestMicrotask

    3. 运行 oldestMicrotask

      这可能涉及调用脚本回调,最终调用在运行脚本后清理 步骤,再次调用此执行微任务检查点算法,这就是为什么我们使用 正在执行微任务检查点 标志来避免重入。

    4. 事件循环当前正在运行的任务 设置为 null。

  4. 对于每个环境设置对象 settingsObject,其负责的事件循环 是此事件循环通知拒绝的 promises,给定 settingsObject全局对象

  5. 清理索引数据库事务

  6. 执行 清除保持的对象

    WeakRef.prototype.deref() 返回一个对象时,该对象保持存活,直到下次调用 清除保持的对象(),之后它再次受到垃圾回收的影响。

  7. 事件循环正在执行微任务检查点 设置为 false。

  8. 记录微任务检查点的计时信息


当运行并行的算法要等待稳定状态时, 用户代理必须排队一个微任务,运行以下步骤,并且必须停止执行(当微任务运行时恢复算法的执行,如下步骤所述):

  1. 运行算法的 同步部分

  2. 如算法步骤中所述,在适当情况下并行恢复算法的执行。

标记在同步部分中的步骤以 ⌛ 标记。


要求旋转事件循环直到达到条件goal 的算法步骤 等价于替换为以下算法步骤:

  1. task 成为 事件循环当前正在运行的任务

    task 可能是 微任务

  2. task source 成为 task

  3. old stack 成为 JavaScript 执行上下文栈 的副本。

  4. 清空 JavaScript 执行上下文栈

  5. 执行微任务检查点

    如果 task微任务,此步骤将是无操作,因为 正在执行微任务检查点 为 true。

  6. 并行

    1. 等待直到条件 goal 满足。

    2. 排队一个任务task source上:

      1. old stack 替换 JavaScript 执行上下文栈

      2. 执行出现在这个 旋转事件循环实例中的原始算法中的任何步骤。

        这会恢复 task

  7. 停止 task,允许调用它的算法恢复。

    这会导致 事件循环的主要步骤集或执行微任务检查点算法继续。

与本规范和其他规范中的其他算法不同,它们的行为类似于编程语言的函数调用,旋转事件循环 更像是一个宏,通过扩展成一系列步骤和操作来节省打字和缩进。

一个算法,其步骤是:

  1. 做某事。

  2. 旋转事件循环直到发生了不起的事情。

  3. 做别的事。

是一个简写,经过“宏扩展”后,变成:

  1. 做某事。

  2. old stack 成为 JavaScript 执行上下文栈 的副本。

  3. 清空 JavaScript 执行上下文栈

  4. 执行微任务检查点

  5. 并行

    1. 等待直到发生了不起的事情。

    2. 排队一个任务 在执行“做某事”的任务源上:

      1. old stack 替换 JavaScript 执行上下文栈

      2. 做别的事。

这是一个更完整的替换示例,其中事件循环是从并行工作中排队的任务内部旋转的。使用 旋转事件循环 的版本:

  1. 并行

    1. 做并行的事 1。

    2. 排队一个任务DOM 操作任务源 上:

      1. 做任务的事 1。

      2. 旋转事件循环直到发生了不起的事情。

      3. 做任务的事 2。

    3. 做并行的事 2。

完整扩展版本:

  1. 并行

    1. 做并行的事 1。

    2. old stack 为 null。

    3. 排队一个任务DOM 操作任务源 上:

      1. 做任务的事 1。

      2. 设置 old stackJavaScript 执行上下文栈 的副本。

      3. 清空 JavaScript 执行上下文栈

      4. 执行微任务检查点

    4. 等待直到发生了不起的事情。

    5. 排队一个任务DOM 操作任务源 上:

      1. old stack 替换 JavaScript 执行上下文栈

      2. 做任务的事 2。

    6. 做并行的事 2。


本规范中的某些算法,由于历史原因,要求用户代理在运行 任务暂停,直到条件 goal 满足。这意味着要运行以下步骤:

  1. global 成为 当前全局对象

  2. timeBeforePause 成为 当前高分辨率时间给定 global

  3. 如有必要,更新任何 文档可导航对象 的渲染或用户界面以反映当前状态。

  4. 等待直到条件 goal 满足。当用户代理具有暂停的 任务时, 相应的 事件循环不得继续运行其他 任务,并且当前运行的任务 中的任何脚本必须阻塞。然而,用户代理在暂停期间应保持对用户输入的响应能力,尽管由于事件循环不会执行任何操作,因此响应能力会有所降低。

  5. 记录暂停持续时间,给定从 持续时间timeBeforePause当前高分辨率时间 给定 global

暂停对用户体验非常不利,尤其是在多个文档共享一个事件循环的情况下。用户代理被鼓励尝试替代暂停的方案,例如旋转事件循环,甚至只是继续执行而没有任何形式的暂停执行,只要在尽可能保持与现有内容的兼容性的情况下做到这一点。本规范会很乐意进行更改,如果发现一种不那么激烈且与网络兼容的替代方案。

与此同时,实施者应该意识到用户代理可能试验的各种替代方案可能会改变事件循环行为的细微方面,包括任务和微任务的时间安排。实现者应该继续实验,即使这样做会导致它们违反暂停操作所暗示的确切语义。

8.1.7.4 通用任务源

以下任务源由本规范和其他规范中的许多不相关的功能使用。

DOM 操作任务源

任务源用于响应 DOM 操作的功能,例如在元素插入文档中时以非阻塞方式发生的事件。

用户交互任务源

任务源用于响应用户交互的功能,例如键盘或鼠标输入。

响应用户输入发送的事件(例如 click 事件)必须使用任务通过排队用户交互任务源触发。[UIEVENTS]

网络任务源

任务源用于响应网络活动触发的功能。

导航和遍历任务源

任务源用于排队涉及导航历史遍历的任务。

渲染任务源

任务源仅用于更新渲染

8.1.7.5 处理其他规范中的事件循环

编写正确与事件循环交互的规范可能会很棘手。这一问题因本规范使用与并发模型无关的术语而更加复杂,因此我们使用了“事件循环”和“并行”等术语,而不是使用更为熟悉的模型特定术语,如“主线程”或“后台线程”。

默认情况下,规范文本通常在事件循环上运行。这源于事件循环处理模型的形式化描述,因为你最终可以将大多数算法追溯到在那里排队的任务

任何 JavaScript 方法的算法步骤都会被调用者代码调用。而调用者代码只能通过排队任务来运行,这些任务通常起源于script处理模型的某个地方。

从这一起点出发,首要指导原则是,任何规范需要执行的工作,如果会阻塞事件循环,则必须改为与其并行执行。这包括(但不限于):

下一个复杂点是,在并行的算法部分中,你不能创建或操作与特定realm全局对象环境设置对象关联的对象。(用更熟悉的术语来说,你不能直接从后台线程访问主线程工件。)这样做会创建 JavaScript 代码可观察到的数据竞争,因为毕竟,你的算法步骤是与 JavaScript 代码并行运行的。

然而,你可以操作来自Infra的规范级数据结构和值,因为它们与 realm 无关。它们不会直接暴露给 JavaScript,除非进行特定的转换(通常是通过 Web IDL)。[INFRA] [WEBIDL]

因此,要影响 JavaScript 对象的可观察世界,你必须排队一个全局任务来执行任何此类操作。这确保了你的步骤相对于其他事件循环中发生的事情是正确交错的。此外,在排队全局任务时,你必须选择任务源;这决定了你的步骤相对于其他步骤的相对顺序。如果你不确定使用哪个任务源,请选择一个最适用的通用任务源。最后,你必须指明你的排队任务与哪个全局对象关联;这确保了如果该全局对象处于非活动状态,则任务不会运行。

构建排队全局任务的基础原语是排队任务算法。通常,排队全局任务更好,因为它会自动选择正确的事件循环,并在适当的情况下选择文档。较旧的规范通常使用排队任务,结合隐含事件循环隐含文档概念,但不推荐这样做。

将这些组合在一起,我们可以为需要异步执行工作的典型算法提供一个模板:

  1. 事件循环上进行任何同步设置工作。这可能包括将realm特定的 JavaScript 值转换为与 realm 无关的规范级值。

  2. 并行执行一组可能耗时的步骤,完全操作与 realm 无关的值,并生成与 realm 无关的结果。

  3. 排队一个全局任务,在指定的任务源上,并给定适当的全局对象,将 realm 无关的结果转换回在事件循环上可观察的 JavaScript 对象世界中的可观察效果。

以下是一个“加密”传入的列表的算法,该列表由input标量值字符串组成,经过解析后作为 URL:

  1. urls成为一个空的列表

  2. 对于 input的每个string

    1. parsed成为编码解析 URL的结果,给定string,相对于当前设置对象

    2. 如果parsed失败,则返回一个因"SyntaxError" DOMException被拒绝的 promise。

    3. serialized成为将URL 序列化器应用于parsed的结果。

    4. serialized添加到urls

  3. realm成为当前 realm

  4. p成为一个新的 promise。

  5. 并行运行以下步骤:

    1. encryptedURLs成为一个空的列表

    2. 对于 urls中的每个url

      1. 等待 100 毫秒,以便让人们认为我们正在进行重度加密。

      2. encrypted成为从url派生的新字符串,其第n代码单元等于url的第n代码单元加 13。

      3. encrypted添加到encryptedURLs

    3. 网络任务源上排队一个全局任务,给定realm全局对象,以执行以下步骤:

      1. array成为encryptedURLs转换为 JavaScript 数组的结果,转换发生在realm中。

      2. array解析p

  6. 返回p

以下是关于此算法的几个注意事项:

(关于最后两点,还请参阅whatwg/webidl issue #135whatwg/webidl issue #371,我们仍在权衡上述 promise 解析模式的细微之处。)

另一个需要注意的事项是,如果此算法是从 Web IDL 指定的操作调用的,并且该操作接受一个sequence<USVString>, 则会自动从作者提供的特定realm的 JavaScript 对象转换为与 realm 无关的sequence<USVString> Web IDL 类型,然后我们将其视为列表标量值字符串。因此,根据你的规范结构,可能还有其他隐式步骤在主事件循环上执行,在这个过程中,这些步骤在准备并行执行中起到了作用。

8.1.8 事件

8.1.8.1 事件处理程序

Events/Event_handlers

许多对象可以指定事件处理程序。这些处理程序作为指定对象上的非捕获事件监听器[DOM]

事件处理程序是一个结构体,包含两个项目

事件处理程序通过两种方式公开。

第一种方式,适用于所有事件处理程序,是作为事件处理程序IDL属性

第二种方式是作为事件处理程序内容属性HTML元素上的事件处理程序和一些Window对象上的事件处理程序通过这种方式公开。

对于这两种方式,事件处理程序通过一个名称来公开,该名称总是以“on”开头,后跟事件名称。


通常,暴露事件处理程序的对象与添加相应事件监听器的对象是相同的。 然而,bodyframeset 元素暴露了多个事件处理程序,这些事件处理程序作用于元素的 Window 对象(如果存在)。在任一情况下,我们称该对象为事件处理程序作用的事件处理程序目标

确定事件处理程序的目标,给定一个EventTarget 对象 eventTarget(该对象暴露了事件处理程序)和一个事件处理程序名称 name,按照以下步骤操作:

  1. 如果 eventTarget 不是 body 元素或 frameset 元素,则返回 eventTarget

  2. 如果 name 不是 WindowEventHandlers 接口混入的属性成员名称,并且Window-反映 body 元素的事件处理程序集包含 name,则返回 eventTarget

  3. 如果 eventTarget节点文档不是活动文档,则返回 null。

    这可能发生在此对象是没有对应的body 元素的 Window 对象的情况下。

    此检查不一定会阻止不是其节点文档body 元素frameset 元素到达下一步。特别是,在活动文档中创建的 body 元素(可能使用 document.createElement() 创建),但未连接的也会有其对应的 Window对象,作为通过其暴露的多个事件处理程序目标

  4. 返回 eventTarget节点文档相关全局对象


每个指定了一个或多个事件处理程序EventTarget对象都有一个相关的事件处理程序映射,它是表示名称有序映射,这些名称表示事件处理程序的名称。

当一个指定了一个或多个事件处理程序EventTarget对象被创建时,它的事件处理程序映射必须初始化,使其包含该对象作为目标的每个事件处理程序的一个条目,其中这些事件处理程序中的项目设置为它们的初始值。

事件处理程序映射条目的顺序可能是任意的。通过任何操作映射的算法都无法观察到。

对于仅公开在该对象上但有其他对象作为目标的事件处理程序,不会在对象的事件处理程序映射中创建条目。


事件处理程序IDL属性是特定事件处理程序的IDL属性。IDL属性的名称与事件处理程序的名称相同。

具有名称name事件处理程序IDL属性的getter在调用时必须运行以下步骤:

  1. eventTarget成为通过确定事件处理程序的目标得出的给定此对象和name的结果。

  2. 如果eventTarget为null,则返回null。

  3. 返回通过获取事件处理程序的当前值给定eventTargetname的结果。

具有名称name事件处理程序IDL属性的setter在调用时必须运行以下步骤:

  1. eventTarget成为通过确定事件处理程序的目标得出的给定此对象和name的结果。

  2. 如果eventTarget为null,则返回。

  3. 如果给定的值为null,则停用事件处理程序,给定eventTargetname

  4. 否则:

    1. handlerMap成为eventTarget事件处理程序映射

    2. eventHandler成为handlerMap[name]。

    3. eventHandler设置为给定值。

    4. 激活事件处理程序,给定eventTargetname

某些事件处理程序IDL属性有附加要求,特别是onmessage属性的MessagePort对象。


事件处理程序内容属性是特定事件处理程序的内容属性。内容属性的名称与名称相同。

事件处理程序内容属性指定时,必须包含有效的JavaScript代码,该代码在解析时将匹配FunctionBody生成规则,并经过自动分号插入

以下属性更改步骤用于在事件处理程序内容属性事件处理程序之间进行同步:[DOM]

  1. 如果namespace不为null,或者localName不是element上的事件处理程序内容属性的名称,则返回。

  2. eventTarget成为通过确定事件处理程序的目标给定elementlocalName的结果。

  3. 如果eventTarget为null,则返回。

  4. 如果value为null,则停用事件处理程序,给定eventTargetlocalName

  5. 否则:

    1. 如果内容安全策略应阻止元素的内联行为?算法在element、“script attribute”和value上执行时返回“Blocked”,则返回。[CSP]

    2. handlerMap成为eventTarget事件处理程序映射

    3. eventHandler成为handlerMap[localName]。

    4. location成为触发这些步骤执行的脚本位置。

    5. eventHandler设置为内部原始未编译处理程序value/location

    6. 激活事件处理程序,给定eventTargetlocalName

根据DOM标准,即使oldValuevalue相同(将属性设置为其当前值),也会运行这些步骤,但如果oldValuevalue都为null(删除不存在的属性),则不会运行这些步骤。[DOM]


停用事件处理程序,给定EventTarget对象eventTarget和表示事件处理程序名称的字符串name,执行以下步骤:

  1. handlerMap成为eventTarget事件处理程序映射

  2. eventHandler成为handlerMap[name]。

  3. eventHandler设置为null。

  4. listener成为eventHandler监听器

  5. 如果listener不为null,则移除事件监听器,给定eventTargetlistener

  6. eventHandler监听器设置为null。

删除所有事件监听器和处理程序,给定EventTarget对象eventTarget,执行以下步骤:

  1. 如果eventTarget有一个相关的事件处理程序映射,则对于eventTarget的相关事件处理程序映射中的每个nameeventHandler停用事件处理程序,给定eventTargetname

  2. 移除所有事件监听器,给定eventTarget

此算法用于定义document.open()

激活事件处理程序,给定EventTarget对象eventTarget和表示事件处理程序名称的字符串name,执行以下步骤:

  1. handlerMap成为eventTarget事件处理程序映射

  2. eventHandler成为handlerMap[name]。

  3. 如果eventHandler监听器不为null,则返回。

  4. callback成为创建一个Web IDLEventListener实例的结果,该实例表示一个函数的引用,该函数有一个参数,执行事件处理程序处理算法的步骤,给定eventTargetname及其参数。

    EventListener回调上下文可以是任意的;它不影响事件处理程序处理算法的步骤。[DOM]

    回调明确不是事件处理程序本身。每个事件处理程序最终都会注册相同的回调,即下文定义的算法,该算法负责调用正确的代码并处理代码的返回值。

  5. listener成为一个新的事件监听器,其类型是与eventHandler对应的事件处理程序事件类型,回调为callback

    需要明确的是,事件监听器与EventListener不同。

  6. 添加事件监听器,给定eventTargetlistener

  7. eventHandler监听器设置为listener

事件监听器注册仅在事件处理程序的值设置为非null时发生,并且事件处理程序尚未激活。由于监听器是按注册顺序调用的,假设未发生停用,则特定事件类型的事件监听器顺序将始终是:

  1. 在事件处理程序的值首次设置为非null之前,通过addEventListener()注册的事件监听器

  2. 然后是当前设置的回调(如果有的话)

  3. 最后是事件处理程序的值首次设置为非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,按如下步骤进行:

  1. 通过eventTargetname获取当前事件处理程序的值,并将结果赋给callback

  2. 如果callback为null,则返回。

  3. 如果eventErrorEvent对象,eventtype为"error",并且eventcurrentTarget实现了WindowOrWorkerGlobalScope混合接口,则设定special error event handling为true。否则,设定special error event handling为false。

  4. 处理Event对象event,具体步骤如下:

    如果 special error event handling 为 true

    return value 设为调用 callback 的结果,使用 « eventmessageeventfilenameeventlinenoeventcolnoeventerror »、 "rethrow",并将 回调此值 设置为 eventcurrentTarget

    否则

    return value 设为调用 callback 的结果,使用 « event »、"rethrow",并将 回调此值 设置为 eventcurrentTarget

    如果回调函数抛出异常,它将被重新抛出,从而结束这些步骤。异常将传播到DOM 事件分发逻辑,然后报告该异常。

  5. 按如下步骤处理return value

    如果eventBeforeUnloadEvent对象,并且eventtype为"beforeunload"

    在这种情况下,事件处理程序IDL属性的类型将为OnBeforeUnloadEventHandler,因此return value将被强制转换为null或DOMString

    如果return value不是null,则:

    1. 设置eventcanceled标志

    2. 如果eventreturnValue属性的值为空字符串,则将eventreturnValue属性的值设置为return value

    如果special error event handling为true

    如果return value为true,则设置eventcanceled标志

    否则

    如果return value为false,则设置eventcanceled标志

    如果我们进入了这个“否则”子句,因为eventtype为"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处理程序有不同的参数:

[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,必须运行以下步骤:

  1. 获取eventTarget事件处理程序映射,并将结果赋给handlerMap

  2. 通过handlerMap[name]获取eventHandler

  3. 如果eventHandler内部原始未编译处理程序,则:

    1. 如果 eventTarget 是一个元素,那么将 element 设为 eventTarget,并将 document 设为 element节点文档。否则,eventTarget 是一个 Window 对象,将 element 设为 null,并将 document 设为 eventTarget关联的 Document

    2. 如果 禁用了脚本 对于 document,则返回 null。

    3. body 设为 eventHandler中的未编译脚本体。

    4. location 设为脚本体的来源位置,如 由 eventHandler给出。

    5. 如果 element 不为 null 且 element表单所有者, 则将 form owner 设为该 表单所有者。 否则,将 form owner 设为 null。

    6. settings object 设为 document相关设置对象

    7. 如果 body 无法解析为 FunctionBody 或者如果解析时检测到 早期错误,则按照以下子步骤进行:

      1. eventHandler 设为 null。

        这不会停用 事件处理程序,还会移除 事件处理程序的监听器(如果存在)。

      2. syntaxError 成为一个新的 SyntaxError 异常, 与 settings object领域相关联,该异常描述了解析过程中出现的错误。它应该基于脚本主体的来源 location

      3. 报告一个异常,使用 syntaxError 针对 settings object全局对象

      4. 返回 null。

    8. settings object领域执行上下文推入 JavaScript 执行上下文堆栈;它现在是 正在运行的 JavaScript 执行上下文

      这是必要的,因此随后的 OrdinaryFunctionCreate 调用会在正确的 领域中进行。

    9. function 设为调用 OrdinaryFunctionCreate 的结果,传入的参数如下:

      functionPrototype
      %Function.prototype%
      sourceText
      如果 nameonerroreventTarget 是一个 Window 对象
      由以下字符串组成:"function "、name、 "(event, source, lineno, colno, error) {"、U+000A LF、 body、U+000A LF 和 "}"。
      否则
      由以下字符串组成:"function "、name、 "(event) {"、U+000A LF、body、U+000A LF 和 "}"。
      ParameterList
      如果 nameonerroreventTarget 是一个 Window 对象
      让函数有五个参数,分别命名为 eventsourcelinenocolnoerror
      否则
      让函数有一个名为 event 的参数。
      body
      上述解析 body 的结果。
      thisMode
      non-lexical-this
      scope
      1. realm 设为 settings object领域

      2. scope 设为 realm 的[[GlobalEnv]]。

      3. 如果 eventHandler 是一个元素的 事件 处理程序,则将 scope 设为 NewObjectEnvironment(document, true, scope)。

        (否则,eventHandler 是一个 Window 对象的事件处理程序。)

      4. 如果 form owner 不为 null,则将 scope 设为 NewObjectEnvironment(form owner, true, scope)。

      5. 如果 element 不为 null,则将 scope 设为 NewObjectEnvironment(element, true, scope)。

      6. 返回 scope

    10. settings object领域执行上下文中移除 JavaScript 执行上下文堆栈

    11. function 的[[ScriptOrModule]]设为 null。

      这样做是因为默认行为,即将创建的函数与堆栈上最近的 脚本相关联,可能会导致路径依赖的结果。例如,由用户交互首次调用的事件处理程序将最终得到 null [[ScriptOrModule]](因为在这种情况下,当活动脚本为 null 时,该算法将首次调用),而由脚本分派事件首次调用的处理程序则会将其 [[ScriptOrModule]] 设置为该脚本。

      相反,我们始终将 [[ScriptOrModule]] 设为 null。这反而更加直观;第一个分派事件的脚本应对事件处理程序代码负责的想法是可疑的。

      实际上,这仅影响通过 import() 解析相对 URL, 它会查找关联脚本的 基本 URL。将 [[ScriptOrModule]] 设为 null 意味着 HostLoadImportedModule 将 回退到 当前设置对象API 基本 URL

    12. eventHandler 设为创建一个 Web IDL EventHandler 回调函数对象的结果,该对象的引用为 function,其 回调上下文settings object

  4. 返回eventHandler

8.1.8.2 元素,Document对象和Window对象上的事件处理程序

以下是所有事件处理程序(及其对应的事件处理程序事件类型)必须由所有HTML 元素支持,既作为事件处理程序内容属性,也作为事件处理程序IDL属性;还必须由所有DocumentWindow对象支持,作为事件处理程序IDL属性

事件处理程序 事件处理程序事件类型
onabort

HTMLMediaElement/abort_event

支持所有当前的引擎。

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

Element/auxclick_event

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

HTMLElement/change_event

支持所有当前的引擎。

Firefox1+Safari3+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
change
onclick

Element/click_event

支持所有当前的引擎。

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

Element/copy_event

支持所有当前的引擎。

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

Element/cut_event

支持所有当前的引擎。

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

Element/dblclick_event

所有当前引擎均支持。

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

HTMLMediaElement/ended_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+
ended
onformdata formdata
oninput

HTMLElement/input_event

所有当前引擎均支持。

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

Element/keydown_event

所有当前引擎均支持。

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

Element/keyup_event

所有当前引擎均支持。

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

Element/mousedown_event

所有当前引擎均支持。

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

Element/mouseenter_event

所有当前引擎均支持。

Firefox10+Safari7+Chrome30+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android?
mouseenter
onmouseleave

Element/mouseleave_event

所有当前引擎均支持。

Firefox10+Safari7+Chrome30+
Opera?Edge79+
Edge (旧版)12+Internet Explorer5.5+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android?
mouseleave
onmousemove

Element/mousemove_event

所有当前引擎均支持。

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

Element/mouseout_event

所有当前引擎均支持。

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

Element/mouseover_event

所有当前引擎均支持。

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

Element/mouseup_event

所有当前引擎均支持。

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

Element/paste_event

所有当前引擎均支持。

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

HTMLMediaElement/pause_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+
pause
onplay

HTMLMediaElement/play_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+
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

Document/scrollend_event

Firefox109+SafariNoChrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Element/scrollend_event

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

HTMLMediaElement/seeked_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+
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

HTMLInputElement/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+

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

HTMLFormElement/submit_event

在所有当前引擎中支持。

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

Element/wheel_event

在所有当前引擎中支持。

Firefox17+Safari7+Chrome31+
Opera?Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS不支持Chrome Android?WebView Android?Samsung Internet?Opera Android?
wheel

以下是必须由所有 事件处理程序(及其对应的 事件处理程序事件类型)支持的 HTML 元素,除了 bodyframeset 元素之外的所有 HTML 元素,它们必须作为 事件处理程序内容属性事件处理程序IDL属性 支持; 必须由所有 Document 对象支持,作为 事件处理程序IDL属性; 必须由所有 Window 对象支持,作为 事件处理程序IDL属性Window 对象本身上暴露,并且对应的 事件处理程序内容属性事件处理程序IDL属性在 所有由该 Window 对象的 关联的 Document 所拥有的 bodyframeset 元素上暴露:

事件处理程序 事件处理程序事件类型
onblur

Element/blur_event

在所有当前引擎中均受支持。

Firefox24+Safari3.1+Chrome1+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

Window/blur_event

在所有当前引擎中均受支持。

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

Window/error_event

在所有当前引擎中均受支持。

Firefox6+Safari5.1+Chrome10+
Opera?Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android?
error
onfocus

Element/focus_event

在所有当前引擎中均受支持。

Firefox24+Safari3.1+Chrome1+
Opera11.6+ Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

Window/focus_event

在所有当前引擎中均受支持。

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

Document/scroll_event

在所有当前引擎中均受支持。

Firefox6+Safari2+Chrome1+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

Element/scroll_event

在所有当前引擎中均受支持。

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所拥有的bodyframeset 元素上公开相应的事件处理程序内容属性事件处理程序 IDL 属性

事件处理程序 事件处理程序事件类型
onafterprint

Window/afterprint_event

在所有当前引擎中均受支持。

Firefox6+Safari13+Chrome63+
Opera?Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
afterprint
onbeforeprint

Window/beforeprint_event

在所有当前引擎中均受支持。

Firefox6+Safari13+Chrome63+
Opera?Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
beforeprint
onbeforeunload

Window/beforeunload_event

在所有当前引擎中均受支持。

Firefox1+Safari3+Chrome1+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12+
beforeunload
onhashchange

Window/hashchange_event

在所有当前引擎中均受支持。

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

Window/languagechange_event

在所有当前引擎中均受支持。

Firefox32+Safari10.1+Chrome37+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet4.0+Opera Android?
languagechange
onmessage

Window/message_event

在所有当前引擎中均受支持。

Firefox9+Safari4+Chrome60+
Opera?Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS4+Chrome Android?WebView Android?Samsung Internet?Opera Android47+
message
onmessageerror

HTMLMediaElement/error_event

在所有当前引擎中均受支持。

Firefox6+Safari3.1+Chrome3+
Opera11.6+Edge79+
Edge (旧版)12+Internet Explorer 9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android?Samsung Internet?Opera Android12+

Window/messageerror_event

在所有当前引擎中均受支持。

Firefox57+Safari16.4+Chrome60+
Opera?Edge79+
Edge (旧版)18Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+
messageerror
onoffline

Window/offline_event

在所有当前引擎中均受支持。

Firefox9+Safari4+Chrome3+
Opera?Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android?
offline
ononline

Window/online_event

在所有当前引擎中均受支持。

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

Window/popstate_event

在所有当前引擎中均受支持。

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

Window/rejectionhandled_event

在所有当前引擎中均受支持。

Firefox69+Safari11+Chrome49+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS11.3+Chrome Android?WebView Android?Samsung Internet?Opera Android?
rejectionhandled
onstorage

Window/storage_event

在所有当前引擎中均受支持。

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

Window/unload_event

在所有当前引擎中均受支持。

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
8.1.8.2.1 IDL 定义
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;
};
8.1.8.3 事件触发

某些操作和方法定义为在元素上触发事件。例如,click()方法在 HTMLElement 接口中定义为在元素上触发click事件。[UIEVENTS]

触发名为e的合成指针事件target上,带有可选的not trusted flag,意味着执行以下步骤:

  1. 使用PointerEvent创建一个event

  2. eventtype属性初始化为e

  3. eventbubblescancelable属性初始化为true。

  4. 设置eventcomposed flag

  5. 如果设置了not trusted flag,将eventisTrusted属性初始化为false。

  6. 根据当前按键输入设备的状态(如果有的话),初始化eventctrlKeyshiftKeyaltKeymetaKey属性(对于不可用的按键则为false)。

  7. eventview属性初始化为target节点文档Window对象(如果有的话),否则为null。

  8. eventgetModifierState()方法应返回适当描述当前按键输入设备状态的值。

  9. 返回在target分派event的结果。

触发click事件target上意味着在target触发一个名为click的合成指针事件

8.2 WindowOrWorkerGlobalScope 混入

WindowOrWorkerGlobalScope 混入用于那些要暴露在WindowWorkerGlobalScope 对象上的 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

isSecureContext

在所有当前引擎中均受支持。

Firefox49+Safari11.1+Chrome47+
Opera?Edge79+
Edge (旧版)15+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回此全局对象是否表示安全上下文[SECURE-CONTEXTS]

self.origin

origin

在所有当前引擎中均受支持。

Firefox54+Safari11+Chrome59+
Opera?Edge79+
Edge (旧版)18Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回全局对象的来源,并序列化为字符串。

self.crossOriginIsolated

crossOriginIsolated

在所有当前引擎中均受支持。

Firefox72+Safari15.2+Chrome87+
Opera?Edge87+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回在此全局范围内运行的脚本是否被允许使用需要跨源隔离的 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 步骤是返回对象的相关设置对象跨源隔离能力

8.3 Base64 实用方法

atob()btoa()方法允许开发者将内容与 base64 编码之间相互转换。

在这些 API 中,出于记忆的目的,可以将 "b" 视为代表 "binary"(二进制),将 "a" 视为代表 "ASCII"。不过,在实际操作中,主要是由于历史原因,这些函数的输入和输出都是 Unicode 字符串。

result = self.btoa(data)

btoa

在所有当前引擎中均受支持。

Firefox1+Safari3+Chrome4+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+

将输入数据(格式为只包含 U+0000 到 U+00FF 范围内字符的 Unicode 字符串,每个字符分别表示一个二进制字节,值为 0x00 到 0xFF)转换为其 base64 表示,并返回该表示。

如果输入字符串包含任何超出范围的字符,则抛出DOMException异常,异常名为"InvalidCharacterError"

result = self.atob(data)

atob

在所有当前引擎中均受支持。

Firefox1+Safari3+Chrome4+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+

将输入数据(格式为包含 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)方法的步骤如下:

  1. decodedData成为在data上运行宽容的 base64 解码的结果。

  2. 如果decodedData失败,则抛出DOMException异常,异常名为"InvalidCharacterError"

  3. 返回decodedData

8.4 动态标记插入

用于动态插入标记到文档中的 API 会与解析器交互,因此它们的行为会根据它们是与HTML 文档(以及HTML 解析器)还是XML 文档(以及XML 解析器)一起使用而有所不同。

Document对象有一个动态标记插入计数器,该计数器与为令牌创建一个元素算法一起使用,以防止自定义元素构造函数在由解析器调用时使用document.open()document.close()document.write()。最初,计数器必须设置为零。

8.4.1 打开输入流

document = document.open()

Document/open

所有当前引擎都支持。

Firefox1+Safari11+Chrome64+
Opera51+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+

导致Document原地替换,就像它是一个新的Document对象,但重用之前的对象,然后返回该对象。

生成的Document具有与其关联的HTML解析器,可以使用document.write()提供数据进行解析。

如果Document仍在解析中,则该方法无效。

如果DocumentXML文档,则抛出DOMException异常,"InvalidStateError"。

如果解析器当前正在执行自定义元素构造函数,则抛出DOMException异常,"InvalidStateError"。

window = document.open(url, name, features)

类似于window.open()方法。

Document对象有一个活动解析器被中止的布尔值,该值用于防止脚本在文档的活动解析器被中止后调用document.open()document.write()方法(直接或间接)。它最初为false。

document open步骤,给定document,如下:

  1. 如果documentXML文档,则抛出DOMException异常,"InvalidStateError"。

  2. 如果document动态标记插入计数器大于0,则抛出DOMException异常,"InvalidStateError"。

  3. entryDocument成为入口全局对象关联的Document

  4. 如果documententryDocument不是同源,则抛出DOMException异常,"SecurityError"。

  5. 如果document活动解析器 脚本嵌套级别大于0,则返回document

    这基本上会导致在解析过程中调用的内联脚本中的document.open()被忽略,但仍允许它在从非解析器任务(例如计时器回调或事件处理程序)调用时生效。

  6. 同样地,如果document卸载计数器大于0,则返回document

    这基本上会导致在beforeunloadpagehideunload事件处理程序中调用document.open()时被忽略,而文档正在卸载中。

  7. 如果document活动解析器被中止为true,则返回document

    这特别会导致在导航开始后(但仅在初始解析期间)调用的document.open()被忽略。有关更多背景,请参见issue #4723

  8. 如果document节点可导航非null,并且document节点可导航正在进行的导航导航ID,则停止加载document节点可导航

  9. 对于document的每个包含阴影的包容性后代node,请根据node执行删除所有事件监听器和处理程序

  10. 如果documentdocument相关全局对象关联Document,则根据document相关全局对象执行删除所有事件监听器和处理程序

  11. 替换所有元素为null在document中。

  12. 如果document完全活动的,则:

    1. newURL成为entryDocumentURL的副本。

    2. 如果entryDocument不是document,则将newURL片段设置为null。

    3. 使用documentnewURL运行URL和历史记录更新步骤

  13. document是否为初始about:blank设置为false。

  14. 如果documentiframe加载进行中标志已设置,则设置document静音iframe加载标志。

  15. document设置为非怪癖模式

  16. 创建一个新的HTML解析器并将其与document关联。这是一个脚本创建的解析器(这意味着它可以通过document.open()document.close()方法关闭,并且在发出结束标记之前,标记器将等待显式调用document.close())。编码置信度无关紧要的

  17. 插入点设置为指向输入流结束之前的位置(此时输入流将为空)。

  18. 更新当前文档准备状态为"loading"。

    这会触发readystatechange事件,但由于前一步删除了所有事件监听器和处理程序,该事件实际上对作者代码是不可观察的。

  19. 返回document

document open步骤不会影响Document是否准备好进行加载后任务完全加载

open(unused1, unused2)方法必须返回使用this执行document open步骤的结果。

unused1unused2参数被忽略,但保留在IDL中,以允许调用该函数并传递一个或两个参数的代码继续工作。它们是必要的,因为Web IDL重载解析算法规则,如果没有这些参数,这种调用会引发TypeError异常。whatwg/webidl issue #581正在调查更改算法以允许其移除。[WEBIDL]

open(url, name, features)方法必须执行以下步骤:

  1. 如果this不是完全活动的,则抛出DOMException异常,"InvalidAccessError"。

  2. 返回使用urlnamefeatures执行window open步骤的结果。

8.4.2 关闭输入流

document.close()

Document/close

支持所有当前引擎。

Firefox1+Safari11+Chrome64+
Opera51+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+

关闭由document.open()方法打开的输入流。

如果DocumentXML文档,则抛出"InvalidStateError"DOMException异常。

如果解析器当前正在执行自定义元素构造函数,则抛出"InvalidStateError"DOMException异常。

close()方法必须执行以下步骤:

  1. 如果thisXML文档,则抛出"InvalidStateError"DOMException异常。

  2. 如果this动态标记插入计数器大于零,则抛出"InvalidStateError"DOMException异常。

  3. 如果没有与this关联的脚本创建的解析器,则返回。

  4. 在解析器的输入流末尾插入一个显式的"EOF"字符

  5. 如果this待解析阻塞脚本不为null,则返回。

  6. 运行标记器,处理生成的标记,直到标记器到达显式的"EOF"字符旋转事件循环

8.4.3 document.write()

document.write(...text)

Document/write

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

通常情况下,将给定的字符串添加到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,步骤如下:

  1. string 为空字符串。

  2. 如果 text 包含 字符串,则令 isTrusted 为 false;否则为 true。

  3. 对于每个 textvalue

    1. 如果 value 是一个 TrustedHTML 对象,则将 value 关联的 数据 追加到 string

    2. 否则,将 value 追加到 string

  4. 如果 isTrusted 为 false,则将 string 设置为调用 获取可信类型兼容字符串 算法的结果,使用 TrustedHTML此对象相关全局对象stringsink 和 "script"。

  5. 如果 lineFeed 为 true,则将 U+000A LINE FEED 追加到 string

  6. 如果 document 是一个 XML 文档,则抛出 "InvalidStateError" DOMException

  7. 如果 document动态标记插入计数器 大于 0,则抛出 "InvalidStateError" DOMException

  8. 如果 document活动解析器被中止 为 true,则返回。

  9. 如果 插入点 未定义,则:

    1. 如果 document卸载计数器 大于 0 或 document忽略破坏性写入计数器 大于 0,则返回。

    2. 运行 document 打开步骤,使用 document

  10. string 插入到 输入流 中,位于 插入点 之前。

  11. 如果 document待处理的阻塞脚本 为空,则让 HTML 解析器 逐个代码点处理 string,在标记化器到达插入点时或当标记化器的处理被树结构构造阶段中止时(这种情况可能发生在 如果标记化器发出了一个 script 结束标签标记)停止。

    如果 document.write() 方法是从内联执行的脚本调用的(即由于解析器解析了一组 script 标签而执行),那么这是一个解析器的重入调用。如果 解析器暂停标志 被设置,标记化器将立即中止,且不会解析任何 HTML,根据标记化器的 解析器暂停标志检查

document.write(...text) 方法步骤是 运行 document 写入步骤,使用 此对象text、false 和 "Document write"。

8.4.4 document.writeln()

document.writeln(...text)

Document/writeln

支持所有当前引擎。

Firefox1+Safari11+Chrome64+
Opera51+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+

将给定的字符串添加到Document的输入流中,并在后面加上一个换行符。如果需要,首先会隐式调用open()方法。

XML文档上调用时,抛出"InvalidStateError"DOMException异常。

如果解析器当前正在执行自定义元素构造函数,则抛出"InvalidStateError"DOMException异常。

此方法不执行任何清理操作来移除潜在危险的元素和属性,如script事件处理程序内容属性

document.writeln(...text) 方法步骤是 运行 document 写入步骤,使用 此对象text、true 和 "Document writeln"。

8.5 DOM 解析与序列化 API

DOMParser

支持所有当前引擎。

Firefox1+Safari1.3+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
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 = [];
};

8.5.1 DOMParser 接口

DOMParser 接口允许开发者通过解析字符串(作为 HTML 或 XML)创建新的 Document 对象。

parser = new DOMParser()

DOMParser/DOMParser

支持所有当前引擎。

Firefox1+Safari1.3+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

构造一个新的 DOMParser 对象。

document = parser.parseFromString(string, type)

DOMParser/parseFromString

支持所有当前引擎。

Firefox1+Safari1.3+Chrome1+
Opera8+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

根据 type,使用 HTML 或 XML 解析器解析 string,并返回生成的 Documenttype 可以是 "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) 方法的步骤如下:

  1. 调用 获取受信任类型兼容字符串 算法,传入 TrustedHTMLthis相关全局对象string、"DOMParser parseFromString" 和 "script",并将结果存储在 compliantString 中。

  2. 创建一个新的 Document 对象,内容类型typeURLthis相关全局对象关联的 DocumentURL

    文档的 编码 将保留为默认的 UTF-8。特别是,解析 compliantString 时找到的任何 XML 声明或 meta 元素都不会有任何效果。

  3. 根据 type 切换:

    "text/html"
    1. 根据 documentcompliantString 执行 从字符串解析 HTML

    由于 document 没有 浏览上下文,因此 脚本执行被禁用

    否则
    1. 创建一个 XML 解析器 parser,并将其与 document 关联,同时禁用 XML 脚本支持

    2. 使用 parser 解析 compliantString

    3. 如果上一步导致 XML 格式或 XML 命名空间格式错误,则:

      1. 断言document 没有子节点。

      2. 根据 document、"parsererror" 和 "http://www.mozilla.org/newlayout/xml/parsererror.xml" 创建一个元素,命名为 root

      3. 可选地,向 root 添加属性或子元素,以描述解析错误的性质。

      4. root 附加document

  4. 返回 document

从字符串解析 HTML,给定一个 Document document 和一个 字符串 html

  1. document类型 设置为 "html"。

  2. 创建一个与 document 关联的 HTML 解析器 parser

  3. html 放入 parser输入流 中。编码的 置信度无关紧要 的。

  4. 启动 parser,让它运行直到消耗掉刚刚插入输入流中的所有字符。

    这可能会改变文档的 模式

8.5.2 不安全的 HTML 解析方法

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事件处理程序内容属性

ElementsetHTMLUnsafe(html)方法的步骤如下:

  1. 调用获取受信任类型兼容字符串算法,传入TrustedHTMLthis相关全局对象html、"Element setHTMLUnsafe"和"script",并将结果存储在compliantHTML中。

  2. 如果this是一个template元素,则将target设为模板内容;否则,将target设为this

  3. 给定targetthiscompliantHTML不安全地设置HTML

ShadowRootsetHTMLUnsafe(html)方法的步骤如下:

  1. 调用获取受信任类型兼容字符串算法,传入TrustedHTMLthis相关全局对象html、"ShadowRoot setHTMLUnsafe"和"script",并将结果存储在compliantHTML中。

  2. 给定thisthisshadow宿主compliantHTML不安全地设置HTML

给定一个ElementDocumentFragmenttarget、一个ElementcontextElement,以及一个字符串html不安全地设置HTML

  1. 给定contextElementhtml和true,使用HTML片段解析算法获取newChildren

  2. 创建一个新的DocumentFragment,其节点文档contextElement节点文档,并将其存储在fragment中。

  3. 对于newChildren中的每个node,将其追加fragment中。

  4. 替换所有使用fragment来替换target中的所有内容。


静态的parseHTMLUnsafe(html)方法的步骤如下:

  1. 调用获取受信任类型兼容字符串算法,传入TrustedHTMLthis相关全局对象html、"Document parseHTMLUnsafe"和"script",并将结果存储在compliantHTML中。

  2. 创建一个新的Document,其内容类型为"text/html",并将其存储在document中。

    由于document没有浏览上下文脚本已禁用

  3. document允许声明性Shadow根设置为true。

  4. 给定documentcompliantHTML从字符串解析HTML

  5. 返回document

8.5.3 HTML 序列化方法

html = element.getHTML({ serializableShadowRoots, shadowRoots })

返回将element序列化为HTML的结果。element中的Shadow根将根据提供的选项进行序列化:

如果未提供任何选项,则不序列化任何Shadow根。

html = shadowRoot.getHTML({ serializableShadowRoots, shadowRoots })

返回将shadowRoot序列化为HTML的结果,并使用其Shadow宿主作为上下文元素。shadowRoot中的Shadow根将根据上述提供的选项进行序列化。

ElementgetHTML(options)方法的步骤如下:

返回HTML片段序列化算法的结果,传入thisoptions["serializableShadowRoots"]和options["shadowRoots"]。

ShadowRootgetHTML(options)方法的步骤如下:

返回HTML片段序列化算法的结果,传入thisoptions["serializableShadowRoots"]和options["shadowRoots"]。

8.5.4 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事件处理程序内容属性)进行消毒。

片段序列化算法步骤,给定 ElementDocumentDocumentFragment node 和布尔值 require well-formed,步骤如下:

  1. context document 成为 node节点文档

  2. 如果 context documentHTML 文档,则返回 HTML 片段序列化算法 的结果, 参数为 node、false 和 « »。

  3. 返回 XML 序列化 的结果, 参数为 noderequire well-formed

片段解析算法步骤,给定 Element context 和字符串 markup,步骤如下:

  1. algorithmHTML 片段解析算法

  2. 如果 context节点文档XML 文档,则将 algorithm 设置为 XML 片段解析算法

  3. new children 为调用 algorithm 的结果,参数为 markupcontext 设置为 context

  4. fragment 为一个新的 DocumentFragment, 其 节点文档context节点文档

  5. 追加每个 节点fragment 中(按树顺序)。

    这确保了新节点文档 是正确的。

  6. 返回 fragment

ElementinnerHTML 获取器 步骤为返回运行 片段序列化算法步骤 的结果, 参数为 this 和 true。

ShadowRootinnerHTML 获取器步骤为返回运行 片段序列化算法步骤 的结果, 参数为 this 和 true。

ElementinnerHTML 设置器步骤如下:

  1. compliantString 为调用 获取受信任类型合规字符串 算法的结果,参数为 TrustedHTMLthis相关全局对象、给定值、"Element innerHTML" 和 "script"。

  2. contextthis

  3. fragment 为调用 片段解析算法步骤 的结果,参数为 contextcompliantString

  4. 如果 context 是一个 template 元素,则将 context 设置为 template 元素的 模板内容(一个 DocumentFragment)。

    template 元素上设置 innerHTML 将替换其模板内容中的所有节点,而不是其子节点

  5. 全部替换 context 中的 fragment

ShadowRootinnerHTML 设置器步骤如下:

  1. compliantString 为调用 获取受信任类型合规字符串 算法的结果,参数为 TrustedHTMLthis相关全局对象、给定值、"ShadowRoot innerHTML" 和 "script"。

  2. contextthis宿主

  3. fragment 为调用 片段解析算法步骤 的结果,参数为 contextcompliantString

  4. 全部替换 this 中的 fragment

8.5.5 outerHTML 属性

outerHTML 属性在DOM Parsing and Serialization 问题跟踪器中存在一些未解决的问题,记录了规范中的各种问题。

element.outerHTML

返回表示元素及其内容的 HTML 或 XML 片段。

在 XML 文档的情况下,如果元素无法序列化为 XML,则抛出 "InvalidStateError" DOMException

element.outerHTML = value

使用从给定字符串解析的节点替换该元素。

在 XML 文档的情况下,如果给定字符串格式不正确,则抛出 "SyntaxError" DOMException

如果元素的父节点是Document,则抛出 "NoModificationAllowedError" DOMException

此属性的设置器不会对潜在危险的元素和属性(如script事件处理程序内容属性)进行消毒。

ElementouterHTML 获取器 步骤如下:

  1. element 成为一个虚构节点,其唯一子节点为 this

  2. 返回运行 片段序列化算法步骤 的结果, 参数为 element 和 true。

ElementouterHTML 设置器步骤如下:

  1. compliantString 为调用 获取受信任类型合规字符串 算法的结果,参数为 TrustedHTMLthis相关全局对象、给定值、"Element outerHTML" 和 "script"。

  2. parentthis父节点

  3. 如果 parent 为 null,则返回。即使继续执行其余步骤,也无法获得对创建的节点的引用。

  4. 如果 parentDocument,则抛出 "NoModificationAllowedError" DOMException

  5. 如果 parentDocumentFragment, 则将 parent 设置为 调用 创建元素 的结果, 参数为 this节点文档bodyHTML 命名空间

  6. fragment 为调用 片段解析算法步骤 的结果,参数为 parentcompliantString

  7. 替换 thisfragment,在 this父节点中。

8.5.6 insertAdjacentHTML() 方法

insertAdjacentHTML() 方法在DOM Parsing and Serialization 问题跟踪器中存在一些未解决的问题,记录了规范中的各种问题。

element.insertAdjacentHTML(position, string)

string解析为 HTML 或 XML,并将生成的节点插入树中由 position 参数指定的位置,具体如下:

"beforebegin"
在元素本身之前(即在element的前一个兄弟节点之后)
"afterbegin"
就在元素内部,在其第一个子节点之前。
"beforeend"
就在元素内部,在其最后一个子节点之后。
"afterend"
在元素本身之后(即在element的下一个兄弟节点之前)

如果参数值无效(例如,在 XML 文档中, 如果给定的字符串格式不正确),则抛出 "SyntaxError" DOMException

如果给定位置不可行(例如在 Document的根元素之后插入元素),则抛出 "NoModificationAllowedError" DOMException

此方法不会对潜在危险的元素和属性(如script事件处理程序内容属性)进行消毒。

ElementinsertAdjacentHTML(position, string) 方法步骤如下:

  1. compliantString 为调用 获取受信任类型合规字符串 算法的结果,参数为 TrustedHTMLthis相关全局对象string、"Element insertAdjacentHTML" 和 "script"。

  2. context 为 null。

  3. 使用以下列表中的第一个匹配项:

    如果 position 是字符串 "beforebegin" 的ASCII 大小写不敏感匹配
    如果 position 是字符串 "afterend" 的ASCII 大小写不敏感匹配
    1. context 设置为 this父节点

    2. 如果 context 为 null 或 Document,则抛出 "NoModificationAllowedError" DOMException

    如果 position 是字符串 "afterbegin" 的ASCII 大小写不敏感匹配
    如果 position 是字符串 "beforeend" 的ASCII 大小写不敏感匹配
    context 设置为 this
    否则

    抛出 "SyntaxError" DOMException

  4. 如果 context 不是 Element 或满足以下所有条件:

    context 设置为 创建元素 的结果,参数为 this节点文档bodyHTML 命名空间

  5. fragment 为调用 片段解析算法步骤 的结果,参数为 contextcompliantString

  6. 使用以下列表中的第一个匹配项:
    如果 position 是字符串 "beforebegin" 的ASCII 大小写不敏感匹配

    插入 fragmentthis父节点中,在 this 之前。

    如果 position 是字符串 "afterend" 的ASCII 大小写不敏感匹配

    插入 fragmentthis第一个子节点之前。

    如果 position 是字符串 "afterbegin" 的ASCII 大小写不敏感匹配

    追加 fragmentthis中。

    如果 position 是字符串 "beforeend" 的ASCII 大小写不敏感匹配

    插入 fragmentthis父节点中,在 this下一个兄弟节点之前。

与其他直接Node操作 API(与innerHTML不同)一样, insertAdjacentHTML() 不包含任何特殊的 template 元素处理。在大多数情况下,您将希望使用 templateEl.content.insertAdjacentHTML(), 而不是直接操作template元素的子节点。

8.5.7 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);
};

RangecreateContextualFragment(string) 方法步骤如下:

  1. compliantString 为调用 获取受信任类型合规字符串 算法的结果,参数为 TrustedHTMLthis相关全局对象string"RangecreateContextualFragment"

  2. nodethis起始节点

  3. element 为 null。

  4. 如果 node 实现了 Element, 则将 element 设置为 node

  5. 否则,如果 node 实现了 TextComment, 则将 element 设置为 node父元素

  6. 如果 element 为 null 或满足以下所有条件:

    则将 element 设置为 创建元素 的结果,参数为 this节点文档bodyHTML 命名空间

  7. fragment node 为调用 片段解析算法步骤 的结果,参数为 elementcompliantString

  8. 对于 fragment nodescript 元素的 后代中的每个 script

    1. script已启动 设置为 false。

    2. script解析器文档 设置为 null。

  9. 返回 fragment node

8.6 定时器

setTimeout()setInterval() 方法允许作者调度基于定时器的回调函数。

id = self.setTimeout(handler [, timeout [, ...arguments ] ])

setTimeout

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera4+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

调度一个超时,在 timeout 毫秒后运行 handler。任何 arguments 直接传递给 handler

id = self.setTimeout(code [, timeout ])

调度一个超时,在 timeout 毫秒后编译并运行 code

self.clearTimeout(id)

clearTimeout

在所有当前引擎中支持。

Firefox1+Safari4+Chrome1+
Opera4+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

取消通过 setTimeout()setInterval() 设置的超时,标识符为 id

id = self.setInterval(handler [, timeout [, ...arguments ] ])

setInterval

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera4+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

调度一个超时,每 timeout 毫秒运行一次 handler。任何 arguments 直接传递给 handler

id = self.setInterval(code [, timeout ])

调度一个超时,每 timeout 毫秒编译并运行 code

self.clearInterval(id)

clearInterval

在所有当前引擎中支持。

Firefox1+Safari1+Chrome1+
Opera4+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

取消通过 setInterval()setTimeout() 设置的超时,标识符为 id

定时器可以嵌套;然而,在五个嵌套的定时器之后,间隔被强制设置为至少四毫秒。

此 API 不保证定时器会精确按计划运行。由于 CPU 负载、其他任务等原因导致的延迟是可以预期的。

实现 WindowOrWorkerGlobalScope 混合体的对象拥有一个setTimeout 和 setInterval ID 映射,该映射是一个有序映射,初始为空。此映射中的每个是一个正整数,对应于 setTimeout()setInterval() 调用的返回值。每个是一个唯一内部值,对应于对象的活动定时器映射中的键。


setTimeout(handler, timeout, ...arguments) 方法步骤是根据定时器初始化步骤的运行结果返回, 其中 thishandlertimeoutarguments 和 false。

setInterval(handler, timeout, ...arguments) 方法步骤是根据定时器初始化步骤的运行结果返回, 其中 thishandlertimeoutarguments 和 true。

clearTimeout(id)clearInterval(id) 方法的步骤是移除 对象的 setTimeout 和 setInterval ID 映射[id]。

由于 clearTimeout()clearInterval() 从同一个映射中清除条目,因此可以使用任一方法来清除由 setTimeout()setInterval() 创建的定时器。


要执行 定时器初始化步骤,给定一个 WindowOrWorkerGlobalScope 对象、一个字符串或 FunctionTrustedScripthandler、一个数字 timeout、一个列表 arguments、布尔值 repeat,并可选地(且仅在 repeat 为 true 时)给出数字 previousId,执行以下步骤。这些步骤返回一个数字。

  1. thisArgglobal,如果它是 WorkerGlobalScope 对象;否则,令 thisArg 为与 global 对应的 WindowProxy

  2. 如果给定了 previousId,则令 idpreviousId;否则,令 id 为一个 实现定义的 大于零的整数,并且该整数在 globalsetTimeout 和 setInterval ID 映射中不存在。

  3. 如果 周围代理事件循环当前运行任务 是由此算法创建的任务,则令 nesting level任务定时器嵌套级别;否则,令 nesting level 为零。

    任务的 定时器嵌套级别 用于嵌套调用 setTimeout(),以及由 setInterval() 创建的重复定时器。(或者,实际上,对于这两者的任何组合。)换句话说,它表示该算法的嵌套调用,而不是某个特定方法的嵌套调用。

  4. 如果 timeout 小于 0,则将 timeout 设置为 0。

  5. 如果 nesting level 大于 5,并且 timeout 小于 4,则将 timeout 设置为 4。

  6. realmglobal相关领域

  7. initiating script活动脚本

  8. uniqueHandle 为 null。

  9. task 为一个 任务,执行以下子步骤:

    1. 断言uniqueHandle 是一个 唯一内部值,且不为 null。

    2. 如果 id 不在 globalsetTimeout 和 setInterval ID 映射存在,则中止这些步骤。

    3. 如果 globalsetTimeout 和 setInterval ID 映射[id] 不等于 uniqueHandle,则中止这些步骤。

      这是为了适应 ID 已被 clearTimeout()clearInterval() 调用清除,并且随后被 setTimeout()setInterval() 调用重用的情况。

    4. 记录定时器处理程序的时间信息,给定 handlerglobal相关设置对象repeat

    5. 如果 handler 是一个 Function,则 调用 handler,给定 arguments 和 " report",并将 回调的 this 值 设置为 thisArg

    6. 否则:

      1. 如果未给定 previousId

        1. 如果globalWindow对象,则将globalName设置为"Window";否则为"Worker"。

        2. methodName 为 "setInterval",如果 repeat 为 true;否则为 "setTimeout"。

        3. sinkglobalName、U+0020 空格和 methodName 的连接。

        4. handler设置为调用获取受信任类型兼容字符串算法的结果, 参数为TrustedScriptglobalhandlersink以及"script"。

      2. 断言handler 是一个字符串。

      3. 执行 确保 CSP 不阻止字符串编译(realm, « », handler, handler, timer, « », handler)。如果抛出异常,捕获它, global 报告,并中止这些步骤。

      4. settings objectglobal相关设置对象

      5. fetch options默认经典脚本获取选项

      6. base URLsettings objectAPI 基础 URL

      7. 如果 initiating script 不为 null,则:

        1. fetch options 设置为 脚本获取选项,其 加密随机数initiating script获取选项加密随机数完整性元数据为空字符串,解析器元数据为 "非解析器插入",凭证模式initiating script获取选项凭证模式引用者策略initiating script获取选项引用者策略获取优先级 为 "自动"。

        2. base URL 设置为 initiating script基础 URL

        这些步骤确保了 setTimeout()setInterval() 执行的字符串编译与 eval() 执行的字符串编译行为一致。也就是说,通过 import() 获取的 模块脚本 在两种上下文中将表现相同。

      8. script创建经典脚本的结果,给定 handlersettings objectbase URLfetch options

      9. 运行经典脚本 script

    7. 如果 id 不在 globalsetTimeout 和 setInterval ID 映射存在,则中止这些步骤。

    8. 如果 globalsetTimeout 和 setInterval ID 映射[id] 不等于 uniqueHandle,则中止这些步骤。

      此 ID 可能已通过 handler 中的作者代码调用 clearTimeout()clearInterval() 被移除。检查 uniqueHandle 是否不同,以防该 ID 在被清除后,被后续的 setTimeout()setInterval() 调用重用。

    9. 如果 repeat 为 true,则重新执行 定时器初始化步骤,给定 globalhandlertimeoutarguments、true 和 id

    10. 否则,移除 globalsetTimeout 和 setInterval ID 映射[id]。

  10. 递增 nesting level

  11. task定时器嵌套级别 设置为 nesting level

  12. completionStep 为一个算法步骤,它在全局任务队列中排队一个全局任务,给定 global 来运行 task

  13. uniqueHandle 设置为 运行超时后步骤 的结果,给定 global、"setTimeout/setInterval"、timeoutcompletionStep

  14. 设置 globalsetTimeout 和 setInterval ID 映射[id] 为 uniqueHandle

  15. 返回 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,表示该计时器的到期时间。

在超时后运行步骤,给定一个WindowOrWorkerGlobalScopeglobal,一个字符串orderingIdentifier,一个数字milliseconds,以及一组步骤completionSteps,执行以下步骤。它们返回一个唯一的内部值

  1. timerKey成为一个新的唯一的内部值

  2. startTime成为给定global当前高分辨率时间

  3. 设置global活动计时器映射[timerKey]为startTimemilliseconds

  4. 并行执行以下步骤:

    1. 如果global是一个Window对象,等待直到global关联的Document在接下来的milliseconds毫秒内(不一定是连续的)完全激活

      否则,global是一个WorkerGlobalScope对象;等待milliseconds毫秒,且此期间worker未被暂停(不一定是连续的)。

    2. 等待所有在相同globalorderingIdentifier的上下文中,比当前算法启动得更早且milliseconds小于或等于当前值的算法执行完毕。

    3. 可选地,再等待一个实现定义的时间长度。

      这允许用户代理根据需要延长超时时间,以优化设备的电源使用。例如,一些处理器有低功耗模式,在这种模式下,计时器的精度会降低;在这些平台上,用户代理可以减缓计时器的执行时间,以适应这种时间表,而不要求处理器使用功耗更高的精确模式。

    4. 执行completionSteps

    5. 移除global活动计时器映射[timerKey]。

  5. 返回timerKey

在超时后运行步骤 旨在供其他规范使用,这些规范希望在开发人员指定的超时后执行开发人员提供的代码,类似于setTimeout()的方式。(请注意,它没有setTimeout()的嵌套和限制行为。) 这些规范可以选择一个orderingIdentifier,以确保在它们自己的规范超时内的顺序,同时不限制与其他规范超时的顺序。

8.7 微任务排队

queueMicrotask

支持所有当前的引擎。

Firefox69+Safari12.1+Chrome71+
Opera?Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
self.queueMicrotask(callback)

排队一个 微任务以运行给定的 callback

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() 的类似代码中会发生)。

8.8 用户提示

8.8.1 简单对话框

window.alert(message)

Window/alert

在所有当前引擎中均支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

显示一个带有给定消息的模态警告框,并等待用户关闭它。

result = window.confirm(message)

Window/confirm

在所有当前引擎中均支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android1+Samsung Internet?Opera Android10.1+

显示一个带有给定消息的模态确定/取消提示,等待用户关闭它,并在用户点击确定时返回 true,在用户点击取消时返回 false。

result = window.prompt(message [, default])

Window/prompt

在所有当前引擎中均支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android1+Samsung Internet?Opera Android10.1+

显示一个带有给定消息的模态文本输入提示,等待用户关闭它,并返回用户输入的值。如果用户取消提示,则返回 null。如果提供了第二个参数,则使用给定的值作为默认值。

依赖于任务微任务的逻辑,例如媒体元素 加载其媒体数据,在调用这些方法时会被暂停。

alert()alert(message) 方法步骤如下:

  1. 如果我们无法显示简单对话框,则 返回。

  2. 如果该方法是在没有参数的情况下调用的,则令 message 为空字符串;否则,令 message 为该方法的第一个 参数。

  3. message 设置为通过给定 message 进行 标准化换行符 的结果。

  4. message 设置为通过给定 message 进行 可选地截断 的结果。

  5. 向用户显示 message,将 U+000A LF 视为换行符。

  6. 调用 WebDriver BiDi 用户提示已打开,使用 此对象、 "alert" 和 message

  7. 在等待用户确认消息时,可选地暂停

  8. 调用 WebDriver BiDi 用户提示已关闭,使用 此对象 和 true。

由于历史原因,该方法使用了两个重载,而不是使用可选参数。这一实际影响是 alert(undefined) 被视为 alert("undefined"),但 alert() 被视为 alert("")

confirm(message) 方法步骤如下:

  1. 如果我们无法显示简单对话框,则 返回 false。

  2. message 设置为通过给定 message 进行 标准化换行符 的结果。

  3. message 设置为通过给定 message 进行 可选地截断 的结果。

  4. 向用户显示 message,将 U+000A LF 视为换行符,并要求用户作出肯定或否定的响应。

  5. 调用 WebDriver BiDi 用户提示已打开,使用 此对象、 "confirm" 和 message

  6. 暂停,直到用户作出肯定或否定的响应。

  7. 调用 WebDriver BiDi 用户提示已关闭,使用 此对象, 如果用户作出了肯定响应,则为 true,否则为 false。

  8. 如果用户作出了肯定响应,返回 true;否则,用户作出了否定响应: 返回 false。

prompt(message, default) 方法步骤如下:

  1. 如果我们无法显示简单对话框,则 返回 null。

  2. message 设置为通过给定 message 进行 标准化换行符 的结果。

  3. message 设置为通过给定 message 进行 可选地截断 的结果。

  4. default 设置为通过给定 default 进行 可选地截断 的结果。

  5. 向用户显示 message,将 U+000A LF 视为换行符,并要求用户作出字符串值的响应或中止。响应必须默认设置为由 default 给定的值。

  6. 调用 WebDriver BiDi 用户提示已打开,使用 此对象、 "prompt"、messagedefault

  7. 暂停,等待用户的响应。

  8. 如果用户中止,则令 result 为 null,否则令其为用户作出的响应字符串。

  9. 调用 WebDriver BiDi 用户提示已关闭,使用 此对象, 如果 result 为 null,则为 false,否则为 true,和 result

  10. 返回 result

对于 可选地截断简单对话框字符串 s,返回 s 本身或从 s 派生的更短的字符串。用户代理不应提供显示 s 省略部分的用户界面,因为这使得恶意用户很容易创建类似“重要的安全警告!点击‘显示更多’以查看详细信息!”的对话框。

例如,用户代理可能只想显示消息的前 100 个字符。或者,用户代理可能用“……”替换字符串的中间部分。这些类型的修改在限制不自然的大而可信的系统对话框的滥用潜力方面可能很有用。

我们在以下算法返回 true 时,无法显示简单对话框,针对 Windowwindow

  1. 如果 window活动沙箱标志集 已设置 沙箱化的模态标志,则返回 true。

  2. 如果 window相关设置对象window相关 设置对象顶级源 不为 同 源域,则返回 true。

  3. 如果 window相关代理事件 循环终止嵌套级别 非零,则可选地返回 true。
  4. 可选地,返回 true。(例如,用户代理可能会给用户提供忽略所有模态对话框的选项,因此每当调用该方法时将在此步骤中止。)

  5. 返回 false。

8.8.2 打印

Window/print

在所有当前引擎中均支持。

Firefox1+Safari1.1+Chrome1+
Opera6+Edge79+
Edge (旧版)12+Internet Explorer5+
Firefox Android114+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
window.print()

提示用户打印页面。

print() 方法步骤如下:

  1. document此对象关联的 Document

  2. 如果 document 不是完全激活的,则返回。

  3. 如果 document卸载 计数器大于 0,则 返回。

  4. 如果 document 准备执行加载后任务,则运行 打印步骤,针对 document

  5. 否则,设置 document加载后打印标志。

每当用户要求获取文档的实体形式(例如打印的副本)或实体形式的表示(例如 PDF 副本)时,用户代理也应运行 打印步骤

Document document打印步骤 如下:

  1. 用户代理可以向用户显示消息或返回(或两者兼而有之)。

    例如,信息亭浏览器可以静默忽略任何对 print() 方法的调用。

    例如,移动设备上的浏览器可以检测到附近没有打印机,并在继续提供“保存为 PDF”选项之前显示一条消息。

  2. 如果 document活动沙箱标志集 设置了 沙箱化的模态标志,则返回。

    如果打印对话框被 Document 的沙箱阻止, 则不会触发 beforeprintafterprint 事件。

  3. 用户代理必须触发一个事件,名为 beforeprint, 在 相关全局对象 以及其中的任何 子导航中。

    仅在子导航中触发似乎不正确,可能需要对某些任务进行排队。请参阅 问题 #5096

    beforeprint 事件可用于 注释打印的副本,例如添加文档打印的时间。

  4. 用户代理应为用户提供获取 document实体形式(或实体形式的表示)的机会。用户代理可以等待用户接受或拒绝后再返回;如果是这样,用户代理必须在方法等待时暂停。即使 用户代理在此时不等待,用户代理也必须在算法的此时点使用相关文档的状态,如果最终创建了备用形式。

  5. 用户代理必须触发一个事件,名为 afterprint, 在 相关全局对象 以及其中的任何 子导航中。

    仅在子导航中触发似乎不正确,可能需要对某些任务进行排队。请参阅 问题 #5096

    afterprint 事件可用于 恢复在早期事件中添加的注释,以及显示打印后的用户界面。例如,如果一个页面正在引导用户完成申请住房贷款的步骤,脚本可以在打印表单或其他内容后自动进入下一步。

8.9 系统状态和能力

8.9.1 Navigator 对象

Navigator

在所有当前引擎中均支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

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对象。

Window/navigator

在所有当前引擎中均支持。

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

navigatorclientInformation 的 getter 步骤是返回this关联的Navigator

8.9.1.1 客户端识别
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 兼容模式,其值可以是 ChromeGeckoWebKit

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

Navigator/userAgent

在所有当前引擎中均支持。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

返回完整的 `User-Agent` 头信息。

window.navigator.vendor

返回空字符串,或字符串 "Apple Computer, Inc.",或字符串 "Google Inc."。

window.navigator.vendorSub

返回空字符串。

appCodeName

必须返回字符串 "Mozilla"。

appName

必须返回字符串 "Netscape"。

appVersion

必须返回以 "5.0 (" 开头的适当字符串,如下所示:

trail默认 `User-Agent` 值 中在 "Mozilla/" 前缀之后的子字符串。

如果 navigator 兼容模式ChromeWebKit

返回 trail

如果 navigator 兼容模式Gecko

如果 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

必须返回以下列表中的适当字符串:

如果 navigator 兼容模式ChromeWebKit

字符串 "20030107"。

如果 navigator 兼容模式Gecko

字符串 "20100101"。

userAgent

必须返回 默认 `User-Agent` 值

vendor

必须返回以下列表中的适当字符串:

如果 navigator 兼容模式Chrome

字符串 "Google Inc."。

如果 navigator 兼容模式Gecko

空字符串。

如果 navigator 兼容模式WebKit

字符串 "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 中包含信息。

8.9.1.2 语言偏好
interface mixin NavigatorLanguage {
  readonly attribute DOMString language;
  readonly attribute FrozenArray<DOMString> languages;
};
self.navigator.language

Navigator/language

在所有当前引擎中均支持。

Firefox1+Safari1+Chrome1+
Opera4+Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

WorkerNavigator/language

在所有当前引擎中均支持。

Firefox3.5+Safari10+Chrome4+
Opera4+Edge79+
Edge (旧版)12+Internet Explorer11
Firefox Android4+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

返回一个表示用户首选语言的语言标签。

self.navigator.languages

Navigator/languages

在所有当前引擎中均支持。

Firefox32+Safari10.1+Chrome37+
Opera24+Edge79+
Edge (旧版)16+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet3.0+Opera Android24+

返回一个表示用户首选语言的语言标签数组,最优先的语言排在最前面。

最优先的语言是由 navigator.language 返回的语言。

当用户代理对用户的首选语言的理解发生变化时,会在 languagechange 事件在 WindowWorkerGlobalScope 对象上触发。

language

必须返回一个有效的 BCP 47 语言标签,表示 一个合理的语言 或用户的首选语言。[BCP47]

languages

必须返回一个冻结数组, 该数组包含一个或多个有效的 BCP 47 语言标签,表示合理的语言或用户的首选语言,并按首选顺序排列,最优先的语言排在最前面。必须返回同一个对象,直到用户代理需要返回不同的值或不同顺序的值为止。[BCP47]

每当用户代理需要让某个 navigator.languages 属性的 WindowWorkerGlobalScope 对象 global 返回一组新的语言标签时,用户代理必须在 DOM 操作任务源排队一个全局任务,然后触发一个事件名为 languagechangeglobal 上,并等待该任务开始执行后再实际返回新值。

为了确定一个合理的语言,用户代理应牢记以下几点:

(这是一个跟踪向量。) 为了避免引入更多的指纹识别向量,用户代理应使用与此函数中定义的 API 相同的列表,用于 HTTP `Accept-Language` 头。

interface mixin NavigatorOnLine {
  readonly attribute boolean onLine;
};
self.navigator.onLine

Navigator/onLine

在所有当前引擎中均支持。

Firefox1.5+Safari4+Chrome2+
Opera3+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android4+Safari iOS?Chrome Android18+🔰 37+Samsung Internet?Opera Android10.1+

WorkerNavigator/onLine

在所有当前引擎中均支持。

Firefox3.5+Safari4+Chrome4+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android4+Safari iOS5+Chrome Android?🔰 4.4+Samsung Internet?Opera Android11+

如果用户代理确定离线(断开与网络的连接),则返回false。否则返回true,表示用户代理可能在线。

当此属性的值发生变化时,将触发onlineoffline 事件。

当用户代理在用户点击链接或脚本请求远程页面时不会联系网络(或知道此类尝试会失败)时,onLine属性必须返回false,否则返回true。

当某个WindowWorkerGlobalScope 对象globalnavigator.onLine属性的值从true变为false时,用户代理必须在网络任务源中为global排队一个全局任务,以触发名为offline的事件。

另一方面,当某个WindowWorkerGlobalScope 对象globalnavigator.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>
8.9.1.4 自定义方案处理程序:registerProtocolHandler() 方法

Navigator/registerProtocolHandler

Firefox2+Safari不支持Chrome13+
Opera11.6+Edge79+
Edge (旧版)不支持Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android不支持WebView Android?Samsung Internet?Opera Android?
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

仅在一个引擎中支持。

Firefox不支持Safari不支持Chrome38+
Opera25+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android不支持WebView Android?Samsung Internet?Opera Android?

注销给定参数的处理程序。

如果用户代理阻止注销(例如使用无效方案),将抛出"SecurityError" DOMException

如果url中缺少 "%s" 字符串,将抛出"SyntaxError" DOMException

registerProtocolHandler(scheme, url) 方法步骤如下:

  1. 让(normalizedScheme, normalizedURLString)成为运行规范化协议处理程序参数的结果,使用schemeurl,以及 this相关设置对象

  2. 并行normalizedSchemenormalizedURLString注册协议处理程序。在所描述的约束内,用户代理可以执行任何操作。例如,用户代理可以提示用户,并提供用户将该站点添加到处理程序短名单或将其设为默认的机会,或取消请求。用户代理也可以静默收集信息,仅在与用户相关时提供这些信息。

    用户代理应记录已注册处理程序的网站(即使用户已拒绝此类注册),以便用户不会反复收到相同的请求。

    如果registerProtocolHandler()自动化模式this相关全局对象关联的Document 不是 "none",用户代理应首先验证它是否处于自动化上下文中(参见 WebDriver 的安全性考虑)。然后,用户代理应绕过上述的信息通信和用户同意收集,直接根据url

    "autoAccept"

    模拟用户查看了注册详情并接受了请求。

    "autoReject"

    模拟用户查看了注册详情并拒绝了请求。

    用户代理使用该处理程序处理一个URLinputURL时:

    1. 断言inputURL方案normalizedScheme

    2. 设置用户名给定inputURL和空字符串。

    3. 设置密码给定inputURL和空字符串。

    4. inputURLStringinputURL序列化结果。

    5. encodedURL为运行UTF-8 百分号编码 inputURLString的结果,使用组件百分号编码集

    6. handlerURLStringnormalizedURLString

    7. encodedURL替换handlerURLString中首次出现的"%s"。

    8. resultURL解析handlerURLString的结果。

    9. 导航到适当的 可导航对象resultURL

    如果用户访问了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) 方法步骤如下:

  1. 令(normalizedScheme, normalizedURLString)成为运行规范化协议处理程序参数的结果,使用 schemeurl,以及 this相关设置对象

  2. 并行:注销由normalizedSchemenormalizedURLString描述的处理程序。


规范化协议处理程序参数,给定字符串scheme、字符串url环境设置对象environment,请执行以下步骤:

  1. scheme设置为scheme转换为 ASCII 小写

  2. 如果scheme既不是安全列方案,也不是以 "web+" 开头并后跟一个或多个ASCII 小写字母的字符串,则抛出"SecurityError" DOMException

    这意味着在scheme中包含冒号(如 "mailto:")将抛出异常。

    以下方案是安全列方案

    此列表可以更改。如果有应添加的方案,请提供反馈。

  3. 如果url不包含 "%s",则抛出 "SyntaxError" DOMException

  4. urlRecord成为编码解析 URL得到的结果,使用 url,相对于environment

  5. 如果urlRecord失败,则抛出"SyntaxError" DOMException

    如果%s占位符在URL的主机或端口中,这是强制性情况。

  6. 如果urlRecord方案不是 HTTP(S)方案urlRecordenvironment同源,则抛出 "SecurityError" DOMException

  7. 断言:根据URL是否潜在可信?urlRecord的结果为"Potentially Trustworthy"。

    由于规范化协议处理程序参数安全上下文中运行, 这由同源条件隐含。

  8. 返回(scheme, urlRecord)。

    序列化urlRecord根据定义不会是一个有效的 URL 字符串,因为它包含 "%s" 字符串,而这在URL中不是一个有效组件。

8.9.1.4.1 安全性和隐私性

自定义协议处理程序可能会引发一些问题,特别是隐私问题。

劫持所有网页使用。用户代理不应允许将其正常操作中关键的协议(例如HTTP(S) 协议)重定向到第三方网站。这将使用户的活动被轻易跟踪,并可能导致在安全连接中的用户信息被收集。

劫持默认设置。强烈建议用户代理不要自动更改任何默认设置,因为这可能会导致用户将数据发送到用户未预料的远程主机。新注册的处理程序不应自动导致这些站点被使用。

注册垃圾信息。用户代理应考虑到站点可能会尝试注册大量处理程序,可能来自多个域(例如,通过重定向到一系列不同域的页面,每个页面注册一个web+spam:处理程序——类似的滥用其他浏览器功能的做法已经被色情网站使用多年)。用户代理应优雅地处理此类恶意尝试,保护用户。

恶意处理程序元数据。用户代理应防止针对接口中嵌入的字符串的典型攻击,例如确保此类字符串中的标记或转义字符不会被执行,正确处理空字节,防止过长的字符串导致崩溃或缓冲区溢出等。

泄露私人数据。网页作者可能会引用使用被认为是私人数据的 URL 的自定义协议处理程序。他们可能期望用户选择的处理程序指向组织内部的页面,从而确保敏感数据不会暴露给第三方。然而,用户可能已经注册了一个指向外部站点的处理程序,从而导致数据泄露给第三方。开发人员可能需要考虑允许管理员在某些子域、内容类型或协议上禁用自定义处理程序。

界面干扰。用户代理应准备好处理有意提供给方法的长参数。例如,如果用户界面包含一个“接受”按钮和一个“拒绝”按钮,并且“接受”按钮中包含处理程序的名称,重要的是长名称不会导致“拒绝”按钮被推到屏幕外。

8.9.1.4.2 用户代理自动化

每个Document都有一个registerProtocolHandler()自动化模式。默认值为"none",但它也可以是"autoAccept"或"autoReject"。

为了用户代理自动化和网站测试的目的,本标准定义了设置 RPH 注册模式WebDriver 扩展命令。它指示用户代理将Document置于一种模式,在这种模式下,它将自动模拟用户接受或拒绝注册确认提示对话框。

HTTP 方法 URI 模板
`POST` /session/{session id}/custom-handlers/set-mode

远程结束步骤如下:

  1. 如果parameters不是 JSON 对象,则返回WebDriver 错误,错误码为WebDriver 错误代码中的无效参数

  2. mode设置为从parameters获取名为"mode"的属性的结果。

  3. 如果mode不是"autoAccept", "autoReject", 或"none", 则返回WebDriver 错误,错误码为WebDriver 错误代码中的无效参数

  4. document设置为当前浏览上下文中的活动文档

  5. documentregisterProtocolHandler() 自动化模式设置为mode

  6. 返回成功并将数据设置为 null。

8.9.1.5 Cookies
interface mixin NavigatorCookies {
  readonly attribute boolean cookieEnabled;
};
window.navigator.cookieEnabled

Navigator/cookieEnabled

支持所有当前引擎。

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

如果设置 Cookie 的操作会被忽略,则返回 false,否则返回 true。

当用户代理试图根据HTTP 状态管理机制处理 Cookie 时,cookieEnabled属性必须返回 true;如果忽略 Cookie 更改请求,则返回 false。[COOKIES]

8.9.1.6 PDF 查看支持
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 对象的列表,这些对象的 名称 分别为:

  1. "PDF Viewer"
  2. "Chrome PDF Viewer"
  3. "Chromium PDF Viewer"
  4. "Microsoft Edge PDF Viewer"
  5. "WebKit built-in PDF"

上述列表的值构成了 PDF 查看器插件名称 列表。

这些名称是基于网站历史搜索证据选择的,因此是用户代理为了保持与现有内容的兼容性而需要公开的名称。它们按字母顺序排列。然后将 "PDF Viewer" 名称插入到第 0 个位置,以便 enabledPlugin 获取器可以指向一个通用的插件名称。

每个 Window 对象都有一个 PDF 查看器 mime 类型对象 列表。如果用户代理的 支持 PDF 查看器 为 false,则该列表为空。否则,它是一个包含两个 MimeType 对象的列表,这些对象的 类型 分别为:

  1. "application/pdf"
  2. "text/pdf"

上述列表的值构成了 PDF 查看器 mime 类型 列表。


每个 NavigatorPlugins 对象都有一个 插件数组,这是一个新的 PluginArray,以及一个 mime 类型数组,这是一个新的 MimeTypeArray

NavigatorPlugins 混入的 plugins 获取器步骤是返回 对象的 插件数组

NavigatorPlugins 混入的 mimeTypes 获取器步骤是返回 对象的 mime 类型数组

NavigatorPlugins 混入的 javaEnabled() 方法步骤是返回 false。

Navigator/pdfViewerEnabled

在所有当前引擎中受支持。

Firefox99+Safari16.4+Chrome94+
Opera?Edge94+
Edge (旧版)?Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

NavigatorPlugins 混入的 pdfViewerEnabled 获取器步骤是返回用户代理的 支持 PDF 查看器 的状态。


PluginArray 接口 支持命名属性。如果用户代理的 支持 PDF 查看器 状态为 true,那么它们就是 PDF 查看器插件名称。否则,它们为空列表。

PluginArray 接口的 namedItem(name) 方法步骤如下:

  1. 对于每个 Plugin plugin ,在 对象的 相关全局对象PDF 查看器插件对象 列表中:如果 plugin名称name,则返回 plugin

  2. 返回 null。

PluginArray 接口 支持索引属性支持的属性索引 是此对象的相关全局对象PDF 查看器插件对象的索引。

PluginArray 接口的 item(index) 方法步骤如下:

  1. plugins 设为 对象的 相关全局对象PDF 查看器插件对象

  2. 如果 index 小于 plugins大小,则返回 plugins[index]。

  3. 返回 null。

PluginArray 接口的 length 获取器步骤是返回此对象的相关全局对象的 PDF 查看器插件对象的大小。

PluginArray 接口的 refresh() 方法步骤是没有操作。


MimeTypeArray 接口 支持命名属性。如果用户代理的 支持 PDF 查看器 为 true,那么它们就是 PDF 查看器 mime 类型。否则,它们为空列表。

MimeTypeArray 接口的 namedItem(name) 方法步骤如下:

  1. 对于每个 MimeType mime 类型 ,在 对象的 相关全局对象PDF 查看器 mime 类型对象 列 表中:如果 mime 类型类型name,则返回 mime 类型

  2. 返回 null。

MimeTypeArray 接口 支持索引属性支持的属性索引 是此对象的相关全局对象PDF 查看器 mime 类型对象的索引。

MimeTypeArray 接口的 item(index) 方法步骤如下:

  1. mime 类型列表 设为 对象的 相关全局对象PDF 查看器 mime 类型对象

  2. 如果index小于mimeTypes大小,则返回mimeTypes[index]。

  3. 返回 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) 方法步骤如下:

  1. 对于每个 MimeType mime 类型 ,在 对象的 相关全局对象PDF 查看器 mime 类型对象 列表中:如果 mime 类型类型name,则返回 mime 类型

  2. 返回 null。

Plugin 接口 支持索引属性支持的属性索引 是此对象的相关全局对象PDF 查看器 mime 类型对象的索引。

Plugin 接口的 item(index) 方法步骤如下:

  1. mime 类型列表 设为 对象的 相关全局对象PDF 查看器 mime 类型对象

  2. 如果index小于mimeType大小,则返回mimeTypes[index]。

  3. 返回 null。

Plugin 接口的 length 获取器步骤是返回此对象的相关全局对象的 PDF 查看器 mime 类型对象的大小。


每个 MimeType 对象都有一个 类型,该类型在创建对象时设置。

MimeType 接口的 type 获取器步骤是返回 对象的 类型

MimeType 接口的 description 获取器步骤是返回"Portable Document Format"。

MimeType 接口的 suffixes 获取器步骤是返回 "pdf"。

MimeType 接口的 enabledPlugin 获取器步骤是返回此对象的相关全局对象的 PDF 查看器插件对象[0](即通用的 "PDF Viewer" 对象)。

8.10 图片

ImageBitmap

支持所有当前的浏览器引擎。

Firefox42+Safari15+Chrome50+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
[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 ])

createImageBitmap

支持所有当前的浏览器引擎。

Firefox42+Safari15+Chrome50+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
promise = self.createImageBitmap(image, sx, sy, sw, sh [, options ])

接受image,它可以是img元素,一个SVG image元素,一个video元素,一个canvas元素,一个Blob对象,一个ImageData对象,或另一个ImageBitmap对象,并返回一个promise,当创建新的ImageBitmap时,promise被解析。

如果无法构造ImageBitmap对象,例如因为提供的image数据实际上不是图像,那么promise将被拒绝。

如果提供了sxsyswsh参数,源图像将被裁剪到指定的像素,原始图像中缺少的任何像素将被替换为透明黑色。这些坐标在源图像的像素坐标空间中,而不是CSS像素中。

如果提供了options,则ImageBitmap对象的位图数据将根据options进行修改。例如,如果premultiplyAlpha选项设置为"premultiply",则位图数据的颜色通道将被与其alpha通道相乘

如果源图像处于无效状态(例如,img元素未成功加载,ImageBitmap对象的[[Detached]]内部槽值为true,或ImageData对象的data属性值的[[ViewedArrayBuffer]]内部槽被分离,或者Blob的数据无法解释为位图图像),则promise将被拒绝,并引发"InvalidStateError"DOMException

如果脚本不允许访问源图像的数据(例如,videoCORS跨源,或canvas由来自其他的worker脚本绘制),则promise将被拒绝,并引发"SecurityError"DOMException

imageBitmap.close()

ImageBitmap/close

支持所有当前的浏览器引擎。

Firefox46+Safari15+Chrome52+
Opera37+Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android37+

释放imageBitmap的底层位图数据

imageBitmap.width

ImageBitmap/width

支持所有当前的浏览器引擎。

Firefox42+Safari15+Chrome50+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回图像的自然宽度,以CSS像素为单位。

imageBitmap.height

ImageBitmap/height

支持所有当前的浏览器引擎。

Firefox42+Safari15+Chrome50+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回图像的自然高度,以CSS像素为单位。

一个ImageBitmap对象,其[[Detached]]内部槽值为false,总是有相关的位图数据,具有宽度和高度。然而,这些数据可能会被破坏。如果一个ImageBitmap对象的媒体数据可以无错误地解码,那么它被认为是完全可解码的

一个ImageBitmap对象的位图有一个origin-clean标志,指示该位图是否被来自不同来源的内容污染。该标志最初设置为true,并可能在createImageBitmap()的步骤中更改为false。


ImageBitmap对象是可序列化的对象可转移的对象

它们的序列化步骤,给定valueserialized,如下:

  1. 如果valueorigin-clean标志未设置,则抛出"DataCloneError"DOMException

  2. serialized的[[BitmapData]]设置为value位图数据的副本。

它们的反序列化步骤,给定serializedvaluetargetRealm,如下:

  1. value位图数据设置为serialized的[[BitmapData]]。

它们的传输步骤,给定valuedataHolder,如下:

  1. 如果valueorigin-clean标志未设置,则抛出"DataCloneError"DOMException

  2. dataHolder的[[BitmapData]]设置为value位图数据

  3. 取消设置value位图数据

它们的传输接收步骤,给定dataHoldervalue,如下:

  1. value位图数据设置为dataHolder的[[BitmapData]]。


createImageBitmap(image, options)createImageBitmap(image sx, sy, sw, sh, options)方法,在调用时,必须执行以下步骤:

  1. 如果给出了swsh并且为0,则返回一个被拒绝的promise,并带有RangeError

  2. 如果optionsresizeWidthoptionsresizeHeight之一存在且为0,则返回一个被拒绝的promise,并带有"InvalidStateError"DOMException

  3. 检查image参数的可用性。如果抛出异常或返回bad,则返回一个被拒绝的promise,并带有"InvalidStateError"DOMException

  4. 设定p为一个新的promise。

  5. 设定imageBitmap为一个新的ImageBitmap对象。

  6. 根据image进行切换:

    img
    SVG image
    1. 如果image的媒体数据没有自然尺寸(例如,它是一个没有指定内容大小的矢量图形),并且optionsresizeWidthoptionsresizeHeight未存在,则返回一个被拒绝的promise,并带有"InvalidStateError"DOMException

    2. 如果image的媒体数据没有自然尺寸(例如,它是一个没有指定内容大小的矢量图形),则应将其渲染为resizeWidthresizeHeight选项指定大小的位图。

    3. imageBitmap位图数据设定为image的媒体数据的副本,裁剪到源矩形并格式化。如果这是一个动画图像,imageBitmap位图数据只能从动画的默认图像(格式定义在不支持或禁用动画时使用的图像)中获取,或者,如果没有这样的图像,则取动画的第一帧。

    4. 如果image不是origin-clean,则将imageBitmap位图的origin-clean标志设置为false。

    5. 并行执行此步骤:

      1. 使用imageBitmap解析p

    video
    1. 如果imagenetworkState属性为NETWORK_EMPTY,则返回一个被拒绝的promise,并带有"InvalidStateError"DOMException

    2. imageBitmap位图数据设定为在当前播放位置的帧的副本,在媒体资源自然宽度自然高度(即在应用了任何纵横比修正后),裁剪到源矩形并格式化

    3. 如果image不是origin-clean,则将imageBitmap位图的origin-clean标志设置为false。

    4. 并行执行此步骤:

      1. 使用imageBitmap解析p

    canvas
    1. imageBitmap位图数据设定为image位图数据的副本,裁剪到源矩形并格式化

    2. imageBitmap位图的origin-clean标志设置为与image位图的 origin-clean标志相同的值。

    3. 并行执行此步骤:

      1. 使用imageBitmap解析p

    Blob

    并行执行这些步骤:

    1. imageData设定为读取image数据的结果。如果在读取对象时发生错误,则使用"InvalidStateError"DOMException拒绝p并中止这些步骤。

    2. 应用图像嗅探规则来确定imageData的文件格式,image的MIME类型(如imagetype属性所示)给出官方类型。

    3. 如果imageData不在支持的图像文件格式中(例如,它根本不是图像),或如果imageData在某种致命方式上损坏,以至于无法获取图像尺寸(例如,一个没有自然大小的矢量图形),则使用"InvalidStateError"DOMException拒绝p并中止这些步骤。

    4. imageBitmap位图数据设定为imageData裁剪到源矩形并格式化。如果这是一个动画图像,imageBitmap位图数据必须仅取自动画的默认图像(格式定义在不支持或禁用动画时使用的图像),或者,如果没有这样的图像,则取动画的第一帧。

    5. 使用imageBitmap解析p

    ImageData
    1. 设定bufferimagedata属性值的[[ViewedArrayBuffer]]内部槽。

    2. 如果IsDetachedBuffer(buffer)为true,则返回一个被拒绝的promise,并带有"InvalidStateError"DOMException

    3. imageBitmap位图数据设定为image的图像数据,裁剪到源矩形并格式化

    4. 并行执行此步骤:

      1. 使用imageBitmap解析p

    ImageBitmap
    1. imageBitmap位图数据设定为image位图数据的副本,裁剪到源矩形并格式化

    2. imageBitmap位图的origin-clean标志设置为与image位图的origin-clean标志相同的值。

    3. 并行执行此步骤:

      1. 使用imageBitmap解析p

    VideoFrame
    1. imageBitmap位图数据设定为image的可见像素数据的副本,裁剪到源矩形并格式化

    2. 并行执行此步骤:

      1. 使用imageBitmap解析p

  7. 返回p

当上述步骤要求用户代理将位图数据裁剪到源矩形并格式化时,用户代理必须执行以下步骤:

  1. input设定为正在转换的位图数据

  2. 如果指定了sxsyswsh,则将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)。

    如果swsh为负值,则该矩形的左上角将位于sxsy点的左侧或上方。

  3. 设定outputWidth如下:

    如果resizeWidth成员的options被指定
    optionsresizeWidth成员的值
    如果resizeWidth成员的options未指定,但resizeHeight成员被指定
    sourceRectangle的宽度乘以optionsresizeHeight成员的值,除以sourceRectangle的高度,并向上取整至最接近的整数
    如果resizeWidthresizeHeight都未指定
    sourceRectangle的宽度
  4. 设定outputHeight如下:

    如果resizeHeight成员的options被指定
    optionsresizeHeight成员的值
    如果resizeHeight成员的options未指定,但resizeWidth成员被指定
    sourceRectangle的高度乘以optionsresizeWidth成员的值,除以sourceRectangle的宽度,并向上取整至最接近的整数
    如果resizeWidthresizeHeight都未指定
    sourceRectangle的高度
  5. input放置在一个无限的透明黑色网格平面上,使其左上角位于平面的原点,x坐标向右增加,y坐标向下增加,并且每个像素在input图像数据中占据平面网格上的一个单元格。

  6. output设定为由sourceRectangle表示的平面上的矩形。

  7. output缩放到outputWidthoutputHeight指定的大小。用户代理应使用resizeQuality选项的值来指导缩放算法的选择。

  8. 如果imageOrientation成员的options值为"flipY",则必须垂直翻转output,无视源图像的任何图像方向元数据(如EXIF元数据),如果有的话。[EXIF]

    如果值为"from-image",则不需要额外的步骤。

    曾经有一个"none"枚举值。它被重命名为"from-image"。将来,"none"将被添加回来,并具有不同的含义。

  9. 如果imageimg元素或Blob对象,则将val设定为colorSpaceConversion成员的options的值,然后执行这些子步骤:

    1. 如果val为"default",颜色空间转换行为是实现特定的,并应根据实现用来将图像绘制到画布上的默认颜色空间来选择。

    2. 如果val为"none",output必须在不执行任何颜色空间转换的情况下解码。这意味着图像解码算法必须忽略嵌入源数据中的颜色配置文件元数据以及显示设备的颜色配置文件。

  10. val设定为premultiplyAlpha成员的options的值,然后执行这些子步骤:

    1. 如果val为"default",alpha预乘行为是实现特定的,并应根据实现认为将图像绘制到画布上最优的选择。

    2. 如果val为"premultiply",则未与alpha预乘的output必须将其颜色分量与alpha相乘,并且已与alpha预乘的部分必须保持不变。

    3. 如果val为"none",则未与alpha预乘的output必须保持不变,而已与alpha预乘的部分必须将其颜色分量除以alpha

  11. 返回output

close()方法的步骤如下:

  1. this[[Detached]]内部槽值设为true。

  2. 取消设置this位图数据

width获取器的步骤如下:

  1. 如果this[[Detached]]内部槽的值为true,则返回0。

  2. 返回this的宽度,以CSS像素为单位。

height获取器的步骤如下:

  1. 如果this[[Detached]]内部槽的值为true,则返回0。

  2. 返回this的高度,以CSS像素为单位。

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);

8.11 动画帧

一些对象包含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

每个目标对象都有一个动画帧回调映射,它是一个有序映射,初始为空;还有一个动画帧回调标识符,它是一个数字,初始值为零。

当满足以下任一条件时,AnimationFrameProviderprovider 被视为受支持


Window/requestAnimationFrame

所有现有引擎均支持。

Firefox23+Safari7+Chrome24+
Opera?Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android23+Safari iOS?Chrome Android?WebView Android4.4+Samsung Internet?Opera Android?

requestAnimationFrame(callback)方法的步骤如下:

  1. 如果this不受支持,则抛出一个"NotSupportedError"DOMException

  2. target成为this目标对象

  3. target动画帧回调标识符增加1,并将其结果设为handle

  4. callbacks成为target动画帧回调映射

  5. 设置callbacks[handle]为callback

  6. 返回handle

Window/cancelAnimationFrame

所有现有引擎均支持。

Firefox23+Safari7+Chrome24+
Opera?Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

cancelAnimationFrame(handle)方法的步骤如下:

  1. 如果this不受支持,则抛出一个"NotSupportedError"DOMException

  2. callbacks成为this目标对象动画帧回调映射

  3. 移除callbacks[handle]。

运行动画帧回调,对于target对象target,使用时间戳now

  1. callbacks成为target动画帧回调映射

  2. callbackHandles成为获取的键的结果callbacks

  3. 对于handlecallbackHandles中,如果handle存在callbacks

    1. callback 设为 callbacks[handle]。

    2. 移除 callbacks[handle]。

    3. 调用 callback,使用 « now » 和 "report"。

在工作线程中,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();
};

9 通信

WebSocket 接口曾在此定义。现在它在WebSockets中定义。[WEBSOCKETS]

9.1 MessageEvent 接口

MessageEvent

在所有当前引擎中支持。

Firefox3+Safari4+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11+

服务器发送事件中、跨文档消息传递中、 通道消息传递中、 广播频道中,以及 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

MessageEvent/data

在所有当前引擎中支持。

Firefox3+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回消息的数据。

event.origin

MessageEvent/origin

在所有当前引擎中支持。

Firefox3+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回消息的来源,对于服务器发送事件跨文档消息传递

event.lastEventId

MessageEvent/lastEventId

在所有当前引擎中支持。

Firefox3+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)17+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回最后事件 ID 字符串, 对于服务器发送事件

event.source

MessageEvent/source

在所有当前引擎中支持。

Firefox3+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回消息源的WindowProxy, 对于跨文档消息传递;在connect 事件中 SharedWorkerGlobalScope 对象中被附加的MessagePort

event.ports

MessageEvent/ports

在所有当前引擎中支持。

Firefox3+Safari4+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+

返回与消息一起发送的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(例如,WebSocketEventSource) 使用 MessageEvent 接口用于它们的message 事件 而不使用MessagePort API。

9.2 服务器发送事件

Server-sent_events

在所有当前引擎中支持。

Firefox6+Safari5+Chrome6+
Opera11+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+

9.2.1 简介

本节为非规范性内容。

为了使服务器能够通过 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

处理这种流的脚本如下(其中addHandlerremoveHandler是接受一个参数的函数,即事件):

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 而不是使用XMLHttpRequestiframe来模拟它,使用户代理能够在用户代理实现者和网络运营商能够预先协调的情况下更好地利用网络资源。除此之外,这还可以显著节省便携式设备的电池寿命。这在下面的无连接推送部分中进一步讨论。

9.2.2 EventSource 接口

EventSource

在所有当前引擎中支持。

Firefox6+Safari5+Chrome6+
Opera11+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+
[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 之外,这些目前并未在 EventSource 对象上公开。

source = new EventSource( url [, { withCredentials: true } ])

EventSource/EventSource

在所有当前引擎中支持。

Firefox6+Safari5+Chrome6+
Opera11+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+

创建一个新的 EventSource 对象。

url 是一个字符串,提供了将提供事件流的 URL

withCredentials 设置为 true 将把连接请求的凭证模式设置为 url 为 "include"。

source.close()

EventSource/close

在所有当前引擎中支持。

Firefox6+Safari5+Chrome6+
Opera12+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+

中止为此 EventSource 对象启动的fetch 算法的任何实例,并将 readyState 属性设置为 CLOSED

source.url

EventSource/url

在所有当前引擎中支持。

Firefox6+Safari6+Chrome18+
Opera12+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android45+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

返回提供事件流的 URL

source.withCredentials

EventSource/withCredentials

在所有当前引擎中支持。

Firefox6+Safari7+Chrome26+
Opera12+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android45+Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

如果连接请求的凭证模式 设置为 "include",则返回 true,否则返回 false。

source.readyState

EventSource/readyState

在所有当前引擎中支持。

Firefox6+Safari5+Chrome6+
Opera12+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+

返回此 EventSource 对象连接的状态。它可以具有以下描述的值。

EventSource(url, eventSourceInitDict) 构造函数在调用时必须执行以下步骤:

  1. ev 为一个新的 EventSource 对象。

  2. settingsev相关设置对象

  3. urlRecord 为在给定 url 的情况下编码解析 URL 的结果, 相对于 settings

  4. 如果 urlRecord 失败,则抛出 "SyntaxError" DOMException

  5. evurl 设置为 urlRecord

  6. corsAttributeStateAnonymous

  7. 如果 eventSourceInitDictwithCredentials 成员的值为 true,则将 corsAttributeState 设置为 Use Credentials 并将 evwithCredentials 属性设置为 true。

  8. request创建一个潜在的 CORS 请求的结果, 给定 urlRecord、空字符串和 corsAttributeState

  9. request客户端 设置为 settings

  10. 用户代理可以在 request头列表中 设置 (`Accept`, `text/event-stream`)。

  11. request缓存模式 设置为 "no-store"。

  12. request发起者类型设置为 "other"。

  13. evrequest 设置为 request

  14. 给定 response res,令 processEventSourceEndOfBody 进行以下步骤:如果 res 不是网络错误, 则重新建立连接

  15. 获取 request,并将 processResponseEndOfBody 设置为 processEventSourceEndOfBody,将 processResponse 设置为以下步骤,给定 response res

    1. 如果 res中止的网络错误,则连接失败

    2. 否则,如果 res网络错误,则重新建立连接,除非用户代理知道这样做无效,在这种情况下,用户代理可以连接失败

    3. 否则,如果 res状态 不是 200,或者如果 res 的 `Content-Type` 不是 `text/event-stream`, 则连接失败

    4. 否则,宣布连接逐行解释 res主体

  16. 返回 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

EventSource/open_event

在所有当前引擎中支持。

Firefox6+Safari5+Chrome6+
Opera12+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+
open
onmessage

EventSource/message_event

在所有当前引擎中支持。

Firefox6+Safari5+Chrome6+
Opera12+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+
message
onerror

EventSource/error_event

在所有当前引擎中支持。

Firefox6+Safari5+Chrome6+
Opera12+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+
error

9.2.3 处理模型

当用户代理需要宣布连接时,用户代理必须排队一个任务,如果readyState 属性被设置为CLOSED以外的值, 则将readyState 属性设置为OPEN触发一个名为open的事件, 在EventSource对象上。

当用户代理需要重新建立连接时,用户代理必须运行以下步骤。这些步骤是在并行运行的,而不是作为任务的一部分运行的。(当然,它排队的任务是像普通任务一样运行的,而不是它们自己并行运行的。)

  1. 排队一个任务 以运行以下步骤:

    1. 如果readyState 属性被设置为CLOSED, 则中止任务。

    2. readyState 属性设置为CONNECTING

    3. 触发一个事件 名为errorEventSource对象上。

  2. 等待与事件源的重连时间相等的延迟。

  3. 可选地,再等待一些时间。特别是,如果上次尝试失败,那么用户代理可能会引入指数级的回退延迟,以避免可能已经超载的服务器过载。或者,如果操作系统报告没有网络连接,用户代理可能会等待操作系统宣布网络连接已恢复,然后再重试。

  4. 等待上述任务运行完毕(如果尚未运行)。

  5. 排队一个任务 以运行以下步骤:

    1. 如果EventSource对象的readyState 属性未设置为CONNECTING, 则返回。

    2. requestEventSource对象的request

    3. 如果EventSource对象的最后事件 ID 字符串不是空字符串,则:

      1. lastEventIDValueEventSource对象的最后事件 ID 字符串编码为 UTF-8

      2. 设置 (`Last-Event-ID`, lastEventIDValue)在request头列表中。

    4. 获取request并按本节前面描述的方式处理由此获得的响应(如果有)。

当用户代理需要连接失败时,用户代理必须排队一个任务,如果readyState 属性被设置为CLOSED以外的值, 则将readyState 属性设置为CLOSED触发一个事件名为errorEventSource对象上。 一旦用户代理连接失败, 它将不会尝试重新连接。


任务源EventSource 对象排队的任务远程事件任务源

9.2.4 `Last-Event-ID` 请求头

Last-Event-ID` HTTP 请求头在用户代理重新建立连接时,向服务器报告一个EventSource对象的最后事件 ID 字符串

参见 whatwg/html issue #7363 以更好地定义值空间。它本质上是任何 UTF-8 编码的字符串,不包含 U+0000 NULL、U+000A LF 或 U+000D CR。

9.2.5 解析事件流

此事件流格式的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) 字符结束的行缓冲是安全的,但使用块缓冲或使用不同预期行结尾的行缓冲可能会导致事件分发的延迟。

9.2.6 解释事件流

流必须使用 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 冒号字符 (:) 开头

忽略此行。

如果该行包含 U+003A 冒号字符 (:)

收集该行中第一个 U+003A 冒号字符 (:) 之前的字符,并将其作为field

收集第一个 U+003A 冒号字符 (:) 之后的字符,并将其作为value。如果value以 U+0020 空格字符开头,将其从value中移除。

处理字段,如以下步骤所述,使用field作为字段名称,使用value作为字段值。

否则,该字符串不为空但不包含 U+003A 冒号字符 (:)

处理字段,如以下步骤所述,使用整个行作为字段名称,并使用空字符串作为字段值。

一旦文件末尾到达,任何未处理的数据都必须被丢弃。(如果文件在事件的中间结束,即在最后一个空行之前,则不分发未完成的事件。)


给定字段名称和字段值,处理字段的步骤取决于字段名称,如以下列表所示。字段名称必须逐字比较,不进行大小写折叠。

如果字段名称是 "event"

event type缓冲区设置为字段值。

如果字段名称是 "data"

将字段值附加到data缓冲区,然后在data缓冲区中附加一个单一的 U+000A 换行符 (LF) 字符。

如果字段名称是 "id"

如果字段值不包含 U+0000 NULL,则将last event ID缓冲区设置为字段值。否则,忽略此字段。

如果字段名称是 "retry"

如果字段值仅包含ASCII 数字,则将字段值解释为一个以十进制表示的整数,并将事件流的重新连接时间设置为该整数。 否则,忽略此字段。

否则

忽略该字段。

当用户代理需要分发事件时,用户代理必须使用适当的步骤处理data缓冲区、event type缓冲区和last event ID缓冲区。

对于网络浏览器,分发事件的适当步骤如下:

  1. 将事件源的最后事件 ID 字符串设置为last event ID缓冲区的值。缓冲区不会被重置,因此事件源的最后事件 ID 字符串将保持为此值,直到下一次由服务器设置为止。

  2. 如果data缓冲区为空字符串,将data缓冲区和event type缓冲区设置为空字符串并返回。

  3. 如果data缓冲区的最后一个字符是 U+000A 换行符 (LF) 字符,则从data缓冲区中删除最后一个字符。

  4. event成为创建一个事件的结果,使用MessageEvent,在事件源的相关领域中。

  5. eventtype属性初始化为message,其data属性初始化为data,其origin属性初始化为事件流最终 URL(即重定向后的 URL)的序列化,其lastEventId属性初始化为事件源的最后事件 ID 字符串

  6. 如果event type缓冲区的值不是空字符串,则将新创建的事件的类型更改为与event type缓冲区的值相等。

  7. data缓冲区和event type缓冲区设置为空字符串。

  8. 排队一个任务,如果readyState属性设置为除CLOSED以外的值,分发刚创建的事件到EventSource对象。

如果事件没有 "id" 字段,但之前的事件确实将事件源的最后事件 ID 字符串设置了,那么事件的lastEventId字段将被设置为最后看到的 "id" 字段的值。

对于其他用户代理,分发事件的适当步骤取决于实现,但至少它们必须在返回之前将dataevent 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

这是因为冒号后的空格(如果存在)会被忽略。

9.2.7 编写说明

已知旧版代理服务器在某些情况下会在短暂超时后断开 HTTP 连接。为了防止此类代理服务器的影响,作者可以每隔 15 秒左右包含一行注释(以 ':' 字符开头)。

希望将事件源连接与其他连接或之前提供的特定文档相关联的作者可能会发现,依赖 IP 地址不起作用,因为单个客户端可能有多个 IP 地址(由于有多个代理服务器),并且单个 IP 地址可能有多个客户端(由于共享代理服务器)。最好在提供文档时包含一个唯一标识符,然后在建立连接时将该标识符作为 URL 的一部分传递。

作者还需注意,HTTP 分块传输可能会对该协议的可靠性产生意想不到的负面影响,特别是在分块传输由不了解时间要求的不同层执行时。如果这是个问题,可以在提供事件流时禁用分块传输。

支持 HTTP 每服务器连接限制的客户端在从站点打开多个页面时,可能会遇到问题,如果每个页面都有一个指向同一域的EventSource。作者可以通过使用每个连接唯一的域名,或允许用户在每个页面上启用或禁用EventSource功能,或通过使用共享worker共享单个EventSource对象来避免这种情况。

9.2.8 无连接推送及其他功能

在受控环境中运行的用户代理(例如与特定运营商绑定的移动设备上的浏览器)可能会将连接的管理卸载到网络上的代理服务器。在这种情况下,为了符合规范,用户代理被视为包括手持设备软件和网络代理。

例如,移动设备上的浏览器在建立连接后,可能会检测到它在支持的网络上,并请求网络上的代理服务器接管连接的管理。这种情况下的时间线可能如下:

  1. 浏览器连接到远程 HTTP 服务器并请求由作者在EventSource 构造函数中指定的资源。
  2. 服务器偶尔发送消息。
  3. 在两次消息之间,浏览器检测到除了保持 TCP 连接活跃所涉及的网络活动外,它处于空闲状态,并决定切换到睡眠模式以节省电量。
  4. 浏览器与服务器断开连接。
  5. 浏览器联系网络上的一个服务,并请求该服务(一个“推送代理”)代为保持连接。
  6. “推送代理”服务联系远程 HTTP 服务器,并请求由作者在EventSource 构造函数中指定的资源(可能包括一个`Last-Event-ID` HTTP 头等)。
  7. 浏览器允许移动设备进入睡眠状态。
  8. 服务器发送另一条消息。
  9. “推送代理”服务使用诸如 OMA 推送之类的技术将事件传送到移动设备,设备仅在处理事件时唤醒,之后再次进入睡眠状态。

这可以减少总数据使用量,从而节省大量电量。

除了实现现有的 API 和text/event-stream 线路格式之外,如上所述,也可以支持其他适用规范定义的事件帧格式。本规范未定义它们的解析或处理方式。

9.2.9 垃圾回收

EventSource 对象的 readyStateCONNECTING 时,并且该对象已注册了一个或多个 openmessageerror 事件的事件监听器时,必须从 WindowWorkerGlobalScope 对象到 EventSource 对象本身有一个强引用。

EventSource 对象的 readyStateOPEN 时,并且该对象已注册了一个或多个 messageerror 事件的事件监听器时,必须从 WindowWorkerGlobalScope 对象到 EventSource 对象本身有一个强引用。

EventSource 对象在 远程事件任务来源 上排队有任务时,必须从 WindowWorkerGlobalScope 对象到 EventSource 对象有一个强引用。

如果用户代理要 强制关闭 一个 EventSource 对象(当 Document 对象永久消失时会发生这种情况),用户代理必须中止为此 EventSource 对象启动的任何 fetch 算法的实例,并且必须将 readyState 属性设置为 CLOSED

如果一个 EventSource 对象在其连接仍然打开时被垃圾回收,则用户代理必须中止由该 EventSource 打开的 fetch 算法的任何实例。

9.2.10 实现建议

本节为非规范性内容。

强烈建议用户代理在其开发控制台中提供有关 EventSource 对象及其相关网络连接的详细诊断信息,以帮助作者调试使用此 API 的代码。

例如,用户代理可以有一个面板,显示页面创建的所有 EventSource 对象,每个对象列出构造函数的参数、是否存在网络错误、连接的 CORS 状态以及客户端发送和从服务器接收的头信息以导致该状态、收到的消息以及它们是如何被解析的,等等。

特别鼓励在开发控制台中报告详细信息,尤其是在触发 error 事件时,因为事件本身几乎无法提供任何信息。

9.3 跨文档消息传递

Window/postMessage

所有当前引擎都支持。

Firefox3+Safari4+Chrome2+
Opera9.5+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android≤37+Samsung Internet?Opera Android10.1+

出于安全和隐私原因,Web 浏览器阻止不同域中的文档相互影响;即,跨站脚本是被禁止的。

虽然这是一个重要的安全功能,但它阻止了来自不同域的页面在非敌对情况下进行通信。本节引入了一种消息传递系统,允许文档之间无论其来源域如何进行通信,同时设计上避免了跨站脚本攻击的发生。

postMessage() API 可以被用作追踪向量

9.3.1 介绍

本节为非规范内容。

例如,如果文档 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);
    }
  }
}

该脚本首先检查域是否是预期的域,然后查看消息内容,决定是将其显示给用户,还是通过发送消息回最初发送消息的文档来响应。

9.3.2 安全性

9.3.2.1 作者注意事项

使用此 API 需要格外小心,以防止用户受到恶意实体的攻击,这些实体可能会滥用站点为他们自己的目的服务。

作者应检查 origin 属性,以确保仅接受来自他们预期接收消息的域的消息。否则,作者消息处理代码中的错误可能会被恶意网站利用。

此外,即使在检查了 origin 属性之后,作者还应检查相关数据是否符合预期格式。否则,如果事件的来源已通过跨站脚本漏洞被攻击,使用 postMessage() 方法发送的未检查信息的进一步处理可能会导致攻击传播到接收方。

对于包含任何机密信息的消息,作者不应在消息中的 targetOrigin 参数中使用通配符 (*),否则无法保证消息仅传递给预期的接收者。


接受来自任何来源的消息的作者,建议考虑拒绝服务攻击的风险。攻击者可能会发送大量消息;如果接收页面为每条此类消息执行昂贵的计算或导致网络流量的发送,攻击者的消息可能会转化为拒绝服务攻击。建议作者采用速率限制(仅接受每分钟一定数量的消息)来使此类攻击变得不切实际。

9.3.2.2 用户代理

此 API 的完整性基于以下事实:一个 的脚本无法向其他源(非 同源)的对象发送任意事件(使用 dispatchEvent() 或其他方式)。

实现者被强烈建议在实现此功能时格外小心。它允许作者将信息从一个域传输到另一个域,而出于安全原因通常是不允许的。这也要求用户代理小心地允许访问某些属性而不允许访问其他属性。


还建议用户代理考虑限制不同 之间的消息流量,以保护不太成熟的站点免受拒绝服务攻击。

9.3.3 发送消息

window.postMessage(message [, options ])

Window/postMessage

Support in all current engines.

Firefox3+Safari4+Chrome2+
Opera9.5+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

向指定的窗口发送消息。消息可以是结构化对象,例如嵌套对象和数组,可以包含 JavaScript 值(字符串、数字、Date 对象等), 还可以包含某些数据对象,如 FileBlobFileListArrayBuffer 对象。

列在 optionstransfer 成员 中的对象是被转移的,而不是仅仅被克隆,这意味着它们在发送方将不再可用。

可以使用 optionstargetOrigin 成员指定目标源。 如果未提供,则默认为 "/"。此默认值仅将消息限制为同源目标。

如果目标窗口的源与指定的目标源不匹配,则为了避免信息泄露,消息将被丢弃。要将消息发送到目标,无论源是什么,请将目标源设置为 "*"。

如果 transfer 数组包含重复对象,或者 message 无法克隆,则抛出 "DataCloneError" DOMException

window.postMessage(message, targetOrigin [, transfer ])

这是 postMessage() 的另一种版本,其中目标源作为参数指定。调用 window.postMessage(message, target, transfer) 等价于 window.postMessage(message, {targetOrigin, transfer})

当向刚刚导航到新 文档浏览上下文窗口 发送消息时,可能会导致消息未能传达到其预期的接收者:目标 浏览上下文中的脚本必须有时间设置接收消息的监听器。因此,例如,在将消息发送到新创建的子 iframe窗口 的情况下,建议作者让子 文档 向父级发送消息以宣布其准备好接收消息,并让父级在开始发送消息之前等待此消息。

给定 targetWindowmessageoptions窗口发送消息步骤如下:

  1. targetRealmtargetWindow领域

  2. incumbentSettings现任设置对象

  3. targetOriginoptions["targetOrigin"]。

  4. 如果 targetOrigin 是单个 U+002F 斜杠字符(/),则将 targetOrigin 设置为 incumbentSettings

  5. 否则,如果 targetOrigin 不是单个 U+002A 星号字符(*),则:

    1. parsedURL 为在 targetOrigin 上运行 URL 解析器 的结果。

    2. 如果 parsedURL 失败,则抛出 "SyntaxError" DOMException

    3. targetOrigin 设置为 parsedURL

  6. transferoptions["transfer"]。

  7. serializeWithTransferResultStructuredSerializeWithTransfer(message, transfer)。重新抛出任何异常。

  8. 给定的 targetWindow 上,在 已发送消息任务源 上队列一个全局任务,以执行以下步骤:

    1. 如果 targetOrigin 参数不是单个字面 U+002A 星号字符 (*),并且 targetWindow关联的 Document 不是与 targetOrigin 同源,则返回。

    2. origin序列化 incumbentSettings

    3. source 为与 incumbentSettings全局对象(一个 Window 对象)对应的 WindowProxy 对象。

    4. deserializeRecordStructuredDeserializeWithTransfer(serializeWithTransferResult, targetRealm)。

      如果这引发异常,捕获它,触发一个名为messageerror 的事件在 targetWindow 上,使用 MessageEvent,其 origin 属性初始化为 origin,并且 source 属性初始化为 source,然后返回。

    5. messageClonedeserializeRecord.[[Deserialized]]。

    6. newPorts 为一个新 冻结数组,包含 deserializeRecord.[[TransferredValues]] 中的所有 MessagePort 对象(如果有),保持它们的相对顺序。

    7. 触发一个名为message 的事件在 targetWindow 上,使用 MessageEvent,其 origin 属性初始化为 originsource 属性初始化为 sourcedata 属性初始化为 messageClone,并且 ports 属性初始化为 newPorts

Window 接口的 postMessage(message, options) 方法步骤是给定 thismessageoptions 运行 窗口发送消息步骤

Window 接口的 postMessage(message, targetOrigin, transfer) 方法步骤是给定 thismessage 和 «[ "targetOrigin" → targetOrigin, "transfer" → transfer ]» 运行 窗口发送消息步骤

9.4 通道消息传递

Channel_Messaging_API

在所有当前引擎中支持。

Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+

Channel_Messaging_API/Using_channel_messaging

在所有当前引擎中支持。

Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+

9.4.1 介绍

本节为非规范性内容。

为了使独立的代码片段(例如,在不同的浏览上下文中运行)能够直接通信,作者可以使用通道消息传递

此机制中的通信通道实现为双向管道,每端都有一个端口。发送到一个端口的消息会在另一个端口接收,反之亦然。消息作为 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']);
9.4.1.1 示例

本节为非规范性内容。

在此示例中,两个 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 隐式调用,都会启动消息流:消息端口上发布的消息最初是暂停的,以防止在脚本有机会设置其处理程序之前消息被丢弃。

9.4.1.2 端口作为 Web 上的对象能力模型基础

本节为非规范性内容。

端口可以被视为向系统中其他参与者暴露有限能力(在对象能力模型意义上)的一种方式。这可以是一个弱能力系统,其中端口仅作为特定来源内的方便模型,或者是一个强能力模型,其中端口由一个来源provider提供,作为另一个来源consumer影响或获取provider信息的唯一机制。

例如,考虑一种情况,一个社交网站在一个iframe中嵌入了用户的电子邮件联系人提供者(来自第二个来源的地址簿网站),并在另一个iframe中嵌入了一个游戏(来自第三个来源)。外部社交网站和第二个iframe中的游戏无法访问第一个iframe内的任何内容;它们只能:

联系人提供者可以使用这些方法,尤其是第三个方法,来提供一个API,以便其他来源可以访问用户的地址簿。例如,它可以响应一条消息"add-contact Guillaume Tell <tell@pomme.example.net>",通过将给定的人和电子邮件地址添加到用户的地址簿。

为了避免任何网站能够操纵用户的联系人,联系人提供者可能只允许某些受信任的网站(如社交网站)这样做。

现在假设游戏想要将联系人添加到用户的地址簿,并且社交网站愿意代表它这样做,基本上是在“共享”联系人提供者与社交网站的信任。有几种方法可以做到这一点;最简单的方法是,它可以在游戏站点和联系人站点之间代理消息。但是,这种解决方案有一些困难:它要求社交网站完全信任游戏站点不会滥用这种特权,或者要求社交网站验证每个请求,以确保它不允许某些请求(例如添加多个联系人、读取联系人或删除联系人);如果多个游戏同时尝试与联系人提供者交互,则还需要一些额外的复杂性。

然而,使用消息通道和MessagePort对象,所有这些问题都可以消除。当游戏告诉社交网站它想要添加联系人时,社交网站可以向联系人提供者请求,不是让它添加联系人,而是请求添加一个联系人的能力。然后,联系人提供者创建一对MessagePort对象,并将其中一个发送回社交网站,社交网站将其转发给游戏。游戏和联系人提供者之间然后建立了直接连接,并且联系人提供者知道只接受一个“添加联系人”请求,其他请求一律不受理。换句话说,游戏已经被授予了添加一个联系人的能力。

9.4.1.3 端口作为服务实现抽象的基础

本节为非规范性内容。

延续上一节的示例,特别考虑联系人提供者。虽然最初的实现可能仅仅在服务的iframe中使用XMLHttpRequest对象,但服务的演变可能会转向使用带有单个WebSocket连接的共享worker

如果最初的设计使用了MessagePort对象来授予能力,或者仅仅是为了允许多个同时独立的会话,那么服务实现可以从每个iframe中的XMLHttpRequest模型切换到共享的WebSocket模型,而无需更改 API:服务提供者端的端口可以全部转发到共享worker,而不会对 API 的用户产生丝毫影响。

9.4.2 消息通道

MessageChannel

所有当前引擎均支持。

Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+
[Exposed=(Window,Worker)]
interface MessageChannel {
  constructor();

  readonly attribute MessagePort port1;
  readonly attribute MessagePort port2;
};
channel = new MessageChannel()

MessageChannel/MessageChannel

所有当前引擎均支持。

Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+

返回一个新的 MessageChannel 对象,其中包含两个新的 MessagePort 对象。

channel.port1

MessageChannel/port1

所有当前引擎均支持。

Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+

返回第一个 MessagePort 对象。

channel.port2

MessageChannel/port2

所有当前引擎均支持。

Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+

返回第二个 MessagePort 对象。

一个 MessageChannel 对象具有一个关联的端口 1和一个关联的 端口 2,它们都是 MessagePort 对象。

new MessageChannel() 构造函数的步骤是:

  1. this端口 1 设置为 新的 MessagePort, 该对象位于 相关领域

  2. this端口 2 设置为 新的 MessagePort, 该对象位于 相关领域

  3. 纠缠 this端口 1this端口 2

port1 的 getter 步骤是返回 this端口 1

port2 的 getter 步骤是返回 this端口 2

9.4.3 消息端口

MessagePort

所有当前引擎均支持。

Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11+

每个通道都有两个消息端口。通过一个端口发送的数据会在另一个端口接收,反之亦然。

[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])

MessagePort/postMessage

所有当前引擎均支持。

Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11.5+
port.postMessage(message [, { transfer }])

通过通道发送消息。列在 transfer 中的对象会被转移,而不仅仅是克隆,这意味着它们在发送方不再可用。

如果 transfer 包含重复的对象或 port,或者 message 无法克隆,则抛出 "DataCloneError" DOMException

port.start()

MessagePort/start

所有当前引擎均支持。

Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11.5+

开始分派端口上收到的消息。

port.close()

MessagePort/close

所有当前引擎均支持。

Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android11.5+

断开端口连接,使其不再活动。

每个 MessagePort 对象都可以与另一个对象纠缠(对称关系)。 每个 MessagePort 对象还有一个称为 任务源端口消息队列,初始为空。端口消息队列可以启用或禁用,初始为禁用状态。一旦启用,端口就不能再禁用(尽管队列中的消息可以转移到另一个队列或完全删除,效果基本相同)。MessagePort 还有一个 已传输 标志,初始值必须为 false。

当端口的 端口消息队列 启用时,事件循环 必须将其用作其 任务源 之一。当端口的 相关全局对象 是一个 Window 时,所有排队在其 端口消息队列 中的 任务 必须与端口的 相关全局对象关联 Document 相关联。

如果文档是 完全激活的,但事件侦听器都是在非 完全激活的 文档上下文中创建的,那么消息不会被接收,除非直到这些文档再次变为 完全激活的

每个 事件循环 都有一个称为 未传输端口消息队列任务源。这是一个虚拟的 任务源:它必须表现得好像包含了每个 端口消息队列 中的 任务,其 已传输 标志为 false,端口消息队列已启用,且其 相关代理事件循环 是该 事件循环,按它们添加到各自的 任务源 的顺序排列。当一个 任务 将从 未传输端口消息队列 中移除时,它必须从其 端口消息队列 中移除。

MessagePort已传输 标志为 false 时,为事件循环的目的,其 端口消息队列 必须被忽略。(此时会使用 未传输端口消息队列。)

当端口、其双胞胎或从中克隆的对象被转移或曾经被转移时,已传输 标志被设置为 true。当 MessagePort已传输 标志为 true 时,其 端口消息队列 作为一流的 任务源 运行,不受任何 未传输端口消息队列 的影响。

当用户代理要 纠缠 两个 MessagePort 对象时,必须执行以下步骤:

  1. 如果其中一个端口已经被纠缠,则解开它与其纠缠的端口。

    如果这两个先前纠缠的端口是一个 MessageChannel 对象的两个端口,那么该 MessageChannel 对象不再表示实际的通道:该对象中的两个端口不再纠缠。

  2. 将要纠缠的两个端口关联起来,使它们成为新通道的两个部分。(没有表示该通道的 MessageChannel 对象。)

    两个已通过此步骤的端口 AB 现在被认为是纠缠的;一个与另一个纠缠,反之亦然。

    虽然本规范将此过程描述为瞬间完成,但实现更可能通过消息传递来实现这一点。与所有算法一样,关键在于最终结果在黑箱意义上与规范中描述的结果不可区分。

给定发起解开的 MessagePort initiatorPort,解开步骤如下:

  1. otherPort 成为 initiatorPort 纠缠的 MessagePort

  2. 断言otherPort 存在。

  3. 解开 initiatorPortotherPort,使它们不再纠缠或彼此关联。

  4. 触发 一个名为 close 的事件在 otherPort 上。

即使端口未被显式关闭,也会触发 close 事件。以下情况会触发此事件:

我们仅在 otherPort 上调度此事件,因为 initiatorPort 显式触发了关闭,它的 文档 不再存在,或已被垃圾回收,如上所述。


MessagePort 对象是 可转移对象。它们的 转移步骤,给定 valuedataHolder,如下:

  1. value已传输 标志设置为 true。

  2. dataHolder 的 [[PortMessageQueue]] 设置为 value端口消息队列

  3. 如果 value 与另一个端口 remotePort 纠缠,则:

    1. remotePort已传输 标志设置为 true。

    2. dataHolder 的 [[RemotePort]] 设置为 remotePort

  4. 否则,将 dataHolder 的 [[RemotePort]] 设置为 null。

它们的 接收步骤,给定 dataHoldervalue,如下:

  1. value已传输 标志设置为 true。

  2. 将所有将在 dataHolder 的 [[PortMessageQueue]] 中触发 message 事件的 任务 移动到 value端口消息队列 中(如果有),将 value端口消息队列 保持在其初始禁用状态,并且如果 value相关全局对象 是一个 Window,则将移动的 任务value相关全局对象关联 Document 相关联。

  3. 如果 dataHolder 的 [[RemotePort]] 不为 null,则 纠缠 dataHolder 的 [[RemotePort]] 和 value。(这将解开 dataHolder 的 [[RemotePort]] 与最初转移的端口的纠缠。)


给定 sourcePorttargetPortmessageoptions消息端口消息发送步骤如下:

  1. transfer 成为 options["transfer"]。

  2. 如果 transfer 包含 sourcePort,则抛出 "DataCloneError" DOMException

  3. doomed 为 false。

  4. 如果 targetPort 不为 null 并且 transfer 包含 targetPort,则将 doomed 设置为 true,并选择性地向开发者控制台报告目标端口发送给自身,导致通信通道丢失。

  5. serializeWithTransferResult 成为 StructuredSerializeWithTransfer(message, transfer) 的结果。重新抛出任何异常。

  6. 如果 targetPort 为 null,或 doomed 为 true,则返回。

  7. 添加一个运行以下步骤的 任务targetPort端口消息队列 中:

    1. finalTargetPort 成为 MessagePort,任务现在位于其 端口消息队列 中。

      如果 targetPort 本身被转移并因此所有任务随之移动,这可能与 targetPort 不同。

    2. targetRealm 成为 finalTargetPort相关领域

    3. deserializeRecord 成为 StructuredDeserializeWithTransfer(serializeWithTransferResult, targetRealm) 的结果。

      如果这抛出异常,捕获它,触发 一个名为 messageerror 的事件在 finalTargetPort 上,使用 MessageEvent,然后返回。

    4. messageClone 成为 deserializeRecord.[[Deserialized]]。

    5. newPorts 成为一个新的 冻结数组,由 deserializeRecord.[[TransferredValues]] 中的所有 MessagePort 对象组成(如果有),保持它们的相对顺序。

    6. 触发 一个名为 message 的事件在 finalTargetPort 上,使用 MessageEvent,将 data 属性初始化为 messageClone,将 ports 属性初始化为 newPorts

给定 messagetransferpostMessage(message, transfer) 方法步骤如下:

  1. targetPort 成为 与之纠缠的端口,如果有;否则为 null。

  2. options 成为 «[ "transfer" → transfer ]»。

  3. 运行 消息端口消息发送步骤,提供 targetPortmessageoptions


给定 sourcePorttargetPortmessageoptionspostMessage(message, options) 方法步骤如下:

  1. targetPort 成为 与之纠缠的端口,如果有;否则为 null。

  2. 运行 消息端口消息发送步骤,提供 targetPortmessageoptions


给定 sourcePortstart() 方法步骤是启用 端口消息队列,如果它尚未启用。


给定 sourcePortclose() 方法步骤如下:

  1. [[Detached]] 内部插槽值设置为 true。

  2. 如果 是纠缠的,则 解开纠缠


以下是 事件处理程序(及其对应的 事件处理程序事件类型)必须由所有实现 MessagePort 接口的 对象支持,作为 事件处理程序 IDL 属性

事件处理程序 事件处理程序事件类型
onmessage

MessagePort/message_event

所有当前引擎均支持。

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() 方法。

9.4.4 端口与垃圾回收

当一个 MessagePort 对象 o 被垃圾回收时,如果 o 是纠缠的,那么用户代理必须 解开纠缠 o

当一个 MessagePort 对象 o 是纠缠的,并且注册了 messagemessageerror 事件监听器时,用户代理必须表现得好像 o 的纠缠 MessagePort 对象对 o 有一个强引用。

此外,当 MessagePort 对象仍然存在一个由 任务 引用的事件在 任务队列 中,且该事件将要在该 MessagePort 对象上分发,或当 MessagePort 对象的 端口消息队列 已启用且不为空时,该对象不得被垃圾回收。

因此,消息端口可以被接收、分配一个事件监听器,然后被遗忘,只要该事件监听器可以接收消息,通道将被维持。

当然,如果这种情况发生在通道的两侧,那么两个端口都可能被垃圾回收,因为它们不会从活动代码中可达,尽管它们对彼此有强引用。然而,如果一个消息端口有待处理的消息,它不会被垃圾回收。

强烈建议作者明确关闭 MessagePort 对象以解开它们的纠缠,以便它们的资源可以被回收。创建许多 MessagePort 对象并在不关闭它们的情况下将其丢弃,可能导致高瞬时内存使用,因为垃圾回收不一定及时执行,尤其是对于 MessagePort,垃圾回收可能涉及跨进程协调。

9.5 广播到其他浏览上下文

BroadcastChannel

在所有当前引擎中均受支持。

Firefox38+Safari15.4+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Broadcast_Channel_API

在所有当前引擎中均受支持。

Firefox38+Safari15.4+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

由同一用户在同一用户代理中打开但在不同不相关 浏览上下文 中的同一 来源 页面,有时需要互相发送通知,例如“嘿,用户在这里登录了,请重新检查您的凭据”。

对于复杂的情况,例如管理共享状态的锁定,管理服务器和多个本地客户端之间的资源同步,共享一个与远程主机的 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

在所有当前引擎中均受支持。

Firefox38+Safari15.4+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回一个新的 BroadcastChannel 对象,通过该对象可以发送和接收给定通道名称的消息。

broadcastChannel.name

BroadcastChannel/name

在所有当前引擎中均受支持。

Firefox38+Safari15.4+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回通道名称(在构造函数中传递)。

broadcastChannel.postMessage(message)

BroadcastChannel/postMessage

在所有当前引擎中均受支持。

Firefox38+Safari15.4+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

将给定消息发送到为此通道设置的其他 BroadcastChannel 对象。消息可以是结构化对象,例如嵌套的对象和数组。

broadcastChannel.close()

BroadcastChannel/close

在所有当前引擎中均受支持。

Firefox38+ Safari 15.4+Chrome54+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

关闭 BroadcastChannel 对象,使其可以被垃圾回收。

一个 BroadcastChannel 对象有一个 通道名称 和一个 关闭标志

new BroadcastChannel(name) 构造函数步骤如下:

  1. 此对象通道名称 设置为 name

  2. 此对象关闭标志 设置为 false。

name 获取步骤是返回 此对象通道名称

当一个 BroadcastChannel 对象的 关闭标志 为 false 且有一个为 messagemessageerror 事件注册的事件监听器时,必须有一个从 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
  // ...
}

10 Web workers

Web_Workers_API

所有当前引擎都支持。

Firefox3.5+Safari4+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+

Web_Workers_API/Using_web_workers

10.1 介绍

10.1.1 范围

本节是非规范性的。

本规范定义了一个API,用于在后台独立于任何用户界面脚本运行脚本。

这允许运行不会被响应点击或其他用户交互的脚本中断的长时间运行的脚本,并允许执行长时间任务而不需要让出以保持页面响应。

Worker(在本文中称为这些后台脚本)相对来说是重量级的,并不打算大规模使用。例如,为四百万像素的图像中的每个像素启动一个Worker是不合适的。下面的示例展示了一些Worker的适当用途。

通常,Worker被期望是长期存在的,具有较高的启动性能成本和较高的每实例内存成本。

10.1.2 示例

本节是非规范性的。

Worker可以用于各种用途。以下小节展示了这些用途的各种示例。

10.1.2.1 一个后台数字处理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() 方法在找到素数时将消息发送回页面。

在线查看此示例

10.1.2.2 使用 JavaScript 模块作为 worker

本节是非规范性的。

到目前为止,我们的所有示例都展示了运行 经典脚本 的 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;
  }
};

在线查看此示例

10.1.2.3 Shared workers 介绍

SharedWorker

所有当前引擎都支持。

Firefox29+Safari16+Chrome5+
Opera10.6+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android33+Safari iOS16+Chrome Android不支持WebView Android?Samsung Internet4.0–5.0Opera Android11–14

本节是非规范性的。

本节通过一个 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');
  }
}

在线查看此示例

10.1.2.4 使用 shared worker 实现共享状态

本节是非规范性的。

在此示例中,可以打开多个窗口(视图),所有窗口都在查看同一张地图。所有窗口共享相同的地图信息,并由一个 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 代理所有消息。

在线查看此示例

10.1.2.5 委托

本节是非规范性的。

随着多核 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。

在线查看此示例

10.1.2.6 提供库

本节是非规范性的。

假设有一个加密库可用,它提供以下三个任务:

生成公钥/私钥对
接收一个端口,该端口将接收两条消息,首先是公钥,然后是私钥。
给定明文和公钥,返回相应的密文
接收一个端口,可以向该端口发送任意数量的消息,第一条消息提供公钥,其余的提供明文,每个明文都会被加密,然后在同一通道上作为密文发送。用户在加密内容完成后可以关闭端口。
给定密文和私钥,返回相应的明文
接收一个端口,可以向该端口发送任意数量的消息,第一条消息提供私钥,其余的提供密文,每个密文都会被解密,然后在同一通道上作为明文发送。用户在解密内容完成后可以关闭端口。

该库本身如下:

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,即使它是通过消息通道接收数据的。

在线查看此示例

10.1.3 教程

10.1.3.1 创建一个专用 worker

本节是非规范性的。

创建一个 worker 需要一个指向 JavaScript 文件的 URL。Worker() 构造函数以该文件的 URL 作为其唯一参数被调用;然后创建并返回一个 worker:

var worker = new Worker('helper.js');

如果你希望你的 worker 脚本被解释为 模块脚本 而不是默认的 经典脚本,你需要使用稍微不同的签名:

var worker = new Worker('helper.mjs', { type: "module" });
10.1.3.2 与专用 worker 通信

本节是非规范性的。

专用 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
10.1.3.3 共享工作线程

SharedWorker

所有当前引擎都支持。

Firefox29+Safari16+Chrome5+
Opera10.6+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android33+Safari iOS16+Chrome Android不支持WebView Android?Samsung Internet4.0–5.0Opera Android11–14

本节是非规范性的。

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
};

10.2 基础设施

本标准定义了两种类型的 workers:专用 workers 和 shared workers。专用 workers 一旦创建,就会与其创建者关联,但可以使用消息端口从专用 worker 与多个其他浏览上下文或 workers 通信。另一方面,shared workers 是有名称的,一旦创建,运行在同一 来源 的任何脚本都可以获取到该 worker 的引用并与之通信。Service Workers 定义了第三种类型。[SW]

10.2.1 全局作用域

全局作用域是 worker 的“内部”。

10.2.1.1 WorkerGlobalScope 公共接口

WorkerGlobalScope

所有当前引擎都支持。

Firefox3.5+Safari4+Chrome4+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+
[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 全局作用域对象的基类,包括 DedicatedWorkerGlobalScopeSharedWorkerGlobalScopeServiceWorkerGlobalScope

一个 WorkerGlobalScope 对象有一个关联的 所有者集(一组 DocumentWorkerGlobalScope 对象)。它最初是空的,在创建或获取 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

WorkerGlobalScope/self

所有当前引擎都支持。

Firefox3.5+Safari4+Chrome4+
Opera11.5+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android34+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android?
返回 workerGlobal
workerGlobal.location

WorkerGlobalScope/location

所有当前引擎都支持。

Firefox3.5+Safari4+Chrome4+
Opera11.5+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android?
返回 workerGlobalWorkerLocation 对象。
workerGlobal.navigator

WorkerGlobalScope/navigator

所有当前引擎都支持。

Firefox3.5+Safari4+Chrome4+
Opera11.5+Edge79+
Edge (旧版)17+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android?
返回 workerGlobalWorkerNavigator 对象。
workerGlobal.importScripts(...urls)

WorkerGlobalScope/importScripts

所有当前引擎都支持。

Firefox4+Safari4+Chrome4+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android? Samsung Internet?Opera Android11+
获取 URL 中的每个 urls,按传递顺序逐个执行,然后返回(或在出现问题时抛出异常)。

self 属性必须返回 WorkerGlobalScope 对象本身。

location 属性必须返回 WorkerLocation 对象,其关联的 WorkerGlobalScope 对象WorkerGlobalScope 对象。

虽然 WorkerLocation 对象在 WorkerGlobalScope 对象之后创建,但这并不成问题,因为从脚本中无法观察到这一点。


以下是必须支持的 事件处理程序(及其对应的 事件处理程序事件类型),它们作为 事件处理程序 IDL 属性,由实现 WorkerGlobalScope 接口的对象支持:

事件处理程序 事件处理程序事件类型
onerror

WorkerGlobalScope/error_event

所有当前引擎都支持。

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
10.2.1.2 专用 workers和DedicatedWorkerGlobalScope 接口

DedicatedWorkerGlobalScope

当前所有引擎均支持。

Firefox3.5+Safari4+Chrome4+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+
[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

当前所有引擎均支持。

Firefox55+Safari12.1+Chrome70+
Opera?Edge79+
Edge (旧版)18Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回dedicatedWorkerGlobalname, 即传递给Worker 构造函数的值。主要用于调试。

dedicatedWorkerGlobal.postMessage(message [, transfer ])

DedicatedWorkerGlobalScope/postMessage

当前所有引擎均支持。

Firefox3.5+Safari4+Chrome4+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+
dedicatedWorkerGlobal.postMessage(message [, { transfer } ])

克隆message并将其传输到与dedicatedWorkerGlobal关联的Worker 对象。transfer可以作为要传输而不是克隆的对象列表传递。

dedicatedWorkerGlobal.close()

DedicatedWorkerGlobalScope/close

当前所有引擎均支持。

Firefox3.5+Safari4+Chrome4+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+

终止dedicatedWorkerGlobal

name获取步骤是返回thisname。 它的值表示使用Worker 构造函数赋予 worker 的名称,主要用于调试。

postMessage(message, transfer)postMessage(message, options)方法在DedicatedWorkerGlobalScope 对象上执行时, 其行为类似于它们立即调用端口上的postMessage(message, transfer)postMessage(message, options),并返回相同的返回值。

关闭一个 worker,给定一个workerGlobal,执行以下步骤:

  1. 丢弃已添加到workerGlobaltasks的任何relevant agentevent looptask queues

  2. workerGlobalclosing 标志设置为 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
10.2.1.3 Shared workers 和SharedWorkerGlobalScope 接口

SharedWorkerGlobalScope

当前所有引擎均支持。

Firefox29+Safari16+Chrome4+
Opera10.6+Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS16+Chrome Android?WebView Android37+Samsung Internet?Opera Android11+
[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

SharedWorkerGlobalScope/name

当前所有引擎均支持。

Firefox29+Safari16+Chrome4+
Opera10.6+Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS16+Chrome Android?WebView Android?Samsung Internet?Opera Android11+

返回sharedWorkerGlobalname,即赋予SharedWorker 构造函数的值。多个SharedWorker 对象可以通过重用相同的名称对应于同一个 shared worker(及SharedWorkerGlobalScope)。

sharedWorkerGlobal.close()

SharedWorkerGlobalScope/close

当前所有引擎均支持。

Firefox29+Safari16+Chrome4+
Opera10.6+Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS16+Chrome Android?WebView Android?Samsung Internet?Opera Android11+

终止sharedWorkerGlobal

name获取步骤是返回thisname。它的值表示可以使用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

10.2.2 事件循环

worker事件循环任务队列仅包含事件、回调和网络活动作为任务。这些worker事件循环运行worker算法创建。

每个WorkerGlobalScope对象都有一个关闭标志,最初必须为false,但可以通过以下处理模型部分中的算法将其设置为true。

一旦WorkerGlobalScope关闭标志设置为true,事件循环任务队列必须丢弃任何将添加到其中的进一步任务(除非另有规定,否则已经在队列中的任务不受影响)。实际上,一旦关闭标志为true,计时器停止触发,所有待处理的后台操作通知将被丢弃,等等。

10.2.3 Worker的生命周期

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所有者集不是,或者:

该定义的第二部分允许共享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

10.2.4 处理模型

当用户代理需要为带有WorkerSharedWorker对象worker的脚本运行一个worker时,URL url环境设置对象 outside settingsMessagePort outside port,以及WorkerOptions字典options,它必须执行以下步骤。

  1. 如果workerSharedWorker对象,则让is shared为true,否则为false。

  2. 给定outside settings,将owner设为相关所有者

  3. unsafeWorkerCreationTime设为不安全的共享当前时间

  4. agent设为给定outside settingsis shared获取专用/共享worker代理的结果。在该代理中运行以下步骤。

  5. realm execution context设为创建新领域的结果,给定agent和以下自定义内容:

  6. worker global scope设为realm execution context的Realm组件的全局对象

    这是在上一步中创建的DedicatedWorkerGlobalScopeSharedWorkerGlobalScope对象。

  7. realm execution contextoutside settingsunsafeWorkerCreationTime设置worker环境设置对象,并将结果设为inside settings

  8. worker global scopename设置为optionsname成员的值。

  9. 附加ownerworker global scope所有者集

  10. 如果is shared为true,则执行以下操作:

    1. worker global scope构造源设置为outside settings

    2. worker global scope构造URL设置为url

    3. worker global scope类型设置为optionstype成员的值。

    4. worker global scope凭据设置为optionscredentials成员的值。

  11. 如果is shared为true,则将destination设为"sharedworker",否则设为"worker"。

  12. 根据optionstype成员的值来获取script

    "classic"
    获取经典worker脚本,给定urloutside settingsdestinationinside settings,以及如下定义的onCompleteperformFetch
    "module"
    获取模块worker脚本图,给定urloutside settingsdestinationoptionscredentials成员的值、inside settings,以及如下定义的onCompleteperformFetch

    在两种情况下,将performFetch设为以下执行获取挂钩,给定requestisTopLevelprocessCustomFetchResponse

    1. 如果isTopLevel为false,fetch request并将processResponseConsumeBody设置为processCustomFetchResponse,并中止这些步骤。

    2. request预留客户端设置为inside settings
    3. Fetch request,将processResponseConsumeBody设置为以下步骤,给定response response和null、失败,或字节序列 bodyBytes

      1. worker global scopeurl设置为responseurl

      2. 初始化worker global scope的策略容器,给定worker global scoperesponseinside settings

      3. 如果在worker global scope上执行运行CSP初始化算法时返回"Blocked",则将response设置为网络错误[CSP]

      4. 如果worker global scope嵌入者策略跨源隔离兼容,并且is shared为true,则将agent代理集群跨源隔离模式设置为"逻辑"或"具体"。选择的模式是实现定义

        这实际上应该在创建代理集群时设置,这需要重新设计本节。

      5. 如果检查全局对象的嵌入者策略worker global scopeoutside settingsresponse的结果为false,则将response设置为网络错误

      6. 如果agent代理集群跨源隔离模式为"具体",则将worker global scope跨源隔离能力设置为true。

      7. 如果is shared为false,且owner跨源隔离能力为false,则将worker global scope跨源隔离能力设置为false。

      8. 如果is shared为false,且responseurlscheme为"data",则将worker global scope跨源隔离能力设置为false。

        这是目前的保守默认设置,我们还在研究如何在权限策略的上下文中处理一般的workers,特别是data: URL workers(它们与其所有者是跨源的)。有关更多详情,请参阅w3c/webappsec-permissions-policy issue #207

      9. 使用responsebodyBytes运行processCustomFetchResponse

    在两种情况下,给定scriptonComplete为以下步骤:

    1. 如果script为null,或者script要重新抛出的错误非空,则:

      1. DOM操作任务源排队一个全局任务,给定worker相关全局对象,以触发一个名为error的事件,针对worker

      2. inside settings运行环境丢弃步骤

      3. 中止这些步骤。

    2. workerworker global scope关联。

    3. inside port设为inside settingsrealm中新建的MessagePort对象。

    4. inside portworker global scope关联。

    5. 缠结outside portinside port

    6. 创建一个新的WorkerLocation对象,并将其与worker global scope关联。

    7. 关闭孤立worker:开始监控worker,以便在它不再是受保护的worker后不久,且不晚于它不再是允许的worker,将worker global scope关闭标志设置为true。

    8. 暂停worker:开始监控worker,使得每当worker global scope关闭标志为false且worker是可暂停的worker时,用户代理会暂停该worker中的脚本执行,直到关闭标志切换为true或worker不再是可暂停的worker为止。

    9. 设置inside settings执行准备就绪标志

    10. 如果script是一个经典脚本,则运行经典脚本 script。否则,它是一个模块脚本运行模块脚本 script

      除了返回值或因异常而失败的通常可能性之外,这可能会被提前中止,由下面定义的终止worker算法。

    11. 启用outside port端口消息队列

    12. 如果is shared为false,则启用worker隐式端口的端口消息队列

    13. 如果is shared为true,则在worker global scope上使用MessageEvent排队一个全局任务,给定worker global scope,以触发一个名为connect的事件,data属性初始化为空字符串,ports属性初始化为包含inside port的新冻结数组source属性初始化为inside port

    14. 启用与worker global scope相关设置对象关联的ServiceWorkerContainer对象的客户端消息队列

    15. 事件循环:运行由inside settings指定的负责的事件循环,直到它被销毁。

      由事件循环运行的任务可能会通过提前中止,这是通过下面定义的终止worker算法实现的。

      worker处理模型将在此步骤上保持不变,直到事件循环被销毁,这是在事件循环处理模型中描述的关闭标志设置为true之后发生的。

    16. 清除worker global scope活动计时器映射

    17. 解开所有worker的端口列表中的端口。

    18. 清空worker global scope所有者集


当用户代理需要终止一个worker时,它必须与worker的主循环(即上面定义的"运行一个worker"处理模型)并行地执行以下步骤:

  1. 将worker的WorkerGlobalScope对象的关闭标志设置为true。

  2. 如果在WorkerGlobalScope对象的相关代理事件循环任务队列中排队了任何任务,则丢弃它们而不处理它们。

  3. 中止当前正在worker中运行的脚本

  4. 如果worker的WorkerGlobalScope对象实际上是DedicatedWorkerGlobalScope对象(即worker是专用worker),则清空worker的隐式端口缠结的端口的端口消息队列

当worker不再是活动需要的worker,且在其关闭标志设置为true后仍继续执行时,用户代理可以调用终止worker算法。

10.2.5 运行时脚本错误

每当在 worker 的脚本之一中发生未捕获的运行时脚本错误时,如果该错误不是在处理先前的脚本错误时发生的,用户代理将报告该错误,针对 worker 的 WorkerGlobalScope 对象。

10.2.6 创建 workers

10.2.6.1 AbstractWorker 混合
interface mixin AbstractWorker {
  attribute EventHandler onerror;
};

以下是实现AbstractWorker接口的对象必须支持的事件处理程序(及其对应的事件处理程序事件类型),作为事件处理程序IDL属性

事件处理程序 事件处理程序事件类型
onerror

ServiceWorker/error_event

支持所有当前引擎。

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (旧版)17+Internet Explorer不支持
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

SharedWorker/error_event

支持所有当前引擎。

Firefox29+Safari16+Chrome5+
Opera10.6+Edge79+
Edge (旧版)?Internet Explorer不支持
Firefox Android33+Safari iOS16+Chrome Android不支持WebView Android?Samsung Internet4.0–5.0Opera Android11–14

Worker/error_event

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+
error
10.2.6.2 Workers 的脚本设置

设置一个Worker环境设置对象,需要给定一个JavaScript执行上下文execution context,一个环境设置对象outside settings,以及一个数字unsafeWorkerCreationTime

  1. inherited origin成为outside settings来源

  2. realm成为execution context的Realm组件的值。

  3. worker global scope成为realm全局对象

  4. settings object成为一个新的环境设置对象,其算法定义如下:

    realm执行上下文

    返回execution context

    模块映射

    返回worker global scope模块映射

    API基础URL

    返回worker global scopeurl

    来源

    如果worker global scopeurlscheme是"data",则返回一个唯一的不透明来源,否则返回inherited origin

    策略容器

    返回worker global scope策略容器

    跨源隔离能力

    返回worker global scope跨源隔离能力

    时间来源

    返回使用worker global scope跨源隔离能力unsafeWorkerCreationTime进行粗化的结果。

  5. 设置settings objectid为一个新的唯一不透明字符串,创建URLworker global scopeurl顶级创建URL为null,目标浏览上下文为null,活动的service worker为null。

  6. 如果worker global scope是一个DedicatedWorkerGlobalScope对象, 则将settings object顶级来源设置为outside settings顶级来源

  7. 否则,将settings object顶级来源设置为实现定义的值。

    请参阅客户端存储分区以了解有关正确定义此内容的最新信息。

  8. realm的[[HostDefined]]字段设置为settings object

  9. 返回settings object

10.2.6.3 专用 Worker 与 Worker接口

Worker

在所有当前引擎中均支持。

Firefox3.5+Safari4+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+
[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/Worker

在所有当前引擎中均支持。

Firefox3.5+Safari4+Chrome4+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+

返回一个新的Worker对象。scriptURL将被获取并在后台执行,创建一个新的全局环境,worker表示通信通道。options可以用来通过name选项定义该全局环境的名称,主要用于调试目的。它还可以确保这个新的全局环境支持 JavaScript 模块(指定type: "module"),如果指定了该选项,还可以通过credentials选项指定如何获取scriptURL

worker.terminate()

Worker/terminate

在所有当前引擎中均支持。

Firefox3.5+Safari4+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+
终止worker关联的全局环境。
worker.postMessage(message [, transfer ])

Worker/postMessage

在所有当前引擎中均支持。

Firefox3.5+Safari4+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+
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)构造函数时,用户代理必须执行以下步骤:

  1. compliantScriptURL设置为使用TrustedScriptURLthis相关全局对象scriptURL、“Worker constructor”和“script”调用获取 Trusted Type 合规字符串算法的结果。

  2. outside settings设置为当前设置对象

  3. worker URL设置为相对outside settingscompliantScriptURL执行编码-解析 URL的结果。

    可以使用任何同源 URL(包括blob: URL)。也可以使用data: URL,但它们会创建具有不透明来源的 worker。

  4. 如果worker URL为失败,则 抛出SyntaxErrorDOMException

  5. 创建一个新的Worker对象并将其设置为worker

  6. 创建一个新的outside port,该outside portoutside settingsrealm中的一个新的MessagePort

  7. outside portworker关联。

  8. 并行运行此步骤:

    1. 根据workerworker URLoutside settingsoutside portoptions执行运行 worker

  9. 返回worker

10.2.6.4 共享 worker 和 SharedWorker 接口

SharedWorker

在所有当前引擎中均受支持。

Firefox29+Safari16+Chrome5+
Opera10.6+Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android33+Safari iOS16+Chrome AndroidNoWebView Android?Samsung Internet4.0–5.0Opera Android11–14
[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/SharedWorker

在所有当前引擎中均受支持。

Firefox29+Safari16+Chrome5+
Opera10.6+Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android33+Safari iOS16+Chrome AndroidNoWebView Android?Samsung Internet4.0–5.0Opera Android11–14

返回一个新的 SharedWorker 对象。scriptURL 将在后台被获取并执行,创建一个新的全局环境,sharedWorker 代表了该全局环境的通信通道。name 可用于定义该全局环境的 name

sharedWorker = new SharedWorker(scriptURL [, options ])

返回一个新的 SharedWorker 对象。scriptURL 将在后台被获取并执行,创建一个新的全局环境,sharedWorker 代表了该全局环境的通信通道。options 可用于通过 name 选项定义该全局环境的 name。它还可以确保这个新的全局环境支持 JavaScript 模块(指定 type: "module"),如果指定了这一选项,还可以通过 credentials 选项来指定如何获取 scriptURL。请注意,尝试使用 options 中的 typecredentials 值与现有共享 worker 不匹配的情况下构建共享 worker,将导致返回的 sharedWorker 触发错误事件,并且不会连接到现有的共享 worker。

sharedWorker.port

SharedWorker/port

在所有当前引擎中均受支持。

Firefox29+Safari16+Chrome5+
Opera10.6+Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android33+Safari iOS16+Chrome AndroidNoWebView Android?Samsung Internet4.0–5.0Opera Android11–14

返回 sharedWorkerMessagePort 对象,该对象可用于与全局环境进行通信。

The port 属性必须返回由对象的构造函数分配的值。它代表与共享 worker 进行通信的 MessagePort

用户代理有一个关联的 共享 worker 管理器,它是 启动一个新的并行队列 的结果。

为了简化,每个用户代理都有一个 共享 worker 管理器。实现可以为每个 origin 使用一个管理器;这在可观察上是没有区别的,并且可以实现更多的并发性。

SharedWorker(script URL, options) 构造函数被调用时:

  1. compliantScriptURL 为调用 获取可信类型兼容字符串 算法的结果,参数为 TrustedScriptURLthis相关全局对象scriptURL,"SharedWorker constructor" 和 "script"。

  2. 如果 options 是一个 DOMString,则将 options 设置为一个新的 WorkerOptions 字典,其中 name 成员设置为 options 的值,其他成员设置为默认值。

  3. outside settings当前设置对象

  4. urlRecord编码解析 URL 的结果,参数为 compliantScriptURL,相对于 outside settings

    任何 同源 URL(包括 blob: URL)都可以使用。data: URL 也可以使用,但它们会创建一个具有 不透明 origin 的 worker。

  5. 如果 urlRecord 失败,则抛出 "SyntaxError" DOMException

  6. worker 为一个新的 SharedWorker 对象。

  7. outside port新建MessagePort,位于 outside settingsrealm 中。

  8. outside port 分配给 workerport 属性。

  9. callerIsSecureContext 为 true,如果 outside settings安全上下文;否则为 false。

  10. outside storage key 为运行 为非存储目的获取存储密钥 的结果,参数为 outside settings

  11. 将以下步骤排队共享 worker 管理器

    1. worker global scope 为 null。

    2. 对每个 scope 进行迭代,在所有 SharedWorkerGlobalScope 对象的列表中:

      1. worker storage key 为运行 为非存储目的获取存储密钥 的结果,参数为 scope相关设置对象

      2. 如果以下所有条件都为真:

        那么:

        1. worker global scope 设置为 scope

        2. 跳出循环

      data: URL 会创建一个具有 不透明 origin 的 worker。构造函数 origin 和构造函数 URL 都会进行比较,因此可以在同一个 origin 中使用相同的 data: URL 访问相同的 SharedWorkerGlobalScope 对象,但不能用于绕过 同源 限制。

    3. 如果 worker global scope 不为 null,但用户代理已配置为禁止由 worker global scope 表示的 worker 与由 script设置对象outside settings 之间的通信,则将 worker global scope 设置为 null。

      例如,用户代理可以有一个开发模式,该模式将特定的 顶级可遍历对象 与所有其他页面隔离,并且该开发模式下的 script 可能会被阻止连接到在普通浏览器模式下运行的共享 worker。

    4. 如果 worker global scope 不为 null,则执行以下子步骤:

      1. settings objectworker global scope相关设置对象

      2. workerIsSecureContext 为 true,如果 settings object安全上下文;否则为 false。

      3. 如果 workerIsSecureContext 不等于 callerIsSecureContext,则 排队一个任务触发一个名为 error 的事件,在 worker 上,终止这些步骤。[SECURE-CONTEXTS]

      4. workerworker global scope 关联。

      5. inside port新建MessagePort,位于 settings objectrealm 中。

      6. 纠缠 outside portinside port

      7. 排队一个任务,使用 DOM 操作任务源触发一个名为 connect 的事件,在 worker global scope 上,使用 MessageEventdata 属性初始化为空字符串,ports 属性初始化为一个新的 冻结数组,仅包含 inside port,以及 source 属性初始化为 inside port

      8. 相关的要添加的所有者 给定 outside settings添加worker global scope 的所有者集合中。

    5. 否则,并行运行一个 worker,给定 workerurlRecordoutside settingsoutside portoptions

  12. 返回 worker

interface mixin NavigatorConcurrentHardware {
  readonly attribute unsigned long long hardwareConcurrency;
};
self.navigator.hardwareConcurrency

Navigator/hardwareConcurrency

Firefox48+Safari10.1–11Chrome37+
Opera?Edge79+
Edge (旧版)15+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Navigator/hardwareConcurrency

Firefox48+Safari10.1–11Chrome37+
Opera?Edge79+
Edge (旧版)15+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

返回可能供用户代理使用的逻辑处理器数量。

(This is a tracking vector.) navigator.hardwareConcurrency 属性的 getter 必须返回一个在 1 到可能供用户代理使用的逻辑处理器数量之间的数字。如果无法确定,则 getter 必须返回 1。

用户代理应该倾向于公开可用的逻辑处理器数量,仅在存在用户代理特定限制(例如对可以创建的 worker 数量的限制)或用户代理希望限制指纹识别可能性的情况下才使用较低的值。

10.3 工作线程可用的 API

10.3.1 导入脚本和库

importScripts(...urls) 方法的步骤如下:

  1. urlStrings 为 « »。

  2. urls 中的每个 url

    1. 追加 调用 获取可信类型兼容字符串 算法的结果,将 TrustedScriptURLthis相关全局对象url、"Worker importScripts" 和 "script" 追加到 urlStrings 中。

  3. 给定 将脚本导入到工作线程全局范围,给定 thisurlStrings

将脚本导入到工作线程全局范围,给定 WorkerGlobalScope 对象 worker global scope、一个 列表标量值字符串 urls,以及可选的 执行抓取钩子 performFetch

  1. 如果 worker global scope类型 是 "module",则抛出 TypeError 异常。

  2. settings object当前设置对象

  3. 如果 urls 为空,则返回。

  4. urlRecords 为 « »。

  5. 对于 urls 中的每个 url

    1. urlRecord编码-解析URL 的结果,给定 url,相对于 settings object

    2. 如果 urlRecord 失败,则抛出 "SyntaxError" DOMException

    3. urlRecord 追加到 urlRecords 中。

  6. 对于 urlRecords 中的每个 urlRecord

    1. 获取经典工作线程导入的脚本,给定 urlRecordsettings object,如果提供则传递 performFetch。如果成功,则令 script 为结果。否则,重新抛出异常。

    2. 运行经典脚本 script,并将重新抛出错误参数设置为 true。

      script 将继续运行,直到它返回、解析失败、未能捕获异常或被提前中止,通过上述定义的终止工作线程算法。

      如果抛出了异常或脚本被提前中止,则中止所有这些步骤,让异常或中止继续由调用的脚本处理。

Service Workers 是一个运行此算法的规范示例,它使用了自己的执行抓取钩子[SW]

10.3.2 WorkerNavigator 接口

WorkerNavigator

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

navigatorWorkerGlobalScope 接口的属性,必须返回 WorkerNavigator 接口的一个实例,该实例表示用户代理(客户端)的身份和状态:

[Exposed=Worker]
interface WorkerNavigator {};
WorkerNavigator includes NavigatorID;
WorkerNavigator includes NavigatorLanguage;
WorkerNavigator includes NavigatorOnLine;
WorkerNavigator includes NavigatorConcurrentHardware;

10.3.3 WorkerLocation 接口

WorkerLocation

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

WorkerLocation/toString

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera15+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android37+Samsung Internet?Opera Android14+
[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 对象)。

WorkerLocation/href

在所有当前引擎中都支持。

Firefox3.5+Safari4+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

href 的 getter 步骤是返回 thisWorkerGlobalScope 对象url,并进行 序列化

WorkerLocation/origin

在所有当前引擎中都支持。

Firefox29+Safari10+Chrome38+
Opera?Edge79+
Edge (旧版)14+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

origin 的 getter 步骤是返回 origin 的序列化,其为 thisWorkerGlobalScope 对象urlorigin

WorkerLocation/protocol

在所有当前引擎中都支持。

Firefox3.5+Safari4+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

protocol 的 getter 步骤是返回 thisWorkerGlobalScope 对象urlscheme,后跟 ":"。

WorkerLocation/host

在所有当前引擎中都支持。

Firefox3.5+Safari4+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

host 的 getter 步骤是:

  1. urlthisWorkerGlobalScope 对象url

  2. 如果 urlhost 为空,则返回空字符串。

  3. 如果 urlport 为空,则返回 urlhost,并进行 序列化

  4. 返回 urlhost,并进行 序列化,后跟 ":" 和 urlport,并进行 序列化

WorkerLocation/hostname

在所有当前引擎中都支持。

Firefox3.5+Safari4+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

hostname 的 getter 步骤是:

  1. hostthisWorkerGlobalScope 对象urlhost

  2. 如果 host 为空,则返回空字符串。

  3. 返回 host,并进行 序列化

WorkerLocation/port

在所有当前引擎中都支持。

Firefox3.5+Safari4+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

port 的 getter 步骤是:

  1. portthisWorkerGlobalScope 对象urlport

  2. 如果 port 为空,则返回空字符串。

  3. 返回 port,并进行 序列化

WorkerLocation/pathname

在所有当前引擎中都支持。

Firefox3.5+Safari4+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

pathname 的 getter 步骤是返回 URL 路径序列化 的结果,作用于 thisWorkerGlobalScope 对象url

WorkerLocation/search

在所有当前引擎中都支持。

Firefox3.5+Safari4+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

search 的 getter 步骤是:

  1. querythisWorkerGlobalScope 对象urlquery

  2. 如果 query 为空或为空字符串,则返回空字符串。

  3. 返回 "?",后跟 query

WorkerLocation/hash

在所有当前引擎中都支持。

Firefox3.5+Safari4+Chrome4+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

hash 的 getter 步骤是:

  1. fragmentthisWorkerGlobalScope 对象urlfragment

  2. 如果 fragment 为空或为空字符串,则返回空字符串。

  3. 返回 "#",后跟 fragment

11 Worklets

11.1 介绍

本节为非规范性内容。

Worklet 是一种规范基础设施,可以用于在主 JavaScript 执行环境之外运行脚本,而不需要特定的实现模型。

此处指定的 worklet 基础设施不能直接被 Web 开发者使用。相反,其他规范在其基础上构建了可以直接使用的 worklet 类型,专门用于在浏览器实现管道的特定部分运行。

11.1.1 动机

本节为非规范性内容。

允许在渲染或实现管道的其他敏感部分(例如音频输出)添加扩展点是困难的。如果扩展点可以完全访问 Window 上的 API,引擎将不得不放弃先前对这些阶段中可能发生的事情的假设。例如,在布局阶段,渲染引擎假设不会修改 DOM。

此外,在 Window 环境中定义扩展点将限制用户代理在与 Window 对象相同的线程中执行工作。(除非实现了复杂的高开销基础设施,以允许线程安全的 API 以及线程连接保证。)

Worklet 的设计旨在允许扩展点,同时保留用户代理当前依赖的保证。这是通过基于 WorkletGlobalScope 子类的新全局环境实现的。

Worklet 类似于 Web Workers。但是,它们具有以下特点:

由于 worklet 具有相对较高的开销,因此应谨慎使用。由于这一点,预计一个给定的 WorkletGlobalScope 将被多个独立的脚本共享。(这类似于一个 Window 在多个独立脚本之间共享。)

Worklet 是一种通用技术,可以服务于不同的用例。一些 worklet,如 CSS Painting API 中定义的 worklet,提供了扩展点,旨在进行无状态、幂等和短期运行的计算,这些计算在接下来的几个部分中有特殊的考虑。其他如 Web Audio API 中定义的 worklet,则用于有状态、长期运行的操作。[CSSPAINT] [WEBAUDIO]

11.1.2 代码幂等性

某些使用 worklet 的规范旨在允许用户代理通过多线程并行处理工作,或根据需要在线程之间移动工作。在这些规范中,用户代理可能会以 实现定义 的顺序调用 Web 开发者提供的类的方法。

因此,为防止互操作性问题,作者在此类 WorkletGlobalScope 上注册类时,应确保其代码的幂等性。也就是说,类中的方法或方法集在给定特定输入的情况下应产生相同的输出。

本规范使用以下技术来鼓励作者编写幂等的代码:

这些限制共同帮助防止两个不同的脚本使用 全局对象 的属性共享状态。

此外,使用 worklet 并打算允许 实现定义 行为的规范必须遵守以下规则:

11.1.3 推测性评估

某些使用 worklet 的规范可以根据用户代理的状态在 Web 开发者提供的类上调用方法。为了增加线程之间的并发性,用户代理可能会基于潜在的未来状态推测性地调用某个方法。

在这些规范中,用户代理可能会随时调用这些方法,并且使用任何参数,而不仅限于与当前用户代理状态相对应的参数。这种推测性评估的结果不会立即显示,但可以缓存以供用户代理状态与推测状态匹配时使用。这可以增加用户代理与 worklet 线程之间的并发性。

因此,为防止用户代理之间的互操作性风险,在此类 WorkletGlobalScope 上注册类的作者应使其代码无状态。也就是说,调用方法的唯一效果应该是其结果,而不应有任何更新可变状态等副作用。

与鼓励 代码幂等性 的相同技术也鼓励作者编写无状态代码。

11.2 示例

本节为非规范性内容。

在这些示例中,我们将使用一个虚拟的 worklet。Window 对象提供了两个 Worklet 实例,每个实例都在其自己的 FakeWorkletGlobalScope 集合中运行代码:

partial interface Window {
[SameObject, SecureContext] readonly attribute Worklet fakeWorklet1;
[SameObject, SecureContext] readonly attribute Worklet fakeWorklet2;
};

每个 Window 都有两个 Worklet 实例,分别是 fake worklet 1fake worklet 2。这两个实例的 worklet 全局范围类型 都设置为 FakeWorkletGlobalScope,其 worklet 目标类型 设置为 "fakeworklet"。用户代理应为每个 worklet 创建至少两个 FakeWorkletGlobalScope 实例。

"fakeworklet" 实际上不是 Fetch 所规定的有效目标。但这说明了真正的 worklet 通常会有其专属的 worklet 类型特定目标。[FETCH]

fakeWorklet1 的 getter 步骤是返回 thisfake worklet 1

fakeWorklet2 的 getter 步骤是返回 thisfake worklet 2


[Global=(Worklet,FakeWorklet),
Exposed=FakeWorklet,
SecureContext]
interface FakeWorkletGlobalScope : WorkletGlobalScope {
undefined registerFake(DOMString type, Function classConstructor);
};

每个 FakeWorkletGlobalScope 都有一个 已注册类构造函数映射,这是一个 有序映射,初始为空。

registerFake(type, classConstructor) 方法的步骤是将 this已注册类构造函数映射[type] 设置为 classConstructor

11.2.1 加载脚本

本节为非规范性内容。

要将脚本加载到 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 1fake 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!

11.2.2 注册类并调用其方法

本节为非规范性内容。

假设我们虚拟的 worklet 的一个预期用途是允许 Web 开发者自定义布尔值求反的高度复杂过程。他们可能会这样注册他们的自定义:

// script.mjs
registerFake('negation-processor', class {
  process(arg) {
    return !arg;
  }
});
// app.mjs
window.fakeWorklet1.addModule("script.mjs");

为了使用此类已注册的类,虚拟 worklet 的规范可以定义一个 查找 true 的相反值 算法,给定一个 Worklet worklet

  1. 可选地,为 worklet 创建一个 worklet 全局范围

  2. workletGlobalScope 成为 worklet全局范围 之一,以 实现定义 的方式选择。

  3. classConstructor 成为 workletGlobalScope已注册类构造函数映射["negation-processor"]。

  4. classInstance 成为 构造 classConstructor 的结果,无需参数。

  5. function 成为 获取(classInstance, "process") 的结果。重新抛出任何异常。

  6. callback 成为 function 转换为 Web IDL Function 实例的结果。

  7. 返回调用 callback的结果,使用 « true » 和 "rethrow",并将 回调此值 设置为 classInstance

另一种或许更好的规范架构是在注册时,将 "process" 属性提取出来并转换为 Function,作为 registerFake() 方法步骤的一部分。

11.3 基础设施

11.3.1 全局范围

WorkletGlobalScope 的子类用于创建在特定 Worklet 中加载的代码可以执行的 全局对象

[Exposed=Worklet, SecureContext]
interface WorkletGlobalScope {};

其他规范旨在继承 WorkletGlobalScope,增加注册类的 API 以及其他特定于其 worklet 类型的 API。

每个 WorkletGlobalScope 都有一个关联的 模块映射。它是一个 模块映射,最初为空。

11.3.1.1 代理和事件循环

本节为非规范性内容。

每个 WorkletGlobalScope 都包含在其自己的 worklet 代理 中,该代理具有其对应的 事件循环。然而,实际上,这些代理和事件循环的实现预计会与大多数其他代理有所不同。

为每个 WorkletGlobalScope 实例存在一个 worklet 代理,因为理论上,一个实现可以为每个 WorkletGlobalScope 实例使用一个单独的线程,允许这种级别的并行性最好通过代理来完成。然而,由于它们的 [[CanBlock]] 值为 false,因此没有要求代理和线程是 1:1 的关系。这使得实现有自由可以在任何线程上执行加载到 worklet 中的脚本,包括运行来自其他具有 false 的 [[CanBlock]] 的代理代码的线程,例如类似源窗口代理("主线程")的线程。这与 专用worker代理 相反,其 [[CanBlock]] 值为 true 实际上要求它们获得一个专用的操作系统线程。

Worklet 事件循环 也是有些特殊的。它们仅用于与 addModule() 相关联的 任务,用户代理调用作者定义方法的任务,以及 微任务。因此,即使 事件循环处理模型 规定所有事件循环都要持续运行,实现可以使用更简单的策略来实现可观察的等效结果,该策略只是 调用 作者提供的方法,然后依赖于该过程 执行微任务检查点

11.3.1.2 创建和终止

要为 Worklet worklet 创建一个 worklet 全局范围

  1. outsideSettingsworklet相关设置对象

  2. agent 为根据 outsideSettings 获取的 worklet 代理。在该代理中运行这些步骤的其余部分。

  3. realmExecutionContext 为根据 agent 和以下自定义创建的新领域的结果:

  4. workletGlobalScoperealmExecutionContext 的领域组件的 全局对象

  5. insideSettings 为根据 realmExecutionContextoutsideSettings 设置的 worklet 环境设置对象的结果。

  6. pendingAddedModulesworklet已添加模块列表克隆

  7. runNextAddedModule 为以下步骤:

    1. 如果 pendingAddedModules 不为空,则:

      1. moduleURL 为从 pendingAddedModules 出队的结果。

      2. 给定 moduleURLinsideSettingsworkletworklet 目标类型什么是凭证模式?insideSettingsworklet模块响应映射,并在给定 script 时执行以下步骤,获取 worklet 脚本图

        这实际上不会执行网络请求,因为它只会重用 worklet模块响应映射 中的 响应。这一步的主要目的是从 workletGlobalScope 特定的 模块脚本中创建一个新的 响应

        1. 断言script 不为 null,因为获取成功并且源代码在 worklet模块响应映射最初填充时成功解析了 moduleURL

        2. 给定 script运行模块脚本

        3. 运行 runNextAddedModule

      3. 中止这些步骤。
    2. workletGlobalScope 附加outsideSettings全局对象关联 Documentworklet 全局范围 中。

    3. workletGlobalScope 附加worklet全局范围 中。

    4. 运行 insideSettings 指定的 负责的事件循环

  8. 运行 runNextAddedModule

终止一个 worklet 全局范围,给定一个 WorkletGlobalScope workletGlobalScope

  1. eventLoopworkletGlobalScope相关代理事件循环

  2. 如果 eventLoop任务队列 中排队的任何 任务存在,则丢弃它们而不处理它们。

  3. 等待 eventLoop 完成 当前运行的任务

  4. 如果前一步骤在 实现定义的时间段内未完成,则 中止 worklet 中当前运行的脚本

  5. 销毁 eventLoop

  6. 从包含 workletGlobalScopeWorklet全局范围移除 workletGlobalScope

  7. 从包含 workletGlobalScopeDocumentworklet 全局范围移除 workletGlobalScope

11.3.1.3 Worklet 的脚本设置

设置一个 Worklet 环境设置对象,给定一个JavaScript 执行上下文executionContext和一个环境设置对象outsideSettings

  1. origin为一个唯一的不透明的来源

  2. inheritedAPIBaseURLoutsideSettingsAPI 基础 URL

  3. inheritedPolicyContaineroutsideSettings策略容器的克隆

  4. realmexecutionContext的领域组件的值。

  5. workletGlobalScoperealm全局对象

  6. settingsObject为一个新的环境设置对象,其算法定义如下:

    领域执行上下文

    返回executionContext

    模块映射

    返回workletGlobalScope模块映射

    API 基础 URL

    返回inheritedAPIBaseURL

    与从单一资源派生的其他全局对象或工人不同,Worklet 没有主要资源;相反,多个脚本,每个脚本都有自己的 URL,通过 worklet.addModule()加载到全局范围中。因此,这个 API 基础 URL与其他全局对象的 URL 有所不同。然而,目前这并不重要,因为没有可用的 Worklet 代码的 API 使用 API 基础 URL

    来源

    返回origin

    策略容器

    返回inheritedPolicyContainer

    跨源隔离能力

    返回 TODO

    时间来源

    断言:此算法永远不会被调用,因为 时间来源在 Worklet 上下文中不可用。

  7. settingsObjectid设置为新的唯一不透明字符串,将创建 URL设置为inheritedAPIBaseURL,将顶级创建 URL设置为 null,将顶级来源设置为outsideSettings顶级来源,将目标浏览上下文设置为 null,并将活动服务worker设置为 null。

  8. realm的 [[HostDefined]] 字段设置为settingsObject

  9. 返回settingsObject

11.3.2 Worklet

Worklet

支持所有当前引擎。

Firefox76+Safari14.1+Chrome65+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

Worklet 类提供了将模块脚本添加到其关联的 WorkletGlobalScope 的能力。然后用户代理可以在 WorkletGlobalScope 上创建注册的类并调用其方法。

[Exposed=Window, SecureContext]
interface Worklet {
  [NewObject] Promise<undefined> addModule(USVString moduleURL, optional WorkletOptions options = {});
};

dictionary WorkletOptions {
  RequestCredentials credentials = "same-origin";
};

创建 Worklet 实例的规范必须为给定实例指定以下内容:

await worklet.addModule(moduleURL[, { credentials }])

Worklet/addModule

支持所有当前引擎。

Firefox76+Safari14.1+Chrome65+
Opera?Edge79+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

加载并执行由 moduleURL 提供的 模块脚本 到所有 worklet全局范围 中。它还可以根据 worklet 类型在此过程中创建额外的全局范围。返回的 promise 将在脚本成功加载并在所有全局范围中运行后完成。

credentials 选项可以设置为 凭据模式,以修改脚本获取过程。默认值为 "same-origin"。

获取脚本或其依赖项时的任何失败都将导致返回的 promise 被 "AbortError" DOMException 拒绝。解析脚本或其依赖项中的任何错误将导致返回的 promise 被解析时生成的异常拒绝。

Worklet 有一个 列表,其中包含 全局范围 的实例,这些实例包含 Workletworklet 全局范围类型。它最初是空的。

Worklet 有一个 添加的模块列表,它是一个 列表,包含 URL,最初是空的。对该列表的访问应是线程安全的。

Worklet 有一个 模块响应映射,它是一个 有序映射,从 URL 到 "fetching" 或包含 响应 以及代表响应主体的 字节序列元组,这映射最初是空的,并且访问它应是线程安全的。

添加的模块列表模块响应映射 的存在是为了确保在不同时间创建的 WorkletGlobalScope 运行基于相同源文本的等效 模块脚本。这允许透明地创建额外的 WorkletGlobalScope 给作者。

实际上,用户代理不需要使用线程安全的编程技术来实现这些数据结构和查询它们的算法。相反,当调用 addModule() 时,用户代理可以在主线程上获取模块图,并将获取到的源文本(即 模块响应映射 中包含的重要数据)发送到每个具有 WorkletGlobalScope 的线程。

然后,当用户代理为给定的 Worklet 创建一个新的 WorkletGlobalScope 时,它可以简单地将从主线程获取的源文本映射和入口点列表发送到包含新 WorkletGlobalScope 的线程。

addModule(moduleURL, options) 方法步骤如下:

  1. outsideSettings 成为 相关设置对象

  2. moduleURLRecord 成为 编码解析 URL 的结果,给定 moduleURL,相对于 outsideSettings

  3. 如果 moduleURLRecord 失败,则返回 被拒绝的 promise,并带有 "SyntaxError" DOMException

  4. promise 成为一个新的 promise。

  5. 并行运行以下步骤:

    1. 如果 this全局范围 为空,则:

      1. 创建一个 worklet 全局范围,给定 this

      2. 可选地,创建额外的全局范围实例,给定 this,具体取决于特定的 worklet 及其规范。

      3. 在继续之前,等待 创建过程的所有步骤——包括在 worklet 代理 内进行的步骤——完成。

    2. pendingTasks 成为 this全局范围大小

    3. addedSuccessfully 为 false。

    4. 对于每个 workletGlobalScope,在 this全局范围 上,队列一个全局任务,在 网络任务源 上,给定 workletGlobalScope获取 worklet 脚本图,给定 moduleURLRecordoutsideSettingsthisworklet 目标类型options["credentials"],workletGlobalScope相关设置对象this模块响应映射,以及给定 script 的以下步骤:

      只有第一个获取实际上会执行网络请求;其他 WorkletGlobalScope 将重用来自 响应this模块响应映射

      1. 如果 script 为 null,则:

        1. 队列一个全局任务网络任务源 上,给定 this相关全局对象 以执行以下步骤:

          1. 如果 pendingTasks 不是 -1,则:

            1. pendingTasks 设置为 -1。

            2. "AbortError" DOMException 拒绝 promise

        2. 中止这些步骤。

      2. 如果 script重抛错误 不是 null,则:

        1. 队列一个全局任务网络任务源 上,给定 this相关全局对象 以执行以下步骤:

          1. 如果 pendingTasks 不是 -1,则:

            1. pendingTasks 设置为 -1。

            2. script重抛错误 拒绝 promise

        2. 中止这些步骤。

      3. 如果 addedSuccessfully 为 false,则:

        1. moduleURLRecord 添加到 添加的模块列表

        2. addedSuccessfully 设置为 true。

      4. 运行模块脚本,给定 script

      5. 队列一个全局任务网络任务源 上,给定 this相关全局对象 以执行以下步骤:

        1. 如果 pendingTasks 不是 -1,则:

          1. pendingTasks 设置为 pendingTasks - 1。

          2. 如果 pendingTasks 为 0,则解决 promise

  6. 返回 promise

11.3.3 Worklet 的生命周期

Worklet 的生命周期没有特殊考虑;它与其所属的对象(如 Window)的生命周期相绑定。

每个 Document 都有一个 worklet 全局作用域,这是一个 有序集合,包含了 WorkletGlobalScope,初始时为空。

WorkletGlobalScope 的生命周期至少与包含它的 Document 的生命周期相绑定。特别是,销毁 Document终止 对应的 WorkletGlobalScope,并允许其被垃圾回收。

此外,除非对应的 worklet 类型的规范另有说明,用户代理可以随时 终止 给定的 WorkletGlobalScope。例如,如果 worklet 代理事件循环 没有排队的 任务,或者用户代理没有任何计划使用 worklet 的操作,或者用户代理检测到异常操作(如无限循环或超出时间限制的回调),它们可能会终止 worklet。

最后,特定 worklet 类型的规范可以提供有关何时 创建 给定 worklet 类型的 WorkletGlobalScope 的更多详细信息。例如,它们可能会在调用 worklet 代码的特定过程中创建这些作用域,正如 示例 中所示。

12 Web 存储

Web_Storage_API

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android6+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11+

Web_Storage_API/Using_the_Web_Storage_API

12.1 简介

本节为非规范性内容。

本规范引入了两种与 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 获取器提供了对共享状态的访问。本规范未定义在多进程用户代理中的与其他代理集群的交互,作者应假设没有锁机制。例如,站点可能尝试读取一个键的值,递增其值,然后将其写回,使用新值作为会话的唯一标识符;如果站点在两个不同的浏览器窗口中同时执行此操作,可能最终会为两个会话使用相同的“唯一”标识符,可能导致灾难性的后果。

12.2 API

Storage

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android6+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11+

12.2.1 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/length

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android6+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11+

返回键/值对的数量。

storage.key (n)

Storage/key

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android6+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11+

返回第 n 个键的名称,如果 n 大于或等于键/值对的数量,则返回 null。

value = storage.getItem (key)

Storage/getItem

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android6+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11+
value = storage[key]

返回与给定 key 关联的当前值,如果给定 key 不存在,则返回 null。

storage.setItem (key, value)

Storage/setItem

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera10.5 +Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android6+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11+
storage[key] = value

将由 key 标识的键的值设置为 value,如果之前没有为 key 存在键/值对,则创建一个新的键/值对。

如果无法设置新值,则抛出 "QuotaExceededError" DOMException 异常。(设置可能会失败,例如,如果用户已禁用该站点的存储,或者已超出配额。)

在持有等效 Storage 对象的 Window 对象上分派一个 storage 事件。

storage.removeItem (key)

Storage/removeItem

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android6+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11+
delete storage[key]

删除具有给定 key 的键/值对,如果存在具有给定 key 的键/值对。

在持有等效 Storage 对象的 Window 对象上分派一个 storage 事件。

storage.clear()

Storage/clear

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android6+Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11+

删除所有键/值对(如果有的话)。

在持有等效 Storage 对象的 Window 对象上分派一个 storage 事件。

Storage 对象具有以下关联项:

map
一个 storage proxy map
type
"local" 或 "session"。

要对 Storage 对象 storage 进行重新排序,请按 storagemapentries实现定义 的方式重新排序。

虽然不幸,但迭代顺序未定义,并且在大多数变更时可能会更改。

要对 Storage 对象 storage 进行广播,给定 keyoldValuenewValue,请按以下步骤操作:

  1. thisDocument 成为 storage相关全局对象关联 Document

  2. url 成为 thisDocumentURL

  3. remoteStorages 成为所有 Storage 对象,排除以下情况:

    并且,如果 type 是 "session",则其 相关设置对象关联 Document节点可导航可遍历导航thisDocument节点可导航可遍历导航 相同。

  4. 对于每个 remoteStorage 中的 remoteStorages,在 remoteStorage相关全局对象排队一个全局任务DOM 操作任务源 中,给定 remoteStorage相关全局对象,使用 StorageEvent,将 key 初始化为 keyoldValue 初始化为 oldValuenewValue 初始化为 newValueurl 初始化为 url,以及 storageArea 初始化为 remoteStorage

    Document 对象关联的结果 任务 不一定是 完全活动的,但在 事件循环 中,该对象上的事件在 Document 再次变为 完全活动 之前将被忽略。


length 获取步骤是返回 thismap大小

key(index) 方法的步骤为:

  1. 如果 index 大于或等于 thismap大小,则返回 null。

  2. keys 成为运行 获取键 的结果。

  3. 返回 keys[index]。

支持的属性名称Storage 对象 storage 上是运行 获取键 的结果。

getItem(key) 方法的步骤为:

  1. 如果 thismap[key] 不 存在,则返回 null。

  2. 返回 thismap[key]。

setItem(key, value) 方法的步骤为:

  1. oldValue 为 null。

  2. reorder 为 true。

  3. 如果 thismap[key] 存在

    1. 设置 oldValuethismap[key]。

    2. 如果 oldValue value,则返回。

    3. reorder 设置为 false。

  4. 如果 value 无法存储,则抛出 "QuotaExceededError" DOMException 异常。

  5. 设置 thismap[key] 为 value

  6. 如果 reorder 为 true,则 重新排序 this

  7. 广播 this,带有 keyoldValuevalue

removeItem(key) 方法的步骤为:

  1. 如果 thismap[key] 不 存在,则返回 null。

  2. oldValue 设置为 thismap[key]。

  3. 移除 thismap[key]。

  4. 重新排序 this

  5. 广播 this,带有 keyoldValue 和 null。

clear() 方法的步骤为:

  1. 清除 thismap

  2. 广播 this,带有 null、null 和 null。

12.2.2 sessionStorage 获取器

interface mixin WindowSessionStorage {
  readonly attribute Storage sessionStorage;
};
Window includes WindowSessionStorage;
window.sessionStorage

Window/sessionStorage

支持所有当前引擎。

Firefox2+Safari4+Chrome4+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11+

返回与该 window 的源关联的 Storage 对象的会话存储区域。

如果 Document不透明的源 或者请求违反了某项策略决定(例如,如果用户代理被配置为不允许页面持久化数据),则抛出 "SecurityError" DOMException

Document 对象有一个关联的 会话存储持有者,它可以为 null 或一个 Storage 对象。它最初为 null。

sessionStorage 获取器的步骤如下:

  1. 如果 this关联 Document会话存储持有者 非 null,则返回 this关联 Document会话存储持有者

  2. map 成为使用 this相关设置对象 和 "sessionStorage" 运行 获取会话存储瓶映射 的结果。

  3. 如果 map 失败,则抛出 "SecurityError" DOMException

  4. storage 成为一个新的 Storage 对象,其 mapmap

  5. this关联 Document会话存储持有者 设置为 storage

  6. 返回 storage

创建一个新的辅助浏览上下文和文档后,会话存储将被复制

12.2.3 localStorage 获取器

interface mixin WindowLocalStorage {
  readonly attribute Storage localStorage;
};
Window includes WindowLocalStorage;
window.localStorage

Window/localStorage

支持所有当前引擎。

Firefox3.5+Safari4+Chrome4+
Opera10.5+Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11+

返回与 window 的源关联的 Storage 对象的本地存储区域。

如果 Document不透明的源 或者请求违反了某项策略决定(例如,如果用户代理被配置为不允许页面持久化数据),则抛出 "SecurityError" DOMException

Document 对象有一个关联的 本地存储持有者,它可以为 null 或一个 Storage 对象。它最初为 null。

localStorage 获取器的步骤如下:

  1. 如果 this关联 Document本地存储持有者 非 null,则返回 this关联 Document本地存储持有者

  2. map 成为使用 this相关设置对象 和 "localStorage" 运行 获取本地存储瓶映射 的结果。

  3. 如果 map 失败,则抛出 "SecurityError" DOMException

  4. storage 成为一个新的 Storage 对象,其 mapmap

  5. this关联 Document本地存储持有者 设置为 storage

  6. 返回 storage

12.2.4 StorageEvent 接口

StorageEvent

支持所有当前引擎。

Firefox13+Safari4+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android12.1+
[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对象。

keyoldValuenewValueurl,和storageArea属性必须返回它们初始化时的值。

initStorageEvent(type, bubbles, cancelable, key, oldValue, newValue, url, storageArea)方法必须以类似于initEvent()方法的方式初始化事件。[DOM]

12.3 隐私

12.3.1 用户追踪

第三方广告商(或任何能够将内容分发到多个网站的实体)可以使用存储在其本地存储区域中的唯一标识符来跨多个会话追踪用户,从而建立用户兴趣的档案,以便进行高度定向的广告投放。与能够识别用户真实身份的网站(例如需要认证凭据的电子商务网站)相结合,这可能会让压制性团体比在纯匿名的网页浏览环境中更准确地定位个人。

有许多技术可以用来减轻用户追踪的风险:

阻止第三方存储

用户代理可以限制访问 localStorage 对象的脚本,仅限于源自 顶层文档的域。例如,拒绝访问其他域的页面中运行在 iframe 中的 API。

使存储数据过期

用户代理可以(可能通过用户配置的方式)在一段时间后自动删除存储的数据。

例如,用户代理可以被配置为将第三方本地存储区域视为仅限会话存储,在用户关闭所有能够访问该存储的可导航元素后删除数据。

这可以限制网站追踪用户的能力,因为网站只能在用户通过自身进行身份验证(例如通过购买或登录服务)时跨多个会话追踪用户。

然而,这也降低了 API 作为长期存储机制的实用性。如果用户不完全理解数据过期的含义,也可能使用户的数据面临风险。

将持久性存储视为 Cookie

如果用户尝试通过清除 Cookie 来保护隐私,但没有同时清除本地存储区域中的数据,网站可以通过将这两项功能作为彼此的冗余备份来破坏这些尝试。用户代理应以帮助用户理解这一可能性的方式呈现清除这些存储的界面,并使其能够同时删除所有持久性存储功能中的数据。[COOKIES]

站点特定的本地存储访问白名单

用户代理可以允许站点在不受限制的情况下访问会话存储区域,但要求用户授权访问本地存储区域。

存储数据的来源追踪

用户代理可以记录导致数据存储的第三方来源的来源

如果这些信息用于呈现当前持久性存储中的数据视图,用户将能够对持久性存储中的哪些部分进行裁剪做出明智的决定。结合阻止列表(“删除此数据并防止此域名再次存储数据”),用户可以将持久性存储的使用限制为他们信任的站点。

共享阻止列表

用户代理可以允许用户共享其持久存储域的阻止列表。

这将允许社区共同行动来保护他们的隐私。

虽然这些建议可以防止API被轻易用于用户追踪,但它们并不能完全阻止这种行为。在单一域名内,网站仍然可以在会话期间追踪用户,并且可以将所有这些信息与任何身份信息(如姓名、信用卡号码、地址)一起传递给第三方。如果第三方与多个网站合作获取这些信息,仍然可以创建一个用户档案。

然而,用户追踪在某种程度上是可能的,即使没有用户代理的任何合作,例如通过在 URL 中使用会话标识符,这种技术已经广泛用于无害的目的,但很容易被重新利用来进行用户追踪(甚至是事后追踪)。然后可以将这些信息与其他网站共享,使用访问者的IP地址和其他用户特定的数据(如用户代理头和配置设置)将独立的会话合并成连贯的用户档案。

12.3.2 数据的敏感性

用户代理应将持久存储的数据视为可能敏感的;例如,电子邮件、日历预约、健康记录或其他机密文件都有可能存储在此机制中。

为此,用户代理应确保在删除数据时,数据能够从底层存储中及时删除。

12.4 安全性

12.4.1 DNS 欺骗攻击

由于存在 DNS 欺骗攻击的可能性,不能保证声称来自某个域的主机确实来自该域。为减轻这种风险,页面可以使用 TLS。使用 TLS 的页面可以确保只有用户、代表用户工作的软件,以及其他使用 TLS 且拥有证明它们来自同一域的证书的页面,能够访问它们的存储区域。

12.4.2 跨目录攻击

共享同一主机名的不同作者,例如在已关闭的 geocities.com 上托管内容的用户,都会共享一个本地存储对象。没有功能可以按路径名限制访问。因此,共享主机的作者被敦促避免使用这些功能,因为其他作者很容易读取和覆盖这些数据。

即使提供了路径限制功能,通常的 DOM 脚本安全模型也能轻易绕过这种保护,从任何路径访问数据。

12.4.3 实现风险

在实现这些持久存储功能时,主要的风险有两个:让恶意网站读取其他域的信息,以及让恶意网站写入其他域的数据。

允许第三方网站读取不应从其域读取的数据会导致信息泄漏。例如,一个域的用户购物愿望清单可能被另一个域用于定向广告;或者一个用户在文字处理网站上存储的进行中的机密文件可能被竞争公司的网站查看。

允许第三方网站将数据写入其他域的持久存储可能导致信息欺骗,这同样危险。例如,恶意网站可能向用户的愿望清单中添加项目;或者恶意网站可能将用户的会话标识符设置为已知 ID,然后利用该 ID 跟踪用户在受害网站上的操作。

因此,严格遵循本规范中描述的模型对于用户安全至关重要。

13 HTML 语法

本节仅描述标记为 HTML MIME 类型 的资源的规则。XML 资源的规则将在下方名为 "XML 语法" 的部分中讨论。

13.1 编写 HTML 文档

本节仅适用于文档、创作工具和标记生成器。特别地,它不适用于一致性检查器;一致性检查器必须使用下一节(“解析 HTML 文档”)中给出的要求。

文档必须由以下部分按给定顺序组成:

  1. 可选的一个 U+FEFF 字节顺序标记 (BOM) 字符。
  2. 任意数量的 注释ASCII 空白符
  3. 一个 DOCTYPE
  4. 任意数量的 注释ASCII 空白符
  5. 一个 文档元素,以 html 元素 的形式出现。
  6. 任意数量的 注释ASCII 空白符

上面提到的各种内容类型将在接下来的几节中进行描述。

此外,还有一些关于如何序列化 字符编码声明 的限制,如该主题的章节中所讨论的。

html 元素之前的 ASCII 空白符,在 html 元素的开始以及 head 元素之前的 ASCII 空白符将在文档解析时被删除;html 元素之后的 ASCII 空白符将被解析为如果它们位于 body 元素的末尾。因此,围绕文档元素的 ASCII 空白符 并不会被原样保存。

建议在 DOCTYPE 之后、在文档元素之前的任何注释之后、html 元素的开始标签之后(如果它未被 省略),以及 html 元素内的任何注释之后、在 head 元素之前插入换行符。

HTML 语法中的许多字符串(例如元素及其属性的名称)是大小写不敏感的,但仅限于 ASCII 大写字母ASCII 小写字母。为了方便起见,在本节中,这只是被简单地称为“大小写不敏感”。

13.1.1 DOCTYPE

DOCTYPE 是一个必需的前言。

由于历史原因,DOCTYPE 是必需的。如果省略,浏览器往往会使用与某些规范不兼容的不同渲染模式。在文档中包含 DOCTYPE 可确保浏览器尽最大努力遵循相关规范。

DOCTYPE 必须按以下顺序由以下组件组成:

  1. 与字符串 "<!DOCTYPE" ASCII 大小写不敏感 匹配的字符串。
  2. 一个或多个 ASCII 空白符
  3. 与字符串 "html" ASCII 大小写不敏感 匹配的字符串。
  4. 可选的一个 DOCTYPE 旧版字符串
  5. 零个或多个 ASCII 空白符
  6. 一个 U+003E 大于号字符 (>)。

换句话说,<!DOCTYPE html>,大小写不敏感。


对于无法输出带有简短 DOCTYPE "<!DOCTYPE html>" 的 HTML 标记的 HTML 生成器,可以在 DOCTYPE 中插入一个 DOCTYPE 旧版字符串(在上面定义的位置)。该字符串必须由以下内容组成:

  1. 一个或多个 ASCII 空白符
  2. 与字符串 "SYSTEM" ASCII 大小写不敏感 匹配的字符串。
  3. 一个或多个 ASCII 空白符
  4. 一个 U+0022 双引号或 U+0027 撇号字符(即 引号)。
  5. 字面字符串 "about:legacy-compat"。
  6. 一个匹配的 U+0022 双引号或 U+0027 撇号字符(即与前一步中的 引号 相同的字符)。

换句话说,<!DOCTYPE html SYSTEM "about:legacy-compat"><!DOCTYPE html SYSTEM 'about:legacy-compat'>,引号中的部分大小写敏感。

除非文档是由无法输出较短字符串的系统生成的,否则不应使用 DOCTYPE 旧版字符串

13.1.2 元素

有六种不同类型的元素空元素template 元素原始文本元素可转义的原始文本元素外部元素普通元素

空元素
areabasebrcolembedhrimginputlinkmetasourcetrackwbr
template 元素
template
原始文本元素
scriptstyle
可转义的原始文本元素
textareatitle
外部元素
来自 MathML 命名空间SVG 命名空间 的元素。
普通元素
所有其他允许的 HTML 元素 都是普通元素。

标签 用于在标记中分隔元素的开始和结束。原始文本可转义的原始文本普通 元素有一个开始标签,表示它们的开始,并且有一个结束标签,表示它们的结束。某些普通元素的开始和结束标签可以省略,如在下面的“可选标签”部分所述。那些不能省略的标签不应省略。空元素 只有一个开始标签;对于空元素,不得指定结束标签。外部元素必须要么有一个开始标签和一个结束标签,要么有一个标记为自闭合的开始标签,在这种情况下它们不得有结束标签。

元素的内容必须放在开始标签(某些情况下可能会被隐含)之后和结束标签(同样地,某些情况下可能会被隐含)之前。每个元素允许的具体内容取决于该元素的内容模型,如本规范前面所述。元素不得包含内容模型不允许的内容。但是,除了这些内容模型对内容施加的限制之外,五种类型的元素还有额外的语法要求。

空元素不能有任何内容(因为没有结束标签,所以无法在开始标签和结束标签之间放置内容)。

template 元素可以有模板内容,但这些模板内容不是template元素本身的子元素。相反,它们存储在一个DocumentFragment中,并与另一个不带浏览上下文Document关联,以避免template内容干扰主Documenttemplate 内容的标记放置在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 语法中,标签名(即使是外部元素的标签名)可以使用任意大小写字母的组合编写,转换为全小写字母后与元素的标签名匹配;标签名不区分大小写。

13.1.2.1 起始标签

起始标签必须具有以下格式:

  1. 起始标签的第一个字符必须是 U+003C 小于号字符(<)。
  2. 起始标签的接下来的几个字符必须是元素的标签名
  3. 如果下一步中有任何属性,则首先必须有一个或多个ASCII 空白字符
  4. 然后,起始标签可以包含多个属性,其语法如下所述。属性之间必须由一个或多个ASCII 空白字符分隔。
  5. 在属性之后,或者在没有属性的情况下,在标签名之后,可能会有一个或多个ASCII 空白字符。(某些属性要求后面跟着空格。详见下文属性部分。)
  6. 然后,如果元素是空元素之一,或者如果元素是外部元素,则可能会有一个 U+002F 斜杠字符(/),在外部元素中标记起始标签为自闭合。在空元素中,它不会标记起始标签为自闭合,而是没有任何效果。对于此类空元素,建议谨慎使用,尤其是在直接前面有一个未引用的属性值时,它将成为属性值的一部分,而不是被解析器丢弃。
  7. 最后,起始标签必须由 U+003E 大于号字符(>)关闭。
13.1.2.2 结束标签

结束标签必须具有以下格式:

  1. 结束标签的第一个字符必须是 U+003C 小于号字符(<)。
  2. 结束标签的第二个字符必须是 U+002F 斜杠字符(/)。
  3. 结束标签的接下来的几个字符必须是元素的标签名
  4. 在标签名之后,可能会有一个或多个ASCII 空白字符
  5. 最后,结束标签必须由 U+003E 大于号字符(>)关闭。
13.1.2.3 属性

属性在元素的起始标签中表达。

属性有一个名称和一个值。属性名称必须由一个或多个字符组成,且这些字符不能是控制字符、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 2MathML);本节仅描述这些属性在HTML语法中的序列化规则。

13.1.2.4 可选标签

某些标签可以被省略

在下述情形中省略元素的起始标签并不意味着该元素不存在;它被隐式表示,但仍然存在。例如,一个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 元素内的第一个内容是 metanoscriptlinkscriptstyletemplate 元素。

一个 body 元素的结束标签可以省略,如果 body 元素后面没有紧跟着注释

注意,在上面的示例中,head 元素的开始和结束标签,以及 body 元素的开始标签,不能省略,因为它们被空白字符包围:

<!DOCTYPE HTML>
<html>
  <head>
    <title>Hello</title>
  </head>
  <body>
    <p>Welcome to this example.</p>
  </body>
</html>

bodyhtml 元素的结束标签可以毫无问题地省略;在这些标签之后的任何空白字符都会被解析到 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元素紧接着的是addressarticleasideblockquotedetailsdialogdivdlfieldsetfigcaptionfigurefooterformh1h2h3h4h5h6headerhgrouphrmainmenunavolppresearchsectiontableul元素,或者父元素中不再有其他内容,且父元素是一个不是aaudiodelinsmapnoscriptvideoHTML 元素,或不是自主自定义元素

因此我们可以进一步简化前面的示例:

<!DOCTYPE HTML><title>Hello</title><p>Welcome to this example.

一个 rt 元素的结束标签可以省略,如果 rt 元素后面紧跟着另一个 rtrp 元素,或者父元素中没有更多内容。

一个 rp 元素的结束标签可以省略,如果 rp 元素后面紧跟着一个 rtrp 元素,或者父元素中没有更多内容。

一个 optgroup 元素的结束标签可以省略,如果 optgroup 元素后面紧跟着另一个 optgroup 元素,如果它后面紧跟着一个 hr 元素,或者父元素中没有更多内容。

一个 option 元素的结束标签可以省略,如果 option 元素后面紧跟着另一个 option 元素,如果它后面紧跟着一个 optgroup 元素,如果它后面紧跟着一个 hr 元素,或者父元素中没有更多内容。

一个 colgroup 元素的开始标签可以省略,如果 colgroup 元素内的第一个内容是 col 元素,并且该元素前面没有紧跟着另一个 colgroup 元素,其结束标签已被省略。(如果该元素为空,则不能省略。)

一个 colgroup 元素的结束标签可以省略,如果 colgroup 元素后面没有紧跟着ASCII空白字符注释

一个 caption 元素的结束标签可以省略,如果 caption 元素后面没有紧跟着ASCII空白字符注释

一个 thead 元素的结束标签可以省略,如果 thead 元素后面紧跟着一个 tbodytfoot 元素。

一个 tbody 元素的开始标签可以省略,如果 tbody 元素内的第一个内容是 tr 元素,并且该元素前面没有紧跟着一个 tbodytheadtfoot 元素,其结束标签已被省略。(如果该元素为空,则不能省略。)

一个 tbody 元素的结束标签可以省略,如果 tbody 元素后面紧跟着一个 tbodytfoot 元素,或者父元素中没有更多内容。

一个 tfoot 元素的结束标签可以省略,如果父元素中没有更多内容。

一个 tr 元素的结束标签可以省略,如果 tr 元素后面紧跟着另一个 tr 元素,或者父元素中没有更多内容。

一个 td 元素的结束标签可以省略,如果 td 元素后面紧跟着一个 tdth 元素,或者父元素中没有更多内容。

一个 th 元素的结束标签可以省略,如果 th 元素后面紧跟着一个 tdth 元素,或者父元素中没有更多内容。

省略所有这些与表格相关的标签可以使表格标记简洁得多。

看这个例子:

<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 差异(这是内容模型设计要避免的一部分原因)。

13.1.2.5 内容模型的限制

由于历史原因,某些元素除了其内容模型规定的限制外,还有额外的限制。

一个 table 元素不得包含 tr 元素,尽管根据本规范中描述的内容模型,这些元素在 table 元素内部在技术上是被允许的。(如果在标记中将一个 tr 元素放在 table 中,它实际上会在其前面隐含一个 tbody 开始标签。)

一个单独的换行符可以紧接在 pretextarea 元素的开始标签之后放置。这不会影响元素的处理。如果元素的内容本身以换行符开头,那么必须包括原本可选的换行符(因为否则内容中的首个换行符会被视为可选换行符,并被忽略)。

以下两个 pre 块是等价的:

<pre>Hello</pre>
<pre>
Hello</pre>
13.1.2.6 原始文本和可转义原始文本元素的内容限制

原始文本可转义原始文本元素中的文本不得包含字符串“</”(U+003C 小于号,U+002F 斜杠)后跟与元素标签名称不区分大小写匹配的字符,后面紧跟 U+0009 字符制表符(tab)、U+000A 换行符(LF)、U+000C 进纸符(FF)、U+000D 回车符(CR)、U+0020 空格、U+003E 大于号(>)或 U+002F 斜杠(/)中的一个。

13.1.3 文本

文本 允许出现在元素、属性值和注释中。基于文本的位置,关于文本允许和不允许的内容有额外的限制,如其他部分所述。

13.1.3.1 换行符

HTML中的换行符可以表示为U+000D回车符(CR)字符、U+000A换行符(LF)字符,或按顺序出现的U+000D回车符(CR)、U+000A换行符(LF)字符对。

在允许使用字符引用的地方,U+000A换行符(LF)字符的字符引用(但不是U+000D回车符(CR)字符)也代表一个换行符

13.1.4 字符引用

在其他部分描述的某些情况下,文本可以与字符引用混合使用。这些字符引用可以用于转义在文本中不能合法包含的字符。

字符引用必须以U+0026 &符号字符(&)开头。接下来有三种可能的字符引用类型:

命名字符引用
在&符号后必须跟随命名字符引用部分中给出的名称之一,使用相同的大小写。名称必须以U+003B分号字符(;)终止。
十进制数字字符引用
在&符号后必须跟随U+0023井号字符(#),然后是一个或多个ASCII数字,表示一个对应于下面定义的代码点的十进制整数。数字后必须跟随一个U+003B分号字符(;)。
十六进制数字字符引用
在&符号后必须跟随U+0023井号字符(#),然后跟随U+0078拉丁小写字母x字符(x)或U+0058拉丁大写字母X字符(X),然后是一个或多个ASCII十六进制数字,表示一个对应于下面定义的代码点的十六进制整数。数字后必须跟随一个U+003B分号字符(;)。

上述数字字符引用形式可以引用任何代码点,但排除U+000D CR、非字符和除ASCII空白以外的控制字符

一个模糊的&符号是指后跟一个或多个ASCII字母数字,再跟一个U+003B分号字符(;)的U+0026 &符号字符(&),但这些字符不与命名字符引用部分中的任何名称匹配。

13.1.5 CDATA 部分

CDATA 部分必须由以下组件按顺序组成:

  1. 字符串“<![CDATA[”。
  2. 可选的文本,但文本不得包含字符串“]]>”。
  3. 字符串“]]>”。

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>

13.1.6 注释

注释必须具有以下格式:

  1. 字符串“<!--”。
  2. 可选的文本,但文本不得以字符串“>”开头,也不得以字符串“->”开头,不得包含字符串“<!--”、“-->”或“--!>”,并且不得以字符串“<!-”结尾。
  3. 字符串“-->”。

文本可以以字符串“<!”结尾,例如<!--My favorite operators are > and <!-->

13.2 解析 HTML 文档

本节仅适用于用户代理、数据挖掘工具和符合性检查器。

解析 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。在可能的情况下,对这些元素的引用都链接到了它们的定义。

13.2.1 解析模型概述

HTML 解析过程的输入由一串代码点组成,这些代码点首先经过标记化阶段,然后进入树构建阶段。输出是一个文档对象。

不支持脚本的实现实际上不需要创建一个 DOM 文档对象,但在这种情况下,DOM 树仍然作为规范其余部分的模型使用。

在常见情况下,标记化阶段处理的数据来自网络,但它也可以来自在用户代理中运行的脚本,例如使用document.write() API。

标记化阶段和树构建阶段只有一组状态,但树构建阶段是可重入的,这意味着当树构建阶段处理一个标记时,标记器可能会恢复,导致在第一个标记的处理完成之前发出并处理更多的标记。

在以下示例中,树构建阶段将在处理“script”结束标签标记时被调用来处理一个“p”开始标签标记:

...
<script>
 document.write('<p>');
</script>
...

为了处理这些情况,解析器有一个脚本嵌套级别,其初始值必须设为零,以及一个解析器暂停标志,其初始值必须设为 false。

13.2.2 解析错误

本规范定义了HTML文档的解析规则,无论其语法是否正确。解析算法中的某些点被称为解析错误。解析错误的处理是明确的(即本规范中描述的处理规则),但用户代理在解析HTML文档时,可以在遇到的第一个他们不想应用本规范中描述的规则的解析错误时中止解析器。

如果文档中存在一个或多个解析错误情况,符合性检查器必须至少报告一个解析错误情况;如果文档中不存在解析错误情况,则不得报告任何解析错误情况。如果文档中存在多个解析错误情况,符合性检查器可以报告多个解析错误情况。

解析错误只是HTML语法上的错误。除了检查解析错误外,符合性检查器还将验证文档是否遵守本规范中描述的所有其他符合性要求。

某些解析错误有专门的代码,在报告中应由符合性检查器使用。

下表中的错误描述是非规范性的。

代码 描述
abrupt-closing-of-empty-comment

当解析器遇到一个由U+003E(>)码点(即<!--><!--->)突然关闭的空注释时,会发生此错误。解析器的行为是好像注释已正确关闭。

abrupt-doctype-public-identifier

当解析器在DOCTYPE公共标识符中遇到U+003E(>)码点时(例如<!DOCTYPE html PUBLIC "foo>),会发生此错误。在这种情况下,如果DOCTYPE正确地作为文档前言放置,解析器将文档Document设置为怪异模式

abrupt-doctype-system-identifier

当解析器在DOCTYPE系统标识符中遇到U+003E(>)码点时(例如<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "foo>),会发生此错误。在这种情况下,如果DOCTYPE正确地作为文档前言放置,解析器将Document设置为怪异模式

absence-of-digits-in-numeric-character-reference

当解析器遇到不包含任何数字的数字字符引用时(例如&#qux;),会发生此错误。在这种情况下,解析器不会解析字符引用。

cdata-in-html-content

当解析器在非外部内容(SVG或MathML)中遇到CDATA部分时,会发生此错误。解析器将这些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

当解析器遇到带有属性结束标签时,会发生此错误。结束标签中的属性被忽略,不会进入DOM。

end-tag-with-trailing-solidus

当解析器遇到在关闭U+003E(>)码点之前带有U+002F(/)的结束标签时(例如</div/>),会发生此错误。此类标签被视为常规结束标签。

eof-before-tag-name

当解析器在应出现标记名称的位置遇到输入流的结束时,会发生此错误。在这种情况下,解析器将开始标签的开始(即<)或结束标签(即</)视为文本内容。

eof-in-cdata

当解析器在CDATA部分中遇到输入流的结束时,会发生此错误。解析器将此类CDATA部分视为在输入流结束之前立即关闭。

eof-in-comment

当解析器在注释中遇到输入流的结束时,会发生此错误。解析器将此类注释视为在输入流结束之前立即关闭。

eof-in-doctype

当解析器在DOCTYPE中遇到输入流的结束时,会发生此错误。在这种情况下,如果DOCTYPE正确地作为文档前言放置,解析器将Document设置为怪异模式

eof-in-script-html-comment-like-text

当解析器在输入流中遇到类似于HTML注释的文本时,会发生此错误,而这些文本位于script元素内容内(例如<script><!-- foo)。

script元素中类似HTML注释的语法结构被解析为文本内容。如果脚本语言支持,它们可以是脚本语言特定语法结构的一部分,或者被视为类似HTML的注释(例如,HTML类似注释的解析规则可以在JavaScript规范的附录B中找到)。此错误的常见原因是违反了script元素内容的限制[JAVASCRIPT]

eof-in-tag

当解析器在输入流中遇到开始标签结束标签(例如<div id=)的结束时,会发生此错误。此类标签将被忽略。

incorrectly-closed-comment

当解析器遇到由"--!>"码点序列关闭的注释时,会发生此错误。解析器将此类注释视为由"-->"码点序列正确关闭。

incorrectly-opened-comment

当解析器遇到"<!"码点序列且后面没有紧跟两个U+002D(-)码点,也不是DOCTYPECDATA部分的开始时,会发生此错误。所有跟随"<!"码点序列的内容,直到U+003E(>)码点(如果存在)或输入流的结束,都会被视为注释。

此错误的一个可能原因是在HTML中使用了XML标记声明(例如<!ELEMENT br EMPTY>)。

invalid-character-sequence-after-doctype-name

当解析器在码点序列中遇到除"PUBLIC"和"SYSTEM"关键字之外的其他内容时,会发生此错误。在这种情况下,解析器忽略所有后续的公共或系统标识符,并且如果DOCTYPE正确地作为文档前言放置,并且解析器无法更改模式标志为false时,将Document设置为怪异模式

invalid-first-character-of-tag-name

当解析器在预期开始标签名称的第一个码点或结束标签名称的第一个码点处遇到不是ASCII字母码点时,会发生此错误。如果预期是开始标签,则该码点和前面的U+003C(<)被视为文本内容,所有后续内容被视为标记。如果预期是结束标签,则该码点和所有后续内容直到U+003E(>)码点(如果存在)或输入流的结束,都会被视为注释。

例如,考虑以下标记:

<42></42>

这将被解析为:

虽然标签名称的第一个码点被限制为ASCII字母,但在后续位置允许使用广泛的码点(包括ASCII数字)。

missing-attribute-value

当解析器在应出现属性值的位置遇到U+003E(>)码点时(例如<div id=>),会发生此错误。解析器将该属性视为具有空值。

missing-doctype-name

当解析器遇到缺少名称的DOCTYPE时(例如<!DOCTYPE>),会发生此错误。在这种情况下,如果DOCTYPE正确地作为文档前言放置,解析器将Document设置为怪异模式

missing-doctype-public-identifier

当解析器在应出现DOCTYPE公共标识符的地方遇到U+003E(>)码点时(例如<!DOCTYPE html PUBLIC >),会发生此错误。在这种情况下,如果DOCTYPE正确地作为文档前言放置,解析器将Document设置为怪异模式

missing-doctype-system-identifier

当解析器在应出现DOCTYPE系统标识符的地方遇到U+003E(>)码点时(例如<!DOCTYPE html SYSTEM >),会发生此错误。在这种情况下,如果DOCTYPE正确地作为文档前言放置,解析器将Document设置为怪异模式

missing-end-tag-name

当解析器在应出现结束标签名称的位置遇到U+003E(>)码点时,即</>,会发生此错误。解析器会忽略整个"</>"码点序列。

missing-quote-before-doctype-public-identifier

当解析器遇到前面没有引号的DOCTYPE公共标识符时(例如<!DOCTYPE html PUBLIC -//W3C//DTD HTML 4.01//EN">),会发生此错误。在这种情况下,解析器忽略公共标识符,如果DOCTYPE正确地作为文档前言放置,则将Document设置为怪异模式

missing-quote-before-doctype-system-identifier

当解析器遇到前面没有引号的DOCTYPE系统标识符时(例如<!DOCTYPE html SYSTEM http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">),会发生此错误。在这种情况下,解析器忽略系统标识符,如果DOCTYPE正确地作为文档前言放置,则将Document设置为怪异模式

missing-semicolon-after-character-reference

当解析器遇到未以U+003B(;)码点终止的字符引用时,会发生此错误。通常,解析器的行为是字符引用由U+003B(;)码点终止;然而,在某些模糊情况下,解析器会将后续的码点包括在字符引用中。

例如,&not;in将解析为"¬in",而&notin将解析为""。

missing-whitespace-after-doctype-public-keyword

当解析器遇到其"PUBLIC"关键字和公共标识符之间没有ASCII空白DOCTYPE时,会发生此错误。在这种情况下,解析器的行为就像存在ASCII空白一样。

missing-whitespace-after-doctype-system-keyword

当解析器遇到其"SYSTEM"关键字和系统标识符之间没有ASCII空白DOCTYPE时,会发生此错误。在这种情况下,解析器的行为就像存在ASCII空白一样。

missing-whitespace-before-doctype-name

当解析器遇到其"DOCTYPE"关键字和名称之间没有ASCII空白DOCTYPE时,会发生此错误。在这种情况下,解析器的行为就像存在ASCII空白一样。

missing-whitespace-between-attributes

当解析器遇到未被属性值分隔的ASCII空白(例如<div id="foo"class="bar">)时,会发生此错误。在这种情况下,解析器的行为就像存在ASCII空白一样。

missing-whitespace-between-doctype-public-and-system-identifiers

当解析器遇到其公共和系统标识符之间没有ASCII空白DOCTYPE时,会发生此错误。在这种情况下,解析器的行为就像存在ASCII空白一样。

nested-comment

当解析器遇到嵌套的注释时(例如<!-- <!-- nested --> -->),会发生此错误。此类注释将由第一次出现的"-->"码点序列关闭,后续的所有内容将被视为标记。

noncharacter-character-reference

当解析器遇到引用非字符的数字字符引用时,会发生此错误。解析器按原样解析此类字符引用。

noncharacter-in-input-stream

输入流包含非字符时,会发生此错误。此类码点按原样解析,并且通常在解析规则不适用其他限制时,会直接进入DOM。

non-void-html-element-start-tag-with-trailing-solidus

当解析器遇到一个开始标签,其元素不在空元素列表中,也不是外部内容(即不是SVG或MathML元素)的一部分,且在关闭的U+003E(>)码点之前带有U+002F(/)码点时,会发生此错误。解析器的行为就像U+002F(/)不存在一样。

例如,考虑以下标记:

<div/><span></span><span></span>

这将被解析为:

开始标签名称中的尾随U+002F(/)只能在外部内容中用于指定自闭合标签。(HTML中不存在自闭合标签。)它也允许用于空元素,但在这种情况下没有任何效果。

null-character-reference

当解析器遇到引用U+0000 NULL字符引用的数字码点时,会发生此错误。解析器将此类字符引用解析为U+FFFD替换字符。

surrogate-character-reference

当解析器遇到引用代理的数字字符引用时,会发生此错误。解析器将此类字符引用解析为U+FFFD替换字符。

surrogate-in-input-stream

输入流包含代理时,会发生此错误。此类码点按原样解析,并且通常在解析规则不适用其他限制时,会直接进入DOM。

代理只能通过脚本API(如document.write())进入输入流。

unexpected-character-after-doctype-system-identifier

当解析器在DOCTYPE系统标识符之后遇到除ASCII空白或关闭的U+003E(>)之外的任何码点时,会发生此错误。解析器会忽略这些码点。

unexpected-character-in-attribute-name

当解析器在属性名称中遇到U+0022(")、U+0027(')或U+003C(<)码点时,会发生此错误。解析器将此类码点包括在属性名称中。

触发此错误的码点通常是另一个语法结构的一部分,可能是属性名称周围的拼写错误的标志。

例如,考虑以下标记:

<div foo<div>

由于在foo之后忘记了U+003E(>)码点,解析器将此标记视为具有"foo<div"属性的单个div元素。

作为此错误的另一个示例,请考虑以下标记:

<div id'bar'>

由于在属性名称和属性值之间忘记了U+003D(=)码点,解析器将此标记视为具有"id'bar'"属性且值为空的div元素。

unexpected-character-in-unquoted-attribute-value

当解析器在未引用的属性值中遇到U+0022(")、U+0027(')、U+003C(<)、U+003D(=)或U+0060(`)码点时,会发生此错误。解析器将此类码点包括在属性值中。

触发此错误的码点通常是另一个语法结构的一部分,可能是属性值周围的拼写错误的标志。

U+0060(`)在触发此错误的码点列表中,因为某些旧版用户代理将其视为引号。

例如,考虑以下标记:

<div foo=b'ar'>

由于U+0027(')码点放错了位置,解析器将"foo"属性的值设置为"b'ar'"。

unexpected-equals-sign-before-attribute-name

当解析器在属性名称之前遇到U+003D(=)码点时,会发生此错误。在这种情况下,解析器将U+003D(=)视为属性名称的第一个码点。

此错误的常见原因是忘记了属性名称。

例如,考虑以下标记:

<div foo="bar" ="baz">

由于忘记了属性名称,解析器将此标记视为具有两个属性的div元素:"foo"属性的值为"bar","="baz""属性的值为空。

unexpected-null-character

当解析器在某些位置的输入流中遇到U+0000 NULL码点时,会发生此错误。通常,此类码点要么被忽略,要么出于安全原因被替换为U+FFFD替换字符。

unexpected-question-mark-instead-of-tag-name

当解析器在应出现开始标签名称的第一个码点的位置遇到U+003F(?)码点时,会发生此错误。U+003F(?)和所有后续内容直到U+003E(>)码点(如果存在)或输入流的结束,将被视为注释。

例如,考虑以下标记:

<?xml-stylesheet type="text/css" href="style.css"?>

这将被解析为:

此错误的常见原因是在HTML中使用XML处理指令(例如<?xml-stylesheet type="text/css" href="style.css"?>)或XML声明(例如<?xml version="1.0" encoding="UTF-8"?>)。

unexpected-solidus-in-tag

当解析器在标记中遇到不是引用属性值的一部分且未紧跟U+003E(>)码点之后的U+002F(/)码点时(例如<div / id="foo">),会发生此错误。在这种情况下,解析器的行为就像遇到ASCII空白一样。

unknown-named-character-reference

当解析器遇到不明确的与号时,会发生此错误。在这种情况下,解析器不会解析字符引用

13.2.3 输入字节流

进入标记化阶段的代码点流最初将由用户代理视为字节流(通常通过网络或从本地文件系统传输)。这些字节根据特定的字符编码对实际字符进行编码,用户代理使用该编码将字节解码为字符。

对于XML文档,要求用户代理使用的确定字符编码的算法由XML定义。本节不适用于XML文档。[XML]

通常,下面定义的编码嗅探算法用于确定字符编码。

给定一个字符编码,输入字节流中的字节必须通过将输入字节流和字符编码传递给解码器来转换为标记化器的输入流中的字符。

前导字节顺序标记(BOM)会导致字符编码参数被忽略,并且BOM本身将被跳过。

原始字节流中不符合编码标准的字节或字节序列(例如UTF-8输入字节流中的无效UTF-8字节序列)是符合性检查器应该报告的错误。[ENCODING]

解码器算法描述了如何处理无效输入;出于安全原因,必须严格遵循这些规则。处理无效字节序列的差异可能导致包括脚本注入漏洞(“XSS”)在内的各种问题。

当HTML解析器解码输入字节流时,它使用字符编码和置信度。置信度可以是暂定的确定的无关紧要的。使用的编码以及该编码的置信度是暂定的还是确定的,在解析期间用于确定是否更改编码。如果不需要编码,例如因为解析器在Unicode流上操作且根本不需要使用字符编码,则置信度是无关紧要的

某些算法通过将字符直接添加到输入流中,而不是将字节添加到输入字节流中,来向解析器提供数据。

13.2.3.1 具有已知字符编码的解析

当HTML解析器要在具有已知确定编码的输入字节流上操作时,字符编码就是该编码,并且置信度确定的

13.2.3.2 确定字符编码

在某些情况下,在解析文档之前明确确定编码可能是不切实际的。出于这个原因,本规范提供了具有可选预扫描的两次通过机制。允许实现如下所述,在开始解析文档之前,将简化的解析算法应用于他们所拥有的字节。然后,启动真正的解析器,使用从预解析和其他带外元数据派生的暂定编码。如果在加载文档时,用户代理发现了与该信息冲突的字符编码声明,则可以重新调用解析器,以实际编码重新解析文档。

用户代理必须使用以下算法,即编码嗅探算法,在第一次传递中确定解码文档时要使用的字符编码。该算法将用户代理可用的任何带外元数据(例如文档的Content-Type元数据)和目前可用的所有字节作为输入,并返回一个字符编码和置信度,这个置信度可以是暂定的确定的

  1. 如果BOM嗅探的结果是编码,则返回该编码,并将置信度设置为确定的

    尽管解码算法本身会根据字节顺序标记的存在更改要使用的编码,但该算法也会嗅探BOM,以设置正确的文档的字符编码和置信度。

  2. 如果用户明确指示用户代理用特定编码覆盖文档的字符编码,则可以选择返回该编码,并将置信度设置为确定的

    通常,用户代理会跨会话记住此类用户请求,并且在某些情况下也将它们应用于iframe中的文档。

  3. 用户代理可以等待更多资源字节可用,在此步骤或此算法中的任何后续步骤中。例如,用户代理可能会等待500毫秒或1024个字节,以先到者为准。通常,预解析源以找到编码可以提高性能,因为它减少了在找到编码信息时丢弃解析时使用的数据结构的需求。然而,如果用户代理等待时间过长以获取数据来确定编码,则延迟的成本可能超过预解析带来的性能提升。

    字符编码声明的创作符合性要求将它们限制为只能出现在前1024个字节中。因此,鼓励用户代理在前1024个字节上使用下面的预扫描算法(按照这些步骤调用),但不要延迟超出此范围。

  4. 如果传输层指定了字符编码,并且该编码受到支持,则返回该编码,并将置信度设置为确定的

  5. 可选择预扫描字节流以确定其编码,终止条件为用户代理认为继续扫描字节将不再有效。鼓励用户代理仅预扫描前1024个字节。用户代理可以认为扫描任何字节都无效,在这种情况下,这些子步骤将完全跳过。

    上述算法返回字符编码或失败。如果它返回字符编码,则返回相同的编码,并将置信度设置为暂定的

  6. 如果与此算法关联的HTML解析器关联的Document d容器文档不为空,则:

    1. parentDocument设为d容器文档

    2. 如果parentDocumentd同源,并且parentDocument字符编码不是UTF-16BE/LE,则返回parentDocument字符编码,置信度为暂定的

  7. 否则,如果用户代理有关于该页面可能编码的信息,例如基于上次访问页面时的编码,则返回该编码,并将置信度设置为暂定的

  8. 用户代理可以尝试通过对数据流应用频率分析或其他算法自动检测字符编码。此类算法可以使用有关资源的其他信息,而不仅仅是资源的内容,包括资源的地址。如果自动检测成功确定字符编码,并且该编码是受支持的编码,则返回该编码,并将置信度设置为暂定的[UNIVCHARDET]

    通常不鼓励用户代理尝试对通过网络获取的资源进行自动检测编码,因为这样做涉及固有的不互通启发式方法。基于HTML文档的前言尝试检测编码特别棘手,因为HTML标记通常仅使用ASCII字符,而HTML文档通常以大量标记开始,而不是文本内容。

    UTF-8编码具有高度可检测的位模式。包含值大于0x7F的字节且与UTF-8模式匹配的本地文件系统中的文件很可能是UTF-8,而包含不匹配字节序列的文档则很可能不是。当用户代理可以检查整个文件,而不仅仅是前言时,专门检测UTF-8特别有效。[PPUTF8] [UTF8DET]

  9. 否则,返回一个实现定义的或用户指定的默认字符编码,置信度为暂定的

    在受控环境中或可以规定文档编码的环境中(例如,旨在专用新网络中使用的用户代理),建议使用全面的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编码,应用于与预扫描字节流以确定其编码算法应用于相同的字节。否则,这些步骤将返回一个字符编码。

  1. fallback encoding为null。

  2. position为指向输入字节流中一个字节的指针,最初指向第一个字节。

  3. 预扫描UTF-16 XML声明:如果position指向:

    以0x3C, 0x0, 0x3F, 0x0, 0x78, 0x0开头的一系列字节(区分大小写的UTF-16小端序'<?x')

    返回UTF-16LE

    以0x0, 0x3C, 0x0, 0x3F, 0x0, 0x78开头的一系列字节(区分大小写的UTF-16大端序'<?x')

    返回UTF-16BE

    出于历史原因,前缀比XML附录F中的前缀多两个字节,并且不检查编码名称。

  4. 循环:如果position指向:

    以0x3C 0x21 0x2D 0x2D(`<!--`)开头的一系列字节

    position指针前移,使其指向前面有两个0x2D字节并位于找到的0x3C字节之后的第一个0x3E字节(即在ASCII'-->'序列的末尾)。(这两个0x2D字节可以与'<!--'序列中的相同。)

    以0x3C, 0x4D或0x6D, 0x45或0x65, 0x54或0x74, 0x41或0x61, 以及0x09, 0x0A, 0x0C, 0x0D, 0x20, 0x2F之一(不区分大小写的ASCII'<meta'后跟空格或斜杠)开头的一系列字节
    1. position指针前移,使其指向下一个0x09, 0x0A, 0x0C, 0x0D, 0x20或0x2F字节(与上面匹配的字符序列中的那个字节)。

    2. attribute list为空字符串列表。

    3. got pragma为false。

    4. need pragma为null。

    5. charset为null值(在此算法中,这与未识别的编码或空字符串不同)。

    6. 属性获取属性及其值。如果没有获取到属性,则跳转到下面的处理步骤。

    7. 如果属性名称已经在attribute list中,则返回属性步骤。

    8. 将属性名称添加到attribute list中。

    9. 运行以下列表中的相应步骤(如果适用):

      如果属性名称是"http-equiv"

      如果属性值是"content-type",则将got pragma设置为true。

      如果属性名称是"content"

      应用meta元素中提取字符编码的算法,将属性值作为解析的字符串。如果返回了一个字符编码,并且charset仍设置为null,则将charset设置为返回的编码,并将need pragma设置为true。

      如果属性名称是"charset"

      charset设为获取编码的结果,取自属性值,并将need pragma设置为false。

    10. 返回属性步骤。

    11. 处理:如果need pragma为null,则跳转到下面标记为下一字节的步骤。

    12. 如果need pragma为true但got pragma为false,则跳转到下面标记为下一字节的步骤。

    13. 如果charset为失败,则跳转到下面标记为下一字节的步骤。

    14. 如果charsetUTF-16BE/LE,则将charset设置为UTF-8

    15. 如果charsetx-user-defined,则将charset设置为windows-1252

    16. 返回charset

    以0x3C字节(<)开头的字节序列,可选的0x2F字节(/),最后是范围0x41-0x5A或0x61-0x7A(A-Z或a-z)中的字节
    1. position指针前移,使其指向下一个0x09(HT)、0x0A(LF)、0x0C(FF)、0x0D(CR)、0x20(SP)或0x3E(>)字节。

    2. 反复获取属性直到找不到更多属性,然后跳转到下面标记为下一字节的步骤。

    以0x3C 0x21 (`<!`)
    以0x3C 0x2F (`</`)
    以0x3C 0x3F (`<?`)

    position指针前移,使其指向找到的0x3C字节之后的第一个0x3E字节(>)。

    任何其他字节

    对该字节不做任何处理。

  5. 下一字节:将position移到输入字节流中的下一个字节,并返回到上面标记为循环的步骤。

预扫描字节流以确定其编码算法要求获取属性时,它的含义如下:

  1. 如果position处的字节是0x09(HT)、0x0A(LF)、0x0C(FF)、0x0D(CR)、0x20(SP)或0x2F(/)之一,则将position前移到下一个字节并重新执行此步骤。

  2. 如果position处的字节是0x3E(>),则中止获取属性算法。不存在属性。

  3. 否则,position处的字节是属性名称的开始。设attribute nameattribute value为空字符串。

  4. 按如下方式处理position处的字节:

    如果是0x3D(=),并且attribute name长度大于空字符串
    position前移到下一个字节并跳转到下面标记为的步骤。
    如果是0x09(HT)、0x0A(LF)、0x0C(FF)、0x0D(CR)或0x20(SP)
    跳转到下面标记为空格的步骤。
    如果是0x2F(/)或0x3E(>)
    中止获取属性算法。属性的名称为attribute name的值,其值为空字符串。
    如果是在范围0x41(A)到0x5A(Z)之间
    将代码点b+0x20追加到attribute name(其中bposition处字节的值)。(这将输入转换为小写。)
    其他任何
    将与position处字节值相同的代码点追加到attribute name。(在此处处理ASCII范围之外的字节实际上无关紧要,因为只有ASCII字节可以用于检测字符编码。)
  5. position前移到下一个字节并返回到上一步骤。

  6. 空格:如果position处的字节是0x09(HT)、0x0A(LF)、0x0C(FF)、0x0D(CR)或0x20(SP)之一,则将position前移到下一个字节,然后重复此步骤。

  7. 如果position处的字节不是0x3D(=),则中止获取属性算法。属性的名称为attribute name的值,其值为空字符串。

  8. position移过0x3D(=)字节。

  9. :如果position处的字节是0x09(HT)、0x0A(LF)、0x0C(FF)、0x0D(CR)或0x20(SP)之一,则将position前移到下一个字节,然后重复此步骤。

  10. 按如下方式处理position处的字节:

    如果是0x22(")或0x27(')
    1. bposition处字节的值。
    2. 引号循环:将position前移到下一个字节。
    3. 如果position处字节的值为b的值,则将position前移到下一个字节并中止"获取属性"算法。属性的名称为attribute name的值,其值为attribute value的值。
    4. 否则,如果position处字节的值在0x41(A)到0x5A(Z)范围内,则将一个代码点追加到attribute value中,其值比position处字节的值大0x20。
    5. 否则,将一个代码点追加到attribute value中,其值与position处字节的值相同。
    6. 返回到上面标记为引号循环的步骤。
    如果是0x3E(>)
    中止获取属性算法。属性的名称为attribute name的值,其值为空字符串。
    如果是在范围0x41(A)到0x5A(Z)之间
    将代码点b+0x20追加到attribute value(其中bposition处字节的值)。将position前移到下一个字节。
    其他任何
    将与position处字节值相同的代码点追加到attribute value中。将position前移到下一个字节。
  11. 按如下方式处理position处的字节:

    如果是0x09(HT)、0x0A(LF)、0x0C(FF)、0x0D(CR)、0x20(SP)或0x3E(>)
    中止获取属性算法。属性的名称为attribute name的值,其值为attribute value的值。
    如果是在范围0x41(A)到0x5A(Z)之间
    将代码点b+0x20追加到attribute value(其中bposition处字节的值)。
    其他任何
    将与position处字节值相同的代码点追加到attribute value
  12. position前移到下一个字节并返回到上一步骤。

预扫描字节流以确定其编码算法在未返回编码的情况下被中止时,获取XML编码的含义如下。

即使在text/html中查找类似XML声明的语法也是为了兼容现有内容。

  1. encodingPosition 为指向流开始的指针。

  2. 如果 encodingPosition 没有指向字节序列 0x3C, 0x3F, 0x78, 0x6D, 0x6C (`<?xml`),则返回失败。

  3. xmlDeclarationEnd 为输入字节流中下一个为 0x3E (>) 的字节指针。如果没有这样的字节,则返回失败。

  4. encodingPosition 设置为在当前 encodingPosition 处或之后的字节子序列 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67 (`encoding`) 的第一次出现的位置。如果没有这样的序列,则返回失败。

  5. encodingPosition 前移超过字节 0x67 (g)。

  6. encodingPosition 处的字节小于或等于 0x20(即它是 ASCII 空格或控制字符)时,将 encodingPosition 前移到下一个字节。

  7. 如果 encodingPosition 处的字节不是 0x3D (=),则返回失败。

  8. encodingPosition 前移到下一个字节。

  9. encodingPosition 处的字节小于或等于 0x20(即它是 ASCII 空格或控制字符)时,将 encodingPosition 前移到下一个字节。

  10. quoteMarkencodingPosition 处的字节。

  11. 如果 quoteMark 不是 0x22 (") 或 0x27 ('),则返回失败。

  12. encodingPosition 前移到下一个字节。

  13. encodingEndPosition 为从 encodingPosition 开始到下一个 quoteMark 出现的位置。如果 quoteMark 不再出现,则返回失败。

  14. potentialEncoding 为介于 encodingPosition(包含)和 encodingEndPosition(不包含)之间的字节序列。

  15. 如果 potentialEncoding 包含一个或多个字节,其字节值为 0x20 或以下,则返回失败。

  16. encoding 为给定 potentialEncoding获取编码的结果, 等值解码后。

  17. 如果 encodingUTF-16BE/LE,则将其更改为 UTF-8

  18. 返回 encoding

为了互操作性,用户代理不应使用返回与上述描述的结果不同的预扫描算法。(但是,如果你这样做,请至少通知我们,这样我们可以改进此算法,造福所有人……)

13.2.3.3 字符编码

用户代理必须支持在编码中定义的编码,包括但不限于UTF-8ISO-8859-2ISO-8859-7ISO-8859-8windows-874windows-1250windows-1251windows-1252windows-1254windows-1255windows-1256windows-1257windows-1258GBKBig5ISO-2022-JPShift_JISEUC-KRUTF-16BEUTF-16LEUTF-16BE/LE,以及x-user-defined。用户代理不得支持其他编码。

上述规定禁止支持例如CESU-8、UTF-7、BOCU-1、SCSU、EBCDIC和UTF-32等编码。本规范不尝试在其算法中支持被禁止的编码;支持和使用被禁止的编码将导致意外行为。[CESU8] [UTF7] [BOCU1] [SCSU]

13.2.3.4 在解析过程中更改编码

当解析器要求用户代理更改编码时,它必须执行以下步骤。这可能发生在编码嗅探算法未能找到字符编码,或找到的字符编码并非文件的实际编码时。

  1. 如果已经用于解释输入流的编码是UTF-16BE/LE,则将置信度设置为确定并返回。新编码被忽略;如果它不是相同的编码,那么它显然是错误的。

  2. 如果新编码是UTF-16BE/LE,则将其更改为UTF-8

  3. 如果新编码是x-user-defined,则将其更改为windows-1252

  4. 如果新编码与已经用于解释输入流的编码相同或等效,则将置信度设置为确定并返回。当文件中找到的编码信息与编码嗅探算法确定的编码匹配时,以及在解析器的第二次通过中,如果第一次通过发现上述编码嗅探算法未能找到正确的编码时,会发生这种情况。

  5. 如果所有字节到当前解码器转换的最后一个字节在当前编码和新编码中的Unicode解释相同,并且如果用户代理支持动态更改转换器,那么用户代理可以动态更改为新编码的转换器。将文档的字符编码和用于转换输入流的编码设置为新编码,将置信度设置为确定,并返回。

  6. 否则,重新启动导航 算法,将historyHandling设置为"替换",其他输入保持不变,但这次跳过编码嗅探算法,而只是将编码设置为新编码,并将置信度设置为确定。只要可能,这应该在不实际联系网络层的情况下完成(字节应该从内存中重新解析),即使例如文档被标记为不可缓存。如果这不可能,并且联系网络层将涉及重复使用非GET方法的请求,那么应将置信度设置为确定并忽略新编码。资源将被误解。用户代理可以通知用户这种情况,以帮助应用程序开发。

此算法仅在在meta元素上找到新编码声明时调用。

13.2.3.5 预处理输入流

输入流由在输入字节流解码时或通过直接操作输入流的各种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"字符并不是流中的真实字符,而是没有任何后续字符的标志。

13.2.4 解析状态

13.2.4.1 插入模式

插入模式是一个控制树构建阶段主要操作的状态变量。

最初,插入模式是"初始"。它可以在解析过程中更改为"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必须按照以下步骤进行:

  1. last为false。

  2. node开放元素栈中的最后一个节点。

  3. 循环:如果node是开放元素栈中的第 一个节点,则将last设置为true,并且如果解析器是作为HTML片段解析算法的一部分创建的(片段情况),则将node设置为传递给该算法的上下文元素。

  4. 如果nodeselect元素,则运行这些子步骤:

    1. 如果last为true,则跳转到下面标记为完成的步骤。

    2. ancestornode

    3. 循环:如果ancestor开放元素栈中的第一个节点,则跳转到下面标记为完成的步骤。

    4. ancestor设为开放元素栈ancestor之前的节点。

    5. 如果ancestor模板节点,则跳转到下面标记为完成的步骤。

    6. 如果ancestortable节点,则将插入模式切换到"在table中的select"并返回。

    7. 跳回到标记为循环的步骤。

    8. 完成:将插入模式切换到"在select中"并返回。

  5. 如果nodetdth元素,并且last为false,则将插入模式切换到"在单元格中"并返回。

  6. 如果nodetr元素,则将插入模式切换到"在行中"并返回。

  7. 如果nodetbodytheadtfoot元素,则将插入模式切换到"在table body中"并返回。

  8. 如果nodecaption元素,则将插入模式切换到"在caption中"并返回。

  9. 如果node列组元素,则将插入模式切换到"在列组中"并返回。

  10. 如果nodetable元素,则将插入模式切换到"在table中"并返回。

  11. 如果node模板元素,则将插入模式切换到当前模板插入模式并返回。

  12. 如果nodehead元素,并且last为false,则将插入模式切换到"在head中"并返回。

  13. 如果nodebody元素,则将插入模式切换到"在body中"并返回。

  14. 如果nodeframeset元素,则将插入模式切换到"在frameset中"并返回。(片段情况

  15. 如果nodehtml元素,则运行这些子步骤:

    1. 如果head元素指针为null,则将插入模式切换到"head之前"并返回。(片段情况

    2. 否则,head元素指针不为null,则将插入模式切换到"head之后"并返回。

  16. 如果last为true,则将插入模式切换到"在body中"并返回。(片段情况

  17. 现在将node设为开放元素栈node之前的节点。

  18. 返回到标记为循环的步骤。

13.2.4.2 打开元素栈

最初,打开元素栈是空的。栈向下增长;栈顶的节点是第一个添加到栈中的节点,而栈底的节点是栈中最近添加的节点(尽管在处理嵌套错误标签的过程中栈会以随机访问的方式操作)。

"html之前"的插入模式会创建html文档元素,然后将其添加到栈中。

片段情况下打开元素栈初始化为包含作为该算法一部分创建的html元素。(片段情况跳过了"html之前"插入模式。)

无论html节点如何创建,它都是栈顶的节点。只有当解析器完成时,它才会从栈中弹出。

当前节点是这个打开元素栈中的栈底节点。

调整后的当前节点是如果解析器是作为HTML片段解析算法的一部分创建的,并且打开元素栈中只有一个元素(片段情况),那么调整后的当前节点是上下文元素;否则,调整后的当前节点就是当前节点

当前节点打开元素栈中移除时,处理内部资源链接给定当前节点节点文档

打开元素栈中的元素分为以下几类:

特殊

以下元素具有不同级别的特殊解析规则:HTML的addressappletareaarticleasidebasebasefontbgsoundblockquotebodybrbuttoncaptioncentercolcolgroupdddetailsdirdivdldtembedfieldsetfigcaptionfigurefooterformframeframeseth1h2h3h4h5h6headheaderhgrouphrhtmliframeimginputkeygenlilinklistingmainmarqueemenumetanavnoembednoframesnoscriptobjectolpparamplaintextprescriptsearchsectionselectsourcestylesummarytabletbodytdtemplatetextareatfootththeadtitletrtrackulwbrxmpMathMLmiMathMLmoMathMLmnMathMLmsMathMLmtextMathMLannotation-xml;以及SVGforeignObjectSVGdescSVGtitle

一个image起始标签标记由树构建器处理,但它不在此列表中,因为它不是一个元素;它被转换为一个img元素。

格式化

以下HTML元素是那些最终出现在活动格式化元素列表中的元素:abbigcodeemfontinobrssmallstrikestrongttu

普通

在解析HTML文档时找到的所有其他元素。

通常,特殊元素具有特定处理开始和结束标签标记的规则,而普通元素的标记则适用于“任何其他开始标签”和“任何其他结束标签”条款,并且树构建器的某些部分会检查打开元素栈中的特定元素是否属于特殊类别。然而,一些元素(例如option元素)虽然其开始或结束标签标记被特定处理,但仍然不属于特殊类别,因此它们在其他地方仍然遵循普通处理。

打开元素栈被称为在特定范围内具有一个元素target node,当以下算法在匹配状态终止时,它包括一个元素类型list

  1. node初始化为当前节点(栈底的节点)。

  2. 如果node是目标节点,则在匹配状态下终止。

  3. 否则,如果nodelist中的元素类型之一,则在失败状态下终止。

  4. 否则,将node设置为打开元素栈中的上一个条目,并返回步骤2。(这永远不会失败,因为如果到达栈顶——一个html元素——循环总会在前一步终止。)

打开元素栈被称为具有特定范围内的某个元素,当它具有该特定范围内的元素,包括以下元素类型:

打开元素栈被称为具有特定列表项范围内的某个元素,当它具有该特定范围内的元素,包括以下元素类型:

打开元素栈被称为具有特定按钮范围内的某个元素,当它具有该特定范围内的元素,包括以下元素类型:

打开元素栈被称为具有特定表格范围内的某个元素,当它具有该特定范围内的元素,包括以下元素类型:

打开元素栈被称为具有特定选择范围内的某个元素,当它具有该特定范围内的元素,包括所有元素类型除外以下:

如果在任何时候打开元素栈中的任何元素被移动到文档树中的新位置或从中移除,什么也不会发生。特别是,栈在这种情况下不会发生变化。这可能会导致,除了其他奇怪的效果之外,内容被附加到已不再存在于DOM中的节点上。

在某些情况下(即在关闭嵌套错误的格式化元素时),栈以随机访问的方式操作。

13.2.4.3 活动格式化元素列表

最初,活动格式化元素列表为空。该列表用于处理格式化元素标签的嵌套错误。

该列表包含格式化类别中的元素和标记标记是在进入appletobjectmarqueetemplatetdthcaption元素时插入的,用于防止格式化“泄漏”这些元素中。

此外,活动格式化元素列表中的每个元素都与创建它的令牌相关联,因此如果有必要,可以为该令牌创建更多元素。

当以下步骤要求UA将元素推入活动格式化元素列表时,UA必须执行以下步骤:

  1. 如果在最后一个标记之后(如果有)或列表中(如果没有标记)已经有三个具有与element相同的标签名、命名空间和属性的元素,则删除活动格式化元素列表中最早的该类元素。为此,属性必须在元素由解析器创建时进行比较;如果它们的所有解析属性都可以配对,并且每对中的两个属性具有相同的名称、命名空间和值(属性的顺序无关紧要),则两个元素具有相同的属性。

    这是诺亚方舟条款,只是每个家族是三个而不是两个。

  2. element添加到活动格式化元素列表中。

当以下步骤要求UA重构活动格式化元素时,UA必须执行以下步骤:

  1. 如果活动格式化元素列表中没有条目,则无内容重构;停止执行该算法。

  2. 如果活动格式化元素列表中的最后一个(最近添加的)条目是一个标记,或如果它是打开元素栈中的一个元素,则无内容重构;停止执行该算法。

  3. entry为活动格式化元素列表中的最后一个(最近添加的)元素。

  4. 倒带:如果活动格式化元素列表中没有在entry之前的条目,则跳到标记为创建的步骤。

  5. entry设置为活动格式化元素列表中entry之前的一个条目。

  6. 如果entry既不是一个标记,也不是打开元素栈中的一个元素,则转到标记为倒带的步骤。

  7. 前进:将entry设置为活动格式化元素列表中entry之后的一个元素。

  8. 创建插入一个HTML元素,为创建元素entry的令牌获得new element

  9. new element的条目替换活动格式化元素列表中的entry条目。

  10. 如果活动格式化元素列表中new element的条目不是列表中的最后一个条目,则返回到标记为前进的步骤。

这将重新打开所有尚未显式关闭的当前正文、单元格或标题(以最年轻的为准)中打开的格式化元素。

按照本规范的编写方式,活动格式化元素列表总是按照时间顺序排列,最早添加的元素在前,最近添加的元素在后(当然,除非正在执行上述算法的第7至第10步)。

当以下步骤要求UA清除直到最后一个标记的活动格式化元素列表时,UA必须执行以下步骤:

  1. entry设置为活动格式化元素列表中的最后一个(最近添加的)条目。

  2. 从活动格式化元素列表中删除entry

  3. 如果entry是一个标记,则在此点停止算法。列表已被清除至最后一个标记

  4. 返回到步骤1。

13.2.4.4 元素指针

最初,head 元素指针form 元素指针均为null。

一旦解析了一个head元素(无论是隐式还是显式),head 元素指针就会指向该节点。

form 元素指针指向最后一个被打开且尚未看到其结束标签的form元素。由于历史原因,它用于在严重错误的标记情况下将表单控件与表单关联。在template元素内被忽略。

13.2.4.5 其他解析状态标志

脚本标志在创建解析器时,如果脚本已启用,则设置为“enabled”,否则设置为“disabled”。

即使在作为HTML片段解析算法的一部分创建解析器时,脚本标志也可以启用,尽管在这种情况下script元素不会执行。

frameset-ok 标志在创建解析器时设置为“ok”。在看到某些标记后,它会被设置为“not ok”。

13.2.5 标记化

实现必须表现得像是使用了以下状态机来对HTML进行标记化。状态机必须从数据状态开始。大多数状态消耗单个字符,这可能会产生各种副作用,并且要么将状态机切换到一个新状态以重新消耗当前输入字符,要么将其切换到新状态以消耗下一个字符,或者保持在相同状态以消耗下一个字符。一些状态有更复杂的行为,可以在切换到另一个状态之前消耗多个字符。在某些情况下,标记化器的状态也会被树构建阶段改变。

当一个状态指示要在指定状态下重新消耗一个匹配的字符时,这意味着切换到该状态,但在尝试消耗下一个输入字符时,提供当前输入字符代替。

某些状态的确切行为取决于插入模式开放元素堆栈。某些状态还使用temporary buffer来跟踪进度,字符引用状态使用return state返回到调用它的状态。

标记化步骤的输出是一系列零个或多个以下标记:DOCTYPE、开始标签、结束标签、注释、字符、文件结束标记。DOCTYPE标记具有名称、公共标识符、系统标识符和强制怪异模式标志。当创建DOCTYPE标记时,其名称、公共标识符和系统标识符必须标记为丢失(这与空字符串是不同的状态),并且强制怪异模式标志必须设置为关闭(另一状态为开启)。开始和结束标签标记具有标签名称、自关闭标志和一个属性列表,其中每个属性都有一个名称和一个值。当创建开始或结束标签标记时,其自关闭标志必须未设置(另一状态是设置),并且其属性列表必须为空。注释和字符标记具有数据。

当标记被发出时,必须立即由树构建阶段处理。树构建阶段可以影响标记化阶段的状态,并且可以将其他字符插入流中。(例如,script元素可能会导致脚本执行,并使用动态标记插入API将字符插入正在标记化的流中。)

创建标记和发出标记是不同的操作。标记可能会被创建但隐式放弃(从未发出),例如如果文件在处理字符时意外结束,这些字符正被解析为一个开始标签标记。

当发出带有自关闭标志的开始标签标记时,如果在树构建阶段处理时该标志未被确认,那就是一个非空HTML元素的开始标签带有尾随斜杠解析错误

当发出带有属性的结束标签标记时,那就是一个带有属性的结束标签解析错误

当发出带有自关闭标志的结束标签标记时,那就是一个带有尾随斜杠的结束标签解析错误

合适的结束标签标记是指其标签名称与从此标记化器发出的最后一个开始标签的标签名称相匹配的结束标签标记(如果有的话)。如果从此标记化器发出的没有开始标签,那么就没有合适的结束标签标记。

字符引用被称为作为属性的一部分消耗,如果返回状态属性值(双引号)状态属性值(单引号)状态属性值(无引号)状态

当某个状态指示刷新作为字符引用消耗的代码点时,这意味着对于临时缓冲区中的每个代码点(按它们添加到缓冲区的顺序),用户代理必须将缓冲区中的代码点追加到当前属性的值中,如果字符引用是作为属性的一部分消耗的,否则将代码点作为字符标记发出。

在标记化器的每一步之前,用户代理必须首先检查解析器暂停标志。如果它为true,那么标记化器必须中止任何嵌套的标记化器调用的处理,将控制权交还给调用者。

标记化器状态机由以下小节中定义的状态组成。

13.2.5.1 数据状态

消耗下一个输入字符

U+0026 AMPERSAND (&)
返回状态设置为数据状态。切换到字符引用状态
U+003C LESS-THAN SIGN (<)
切换到标签打开状态
U+0000 NULL
这是一个意外的空字符 解析错误。将当前输入字符作为字符标记发出。
EOF
发出文件结束标记。
其他任何情况
当前输入字符作为字符标记发出。
13.2.5.2 RCDATA 状态

消耗下一个输入字符

U+0026 AMPERSAND (&)
返回状态设置为RCDATA 状态。切换到字符引用状态
U+003C LESS-THAN SIGN (<)
切换到RCDATA 小于号状态
U+0000 NULL
这是一个意外的空字符 解析错误。发出一个U+FFFD 替换字符的字符标记。
EOF
发出文件结束标记。
其他任何情况
当前输入字符作为字符标记发出。
13.2.5.3 RAWTEXT 状态

消耗下一个输入字符

U+003C LESS-THAN SIGN (<)
切换到RAWTEXT 小于号状态
U+0000 NULL
这是一个意外的空字符 解析错误。发出一个U+FFFD 替换字符的字符标记。
EOF
发出文件结束标记。
其他任何情况
当前输入字符作为字符标记发出。
13.2.5.4 脚本数据状态

消耗下一个输入字符

U+003C LESS-THAN SIGN (<)
切换到脚本数据小于号状态
U+0000 NULL
这是一个意外的空字符 解析错误。发出一个U+FFFD 替换字符的字符标记。
EOF
发出文件结束标记。
其他任何情况
当前输入字符作为字符标记发出。
13.2.5.5 纯文本状态

消耗下一个输入字符

U+0000 NULL
这是一个意外的空字符 解析错误。发出一个U+FFFD 替换字符的字符标记。
EOF
发出文件结束标记。
其他任何情况
当前输入字符作为字符标记发出。
13.2.5.6 标签打开状态

消耗下一个输入字符

U+0021 EXCL AMATION MARK (!)
切换到标记声明打开状态
U+002F SOLIDUS (/)
切换到结束标签打开状态
ASCII 字母
创建一个新的开始标签标记,将其标签名称设置为空字符串。重新消费并切换到标签名称状态
U+003F QUESTION MARK (?)
这是一个意外的问号而不是标签名称 解析错误。创建一个数据为空字符串的注释标记。重新消费并切换到伪注释状态
EOF
这是一个标签名称前遇到EOF 解析错误。发出一个U+003C 小于号字符标记和一个文件结束标记。
其他任何情况
这是一个无效的标签名称第一个字符 解析错误。发出一个U+003C 小于号字符标记。重新消费并切换到数据状态
13.2.5.7 结束标签打开状态

消耗下一个输入字符

ASCII 字母
创建一个新的结束标签标记,将其标签名称设置为空字符串。重新消费并切换到标签名称状态
U+003E GREATER-THAN SIGN (>)
这是一个缺少结束标签名称 解析错误。切换到数据状态
EOF
这是一个标签名称前遇到EOF 解析错误。发出一个U+003C 小于号字符标记、一个U+002F 斜线字符标记和一个文件结束标记。
其他任何情况
这是一个无效的标签名称第一个字符 解析错误。创建一个数据为空字符串的注释标记。重新消费并切换到伪注释状态
13.2.5.8 标签名称状态

消耗下一个输入字符

U+0009 CHARACTER TABULATION (tab)
U+000A LINE FEED (LF)
U+000C FORM FEED (FF)
U+0020 SPACE
切换到属性名称前状态
U+002F SOLIDUS (/)
切换到自闭合开始标签状态
U+003E GREATER-THAN SIGN (>)
切换到数据状态。发出当前标签标记。
ASCII 大写字母
当前输入字符的小写版本(在字符代码点上加上0x0020)附加到当前标签标记的标签名称中。
U+0000 NULL
这是一个意外的空字符 解析错误。将一个U+FFFD 替换字符附加到当前标签标记的标签名称中。
EOF
这是一个标签中遇到EOF 解析错误。发出一个文件结束标记。
其他任何情况
当前输入字符附加到当前标签标记的标签名称中。
13.2.5.9 RCDATA 小于号状态

消耗下一个输入字符

U+002F SOLIDUS (/)
临时缓冲区设置为空字符串。切换到RCDATA 结束标签打开状态
其他任何情况
发出一个U+003C 小于号字符标记。重新消费并切换到RCDATA 状态
13.2.5.10 RCDATA 结束标签打开状态

消耗下一个输入字符

ASCII 字母
创建一个新的结束标签标记,将其标签名称设置为空字符串。重新消费并切换到RCDATA 结束标签名称状态
其他任何情况
发出一个U+003C 小于号字符标记和一个U+002F 斜线字符标记。重新消费并切换到RCDATA 状态
13.2.5.11 RCDATA 结束标签名称状态

消耗下一个输入字符:

U+0009 字符制表符(tab)
U+000A 换行符(LF)
U+000C 换页符(FF)
U+0020 空格
如果当前结束标签令牌是适当的结束标签令牌,则切换到属性名称之前状态。否则,按照下方的“其他情况”处理。
U+002F 斜杠(/)
如果当前结束标签令牌是适当的结束标签令牌,则切换到自闭合起始标签状态。否则,按照下方的“其他情况”处理。
U+003E 大于号(>)
如果当前结束标签令牌是适当的结束标签令牌,则切换到数据状态并发出当前标签令牌。否则,按照下方的“其他情况”处理。
ASCII 大写字母
当前输入字符的小写版本(在字符的代码点上加 0x0020)附加到当前标签令牌的标签名称中。将当前输入字符附加到临时缓冲区中。
ASCII 小写字母
当前输入字符附加到当前标签令牌的标签名称中。将当前输入字符附加到临时缓冲区中。
其他情况
发出 U+003C 小于号字符令牌、U+002F 斜杠字符令牌,并为临时缓冲区中的每个字符发出一个字符令牌(按添加到缓冲区的顺序)。重新消费,进入RCDATA 状态
13.2.5.12 RAWTEXT 小于号状态

消耗下一个输入字符:

U+002F 斜杠(/)
临时缓冲区设置为空字符串。切换到RAWTEXT 结束标签打开状态
其他情况
发出 U+003C 小于号字符令牌。重新消费,进入RAWTEXT 状态
13.2.5.13 RAWTEXT 结束标签打开状态

消耗下一个输入字符:

ASCII 字母
创建一个新的结束标签令牌,将其标签名称设置为空字符串。重新消费,进入RAWTEXT 结束标签名称状态
其他情况
发出 U+003C 小于号字符令牌和 U+002F 斜杠字符令牌。重新消费,进入RAWTEXT 状态
13.2.5.14 RAWTEXT 结束标签名称状态

消耗下一个输入字符:

U+0009 字符制表符(tab)
U+000A 换行符(LF)
U+000C 换页符(FF)
U+0020 空格
如果当前结束标签令牌是适当的结束标签令牌,则切换到属性名称之前状态。否则,按照下方的“其他情况”处理。
U+002F 斜杠(/)
如果当前结束标签令牌是适当的结束标签令牌,则切换到自闭合起始标签状态。否则,按照下方的“其他情况”处理。
U+003E 大于号(>)
如果当前结束标签令牌是适当的结束标签令牌,则切换到数据状态并发出当前标签令牌。否则,按照下方的“其他情况”处理。
ASCII 大写字母
当前输入字符的小写版本(在字符的代码点上加 0x0020)附加到当前标签令牌的标签名称中。将当前输入字符附加到临时缓冲区中。
ASCII 小写字母
当前输入字符附加到当前标签令牌的标签名称中。将当前输入字符附加到临时缓冲区中。
其他情况
发出 U+003C 小于号字符令牌、U+002F 斜杠字符令牌,并为临时缓冲区中的每个字符发出一个字符令牌(按添加到缓冲区的顺序)。重新消费,进入RAWTEXT 状态
13.2.5.15 脚本数据小于号状态

消耗下一个输入字符:

U+002F 斜杠(/)
临时缓冲区设置为空字符串。切换到脚本数据结束标签打开状态
U+0021 感叹号(!)
切换到脚本数据转义起始状态。发出 U+003C 小于号字符令牌和 U+0021 感叹号字符令牌。
其他情况
发出 U+003C 小于号字符令牌。重新消费,进入脚本数据状态
13.2.5.16 脚本数据结束标签打开状态

消耗下一个输入字符:

ASCII 字母
创建一个新的结束标签令牌,将其标签名称设置为空字符串。重新消费,进入脚本数据结束标签名称状态
其他情况
发出 U+003C 小于号字符令牌和 U+002F 斜杠字符令牌。重新消费,进入脚本数据状态
13.2.5.17 脚本数据结束标签名称状态

消耗下一个输入字符:

U+0009 字符制表符(tab)
U+000A 换行符(LF)
U+000C 换页符(FF)
U+0020 空格
如果当前结束标签令牌是适当的结束标签令牌,则切换到属性名称之前状态。否则,按照下方的“其他情况”处理。
U+002F 斜杠(/)
如果当前结束标签令牌是适当的结束标签令牌,则切换到自闭合起始标签状态。否则,按照下方的“其他情况”处理。
U+003E 大于号(>)
如果当前结束标签令牌是适当的结束标签令牌,则切换到数据状态并发出当前标签令牌。否则,按照下方的“其他情况”处理。
ASCII 大写字母
当前输入字符的小写版本(在字符的代码点上加 0x0020)附加到当前标签令牌的标签名称中。将当前输入字符附加到临时缓冲区中。
ASCII 小写字母
当前输入字符附加到当前标签令牌的标签名称中。将当前输入字符附加到临时缓冲区中。
其他情况
发出 U+003C 小于号字符令牌、U+002F 斜杠字符令牌,并为临时缓冲区中的每个字符发出一个字符令牌(按添加到缓冲区的顺序)。重新消费,进入脚本数据状态
13.2.5.18 脚本数据转义起始状态

消耗下一个输入字符:

U+002D 连字符(-)
切换到脚本数据转义起始连字符状态。发出 U+002D 连字符字符令牌。
其他情况
重新消费,进入脚本数据状态
13.2.5.19 脚本数据转义起始连字符状态

消耗下一个输入字符:

U+002D 连字符(-)
切换到脚本数据转义连字符连字符状态。发出 U+002D 连字符字符令牌。
其他情况
重新消费,进入脚本数据状态
13.2.5.20 脚本数据转义状态

消耗下一个输入字符:

U+002D 连字符(-)
切换到脚本数据转义连字符状态。发出 U+002D 连字符字符令牌。
U+003C 小于号(<)
切换到脚本数据转义小于号状态
U+0000 NULL
这是一个意外的空字符 解析错误。发出 U+FFFD 替换字符。
EOF
这是一个脚本 HTML 注释样式文本中的意外结束文件 解析错误。发出一个结束文件令牌。
其他情况
当前输入字符作为字符令牌发出。
13.2.5.21 脚本数据转义连字符状态

消耗下一个输入字符:

U+002D 连字符(-)
切换到脚本数据转义连字符连字符状态。发出一个 U+002D 连字符字符令牌。
U+003C 小于号(<)
切换到脚本数据转义小于号状态
U+0000 NULL
这是一个意外的空字符 解析错误。切换到脚本数据转义状态。发出一个 U+FFFD 替换字符令牌。
EOF
这是一个脚本 HTML 注释样式文本中的意外结束文件 解析错误。发出一个结束文件令牌。
其他情况
切换到脚本数据转义状态。将当前输入字符作为字符令牌发出。
13.2.5.22 脚本数据转义连字符连字符状态

消耗下一个输入字符:

U+002D 连字符(-)
发出一个 U+002D 连字符字符令牌。
U+003C 小于号(<)
切换到脚本数据转义小于号状态
U+003E 大于号(>)
切换到脚本数据状态。发出一个 U+003E 大于号字符令牌。
U+0000 NULL
这是一个意外的空字符 解析错误。切换到脚本数据转义状态。发出一个 U+FFFD 替换字符令牌。
EOF
这是一个脚本 HTML 注释样式文本中的意外结束文件 解析错误。发出一个结束文件令牌。
其他情况
切换到脚本数据转义状态。将当前输入字符作为字符令牌发出。
13.2.5.23 脚本数据转义小于号状态

消耗下一个输入字符:

U+002F 斜杠(/)
临时缓冲区设置为空字符串。切换到脚本数据转义结束标签打开状态
ASCII 字母
临时缓冲区设置为空字符串。发出一个 U+003C 小于号字符令牌。重新消费进入脚本数据双重转义起始状态
其他情况
发出一个 U+003C 小于号字符令牌。重新消费进入脚本数据转义状态
13.2.5.24 脚本数据转义结束标签打开状态

消耗下一个输入字符:

ASCII 字母
创建一个新的结束标签令牌,将其标签名称设置为空字符串。重新消费进入脚本数据转义结束标签名称状态
其他情况
发出一个 U+003C 小于号字符令牌和一个 U+002F 斜杠字符令牌。重新消费进入脚本数据转义状态
13.2.5.25 脚本数据转义结束标签名称状态

消耗下一个输入字符:

U+0009 字符制表符(tab)
U+000A 换行符(LF)
U+000C 换页符(FF)
U+0020 空格
如果当前结束标签令牌是适当的结束标签令牌,则切换到属性名称之前状态。否则,按照下方的“其他情况”处理。
U+002F 斜杠(/)
如果当前结束标签令牌是适当的结束标签令牌,则切换到自闭合起始标签状态。否则,按照下方的“其他情况”处理。
U+003E 大于号(>)
如果当前结束标签令牌是适当的结束标签令牌,则切换到数据状态并发出当前标签令牌。否则,按照下方的“其他情况”处理。
ASCII 大写字母
当前输入字符的小写版本(在字符的代码点上加 0x0020)附加到当前标签令牌的标签名称中。将当前输入字符附加到临时缓冲区中。
ASCII 小写字母
当前输入字符附加到当前标签令牌的标签名称中。将当前输入字符附加到临时缓冲区中。
其他情况
发出一个 U+003C 小于号字符令牌、一个 U+002F 斜杠字符令牌,并为临时缓冲区中的每个字符发出一个字符令牌(按添加到缓冲区的顺序)。重新消费进入脚本数据转义状态
13.2.5.26 脚本数据双重转义起始状态

消耗下一个输入字符:

U+0009 字符制表符(tab)
U+000A 换行符(LF)
U+000C 换页符(FF)
U+0020 空格
U+002F 斜杠(/)
U+003E 大于号(>)
如果临时缓冲区是字符串“script”,则切换到脚本数据双重转义状态。否则,切换到脚本数据转义状态。将当前输入字符作为字符令牌发出。
ASCII 大写字母
当前输入字符的小写版本(在字符的代码点上加 0x0020)附加到临时缓冲 区中。将当前输入字符作为字符令牌发出。
ASCII 小写字母
当前输入字符附加到临时缓冲区中。将当前输入字符作为字符令牌发出。
其他情况
重新消费进入脚本数据转义状态
13.2.5.27 脚本数据双重转义状态

消耗下一个输入字符:

U+002D 连字符(-)
切换到脚本数据双重转义连字符状态。发出一个 U+002D 连字符字符令牌。
U+003C 小于号(<)
切换到脚本数据双重转义小于号状态。发出一个 U+003C 小于号字符令牌。
U+0000 NULL
这是一个意外的空字符 解析错误。发出一个 U+FFFD 替换字符令牌。
EOF
这是一个脚本 HTML 注释样式文本中的意外结束文件 解析错误。发出一个结束文件令牌。
其他情况
当前输入字符作为字符令牌发出。
13.2.5.28 脚本数据双重转义连字符状态

消耗下一个输入字符:

U+002D 连字符(-)
切换到脚本数据双重转义连字符连字符状态。发出一个 U+002D 连字符字符令牌。
U+003C 小于号(<)
切换到脚本数据双重转义小于号状态。发出一个 U+003C 小于号字符令牌。
U+0000 NULL
这是一个意外的空字符 解析错误。切换到脚本数据双重转义状态。发出一个 U+FFFD 替换字符令牌。
EOF
这是一个脚本 HTML 注释样式文本中的意外结束文件 解析错误。发出一个结束文件令牌。
其他情况
切换到脚本数据双重转义状态。将当前输入字符作为字符令牌发出。
13.2.5.29 脚本数据双重转义连字符连字符状态

消耗下一个输入字符:

U+002D 连字符(-)
发出一个 U+002D 连字符字符令牌。
U+003C 小于号(<)
切换到脚本数据双重转义小于号状态。发出一个 U+003C 小于号字符令牌。
U+003E 大于号(>)
切换到脚本数据状态。发出一个 U+003E 大于号字符令牌。
U+0000 NULL
这是一个意外的空字符 解析错误。切换到脚本数据双重转义状态。发出一个 U+FFFD 替换字符令牌。
EOF
这是一个脚本 HTML 注释样式文本中的意外结束文件 解析错误。发出一个结束文件令牌。
其他情况
切换到脚本数据双重转义状态。将当前输入字符作为字符令牌发出。
13.2.5.30 脚本数据双重转义小于号状态

消耗下一个输入字符:

U+002F 斜杠(/)
临时缓冲区设置为空字符串。切换到脚本数据双重转义结束状态。发出一个 U+002F 斜杠字符令牌。
其他情况
重新消费进入脚本数据双重转义状态
13.2.5.31 脚本数据双重转义结束状态

消耗下一个输入字符:

U+0009 字符制表符(tab)
U+000A 换行符(LF)
U+000C 换页符(FF)
U+0020 空格
U+002F 斜杠(/)
U+003E 大于号(>)
如果临时缓冲区是字符串“script”,则切换到脚本数据转义状态。否则,切换到脚本数据双重转义状态。将当前输入字符作为字符令牌发出。
ASCII 大写字母
当前输入字符的小写版本(在字符的代码点上加 0x0020)附加到临时缓冲区中。将当前输入字符作为字符令牌发出。
ASCII 小写字母
当前输入字符附加到临时缓冲区中。将当前输入字符作为字符令牌发出。
其他情况
重新消费进入脚本数据双重转义状态
13.2.5.32 属性名称之前状态

消耗下一个输入字符:

U+0009 字符制表符(tab)
U+000A 换行符(LF)
U+000C 换页符(FF)
U+0020 空格
忽略该字符。
U+002F 斜杠(/)
U+003E 大于号(>)
EOF
重新消费进入属性名称之后状态
U+003D 等号(=)
这是一个意外的等号出现在属性名称之前 解析错误。在当前标签 令牌中启动一个新属性。将该属性的名称设置为当前输入字符,并将其值设置为空字符串。切换到属性名称状态
其他情况
在当前标签令牌中启动一个新属性。将该属性的名称和值设置为空字符串。重新消费进入属性名称状态
13.2.5.33 属性名称状态

消耗下一个输入字符:

U+0009 字符制表符(tab)
U+000A 换行符(LF)
U+000C 换页符(FF)
U+0020 空格
U+002F 斜杠(/)
U+003E 大于号(>)
EOF
重新消费进入属性名称之后状态
U+003D 等号(=)
切换到属性值之前状态
ASCII 大写字母
当前输入字符的小写版本(在字符的代码点上加 0x0020)附加到当前属性的名称中。
U+0000 NULL
这是一个意外的空字符 解析错误。在当前属性的名称中附加一个 U+FFFD 替换字符。
U+0022 引号(")
U+0027 单引号(')
U+003C 小于号(<)
这是一个意外的字符出现在属性名称中 解析错误。按照下方的“其他情况”处理。
其他情况
当前输入字符附加到当前属性的名称中。

当用户代理离开属性名称状态(如果合适,在发出标签令牌之前),必须将完整的属性名称与同一令牌上的其他属性进行比较;如果令牌上已经有一个具有完全相同名称的属性,那么这就是一个重复属性 解析错误,并且必须从令牌中删除新属性。

如果属性以这种方式从令牌中删除,则解析器不会在后续使用它及其关联的值(如果有的话),因此它们实际上被丢弃。然而,这种方式删除属性并不会改变它作为“当前属性”的状态,针对标记化器来说。

13.2.5.34 属性名称之后状态

消耗下一个输入字符:

U+0009 字符制表符(tab)
U+000A 换行符(LF)
U+000C 换页符(FF)
U+0020 空格
忽略该字符。
U+002F 斜杠(/)
切换到自闭合起始标签状态
U+003D 等号(=)
切换到属性值之前状态
U+003E 大于号(>)
切换到数据状态。发出当前标签令牌。
EOF
这是一个标签中的意外结束文件 解析错误。发出一个结束文件令牌。
其他情况
在当前标签令牌中启动一个新属性。将该属性的名称和值设置为空字符串。重新消费进入属性名称状态
13.2.5.35 属性值之前状态

消耗下一个输入字符:

U+0009 字符制表符(tab)
U+000A 换行符(LF)
U+000C 换页符(FF)
U+0020 空格
忽略该字符。
U+0022 引号(")
切换到属性值(双引号)状态
U+0027 单引号(')
切换到属性值(单引号)状态
U+003E 大于号(>)
这是一个缺少属性值 解析错误。切换到数据状态。发出当前标签令牌。
其他情况
重新消费进入属性值(未加引号)状态
13.2.5.36 属性值(双引号)状态

消耗下一个输入字符:

U+0022 引号(")
切换到属性值(引用)之后状态
U+0026 符号(&)
返回状态设置为属性值(双引号)状态。切换到字符引用状态
U+0000 NULL
这是一个意外的空字符 解析错误。在当前属性的值中附加一个 U+FFFD 替换字符。
EOF
这是一个标签中的意外结束文件 解析错误。发出一个结束文件令牌。
其他情况
当前输入字符附加到当前属性的值中。
13.2.5.37 属性值(单引号)状态

消耗下一个输入字符:

U+0027 单引号(')
切换到属性值(引用)之后状态
U+0026 符号(&)
返回状态设置为属性值(单引号)状态。切换到字符引用状态
U+0000 NULL
这是一个意外的空字符 解析错误。在当前属性的值中附加一个 U+FFFD 替换字符。
EOF
这是一个标签中的意外结束文件 解析错误。发出一个结束文件令牌。
其他情况
当前输入字符附加到当前属性的值中。
13.2.5.38 属性值(未加引号)状态

消耗下一个输入字符:

U+0009 字符制表符(tab)
U+000A 换行符(LF)
U+000C 换页符(FF)
U+0020 空格
切换到属性名称之前状态
U+0026 符号(&)
返回状态设置为属性值(未加引号)状态。切换到字符引用状态
U+003E 大于号(>)
切换到数据状态。发出当前标签令牌。
U+0000 NULL
这是一个意外的空字符 解析错误。在当前属性的值中附加一个 U+FFFD 替换字符。
U+0022 引号(")
U+0027 单引号(')
U+003C 小于号(<)
U+003D 等号(=)
U+0060 反引号(`)
这是一个意外的字符出现在未加引号的属性值中 解析错误。按照下方的“其他情况”处理。
EOF
这是一个标签中的意外结束文件 解析错误。发出一个结束文件令牌。
其他情况
当前输入字符附加到当前属性的值中。
13.2.5.39 属性值(引用)之后状态

消耗下一个输入字符:

U+0009 字符制表符(tab)
U+000A 换行符(LF)
U+000C 换页符(FF)
U+0020 空格
切换到属性名称之前状态
U+002F 斜杠(/)
切换到自闭合起始标签状态
U+003E 大于号(>)
切换到数据状态。发出当前标签令牌。
EOF
这是一个标签中的意外结束文件 解析错误。发出一个结束文件令牌。
其他情况
这是一个属性之间缺少空白 解析错误重新消费进入属性名称之前状态
13.2.5.40 自闭合起始标签状态

消耗下一个输入字符:

U+003E 大于号(>)
设置当前标签令牌的自闭合标志。切换到数据状态。发出当前标签令牌。
EOF
这是一个标签中的意外结束文件 解析错误。发出一个结束文件令牌。
其他情况
这是一个标签中意外的斜杠 解析错误重新消耗进入属性名称之前状态
13.2.5.41 伪注释状态

消耗 下一个输入字符

U+003E 大于号(>)
切换到 数据状态。发出当前注释标记。
EOF
发出注释。发出文件结束标记。
U+0000 NULL
这是一个 意外的空字符 解析错误。将 U+FFFD 替换字符追加到注释标记的数据中。
其他任何字符
当前输入字符 追加到注释标记的数据中。
13.2.5.42 标记声明打开状态

如果接下来的几个字符是:

两个 U+002D 连字符(-)
消耗这两个字符,创建一个数据为空字符串的评论令牌,并切换到评论开始状态
ASCII 不区分大小写匹配单词 "DOCTYPE"
消耗这些字符并切换到DOCTYPE 状态
字符串 "[CDATA[" (五个大写字母 "CDATA" 和前后的一个 U+005B 左方括号字符)
消耗这些字符。如果存在一个调整后的当前节点并且它不是HTML 命名空间中的元素, 则切换到CDATA 段状态。否则,这是一个HTML 内容中的 CDATA 解析错误。创建一个数据为 "[CDATA[" 字符串的评论令牌。切换到 伪评论状态
其他情况
这是一个不正确打开的评论 解析错误。创建一个数据为空字符串的评论令牌。切换到 伪评论状态(不要在当前状态下消耗任何内容)。
13.2.5.43 注释开始状态

消耗 下一个输入字符

U+002D 连字符减号(-)
切换到 注释开始连字符状态
U+003E 大于号(>)
这是一个 空注释突然闭合 解析错误。切换到 数据状态。发出当前注释标记。
其他任何字符
重新消费注释状态
13.2.5.44 评论开始连字符状态

消耗下一个输入字符:

U+002D 连字符(-)
切换到评论结束状态
U+003E 大于号 (>)
这是一个突然关闭的空评论 解析错误。切换到数据状态。发出当前评论令牌。
EOF
这是一个评论中的 EOF 解析错误。发出当前评论令牌。发出一个结束文件令牌。
其他情况
将一个 U+002D 连字符 (-) 附加到评论令牌的数据中。 重新消费进入评论状态
13.2.5.45 注释状态

消费 下一个输入字符

U+003C 小于号(<)
当前输入字符 追加到注释标记的数据中。切换到 注释小于号状态
U+002D 连字符减号(-)
切换到 注释结束连字符状态
U+0000 NULL
这是一个 意外的空字符 解析错误。将 U+FFFD 替换字符追加到注释标记的数据中。
EOF
这是一个 注释中的 EOF 解析错误。发出当前注释标记。发出文件结束标记。
其他任何字符
当前输入字符 追加到注释标记的数据中。
13.2.5.46 注释小于号状态

消费 下一个输入字符

U+0021 感叹号(!)
当前输入字符 追加到注释标记的数据中。切换到 注释小于号感叹号状态
U+003C 小于号(<)
当前输入字符 追加到注释标记的数据中。
其他任何字符
重新消费注释状态
13.2.5.47 注释小于号感叹号状态

消费 下一个输入字符

U+002D 连字符减号(-)
切换到 注释小于号感叹号连字符状态
其他任何字符
重新消费注释状态
13.2.5.48 注释小于号感叹号连字符状态

消费 下一个输入字符

U+002D 连字符减号(-)
切换到 注释小于号感叹号连字符双连字符状态
其他任何字符
重新消费注释结束连字符状态
13.2.5.49 注释小于号感叹号连字符双连字符状态

消费 下一个输入字符

U+003E 大于号(>)
EOF
重新消费注释结束状态
其他任何字符
这是一个 嵌套注释 解析错误重新消费注释结束状态
13.2.5.50 注释结束连字符状态

消费 下一个输入字符

U+002D 连字符减号(-)
切换到 注释结束状态
EOF
这是一个 注释中的 EOF 解析错误。发出当前注释标记。发出文件结束标记。
其他任何字符
将 U+002D 连字符减号(-)追加到注释标记的数据中。重新消费注释状态
13.2.5.51 注释结束状态

消费 下一个输入字符

U+003E 大于号(>)
切换到 数据状态。发出当前注释标记。
U+0021 感叹号(!)
切换到 注释结束感叹号状态
U+002D 连字符减号(-)
将 U+002D 连字符减号(-)追加到注释标记的数据中。
EOF
这是一个 注释中的 EOF 解析错误。发出当前注释标记。发出文件结束标记。
其他任何字符
将两个 U+002D 连字符减号(-)追加到注释标记的数据中。重新消费注释状态
13.2.5.52 注释结束感叹号状态

消费 下一个输入字符

U+002D 连字符减号(-)
将两个 U+002D 连字符减号(-)和一个 U+0021 感叹号字符(!)追加到注释标记的数据中。切换到 注释结束连字符状态
U+003E 大于号(>)
这是一个 错误关闭的注释 解析错误。切换到 数据状态。发出当前注释标记。
EOF
这是一个 注释中的 EOF 解析错误。发出当前注释标记。发出文件结束标记。
其他任何字符
将两个 U+002D 连字符减号(-)和一个 U+0021 感叹号字符(!)追加到注释标记的数据中。重新消费注释状态
13.2.5.53 DOCTYPE 状态

消耗下一个输入字符:

U+0009 字符制表符 (tab)
U+000A 换行符 (LF)
U+000C 进纸符 (FF)
U+0020 空格
切换到DOCTYPE 名称之前状态
U+003E 大于号 (>)
重新消费进入DOCTYPE 名称之前状态
EOF
这是一个DOCTYPE 中的 EOF 解析 错误。创建一个新的 DOCTYPE 令牌。将其 强制怪癖标志 设置为 。发出当前令牌。发出一个结束文件令牌。
其他情况
这是一个缺少 DOCTYPE 名称之前的空白 解析错误重新消费进入DOCTYPE 名称之前状态
13.2.5.54 DOCTYPE 名称之前状态

消耗下一个输入字符:

U+0009 字符制表符 (tab)
U+000A 换行符 (LF)
U+000C 进纸符 (FF)
U+0020 空格
忽略该字符。
ASCII 大写字母
创建一个新的 DOCTYPE 令牌。将令牌的名称设置为 当前输入字符的 小写版本(将字符的代码点加 0x0020)。切换到 DOCTYPE 名称状态
U+0000 NULL
这是一个意外的空字符 解析错误。创建一个新的 DOCTYPE 令牌。将令牌的名称设置为一个 U+FFFD 替换字符 字符。切换到DOCTYPE 名称状态
U+003E 大于号 (>)
这是一个缺少 DOCTYPE 名称 解析 错误。创建一个新的 DOCTYPE 令牌。将其 强制怪癖标志 设置为 。切换到 数据状态。发出当前令牌。
EOF
这是一个DOCTYPE 中的 EOF 解析 错误。创建一个新的 DOCTYPE 令牌。将其 强制怪癖标志 设置为 。发出当前令牌。发出一个结束文件令牌。
其他情况
创建一个新的 DOCTYPE 令牌。将令牌的名称设置为 当前输入字符。 切换到 DOCTYPE 名称状态
13.2.5.55 DOCTYPE 名称状态

消耗下一个输入字符:

U+0009 字符制表符 (tab)
U+000A 换行符 (LF)
U+000C 进纸符 (FF)
U+0020 空格
切换到DOCTYPE 名称之后状态
U+003E 大于号 (>)
切换到数据状态。发出当前 DOCTYPE 令牌。
ASCII 大写字母
当前输入字符的 小写版本(将字符的代码点加 0x0020)附加到当前 DOCTYPE 令牌的名称中。
U+0000 NULL
这是一个意外的空字符 解析 错误。将一个 U+FFFD 替换字符附加到当前 DOCTYPE 令牌的 名称中。
EOF
这是一个DOCTYPE 中的 EOF 解析 错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
当前输入字符附加到当前 DOCTYPE 令牌的 名称中。
13.2.5.56 DOCTYPE 名称之后状态

消耗下一个输入字符:

U+0009 字符制表符 (tab)
U+000A 换行符 (LF)
U+000C 进纸符 (FF)
U+0020 空格
忽略该字符。
U+003E 大于号 (>)
切换到数据状态。发出当前 DOCTYPE 令牌。
EOF
这是一个DOCTYPE 中的 EOF 解析 错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况

如果从当前输入字符开始的六个字符是 ASCII 不区分大小写匹配单词 "PUBLIC",则消耗这些字符 并切换到DOCTYPE 公共关键字之后状态

否则,如果从当前输入字符开始的六个字符是 ASCII 不区分大小写匹配单词 "SYSTEM",则消耗这些 字符并切换到DOCTYPE 系统关键字之后状态

否则,这是一个DOCTYPE 名称之后的无效字符序列 解析 错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 重新消费进入伪 DOCTYPE 状态

13.2.5.57 DOCTYPE public 关键字之后状态

消耗下一个输入字符:

U+0009 字符制表符 (tab)
U+000A 换行符 (LF)
U+000C 进纸符 (FF)
U+0020 空格
切换到DOCTYPE 公共标识符之前状态
U+0022 引号 (")
这是一个DOCTYPE 公共关键字之后缺少空格 解析 错误。将当前 DOCTYPE 令牌的公共标识符设置为空字符串(不缺失),然后切换到DOCTYPE 公共标识符(双引号)状态
U+0027 撇号 (')
这是一个DOCTYPE 公共关键字之后缺少空格 解析 错误。将当前 DOCTYPE 令牌的公共标识符设置为空字符串(不缺失),然后切换到DOCTYPE 公共标识符(单引号)状态
U+003E 大于号 (>)
这是一个缺少 DOCTYPE 公共标识符 解析 错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。切换到数据状态。发出当前 DOCTYPE 令牌。
EOF
这是一个DOCTYPE 中的 EOF 解析 错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
这是一个DOCTYPE 公共标识符之前缺少引号 解析 错误。将当前 DOCTYPE 令牌的 强制怪癖 标志 设置为 重新消费进入伪 DOCTYPE 状态
13.2.5.58 DOCTYPE public 标识符之前状态

消耗下一个输入字符:

U+0009 字符制表符 (tab)
U+000A 换行符 (LF)
U+000C 进纸符 (FF)
U+0020 空格
忽略该字符。
U+0022 引号 (")
将当前 DOCTYPE 令牌的公共标识符设置为空字符串(不缺失),然后切换到 DOCTYPE 公共 标识符(双引号)状态
U+0027 撇号 (')
将当前 DOCTYPE 令牌的公共标识符设置为空字符串(不缺失),然后切换到 DOCTYPE 公共 标识符(单引号)状态
U+003E 大于号 (>)
这是一个缺少 DOCTYPE 公共标识符 解析 错误。将当前 DOCTYPE 令牌的 强制怪癖 标志 设置为 。切换到数据状态。发出当前 DOCTYPE 令牌。
EOF
这是一个DOCTYPE 中的 EOF 解析 错误。将当前 DOCTYPE 令牌的 强制怪癖 标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
这是一个DOCTYPE 公共标识符之前缺少引号 解析 错误。将当前 DOCTYPE 令牌的 强制怪癖 标志 设置为 重新消费进入伪 DOCTYPE 状态
13.2.5.59 DOCTYPE public 标识符(双引号)状态

消耗下一个输入字符:

U+0022 引号 (")
切换到DOCTYPE 公共 标识符之后状态
U+0000 NULL
这是一个意外的空字符 解析 错误。将一个 U+FFFD 替换字符附加到当前 DOCTYPE 令牌的 公共标识符中。
U+003E 大于号 (>)
这是一个突然终止的 DOCTYPE 公共标识符 解析错误。将当前 DOCTYPE 令牌的 强制怪癖 标志 设置为 。切换到数据状态。发出当前 DOCTYPE 令牌。
EOF
这是一个DOCTYPE 中的 EOF 解析 错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
当前输入字符附加到 当前 DOCTYPE 令牌的公共 标识符中。
13.2.5.60 DOCTYPE public 标识符(单引号)状态

消耗下一个输入字符:

U+0027 撇号 (')
切换到DOCTYPE 公共 标识符之后状态
U+0000 NULL
这是一个意外的空字符 解析 错误。将一个 U+FFFD 替换字符附加到当前 DOCTYPE 令牌的 公共标识符中。
U+003E 大于号 (>)
这是一个突然终止的 DOCTYPE 公共标识符 解析错误。将当前 DOCTYPE 令牌的 强制怪癖 标志 设置为 。切换到数据状态。发出当前 DOCTYPE 令牌。
EOF
这是一个DOCTYPE 中的 EOF 解析 错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
当前输入字符附加到 当前 DOCTYPE 令牌的公共 标识符中。
13.2.5.61 DOCTYPE public 标识符之后状态

消耗下一个输入字符:

U+0009 字符制表符 (tab)
U+000A 换行符 (LF)
U+000C 进纸符 (FF)
U+0020 空格
切换到 DOCTYPE 公共标识符和系统标识符之间状态
U+003E 大于号 (>)
切换到 数据状态。发出当前 DOCTYPE 令牌。
U+0022 引号 (")
这是一个 缺少 DOCTYPE 公共标识符和系统标识符之间的空格 解析错误。将当前 DOCTYPE 令牌的系统标识符设置为空字符串(不缺失),然后切换到 DOCTYPE 系统标识符(双引号)状态
U+0027 撇号 (')
这是一个 缺少 DOCTYPE 公共标识符和系统标识符之间的空格 解析错误。将当前 DOCTYPE 令牌的系统标识符设置为空字符串(不缺失),然后切换到 DOCTYPE 系统标识符(单引号)状态
EOF
这是一个 DOCTYPE 中的 EOF 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
这是一个 DOCTYPE 系统标识符之前缺少引号 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 重新消费进入 伪 DOCTYPE 状态
13.2.5.62 DOCTYPE public 和系统标识符之间状态

消耗下一个输入字符:

U+0009 字符制表符 (tab)
U+000A 换行符 (LF)
U+000C 进纸符 (FF)
U+0020 空格
忽略该字符。
U+003E 大于号 (>)
切换到 数据状态。发出当前 DOCTYPE 令牌。
U+0022 引号 (")
将当前 DOCTYPE 令牌的系统标识符设置为空字符串(不缺失),然后切换到 DOCTYPE 系统标识符(双引号)状态
U+0027 撇号 (')
将当前 DOCTYPE 令牌的系统标识符设置为空字符串(不缺失),然后切换到 DOCTYPE 系统标识符(单引号)状态
EOF
这是一个 DOCTYPE 中的 EOF 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
这是一个 DOCTYPE 系统标识符之前缺少引号 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 重新消费进入 伪 DOCTYPE 状态
13.2.5.63 DOCTYPE system 关键字之后状态

消耗下一个输入字符:

U+0009 字符制表符 (tab)
U+000A 换行符 (LF)
U+000C 进纸符 (FF)
U+0020 空格
切换到 DOCTYPE 系统标识符之前状态
U+0022 引号 (")
这是一个 DOCTYPE 系统关键字之后缺少空格 解析错误。将当前 DOCTYPE 令牌的系统标识符设置为空字符串(不缺失),然后切换到 DOCTYPE 系统标识符(双引号)状态
U+0027 撇号 (')
这是一个 DOCTYPE 系统关键字之后缺少空格 解析错误。将当前 DOCTYPE 令牌的系统标识符设置为空字符串(不缺失),然后切换到 DOCTYPE 系统标识符(单引号)状态
U+003E 大于号 (>)
这是一个 缺少 DOCTYPE 系统标识符 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。切换到 数据状态。发出当前 DOCTYPE 令牌。
EOF
这是一个 DOCTYPE 中的 EOF 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
这是一个 DOCTYPE 系统标识符之前缺少引号 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 重新消费进入 伪 DOCTYPE 状态
13.2.5.64 DOCTYPE system 标识符之前状态

消耗下一个输入字符:

U+0009 字符制表符 (tab)
U+000A 换行符 (LF)
U+000C 进纸符 (FF)
U+0020 空格
忽略该字符。
U+0022 引号 (")
将当前 DOCTYPE 令牌的系统标识符设置为空字符串(不缺失),然后切换到 DOCTYPE 系统标识符(双引号)状态
U+0027 撇号 (')
将当前 DOCTYPE 令牌的系统标识符设置为空字符串(不缺失),然后切换到 DOCTYPE 系统标识符(单引号)状态
U+003E 大于号 (>)
这是一个 缺少 DOCTYPE 系统标识符 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。切换到 数据状态。发出当前 DOCTYPE 令牌。
EOF
这是一个 DOCTYPE 中的 EOF 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
这是一个 DOCTYPE 系统标识符之前缺少引号 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 重新消费进入 伪 DOCTYPE 状态
13.2.5.65 DOCTYPE system 标识符(双引号)状态

消耗下一个输入字符:

U+0022 引号 (")
切换到 DOCTYPE 系统标识符之后状态
U+0000 NULL
这是一个 意外的 NULL 字符 解析错误。将 U+FFFD 替换字符附加到当前 DOCTYPE 令牌的系统标识符中。
U+003E 大于号 (>)
这是一个 突然的 DOCTYPE 系统标识符 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。切换到 数据状态。发出当前 DOCTYPE 令牌。
EOF
这是一个 DOCTYPE 中的 EOF 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
当前输入字符 附加到当前 DOCTYPE 令牌的系统标识符中。
13.2.5.66 DOCTYPE system 标识符(单引号)状态

消耗下一个输入字符:

U+0027 撇号 (')
切换到 DOCTYPE 系统标识符之后状态
U+0000 NULL
这是一个 意外的 NULL 字符 解析错误。将 U+FFFD 替换字符附加到当前 DOCTYPE 令牌的系统标识符中。
U+003E 大于号 (>)
这是一个 突然的 DOCTYPE 系统标识符 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。切换到 数据状态。发出当前 DOCTYPE 令牌。
EOF
这是一个 DOCTYPE 中的 EOF 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
当前输入字符 附加到当前 DOCTYPE 令牌的系统标识符中。
13.2.5.67 DOCTYPE system 标识符之后状态

消耗下一个输入字符:

U+0009 字符制表符 (tab)
U+000A 换行符 (LF)
U+000C 进纸符 (FF)
U+0020 空格
忽略该字符。
U+003E 大于号 (>)
切换到 数据状态。发出当前 DOCTYPE 令牌。
EOF
这是一个 DOCTYPE 中的 EOF 解析错误。将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。发出当前 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
这是一个 DOCTYPE 系统标识符之后的意外字符 解析错误重新消费进入 伪 DOCTYPE 状态。(这并未将当前 DOCTYPE 令牌的 强制怪癖标志 设置为 。)
13.2.5.68 伪 DOCTYPE 状态

消耗下一个输入字符:

U+003E 大于号 (>)
切换到 数据 状态。发出 DOCTYPE 令牌。
U+0000 NULL
这是一个 意外的 NULL 字符 解析错误。忽略该字符。
EOF
发出 DOCTYPE 令牌。发出一个结束文件令牌。
其他情况
忽略该字符。
13.2.5.69 CDATA 段状态

消耗下一个输入字符:

U+005D 右方括号 (])
切换到 CDATA 段括号状态
EOF
这是一个 CDATA 中的 EOF 解析错误。发出一个结束文件令牌。
其他情况
当前输入字符 作为字符令牌发出。

U+0000 NULL 字符在树构建阶段处理,作为 在外来内容中插入模式的一部分,这是 CDATA 段可以出现的唯一位置。

13.2.5.70 CDATA 段括号状态

消耗下一个输入字符:

U+005D 右方括号 (])
切换到 CDATA 段结束状态
其他情况
发出一个 U+005D 右方括号字符令牌。重新消费进入 CDATA 段状态
13.2.5.71 CDATA 段结束状态

消耗下一个输入字符:

U+005D 右方括号 (])
发出一个 U+005D 右方括号字符令牌。
U+003E 大于号字符
切换到 数据 状态
其他情况
发出两个 U+005D 右方括号字符令牌。重新消费进入 CDATA 段状态
13.2.5.72 字符引用状态

临时缓冲区设置为空字符串。将 U+0026 AMPERSAND (&) 字符附加到 临时缓冲区中。消耗下一个输入字符:

ASCII 字母数字
重新消费进入 命名字符引用状态
U+0023 井号 (#)
当前输入字符 附加到 临时缓冲区中。切换到 数字字符引用状态
其他情况
刷新作为字符引用消耗的代码点重新消费进入 返回状态
13.2.5.73 命名字符引用状态

消耗尽可能多的字符,这些消耗的字符是命名字符引用表第一列中的标识符之一。每次消耗时,将字符附加到临时缓冲区中。

如果有匹配项

如果字符引用是作为属性的一部分消耗的,并且最后一个匹配的字符不是 U+003B 分号字符 (;),并且下一个输入字符是 U+003D 等号字符 (=) 或ASCII 字母数字,那么出于历史原因,刷新作为字符引用消耗的代码点并切换到返回状态

否则:

  1. 如果最后一个匹配的字符不是 U+003B 分号字符 (;),那么这是一个缺少字符引用之后的分号 解析错误

  2. 临时缓冲区设置为空字符串。将一个或两个与字符引用名称(如命名字符引用表第二列所示的字符引用名称相对应的字符附加到临时缓冲区中。

  3. 刷新作为字符引用消耗的代码点。切换到返回状态
否则
刷新作为字符引用消耗的代码点。切换到 不明确的与号状态

如果标记(不在属性中)包含字符串I'm &notit; I tell you,字符引用将解析为"not",如I'm ¬it; I tell you(这是解析错误)。但如果标记为I'm &notin; I tell you,字符引用将解析为"notin;",结果为I'm ∉ I tell you(没有解析错误)。

然而,如果标记在属性中包含字符串I'm &notit; I tell you,则不会解析字符引用,字符串保持不变(且无解析错误)。

13.2.5.74 不明确的与号状态

消耗下一个输入字符:

ASCII 字母数字
如果字符引用是作为属性的一部分消耗的,则将当前输入字符附加到当前属性的值中。否则,发出当前输入字符作为字符令牌。
U+003B 分号 (;)
这是一个未知命名字符引用 解析错误重新消费进入 返回状态
其他情况
重新消费进入 返回状态
13.2.5.75 数字字符引用状态

字符引用代码 设置为 0。

消耗下一个输入字符:

U+0078 拉丁字母小写 X
U+0058 拉丁字母大写 X
当前输入字符 附加到临时缓冲区中。切换到十六进制字符引用开始状态
其他情况
重新消费 进入十进制字符引用开始状态
13.2.5.76 十六进制字符引用开始状态

消耗下一个输入字符:

ASCII 十六进制数字
重新消费进入十六进制字符引用状态
其他情况
这是一个数字字符引用中缺少数字 解析错误刷新作为字符引用消耗的代码点重新消费进入返回状态
13.2.5.77 十进制字符引用开始状态

消耗下一个输入字符:

ASCII 数字
重新消费 进入十进制字符引用状态
其他情况
这是一个数字字符引用中缺少数字 解析错误刷新作为字符引用消耗的代码点重新消费 进入返回状态
13.2.5.78 十六进制字符引用状态

消耗下一个输入字符:

ASCII 数字
字符引用代码 乘以 16。将 当前输入字符的数值版本(从字符的代码点中减去 0x0030)添加到 字符引用代码
ASCII 大写十六进制数字
字符引用代码 乘以 16。将 当前输入字符作为十六进制数字(从字符的代码点中减去 0x0037)添加到 字符引用代码
ASCII 小写十六进制数字
字符引用代码 乘以 16。将 当前输入字符作为十六进制数字(从字符的代码点中减去 0x0057)添加到 字符引用代码
U+003B 分号
切换到数字字符引用结束状态
其他情况
这是一个字符引用后缺少分号 解析错误重新消费进入数字字符引用结束状态
13.2.5.79 十进制字符引用状态

消耗下一个输入字符:

ASCII 数字
字符引用代码 乘以 10。将 当前输入字符的数值版本(从字符的代码点中减去 0x0030)添加到 字符引用代码
U+003B 分号
切换到数字字符引用结束状态
其他情况
这是一个字符引用后缺少分号 解析错误重新消费进入数字字符引用结束状态
13.2.5.80 数字字符引用结束状态

检查 字符引用代码:

临时缓冲区设置为空字符串。将一个等于字符引用代码的代码点附加到临时缓冲区中。刷新作为字符引用消耗的代码点。切换到返回状态

13.2.6 树构建

树构建阶段的输入是一系列来自标记化阶段的标记。当解析器创建时,树构建阶段与 DOM 文档对象关联。该阶段的“输出”包括动态修改或扩展该文档的 DOM 树。

本规范未定义交互式用户代理何时必须呈现 文档以便用户可以使用,或何时必须开始接受用户输入。


当每个标记从标记器发出时,用户代理必须遵循以下列表中的适当步骤,该列表称为 树构建分发器

如果打开元素栈为空
如果调整后的当前节点HTML 命名空间中的元素
如果调整后的当前节点MathML 文本集成点,且标记是起始标记,其标签名既不是“mglyph”也不是“malignmark”
如果调整后的当前节点MathML 文本集成点,且标记是字符标记
如果调整后的当前节点MathML annotation-xml元素,且标记是标签名为“svg”的起始标记
如果调整后的当前节点HTML 集成点,且标记是起始标记
如果调整后的当前节点HTML 集成点,且标记是字符标记
如果标记是文件结束标记
根据 HTML 内容中与当前插入模式对应的部分中给出的规则处理标记。
否则
根据解析标记在外来内容中的部分中给出的规则处理标记。

下一个标记是即将由树构建分发器处理的标记(即使标记随后只是被忽略)。

如果节点是以下元素之一,则该节点是MathML 文本集成点

如果节点是以下元素之一,则该节点是HTML 集成点

如果问题中的节点是上下文元素传递到HTML 片段解析算法,则该元素的起始标记是该HTML 片段解析算法期间创建的“伪造”标记。


以下提到的所有标签名称并非本规范中的合规标签名称;许多标签名被包括在内是为了处理遗留内容。它们仍然构成实现要求遵循的算法的一部分,以声称符合规范。

下面描述的算法对生成的 DOM 树的深度、标签名称、属性名称、属性值、文本节点等的长度没有限制。虽然鼓励实现者避免任意限制,但也认识到实际问题可能会迫使用户代理施加嵌套深度约束。

13.2.6.1 创建和插入节点

当解析器正在处理标记时,它可以启用或禁用寄养父母。这会影响以下算法。

使用特定覆盖目标(可选)插入节点的适当位置是运行以下步骤返回的元素中的位置:

  1. 如果指定了覆盖目标,则将target设为覆盖目标

    否则,将target设为当前节点

  2. 使用以下列表中第一个匹配步骤确定adjusted insertion location

    如果寄养父母已启用且targettabletbodytfoottheadtr元素

    当内容在表格中嵌套错误时,会发生寄养父母。

    运行以下子步骤:

    1. last template设为打开元素栈中最后一个template元素(如果有)。

    2. last table设为打开元素栈中最后一个table元素(如果有)。

    3. 如果有last template且没有last table,或者有last table,但在打开元素栈last template低于(最近添加)last table,则将adjusted insertion location设为last templatetemplate 内容的最后一个子元素(如果有)之后,并中止这些步骤。

    4. 如果没有last table,则将adjusted insertion location设为打开元素栈中的第一个元素(html元素)内的最后一个子元素之后,并中止这些步骤。(片段情况

    5. 如果last table有一个父节点,则将adjusted insertion location设为last table的父节点内,紧接在last table之前,并中止这些步骤。

    6. previous element设为打开元素栈中紧挨last table上方的元素。

    7. adjusted insertion location设为previous element内的最后一个子元素之后。

    这些步骤部分是因为元素(特别是table元素)可能已被脚本在 DOM 中移动,或者在元素被解析器插入后,已完全从 DOM 中删除。

    否则

    adjusted insertion location设为target内的最后一个子元素之后。

  3. 如果adjusted insertion locationtemplate元素内,则将其改为template元素的template 内容中的最后一个子元素之后。

  4. 返回adjusted insertion location


当以下步骤要求 UA 为特定given namespace和特定intended parent中的标记创建一个元素时,UA 必须运行以下步骤:

  1. 如果活动推测性 HTML 解析器不为空,则返回创建推测性模拟元素的结果,给定given namespace、标记的标签名称和标记的属性。

  2. 否则,选择性地创建推测性模拟元素,给定given namespace、标记的标签名称和标记的属性。

    结果不被使用。此步骤允许从非推测性解析中启动推测性获取。在此时获取仍然是推测性的,因为,例如,在元素插入时,intended parent可能已经从文档中移除。

  3. document设为intended parent节点文档

  4. local name设为标记的标签名称。

  5. 如果该标记存在"is"属性,将is设为该属性的值,否则为 null。

  6. definition设为查找自定义元素定义的结果,给定documentgiven namespacelocal nameis

  7. 如果definition不为空且解析器不是作为HTML 片段解析算法的一部分创建的,则设will execute script为 true。否则,设为 false。

  8. 如果will execute script为 true,则:

    1. 递增document动态标记插入计数器

    2. 如果JavaScript 执行上下文栈为空,则执行微任务检查点

    3. 将一个新的元素队列推入document相关代理自定义元素反应栈

  9. element设为创建元素的结果,给定documentlocalNamegiven namespace、null 和is。如果will execute script为 true,则设置synchronous custom elements flag;否则,保持未设置。

    这将导致运行自定义元素构造函数,如果will execute script为 true。然而,由于我们递增了动态标记插入计数器,这不会导致新字符插入到标记化器,或文档被摧毁

  10. 追加给定标记中的每个属性到element

    这可以排队自定义元素回调反应以触发attributeChangedCallback,可能会立即运行(在下一步中)。

    虽然is属性决定了创建自定义内置元素,但它在相关的自定义元素构造函数执行期间不可见;它与所有其他属性一起在此步骤中追加。

  11. 如果will execute script为 true,则:

    1. document相关代理自定义元素反应栈中的队列弹出。(这将是上面推入的相同元素队列。)

    2. 调用自定义元素反应queue中。

    3. 减少document动态标记插入计数器

  12. 如果element具有xmlns属性XMLNS 命名空间中,其值与元素的命名空间不完全相同,则这是一个解析错误。类似地,如果element具有xmlns:xlink属性在XMLNS 命名空间中,其值与XLink 命名空间不相符,则这是一个解析错误

  13. 如果element可重置元素,则调用其重置算法。(这将基于元素的属性初始化元素的选中状态。)

  14. 如果element与表单相关的元素,而不是与表单相关的自定义元素,且form 元素指针不为 null,打开元素堆栈上没有template元素,element既不列出,也没有form属性,并且intended parentform元素指针指向的元素位于同一中,那么将elementform元素关联,并设置element解析器插入标志

  15. 返回element


为了用元素element在调整后的插入位置插入一个元素

  1. adjusted insertion location设为适当的插入节点位置

  2. 如果无法在adjusted insertion location插入element,则中止这些步骤。

  3. 如果解析器不是作为HTML 片段解析算法的一部分创建的,则将一个新的元素队列推入element相关代理自定义元素反应栈

  4. adjusted insertion location插入element

  5. 如果解析器不是作为HTML 片段解析算法的一部分创建的,则从element相关代理自定义元素反应栈中弹出元素队列,并调用该队列中的自定义元素反应

如果adjusted insertion location无法接受更多元素,例如,因为它是文档,它已经有了一个元素子节点,则element将被丢弃。

当以下步骤要求用户代理为给定命名空间中的标记并使用布尔onlyAddToElementStack插入外来元素时,用户代理必须执行以下步骤:

  1. adjusted insertion location设为适当的插入节点位置

  2. element设为为标记创建元素的结果,在给定的命名空间中,预定父节点为adjusted insertion location所在的元素。

  3. 如果onlyAddToElementStack为 false,则使用element运行在调整后的插入位置插入元素

  4. element推入打开元素栈 ,使其成为新的当前节点

  5. 返回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 命名空间

当以下步骤要求用户代理在处理令牌时插入一个字符时,用户代理必须运行以下步骤:

  1. data为传递给算法的字符,或者,如果没有明确指定字符,则为正在处理的字符令牌的字符。

  2. adjusted insertion location插入节点的适当位置

  3. 如果adjusted insertion location位于Document 节点中,则返回。

    DOM 不允许Document 节点拥有Text 节点子节点,因此它们会被丢弃。

  4. 如果在adjusted insertion location之前立即有一个Text 节点,则将data附加到该Text 节点的data

    否则,创建一个新的Text 节点,其datadata,其节点文档adjusted insertion location所在的元素的节点文档相同,并将新创建的节点插入到adjusted insertion location中。

以下是解析器的一些示例输入及其对应的Text 节点数量,假设用户代理执行脚本。

输入 Text 节点数量
A<script>
var script = document.getElementsByTagName('script')[0];
document.body.removeChild(script);
</script>B
文档中有一个Text 节点,包含"AB"。
A<script>
var text = document.createTextNode('B');
document.body.appendChild(text);
</script>C
三个Text 节点;脚本前的"A"、脚本内容以及脚本后的"BC"(解析器会附加到由脚本创建的 Text 节点)。
A<script>
var text = document.getElementsByTagName('script')[0].firstChild;
text.data = 'B';
document.body.appendChild(text);
</script>C
文档中有两个相邻的Text 节点,包含"A"和"BC"。
A<table>B<tr>C</tr>D</table>
表格之前有一个Text 节点,包含"ABCD"。(这是由寄养父母引起的。)
A<table><tr> B</tr> C</table>
表格之前有一个Text 节点,包含"A B C" (A-空格-B-空格-C)。(这是由寄养父母引起的。)
A<table><tr> B</tr> </em>C</table>
表格之前有一个Text 节点,包含"A BC" (A-空格-B-C),表格内有一个Text 节点(作为 tbody 的子节点),包含单个空格字符。(由非字符标记将空格字符与非空格字符分隔开,即使这些其他标记随后被忽略,也不会受到寄养父母的影响。)

当以下步骤要求用户代理在处理注释令牌时插入一个注释时,可以选择使用显式插入位置position,用户代理必须运行以下步骤:

  1. data为正在处理的注释令牌中的数据。

  2. 如果指定了position,则让adjusted insertion locationposition。否则,让adjusted insertion location插入节点的适当位置

  3. 创建一个Comment 节点,其data属性设置为 data,其节点文档adjusted insertion location所在节点的文档相同。

  4. 将新创建的节点插入到adjusted insertion location中。

13.2.6.2 解析仅包含文本的元素

通用原始文本元素解析算法通用 RCDATA 元素 解析算法包括以下步骤。这些算法总是在响应开始标签令牌时被调用。

  1. 为令牌插入一个 HTML 元素

  2. 如果调用的算法是通用原始文本 元素解析 算法,则将标记化器切换到RAWTEXT 状态;否则,调用的算法是通用 RCDATA 元素 解析算法,将标记化器切换到 RCDATA 状态

  3. 原始插入模式设为当前的插入 模式

  4. 然后,将插入模式切换为"文本"。

13.2.6.3 关闭具有隐含结束标签的元素

当以下步骤要求 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 必须从当前节点中将其弹出打开元素的堆栈

13.2.6.4 在 HTML 内容中解析令牌的规则
13.2.6.4.1 "initial" 插入模式

Document 对象有一个关联的解析器不能改变模式标志(布尔值)。最初为 false。

当用户代理应用 "initial" 插入 模式 的规则时,用户代理必须按如下方式处理该令牌:

字符令牌是以下之一:U+0009 字符制表符,U+000A 换行符(LF),U+000C 换页符(FF),U+000D 回车符(CR),或 U+0020 空格

忽略该令牌。

注释令牌

插入 一个 注释 作为 Document 对象的最后一个子节点。

DOCTYPE 令牌

如果 DOCTYPE 令牌的名称不是 "html",或者令牌的公共标识符不存在,或者令牌的系统标识符既不存在也不是 "about:legacy-compat", 那么会发生解析错误

将一个 DocumentType 节点附加到 Document 节点上,其 名称 设置为 DOCTYPE 令牌中给定的名称,或者如果名称不存在,则设置为空字符串;其 公共 ID 设置为 DOCTYPE 令牌中给定的公共标识符,或者如果公共标识符不存在,则设置为空字符串;其 系统 ID 设置为 DOCTYPE 令牌中给定的系统标识符,或者如果系统标识符不存在,则设置为空字符串。

这也确保 DocumentType 节点作为 doctype 属性的值返回给 Document 对象。

然后,如果文档不是 一个 iframe srcdoc 文档,并且 解析器不能 改变模式标志 为 false,并且 DOCTYPE 令牌符合以下列表中的条件之一,那么将 Document 设置为 quirks 模式

否则,如果文档不是 一个 iframe srcdoc 文档,并且 解析器不能改变 模式标志 为 false,并且 DOCTYPE 令牌符合以下列表中的条件之一,那么将 Document 设置为 有限的 quirks 模式

系统标识符和公共标识符字符串必须以ASCII 大小写不敏感的方式与上面列表中给定的值进行比较。对于上述条件,值为空字符串的系统标识符不被视为不存在。

然后,将 插入模式 切换为 "before html"。

其他任何情况

如果文档不是 一个 iframe srcdoc 文档,那么这是一个 解析 错误;如果 解析器不能改变模式标志 为 false,则将 Document 设置为 quirks 模式

无论如何,将 插入模式 切换为 "before html",然后重新处理该令牌。

13.2.6.4.2 "before html" 插入模式

当用户代理应用 "before html" 插入 模式 的规则时,用户代理必须按如下方式处理该令牌:

DOCTYPE 令牌

解析 错误。忽略该令牌。

注释令牌

插入 一个 注释 作为 Document 对象的最后一个子节点。

字符令牌是以下之一:U+0009 字符制表符,U+000A 换行符(LF),U+000C 换页符(FF),U+000D 回车符(CR),或 U+0020 空格

忽略该令牌。

标签名为 "html" 的开始标签

为令牌创建一个元素HTML 命名空间中,以 Document 作为预期父节点。将其附加到 Document 对象中。将 此元素放入 打开元素的堆栈中。

插入模式 切换为 "before head"。

标签名为 "head"、"body"、"html"、"br" 之一的结束标签

按照以下 "其他任何情况" 条目中描述的方式操作。

其他任何结束标签

解析 错误。忽略该令牌。

其他任何情况

创建一个 html 元素,其 节点文档Document 对象。将其附加到 Document 对象中。将此元素放入 打开元素的堆栈中。

插入模式 切换为 "before head",然后重新处理该令牌。

文档元素 可能会从 Document 对象中移除,例如通过脚本;在这种情况下,不会发生任何特殊情况,内容将继续按照下一节所述附加到节点中。

13.2.6.4.3 "before head" 插入模式

当用户代理应用 "before head" 插入 模式 的规则时,用户代理必须按如下方式处理该令牌:

字符令牌是以下之一:U+0009 字符制表符,U+000A 换行符(LF),U+000C 换页符(FF),U+000D 回车符(CR),或 U+0020 空格

忽略该令牌。

注释令牌

插入 一个 注释

DOCTYPE 令牌

解析 错误。忽略该令牌。

标签名为 "html" 的开始标签

使用 "in body" 插入模式 的规则处理该令牌。

标签名为 "head" 的开始标签

为该令牌插入一个 HTML 元素

head 元素指针 设置为新创建的 head 元素。

插入模式 切换为 "in head"。

标签名为 "head"、"body"、"html"、"br" 之一的结束标签

按照以下 "其他任何情况" 条目中描述的方式操作。

其他任何结束标签

解析 错误。忽略该令牌。

其他任何情况

为没有属性的 "head" 开始标签令牌插入一个 HTML 元素

head 元素指针 设置为新创建的 head 元素。

插入模式 切换为 "in head"。

重新处理当前令牌。

13.2.6.4.4 "in head" 插入模式

当用户代理应用 "in head" 插入模式 的规则时,用户代理必须按如下方式处理该令牌:

字符令牌是以下之一:U+0009 字符制表符,U+000A 换行符(LF),U+000C 换页符(FF),U+000D 回车符(CR),或 U+0020 空格

插入该字符

注释令牌

插入一个注释

DOCTYPE 令牌

解析错误。忽略该令牌。

标签名为 "html" 的开始标签

使用 "in body" 插入模式 的规则处理该令牌。

标签名为 "base"、"basefont"、"bgsound"、"link" 之一的开始标签

为该令牌插入一个 HTML 元素。立即将 当前节点打开元素的堆栈 中弹出。

确认该令牌的 自闭合标志,如果已设置。

标签名为 "meta" 的开始标签

为该令牌插入一个 HTML 元素。立即将 当前节点打开元素的堆栈 中弹出。

确认该令牌的 自闭合标志,如果已设置。

如果 活动推测性 HTML 解析器 为 null,则:

  1. 如果该元素具有 charset 属性,并且从其值中获取编码 的操作得到一个 编码,并且 置信度 目前为 暂定,则 将编码更改为所得的编码。

  2. 否则,如果该元素具有 http-equiv 属性,且其值与字符串 "Content-Type" 匹配(不区分大小写),并且该元素具有 content 属性,并且将 meta 元素提取字符编码的算法 应用于该属性的值,返回一个 编码,并且 置信度 目前为 暂定,则 将编码更改为提取的编码。

为了简化实现,推测性 HTML 解析器 不会推测性地应用字符编码声明。

标签名为 "title" 的开始标签

遵循 通用 RCDATA 元素解析算法

标签名为 "noscript" 的开始标签,如果 脚本标志 已启用
标签名为 "noframes"、"style" 之一的开始标签

遵循 通用原始文本元素解析算法

标签名为 "noscript" 的开始标签,如果 脚本标志 已禁用

为该令牌插入一个 HTML 元素

插入模式 切换为 "in head noscript"。

标签名为 "script" 的开始标签

执行以下步骤:

  1. adjusted insertion location 设为 适当的节点插入位置

  2. 为该令牌创建一个元素HTML 命名空间 中,并且目标父节点为 adjusted insertion location 中的元素。

  3. 将元素的 解析器文档 设置为 Document,并将元素的 强制异步 设置为 false。

    这可以确保,如果脚本是外部脚本,则脚本中的任何 document.write() 调用将会在行内执行,而不是像在大多数其他情况下那样将文档抹掉。它还可以防止脚本在看到结束标签之前执行。

  4. 如果解析器是作为 HTML 片段解析算法 的一部分创建的,则将 script 元素的 已经开始 设置为 true。 (片段情况)

  5. 如果解析器是通过 document.write()document.writeln() 方法调用的,那么可以选择将 script 元素的 已经开始 设置为 true。(例如,用户代理可能会使用此条款来防止在网络条件较慢或页面加载时间较长的情况下,通过 document.write() 插入的跨域脚本的执行。)

  6. adjusted insertion location 插入新创建的元素。

  7. 将该元素推入 打开元素的堆栈 中,使其成为新的 当前节点

  8. 将分词器切换到 脚本数据状态

  9. 原始插入模式 设置为当前 插入模式

  10. 插入模式 切换为 "text"。

标签名为 "head" 的结束标签

当前节点(将是 head 元素)从 打开元素的堆栈 中弹出。

插入模式 切换为 "after head"。

标签名为 "body"、"html"、"br" 之一的结束标签

按照以下 "其他任何情况" 条目中描述的方式操作。

标签名为 "template" 的开始标签

template start tag 设为开始标签。

活动格式化元素列表 末尾插入一个 标记

frameset-ok 标志 设置为 "不行"。

插入模式 切换为 "in template"。

将 "in template" 推入 模板插入模式堆栈 中,使其成为新的 当前模板插入模式

adjusted insertion location 设为 适当的节点插入位置

intended parent 设为 adjusted insertion location 中的元素。

document 设为 intended parent节点文档

如果以下任何一项为 false:

为该令牌插入一个 HTML 元素

否则:

  1. declarative shadow host element调整后的当前节点

  2. template插入一个外部元素 的结果,使用 HTML 命名空间 和 true。

  3. modetemplate start tagshadowrootmode 属性的值。

  4. 如果 template start tagshadowrootclonable 属性,则让 clonable 为 true;否则为 false。

  5. 如果 template start tagshadowrootserializable 属性,则让 serializable 为 true;否则为 false。

  6. 如果 template start tagshadowrootdelegatesfocus 属性,则让 delegatesFocus 为 true;否则为 false。

  7. 如果 declarative shadow host elementShadow 主机, 则使用 template 在调整后的插入位置插入一个元素

  8. 否则:

    1. 附加一个 Shadow 根节点,使用 declarative shadow host elementmodeclonableserializabledelegatesFocus,以及 "named"。

      如果抛出异常,则捕获异常并:

      1. 在调整后的插入位置插入一个元素,使用 template

      2. 用户代理可能会向开发者控制台报告错误。

      3. 返回。

    2. shadowdeclarative shadow host elementShadow 根节点

    3. shadow声明性 设置为 true。

    4. 模板模板内容 属性设置为 shadow

    5. shadow可用于元素内部 设置为 true。

标签名为 "template" 的结束标签

如果 打开元素的堆栈 中没有 template 元素,则这是一个 解析错误;忽略该令牌。

否则,执行以下步骤:

  1. 彻底生成所有隐式结束标签

  2. 如果 当前节点 不是 template 元素,则这是一个 解析错误

  3. 打开元素的堆栈 中弹出元素,直到 template 元素被弹出为止。

  4. 清除活动格式化元素列表直至最后一个标记
  5. 模板插入模式堆栈 中弹出 当前模板插入模式

  6. 适当地重置插入模式

标签名为 "head" 的开始标签
任何其他结束标签

解析错误。忽略该令牌。

其他任何情况

当前节点(将是 head 元素)从 打开元素的堆栈 中弹出。

插入模式切换为"head 之后"。

重新处理该令牌。

13.2.6.4.5 “in head noscript”插入模式

当用户代理要应用“in head noscript插入模式的规则时,用户代理必须按以下方式处理令牌:

DOCTYPE 令牌

解析错误。忽略该令牌。

标签名为 "html" 的开始标签

使用in body插入模式的规则处理该令牌。

标签名为 "noscript" 的结束标签

当前节点(即noscript元素)从打开元素的堆栈中弹出;新当前节点将是head元素。

插入模式切换为“in head”。

字符令牌(其字符为 U+0009 制表符、U+000A 换行符 (LF)、U+000C 换页符 (FF)、U+000D 回车符 (CR) 或 U+0020 空格)
注释令牌
标签名为 "basefont"、"bgsound"、"link"、"meta"、"noframes"、"style" 的开始标签

使用in head插入模式的规则处理该令牌。

标签名为 "br" 的结束标签

按以下“其他情况”条目中的描述操作。

标签名为 "head" 或 "noscript" 的开始标签
任何其他结束标签

解析错误。忽略该令牌。

其他情况

解析错误

当前节点(即noscript元素)从打开元素的堆栈中弹出;新当前节点将是head元素。

插入模式切换为“in head”。

重新处理该令牌。

13.2.6.4.6“after head”插入模式

当用户代理要应用“after head插入模式的规则时,用户代理必须按以下方式处理令牌:

字符令牌(其字符为U+0009制表符、U+000A换行符(LF)、U+000C换页符(FF)、U+000D回车符(CR)或U+0020空格)

插入字符

注释令牌

插入注释

DOCTYPE令牌

解析错误。忽略该令牌。

标签名为“html”的开始标签

使用in body插入模式的规则处理该令牌。

标签名为“body”的开始标签

插入HTML元素来处理该令牌。

frameset-ok标志设置为“not ok”。

插入模式切换为“in body”。

标签名为“frameset”的开始标签

插入HTML元素来处理该令牌。

插入模式切换为“in frameset”。

标签名为以下之一的开始标签:“base”、“basefont”、“bgsound”、“link”、“meta”、“noframes”、“script”、“style”、“template”、“title”

解析错误

head元素指针指向的节点推送到打开元素的堆栈中。

使用in head插入模式的规则处理该令牌。

head元素指针指向的节点从打开元素的堆栈中移除。(此时它可能不是当前节点。)

head元素指针此时不能为null。

标签名为“template”的结束标签

使用in head插入模式的规则处理该令牌。

标签名为以下之一的结束标签:“body”、“html”、“br”

按以下“其他情况”条目中的描述操作。

标签名为“head”的开始标签
任何其他结束标签

解析错误。忽略该令牌。

其他情况

插入HTML元素来处理一个不带属性的“body”开始标签令牌。

插入模式切换为“in body”。

重新处理当前令牌。

13.2.6.4.7“in body”插入模式

当用户代理要应用“in body插入模式的规则时,用户代理必须按以下方式处理令牌:

字符令牌(为U+0000 NULL)

解析错误。忽略该令牌。

字符令牌(其字符为U+0009制表符、U+000A换行符(LF)、U+000C换页符(FF)、U+000D回车符(CR)或U+0020空格)

重建活动格式化元素(如果有)。

插入令牌的字符

任何其他字符令牌

重建活动格式化元素(如果有)。

插入令牌的字符

frameset-ok标志设置为“not ok”。

注释令牌

插入注释

DOCTYPE令牌

解析错误。忽略该令牌。

标签名为“html”的开始标签

解析错误

如果打开元素的堆栈中存在template元素,则忽略该令牌。

否则,对于令牌上的每个属性,检查该属性是否已存在于打开元素的堆栈的顶部元素上。如果没有,则将该属性及其对应的值添加到该元素。

标签名为以下之一的开始标签:“base”、“basefont”、“bgsound”、“link”、“meta”、“noframes”、“script”、“style”、“template”、“title”
标签名为“template”的结束标签

使用in head插入模式的规则处理该令牌。

标签名为“body”的开始标签

解析错误

如果打开元素的堆栈上只有一个节点,如果打开元素的堆栈上的第二个元素不是body元素,或者如果打开元素的堆栈中存在template元素,则忽略该令牌。(片段情况或在堆栈中存在template元素)

否则,将frameset-ok标志设置为“not ok”;然后对于令牌上的每个属性,检查该属性是否已存在于打开元素的堆栈上的body元素(第二个元素)上,如果没有,则将该属性及其对应的值添加到该元素。

标签名为“frameset”的开始标签

解析错误

如果打开元素的堆栈上只有一个节点,或者打开元素的堆栈上的第二个元素不是body元素,则忽略该令牌。(片段情况或在堆栈中存在template元素)

如果frameset-ok标志设置为“not ok”,则忽略该令牌。

否则,运行以下步骤:

  1. 从其父节点中移除打开元素的堆栈上的第二个元素(如果有)。

  2. 打开元素的堆栈底部开始,弹出所有节点,直到当前节点为止,但不包括根html元素。

  3. 插入HTML元素来处理该令牌。

  4. 插入模式切换为“in frameset”。

文件结束符(EOF)令牌

如果模板插入模式的堆栈不为空,则使用in template插入模式的规则处理该令牌。

否则,按照以下步骤操作:

  1. 如果打开元素的堆栈中存在非dd元素、dt元素、li元素、optgroup元素、option元素、p元素、rb元素、rp元素、rt元素、rtc元素、tbody元素、td元素、tfoot元素、th元素、thead元素、tr元素、body元素或html元素的节点,则这是一个解析错误

  2. 停止解析

标签名为“body”的结束标签

如果打开元素的堆栈中没有处于作用域内的body元素,则这是一个解析错误;忽略该令牌。

否则,如果打开元素的堆栈中存在非dd元素、dt元素、li元素、optgroup元素、option元素、p元素、rb元素、rp元素、rt元素、rtc元素、tbody元素、td元素、tfoot元素、th元素、thead元素、tr元素、body元素或html元素的节点,则这是一个解析错误

插入模式切换为“after body”。

标签名为“html”的结束标签

如果打开元素的堆栈中没有处于作用域内的body元素,则这是一个解析错误;忽略该令牌。

否则,如果打开元素的堆栈中存在非dd元素、dt元素、li元素、optgroup元素、option元素、p元素、rb元素、rp元素、rt元素、rtc元素、tbody元素、td元素、tfoot元素、th元素、thead元素、tr元素、body元素或html元素的节点,则这是一个解析错误

插入模式切换为“after body”。

重新处理该令牌。

标签名为以下之一的开始标签:“address”、“article”、“aside”、“blockquote”、“center”、“details”、“dialog”、“dir”、“div”、“dl”、“fieldset”、“figcaption”、“figure”、“footer”、“header”、“hgroup”、“main”、“menu”、“nav”、“ol”、“p”、“search”、“section”、“summary”、“ul”

如果打开元素的堆栈在按钮作用域内有p元素,则关闭p元素

插入HTML元素来处理该令牌。

标签名为以下之一的开始标签:“h1”、“h2”、“h3”、“h4”、“h5”、“h6”

如果打开元素的堆栈在按钮作用域内有p元素,则关闭p元素

如果当前节点是标签名为“h1”、“h2”、“h3”、“h4”、“h5”或“h6”的HTML元素,则这是一个解析错误;从打开元素的堆栈中弹出当前节点

插入HTML元素来处理该令牌。

标签名为“pre”、“listing”的开始标签

如果打开元素的堆栈在按钮作用域内有p元素,则关闭p元素

插入HTML元素来处理该令牌。

如果下一个令牌是U+000A换行符(LF)字符令牌,则忽略该令牌并继续处理下一个令牌。(pre块开头的换行符作为一种方便的编写方式被忽略。)

frameset-ok标志设置为“not ok”。

标签名为“form”的开始标签

如果form元素指针不为null,且打开元素的堆栈中没有template元素,则这是一个解析错误;忽略该令牌。

否则:

如果打开元素的堆栈在按钮作用域内有p元素,则关闭p元素

插入HTML元素来处理该令牌,如果打开元素的堆栈中没有template元素,则将form元素指针设置为指向创建的元素。

标签名为“li”的开始标签

运行以下步骤:

  1. frameset-ok标志设置为“not ok”。

  2. 初始化node当前节点(堆栈的最底部节点)。

  3. 循环:如果node是一个li元素,则运行以下子步骤:

    1. 生成隐含的结束标签,但不包括li元素。

    2. 如果当前节点不是li元素,则这是一个解析错误

    3. 打开元素的堆栈中弹出元素,直到弹出一个li元素为止。

    4. 跳到下面标记为完成的步骤。

  4. 如果node特殊类别中,但不是addressdivp元素,则跳到标记为完成的步骤。

  5. 否则,将node设置为打开元素的堆栈中的前一个条目,并返回到标记为循环的步骤。

  6. 完成:如果打开元素的堆栈在按钮作用域内有p元素,则关闭p元素

  7. 最后,插入HTML元素来处理该令牌。

标签名为“dd”、“dt”的开始标签

运行以下步骤:

  1. frameset-ok标志设置为“not ok”。

  2. 初始化node当前节点(堆栈的最底部节点)。

  3. 循环:如果nodedd元素,则运行以下子步骤:

    1. 生成隐含的结束标签,但不包括dd元素。

    2. 如果当前节点不是dd元素,则这是一个解析错误

    3. 打开元素的堆栈中弹出元素,直到弹出一个dd元素为止。

    4. 跳到下面标记为完成的步骤。

  4. 如果nodedt元素,则运行以下子步骤:

    1. 生成隐含的结束标签,但不包括dt元素。

    2. 如果当前节点不是dt元素,则这是一个解析错误

    3. 打开元素的堆栈中弹出元素,直到弹出一个dt元素为止。

    4. 跳到下面标记为完成的步骤。

  5. 如果node特殊类别中,但不是addressdivp元素,则跳到标记为完成的步骤。

  6. 否则,将node设置为打开元素的堆栈中的前一个条目,并返回到标记为循环的步骤。

  7. 完成:如果打开元素的堆栈在按钮作用域内有p元素,则关闭p元素

  8. 最后,插入HTML元素来处理该令牌。

标签名为“plaintext”的开始标签

如果打开元素的堆栈在按钮作用域内有p元素,则关闭p元素

插入HTML元素来处理该令牌。

将标记器切换到PLAINTEXT状态

一旦看到标签名为 "plaintext" 的开始标签,所有剩余的标记都将是字符标记(以及最终的文件结束标记),因为没有办法将标记器切换出PLAINTEXT状态。然而,由于树构建器保持其现有的插入模式,它可能会在处理这些字符标记时重建活动格式化元素。这意味着解析器可以将其他元素插入到plaintext元素中。

标签名为“button”的开始标签
  1. 如果打开元素的堆栈在作用域内有button元素,则运行以下子步骤:

    1. 解析错误

    2. 生成隐含的结束标签

    3. 打开元素的堆栈中弹出元素,直到弹出一个button元素为止。

  2. 重建活动格式化元素(如果有)。

  3. 插入HTML元素来处理该令牌。

  4. frameset-ok标志设置为“not ok”。

标签名为以下之一的结束标签:“address”、“article”、“aside”、“blockquote”、“button”、“center”、“details”、“dialog”、“dir”、“div”、“dl”、“fieldset”、“figcaption”、“figure”、“footer”、“header”、“hgroup”、“listing”、“main”、“menu”、“nav”、“ol”、“pre”、“search”、“section”、“summary”、“ul”

如果 打开元素的堆栈中没有在作用域内的具有相同标签名的HTML元素,则这是一个解析错误;忽略该令牌。

否则,运行以下步骤:

  1. 生成隐含的结束标签

  2. 如果当前节点不是标签名与令牌相同的HTML元素,则这是一个解析错误

  3. 打开元素的堆栈中弹出元素,直到弹出标签名与令牌相同的HTML元素为止。

标签名为“form”的结束标签

如果打开元素的堆栈中没有template元素,则运行以下子步骤:

  1. node设置为form元素指针指向的元素,或者如果未设置为元素,则为null。

  2. form元素指针设置为null。

  3. 如果node为null,或者打开元素的堆栈中没有node处于作用域内,则这是一个解析错误;返回并忽略该令牌。

  4. 生成隐含的结束标签

  5. 如果当前节点不是node,则这是一个解析错误

  6. 打开元素的堆栈中移除node

如果打开元素的堆栈中存在template元素,则改为运行以下子步骤:

  1. 如果打开元素的堆栈中没有在作用域内的form元素,则这是一个解析错误;返回并忽略该令牌。

  2. 生成隐含的结束标签

  3. 如果当前节点不是form元素,则这是一个解析错误

  4. 打开元素的堆栈中弹出元素,直到弹出一个form元素为止。

标签名为“p”的结束标签

如果打开元素的堆栈中没有在按钮作用域内的p元素,则这是一个解析错误插入一个无属性的“p”开始标签令牌对应的HTML元素

关闭p元素

标签名为“li”的结束标签

如果打开元素的堆栈中没有在列表项作用域内的li元素,则这是一个解析错误;忽略该令牌。

否则,运行以下步骤:

  1. 生成隐含的结束标签,但不包括li元素。

  2. 如果当前节点不是li元素,则这是一个解析错误

  3. 打开元素的堆栈中弹出元素,直到弹出一个li元素为止。

标签名为“dd”、“dt”的结束标签

如果打开元素的堆栈中没有在作用域内的具有相同标签名的HTML元素,则这是一个解析错误;忽略该令牌。

否则,运行以下步骤:

  1. 生成隐含的结束标签,但不包括与令牌标签名相同的HTML元素

  2. 如果当前节点不是标签名与令牌相同的HTML元素,则这是一个解析错误

  3. 打开元素的堆栈中弹出元素,直到弹出一个标签名与令牌相同的HTML元素为止。

标签名为“h1”、“h2”、“h3”、“h4”、“h5”、“h6”的结束标签

如果打开元素的堆栈中没有在作用域内的HTML元素且其标签名为“h1”、“h2”、“h3”、“h4”、“h5”或“h6”中的一个,则这是一个解析错误;忽略该令牌。

否则,运行以下步骤:

  1. 生成隐含的结束标签

  2. 如果当前节点不是标签名与令牌相同的HTML元素,则这是一个解析错误

  3. 打开元素的堆栈中弹出元素,直到弹出一个标签名与令牌相同的HTML元素为止。

标签名为“sarcasm”的结束标签

深吸一口气,然后按照下面“任何其他结束标签”条目中的描述进行操作。

标签名为“a”的开始标签

如果活动格式化元素列表包含一个a元素,该元素位于列表的末尾和最后一个标记之间(如果列表中没有标记,则位于列表的开头),则这是一个解析错误;为该令牌运行收养机构算法,然后从活动格式化元素列表打开元素的堆栈中移除该元素(如果收养机构算法尚未移除它(如果该元素不在表格作用域内,可能不会移除))。

在不符合标准的流<a href="a">a<table><a href="b">b</table>x中,第一个a元素将在看到第二个时关闭,并且“x”字符将在指向“b”的链接中,而不是指向“a”。尽管外部的a元素不在表格作用域内(这意味着在表格开始时的常规</a>结束标签不会关闭外部的a元素)。结果是两个a元素间接嵌套在彼此内部——当解析不符合标准的标记时,通常会导致不符合标准的DOM。

重建活动格式化元素,如果有的话。

为该令牌插入一个HTML元素将该元素推送到活动格式化元素列表中

标签名为以下之一的开始标签:“b”、“big”、“code”、“em”、“font”、“i”、“s”、“small”、“strike”、“strong”、“tt”、“u”

重建活动格式化元素,如果有的话。

为该令牌插入一个HTML元素将该元素推送到活动格式化元素列表中

标签名为“nobr”的开始标签

重建活动格式化元素,如果有的话。

如果打开元素的堆栈具有在作用域内的nobr元素,则这是一个解析错误;为该令牌运行收养机构算法,然后再次重建活动格式化元素,如果有的话。

为该令牌插入一个HTML元素将该元素推送到活动格式化元素列表中

标签名为以下之一的结束标签:“a”、“b”、“big”、“code”、“em”、“font”、“i”、“nobr”、“s”、“small”、“strike”、“strong”、“tt”、“u”

为该令牌运行收养机构算法

标签名为以下之一的开始标签:“applet”、“marquee”、“object”

重建活动格式化元素,如果有的话。

为该令牌插入一个HTML元素

活动格式化元素列表末尾插入一个标记

frameset-ok 标志设置为“not ok”。

标签名为以下之一的结束标签:“applet”、“marquee”、“object”

如果打开元素的堆栈中没有具有相同标签名的元素在作用域内,则这是一个解析错误;忽略该令牌。

否则,运行以下步骤:

  1. 生成隐含的结束标签

  2. 如果当前节点不是标签名与令牌相同的HTML元素,则这是一个解析错误

  3. 打开元素的堆栈中弹出元素,直到弹出一个标签名与令牌相同的HTML元素为止。

  4. 清除活动格式化元素列表中的元素,直到最后一个标记
标签名为“table”的开始标签

如果文档未设置为怪异模式,并且打开元素的堆栈具有p元素在按钮作用域内,则关闭p元素

为该令牌插入一个HTML元素

frameset-ok 标志设置为“not ok”。

插入模式切换为“表格内”。

标签名为“br”的结束标签

解析错误。删除该令牌的属性,并按下一个条目中的描述进行操作;即,按没有属性的“br”开始标签令牌而不是实际的结束标签令牌进行操作。

标签名为以下之一的开始标签:“area”、“br”、“embed”、“img”、“keygen”、“wbr”

重建活动格式化元素,如果有的话。

为该令牌插入一个HTML元素。立即从当前节点中弹出元素堆栈中的打开元素

确认令牌的自关闭标志,如果已设置。

frameset-ok 标志设置为“not ok”。

标签名为“input”的开始标签

重建活动格式化元素,如果有的话。

为该令牌插入一个HTML元素。立即从当前节点中弹出元素堆栈中的打开元素

确认令牌的自关闭标志,如果已设置。

如果该令牌没有名为“type”的属性,或者如果有该属性,但其值与字符串“hidden”不匹配,则将frameset-ok 标志设置为“not ok”。

标签名为以下之一的开始标签:“param”、“source”、“track”

为该令牌插入一个HTML元素。立即从当前节点中弹出元素堆栈中的打开元素

确认令牌的自关闭标志,如果已设置。

标签名为“hr”的开始标签

如果打开元素的堆栈具有p元素在按钮作用域内,则关闭p元素

为该令牌插入一个HTML元素。立即从当前节点中弹出元素堆栈中的打开元素

确认令牌的自关闭标志,如果已设置。

frameset-ok 标志设置为“not ok”。

标签名为“image”的开始标签

解析错误。将令牌的标签名更改为“img”并重新处理它。(别问。)

标签名为“textarea”的开始标签

运行以下步骤:

  1. 为该令牌插入一个HTML元素

  2. 如果下一个令牌是一个U+000A换行符(LF)字符令牌,则忽略该令牌并继续处理下一个。(在textarea元素开头的换行符将被忽略,以方便作者。)

  3. 将令牌生成器切换到RCDATA状态

  4. 原始插入模式设为当前的插入模式

  5. frameset-ok 标志设置为“not ok”。

  6. 插入模式切换为“文本”。

标签名为“xmp”的开始标签

如果打开元素的堆栈具有p元素在按钮作用域内,则关闭p元素

重建活动格式化元素,如果有的话。

frameset-ok 标志设置为“not ok”。

遵循通用原始文本元素解析算法

标签名为“iframe”的开始标签

frameset-ok 标志设置为“not ok”。

遵循通用原始文本元素解析算法

标签名为“noembed”的开始标签
标签名为“noscript”的开始标签,如果脚本标志已启用

遵循通用原始文本元素解析算法

标签名为“select”的开始标签

重建活动格式化元素,如果有的话。

为该令牌插入一个HTML元素

frameset-ok 标志设置为“not ok”。

如果插入模式为“表格内”、“标题内”、“表格体内”、“行内”或“单元格内”之一,则将插入模式切换为“表格中的选择”。否则,将插入模式切换为“选择内”。

标签名为以下之一的开始标签:“optgroup”、“option”

如果当前节点是一个option元素,则从当前节点中弹出元素堆栈中的打开元素

重建活动格式化元素,如果有的话。

为该令牌插入一个HTML元素

标签名为以下之一的开始标签:“rb”、“rtc”

如果打开元素的堆栈具有在作用域内的ruby元素,则生成隐含的结束标签。如果当前节点现在不是ruby元素,则这是一个解析错误

为该令牌插入一个HTML元素

标签名为以下之一的开始标签:“rp”、“rt”

如果打开元素的堆栈具有在作用域内的ruby元素,则生成隐含的结束标签,但不包括rtc元素。如果当前节点现在不是rtc元素或ruby元素,则这是一个解析错误

为该令牌插入一个HTML元素

标签名为“math”的开始标签

重建活动格式化元素,如果有的话。

调整该令牌的MathML属性。(这会修复MathML属性的大小写问题。)

调整该令牌的外部属性。(这会修复命名空间属性的使用,特别是XLink。)

为该令牌插入一个外部元素,并使用MathML命名空间和false。

如果令牌设置了自关闭标志,则从当前节点中弹出元素堆栈中的打开元素确认令牌的自关闭标志

标签名为“svg”的开始标签

重建活动格式化元素,如果有的话。

调整该令牌的SVG属性。(这会修复SVG属性的大小写问题。)

调整该令牌的外部属性。(这会修复命名空间属性的使用,特别是在SVG中的XLink。)

为该令牌插入一个外部元素,并使用SVG命名空间和false。

如果令牌设置了自关闭标志,则从当前节点中弹出元素堆栈中的打开元素确认令牌的自关闭标志

标签名为以下之一的开始标签:“caption”、“col”、“colgroup”、“frame”、“head”、“tbody”、“td”、“tfoot”、“th”、“thead”、“tr”

解析错误。忽略该令牌。

任何 其他的开始标签

重建活动格式化元素,如果有的话。

为该令牌插入一个HTML元素

该元素将是一个普通元素。有一个例外:如果脚本标志被禁用,它也可以是一个noscript元素。

任何其他的结束标签

运行以下步骤:

  1. 初始化node当前节点(堆栈底部的节点)。

  2. 循环:如果node是一个HTML元素,并且其标签名与令牌相同,则:

    1. 生成隐含的结束标签,但不包括与令牌标签名相同的HTML元素

    2. 如果node不是当前节点,则这是一个解析错误

    3. 当前节点node之间弹出所有节点,包括node,然后停止这些步骤。

  3. 否则,如果node属于特殊类别,则这是一个解析错误;忽略该令牌并返回。

  4. node设置为打开元素的堆栈中的上一个条目。

  5. 返回到标记为循环的步骤。

当上面的步骤说用户代理应该关闭p元素时,这意味着用户代理必须运行以下步骤:

  1. 生成隐含的结束标签,但不包括p元素。

  2. 如果当前节点不是p元素,则这是一个解析错误

  3. 打开元素的堆栈中弹出元素,直到弹出一个p元素。

收养机构算法,其唯一参数为正在运行算法的令牌token,包含以下步骤:

  1. subject设为token的标签名。

  2. 如果当前节点是一个HTML元素,其标签名为subject,并且当前节点不在活动格式化元素列表中,则弹出当前节点,并返回。

  3. outerLoopCounter设为0。

  4. 在真时运行:

    1. 如果outerLoopCounter大于或等于8,则返回。

    2. outerLoopCounter加1。

    3. formattingElement设为活动格式化元素列表中从末尾到列表中最后一个标记之间的最后一个元素(如果有),否则从列表开头开始,且其标签名为subject

      如果没有这样的元素,则返回并按照上述“任何其他结束标签”条目中的描述进行操作。

    4. 如果formattingElement不在打开元素的堆栈中,则这是一个解析错误;从列表中移除该元素,并返回。

    5. 如果formattingElement打开元素的堆栈中,但该元素不在作用域内,则 这是一个解析错误;返回。

    6. 如果formattingElement不是当前节点,则这是一个解析错误。(但不要返回。)

    7. furthestBlock设为打开元素的堆栈中最上面的节点,该节点在堆栈中低于formattingElement,并且是属于特殊类别的元素。可能没有一个。

    8. 如果没有furthestBlock,则用户代理必须首先弹出打开元素的堆栈中的所有节点,从当前节点到包括formattingElement,然后从活动格式化元素列表中移除formattingElement,最后返回。

    9. commonAncestor设为formattingElement打开元素的堆栈中上方的元素。

    10. 活动格式化元素列表中,为formattingElement的位置做一个书签,相对于列表中的前后元素。

    11. nodelastNode设为furthestBlock

    12. innerLoopCounter设为0。

    13. 在真时运行:

      1. innerLoopCounter加1。

      2. node设为打开元素的堆栈node上方的元素,或者如果node不再在打开元素的堆栈中(例如,因为它被此算法移除),则为node在从堆栈中移除之前在打开元素的堆栈中上方的元素。

      3. 如果nodeformattingElement,则中断

      4. 如果innerLoopCounter大于3,并且node活动格式化元素列表中,则从列表中移除node

      5. 如果node不在活动格式化元素列表中,则从打开元素的堆栈中移除node继续

      6. 为创建node的令牌创建一个元素,使用HTML命名空间,并以commonAncestor作为预期的父元素;将活动格式化元素列表node的条目替换为新元素的条目,将打开元素的堆栈node的条目替换为新元素的条目,并将node设为新元素。

      7. 如果last nodefurthestBlock,则将前述书签移至活动格式化元素列表中新node之后的位置。

      8. lastNode附加到node

      9. lastNode设为node

    14. 适当的位置插入节点,但使用commonAncestor作为覆盖目标

    15. 为创建formattingElement的令牌创建一个元素,使用HTML命名空间,并以furthestBlock作为预期的父元素。

    16. furthestBlock的所有子节点附加到上一步创建的元素中。

    17. 将新元素附加到furthestBlock

    18. 活动格式化元素列表中移除formattingElement,并将新元素插入到活动格式化元素列表中的书签位置。

    19. 打开元素的堆栈中移除formattingElement,并将新元素插入到打开元素的堆栈中,位置位于furthestBlock之下。

该算法的名称“收养机构算法”源于它如何使元素更改父元素,这与处理错误嵌套内容的其他可能算法形成对比。

13.2.6.4.8文本”插入模式

当用户代理应用“文本插入模式的规则时,用户代理必须按以下方式处理令牌:

一个字符令牌

插入该令牌的字符

这永远不会是U+0000 NULL字符;标记器会将这些字符转换为U+FFFD替换字符。

文件结尾令牌

解析错误

如果当前节点script元素,则将其已启动设置为true。

打开元素的堆栈中弹出当前节点

插入模式切换到原始插入模式并重新处理该令牌。

一个标签名为“script”的结束标签

如果活动推测性HTML解析器为空,并且JavaScript执行上下文堆栈为空,则执行微任务检查点

script设为当前节点(这将是一个script元素)。

打开元素的堆栈中弹出当前节点

插入模式切换到原始插入模式

old insertion point与当前的插入点具有相同的值。将插入点设在下一个输入字符之前。

将解析器的脚本嵌套级别增加1。

如果活动推测性HTML解析器为空,则准备脚本元素script。这可能会导致某些脚本执行,从而可能导致新的字符被插入到标记器中,并可能导致标记器输出更多令牌,从而导致解析器的重新进入调用

将解析器的脚本嵌套级别减少1。如果解析器的脚本嵌套级别为零,则将解析器暂停标志设置为false。

插入点设置为old insertion point的值。(换句话说,将插入点恢复到其先前的值。这可能是“未定义”的值。)

在此阶段,如果挂起的解析阻塞脚本不为空,则:

如果脚本嵌套级别不为零:

解析器暂停标志设置为true,并中止对任何嵌套调用标记器的处理,将控制权交回调用方。(当调用方返回到“外部”树构建阶段时,标记化将恢复。)

此特定解析器的树构建阶段正在重新进入调用,例如,通过调用document.write()

否则:

挂起的解析阻塞脚本不为空时:

  1. script设为挂起的解析阻塞脚本

  2. 挂起的解析阻塞脚本设置为空。

  3. 启动推测性HTML解析器以处理该HTML解析器实例。

  4. 阻止该HTML解析器实例的标记化,以便事件循环不会运行调用任务的标记器。

  5. 如果解析器的文档有阻止脚本的样式表script准备好被解析器执行为false:旋转事件循环,直到解析器的文档没有阻止脚本的样式表,并且script准备好被解析器执行变为true。

  6. 如果此解析器已在此期间被中止,则返回。

    如果例如在运行旋转事件循环算法期间,文档销毁,或在文档上调用了document.open()方法,这种情况可能会发生。

  7. 停止推测性HTML解析器以处理该HTML解析器实例。

  8. 解除该HTML解析器实例的标记化,以便可以再次运行调用标记器的任务

  9. 插入点设在下一个输入字符之前。

  10. 将解析器的脚本嵌套级别增加1(在此步骤之前它应该为零,因此这将其设置为1)。

  11. 执行脚本元素script

  12. 将解析器的脚本嵌套级别减少1。如果解析器的脚本嵌套级别为零(此时它应该总是为零),则将解析器暂停标志设置为false。

  13. 插入点再次设为未定义。

任何其他结束标签

打开元素的堆栈中弹出当前节点

插入模式切换到原始插入模式

13.2.6.4.9在表格中”插入模式

当用户代理应用“在表格中插入模式的规则时,用户代理必须按以下方式处理令牌:

一个字符令牌,如果当前节点tabletbodytemplatetfootthead, 或tr 元素

pending table character tokens设为一个空的令牌列表。

原始插入模式设为当前的插入模式

插入模式切换到“在表格文本中”,并重新处理该令牌。

一个注释令牌

插入一个注释

一个DOCTYPE令牌

解析错误。忽略该令牌。

标签名为“caption”的开始标签

将堆栈清除回表格上下文。(见下文。)

活动格式化元素列表的末尾插入一个标记

为该令牌插入一个HTML元素,然后将插入模式切换到“在标题中”。

标签名为“colgroup”的开始标签

将堆栈清除回表格上下文。(见下文。)

为该令牌插入一个HTML元素,然后将插入模式切换到“在列组中”。

标签名为“col”的开始标签

将堆栈清除回表格上下文。(见下文。)

为一个没有属性的“colgroup”开始标签令牌插入一个HTML元素,然后将插入模式切换到“在列组中”。

重新处理当前令牌。

标签名为“tbody”、“tfoot”、“thead”之一的开始标签

将堆栈清除回表格上下文。(见下文。)

为该令牌插入一个HTML元素,然后将插入模式切换到“在表格正文中”。

标签名为“td”、“th”、“tr”之一的开始标签

将堆栈清除回表格上下文。(见下文。)

为一个没有属性的“tbody”开始标签令牌插入一个HTML元素,然后将插入模式切换到“在表格正文中”。

重新处理当前令牌。

标签名为“table”的开始标签

解析错误

如果打开元素的堆栈中没有在表格范围内的table元素,则忽略该令牌。

否则:

从该堆栈中弹出元素,直到弹出一个table元素。

适当地重置插入模式

重新处理该令牌。

标签名为“table”的结束标签

如果打开元素的堆栈中没有在表格范围内的table元素,这是一个解析错误;忽略该令牌。

否则:

从该堆栈中弹出元素,直到弹出一个table元素。

适当地重置插入模式

标签名为“body”、“caption”、“col”、“colgroup”、“html”、“tbody”、“td”、“tfoot”、“th”、“thead”、“tr”之一的结束标签

解析错误。忽略该令牌。

标签名为“style”、“script”、“template”之一的开始标签
标签名为“template”的结束标签

使用在头部中插入模式的规则处理该令牌。

标签名为“input”的开始标签

如果该令牌没有名为“type”的属性,或者如果有,但该属性的值与字符串“hidden”不区分ASCII大小写匹配,则:按下面“其他任何情况”条目中描述的方式处理。

否则:

解析错误

为该令牌插入一个HTML元素

将该input元素从打开元素的堆栈中弹出。

确认令牌的自关闭标志,如果已设置。

标签名为“form”的开始标签

解析错误

如果打开元素的堆栈中有一个template元素,或者如果form元素指针不为空,则忽略该令牌。

否则:

为该令牌插入一个HTML元素,并将form元素指针指向创建的元素。

将该form元素从打开元素的堆栈中弹出。

文件结束令牌

使用在正文中插入模式的规则处理该令牌。

其他任何情况

解析错误。启用寄养使用在正文中插入模式的规则处理该令牌,然后禁用寄养

当上述步骤要求UA 将堆栈清除回表格上下文时,这意味着UA必须在当前节点不是tabletemplate, 或html元素时,从打开元素的堆栈中弹出元素。

这是与在表格范围内具有元素步骤中使用的相同的元素列表。

当前节点在此过程中为html元素是一个片段情况

13.2.6.4.10表格文本中” 插入模式

当用户代理要应用“表格文本中插入模式的规则时,用户代理必须按以下方式处理该令牌:

一个U+0000 NULL的字符令牌

解析错误。忽略该令牌。

任何其他字符令牌

将字符令牌追加到待处理表格字符令牌列表中。

其他任何情况

如果待处理表格字符令牌列表中的任何令牌是非ASCII空白字符的字符令牌,则这是一个解析错误:使用“表格中”插入模式的“其他任何情况”条目中的规则重新处理待处理表格字符令牌列表中的字符令牌。

否则,插入待处理表格字符令牌列表中给出的字符。

插入模式切换到原始插入模式并重新处理该令牌。

13.2.6.4.11在标题中” 插入模式

当用户代理要应用“在标题中插入模式的规则时,用户代理必须按以下方式处理该令牌:

结束标签,其标签名为“caption”

如果开放元素栈中没有在表格范围内的caption元素,则这是解析错误;忽略该令牌。(片段情况)

否则:

生成隐含结束标签

现在,如果当前节点不是caption元素,则这是解析错误

从此栈中弹出元素,直到弹出caption元素为止。

清除活动格式化元素列表直到最后一个标记

插入模式切换到“在表格中”。

起始标签,其标签名是以下之一:“caption”、“col”、“colgroup”、“tbody”、“td”、“tfoot”、“th”、“thead”、“tr”
结束标签,其标签名为“table”

如果开放元素栈中没有在表格范围内的caption元素,则这是解析错误;忽略该令牌。(片段情况)

否则:

生成隐含结束标签

现在,如果当前节点不是caption元素,则这是解析错误

从此栈中弹出元素,直到弹出caption元素为止。

清除活动格式化元素列表直到最后一个标记

插入模式切换到“在表格中”。

重新处理该令牌。

结束标签,其标签名是以下之一:“body”、“col”、“colgroup”、“html”、“tbody”、“td”、“tfoot”、“th”、“thead”、“tr”

解析错误。忽略该令牌。

其他任何情况

使用“使用规则”处理该令牌,“在正文中插入模式

13.2.6.4.12在列组中” 插入模式

当用户代理要应用“在列组中插入模式的规则时,用户代理必须按以下方式处理该令牌:

字符令牌为以下之一:U+0009 字符制表符、U+000A 换行符 (LF)、U+000C 换页符 (FF)、U+000D 回车符 (CR) 或 U+0020 空格

插入字符

注释令牌

插入注释

DOCTYPE 令牌

解析错误。忽略该令牌。

起始标签,其标签名为“html”

使用“使用规则”处理该令牌,“在正文中插入模式

起始标签,其标签名为“col”

为令牌插入一个 HTML 元素。立即将当前节点开放元素栈中弹出。

确认令牌的自闭合标志,如果已设置。

结束标签,其标签名为“colgroup”

如果当前节点不是colgroup元素,则这是解析错误;忽略该令牌。

否则,从开放元素栈中弹出当前节点。将插入模式切换到“在表格中”。

结束标签,其标签名为“col”

解析错误。忽略该令牌。

起始标签,其标签名为“template”
结束标签,其标签名为“template”

使用“使用规则”处理该令牌,“在头部中插入模式

文件结束令牌

使用“使用规则”处理该令牌,“在正文中插入模式

其他任何情况

如果当前节点不是colgroup元素,则这是解析错误;忽略该令牌。

否则,从开放元素栈中弹出当前节点

插入模式切换到“在表格中”。

重新处理该令牌。

13.2.6.4.13在表格主体中” 插入模式

当用户代理要应用“在表格主体中插入模式的规则时,用户代理必须按以下方式处理该令牌:

起始标签,其标签名为“tr”

清除堆栈返回表格主体上下文。(见下文。)

为令牌插入一个 HTML 元素,然后将插入模式切换到“在行中”。

起始标签,其标签名为“th”或“td”

解析错误

清除堆栈返回表格主体上下文。(见下文。)

为没有属性的“tr”起始标签令牌插入一个 HTML 元素,然后将插入模式切换到“在行中”。

重新处理当前令牌。

结束标签,其标签名为“tbody”、“tfoot”或“thead”

如果开放元素栈中没有在表格范围内的元素,其标签名与令牌相同,这是解析错误;忽略该令牌。

否则:

清除堆栈返回表格主体上下文。(见下文。)

开放元素栈中弹出当前节点。将插入模式切换到“在表格中”。

起始标签,其标签名为“caption”、“col”、“colgroup”、“tbody”、“tfoot”或“thead”
结束标签,其标签名为“table”

如果开放元素栈中没有在表格范围内的tbodytheadtfoot元素,这是解析错误;忽略该令牌。

否则:

清除堆栈返回表格主体上下文。(见下文。)

开放元素栈中弹出当前节点。将插入模式切换到“在表格中”。

重新处理令牌。

结束标签,其标签名为“body”、“caption”、“col”、“colgroup”、“html”、“td”、“th”或“tr”

解析错误。忽略该令牌。

其他任何情况

使用“使用规则”处理该令牌,“在表格中插入模式

当上述步骤要求 UA 清除堆栈返回表格主体上下文时,意味着 UA 必须在当前节点不是tbodytfoottheadtemplatehtml元素时,从开放元素栈中弹出元素。

片段情况是,在此过程中当前节点html元素。

13.2.6.4.14在行中”插入模式

当用户代理要应用“在行中插入模式的规则时,用户代理必须按以下方式处理该令牌:

起始标签,其标签名为:“th”、“td”

清除堆栈返回表格行上下文。(见下文。)

为令牌插入一个 HTML 元素,然后将插入模式切换到“在单元格中”。

活动格式化元素列表末尾插入一个标记

结束标签,其标签名为“tr”

如果开放元素栈中没有在表格范围内的tr元素,这是解析错误;忽略该令牌。

否则:

清除堆栈返回表格行上下文。(见下文。)

开放元素栈中弹出当前节点(它将是一个tr元素)。将插入模式切换到“在表格主体中”。

起始标签,其标签名为:“caption”、“col”、“colgroup”、“tbody”、“tfoot”、“thead”、“tr”
结束标签,其标签名为“table”

如果开放元素栈中没有在表格范围内的tr元素,这是解析错误;忽略该令牌。

否则:

清除堆栈返回表格行上下文。(见下文。)

开放元素栈中弹出当前节点(它将是一个tr元素)。将插入模式切换到“在表格主体中”。

重新处理该令牌。

结束标签,其标签名为:“tbody”、“tfoot”、“thead”

如果开放元素栈中没有在表格范围内的元素,该元素是一个标签名与令牌相同的HTML 元素,这是解析错误;忽略该令牌。

如果开放元素栈中没有在表格范围内的tr元素,忽略该令牌。

否则:

清除堆栈返回表格行上下文。(见下文。)

开放元素栈中弹出当前节点(它将是一个tr元素)。将插入模式切换到“在表格主体中”。

重新处理该令牌。

结束标签,其标签名为:“body”、“caption”、“col”、“colgroup”、“html”、“td”、“th”

解析错误。忽略该令牌。

其他任何情况

使用“在表格中插入模式的规则处理该令牌。

当上述步骤要求 UA 清除堆栈返回表格行上下文时,意味着 UA 必须在当前节点不是trtemplatehtml元素时,从开放元素栈中弹出元素。

片段情况是,在此过程中当前节点html元素。

13.2.6.4.15在单元格中”插入模式

当用户代理要应用“在单元格中插入模式的规则时,用户代理必须按以下方式处理该令牌:

结束标签,其标签名为:“td”、“th”

如果开放元素栈中没有在表格范围内的元素,该元素是一个标签名与令牌相同的HTML 元素,则这是解析错误;忽略该令牌。

否则:

生成隐式结束标签

现在,如果当前节点不是一个标签名与令牌相同的HTML 元素,则这是解析错误

开放元素栈中弹出元素,直到一个标签名与令牌相同的HTML 元素被从栈中弹出。

清除活动格式化元素列表直到最后一个标记

插入模式切换到“在行中”。

起始标签,其标签名为:“caption”、“col”、“colgroup”、“tbody”、“td”、“tfoot”、“th”、“thead”、“tr”

断言开放元素栈在表格范围内有一个tdth元素

关闭单元格(见下文)并重新处理令牌。

结束标签,其标签名为:“body”、“caption”、“col”、“colgroup”、“html”

解析错误。忽略该令牌。

结束标签,其标签名为:“table”、“tbody”、“tfoot”、“thead”、“tr”

如果开放元素栈中没有在表格范围内的元素,该元素是一个标签名与令牌相同的HTML 元素,则这是解析错误;忽略该令牌。

否则,关闭单元格(见下文)并重新处理该令牌。

其他任何情况

使用“在正文中插入模式的规则处理该令牌。

上述步骤中提到的关闭单元格,意味着运行以下算法:

  1. 生成隐式结束标签

  2. 如果当前节点现在不是td元素或th元素,则这是解析错误

  3. 开放元素栈中弹出元素,直到td元素或th元素被从栈中弹出。

  4. 清除活动格式化元素列表直到最后一个标记

  5. 插入模式切换到“在行中”。

开放元素栈不能同时包含tdth元素在表格范围内,也不能在调用关闭单元格算法时既不包含这两者。

13.2.6.4.16在选择框中”插入模式

当用户代理要应用“在选择框中插入模式的规则时,用户代理必须按以下方式处理该令牌:

字符令牌(U+0000 NULL)

解析错误。忽略该令牌。

其他字符令牌

插入该令牌的字符

注释令牌

插入注释

DOCTYPE 令牌

解析错误。忽略该令牌。

起始标签,其标签名为“html”

使用“在正文中插入模式的规则处理该令牌。

起始标签,其标签名为“option”

如果当前节点是一个option元素,则从开放元素栈中弹出该节点。

为该令牌插入一个 HTML 元素

起始标签,其标签名为“optgroup”

如果当前节点是一个option元素,则从开放元素栈中弹出该节点。

如果当前节点是一个optgroup元素,则从开放元素栈中弹出该节点。

为该令牌插入一个 HTML 元素

起始标签,其标签名为“hr”

如果当前节点是一个option元素,则从开放元素栈中弹出该节点。

如果当前节点是一个optgroup元素,则从开放元素栈中弹出该节点。

为该令牌插入一个 HTML 元素。立即从开放元素栈中弹出当前节点

确认该令牌的自闭合标志,如果已设置。

结束标签,其标签名为“optgroup”

首先,如果当前节点是一个option元素,并且在开放元素栈中紧接在其前面的节点是一个optgroup元素,则从开放元素栈中弹出当前节点

如果当前节点是一个optgroup元素,则从开放元素栈中弹出该节点。否则,这是一个解析错误;忽略该令牌。

结束标签,其标签名为“option”

如果当前节点是一个option元素,则从开放元素栈中弹出该节点。否则,这是一个解析错误;忽略该令牌。

结束标签,其标签名为“select”

如果开放元素栈中没有在选择范围内select元素,这是一个解析错误;忽略该令牌。(片段情况

否则:

开放元素栈中弹出元素,直到弹出一个select元素。

适当地重置插入模式

起始标签,其标签名为“select”

解析错误

如果开放元素栈中没有在选择范围内select元素,忽略该令牌。(片段情况

否则:

开放元素栈中弹出元素,直到弹出一个select元素。

适当地重置插入模式

它只是像结束标签一样处理。

起始标签,其标签名为以下之一:“input”、“keygen”、“textarea”

解析错误

如果开放元素栈中没有在选择范围内select元素,忽略该令牌。(片段情况

否则:

开放元素栈中弹出元素,直到弹出一个select元素。

适当地重置插入模式

重新处理该令牌。

起始标签,其标签名为以下之一:“script”、“template”
结束标签,其标签名为“template”

使用“在头部插入模式的规则处理该令牌。

文件结束令牌

使用“在正文中插入模式的规则处理该令牌。

其他任何内容

解析错误。忽略该令牌。

13.2.6.4.17在表格中的选择框”插入模式

当用户代理要应用“在表格中的选择框插入模式的规则时,用户代理必须按以下方式处理该令牌:

起始标签,其标签名为以下之一:“caption”、“table”、“tbody”、“tfoot”、“thead”、“tr”、“td”、“th”

解析错误

开放元素栈中弹出元素,直到弹出一个select元素。

适当地重置插入模式

重新处理该令牌。

结束标签,其标签名为以下之一:“caption”、“table”、“tbody”、“tfoot”、“thead”、“tr”、“td”、“th”

解析错误

如果开放元素栈中没有在表格范围内的HTML元素与该令牌的标签名相同,则忽略该令牌。

否则:

开放元素栈中弹出元素,直到弹出一个select元素。

适当地重置插入模式

重新处理该令牌。

其他任何内容

使用“在选择框中插入模式的规则处理该令牌。

13.2.6.4.18在模板中”插入模式

当用户代理要应用“在模板中插入模式的规则时,用户代理必须按以下方式处理该令牌:

一个字符令牌
一个注释令牌
一个DOCTYPE令牌

使用“在主体中插入模式的规则处理该令牌。

起始标签,其标签名为以下之一:“base”、“basefont”、“bgsound”、“link”、“meta”、“noframes”、“script”、“style”、“template”、“title”
结束标签,其标签名为“template”

使用“在头部中插入模式的规则处理该令牌。

起始标签,其标签名为以下之一:“caption”、“colgroup”、“tbody”、“tfoot”、“thead”

当前模板插入模式中弹出模板插入模式栈

将“在表格中”推入模板插入模式栈,使其成为新的当前模板插入模式

插入模式切换为“在表格中”,并重新处理该令牌。

起始标签,其标签名为“col”

当前模板插入模式中弹出模板插入模式栈

将“在列组中”推入模板插入模式栈,使其成为新的当前模板插入模式

插入模式切换为“在列组中”,并重新处理该令牌。

起始标签,其标签名为“tr”

当前模板插入模式中弹出模板插入模式栈

将“在表格主体中”推入模板插入模式栈,使其成为新的当前模板插入模式

插入模式切换为“在表格主体中”,并重新处理该令牌。

起始标签,其标签名为以下之一:“td”、“th”

当前模板插入模式中弹出模板插入模式栈

将“在行中”推入模板插入模式栈,使其成为新的当前模板插入模式

插入模式切换为“在行中”,并重新处理该令牌。

其他任何起始标签

当前模板插入模式中弹出模板插入模式栈

将“在主体中 ”推入模板插入模式栈,使其成为新的当前模板插入模式

插入模式切换为“在主体中”,并重新处理该令牌。

其他任何结束标签

解析错误。忽略该令牌。

一个文件结束令牌

如果在开放元素栈上没有template元素,则停止解析。(片段情况

否则,这是一个解析错误

开放元素栈中弹出元素,直到弹出一个template元素。

清除活动格式化元素列表直至最后一个标记

当前模板插入模式中弹出模板插入模式栈

适当地重置插入模式

重新处理该令牌。

13.2.6.4.19在主体之后”插入模式

当用户代理要应用“在主体之后插入模式的规则时,用户代理必须按以下方式处理该令牌:

一个字符令牌,该字符为U+0009字符制表符、U+000A换行符(LF)、U+000C换页符(FF)、U+000D回车符(CR)或U+0020空格

使用“在主体中插入模式的规则处理该令牌。

一个注释令牌

作为开放元素栈中第一个元素(html元素)的最后一个子元素插入注释。

一个DOCTYPE令牌

解析错误。忽略该令牌。

起始标签,其标签名为“html”

使用“在主体中插入模式的规则处理该令牌。

结束标签,其标签名为“html”

如果解析器是作为HTML片段解析算法的一部分创建的,这是一个解析错误;忽略该令牌。(片段情况

否则,将插入模式切换为“在主体之后之后”。

一个文件结束令牌

停止解析

其他任何内容

解析错误。将插入模式切换为“在主体中”,并重新处理该令牌。

13.2.6.4.20在框架集内”插入模式

当用户代理要应用“在框架集内插入模式的规则时,用户代理必须按以下方式处理该令牌:

一个字符令牌,该字符为U+0009字符制表符、U+000A换行符(LF)、U+000C换页符(FF)、U+000D回车符(CR)或U+0020空格

插入字符

一个注释令牌

插入注释

一个DOCTYPE令牌

解析错误。忽略该令牌。

起始标签,其标签名为“html”

使用“在主体中插入模式的规则处理该令牌。

起始标签,其标签名为“frameset”

为该令牌插入一个HTML元素

结束标签,其标签名为“frameset”

如果当前节点是根html元素,则这是一个解析错误;忽略该令牌。(片段情况

否则,将当前节点开放元素栈中弹出。

如果解析器不是作为HTML片段解析算法的一部分创建的(片段情况),并且当前节点不再是frameset元素,则将插入模式切换为“在框架集之后”。

起始标签,其标签名为“frame”

为该令牌插入一个HTML元素。立即将当前节点开放元素栈中弹出。

确认令牌的自关闭标志(如果设置了该标志)。

起始标签,其标签名为“noframes”

使用“在头部中插入模式的规则处理该令牌。

一个文件结束令牌

如果当前节点不是根html元素,则这是一个解析错误

当前节点只能在片段情况下是根html元素。

停止解析

其他任何内容

解析错误。忽略该令牌。

13.2.6.4.21在框架集之后”插入模式

当用户代理要应用“在框架集之后插入模式的规则时,用户代理必须按以下方式处理该令牌:

一个字符令牌,该字符为U+0009字符制表符、U+000A换行符(LF)、U+000C换页符(FF)、U+000D回车符(CR)或U+0020空格

插入字符

一个注释令牌

插入注释

一个DOCTYPE令牌

解析错误。忽略该令牌。

起始标签,其标签名为“html”

使用“在主体中插入模式的规则处理该令牌。

结束标签,其标签名为“html”

插入模式切换为“在框架集之后之后”。

起始标签,其标签名为“noframes”

使用“在头部中插入模式的规则处理该令牌。

一个文件结束令牌

停止解析

其他任何内容

解析错误。忽略该令牌。

13.2.6.4.22在主体之后之后”插入模式

当用户代理要应用“在主体之后之后插入模式的规则时,用户代理必须按以下方式处理该令牌:

一个注释令牌

将注释作为文档对象的最后一个子节点插入。

一个DOCTYPE令牌
一个字符令牌,该字符为U+0009字符制表符、U+000A换行符(LF)、U+000C换页符(FF)、U+000D回车符(CR)或U+0020空格
起始标签,其标签名为“html”

使用“在主体中插入模式的规则处理该令牌。

一个文件结束令牌

停止解析

其他任何内容

解析错误。将插入模式切换为“在主体中”并重新处理该令牌。

13.2.6.4.23在框架集之后之后”插入模式

当用户代理要应用“在框架集之后之后插入模式的规则时,用户代理必须按以下方式处理该令牌:

一个注释令牌

将注释作为文档对象的最后一个子节点插入。

一个DOCTYPE令牌
一个字符令牌,该字符为U+0009字符制表符、U+000A换行符(LF)、U+000C换页符(FF)、U+000D回车符(CR)或U+0020空格
起始标签,其标签名为“html”

使用“在主体中插入模式的规则处理该令牌。

一个文件结束令牌

停止解析

起始标签,其标签名为“noframes”

使用“在头部中插入模式的规则处理该令牌。

其他任何内容

解析错误。忽略该令牌。

13.2.6.5 在“外来内容”中解析令牌的规则

当用户代理要应用在外来内容中解析令牌的规则时,用户代理必须按以下方式处理该令牌:

一个字符令牌,其值为U+0000 NULL

解析错误插入一个U+FFFD替换字符

一个字符令牌,其值为U+0009字符制表符、U+000A换行符(LF)、U+000C换页符(FF)、U+000D回车符(CR)或U+0020空格

插入该令牌的字符

任何其他字符令牌

插入该令牌的字符

frameset-ok标志设置为“不可以”。

一个注释令牌

插入一个注释

一个DOCTYPE令牌

解析错误。忽略该令牌。

起始标签,其标签名为以下之一:“b”、“big”、“blockquote”、“body”、“br”、“center”、“code”、“dd”、“div”、“dl”、“dt”、“em”、“embed”、“h1”、“h2”、“h3”、“h4”、“h5”、“h6”、“head”、“hr”、“i”、“img”、“li”、“listing”、“menu”、“meta”、“nobr”、“ol”、“p”、“pre”、“ruby”、“s”、“small”、“span”、“strong”、“strike”、“sub”、“sup”、“table”、“tt”、“u”、“ul”、“var”
起始标签,其标签名为“font”,如果该令牌具有名为“color”、“face”或“size”的任何属性
结束标签,其标签名为“br”、“p”

解析错误

当前节点不是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”,并且新的当前节点SVG命名空间

确认令牌的自闭合标志,然后按照下面“script”结束标签的步骤进行操作。

否则

开放元素堆栈中弹出当前节点确认令牌的自闭合标志

结束标签,其标签名为“script”,如果当前节点SVGscript元素

开放元素堆栈中弹出当前节点

old insertion point的值设置为当前插入点的值。将插入点设置为下一个输入字符之前。

将解析器的脚本嵌套级别增加1。将解析器暂停标志设置为true。

如果活动的推测性HTML解析器为null并且用户代理支持SVG,则根据SVG规则处理SVGscript元素[SVG]

即使这导致向令牌器插入新字符,由于解析器暂停标志为true,解析器也不会被重新进入地执行。

将解析器的脚本嵌套级别减少1。如果解析器的脚本嵌套级别为零,则将解析器暂停标志设置为false。

插入点的值恢复为old insertion point的值。(换句话说,将插入点恢复到其以前的值。这个值可能是“未定义”的值。)

任何其他结束标签

运行以下步骤:

  1. node初始化为当前节点(堆栈的最底部节点)。

  2. 如果node的标签名转换为ASCII小写后与令牌的标签名不同,则这是一个解析错误

  3. 循环:如果node开放元素堆栈中的顶层元素,则返回。(片段情况

  4. 如果node的标签名转换为ASCII小写后与令牌的标签名相同,则从开放元素堆栈中弹出元素,直到node被弹出堆栈,然后返回。

  5. node设置为开放元素堆栈中的上一个条目。

  6. 如果node不是HTML命名空间中的元素,则返回到标记为循环的步骤。

  7. 否则,根据HTML内容中与当前插入模式相应部分中给出的规则处理令牌。

13.2.7 结束

Document/DOMContentLoaded_event

所有当前引擎均支持。

Firefox1+Safari3.1+Chrome1+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

一旦用户代理停止解析文档,用户代理必须执行以下步骤:

Window/load_event

所有当前引擎均支持。

Firefox1+Safari1.3+Chrome1+
Opera4+Edge79+
Edge (旧版)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
  1. 如果活动推测性HTML解析器不为null,则停止推测性HTML解析器并返回。

  2. 插入点设置为未定义。

  3. 将当前文档准备状态更新为“interactive”。

  4. 开放元素堆栈中弹出所有节点。

  5. 文档解析完成后将执行的脚本列表不为空时:

    1. 旋转事件循环,直到文档解析完成后将执行的脚本列表中的第一个script准备被解析器执行设置为true并且解析器的Document没有阻止脚本的样式表

    2. 执行脚本元素,该元素由文档解析完成后将执行的脚本列表中的第一个script提供。

    3. 文档解析完成后将执行的脚本列表中删除第一个script元素(即从列表中移除第一个条目)。

  6. DOM操作任务源上排队一个全局任务,给定Document相关全局对象,以执行以下子步骤:

    1. 将当前文档准备状态更新为“complete”。

    2. 如果Document对象的浏览上下文为null,则中止这些步骤。

    3. windowDocument相关全局对象

    4. Document加载时序信息加载事件开始时间设置为window当前高分辨率时间

    5. 触发一个名为load的事件,目标为window,并设置legacy target override flag

    6. 调用WebDriver BiDi加载完成,使用Document浏览上下文,并使用新的WebDriver BiDi导航状态,其idDocumentWebDriver BiDi加载时导航ID状态为“complete”,并且urlDocument对象的URL

    7. Document对象的WebDriver BiDi加载时导航ID设置为null。

    8. Document加载时序信息加载事件结束时间设置为window当前高分辨率时间

    9. 断言Document页面显示为false。

    10. Document页面显示标志设置为true。

    11. 触发一个页面过渡事件,名为pageshow,目标为window,并设置为false。

    12. 完全完成Document的加载。

    13. 将导航时序条目排队Document

  7. 如果Document加载完成时打印标志已设置,则执行打印步骤

  8. Document现在准备好执行加载后任务

当用户代理要中止解析器时,必须执行以下步骤:

  1. 丢弃输入流中任何未处理的内容,并丢弃将来可能会添加的任何内容。

  2. 停止此HTML解析器的推测性HTML解析器

  3. 将当前文档准备状态更新为“interactive”。

  4. 开放元素堆栈中弹出所有节点。

  5. 将当前文档准备状态更新为“complete”。

13.2.8 推测性HTML解析

用户代理可以实现一种优化,如本节所述,在HTML解析器等待待定的解析阻塞脚本获取并执行时,或在正常解析期间,当为标记创建元素时,推测性地获取HTML标记中声明的资源。虽然这种优化没有详细定义,但有一些规则需要考虑以实现互操作性。

每个HTML解析器可以有一个活动的推测性HTML解析器,它最初为null。

推测性HTML解析器必须像普通的HTML解析器一样运作(例如,适用树构建规则),但有一些例外:

针对推测性模拟元素element推测性获取必须遵循以下规则:

是否应将其中的一些东西应用到文档“实际”上,即使它们是推测性地找到的?

每个Document都有一个推测性获取URL列表,这是一个列表,最初为空。

要为HTML解析器实例parser启动推测性HTML解析器

  1. 可以选择返回。

    此步骤允许用户代理选择不进行推测性HTML解析。

  2. 如果parser活动的推测性HTML解析器不为null,则为parser停止推测性HTML解析器

    这可能发生在document.write()写入另一个阻塞解析的脚本时。为简化起见,本规范总是重新启动推测性解析,但用户代理可以实现更有效的策略,只要最终结果等效即可。

  3. speculativeParser成为一个新的推测性HTML解析器,其状态与parser相同。

  4. speculativeDoc成为parserDocument的新同构表示,其中所有元素都为推测性模拟元素。让speculativeParser解析为speculativeDoc

  5. parser活动的推测性HTML解析器设置为speculativeParser

  6. 并行运行speculativeParser,直到它被停止或直到它达到其输入流的末尾。

要为HTML解析器实例parser停止推测性HTML解析器

  1. speculativeParser成为parser活动的推测性HTML解析器

  2. 如果speculativeParser为null,则返回。

  3. 丢弃speculativeParser输入流中的任何待处理内容,并丢弃将来可能添加的任何内容。

  4. parser活动的推测性HTML解析器设置为null。

推测性HTML解析器将创建推测性模拟元素,而不是普通元素。树构建器通常对元素执行的DOM操作应在推测性模拟元素上适当工作。

推测性模拟元素是一个结构体,具有以下项目

要在给定namespacetagNameattributes的情况下创建推测性模拟元素

  1. element成为一个新的推测性模拟元素

  2. element命名空间设置为namespace

  3. element本地名称设置为tagName

  4. element属性列表设置为attributes

  5. element子元素设置为一个新的空列表

  6. 可以选择为element执行推测性获取

  7. 返回element

当树构建器说要将元素插入到template元素的template内容中时,如果这是一个推测性模拟元素,并且template元素的template内容不是ShadowRoot节点,则不执行任何操作。非声明性影子根内推测找到的URLtemplate元素本身可能是模板,不得推测性获取。

13.2.9 将 HTML DOM 强制转换为信息集

当应用程序将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的实际元素来处理该开始标签。

13.2.10 解析器中的错误处理和奇怪情况介绍

本节是非规范性的。

本节讨论了一些错误标记,并讨论了HTML解析器如何处理这些情况。

13.2.10.1 标签嵌套错误:<b><i></b></i>

本节是非规范性的。

最常讨论的错误标记示例如下:

<p>1<b>2<i>3</b>4</i>5</p>

在解析这个标记时,到"3"为止是直截了当的。这时,DOM看起来像这样:

此时,打开元素堆栈中有五个元素:htmlbodypbi活动格式化元素列表中只有两个:bi插入模式是"在正文中"。

在接收到标签名为"b"的结束标签标记时,调用了"领养机构算法"。这是一个简单的情况,其中formattingElementb元素,并且没有furthest block。因此,打开元素堆栈只剩下三个元素:htmlbodyp,而活动格式化元素列表中只有一个:i。此时DOM树未修改。

下一个标记是字符"4",触发了活动格式化元素的重建,在本例中只有i元素。因此,为"4"节点创建了一个新的i元素。在接收到"i"的结束标签标记并插入"5"节点后,DOM如下所示:

13.2.10.2 标签嵌套错误:<b><p></b></p>

本节是非规范性的。

与前一个类似的一个案例如下:

<b>1<p>2</b>3</p>

在解析到"2"之前,解析过程很简单:

有趣的是,当解析到标签名为"b"的结束标签时。

在看到该标记之前,打开元素堆栈中有四个元素:htmlbodybp活动格式化元素列表中只有一个:b插入模式是"在正文中"。

在接收到标签名为"b"的结束标签标记时,调用了"领养机构算法",与前一个例子类似。然而,在这种情况下,有一个furthest block,即p元素。因此,这次不会跳过领养机构算法。

common ancestorbody元素。概念上的"书签"标记了b活动格式化元素列表中的位置,但由于该列表中只有一个元素,书签不会有太大作用。

随着算法的进行,node最终设置为格式化元素(b),而last node最终设置为furthest blockp)。

last node被附加(移动)到common ancestor,使得DOM看起来如下:

创建一个新的b元素,并将p元素的子元素移动到其中:

最后,将新创建的b元素附加到p元素上,使得DOM如下所示:

b元素从活动格式化元素列表打开元素堆栈中删除,因此当解析"3"时,它将被附加到p元素上:

13.2.10.3 表格中的意外标记

本节是非规范性的。

出于历史原因,表格中的错误处理尤其奇怪。例如,考虑以下标记:

<table><b><tr><td>aaa</td></tr>bbb</table>ccc

高亮的b元素开始标签不允许直接放置在表格内,解析器通过将该元素放置在表格之前来处理这种情况。(这被称为寄养父母)。可以通过查看DOM树来观察这一点,正如在看到table元素的开始标签之后的情形:

...然后在看到b元素开始标签之后:

此时,打开元素堆栈中包含了元素htmlbodytableb(尽管最终的DOM树不匹配);活动格式化元素列表中只有一个b元素;插入模式为"在表格中"。

tr开始标签会导致b元素被从堆栈中弹出,并隐式推导出一个tbody开始标签;然后tbodytr元素以相当直接的方式处理,将解析器带入"在表格体内"和"在行内"插入模式,之后DOM如下所示:

此时,打开元素堆栈中包含了元素htmlbodytabletbodytr活动格式化元素列表中仍然有b元素;插入模式为"在行内"。

td元素开始标签标记,在树中放置一个td元素后,在活动格式化元素列表中放置了一个标记(它还切换到了"在单元格中"插入模式)。

标记意味着在看到"aaa"字符标记时,不会创建b元素来保存生成的文本节点:

结束标签以直接的方式处理;在处理完它们之后,打开元素堆栈中包含了元素htmlbodytabletbody活动格式化元素列表中仍然有b元素("td"结束标签标记已删除标记);插入模式为"在表格体内"。

于是"bbb"字符标记出现了。这些字符标记触发了使用"在表格文本中"插入模式(原始插入模式设置为"在表格体内")。字符标记被收集,当下一个标记(table元素结束标签)出现时,它们作为一个整体处理。由于它们不是全部空格,因此根据"在表格中"插入模式中的"其他任何内容"规则进行处理,但带有寄养父母

活动格式化元素被重建时,会创建一个b元素并进行寄养,然后将"bbb"文本节点附加到它上面:

打开元素堆栈中包含了元素htmlbodytabletbody和新创建的b(再次注意,这与结果树不匹配!);活动格式化元素列表中有新创建的b元素;插入模式仍然是"在表格体内"。

如果这些字符标记只是ASCII空白符而不是"bbb",那么这些ASCII空白符将仅附加到tbody元素中。

最后,通过"table"结束标签关闭table。这会将打开元素堆栈中的所有节点弹出,直到包括table元素,但不会影响活动格式化元素列表,因此表格后的"ccc"字符标记会导致在表格之后再次创建一个b元素:

13.2.10.4解析时修改页面的脚本

本节为非规范性内容。

考虑以下标记,在本例中,我们假设它是文档 URLhttps://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。

13.2.10.5 跨多个文档移动的脚本的执行

本节为非规范性内容。

在上一节的示例基础上,考虑以下情况:第二个 script 元素是一个外部脚本(即具有 src 属性的脚本)。由于该元素在创建时不在解析器的 Document 中,因此该外部脚本甚至不会被下载。

在另一个场景中,一个带有 src 属性的 script 元素被正常解析到其解析器的 Document 中,但在外部脚本下载过程中,该元素被移动到另一个文档中,脚本会继续下载,但不会执行。

一般来说,在 Document 之间移动 script 元素被认为是一种不良做法。

13.2.10.6 未闭合的格式化元素

本节为非规范性内容。

以下标记展示了嵌套的格式化元素(如 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树如下:

请注意标记中的第二个 p 元素没有显式的 b 元素,但在生成的 DOM 中,每种格式化元素(在本例中为带有 class 属性的三个 b 元素和两个不带修饰的 b 元素)在元素的 "X" 之前最多会被重建三次。

另请注意,这意味着在最后一段中,只有六个 b 结束标签就足以完全清除 活动格式化元素列表,尽管到目前为止已经看到了九个 b 开始标签。

13.3 序列化HTML片段

在以下算法中,如果一个元素的元素类型是void元素之一,或者是basefontbgsoundframekeygenparam,则该元素序列化为空

以下步骤构成了HTML片段序列化算法。该算法以DOM中的ElementDocumentDocumentFragment作为输入节点,并称之为node,输入一个布尔值serializableShadowRoots,以及一个sequence<ShadowRoot>类型的shadowRoots,返回一个字符串。

此算法序列化的是被序列化节点的子节点,而不是节点本身。

  1. 如果node序列化为空,则返回空字符串。

  2. s为一个字符串,并将其初始化为空字符串。

  3. 如果nodetemplate元素,则将node替换为template元素的模板内容(一个DocumentFragment节点)。

  4. 如果current nodeshadow host,则:

    1. shadowcurrent nodeshadow root

    2. 如果以下情况之一为真:

      • serializableShadowRoots为true且shadowserializable为true;或

      • shadowRoots包含shadow

      那么:

      1. 附加"<template shadowrootmode=""。

      2. 如果shadowmode为"open",则附加"open"。否则,附加"closed"。

      3. 附加"""。

      4. 如果shadowdelegates focus已设置,则附加" shadowrootdelegatesfocus="""。

      5. 如果shadowserializable已设置,则附加" shadowrootserializable="""。

      6. 如果shadowclonable已设置,则附加" shadowrootclonable="""。

      7. 附加">"。

      8. 附加运行HTML片段序列化算法的值,其中传入shadowserializableShadowRootsshadowRoots(因此对该元素递归调用此算法)。

      9. 附加"</template>"。

  5. 对于node的每个子节点,按树顺序执行以下步骤:

    1. current node为正在处理的子节点。

    2. 将下列列表中的适当字符串附加到s

      如果current nodeElement

      如果current nodeHTML命名空间MathML命名空间SVG命名空间中的元素,则令 tagnamecurrent node的本地名称。否则,令tagnamecurrent node的限定名称。

      附加一个U+003C小于号字符(<),然后是tagname

      对于由HTML 解析器创建的HTML 元素或通过createElement()创建的元素,tagname将为小写。

      如果current nodeis不为null,并且该元素的属性列表中没有is属性,则附加字符串" is="",然后附加current nodeis按下面描述的方式转义,使用属性模式,然后附加一个U+0022引号字符(")。

      对于元素具有的每个属性,附加一个U+0020空格字符、按下文描述的方式序列化的属性名称,一个U+003D等号字符(=),一个U+0022引号字符("),属性值,按下文描述的方式转义,使用属性模式,然后附加第二个U+0022引号字符(")。

      属性的序列化名称应根据以下规则确定:

      如果该属性没有命名空间

      该属性的序列化名称是该属性的本地名称。

      对于由HTML 元素上的属性,由HTML 解析器或通过setAttribute()设置时,本地名称将为小写。

      如果该属性位于XML命名空间

      属性的序列化名称是字符串"xml:",后跟属性的本地名称。

      如果该属性位于XMLNS命名空间中,并且属性的本地名称为xmlns

      属性的序列化名称是字符串"xmlns"。

      如果该属性位于XMLNS命名空间中,并且属性的本地名称不是xmlns

      属性的序列化名称是字符串"xmlns:",后跟属性的本地名称。

      如果该属性位于XLink命名空间

      属性的序列化名称是字符串"xlink:",后跟属性的本地名称。

      如果该属性位于其他命名空间中

      属性的序列化名称是属性的限定名称。

      虽然属性的确切顺序是实现定义的,可能取决于属性在原始标记中的顺序等因素,但排序顺序必须是稳定的,以便连续调用此算法可以以相同的顺序序列化元素的属性。

      附加一个U+003E大于号字符(>)。

      如果current node序列化为空,则此时继续处理下一个子节点。

      附加运行HTML片段序列化算法的值,其中传入current nodeserializableShadowRootsshadowRoots(因此对该节点递归调用此算法),然后附加一个U+003C小于号字符(<)、一个U+002F斜杠字符(/)、tagname,最后附加一个U+003E大于号字符(>)。

      如果current node文本节点

      如果current node的父节点是stylescriptxmpiframenoembednoframesplaintext元素,或者如果current node的父节点是noscript元素,并且为该节点启用了脚本,则按字面附加current node数据

      否则,附加current node数据按下文描述的方式转义

      如果current node注释节点

      附加"<!--"(U+003C小于号、U+0021感叹号、U+002D短横线、U+002D短横线),然后附加current node数据的值,然后附加字面字符串"-->"(U+002D短横线、U+002D短横线、U+003E大于号)。

      如果current node处理指令节点

      附加"<?"(U+003C小于号、U+003F问号),然后附加current nodetarget IDL属性的值,附加一个U+0020空格字符,然后附加current node数据的值,最后附加一个U+003E大于号字符(>)。

      如果current node文档类型节点

      附加"<!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大于号)。

  6. 返回s

该算法的输出如果使用HTML解析器进行解析,可能不会还原原始的树结构。甚至HTML解析器本身也可能生成在序列化-重新解析步骤中不回送的树结构,尽管这种情况通常是不符合规范的。

例如,如果将一个附加了textarea元素的Comment节点进行序列化,然后输出再重新解析,则注释会显示在文本控件中。类似地,如果由于DOM操作,一个元素包含了一个包含"-->"的注释,则在解析序列化元素的结果时,注释会在该点被截断,剩余部分将被解释为标记。另一个例子是让一个script元素包含一个带有"</script>"文本节点的Text节点,或者让一个包含ul元素的p元素存在(因为ul元素的起始标签会暗示p的结束标签)。

这可能会导致跨站脚本攻击。例如,一个页面允许用户输入一些字体族名称,然后通过DOM将它们插入到一个CSS style块中,然后使用innerHTMLID属性获取该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)字符在pretextarealisting元素中可以是符合规范的,本文的算法也不会将该字符进行轮回转移。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>

转义字符串(用于上述算法)包括以下步骤:

  1. 将任何出现的"&"字符替换为字符串"&amp;"。

  2. 将任何出现的U+00A0不间断空格字符替换为字符串"&nbsp;"。

  3. 如果在属性模式下调用了该算法,则将任何出现的"""字符替换为字符串"&quot;"。

  4. 如果该算法未在属性模式下调用,则将任何出现的"<"字符替换为字符串"&lt;",并将任何出现的">"字符替换为字符串"&gt;"。

13.4 解析 HTML 片段

以下步骤构成了HTML片段解析算法。该算法接受一个元素节点作为输入,该节点被称为context元素,用于为解析器提供上下文信息,还有一个字符串input用于解析,以及一个可选的布尔值allowDeclarativeShadowRoots(默认值为false)。该算法返回零个或多个节点的列表。

在解析器部分标记为片段情况的部分仅在解析器是为了执行此算法而创建时才会出现。此类标记仅出于信息目的对算法进行注释,并没有规范性的权重。如果描述为片段情况的条件即使在解析器不是为了处理此算法而创建的情况下也可能发生,那么这是规范中的错误。

  1. 创建一个新的文档节点,并将其标记为HTML文档

  2. 如果上下文元素的节点文档处于怪异模式,则将文档置于怪异模式。否则,如果上下文元素的节点文档处于有限怪异模式,则将文档置于有限怪异模式。否则,将文档保持在非怪异模式

  3. 如果allowDeclarativeShadowRoots为true,则将文档允许声明性Shadow Root属性设置为true。

  4. 创建一个新的HTML解析器,并将其与刚创建的文档节点关联。

  5. 根据上下文元素,设置HTML解析器的标记化阶段的状态:

    title
    textarea
    将标记器切换到RCDATA状态
    style
    xmp
    iframe
    noembed
    noframes
    将标记器切换到RAWTEXT状态
    script
    将标记器切换到脚本数据状态
    noscript
    如果脚本标志启用,则将标记器切换到RAWTEXT状态。否则,将标记器保持在数据状态
    plaintext
    将标记器切换到纯文本状态
    其他任何元素
    将标记器保持在数据状态

    出于性能原因,不报告错误并直接使用此规范中描述的实际状态机的实现可以使用纯文本状态代替上述列表中提到的RAWTEXT和脚本数据状态。除了解析错误规则之外,它们是等效的,因为在片段情况下没有适当的结束标签标记,但它们涉及的状态转换要少得多。

  6. root成为一个没有属性的新的html元素。

  7. root元素附加到上面创建的文档节点。

  8. 设置解析器的打开元素栈,使其只包含单个元素root

  9. 如果上下文元素是一个模板元素,将"在模板中"推送到模板插入模式栈,使其成为新的当前模板插入模式

  10. 创建一个开始标签标记,其名称为上下文的本地名称,其属性为上下文的属性。

    将此开始标签标记作为上下文节点的开始标签标记,例如用于确定它是否是HTML集成点

  11. 适当地重置解析器的插入模式

    解析器将在该算法的部分过程中引用上下文元素。

  12. 将解析器的form元素指针设置为最接近上下文元素的节点,该节点是一个表单元素(直接向上遍历祖先链,包括该元素本身,如果它是一个表单元素),如果有的话。(如果没有这样的表单元素,则form元素指针保持其初始值null。)

  13. input放入刚刚创建的HTML解析器输入流中。编码的置信度无关紧要的

  14. 启动解析器,并让它运行,直到它消耗了所有刚刚插入输入流中的字符。

  15. 树顺序返回root的子节点。

13.5 命名字符引用

此表列出了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
fflig; U+0FB00
ffllig; U+0FB04
Ffr; U+1D509 𝔉
ffr; U+1D523 𝔣
filig; U+0FB01
FilledSmallSquare; U+025FC
FilledVerySmallSquare; U+025AA
fjlig; U+00066 U+0006A fj
flat; U+0266D
fllig; U+0FB02
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]

此列表是静态的,将来不会扩展或更改

14 XML 语法

HTML/XHTML

在所有当前的引擎中都支持。

Firefox2+Safari3.1+Chrome4+
Opera9+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android4+Safari iOS2+Chrome Android18+WebView Android2+Samsung Internet1.0+Opera Android10.1+

本节仅描述 XML 资源的规则。关于text/html资源的规则在上面标题为"HTML 语法"的部分中讨论。

14.1 使用 XML 语法编写文档

HTML 的 XML 语法以前被称为 "XHTML",但本规范不使用该术语(其中一个原因是,MathML 和 SVG 的 HTML 语法没有使用此类术语)。

XML 的语法定义在XMLXML 中的命名空间中。[XML] [XMLNS]

本规范未定义超出 XML 本身定义的任何语法级要求。

如果需要,XML 文档可以包含DOCTYPE,但这不是符合本规范的必需条件。本规范未定义公共或系统标识符,也未提供正式的 DTD。

根据XML,不能保证 XML 处理器会处理在 DOCTYPE 中引用的外部 DTD 子集。这意味着,例如,如果字符在外部文件中定义,则在 XML 文档中使用实体引用是不安全的(&lt;&gt;&amp;&quot;&apos;除外)。

14.2 解析 XML 文档

本节描述了 XML 和 DOM 之间的关系,特别强调了它如何与 HTML 交互。

为了本规范的目的,XML 解析器是一个遵循XML中给出的规则,将字节或字符串映射为Document对象的构造体。

在撰写本文时,实际上并不存在这样的规则。

一个XML 解析器要么在创建时与Document对象相关联,要么隐式创建一个。

然后必须使用 DOM 节点来填充该Document,这些节点表示传递给解析器的输入的树结构,如XMLXML 中的命名空间DOM中定义的那样。在创建表示元素的 DOM 节点时,必须使用为令牌创建元素算法或某种等效算法,该算法在适当的 XML 数据结构上运行,以确保创建正确的元素接口,并且正确设置自定义元素

对于XML 解析器文档的树上执行的操作,用户代理必须仿效元素和属性分别被追加和设置的方式,以触发本规范中关于当元素插入文档或其属性被设置时发生的规则,并且 DOM 的关于突变观察者的要求意味着突变观察者确实被触发。 [XML] [XMLNS] [DOM] [UIEVENTS]

在解析元素的开始标签与解析元素的结束标签或解析器检测到格式正确性错误之间的时间内,用户代理必须表现得像该元素位于打开元素堆栈中。

这被各种元素用于仅在它们从打开元素堆栈中弹出后才开始某些进程。

本规范提供了用户代理在检索外部实体时应使用的以下附加信息:以下列表中给出的公共标识符都对应于 链接提供的 URL. (此 URL 是一个 DTD,包含实体声明,用于命名字符引用部分中列出的名称。)[XML]

此外,当使用上述公共标识符之一时,用户代理应尝试检索上述外部实体的内容,并且不应尝试检索任何其他外部实体的内容。

这并不严格算作XML违规,但它确实与XML的要求精神相矛盾。这是出于希望用户代理能够以互操作的方式处理实体,而不需要任何网络访问来处理外部子集的考虑。[XML]

可以在启用 XML 脚本支持禁用 XML 脚本支持的情况下调用 XML 解析器。除非另有说明,否则 XML 解析器是在启用 XML 脚本支持的情况下调用的。

XML解析器在启用了XML脚本支持的情况下创建一个script元素时,它必须设置其解析器文档,并将其强制异步设置为false。如果解析器是作为XML片段解析算法的一部分创建的,则元素的已启动必须设置为true。当元素的结束标签随后被解析时,用户代理必须执行微任务检查点,然后准备 script元素。如果这导致存在挂起的解析阻塞脚本,则用户代理必须执行以下步骤:

  1. 阻止此实例的XML 解析器,使得事件循环不会运行任务来调用它。

  2. 旋转事件循环直到解析器的文档没有阻止脚本的样式表,并且挂起的解析阻塞脚本准备好被解析器执行状态为 true。

  3. 取消阻止此实例的XML 解析器,使得可以再次运行任务来调用它。

  4. 执行由挂起的解析阻塞脚本提供的脚本元素。

  5. 挂起的解析阻塞脚本设置为 null。

由于document.write() API 不适用于XML 文档,因此HTML 解析器中的许多复杂性在XML 解析器中是不需要的。

XML 解析器禁用XML 脚本支持时,这些都不会发生。

XML 解析器将一个节点附加到template元素时,它必须将其附加到该template元素的模板内容(一个DocumentFragment节点)中。

这是对XML故意违反;不幸的是,XML 并没有以处理template的方式进行正式扩展的能力。[XML]

XML 解析器创建一个节点对象时,它的节点文档必须设置为要插入新创建节点的节点的节点文档

本规范中的某些算法一口一口地喂解析器字符。这种情况下,XML 解析器必须像面对由所有这些字符连接而成的单个字符串时一样行事。

XML 解析器到达其输入的末尾时,它必须停止解析,并遵循与HTML 解析器相同的规则。XML 解析器也可以中止,这必须与HTML 解析器的中止方式相同。

为了符合性检查器的目的,如果确定资源采用XML 语法,那么它就是一个XML 文档

14.3 序列化 XML 片段

用于DocumentElement节点的XML 片段序列化算法要么返回表示该节点的 XML 片段,要么抛出异常。

对于Document,如果没有适用的错误情况,该算法必须返回文档实体形式的字符串。

对于Element,如果没有适用的错误情况,该算法必须返回内部通用解析实体形式的字符串。

在这两种情况下,返回的字符串必须是 XML 命名空间格式正确的,并且必须是该节点所有相关子节点的同构序列化,按树顺序排列。用户代理可以在序列化中调整前缀和命名空间声明(实际上在某些情况下可能不得不这样做,以获得命名空间格式正确的 XML)。用户代理可以使用常规文本和字符引用的组合来表示 DOM 中的Text节点。

节点的相关子节点是根据以下规则适用的节点:

对于template元素
相关子节点是template元素的模板内容的子节点(如果有)。
对于所有其他节点
相关子节点是节点本身的子节点(如果有)。

对于Element,如果序列化中的任何元素没有命名空间,则必须将这些元素的范围内的默认命名空间显式声明为空字符串。(这不适用于Document情况。)[XML][XMLNS]

在本节的上下文中,如果一个文档由一个没有命名空间声明的元素组成,其内容是内部通用解析实体,那么该文档本身是 XML 命名空间格式正确的,则该内部通用解析实体被认为是 XML 命名空间格式正确的。

如果在正在序列化的 DOM 子树中发现以下任何错误情况,则该算法必须抛出一个"InvalidStateError"DOMException,而不是返回字符串:

这些是使 DOM 无法序列化的唯一方法。DOM 强制执行所有其他 XML 约束;例如,尝试将两个元素附加到Document节点将抛出"HierarchyRequestError"DOMException

14.4 解析 XML 片段

XML 片段解析算法要么返回一个Document,要么抛出一个"SyntaxError"DOMException。给定一个字符串input和一个上下文元素context,算法如下:

  1. 创建一个新的XML 解析器

  2. 将字符串(对应于context元素的开始标签)传递给刚刚创建的解析器,并声明该元素在 DOM 中范围内的所有命名空间前缀,以及声明在 DOM 中该元素范围内的默认命名空间(如果有)。

    如果 DOM 元素上的lookupNamespaceURI()方法为该前缀返回一个非 null 值,则命名空间前缀在范围内。

    默认命名空间是 DOM 元素上的isDefaultNamespace()方法为其返回 true 的命名空间。

    不向解析器传递DOCTYPE,因此不会引用任何外部子集,也不会识别任何实体。

  3. 将字符串input传递给刚刚创建的解析器。

  4. 将字符串(对应于context元素的结束标签)传递给刚刚创建的解析器。

  5. 如果出现 XML 格式正确性或 XML 命名空间格式正确性错误,则抛出一个"SyntaxError"DOMException

  6. 如果生成的Document文档元素有任何兄弟节点,则抛出一个"SyntaxError"DOMException

  7. 树顺序返回生成的Document文档元素的子节点。

15 渲染

用户代理不需要以任何特定方式呈现HTML文档。然而,本节提供了一套渲染HTML文档的建议,如果遵循这些建议,可能会带来与文档作者预期的用户体验非常接近的结果。为了避免对本节的规范性产生混淆,没有使用"必须"一词。相反,使用了"预期"一词来表示将会导致这种体验的行为。对于被指定为支持建议的默认渲染的用户代理,"预期"一词在本节中的符合性含义与"必须"相同。

15.1 介绍

本节中的建议通常以CSS术语表达。用户代理应支持CSS,或将本节中给出的CSS规则转换为其他展示机制的近似值。

在没有相反的样式层规则(例如作者样式表)的情况下,用户代理应当渲染一个元素,使其能够向用户传达该元素所代表的含义,如本规范所述。

本节中的建议通常假定为96dpi或更高分辨率的视觉输出介质,但HTML旨在应用于多种媒介(它是一种媒介无关的语言)。鼓励用户代理实现者根据其目标媒介调整本节中的建议。


如果一个元素具有任何关联的CSS布局框、SVG布局框或其他样式语言中的等效物,则该元素被称为正在渲染

仅仅在屏幕外并不意味着该元素没有正在渲染。通常,hidden属性的存在意味着该元素没有正在渲染,尽管这可能会被样式表覆盖。

完全活动状态不会影响一个元素是否正在渲染。即使一个文档不完全活动且根本不向用户显示,其内部的元素仍然可以视为"正在渲染"。

当一个元素正在渲染并且其关联的CSS布局框与视口相交时,称该元素与视口相交。

正在渲染状态类似,非完全活动文档中的元素仍然可以与视口相交视口在文档之间不共享,并且可能并不总是显示给用户,因此非完全活动文档中的元素仍然可以与其文档关联的视口相交。

本规范未定义何时测试交叉的精确时间,但建议该时间与Intersection Observer API的时间相匹配。[INTERSECTIONOBSERVER]

如果一个元素不正在渲染,但其子元素(如果有)可以渲染,则称该元素将其渲染委托给其子元素,这是CSS 'display: contents'的结果,或其他样式语言中的等效物。[CSSDISPLAY]


即使不遵循作者级别的CSS样式表,用户代理仍然应表现得像是以与本规范以及相关的CSS和Unicode规范一致的方式应用了本节中的CSS规则。[CSS] [UNICODE] [BIDI]

这对涉及'display''unicode-bidi''direction'属性的问题尤为重要。

15.2 CSS 用户代理样式表和呈现提示

除非另有说明,本小节中给出的CSS规则应作为包含HTML元素的所有文档的用户代理级别样式表默认值的一部分。

某些规则是为CSS层叠中的作者级零特异性呈现提示部分设计的;这些规则被明确标注为呈现提示


当下文中提到某个元素element上的属性attribute 映射到像素长度属性(或多个属性properties)时,这意味着如果element具有属性attribute,并且使用解析非负整数的规则解析该属性的值没有产生错误,则用户代理应使用解析后的值作为properties呈现提示的像素长度。

当下文中提到某个元素element上的属性attribute 映射到维度属性(或多个属性properties)时,这意味着如果element具有属性attribute,并且使用解析维度值的规则解析该属性的值没有产生错误,则用户代理应使用解析后的维度作为properties呈现提示的值,如果维度是长度,则以像素长度表示该值,如果维度是百分比,则以百分比表示该值。

当下文中提到某个元素element上的属性attribute 映射到维度属性(忽略零)(或多个属性properties)时,这意味着如果element具有属性attribute,并且使用解析非零维度值的规则解析该属性的值没有产生错误,则用户代理应使用解析后的维度作为properties呈现提示的值,如果维度是长度,则以像素长度表示该值,如果维度是百分比,则以百分比表示该值。

当下文中提到元素element上的一对属性wh 映射到宽高比属性时,这意味着如果element具有属性wh,并且使用解析非负整数的规则解析这些属性的值没有产生错误,则用户代理应使用解析后的整数作为呈现提示,其形式为auto w / h

当下文中提到元素element上的一对属性wh 映射到宽高比属性(使用维度规则)时,这意味着如果element具有属性wh,并且使用解析维度值的规则解析这些属性的值没有产生错误或返回百分比,则用户代理应使用解析后的维度作为呈现提示,其形式为auto w / h

当用户代理对节点的后代进行对齐时,用户代理应只对那些margin-inline-startmargin-inline-end属性计算值不为'auto'的后代进行对齐,这些后代是过度约束的,并且其中一个边距的使用值被强制为更大的值,并且它们本身没有适用的align属性。当多个元素需要对齐特定的后代时,嵌套最深的元素应覆盖其他元素。对齐的元素应通过设置其边距在行左行右侧的使用值来进行对齐。[CSSLOGICAL] [CSSWM]

15.3 非替换元素

15.3.1 隐藏元素

@namespace "http://www.w3.org/1999/xhtml";

area, base, basefont, datalist, head, link, meta, noembed,
noframes, param, rp, script, style, template, title {
  display: none;
}

[hidden]:not([hidden=until-found i]):not(embed) {
  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; }
}

15.3.2 页面

@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 元素的 节点文档节点可导航对象 是一个 子可导航对象,并且该可导航对象的 容器 是一个 frameiframe 元素,那么该 body 元素的 容器框架元素 就是该 frameiframe 元素。否则,没有 容器框架元素

上述要求意味着页面可以通过例如iframe更改另一个页面(包括来自其他来源的页面)的边距。这可能是一个安全风险,因为在某些情况下,它可能允许攻击者伪造出与作者意图不符的页面渲染,可能用于钓鱼或误导用户。


如果文档可导航节点子可导航节点,则应将其定位并调整大小以适应该内容框内的容器可导航节点。如果该容器没有正在渲染,则可导航节点应具有一个宽度和高度为零的视口

如果文档可导航节点子可导航节点,且该容器是该可导航节点frameiframe元素,该元素具有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'属性设置为结果颜色。

15.3.3 流内容

@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: 1em;
}

blockquote, figure { margin-inline: 40px; }

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: 1em;
  background-color: Canvas;
  color: CanvasText;
}
dialog:modal {
  position: fixed;
  overflow: auto;
  inset-block: 0;
  max-width: calc(100% - 6px - 2em);
  max-height: calc(100% - 6px - 2em);
}
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.25em;
  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: 1em; }

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',并且应将后代元素对齐到左边

15.3.4 短语内容

@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元素的子元素中,不是rtrp元素的部分应包装在匿名框中,其'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'属性:

  1. input为属性的值。

  2. position为指向input的指针,初始指向字符串的开头。

  3. 跳过position处的input内的ASCII空白符

  4. 如果position超出input的末尾,则没有呈现提示。返回。

  5. 如果position处的字符是U+002B加号字符(+),则将mode设为relative-plus,并将position前移一个字符。否则,如果position处的字符是U+002D连字符(-),则将mode设为relative-minus,并将position前移一个字符。否则,将mode设为absolute

  6. 收集从position给定的input中的ASCII数字的代码点序列,并将结果序列设为digits

  7. 如果digits为空字符串,则没有呈现提示。返回。

  8. digits解释为十进制整数。将value设为结果数字。

  9. 如果moderelative-plus,则将value加3。如果moderelative-minus,则将value减去3。

  10. 如果value大于7,则将其设为7。

  11. 如果value小于1,则将其设为1。

  12. 根据以下表格,将'font-size'设置为与value的值对应的关键字:

    value 'font-size'关键字
    1 'x-small'
    2 'small'
    3 'medium'
    4 'large'
    5 'x-large'
    6 'xx-large'
    7 'xxx-large'

15.3.5 双向文本

@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;
}

15.3.6 章节和标题

@namespace "http://www.w3.org/1999/xhtml";

article, aside, h1, h2, h3, h4, h5, h6, hgroup, nav, section {
  display: block;
}

h1 { margin-block: 0.67em; font-size: 2.00em; font-weight: bold; }
h2 { margin-block: 0.83em; font-size: 1.50em; font-weight: bold; }
h3 { margin-block: 1.00em; font-size: 1.17em; font-weight: bold; }
h4 { margin-block: 1.33em; font-size: 1.00em; font-weight: bold; }
h5 { margin-block: 1.67em; font-size: 0.83em; font-weight: bold; }
h6 { margin-block: 2.33em; font-size: 0.67em; font-weight: bold; }

在以下CSS块中,x是以下选择器的简写::is(article, aside, nav, section)

@namespace "http://www.w3.org/1999/xhtml";

x h1 { margin-block: 0.83em; font-size: 1.50em; }
x x h1 { margin-block: 1.00em; font-size: 1.17em; }
x x x h1 { margin-block: 1.33em; font-size: 1.00em; }
x x x x h1 { margin-block: 1.67em; font-size: 0.83em; }
x x x x x h1 { margin-block: 2.33em; font-size: 0.67em; }

此简写用于保持该块代码至少具有一定的可读性。

15.3.7 列表

@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: 1em; }

:is(dir, dl, menu, ol, ul) :is(dir, dl, menu, ol, ul) {
  margin-block: 0;
}

dd { margin-inline-start: 40px; }
dir, menu, ol, ul { padding-inline-start: 40px; }

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'属性:

  1. value为null。

  2. 如果元素具有start属性,则将value设置为使用解析整数的规则解析该属性的值的结果。

  3. 如果元素具有reversed属性,则:

    1. 如果value是整数,则将value增加1,并返回reversed(list-item) value

    2. 否则,返回reversed(list-item)

      可能是start属性不存在,或解析其值时产生了错误。

  4. 否则:

    1. 如果value是整数,则将value减少1,并返回list-item value

    2. 否则,没有呈现提示

15.3.8 表格

@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: 2px;
  border-collapse: separate;
  text-indent: initial;
}
td, th { padding: 1px; }
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: 1px;
  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: 1px;
  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: 1px;
  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: 1px;
  border-style: solid;
}

table[rules=groups i] > colgroup {
  border-inline-width: 1px;
  border-inline-style: solid;
}
table[rules=groups i] > thead,
table[rules=groups i] > tbody,
table[rules=groups i] > tfoot {
  border-block-width: 1px;
  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: 1px;
  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表格模型的目的,colspanrowspan属性在tdth元素上应提供关于跨行和跨列单元格的特殊知识,参见解析非负整数的规则

HTML文档中,还应适用以下规则:

@namespace "http://www.w3.org/1999/xhtml";

:is(table, thead, tbody, tfoot, tr) > form { display: none !important; }

table元素的cellspacing属性映射到像素长度属性,即元素上的'border-spacing'

table元素的cellpadding属性映射到像素长度属性,即任何tdth元素的'padding-top''padding-right''padding-bottom''padding-left',这些元素在与对应table元素的表格对应的单元格中。

table元素的height属性映射到尺寸属性,即元素上的'height'

table元素的width属性映射到尺寸属性(忽略零),即元素上的'width'

col元素的width属性映射到尺寸属性,即元素上的'width'

theadtbodytfoot元素的height属性映射到尺寸属性,即元素上的'height'

tr元素的height属性映射到尺寸属性,即元素上的'height'

tdth元素的height属性映射到尺寸属性(忽略零),即元素上的'height'

tdth元素的width属性映射到尺寸属性(忽略零),即元素上的'width'


theadtbodytfoottrtdth元素,当它们具有align属性且该属性的值与字符串"center"或字符串"middle"进行ASCII大小写不敏感匹配时,预期会将文本居中对齐,仿佛它们的'text-align'属性已设置为“center”作为呈现提示,并将子元素对齐到中心。

theadtbodytfoottrtdth元素,当它们具有align属性且该属性的值与字符串"left"进行ASCII大小写不敏感匹配时,预期会将文本左对齐,仿佛它们的'text-align'属性已设置为“left”作为呈现提示,并将子元素对齐到左侧。

theadtbodytfoottrtdth元素,当它们具有align属性且该属性的值与字符串"right"进行ASCII大小写不敏感匹配时,预期会将文本右对齐,仿佛它们的'text-align'属性已设置为“right”作为呈现提示,并将子元素对齐到右侧。

theadtbodytfoottrtdth元素,当它们具有align属性且该属性的值与字符串"justify"进行ASCII大小写不敏感匹配时,预期会将文本两端对齐,仿佛它们的'text-align'属性已设置为“justify”作为呈现提示,并将子元素对齐到左侧。

用户代理预期在其用户代理样式表中具有匹配th元素的规则,这些元素的父节点的计算值'text-align'属性是其初始值,该声明块仅由一个将'text-align'属性设置为“center”的声明组成。


tabletheadtbodytfoottrtdth元素具有background属性且其值为非空时,新的值应根据元素的节点文档进行编码、解析和序列化,如果这不返回失败,用户代理应将该属性视为呈现提示,将元素的'background-image'属性设置为返回值。

tabletheadtbodytfoottrtdth元素具有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”。

15.3.9 边距折叠怪癖

节点是实质性的,如果它是一个文本节点且不是元素间空白,或者如果它是一个元素节点。

节点是空白的,如果它是一个不包含实质性节点的元素。

具有默认边距的元素包括以下元素:blockquotedirdlh1h2h3h4h5h6listingmenuolpplaintextpreulxmp

怪癖模式中,任何具有默认边距的元素,如果它是bodytdth元素的子节点且没有实质性的前一个兄弟节点,则应具有一个用户代理级别的样式表规则,将其'margin-block-start'属性设置为零。

怪癖模式中,任何具有默认边距的元素,如果它是bodytdth元素的子节点,没有实质性的前一个兄弟节点且是空白的,则应具有一个用户代理级别的样式表规则,将其'margin-block-end'属性也设置为零。

怪癖模式中,任何具有默认边距的元素,如果它是tdth元素的子节点,没有实质性的后一个兄弟节点且是空白的,则应具有一个用户代理级别的样式表规则,将其'margin-block-start'属性设置为零。

怪癖模式中,任何p元素,如果它是tdth元素的子节点且没有实质性的后一个兄弟节点,则应具有一个用户代理级别的样式表规则,将其'margin-block-end'属性设置为零。

15.3.10 表单控件

@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属性不处于隐藏状态或图像按钮状态,且该元素正在渲染时,预期应如下操作:

15.3.11 hr 元素

@namespace "http://www.w3.org/1999/xhtml";

hr {
  color: gray;
  border-style: inset;
  border-width: 1px;
  margin-block: 0.5em;
  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'设置提示。

width属性在hr元素上的映射到尺寸属性'width'

hr元素具有color属性时,预期其值将使用解析传统颜色值的规则进行解析,并且如果解析不返回错误,用户代理应将该属性视为表现提示,将元素的'color'属性设置为结果颜色。

15.3.12 fieldset 元素和legend 元素

@namespace "http://www.w3.org/1999/xhtml";

fieldset {
  display: block;
  margin-inline: 2px;
  border: groove 2px ThreeDFace;
  padding-block: 0.35em 0.625em;
  padding-inline: 0.75em;
  min-inline-size: min-content;
}

legend {
  padding-inline: 2px;
}

legend[align=left i] {
  justify-self: left;
}

legend[align=center i] {
  justify-self: center;
}

legend[align=right i] {
  justify-self: right;
}

fieldset元素在生成CSS盒时,预期行为如下:

fieldset元素的已渲染legend(如果有的话),预期行为如下:

fieldset元素的匿名fieldset内容盒预期行为如下:

fieldset's margin legend padding legend's margin padding anonymous fieldset content box content
legend 渲染在顶部边框上方,顶部边框区域为 legend 保留垂直空间。fieldset 的上边距从 legend 的上边距边缘开始。legend 的水平边距或 'justify-self' 属性决定其水平位置。匿名 fieldset 内容盒 出现在 legend 下方。

15.4 替换元素

以下元素可以是替换元素audiocanvasembediframeimginputobject,以及video

15.4.1 嵌入内容

embediframevideo 元素预计会被视为替换元素

canvas 元素表示嵌入内容时,预计它会被视为替换元素;此类元素的内容是元素的位图(如果有),否则是与元素具有相同自然尺寸透明黑色位图。其他 canvas 元素预计会在渲染模型中被视为普通元素。

object 元素表示图像、插件或其内容导航时,预计会被视为替换元素。其他 object 元素预计会在渲染模型中被视为普通元素。

audio 元素显示用户界面时,预计会被视为高度大约为一行、宽度为所需的用户代理的用户界面特性,以便暴露的替换元素。当 audio 元素未显示用户界面时,预计用户代理会强制将其'display' 属性计算为 'none',无论CSS规则如何。

video 元素是否显示用户界面预计不会影响渲染大小;控件预计会覆盖在页面内容上方,不会引起任何布局变化,并且当用户不需要它们时预计会消失。

video 元素显示海报帧或视频帧时,预计海报帧或视频帧会按保持该海报帧或视频帧的纵横比的最大尺寸渲染,且不会超过 video 元素本身的高度或宽度,并且预计会居中显示在 video 元素中。

任何字幕或说明预计会直接覆盖在其video元素上,如相关的渲染规则所定义的那样;对于WebVTT,这些规则是更新WebVTT文本轨道显示的规则[WEBVTT]

当用户代理开始显示 video 元素的用户界面时,用户代理应运行该 更新文本轨道渲染的规则,以处理 video 元素中 文本轨道列表 中显示的且文本轨道类型subtitlescaptions 的每个文本轨道(例如,对于基于WebVTT的文本轨道,则为更新WebVTT文本轨道显示的规则)。[WEBVTT]

调整 videocanvas 元素大小不会中断视频播放或清除画布。


预计以下CSS规则会被应用:

@namespace "http://www.w3.org/1999/xhtml";

iframe { border: 2px inset; }
video { object-fit: contain; }

15.4.2 图片

用户代理预计会根据以下列表中的第一个适用规则来渲染 img 元素和 input 元素,这些元素的 type 属性处于 图像按钮状态:

如果该元素表示一张图片
用户代理预计会将该元素视为替换元素,并根据CSS中定义的规则渲染该图片。
如果该元素未表示图片,并且满足以下任一条件:
用户代理预计会将该元素视为替换元素,其内容是该元素表示的文本(如果有的话),并且可以选择在旁边显示一个图标,指示正在获取图片(如果适用)。对于 input 元素,预计该元素看起来像一个按钮,以指示该元素是一个按钮
如果该元素是 img 元素,并且该元素表示一些文本,且用户代理不期望这种情况发生变化
用户代理预计会将该元素视为非替换的短语元素,其内容是文本,并可以选择显示一个图标,指示图片缺失,以便用户可以请求显示图片或调查为什么没有渲染。在非图形环境中,此类图标应被省略。
如果该元素是 img 元素,并且该元素表示为空,且用户代理不期望这种情况发生变化
用户代理预计会将该元素视为替换元素,其自然尺寸为0。(在没有进一步样式的情况下,这将导致该元素实际上不被渲染。)
如果该元素是 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: 3px; }
img[align=right i] { margin-left: 3px; }

15.4.3 嵌入内容和图像的属性

预计以下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;
}

embediframeimgobject 元素,或者 input 元素,其 type 属性处于 Image Button 状态时,且具有 align 属性,其值与字符串 "center" 或 "middle" 进行 ASCII 不区分大小写 匹配时,用户代理预期会将该元素的 'vertical-align' 属性设置为将元素的垂直中线与父元素基线对齐的值。

hspace 属性在 embedimgobject 元素,以及 input 元素中,其 type 属性处于 Image Button 状态,映射到维度属性'margin-left''margin-right' 属性。

vspace 属性在 embedimgobject 元素,以及 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'。

widthheight 属性在 img 元素的 尺寸属性源 映射到维度属性 'width''height' 分别对应于 img 元素。它们同样 映射到比例属性(使用尺寸规则)img 元素。

widthheight 属性在 embediframeobjectvideo 元素,以及 input 元素中,其 type 属性处于 Image Button 状态,并且要么表示图像,要么用户预计最终将表示图像,映射到维度属性 'width''height' 分别对应于该元素。

widthheight 属性 映射到比例属性(使用尺寸规则)imgvideo 元素,以及 input 元素中,其 type 属性处于 Image Button 状态。

widthheight 属性 映射到比例属性canvas 元素。

15.4.4 图像映射

图像映射上的形状在 CSS 层叠的目的下,预计会表现为独立于原始的 area 元素的元素,这些元素恰好匹配相同的样式规则,但继承自 imgobject 元素。

在渲染过程中,预计只有 'cursor' 属性会对形状产生任何影响。

因此,例如,如果一个 area 元素具有一个 style 属性,该属性将 'cursor' 属性设置为 'help',那么当用户指示该形状时,光标将变为帮助光标。

类似地,如果一个 area 元素有一个 CSS 规则,将其 'cursor' 属性设置为 'inherit'(或者如果没有设置 'cursor' 属性的规则匹配该元素),则该形状的光标将继承自 imgobject 元素,而不是继承自 area 元素的父元素。

15.5 小部件

15.5.1 原生外观

CSS 基础用户界面 规范称可以具有原生外观的元素为小部件,并根据 'appearance' 属性定义是否使用该 原生外观。该逻辑依赖于元素是被分类为 可退化的小部件还是 不可退化的小部件。本节定义了哪些元素与 HTML 的这些概念相符,它们的原生外观是什么,以及它们的退化状态基本外观的任何特殊性。 [CSSUI]

以下元素可以具有 原生外观,以便于 CSS 'appearance' 属性的使用。

15.5.2 书写模式

有几个小部件的渲染是由 'writing-mode' CSS 属性控制的。对于这些小部件,我们有以下定义。

当解析控件的 'writing-mode' 属性时,计算值为 'horizontal-tb' 时,则为水平书写模式

当解析控件的 'writing-mode' 属性时,计算值为 'vertical-rl'、'vertical-lr'、'sideways-rl' 或 'sideways-lr' 时,则为垂直书写模式

15.5.3 按钮布局

当一个元素使用按钮布局时,它是一个可退化小部件,并且其本地外观与按钮相同。

按钮布局如下:

需要定义预期的原始外观

15.5.4 button 元素

button 元素在生成 CSS 盒子时,预期表现为一个按钮,并使用 按钮布局,其 匿名按钮内容盒子的内容(如果有 匿名按钮内容盒子)将是该元素的盒子原本应该拥有的子盒子。

15.5.5 detailssummary 元素

@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,其中包含三个子元素:

  1. 第一个子元素是一个 slot,该元素应当接收 details 元素的第一个 summary 子元素(如果有的话)。该元素有一个单独的 summary 子元素,称为 默认摘要,其文本内容是 实现定义(并且可能与区域设置相关)。

    这个 summary 元素表示允许用户请求显示或隐藏详细信息。

  2. 第二个子元素是一个 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 的结果。

  3. 第三个子元素是一个 linkstyle 元素,具有以下针对 默认摘要 的样式:

    :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 的结构。

15.5.6 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 属性到该元素。用户代理应按以下步骤确定其 内联大小内在大小

  1. 如果元素上的 'field-sizing' 属性的 计算值'content',则内联大小由元素显示的文本决定。文本可以是 或由 placeholder 属性指定的简短提示。用户代理可能会在内联大小中考虑文本插入符号的大小。

  2. 如果元素有一个 size 属性,并且使用 解析非负整数的规则 解析该属性的值不会产生错误,则返回通过应用 将字符宽度转换为像素 算法到该属性值所获得的值。

  3. 否则,返回通过应用 将字符宽度转换为像素 算法到数字20所获得的值。

将字符宽度转换为像素的算法返回 (size-1)×avg + max,其中 size 是要转换的字符宽度,avg 是元素的主要字体的平均字符宽度(以像素为单位),max 是同一字体的最大字符宽度(也以像素为单位)。(元素的 'letter-spacing' 属性不影响结果。)

这些文本控件应当是 滚动容器 并支持在 内联轴 上的滚动,而不是 块轴

需要详细说明预期的 原生外观原始外观

15.5.7 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 属性处于 日期月份时间本地日期和时间 状态时,预期应约为一行高,并约为展示最宽可能值所需的宽度。

需要详细说明预期的 本地外观原始外观

15.5.8 input 元素作为范围控制

input 元素,其 type 属性处于 范围 状态,是一个不可降级的小部件。其预期的本地外观 应呈现为一个显示滑块控制的“inline-block”框。

当此控件具有水平书写模式时,控件预计为水平滑块。如果“direction”属性的计算值为“rtl”,则其最小值在右侧,否则在左侧。当此控件具有垂直书写模式时,预计为垂直滑块。如果“direction”属性的计算值为“rtl”,则其最小值在底部,否则在顶部。

建议的预定义值(由 list 属性提供)预计显示为滑块上的刻度标记,滑块可以对其对齐。

需要详细说明预期的基本外观

15.5.9 input 元素作为颜色选择器

input 元素,其 type 属性处于 颜色 状态时,预计会显示一个颜色选择器,当激活时,它会为用户提供一个颜色选择工具(例如色轮或调色板),用户可以从中更改颜色。当元素生成 CSS 盒 时,预计会使用按钮布局,该布局没有 匿名按钮内容框的子框。匿名按钮内容框预计会有一个将 表现提示 设置为元素的“background-color”属性的

建议的预定义值(由 list 属性提供)预计显示在颜色选择界面中,而不是颜色选择器本身。

需要详细说明预期的本地外观基本外观

15.5.10 input 元素作为复选框和单选按钮部件

input 元素,其 type 属性处于 复选框 状态,是一个不可降级的小部件,预计会渲染为包含单个复选框控件的“inline-block”框,无标签。

需要详细说明预期的本地外观基本外观

input 元素,其 type 属性处于 单选按钮 状态,是一个不可降级的小部件,预计会渲染为包含单个单选按钮控件的“inline-block”框,无标签。

需要详细说明预期的本地外观基本外观

15.5.11 input 元素作为文件上传控件

input 元素,其 type 属性处于 文件上传 状态时,当它生成 CSS 盒 时,预计会渲染为一个包含文本段的 “inline-block” 框,显示(如果有的话)已选择文件 的文件名,后面跟着一个按钮,激活时为用户提供一个文件选择器,用户可以通过该选择器更改选择。该按钮预计使用按钮布局,并与 “::file-selector-button” 伪元素匹配。其 匿名按钮内容框 的内容预计为实现定义(可能与区域相关)的文本,例如“选择文件”。

用户代理可以将 input 元素的 type 属性处于 文件上传 状态时视为具有默认首选大小的元素,并且用户代理可以将 “field-sizing” CSS 属性应用于该元素。如果该元素上的“field-sizing” 属性的计算值“content”,则该元素的 固有大小 预计取决于其内容,例如 “::file-selector-button” 伪元素和已选择的文件名。

15.5.12 input 元素作为按钮

input 元素,其 type 属性处于 提交按钮重置按钮按钮 状态时,当它生成 CSS 盒 时,预计会显示为一个按钮,并使用按钮布局匿名按钮内容框的内容预计为元素的 value 属性的文本(如果有的话),否则为从元素的 type 属性派生的文本,按照 实现定义(可能与区域相关)的方式处理。

15.5.13 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 元素上的 widthheight 属性映射到维度属性,即元素上的 “width”“height” 属性。

marquee 元素的 direction 属性处于 updown 状态时,其自然高度为 200 CSS 像素

marquee 元素的 vspace 属性映射到维度属性,即元素上的“margin-top”“margin-bottom” 属性。marquee 元素的 hspace 属性映射到维度属性,即元素上的“margin-left”“margin-right” 属性。

15.5.14 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 元素的定义中。

需要详细说明预期的基本外观

15.5.15 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 元素的定义中。

需要详细说明预期的基本外观

15.5.16 select 元素

select 元素是一个具有默认首选大小的元素,预计用户代理会将“field-sizing” CSS 属性应用于select 元素。

select 元素根据其属性可以是一个列表框下拉框

select 元素如果存在 multiple 属性,预计会渲染为一个多选列表框

select 元素如果不存在 multiple 属性,且其显示大小大于1,预计会渲染为一个单选列表框

当元素渲染为列表框时,它是一个可降级的小部件,预计会渲染为一个“inline-block”框。其内联大小固有大小“select”标签的宽度加上滚动条的宽度。其块大小固有大小由以下步骤确定:

  1. 如果元素上的“field-sizing”属性的计算值“content”,则返回容纳所有项目行所需的高度。

  2. 如果 size 属性不存在或没有有效值,则返回容纳四行所需的高度。

  3. 否则,返回容纳由元素的显示大小给定的行数所需的高度。

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 中的标签。

需要详细说明预期的本地外观基本外观

15.5.17 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”。

需要详细说明预期的本地外观基本外观

15.6 Frame 和 frameset

预计用户代理将 frameset 元素渲染为一个具有 视口 高度和宽度的框,其表面按照以下布局算法进行渲染:

  1. colsrows 变量是由数字和单位(单位为 百分比相对绝对 之一)组成的零个或多个对的列表。

    使用 解析尺寸列表的规则 解析元素的 cols 属性值(如果有)。将 cols 设为结果,如果没有此类属性,则为空列表。

    使用 解析尺寸列表的规则 解析元素的 rows 属性值(如果有)。将 rows 设为结果,如果没有此类属性,则为空列表。

  2. 对于 colsrows 中单位为 相对 的条目,如果数字为零,则将条目的数字更改为一。

  3. 如果 cols 没有条目,则在 cols 中添加一个值为 1 且单位为 相对 的条目。

    如果 rows 没有条目,则在 rows 中添加一个值为 1 且单位为 相对 的条目。

  4. 调用以下定义的算法将尺寸列表转换为像素值列表,使用 cols 作为输入列表,并以 frameset 所渲染表面的宽度(以CSS 像素为单位)作为输入尺寸。将结果列表设为 sized cols

    调用以下定义的算法将尺寸列表转换为像素值列表,使用 rows 作为输入列表,并以 frameset 所渲染表面的高度(以CSS 像素为单位)作为输入尺寸。将结果列表设为 sized rows

  5. 将表面分割成 w×h 的矩形网格,其中 wsized cols 中的条目数,hsized rows 中的条目数。

    设置列的大小,使得网格中的每一列的宽度都与 sized cols 列表中对应条目的像素值相同。

    设置行的大小,使得网格中的每一行的高度都与 sized rows 列表中对应条目的像素值相同。

  6. children 设为frameframeset 元素的列表,这些元素是调用该算法的 frameset 元素的子元素

  7. 对于在前一步中创建的矩形网格的每一行,从上到下执行以下子步骤:

    1. 对于每一行中的每个矩形,从左到右执行以下子步骤:

      1. 如果 children 中还有剩余元素,则取列表中的第一个元素并分配给该矩形。

        如果这是一个 frameset 元素,则为该 frameset 元素递归执行整个 frameset 布局算法,以该矩形为表面。

        否则,它是一个 frame 元素;渲染其 可导航内容,其位置和大小应适应该矩形。

      2. 如果 children 中还有剩余元素,则从 children 中移除第一个元素。

  8. 如果 frameset 元素有边框,则围绕矩形绘制一组外边框,使用元素的框架边框颜色

    对于每个矩形,如果该矩形被分配了一个元素,并且该元素有边框,则围绕该矩形绘制一组内边框,使用元素的框架边框颜色

    对于每一个(可见的)边框,如果它没有与分配了 frame 元素且带有 noresize 属性的矩形相邻(包括进一步嵌套的 frameset 元素中的矩形),则预计用户代理允许用户移动边框,重新调整矩形的大小,同时保持嵌套 frameset 网格的比例。

    一个 framesetframe 元素是否有边框,取决于以下算法是否返回 true:

    1. 如果元素有一个 frameborder 属性,其值不为空字符串且第一个字符为 U+0031 数字 1(1)字符、U+0079 小写字母 y(y)字符或 U+0059 大写字母 Y(Y)字符,则返回 true。

    2. 否则,如果元素有 frameborder 属性,则返回 false。

    3. 否则,如果元素有一个父元素且该父元素是一个 frameset 元素,则如果元素有边框则返回 true,否则返回 false。

    4. 否则,返回 true。

    框架边框颜色framesetframe 元素的颜色,按以下算法获得:

    1. 如果元素有 bordercolor 属性,并且将解析传统颜色值的规则 应用于该属性的值时没有导致错误,则返回所获得的颜色。

    2. 否则,如果元素有一个父元素且该父元素是一个 frameset 元素,则返回该元素的框架边框颜色

    3. 否则,返回灰色。

尺寸列表转换为像素值列表的算法包括以下步骤:

  1. input list 设为传递给该算法的数字和单位的列表。

    output list 设为与 input list 长度相同且所有值均为零的数字列表。

    output list 中的条目对应于 input list 中具有相同位置的条目。

  2. input dimension 设为传递给算法的大小。

  3. 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 的值。

  4. 如果 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

  5. 如果 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。

  6. 对于 input list 中单位为 相对 的每个条目,将 output list 中对应的值设为 input list 中该条目的数字乘以 remaining space 并除以 total relative

  7. 返回 output list

对于以整数值处理框架宽度的用户代理(与可以以子像素精度布局框架的用户代理不同),预计它们会首先将余数分配给单位为 相对 的最后一个条目,然后平均分配(而不是按比例分配)给单位为 百分比 的每个条目,再平均分配(而不是按比例分配)给单位为 绝对 的每个条目,最后,所有其他方法都失败时,分配给最后一个条目。


没有 frameset 父元素的 frame 元素的内容预计会被渲染为 透明黑;在这种情况下,预计用户代理不会渲染其 可导航内容,并且其可导航内容预计会有一个宽度和高度为零的 视口

15.7 交互媒体

15.7.1 链接、表单和导航

预计用户代理允许用户控制超链接激活和表单提交的各个方面,例如用于后续导航可导航对象

预计用户代理允许用户在触发导航之前,发现超链接表单的目的地。

预计用户代理会告知用户某个超链接是否包含超链接审计,并至少告知用户哪些域将作为此类审计的一部分被联系。

用户代理可以允许用户将可导航对象 导航到由cite属性指示的 URL解析,包括 qblockquoteinsdel 元素。

用户代理可以在其用户界面中显示由link 元素创建的超链接,如之前讨论的那样。

15.7.2 title 属性

预计用户代理在用户请求时公开元素的建议性信息,并让用户了解此类信息的存在。

在用户可以使用指针设备的交互式图形系统上,这可以采用工具提示的形式。当用户无法使用指针设备时,预计用户代理会通过其他方式使内容可用,例如将该元素设为可聚焦区域并始终显示当前聚焦元素的建议性信息,或在触摸设备上,当用户在屏幕上移动时,显示用户手指下元素的建议性信息

预计 U+000A 换行符(LF)字符会在工具提示中引起换行;预计 U+0009 字符制表符(tab)字符会呈现为非零水平位移,使下一个字形与下一个制表位对齐,制表位出现在 U+0020 空格字符宽度的 8 倍的倍数处。

例如,可视用户代理可以使具有title属性的元素可聚焦,并且可以使任何具有title属性的聚焦元素在元素获得焦点时显示其工具提示。这将允许用户通过 Tab 键在文档中浏览,找到所有的建议性文本。

再例如,屏幕阅读器在读取带有工具提示的元素时可以提供音频提示,并配有一个键,用于读取上一个播放提示的工具提示。

15.7.3 编辑容器

当前的文本编辑插入符(即活动范围,如果它是空的并且在编辑容器中),预计在 CSS 渲染模型中表现为一个内联的替换元素,其垂直尺寸为插入符的高度,宽度为零。

这意味着即使是一个空块也可以包含插入符,并且当插入符位于这样的元素中时,它会阻止边距在元素内折叠

15.7.4 在原生用户界面中呈现的文本

用户代理应遵循在用户界面中暴露的文本的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]

当用户实际获取物理形式(或物理形式的表示)文档时,用户代理应为打印媒体创建该文档的新渲染。

15.9 无样式的 XML 文档

HTML用户代理在某些情况下可能会渲染非HTML文档,这些文档使用的词汇表可能是用户代理没有内置知识的。本节为用户代理提供了一种处理这些文档的有用方式。

文档是一个无样式文档时,用户代理应渲染无样式文档视图

文档符合以下条件时,它是一个无样式文档

无样式文档视图是指DOM没有按照CSS渲染(在这种情况下,由于没有适用的样式,最终只会产生一堆文本),而是以对开发者有用的方式进行渲染。它可以只是显示文档对象的源代码,可能带有语法高亮,或者显示DOM树,或者仅仅显示一条消息,说明页面不是样式化文档。

如果文档不再是无样式文档,则上述条件不再适用,因此,遵循这些要求的用户代理将切换到使用常规的CSS渲染。

16 废弃的功能

16.1 废弃但合规的功能

本节中列出的功能将在合规性检查器中触发警告。

作者不应在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元素上指定maxlengthsize属性,这些元素的type属性处于Number状态。尽管如此,一个合理的原因是,为了帮助不支持input元素的旧版用户代理,这些旧版用户代理无法正确渲染带有type="number"的文本控件。

16.1.1 废弃但合规功能的警告

为了简化从HTML4过渡到本规范定义的语言,并为了劝阻在极少数情况下才允许的某些功能,合规性检查器必须在文档中使用以下功能时向用户发出警告。这些通常是没有效果的旧的废弃功能,仅允许用于区分可能的错误(常规的合规性错误)和仅仅是残留标记或不常见且不推荐的做法(这些警告)。

以下功能必须如上所述分类:

合规性检查器必须区分没有合规性错误且没有这些废弃功能的页面和没有合规性错误但有这些废弃功能的页面。

例如,验证器可以将某些页面报告为“有效的HTML”,而将其他页面报告为“带有警告的有效HTML”。

16.2 不合规功能

以下列表中的元素已完全废弃,作者不得使用:

applet

请改用embedobject

acronym

请改用abbr

bgsound

请改用audio

dir

请改用ul

frame
frameset
noframes

请改用iframe和CSS,或使用服务器端包含生成包含各个不变部分的完整页面。

isindex

请改用显式form文本控件组合。

keygen

对于企业设备管理的使用场景,请使用设备本地的管理功能。

对于证书注册的使用场景,请使用Web Cryptography API生成证书的密钥对,然后导出证书和密钥,以允许用户手动安装它们。[WEBCRYPTO]

listing

请改用precode

menuitem

要实现自定义上下文菜单,请使用脚本处理contextmenu事件。

nextid

请改用GUID。

noembed

在需要回退时,请改用object而不是embed

param

请使用data属性设置object元素的外部资源URL。

plaintext

请改用"text/plain"MIME类型

rb
rtc

直接在ruby元素中提供ruby基,或使用嵌套ruby元素。

strike

如果元素标记为编辑内容,请改用del,否则请改用s

xmp

请改用precode,并分别将"<"和"&"字符转义为"&lt;"和"&amp;"。

basefont
big
blink
center
font
marquee
multicol
nobr
spacer
tt

请改用适当的元素或CSS。

如果tt元素曾用于标记键盘输入,请考虑使用kbd元素;对于变量,请考虑使用var元素;对于计算机代码,请考虑使用code元素;对于计算机输出,请考虑使用samp元素。

同样,如果big元素用于表示标题,请考虑使用h1元素;如果它用于标记重要段落,请考虑使用strong元素;如果用于突出显示参考目的的文本,请考虑使用mark元素。

另请参见文本级语义使用摘要,其中提供了更多建议和示例。


以下属性已废弃(尽管元素仍然是语言的一部分),作者不得使用:

charseta元素上
charsetlink元素上

请改用链接资源上的HTTP `Content-Type` 头。

charsetscript元素上(除了前一部分中提到的情况)

省略此属性。文档和脚本都要求使用UTF-8,因此在script元素上指定此属性是多余的,因为它继承自文档。

coordsa元素上
shapea元素上

对于图像映射,请改用area元素。

methodsa元素上
methodslink元素上

请改用HTTP OPTIONS功能。

namea元素上(除了前一部分中提到的情况)
nameembed元素上
nameimg元素上
nameoption元素上

请改用id属性。

reva元素上
revlink元素上

请改用rel属性,并使用相反的术语。(例如,不使用rev="made",而使用rel="author"。)

urna元素上
urnlink元素上

请改用href属性指定首选持久标识符。

acceptform元素上

请直接在accept属性的input元素上使用该属性。

hreflangarea元素上
typearea元素上

这些属性没有任何实用作用,出于历史原因,area元素上没有相应的IDL属性。请完全省略它们。

nohrefarea元素上

省略href属性就足够了;nohref属性是多余的。请完全省略它。

profilehead元素上

不必要。请完全省略它。

manifesthtml元素上

请改用服务工作线程。[SW]

versionhtml元素上

不必要。请完全省略它。

ismapinput元素上

不必要。请完全省略它。所有input元素,type属性处于图像按钮状态时,将作为服务器端图像映射进行处理。

usemapinput元素上
usemapobject元素上

对于图像映射,请改用img元素。

longdesciframe元素上
longdescimg元素上

请使用常规a元素链接到描述,或(在图像的情况下)使用图像映射,从图像链接到图像的描述。

lowsrcimg元素上

请改用渐进式JPEG图像(在src属性中给出),而不是使用两个单独的图像。

targetlink元素上

不必要。请完全省略它。

typemenu元素上

要实现自定义上下文菜单,请使用脚本处理contextmenu事件。对于工具栏菜单,请省略此属性。

labelmenu元素上
contextmenu 在所有元素上
onshow 在所有元素上

要实现自定义上下文菜单,请使用脚本处理contextmenu事件。

schememeta元素上

每个字段仅使用一个方案,或使方案声明成为值的一部分。

archiveobject元素上
classidobject元素上
codeobject元素上
codebaseobject元素上
codetypeobject元素上

请改用datatype属性来调用插件

declareobject元素上

每次重新使用资源时,请完全重复object元素。

standbyobject元素上

优化链接资源,使其加载速度更快,或至少是增量加载。

typemustmatchobject元素上

避免使用带有不受信任资源的object元素。

languagescript元素上(除了前一部分中提到的情况)

对于JavaScript,请省略该属性;对于数据块,请改用type属性。

eventscript元素上
forscript元素上

请使用DOM事件机制来注册事件监听器。[DOM]

typestyle元素上(除了前一部分中提到的情况)

对于CSS,请省略该属性;对于数据块,请使用script作为容器,而不是style

datapagesizetable元素上

不必要。请完全省略它。

summarytable元素上

请改用描述表格的技术中提供的技术。该技术在table部分中进行了说明。

abbrtd元素上

请使用以明确简洁方式开头的文本,并在之后包括任何更详细的文本。title属性也可以在包括更详细的文本时有用,以便使单元格的内容简洁。如果是标题,请使用th(它有一个abbr属性)。

axistdth元素上

请在相关th元素上使用scope属性。

scopetd元素上

对于标题单元格,请使用th元素。

datasrcabuttondivframeiframeimginputlabellegendmarqueeobjectoptionselectspantable 元素上
datafldabuttondivfieldsetframeiframeimginputlabellegendmarqueeobjectselectspantextarea 元素上
dataformatasbuttondivinputlabellegendmarqueeobjectoptionselectspantable 元素上

使用脚本和诸如 XMLHttpRequest 等机制来动态填充页面。[XHR]

dropzone 在所有元素上

请使用脚本处理dragenterdragover事件。

alinkbody元素上
bgcolorbody元素上
bottommarginbody元素上
leftmarginbody元素上
linkbody元素上
marginheightbody元素上
marginwidthbody元素上
rightmarginbody元素上
textbody元素上
topmarginbody元素上
vlinkbody元素上
clearbr元素上
aligncaption元素上
aligncol元素上
charcol元素上
charoffcol元素上
valigncol元素上
widthcol元素上
aligndiv元素上
compactdl元素上
alignembed元素上
hspaceembed元素上
vspaceembed元素上
alignhr元素上
colorhr元素上
noshadehr元素上
sizehr元素上
widthhr元素上
alignh1h6元素上
aligniframe元素上
allowtransparencyiframe元素上
frameborderiframe元素上
framespacingiframe元素上
hspaceiframe元素上
marginheightiframe元素上
marginwidthiframe元素上
scrollingiframe元素上
vspaceiframe元素上
aligninput元素上
borderinput元素上
hspaceinput元素上
vspaceinput元素上
alignimg元素上
borderimg元素上(除了前一部分中提到的情况)
hspaceimg元素上
vspaceimg元素上
alignlegend元素上
typeli元素上
compactmenu元素上
alignobject元素上
borderobject元素上
hspaceobject元素上
vspaceobject元素上
compactol元素上
alignp元素上
widthpre元素上
aligntable元素上
bgcolortable元素上
bordertable元素上
bordercolortable元素上
cellpaddingtable元素上
cellspacingtable元素上
frametable元素上
heighttable元素上
rulestable元素上
widthtable元素上
aligntbodytheadtfoot元素上
chartbodytheadtfoot元素上
charofftbodytheadtfoot元素上
heighttheadtbodytfoot元素上
valigntbodytheadtfoot元素上
aligntdth元素上
bgcolortdth元素上
chartdth元素上
charofftdth元素上
heighttdth元素上
nowraptdth元素上
valigntdth元素上
widthtdth元素上
aligntr元素上
bgcolortr元素上
chartr元素上
charofftr元素上
heighttr元素上
valigntr元素上
compactul元素上
typeul元素上
backgroundbodytabletheadtbodytfoottrtdth元素上

请使用CSS。

16.3 实现要求

16.3.1 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();
};

marquee 元素可以被打开关闭。创建时,它是打开的

当调用 start() 方法时,marquee 元素必须打开

当调用 stop() 方法时,marquee 元素必须关闭


behavior 属性在 marquee 元素上是一个枚举属性,具有以下关键字和状态(均不符合标准):

关键字 状态
scroll scroll
slide slide
alternate alternate

该属性的缺失值默认值无效值默认值都是scroll状态。


direction 属性在 marquee 元素上是一个枚举属性,具有以下关键字和状态(均不符合标准):

关键字 状态
left left
right right
up up
down down

该属性的缺失值默认值无效值默认值都是left状态。


truespeed 属性在 marquee 元素上是一个布尔属性


marquee 元素具有一个滚动间隔,通过以下方式获得:

  1. 如果元素具有scrolldelay属性,并且使用解析非负整数的规则解析其值时未返回错误,则将delay设置为解析后的值。否则,将delay设置为85。

  2. 如果元素没有truespeed属性,并且delay值小于60,则将delay设置为60。

  3. 滚动间隔delay,以毫秒为单位。


marquee 元素具有一个滚动距离,如果元素具有scrollamount属性,并且使用解析非负整数的规则解析其值时未返回错误,则该值以CSS 像素为单位解析,否则为6CSS 像素


marquee 元素具有一个循环次数,如果元素具有loop属性,并且使用解析整数的规则解析其值时未返回错误或数字小于1,则该值为解析后的值,否则为-1。

loop IDL属性在获取时,必须返回元素的循环次数;在设置时,如果新值与元素的循环次数不同,并且大于零或等于-1,则必须将元素的loop内容属性(如有必要)设置为表示新值的有效整数。(其他值将被忽略。)

marquee 元素还具有一个当前循环索引,该索引在元素创建时为零。

渲染层偶尔会增加当前循环索引,这将导致运行以下步骤:

  1. 如果循环次数为-1,则返回。

  2. 当前循环索引增加一。

  3. 如果当前循环索引现在大于或等于元素的循环次数,则关闭 marquee 元素。


behaviordirectionheighthspacevspacewidth IDL属性必须反映同名内容属性。

bgColor IDL属性必须反映 bgcolor 内容属性。

scrollAmount IDL属性必须反映 scrollamount 内容属性。默认值为6。

scrollDelay IDL属性必须反映 scrolldelay 内容属性。默认值为85。

trueSpeed IDL属性必须反映 truespeed 内容属性。

16.3.2 框架

frameset 元素在使用框架的文档中充当body 元素

frameset 元素必须实现 HTMLFrameSetElement 接口。

[Exposed=Window]
interface HTMLFrameSetElement : HTMLElement {
  [HTMLConstructor] constructor();

  [CEReactions] attribute DOMString cols;
  [CEReactions] attribute DOMString rows;
};
HTMLFrameSetElement includes WindowEventHandlers;

colsrows IDL 属性必须反映同名内容属性。

frameset 元素公开了一些事件处理程序内容属性,这些属性属于 Window 对象的事件处理程序。它还会镜像其事件处理程序 IDL 属性

Window 对象的事件处理程序,由Window 反映 body 元素事件处理程序集命名,在 frameset 元素上公开时,替换了通常由HTML 元素支持的具有相同名称的通用事件处理程序


frame 元素具有类似于 iframe 元素的可导航内容,但在 frameset 元素中呈现。

frameHTML 元素插入步骤,给定 insertedNode,如下:

  1. 如果 insertedNode 不在文档树中,则返回。

  2. 如果 insertedNode浏览上下文为空,则返回。

  3. insertedNode 创建一个新的子导航

  4. insertedNode 处理 frame 属性,并将 initialInsertion 设置为 true。

frameHTML 元素删除步骤,给定 removedNode,是销毁给定 removedNode 的子导航

每当具有非空可导航内容frame 元素的 src 属性被设置、更改或删除时,用户代理必须处理 frame 属性

为元素 element 处理 frame 属性,可选地带有布尔值 initialInsertion

  1. url 是在给定 elementinitialInsertion 的情况下运行iframe 和 frame 元素的共享属性处理步骤的结果。

  2. 如果 url 为 null,则返回。

  3. 如果 url 匹配 about:blank 并且 initialInsertion 为 true,则:

    1. 触发一个名为 load 的事件在 element 上。

    2. 返回。

  4. 在给定 elementurl 和空字符串的情况下导航 iframeframe

frame 元素可能会延迟 load 事件

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;
};

namescrollingsrc IDL 属性必须反映同名内容属性。为反映的目的,frame 元素的 src 内容属性被定义为包含URL

frameBorder IDL 属性必须反映元素的 frameborder 内容属性。

longDesc IDL 属性必须反映元素的 longdesc 内容属性,该属性为反映的目的被定义为包含URL

noResize IDL 属性必须反映元素的 noresize 内容属性。

marginHeight IDL 属性必须反映元素的 marginheight 内容属性。

marginWidth IDL 属性必须反映元素的 marginwidth 内容属性。

contentDocument 的获取步骤是返回this内容文档

contentWindow 的获取步骤是返回this内容窗口

16.3.3 其他元素、属性和 APIs

用户代理必须将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;
};

coordscharsetnamerevshape 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;
};

text IDL 属性必须反映元素的text内容属性。

link IDL 属性必须反映元素的link内容属性。

aLink IDL 属性必须反映元素的alink内容属性。

vLink IDL 属性必须反映元素的vlink内容属性。

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;
};

alignwidth IDL 属性必须反映同名内容属性。

ch IDL 属性必须反映元素的char内容属性。

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;
};

namealign IDL 属性必须反映同名内容属性。


font元素 必须实现HTMLFontElement接口。

[Exposed=Window]
interface HTMLFontElement : HTMLElement {
  [HTMLConstructor] constructor();

  [CEReactions] attribute [LegacyNullToEmptyString] DOMString color;
  [CEReactions] attribute DOMString face;
  [CEReactions] attribute DOMString size; 
};

colorfacesize 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;
};

aligncolorsizewidth 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;
};

alignscrolling 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;
};

namealignborderhspacevspace 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;
};

charsetrevtarget 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;
};

alignarchivebordercodedeclarehspacestandbyvspace IDL 属性必须反映同名内容属性。

codeBase IDL 属性必须反映元素的codebase内容属性,出于反映的目的, 定义为包含URL

codeType IDL 属性必须反映元素的codetype内容属性。

HTMLObjectElement/useMap

支持所有当前引擎。

Firefox1+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (旧版)12+Internet Explorer6+
Firefox Android?Safari iOS1+Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+

useMap IDL 属性必须反映usemap内容属性。


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;
};

namevaluetype 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;
};

charsetevent 的 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;
};

alignborderframesummaryruleswidth 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 属性的 tbodytheadtfoot 元素必须 反映 同名内容属性。

ch IDL 属性的 tbodytheadtfoot 元素必须 反映 元素的 char 内容属性。

chOff IDL 属性的 tbodytheadtfoot 元素必须 反映 元素的 charoff 内容属性。

vAlign IDL 属性的 tbodytheadtfoot 元素必须 反映 元素的 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;
};

alignaxisheightwidth IDL 属性的 tdth 元素必须 反映 同名内容属性。

ch IDL 属性的 tdth 元素必须 反映 元素的 char 内容属性。

chOff IDL 属性的 tdth 元素必须 反映 元素的 charoff 内容属性。

noWrap IDL 属性的 tdth 元素必须 反映 元素的 nowrap 内容属性。

vAlign IDL 属性的 tdth 元素必须 反映 元素的 valign 内容属性。

bgColor IDL 属性的 tdth 元素必须 反映 元素的 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;
};

compacttype 的 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() 方法必须不执行任何操作。

17 IANA 考虑事项

17.1 text/html

此注册供社区审查,并将提交给 IESG 以进行审查、批准和向 IANA 注册。

类型名称:
text
子类型名称:
html
必需参数:
无必需参数
可选参数:
charset

可以提供 charset 参数来指定 文档的字符编码,覆盖文档中的任何 字符编码声明(字节顺序标记(BOM)除外)。该参数的值必须与字符串 "utf-8" 进行 ASCII 不区分大小写 匹配。[ENCODING]

编码注意事项:
8位(参见有关 字符编码声明 的章节)
安全注意事项:

关于适用于 HTML 文档的安全注意事项,已经写了整本小说。本文件中列出了许多,读者可参阅以了解更多细节。然而,这里提到了一些一般关注的问题:

HTML 是一种脚本语言,具有大量的 API(其中一些在本文件中有描述)。脚本可能会使用户面临信息泄露、凭证泄露、跨站脚本攻击、跨站请求伪造以及许多其他问题的潜在风险。虽然本规范中的设计旨在正确实现时是安全的,但完全实现是一个庞大的工作,和任何软件一样,用户代理可能会有安全漏洞。

即使没有脚本,HTML 中也有一些特定功能由于历史原因需要与旧内容广泛兼容,但这会使用户面临不幸的安全问题。特别是,img 元素可以与其他一些功能结合使用,作为从用户在互联网上的位置进行端口扫描的一种方式。这可能会暴露攻击者无法确定的本地网络拓扑。

HTML 依赖于一种隔离方案,有时称为 同源策略来源 在大多数情况下由使用相同协议、在相同端口上提供的所有页面组成。

因此,至关重要的是,确保任何不受信任的内容作为站点的一部分托管在与该站点上的任何敏感内容不同的 来源 上。不受信任的内容可以很容易地伪造同一来源上的任何其他页面,读取该来源的数据,使该来源中的脚本执行,即使它们受到独特令牌的跨站请求伪造攻击保护,也可以提交表单到该来源并从该来源提交表单,并利用暴露给该来源的任何第三方资源或授予该来源的权利。

互操作性注意事项:
本规范中定义了处理符合规范和不符合规范内容的规则。
已发布的规范:
本文件是相关的规范。将资源标记为 text/html 类型表明该资源是使用 HTML 文档 使用 HTML 语法
使用此媒体类型的应用程序:
Web 浏览器、处理 web 内容的工具、HTML 编写工具、搜索引擎、验证器。
其他信息:
魔数:
没有字节序列可以唯一标识 HTML 文档。有关检测 HTML 文档的更多信息,请参见 MIME Sniffing[MIMESNIFF]
文件扩展名:
"html" 和 "htm" 通常(但绝不是唯一的)用作 HTML 文档的扩展名。
Macintosh 文件类型代码:
TEXT
联系人及邮箱以获取更多信息:
Ian Hickson <ian@hixie.ch>
预期用途:
常见
使用限制:
无适用限制。
作者:
Ian Hickson <ian@hixie.ch>
变更控制者:
W3C

片段 用于 text/html 资源时,指向对应 文档的指示部分,或为页面内的脚本提供状态信息。

17.2multipart/x-mixed-replace

此注册供社区审查,并将提交给 IESG 以进行审查、批准和向 IANA 注册。

类型名称:
multipart
子类型名称:
x-mixed-replace
必需参数:
可选参数:
无可选参数。
编码注意事项:
二进制
安全注意事项:
multipart/x-mixed-replace 资源的子资源可以是任何类型,包括具有非平凡安全隐患的类型,例如 text/html
互操作性注意事项:
无。
已发布的规范:
本规范描述了网页浏览器的处理规则。生成此类型资源的符合性要求与 multipart/mixed 相同。[RFC2046]
使用此媒体类型的应用程序:
此类型旨在由 web 服务器生成资源,以供 web 浏览器使用。
其他信息:
魔数:
没有字节序列可以唯一标识 multipart/x-mixed-replace 资源。
文件扩展名:
不推荐此类型的特定文件扩展名。
Macintosh 文件类型代码:
不推荐此类型的特定 Macintosh 文件类型代码。
联系人及邮箱以获取更多信息:
Ian Hickson <ian@hixie.ch>
预期用途:
常见
使用限制:
无适用限制。
作者:
Ian Hickson <ian@hixie.ch>
变更控制者:
W3C

片段 用于 multipart/x-mixed-replace 资源时,适用于每个由该主体部分使用的类型定义的主体部分。

17.3 application/xhtml+xml

此注册供社区审查,并将提交给 IESG 以进行审查、批准和向 IANA 注册。

类型名称:
application
子类型名称:
xhtml+xml
必需参数:
application/xml 相同 [RFC7303]
可选参数:
application/xml 相同 [RFC7303]
编码注意事项:
application/xml 相同 [RFC7303]
安全注意事项:
application/xml 相同 [RFC7303]
互操作性注意事项:
application/xml 相同 [RFC7303]
已发布的规范:
将资源标记为 application/xhtml+xml 类型表明该资源是一个 XML 文档,并且可能具有来自 文档元素HTML 命名空间。因此,相关的规范是 XMLXML 命名空间 以及本规范。[XML] [XMLNS]
使用此媒体类型的应用程序:
application/xml 相同 [RFC7303]
其他信息:
魔数:
application/xml 相同 [RFC7303]
文件扩展名:
"xhtml" 和 "xht" 有时用作具有来自 文档元素HTML 命名空间 的 XML 资源的扩展名。
Macintosh 文件类型代码:
TEXT
联系人及邮箱以获取更多信息:
Ian Hickson <ian@hixie.ch>
预期用途:
常见
使用限制:
无适用限制。
作者:
Ian Hickson <ian@hixie.ch>
变更控制者:
W3C

片段 用于 application/xhtml+xml 资源时,其语义与任何 XML MIME 类型 相同。[RFC7303]

17.4 text/ping

此注册供社区审查,并将提交给 IESG 以进行审查、批准和向 IANA 注册。

类型名称:
text
子类型名称:
ping
必需参数:
无参数
可选参数:
charset

可以提供 charset 参数。该参数的值必须为 "utf-8"。此参数没有实际用途;仅为了与旧版服务器兼容而允许使用。

编码注意事项:
不适用。
安全注意事项:

如果完全按照超链接审计的上下文中描述的方式使用,则此类型不会引入新的安全问题。

互操作性注意事项:
适用于此类型的规则在本规范中定义。
已发布的规范:
本文件是相关规范。
使用此媒体类型的应用程序:
Web 浏览器。
其他信息:
魔数:
text/ping 资源始终由四个字节 0x50 0x49 0x4E 0x47 (`PING`) 组成。
文件扩展名:
不推荐此类型的特定文件扩展名。
Macintosh 文件类型代码:
不推荐此类型的特定 Macintosh 文件类型代码。
联系人及邮箱以获取更多信息:
Ian Hickson <ian@hixie.ch>
预期用途:
常见
使用限制:
仅用于由 Web 浏览器处理 ping 属性时生成的 HTTP POST 请求。
作者:
Ian Hickson <ian@hixie.ch>
变更控制者:
W3C

片段 对于 text/ping 资源没有意义。

17.5application/microdata+json

此注册供社区审查,并将提交给 IESG 以进行审查、批准和向 IANA 注册。

类型名称:
application
子类型名称:
microdata+json
必需参数:
application/json 相同 [JSON]
可选参数:
application/json 相同 [JSON]
编码注意事项:
8位(始终为 UTF-8)
安全注意事项:
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]
Macintosh 文件类型代码:
application/json 相同 [JSON]
联系人及邮箱以获取更多信息:
Ian Hickson <ian@hixie.ch>
预期用途:
常见
使用限制:
无适用限制。
作者:
Ian Hickson <ian@hixie.ch>
变更控制者:
W3C

片段 用于 application/microdata+json 资源时,其语义与用于 application/json 时相同(即在撰写本文时,没有任何语义)。[JSON]

17.6text/event-stream

此注册供社区审查,并将提交给 IESG 以进行审查、批准和向 IANA 注册。

类型名称:
text
子类型名称:
event-stream
必需参数:
无参数
可选参数:
charset

可以提供 charset 参数。该参数的值必须为 "utf-8"。此参数没有实际用途;仅为了与旧版服务器兼容而允许使用。

编码注意事项:
8位(始终为 UTF-8)
安全注意事项:

来自与使用事件流的内容的来源不同的来源的事件流可能会导致信息泄露。为避免这种情况,要求用户代理应用 CORS 语义。[FETCH]

事件流可能会使用户代理不堪重负;预期用户代理会应用适当的限制,以避免由于来自事件流的信息过多而耗尽本地资源。

如果服务器导致客户端快速重新连接,服务器可能会不堪重负。服务器应使用 5xx 状态码来表示容量问题,因为这将防止符合标准的客户端自动重新连接。

互操作性注意事项:
本规范中定义了处理符合规范和不符合规范内容的规则。
已发布的规范:
本文件是相关规范。
使用此媒体类型的应用程序:
Web 浏览器和使用 Web 服务的工具。
其他信息:
魔数:
没有字节序列可以唯一标识事件流。
文件扩展名:
不推荐此类型的特定文件扩展名。
Macintosh 文件类型代码:
不推荐此类型的特定 Macintosh 文件类型代码。
联系人及邮箱以获取更多信息:
Ian Hickson <ian@hixie.ch>
预期用途:
常见
使用限制:
此格式仅预期用于通过 HTTP 或类似协议提供的动态开放式流。不预期有限资源使用此类型进行标记。
作者:
Ian Hickson <ian@hixie.ch>
变更控制者:
W3C

片段 对于 text/event-stream 资源没有意义。

17.7web+ scheme 前缀

本节描述了 IANA URI 协议注册表中使用的约定。它本身并未注册特定的协议。[RFC7595]

协议名称:
以 "web+" 开头,后跟一个或多个 a-z 范围内字母的协议。
状态:
永久
协议语法:
协议特定。
协议语义:
协议特定。
编码注意事项:
所有 "web+" 协议在相关情况下应使用 UTF-8 编码。
使用此协议名称的应用程序/协议:
协议特定。
互操作性注意事项:
该协议预计将在 Web 应用程序的上下文中使用。
安全注意事项:
任何网页都可以为所有 "web+" 协议注册一个处理程序。因此,这些协议不得用于预期为核心平台功能(例如 HTTP)的功能。同样,此类协议不得在其 URL 中存储机密信息,例如用户名、密码、个人信息或机密项目名称。
联系人:
Ian Hickson <ian@hixie.ch>
变更控制者:
Ian Hickson <ian@hixie.ch>
参考资料:
Custom scheme handlers,HTML Living Standard: #custom-handlers

索引

以下部分仅涵盖符合规范的元素和特性。

元素

本节为非规范性内容。

元素列表
元素 描述 类别 父元素† 子元素 属性 接口
a 超链接 流内容; 短语内容*; 交互内容; 可感知内容 短语内容 透明* 全局属性; href; target; download; ping; rel; hreflang; type; referrerpolicy HTMLAnchorElement
abbr 缩写 流内容; 短语内容; 可感知内容 短语内容 短语内容 全局属性 HTMLElement
address 页面或 article 元素的联系信息 流内容; 可感知内容 流内容 流内容* 全局属性 HTMLElement
area 图像映射上的超链接或死区 流内容; 短语内容 短语内容* 全局属性; alt; coords; shape; href; target; download; ping; rel; referrerpolicy HTMLAreaElement
article 独立的可联合或可重用的组成部分 流内容; 章节内容; 可感知内容 流内容 流内容 全局属性 HTMLElement
aside 与内容有间接关系的侧栏 流内容; 章节内容; 可感知内容 流内容 流内容 全局属性 HTMLElement
audio 音频播放器 流内容; 短语内容; 嵌入内容; 交互内容; 可感知内容* 短语内容 source*; track*; 透明* 全局属性; src; crossorigin; preload; autoplay; loop; muted; controls HTMLAudioElement
b 关键词 流内容; 短语内容; 可感知内容 短语内容 短语内容 全局属性 HTMLElement
base 超链接和表单的基准 URL 和默认目标 导航 元数据 head 全局属性; href; target HTMLBaseElement
bdi 文本方向隔离 流内容; 短语内容; 可感知内容 短语内容 短语内容 全局属性 HTMLElement
bdo 文本方向格式化 流内容; 短语内容; 可感知内容 短语内容 短语内容 全局属性 HTMLElement
blockquote 引用自其他来源的部分 流内容; 可感知内容 流内容 流内容 全局属性; cite HTMLQuoteElement
body 文档主体 html 流内容 全局属性; onafterprint; onbeforeprint; onbeforeunload; onhashchange; onlanguagechange; onmessage; onmessageerror; onoffline; ononline; onpageswap; onpagehide; onpagereveal; onpageshow; onpopstate; onrejectionhandled; onstorage; onunhandledrejection; onunload HTMLBodyElement
br 换行符,例如在诗或地址中 流内容; 短语内容 短语内容 全局属性 HTMLBRElement
button 按钮控件 流内容; 短语内容; 交互内容; 列表项; 标签项; 提交项; 表单相关元素; 可感知内容 短语内容 短语内容* 全局属性; disabled; form; formaction; formenctype; formmethod; formnovalidate; formtarget; name; popovertarget; popovertargetaction; type; value HTMLButtonElement
canvas 可编程位图画布 流内容; 短语内容; 嵌入内容; 可感知内容 短语内容 透明 全局属性; width; height HTMLCanvasElement
caption 表格标题 table 流内容* 全局属性 HTMLTableCaptionElement
cite 作品标题 流内容; 短语内容; 可感知内容 短语内容 短语内容 全局属性 HTMLElement
code 计算机代码 流内容; 短语内容; 可感知内容 短语内容 短语内容 全局属性 HTMLElement
col 表格列 colgroup 全局属性; span HTMLTableColElement
colgroup 表格中的列组 table col*; template* 全局属性; span HTMLTableColElement
data 机器可读的等效内容 流内容; 短语内容; 可感知内容 短语内容 短语内容 全局属性; value HTMLDataElement
datalist 组合框控件 提供选项的容器 流内容; 短语内容 短语内容 短语内容*; option*; 脚本支持元素* 全局属性 HTMLDataListElement
dd 对应dt 元素的内容 dl; div* 流内容 全局属性 HTMLElement
del 文档中的删除部分 流内容; 短语内容*; 显著内容 短语内容 透明 全局属性; cite; datetime HTMLModElement
details 用于隐藏详细信息的展开控件 流内容; 交互式内容; 显著内容 流内容 summary*; 流内容 全局属性; name; open HTMLDetailsElement
dfn 定义实例 流内容; 短语内容; 显著内容 短语内容 短语内容* 全局属性 HTMLElement
dialog 对话框或窗口 流内容 流内容 流内容 全局属性; open HTMLDialogElement
div 通用流容器,或dl 元素中的名称-值组容器 流内容; 显著内容 流内容; dl 流内容 全局属性 HTMLDivElement
dl 由零个或多个名称-值组组成的关联列表 流内容; 显著内容 流内容 dt*; dd*; div*; 支持脚本的元素 全局属性 HTMLDListElement
dt 对应dd 元素的标题 dl; div* 流内容* 全局属性 HTMLElement
em 强调重音 流内容; 短语内容; 显著内容 短语内容 短语内容 全局属性 HTMLElement
embed 插件 流式; 短语; 嵌入; 交互式; 可感知 短语 全局属性; src; type; width; height; 任何* HTMLEmbedElement
fieldset 表单控件组 流式; 列表; 表单关联; 可感知 流式 legend*; 流式 全局属性; disabled; form; name HTMLFieldSetElement
figcaption figure提供标题 figure 流式 全局属性 HTMLElement
figure 带可选标题的图形 流式; 可感知 流式 figcaption*; 流式 全局属性 HTMLElement
footer 页面或部分的页脚 流式; 可感知 流式 流式* 全局属性 HTMLElement
form 用户可提交的表单 流式; 可感知 流式 流式* 全局属性; accept-charset; action; autocomplete; enctype; method; name; novalidate; rel; target HTMLFormElement
h1, h2, h3, h4, h5, h6 标题 流式; 标题; 可感知 legend; summary; 流式 短语 全局属性 HTMLHeadingElement
head 文档元数据容器 html 元数据内容* 全局属性 HTMLHeadElement
header 页面或部分的介绍或导航辅助 流式; 可感知 流式 流式* 全局属性 HTMLElement
hgroup 标题容器 流式; 可感知 legend; summary; 流式 h1; h2; h3; h4; h5; h6; 脚本支持元素 全局属性 HTMLElement
hr 主题分隔符 流式 流式 全局属性 HTMLHRElement
html 根元素 无* head*; body* 全局属性; manifest HTMLHtmlElement
i 备用语气 流式; 短语; 可感知 短语 短语 全局属性 HTMLElement
iframe 子导航 流式; 短语; 嵌入式; 交互式; 可感知 短语 全局属性; src; srcdoc; name; sandbox; allow; allowfullscreen; width; height; referrerpolicy; loading HTMLIFrameElement
img 图片 ; 短语; 嵌入; 互动*; 表单关联; 可感知 短语; picture 全局属性; alt; src; srcset; sizes; crossorigin; usemap; ismap; width; height; referrerpolicy; decoding; loading; fetchpriority HTMLImageElement
input 表单控件 ; 短语; 互动*; 列出; 可标记; 可提交; 可重置; 表单关联; 可感知* 短语 全局属性; accept; alt; autocomplete; checked; dirname; disabled; form; formaction; formenctype; formmethod; formnovalidate; formtarget; height; list; max; maxlength; min; minlength; multiple; name; pattern; placeholder; popovertarget; popovertargetaction; readonly; required; size; src; step; type; value; width HTMLInputElement
ins 文档中的新增内容 ; 短语*; 可感知 短语 透明 全局属性; cite; datetime HTMLModElement
kbd 用户输入 ; 短语; 可感知 短语 短语 全局属性 HTMLElement
label 表单控件的标签 ; 短语; 互动; 可感知 短语 短语* 全局属性; for HTMLLabelElement
legend fieldset提供标题 fieldset 短语; 标题内容 全局属性 HTMLLegendElement
li 列表项 ol; ul; menu* 全局属性; value* HTMLLIElement
link 链接元数据 元数据; *; 短语* head; noscript*; 短语* 全局属性; href; crossorigin; rel; as; media; hreflang; type; sizes; imagesrcset; imagesizes; referrerpolicy; integrity; blocking; color; disabled; fetchpriority HTMLLinkElement
main 文档的主要内容容器 ; 可感知 * 全局属性 HTMLElement
map 图片地图 ; 短语*; 可感知 短语 透明; area* 全局属性; name HTMLMapElement
mark 高亮 ; 短语; 可感知 短语 短语 全局属性 HTMLElement
MathML math MathML 根元素 ; 短语; 嵌入; 可感知 短语 按照[MATHML] 按照[MATHML] Element
menu 命令菜单 ; 可感知* li; 支持脚本的元素 全局属性 HTMLMenuElement
meta 文本元数据 元数据; *; 短语* head; noscript*; 短语* 全局属性; name; http-equiv; content; charset; media HTMLMetaElement
meter 测量仪表 ; 短语; 可标记; 可感知 短语 短语* 全局属性; value; min; max; low; high; optimum HTMLMeterElement
nav 包含导航链接的部分 ; 分区; 可感知 全局属性 HTMLElement
noscript 脚本的回退内容 元数据; ; 短语 head*; 短语* 多变* 全局属性 HTMLElement
object 图像,可子导航,或插件 ; 短语; 嵌入; 交互*; 列出; 表单关联; 可感知 短语 透明 全局属性; data; type; name; form; width; height HTMLObjectElement
ol 有序列表 ; 可感知* li; 支持脚本的元素 全局属性; reversed; start; type HTMLOListElement
optgroup 列表框中的选项组 select option; 支持脚本的元素 全局属性; disabled; label HTMLOptGroupElement
option 列表框或组合框控件中的选项 select; datalist; optgroup 文本* 全局属性; disabled; label; selected; value HTMLOptionElement
output 计算结果值 ; 短语; 可列出; 可标记; 可重置; 表单关联; 可感知 短语 短语 全局属性; for; form; name HTMLOutputElement
p 段落 ; 可感知 短语 全局属性 HTMLParagraphElement
picture 图像 ; 短语; 嵌入; 可感知 短语 source*; 一个 img; 支持脚本的元素 全局属性 HTMLPictureElement
pre 预格式化文本块 ; 可感知 短语 全局属性 HTMLPreElement
progress 进度条 ; 短语; 可标记; 可感知 短语 短语* 全局属性; value; max HTMLProgressElement
q 引述 ; 短语; 可感知 短语 短语 全局属性; cite HTMLQuoteElement
rp 用于 ruby 注释文本的括号 ruby 文本 全局属性 HTMLElement
rt 注释文字 ruby 短语 全局属性 HTMLElement
ruby 注释标记 ; 短语; 可感知 短语 短语; rt; rp* 全局属性 HTMLElement
s 错误的文本 ; 短语; 可感知 短语 短语 全局属性 HTMLElement
samp 计算机输出 ; 短语; 可感知 短语 短语 全局属性 HTMLElement
script 嵌入脚本 元数据; ; 短语; 脚本支持 head; 短语; 脚本支持 脚本、数据或脚本文档* 全局属性; src; type; nomodule; async; defer; crossorigin; integrity; referrerpolicy; blocking; fetchpriority HTMLScriptElement
search 搜索控件的容器 ; 可感知 全局属性 HTMLElement
section 通用文档或应用部分 ; 章节; 可感知 全局属性 HTMLElement
select 列表框控件 ; 短语; 交互; 列出; 可标记; 可提交; 可重置; 表单关联; 可感知 短语 option; optgroup; 脚本支持元素 全局属性; autocomplete; disabled; form; multiple; name; required; size HTMLSelectElement
slot 影子树插槽 ; 短语 短语 透明 全局属性; name HTMLSlotElement
small 附注 ; 短语; 可感知 短语 短语 全局属性 HTMLElement
source img的图片源 或 video 的媒体源 或 audio 的媒体源 picture; video; audio 全局属性; type; media; src; srcset; sizes; width; height HTMLSourceElement
span 通用短语容器 ; 短语; 可感知 短语 短语 全局属性 HTMLSpanElement
strong 重要性 ; 短语; 可感知 短语 短语 全局属性 HTMLElement
style 嵌入的样式信息 元数据 head; noscript* 文本* 全局属性; media; blocking HTMLStyleElement
sub 下标 ; 短语; 可感知 短语 短语 全局属性 HTMLElement
summary details的标题 details 短语; 标题内容 全局属性 HTMLElement
sup 上标 ; 短语; 可感知 短语 短语 全局属性 HTMLElement
SVG svg SVG根元素 ; 短语; 嵌入; 可感知 短语 参考 [SVG] 参考 [SVG] SVGSVGElement
table 表格 ; 可感知 caption*; colgroup*; thead*; tbody*; tfoot*; tr*; 脚本支持元素 全局属性 HTMLTableElement
tbody 表格中的行组 table tr; 脚本支持元素 全局属性 HTMLTableSectionElement
td 表格单元格 tr 全局属性; colspan; rowspan; headers HTMLTableCellElement
template 模板 元数据; ; 短语; 脚本支持 元数据; 短语; 脚本支持; colgroup* 全局属性; shadowrootmode; shadowrootdelegatesfocus; shadowrootclonable; shadowrootserializable HTMLTemplateElement
textarea 多行文本控件 ; 短语; 交互; 列出; 可标记; 可提交; 可重置; 表单关联; 可感知 短语 文本 全局属性; autocomplete; cols; dirname; disabled; form; maxlength; minlength; name; placeholder; readonly; required; rows; wrap HTMLTextAreaElement
tfoot 表格中的页脚行组 table tr; 脚本支持元素 全局属性 HTMLTableSectionElement
th 表格标题单元格 交互* tr * 全局属性; colspan; rowspan; headers; scope; abbr HTMLTableCellElement
thead 表格中的标题行组 table tr; 脚本支持元素 全局属性 HTMLTableSectionElement
time 机器可读的日期或时间相关数据 ; 短语; 可感知 短语 短语 全局属性; datetime HTMLTimeElement
title 文档标题 元数据 head 文本* 全局属性 HTMLTitleElement
tr 表格行 table; thead; tbody; tfoot th*; td; 脚本支持元素 全局属性 HTMLTableRowElement
track 定时文本轨道 audio; video 全局属性; default; kind; label; src; srclang HTMLTrackElement
u 未明确的注释 ; 短语; 可感知 短语 短语 全局属性 HTMLElement
ul 列表 ; 可感知* li; 脚本支持元素 全局属性 HTMLUListElement
var 变量 ; 短语; 可感知 短语 短语 全局属性 HTMLElement
video 视频播放器 ; 短语; 嵌入; 交互; 可感知 短语 source*; track*; 透明* 全局属性; src; crossorigin; poster; preload; autoplay; playsinline; loop; muted; controls; width; height HTMLVideoElement
wbr 换行机会 ; 短语 短语 全局属性 HTMLElement
自主定义元素 作者定义的元素 ; 短语; 可感知 ; 短语 透明 全局属性; 任意,由元素的作者决定 由元素的作者提供(继承自HTMLElement

表格中的单元格内标有星号(*)表示实际规则比上表中显示的更为复杂。

† "父级"列中的类别指的是在其内容模型中列出了给定类别的父级元素,而不是那些自身属于这些类别的元素。例如,a元素的"父级"列中显示为"短语",因此任何内容模型包含"短语"类别的元素都可以是a元素的父级。由于"流"类别包含所有的"短语"元素,这意味着th元素可以是a元素的父级。

元素内容类别

本节为非规范性内容。

元素内容类别列表
类别 元素 有例外的元素
元数据内容 base; link; meta; noscript; script; style; template; title
流内容 a; abbr; address; 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; map; mark; MathML math; menu; 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 svg; table; template; textarea; time; u; ul; var; video; wbr; 自主定义元素; 文本 area (如果它是map元素的后代); link (如果它允许在body中); main (如果它是层级正确的main元素); meta (如果存在itemprop属性)
章节内容 article; aside; nav; section
标题内容 h1; h2; h3; h4; h5; h6; hgroup
短语内容 a; abbr; audio; b; bdi; bdo; br; button; canvas; cite; code; data; datalist; del; dfn; em; embed; i; iframe; img; input; ins; kbd; label; map; mark; MathML math; meter; noscript; object; output; picture; progress; q; ruby; s; samp; script; select; slot; small; span; strong; sub; sup; SVG svg; template; textarea; time; u; var; video; wbr; 自主定义元素; 文本 area (如果它是map元素的后代); link (如果它允许在body中); meta (如果存在itemprop属性)
嵌入内容 audio; canvas; embed; iframe; img; MathML math; object; picture; SVG svg; video
交互内容 button; details; embed; iframe; label; select; textarea a (如果存在href属性); audio (如果存在controls属性); img (如果存在usemap属性); input (如果type属性处于隐藏状态); video (如果存在controls属性)
表单关联元素 button; fieldset; input; label; object; output; select; textarea; img; 表单关联自定义元素
列举元素 button; fieldset; input; object; output; select; textarea; 表单关联自定义元素
可提交元素 button; input; select; textarea; 表单关联自定义元素
可重置元素 input; output; select; textarea; 表单关联自定义元素
自动大写和自动更正继承的元素 button; fieldset; input; output; select; textarea
可标记元素 button; input; meter; output; progress; select; textarea; 表单关联自定义元素
可感知内容 a; abbr; address; article; aside; b; bdi; bdo; blockquote; button; canvas; cite; code; data; del; details; dfn; div; em; embed; fieldset; figure; footer; form; h1; h2; h3; h4; h5; h6; header; hgroup; i; iframe; img; ins; kbd; label; main; map; mark; MathML math; meter; nav; object; output; p; picture; pre; progress; q; ruby; s; samp; search; section; select; small; span; strong; sub; sup; SVG svg; table; textarea; time; u; var; video; 自主定义元素 audio (如果存在 controls 属性); dl (如果元素的子元素包含至少一个名称-值对); input (如果 type 属性不是 隐藏 状态); menu (如果元素的子元素包含至少一个 li 元素); ol (如果元素的子元素包含至少一个 li 元素); ul (如果元素的子元素包含至少一个 li 元素); 文本 不是 元素间空白
Script-supporting elements script; template

属性

本节为非规范性内容。

属性列表(不包括事件处理程序内容属性)
属性 元素 描述
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 HTML 元素 元素是否相关 "until-found"; "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 (videoaudio); 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"; 空字符串

单元格中的星号(*)表示实际规则比上表中所示的更为复杂。


HTMLElement/drag_event

所有当前引擎中均支持。

Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

HTMLElement/dragend_event

所有当前引擎中均支持。

Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

HTMLElement/dragenter_event

所有当前引擎中均支持。

Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

HTMLElement/dragleave_event

所有当前引擎中均支持。

Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

HTMLElement/dragover_event

所有当前引擎中均支持。

Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

HTMLElement/dragstart_event

所有当前引擎中均支持。

Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+

HTMLElement/drop_event

所有当前引擎中均支持。

Firefox9+Safari3.1+Chrome1+
Opera12+Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12+
事件处理程序内容属性列表
属性 元素 描述
onafterprint body afterprint Window 对象的事件处理程序 事件处理程序内容属性
onauxclick HTML 元素 auxclick 事件处理程序 事件处理程序内容属性
onbeforeinput HTML 元素 beforeinput 事件处理程序 事件处理程序内容属性
onbeforematch HTML 元素 beforematch 事件处理程序 事件处理程序内容属性
onbeforeprint body beforeprint Window 对象的事件处理程序 事件处理程序内容属性
onbeforeunload body beforeunload Window 对象的事件处理程序 事件处理程序内容属性
onbeforetoggle HTML 元素 beforetoggle 事件处理程序 事件处理程序内容属性
onblur HTML 元素 blur 事件 处理程序 事件处理程序内容属性
oncancel HTML 元素 cancel 事件处理程序 事件处理程序内容属性
oncanplay HTML 元素 canplay 事件处理程序 事件处理程序内容属性
oncanplaythrough HTML 元素 canplaythrough 事件处理程序 事件处理程序内容属性
onchange HTML 元素 change 事件处理程序 事件处理程序内容属性
onclick HTML 元素 click 事件处理程序 事件处理程序内容属性
onclose HTML 元素 close 事件处理程序 事件处理程序内容属性
oncontextlost HTML 元素 contextlost 事件处理程序 事件处理程序内容属性
oncontextmenu HTML 元素 contextmenu 事件处理程序 事件处理程序内容属性
oncontextrestored HTML 元素 contextrestored 事件处理程序 事件处理程序内容属性
oncopy HTML 元素 copy 事件处理程序 事件处理程序内容属性
oncuechange HTML 元素 cuechange 事件处理程序 事件处理程序内容属性
oncut HTML 元素 cut 事件处理程序 事件处理程序内容属性
ondblclick HTML 元素 dblclick 事件处理程序 事件处理程序内容属性
ondrag HTML 元素 drag 事件处理程序 事件处理程序内容属性
ondragend HTML 元素 dragend 事件处理程序 事件处理程序内容属性
ondragenter HTML 元素 dragenter 事件处理程序 事件处理程序内容属性
ondragleave HTML 元素 dragleave 事件处理程序 事件处理程序内容属性
ondragover HTML 元素 dragover 事件处理程序 事件处理程序内容属性
ondragstart HTML 元素 dragstart 事件处理程序 事件处理程序内容属性
ondrop HTML 元素 drop 事件处理程序 事件处理程序内容属性
ondurationchange HTML 元素 durationchange 事件处理程序 事件处理程序内容属性
onemptied HTML 元素 emptied 事件处理程序 事件处理程序内容属性
onended HTML 元素 ended 事件处理程序 事件处理程序内容属性
onerror HTML 元素 error 事件处理程序 事件处理程序内容属性
onfocus HTML 元素 focus 事件处理程序 事件处理程序内容属性
onformdata HTML 元素 formdata 事件处理程序 事件处理程序内容属性
onhashchange body hashchange Window 对象的事件处理程序 事件处理程序内容属性
oninput HTML 元素 input 事件处理程序 事件处理程序内容属性
oninvalid HTML 元素 invalid 事件处理程序 事件处理程序内容属性
onkeydown HTML 元素 keydown 事件处理程序 事件处理程序内容属性
onkeypress HTML 元素 keypress 事件处理程序 事件处理程序内容属性
onkeyup HTML 元素 keyup 事件处理程序 事件处理程序内容属性
onlanguagechange body languagechange Window 对象的事件处理程序 事件处理程序内容属性
onload HTML 元素 load 事件处理程序 事件处理程序内容属性
onloadeddata HTML 元素 loadeddata 事件处理程序 事件处理程序内容属性
onloadedmetadata HTML 元素 loadedmetadata 事件处理程序 事件处理程序内容属性
onloadstart HTML 元素 loadstart 事件处理程序 事件处理程序内容属性
onmessage body message Window 对象的事件处理程序 事件处理程序内容属性
onmessageerror body messageerror Window 对象的事件处理程序 事件处理程序内容属性
onmousedown HTML 元素 mousedown 事件处理程序 事件处理程序内容属性
onmouseenter HTML 元素 mouseenter 事件处理程序 事件处理程序内容属性
onmouseleave HTML 元素 mouseleave 事件处理程序 事件处理程序内容属性
onmousemove HTML 元素 mousemove 事件处理程序 事件处理程序内容属性
onmouseout HTML 元素 mouseout 事件处理程序 事件处理程序内容属性
onmouseover HTML 元素 mouseover 事件处理程序 事件处理程序内容属性
onmouseup HTML 元素 mouseup 事件处理程序 事件处理程序内容属性
onoffline body offline Window 对象的事件处理程序 事件处理程序内容属性
ononline body online Window 对象的事件处理程序 事件处理程序内容属性
onpagehide body pagehide Window 对象的事件处理程序 事件处理程序内容属性
onpagereveal body pagereveal Window 对象的事件处理程序 事件处理程序内容属性
onpageshow body pageshow Window 对象的事件处理程序 事件处理程序内容属性
onpageswap body pageswap Window 对象的事件处理程序 事件处理程序内容属性
onpaste HTML 元素 paste 事件处理程序 事件处理程序内容属性
onpause HTML 元素 pause 事件处理程序 事件处理程序内容属性
onplay HTML 元素 play 事件处理程序 事件处理程序内容属性
onplaying HTML 元素 playing 事件处理程序 事件处理程序内容属性
onpopstate body popstate Window 对象的事件处理程序 事件处理程序内容属性
onprogress HTML 元素 progress 事件处理程序 事件处理程序内容属性
onratechange HTML 元素 ratechange 事件处理程序 事件处理程序内容属性
onreset HTML 元素 reset 事件处理程序 事件处理程序内容属性
onresize HTML 元素 resize 事件处理程序 事件处理程序内容属性
onrejectionhandled body rejectionhandled Window 对象的事件处理程序 事件处理程序内容属性
onscroll HTML 元素 scroll 事件处理程序 事件处理程序内容属性
onscrollend HTML 元素 scrollend 事件处理程序 事件处理程序内容属性
onsecuritypolicyviolation HTML 元素 securitypolicyviolation 事件处理程序 事件处理程序内容属性
onseeked HTML 元素 seeked 事件处理程序 事件处理程序内容属性
onseeking HTML 元素 seeking 事件处理程序 事件处理程序内容属性
onselect HTML 元素 select 事件处理程序 事件处理程序内容属性
onslotchange HTML 元素 slotchange 事件处理程序 事件处理程序内容属性
onstalled HTML 元素 stalled 事件处理程序 事件处理程序内容属性
onstorage body storage Window 对象的事件处理程序 事件处理程序内容属性
onsubmit HTML 元素 submit 事件处理程序 事件处理程序内容属性
onsuspend HTML 元素 suspend 事件处理程序 事件处理程序内容属性
ontimeupdate HTML 元素 timeupdate 事件处理程序 事件处理程序内容属性
ontoggle HTML 元素 toggle 事件处理程序 事件处理程序内容属性
onunhandledrejection body unhandledrejection Window 对象的事件处理程序 事件处理程序内容属性
onunload body unload Window 对象的事件处理程序 事件处理程序内容属性
onvolumechange HTML 元素 volumechange 事件处理程序 事件处理程序内容属性
onwaiting HTML 元素 waiting 事件处理程序 事件处理程序内容属性
onwheel HTML 元素 wheel 事件处理程序 事件处理程序内容属性

元素接口

本节为非规范性内容。

元素接口列表
元素 接口
a HTMLAnchorElement : HTMLElement
abbr HTMLElement
address HTMLElement
area HTMLAreaElement : HTMLElement
article HTMLElement
aside HTMLElement
audio HTMLAudioElement : HTMLMediaElement : HTMLElement
b HTMLElement
base HTMLBaseElement : HTMLElement
bdi HTMLElement
bdo HTMLElement
blockquote HTMLQuoteElement : HTMLElement
body HTMLBodyElement : HTMLElement
br HTMLBRElement : HTMLElement
button HTMLButtonElement : HTMLElement
canvas HTMLCanvasElement : HTMLElement
caption HTMLTableCaptionElement : HTMLElement
cite HTMLElement
code HTMLElement
col HTMLTableColElement : HTMLElement
colgroup HTMLTableColElement : HTMLElement
data HTMLDataElement : HTMLElement
datalist HTMLDataListElement : HTMLElement
dd HTMLElement
del HTMLModElement : HTMLElement
details HTMLDetailsElement : HTMLElement
dfn HTMLElement
dialog HTMLDialogElement : HTMLElement
div HTMLDivElement : HTMLElement
dl HTMLDListElement : HTMLElement
dt HTMLElement
em HTMLElement
embed HTMLEmbedElement : HTMLElement
fieldset HTMLFieldSetElement : HTMLElement
figcaption HTMLElement
figure HTMLElement
footer HTMLElement
form HTMLFormElement : HTMLElement
h1 HTMLHeadingElement : HTMLElement
h2 HTMLHeadingElement : HTMLElement
h3 HTMLHeadingElement : HTMLElement
h4 HTMLHeadingElement : HTMLElement
h5 HTMLHeadingElement : HTMLElement
h6 HTMLHeadingElement : HTMLElement
head HTMLHeadElement : HTMLElement
header HTMLElement
hgroup HTMLElement
hr HTMLHRElement : HTMLElement
html HTMLHtmlElement : HTMLElement
i HTMLElement
iframe HTMLIFrameElement : HTMLElement
img HTMLImageElement : HTMLElement
input HTMLInputElement : HTMLElement
ins HTMLModElement : HTMLElement
kbd HTMLElement
label HTMLLabelElement : HTMLElement
legend HTMLLegendElement : HTMLElement
li HTMLLIElement : HTMLElement
link HTMLLinkElement : HTMLElement
main HTMLElement
map HTMLMapElement : HTMLElement
mark HTMLElement
menu HTMLMenuElement : HTMLElement
meta HTMLMetaElement : HTMLElement
meter HTMLMeterElement : HTMLElement
nav HTMLElement
noscript HTMLElement
object HTMLObjectElement : HTMLElement
ol HTMLOListElement : HTMLElement
optgroup HTMLOptGroupElement : HTMLElement
option HTMLOptionElement : HTMLElement
output HTMLOutputElement : HTMLElement
p HTMLParagraphElement : HTMLElement
picture HTMLPictureElement : HTMLElement
pre HTMLPreElement : HTMLElement
progress HTMLProgressElement : HTMLElement
q HTMLQuoteElement : HTMLElement
rp HTMLElement
rt HTMLElement
ruby HTMLElement
s HTMLElement
samp HTMLElement
search HTMLElement
script HTMLScriptElement : HTMLElement
section HTMLElement
select HTMLSelectElement : HTMLElement
slot HTMLSlotElement : HTMLElement
small HTMLElement
source HTMLSourceElement : HTMLElement
span HTMLSpanElement : HTMLElement
strong HTMLElement
style HTMLStyleElement : HTMLElement
sub HTMLElement
summary HTMLElement
sup HTMLElement
table HTMLTableElement : HTMLElement
tbody HTMLTableSectionElement : HTMLElement
td HTMLTableCellElement : HTMLElement
template HTMLTemplateElement : HTMLElement
textarea HTMLTextAreaElement : HTMLElement
tfoot HTMLTableSectionElement : HTMLElement
th HTMLTableCellElement : HTMLElement
thead HTMLTableSectionElement : HTMLElement
time HTMLTimeElement : HTMLElement
title HTMLTitleElement : HTMLElement
tr HTMLTableRowElement : HTMLElement
track HTMLTrackElement : HTMLElement
u HTMLElement
ul HTMLUListElement : HTMLElement
var HTMLElement
video HTMLVideoElement : HTMLMediaElement : HTMLElement
wbr HTMLElement
自定义元素 由元素的作者提供(继承自 HTMLElement

所有接口

本节为非规范性内容。

事件

本节为非规范性内容。

下表列出了此文档触发的事件,不包括已经在 媒体元素事件拖放事件 中定义的事件。

事件列表
事件 接口 相关目标 描述
DOMContentLoaded

Window/DOMContentLoaded_event

所有当前引擎均支持。

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

Window/afterprint_event

所有当前引擎均支持。

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

Window/beforeprint_event

所有当前引擎均支持。

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

Element/beforematch_event

仅在一个引擎中支持。

FirefoxSafariChrome102+
OperaEdge102+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
Event 元素 在带有 hidden=until-found 属性的元素被显示前触发。
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

Window/beforeunload_event

所有当前引擎均支持。

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 AndroidWebView Android?Samsung Internet?Opera Android?
Event CloseWatcher, 对话框 元素, 输入 元素 CloseWatcher 对象或 对话框 元素上接收到 关闭请求 时触发,或当用户未更改选择时,在文件上传状态(type=file)的 输入 元素上触发
change

HTMLElement/change_event

所有当前引擎均支持。

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

HTMLDialogElement/close_event

所有当前引擎均支持。

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

仅支持一个引擎。

FirefoxSafariChrome98+
Opera?Edge98+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
Event canvas 元素, OffscreenCanvas 对象 在对应的 CanvasRenderingContext2DOffscreenCanvasRenderingContext2D 丢失时触发
contextrestored

HTMLCanvasElement/contextrestored_event

仅支持一个引擎。

FirefoxSafariChrome98+
Opera?Edge98+
Edge (旧版)?Internet Explorer
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
Event canvas 元素, OffscreenCanvas 对象 在对应的 CanvasRenderingContext2DOffscreenCanvasRenderingContext2D 在丢失后恢复时触发
currententrychange NavigationCurrentEntryChangeEvent Navigation navigation.currentEntry 更改时触发
dispose Event NavigationHistoryEntry 当对应于 NavigationHistoryEntry会话历史条目 被永久驱逐出会话历史且无法再导航到时触发
error

EventSource/error_event

支持所有当前引擎。

Firefox6+Safari5+Chrome6+
Opera12+Edge79+
Edge (旧版)?Internet Explorer
Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+

Window/error_event

支持所有当前引擎。

Firefox6+Safari5.1+Chrome10+
Opera?Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android?
EventErrorEvent 全局范围对象, 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

Window/hashchange_event

支持所有当前引擎。

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

Window/languagechange_event

支持所有当前引擎。

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 上触发;在包含资源的元素上触发(例如 imgembed) 当其资源加载完成时
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+

EventSource/message_event

支持所有当前引擎。

Firefox6+Safari5+Chrome6+
Opera12+Edge79+
Edge (旧版)?Internet Explorer
Firefox Android45+Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android12+

MessagePort/message_event

支持所有当前引擎。

Firefox41+Safari5+Chrome2+
Opera10.6+Edge79+
Edge (旧版)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android11.5+

Window/message_event

支持所有当前引擎。

Firefox9+Safari4+Chrome60+
Opera?Edge79+
Edge (旧版)12+Internet Explorer8+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+

Worker/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+
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+

Window/messageerror_event

在所有当前引擎中均受支持。

Firefox57+Safari16.4+Chrome60+
Opera?Edge79+
Edge (旧版)18Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android47+

Worker/messageerror_event

在所有当前引擎中均受支持。

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

Window/offline_event

在所有当前引擎中均受支持。

Firefox9+Safari4+Chrome3+
Opera?Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android?
Event 全局范围对象 当网络连接失败时在全局范围对象中触发
online

Window/online_event

在所有当前引擎中均受支持。

Firefox9+Safari4+Chrome3+
Opera?Edge79+
Edge (旧版)12+Internet Explorer9+
Firefox Android?Safari iOS3+Chrome Android?WebView Android37+Samsung Internet?Opera Android?
Event 全局范围对象 当网络连接恢复时在全局范围对象中触发
open

EventSource/open_event

在所有当前引擎中均受支持。

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

Window/pagehide_event

在所有当前引擎中均受支持。

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

Window/pageshow_event

在所有当前引擎中均受支持。

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

Window/popstate_event

在所有当前引擎中均受支持。

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

HTMLFormElement/reset_event

在所有当前引擎中均受支持。

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

HTMLInputElement/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+

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

Window/storage_event

在所有当前引擎中均受支持。

Firefox45+Safari4+Chrome1+
Opera?Edge79+
Edge (旧版)15+Internet Explorer9+
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android?
StorageEvent Window 当相应的 localStoragesessionStorage 存储区域发生变化时在 Window 事件中触发
submit

HTMLFormElement/submit_event

在所有当前引擎中均受支持。

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?

HTMLElement/toggle_event

在所有当前引擎中均受支持。

🔰 114+Safari预览版+Chrome114+
Opera?Edge114+
Edge (旧版)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?
ToggleEvent detailspopover 元素 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

Window/unload_event

在所有当前引擎中均受支持。

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 头部

本节为非规范性内容。

本规范定义了以下 HTTP 请求头部:

本规范定义了以下 HTTP 响应头部:

MIME 类型

本节为非规范性内容。

本规范中提到了以下 MIME 类型:

application/atom+xml
Atom [ATOM]
application/json
JSON [JSON]
application/octet-stream
通用二进制数据 [RFC2046]
application/microdata+json
作为 JSON 的微数据
application/rss+xml
RSS
application/x-www-form-urlencoded
表单提交
application/xhtml+xml
HTML
application/xml
XML [XML] [RFC7303]
image/gif
GIF 图片 [GIF]
image/jpeg
JPEG 图片 [JPEG]
image/png
PNG 图片 [PNG]
image/svg+xml
SVG 图片 [SVG]
multipart/form-data
表单提交 [RFC7578]
multipart/mixed
通用混合内容 [RFC2046]
multipart/x-mixed-replace
流式服务器推送
text/css
CSS [CSS]
text/event-stream
服务器发送事件流
text/javascript
JavaScript [JAVASCRIPT] [RFC9239]
text/json
JSON(遗留类型)
text/plain
通用纯文本 [RFC2046] [RFC3676]
text/html
HTML
text/ping
超链接审计
text/uri-list
URL 列表 [RFC2483]
text/vcard
vCard [RFC6350]
text/vtt
WebVTT [WEBVTT]
text/xml
XML [XML] [RFC7303]
video/mp4
MPEG-4 视频 [RFC4337]
video/mpeg
MPEG 视频 [RFC2046]

参考文献

所有参考文献均为规范性引用,除非标注为“非规范性”。

[ABNF]
语法规范增强版 BNF: ABNF, D. Crocker, P. Overell. IETF.
[ABOUT]
“about” URI 方案, S. Moonesamy. IETF.
[APNG]
(非规范性) APNG 规范. S. Parmenter, V. Vukicevic, A. Smith. Mozilla.
[ARIA]
无障碍富互联网应用 (WAI-ARIA), J. Diggs, J. Nurthen, M. Cooper. W3C.
[ARIAHTML]
HTML 中的 ARIA, S. Faulkner, S. O'Hara. W3C.
[ATAG]
(非规范性) 创作工具无障碍指南 (ATAG) 2.0, J. Richards, J. Spellman, J. Treviranus. W3C.
[ATOM]
(非规范性) Atom 订阅格式, M. Nottingham, R. Sayre. IETF.
[BATTERY]
(非规范性) 电池状态 API, A. Kostiainen, M. Lamouri. W3C.
[BCP47]
用于标识语言的标签; 语言标签的匹配, A. Phillips, M. Davis. IETF.
[BEZIER]
Courbes à poles, P. de Casteljau. INPI, 1959.
[BIDI]
UAX #9: Unicode 双向算法, M. Davis. Unicode Consortium.
[BOCU1]
(非规范性) UTN #6: BOCU-1: 兼容 MIME 的 Unicode 压缩方案, M. Scherer, M. Davis. Unicode Consortium.
[CESU8]
(非规范性) UTR #26: UTF-16 兼容编码方案: 8-BIT (CESU-8), T. Phipps. Unicode Consortium.
[CHARMOD]
(非规范性) 万维网字符模型 1.0: 基础, M. Dürst, F. Yergeau, R. Ishida, M. Wolf, T. Texin. W3C.
[CHARMODNORM]
(非规范性) 万维网字符模型: 字符串匹配, A. Phillips. W3C.
[CLIPBOARD-APIS]
剪贴板 API 和事件, G. Kacmarcik, A. Snigdha. W3C.
[COMPOSITE]
合成与混合, R. Cabanier, N. Andronikos. W3C.
[COMPUTABLE]
(非规范性) 可计算数的研究,及其对判定问题的应用, A. Turing. 见 伦敦数学会学报, 第二系列, 第 42 卷, 页 230-265. 伦敦数学会, 1937.
[COMPUTEPRESSURE]
(非规范性) 计算压力, K. Christiansen, A. Mandy. W3C.
[CONSOLE]
控制台, T. Stock, R. Kowalski, D. Farolino. WHATWG.
[COOKIES]
HTTP 状态管理机制, A. Barth. IETF.
[CREDMAN]
凭证管理, N. Satragno, J. Hodges, M. West. W3C.
[CSP]
内容安全策略, M. West, D. Veditz. W3C.
[CSS]
层叠样式表 (CSS) 2 级 (修订版), B. Bos, T. Çelik, I. Hickson, H. Lie. W3C.
[CSSALIGN]
CSS 盒子对齐, E. Etemad, T. Atkins. W3C.
[CSSANIMATIONS]
CSS 动画, D. Jackson, D. Hyatt, C. Marrin, S. Galineau, L. Baron. W3C.
[CSSATTR]
CSS 样式属性, T. Çelik, E. Etemad. W3C.
[CSSBG]
CSS 背景和边框, B. Bos, E. Etemad, B. Kemper. W3C.
[CSSBOX]
CSS 盒模型, E. Etemad. W3C.
[CSSCASCADE]
CSS 层叠与继承, E. Etemad, T. Atkins. W3C.
[CSSCONTAIN]
CSS 包含, T. Atkins, F. Rivoal, V. Levin. W3C.
[CSSCOLOR]
CSS 颜色模块, T. Çelik, C. Lilley, L. Baron. W3C.
[CSSCOLORADJUST]
CSS 颜色调整 模块, E. Etemad, R. Atanassov, R. Lillesveen, T. Atkins. W3C.
[CSSDEVICEADAPT]
CSS 设备适配, F. Rivoal, M. Rakow. W3C.
[CSSDISPLAY]
CSS 显示, T. Atkins, E. Etemad. W3C.
[CSSFONTLOAD]
CSS 字体加载, T. Atkins, J. Daggett. W3C.
[CSSFONTS]
CSS 字体, J. Daggett. W3C.
[CSSFLEXBOX]
CSS 弹性盒布局, T. Atkins, E. Etemad, R. Atanassov. W3C.
[CSSGC]
CSS 生成内容, H. Lie, E. Etemad, I. Hickson. W3C.
[CSSGRID]
CSS 网格布局, T. Atkins, E. Etemad, R. Atanassov. W3C.
[CSSIMAGES]
CSS 图像模块, E. Etemad, T. Atkins, L. Verou. W3C.
[CSSIMAGES4]
CSS 图像模块第 4 级, E. Etemad, T. Atkins, L. Verou. W3C.
[CSSINLINE]
CSS 内联布局, D. Cramer, E. Etemad. W3C.
[CSSLISTS]
CSS 列表和计数器, T. Atkins. W3C.
[CSSLOGICAL]
CSS 逻辑属性, R. Atanassov, E. Etemad. W3C.
[CSSMULTICOL]
CSS 多列布局, H. Lie, F. Rivoal, R. Andrew. W3C.
[CSSOM]
层叠样式表对象模型 (CSSOM), S. Pieters, G. Adams. W3C.
[CSSOMVIEW]
CSSOM 视图模块, S. Pieters, G. Adams. W3C.
[CSSOVERFLOW]
CSS 溢出模块, L. Baron, F. Rivoal. W3C.
[CSSPAINT]
(非规范性) CSS 绘制 API, I. Kilpatrick, D. Jackson. W3C.
[CSSPOSITION]
CSS 定位布局, R. Atanassov, A. Eicholz. W3C.
[CSSPSEUDO]
CSS 伪元素, D. Glazman, E. Etemad, A. Stearns. W3C.
[CSSRUBY]
CSS3 Ruby 模块, R. Ishida. W3C.
[CSSSCOPING]
CSS 作用域模块, T. Atkins. W3C.
[CSSSIZING]
CSS 盒子大小调整模块, T. Atkins, E. Etemad. W3C.
[CSSSCROLLANCHORING]
(非规范性) CSS 滚动锚定, T. Atkins-Bittner. W3C.
[CSSSYNTAX]
CSS 语法, T. Atkins, S. Sapin. W3C.
[CSSTRANSITIONS]
(非规范性) CSS 过渡, L. Baron, D. Jackson, B. Birtles. W3C.
[CSSTABLE]
CSS 表格, F. Remy, G. Whitworth. W3C.
[CSSTEXT]
CSS 文本, E. Etemad, K. Ishii. W3C.
[CSSVALUES]
CSS3 值与单位, H. Lie, T. Atkins, E. Etemad. W3C.
[CSSVIEWTRANSITIONS]
CSS 视图过渡, T. Atkins Jr.; J. Archibald; K Sagar. W3C.
[CSSUI]
CSS3 基本用户界面模块, F. Rivoal. W3C.
[CSSWM]
CSS 书写模式, E. Etemad, K. Ishii. W3C.
[DASH]
HTTP 动态自适应流 (DASH). ISO.
[DEVICEPOSTURE]
(非规范性) 设备姿态 API, D. Gonzalez-Zuniga, K. Christiansen. W3C.
[DOM]
文档对象模型 (DOM), A. van Kesteren, A. Gregor, Ms2ger. WHATWG.
[DOMPARSING]
DOM 解析与序列化, T. Leithead. W3C.
[DOT]
(非规范性) DOT 语言. Graphviz.
[E163]
建议 E.163 — 国际电话服务编号计划, CCITT 蓝皮书, Fascicle II.2, pp. 128-134, 1988年11月.
[ENCODING]
编码, A. van Kesteren, J. Bell. WHATWG.
[EXECCOMMAND]
execCommand, J. Wilm, A. Gregor. W3C 编辑 API CG.
[EXIF]
(非规范性) 可交换图像文件格式 (EXIF). JEITA.
[FETCH]
获取, A. van Kesteren. WHATWG.
[FILEAPI]
文件 API, A. Ranganathan. W3C.
[FILTERS]
滤镜效果, D. Schulze, D. Jackson, C. Harrelson. W3C.
[FULLSCREEN]
全屏, A. van Kesteren, T. Çelik. WHATWG.
[GEOMETRY]
几何接口. S. Pieters, D. Schulze, R. Cabanier. W3C.
[GIF]
(非规范性) 图形交换格式 (GIF). CompuServe.
[GRAPHICS]
(非规范性) 计算机图形学:C语言原理与实践, 第二版, J. Foley, A. van Dam, S. Feiner, J. Hughes. Addison-Wesley. ISBN 0-201-84840-6.
[GREGORIAN]
(非规范性) Inter Gravissimas, A. Lilius, C. Clavius. 格里高利十三世教皇诏书, 1582年2月.
[HRT]
高分辨率时间, I. Grigorik, J. Simonsen, J. Mann. W3C.
[HTMLAAM]
HTML 无障碍 API 映射 1.0, S. Faulkner, A. Surkov, S. O'Hara. W3C.
[HTTP]
超文本传输协议 (HTTP/1.1):消息语法和路由, R. Fielding, J. Reschke. IETF.
超文本传输协议 (HTTP/1.1):语义与内容, R. Fielding, J. Reschke. IETF.
超文本传输协议 (HTTP/1.1):条件请求, R. Fielding, J. Reschke. IETF.
超文本传输协议 (HTTP/1.1):范围请求, R. Fielding, Y. Lafon, J. Reschke. IETF.
超文本传输协议 (HTTP/1.1):缓存, R. Fielding, M. Nottingham, J. Reschke. IETF.
超文本传输协议 (HTTP/1.1):认证, R. Fielding, J. Reschke. IETF.
[INDEXEDDB]
索引数据库 API, A. Alabbas, J. Bell. W3C.
[INBAND]
从媒体容器中向 HTML 源输入带内媒体资源 轨道, S. Pfeiffer, B. Lund. W3C.
[INFRA]
基础设施, A. van Kesteren, D. Denicola. WHATWG.
[INTERSECTIONOBSERVER]
交叉观察器, S. Zager. W3C.
[RESIZEOBSERVER]
调整观察器, O. Brufau, E. Álvarez. W3C.
[ISO3166]
ISO 3166: 国家名称及其分支机构的代码. ISO.
[ISO4217]
ISO 4217: 货币和资金表示代码. ISO.
[ISO8601]
(非规范性) ISO8601: 数据元素和交换格式——信息交换——日期和时间的表示. ISO.
[JAVASCRIPT]
ECMAScript 语言规范. Ecma International.
[JLREQ]
日文文本布局要求. W3C.
[JPEG]
JPEG 文件交换格式, E. Hamilton.
[JSERRORSTACKS]
(非规范性) 错误堆栈. Ecma International.
[JSDYNAMICCODEBRANDCHECKS]
动态代码品牌检查. Ecma International.
[JSIMPORTATTRIBUTES]
导入属性. Ecma International.
[JSJSONMODULES]
JSON 模块. Ecma International.
[JSRESIZABLEBUFFERS]
可调整大小的 ArrayBuffer 和可增长的 SharedArrayBuffer. Ecma International.
[JSINTL]
ECMAScript 国际化 API 规范. Ecma International.
[JSON]
JavaScript 对象表示法 (JSON) 数据交换 格式, T. Bray. IETF.
[JSTEMPORAL]
时间模块. Ecma International.
[LONGTASKS]
长任务, D. Denicola, I. Grigorik, S. Panicker. W3C.
[LONGANIMATIONFRAMES]
长动画帧, N. Rosenthal. W3C.
[MAILTO]
(非规范性) “mailto” URI 方案, M. Duerst, L. Masinter, J. Zawinski. IETF.
[MANIFEST]
Web 应用程序清单, M. Caceres, K. Rohde Christiansen, M. Lamouri, A. Kostiainen, M. Giuca, A. Gustafson. W3C.
[MATHMLCORE]
数学标记语言 (MathML), D. Carlisle, Frédéric Wang. W3C.
[MEDIAFRAG]
媒体片段 URI, R. Troncy, E. Mannens, S. Pfeiffer, D. Van Deursen. W3C.
[MEDIASOURCE]
媒体源扩展, A. Colwell, A. Bateman, M. Watson. W3C.
[MEDIASTREAM]
媒体采集与流 Streams, D. Burnett, A. Bergkvist, C. Jennings, A. Narayanan. W3C.
[REPORTING]
报告, D. Creager, I. Clelland, M. West. W3C.
[MFREL]
Microformats Wiki: 现有的 rel 值. Microformats.
[MIMESNIFF]
MIME 嗅探, G. Hemsley. WHATWG.
[MIX]
混合内容, M. West. W3C.
[MNG]
MNG (多图像网络图形) 格式. G. Randers-Pehrson.
[MPEG2]
ISO/IEC 13818-1: 信息技术 — 移动图像及相关音频信息的通用编码: 系统. ISO/IEC.
[MPEG4]
ISO/IEC 14496-12: ISO 基础媒体文件格式. ISO/IEC.
[MQ]
媒体查询, H. Lie, T. Çelik, D. Glazman, A. van Kesteren. W3C.
[MULTIPLEBUFFERING]
(非规范性) 多重 缓冲. Wikipedia.
[NAVIGATIONTIMING]
导航计时, Y. Weiss. W3C.
[NPAPI]
(非规范性) Gecko 插件 API 参考. Mozilla.
[OGGSKELETONHEADERS]
SkeletonHeaders. Xiph.Org.
[OPENSEARCH]
HTML/XHTML 中的自动发现. 在 OpenSearch 1.1 Draft 6 中. GitHub.
[ORIGIN]
(非规范性) Web 源概念, A. Barth. IETF.
[PAINTTIMING]
绘制时序, S. Panicker. W3C.
[PAYMENTREQUEST]
支付请求 API, M. Cáceres, D. Wang, R. Solomakhin, I. Jacobs. W3C.
[PDF]
(非规范性) 文档管理 — 便携式文档格式 — 第 1 部分: PDF. ISO.
[PERFORMANCETIMELINE]
性能时间轴, N. Peña Moreno, W3C.
[PERMISSIONSPOLICY]
权限策略, I. Clelland, W3C.
[PICTUREINPICTURE]
(非规范性) 画中画, F. Beaufort, M. Lamouri, W3C
[PINGBACK]
Pingback 1.0, S. Langridge, I. Hickson.
[PNG]
便携式网络图形 (PNG) 规范, D. Duce. W3C.
[POINTEREVENTS]
指针事件, J. Rossi, M. Brubeck, R. Byers, P. H. Lauke. W3C.
[POINTERLOCK]
指针锁定, V. Scheib. W3C.
[PPUTF8]
(非规范性) UTF-8 的特性与承诺, M. Dürst. 苏黎世大学. 在 第 11 届国际 Unicode 会议的论文集 中.
[PRESENTATION]
演示 API, M. Foltz, D. Röttsches. W3C.
[REFERRERPOLICY]
引用策略, J. Eisinger, E. Stark. W3C.
[REQUESTIDLECALLBACK]
后台任务的协作调度, R. McIlroy, I. Grigorik. W3C.
[RESOURCETIMING]
资源时序, Yoav Weiss; Noam Rosenthal. W3C.
[RFC1034]
域名 - 概念与设施, P. Mockapetris. IETF, 1987 年 11 月.
[RFC1123]
互联网主机的要求——应用与支持, R. Braden. IETF, 1989 年 10 月.
[RFC2046]
多用途互联网邮件扩展 (MIME) 第二部分:媒体类型, N. Freed, N. Borenstein. IETF.
[RFC2397]
“data” URL 方案, L. Masinter. IETF.
[RFC5545]
互联网日历与调度核心对象规范 (iCalendar), B. Desruisseaux. IETF.
[RFC2483]
URN 解析所需的 URI 解析服务, M. Mealling, R. Daniel. IETF.
[RFC3676]
Text/Plain 格式与 DelSp 参数, R. Gellens. IETF.
[RFC9239]
对 ECMAScript 媒体类型的更新, M. Miller, M. Borins, M. Bynens, B. Farias. IETF.
[RFC4337]
(非规范性) MPEG-4 的 MIME 类型注册, Y. Lim, D. Singer. IETF.
[RFC7595]
URI 方案的指南与注册程序, D. Thaler, T. Hansen, T. Hardie. IETF.
[RFC5322]
互联网消息格式, P. Resnick. IETF.
[RFC6381]
"Bucket" 媒体类型的 “编解码器”和“配置文件” 参数, R. Gellens, D. Singer, P. Frojdh. IETF.
[RFC6266]
在超文本传输协议 (HTTP) 中使用 Content-Disposition 头字段, J. Reschke. IETF.
[RFC6350]
vCard 格式规范, S. Perreault. IETF.
[RFC6596]
规范链接关系, M. Ohye, J. Kupke. IETF.
[RFC6903]
其他链接关系类型, J. Snell. IETF.
[RFC7034]
(非规范性) HTTP 头字段 X-Frame-Options, D. Ross, T. Gondrom. IETF.
[RFC7303]
XML 媒体类型, H. Thompson, C. Lilley. IETF.
[RFC7578]
从表单返回值: multipart/form-data, L. Masinter. IETF.
[RFC8297]
用于指示提示的 HTTP 状态码, K. Oku. IETF.
[SCREENORIENTATION]
屏幕方向, M. Cáceres. W3C.
[SCSU]
(非规范性) UTR #6: Unicode 的标准压缩方案, M. Wolf, K. Whistler, C. Wicksteed, M. Davis, A. Freytag, M. Scherer. Unicode Consortium.
[SECURE-CONTEXTS]
安全上下文, M. West. W3C.
[SELECTION]
选择 API, R. Niwa. W3C.
[SELECTORS]
选择器, E. Etemad, T. Çelik, D. Glazman, I. Hickson, P. Linss, J. Williams. W3C.
[SMS]
(非规范性) 全球移动通信系统 (GSM) 短消息服务 (SMS) 的 URI 方案, E. Wilde, A. Vaha-Sipila. IETF.
[STRUCTURED-FIELDS]
HTTP 的结构化字段值, M. Nottingham, P-H. Kamp. IETF.
[SRI]
子资源完整性, D. Akhawe, F. Braun, F. Marier, J. Weinberger. W3C.
[STORAGE]
存储, A. van Kesteren. WHATWG.
[SVG]
可缩放矢量图形 (SVG) 2, N Andronikos, R. Atanassov, T. Bah, B. Birtles, B. Brinza, C. Concolato, E. Dahlström, C. Lilley, C. McCormack, D. Schepers, R. Schwerdtfeger, D. Storey, S. Takagi, J. Watt. W3C.
[SW]
服务worker, A. Russell, J. Song, J. Archibald. W3C.
[TOR]
(非规范性) Tor.
[TOUCH]
触摸事件, D. Schepers, S. Moon, M. Brubeck, A. Barstow, R. Byers. W3C.
[TRUSTED-TYPES]
受信类型, K. Kotowicz, M. West. W3C.
[TZDATABASE]
(非规范性) 时区数据库. IANA.
[UAAG]
(非规范性) 用户代理可访问性指南 (UAAG) 2.0, J. Allan, K. Ford, J. Richards, J. Spellman. W3C.
[UIEVENTS]
用户界面事件规范, G. Kacmarcik, T. Leithead. W3C.
[UNICODE]
Unicode 标准. Unicode Consortium.
[UNIVCHARDET]
(非规范性) 语言/编码检测的综合方法, S. Li, K. Momoi. Netscape. 在 第 19 届国际 Unicode 会议的论文集 中.
[URL]
统一资源定位符 (URL), A. van Kesteren. WHATWG.
[URN]
URN 语法, R. Moats. IETF.
[UTF7]
(非规范性) UTF-7: 一种邮件安全的 Unicode 转换格式, D. Goldsmith, M. Davis. IETF.
[UTF8DET]
(非规范性) 多语言表单编码, M. Dürst. W3C.
[UTR36]
(非规范性) UTR #36: Unicode 安全考虑, M. Davis, M. Suignard. Unicode Consortium.
[WASM]
WebAssembly Core Specification, A. Rossberg. W3C.
[WASMESM]
WebAssembly JavaScript Interface: ESM Integration, L. Clark, D. Ehrenberg., A. Takikawa., G. Bedford. W3C.
[WASMJS]
(非规范性) WebAssembly JavaScript 接口, D. Ehrenberg. W3C.
[WCAG]
(非规范性) Web 内容可访问性指南 (WCAG), A. Kirkpatrick, J. O Connor, A. Campbell, M. Cooper. W3C.
[WEBANIMATIONS]
Web 动画, B. Birtles, S. Stephens, D. Stockwell. W3C.
[WEBAUDIO]
(非规范性) Web 音频 API, P. Adenot, H. Choi. W3C.
[WEBAUTHN]
Web 身份验证:访问公钥凭证的 API, M. Jones, A. Kumar, E. Lundberg, D. Balfanz, V. Bharadwaj, A. Birgisson, A. Czeskis, J. Hodges, J.C. Jones, H. Le Van Gong, A. Liao, R. Lindemann, J. Bradley, C. Brand, T. Cappalli, A. Langley, G. Mandyam, M. Miller, N. Satragno, N. Steele, J. Tan, S. Weeden, M. West, J. Yasskin. W3C.
[WEBCODECS]
WebCodecs API, C. Cunningham, P. Adenot, B. Aboba. W3C.
[WEBCRYPTO]
Web 加密 API, D. Huigens. W3C.
[WEBDRIVER]
WebDriver, S. Stewart, D. Burns. W3C.
[WEBDRIVERBIDI]
WebDriver BiDi. W3C
[WEBGL]
WebGL 规范, D. Jackson, J. Gilbert. Khronos Group.
[WEBGPU]
WebGPU, D. Malyshau, K. Ninomiya. W3C.
[WEBIDL]
Web IDL, E. Chen, T. Gu. WHATWG.
Web 链接, M. Nottingham. IETF.
[WEBLOCKS]
(非规范性) Web 锁 API, J. Bell, K. Rosylight. W3C.
[WEBMCG]
WebM 容器指南. WebM 项目.
[WEBNFC]
(非规范性) Web NFC, F. Beaufort, K. Christiansen, Z. Kis. W3C.
[WEBRTC]
(非规范性) Web RTC, C. Jennings, F. Castelli, H. Boström, J. Bruaroey. W3C.
[WEBSOCKETS]
WebSockets, A. Rice. WHATWG.
[WEBTRANSPORT]
WebTransport, B. Aboba, N. Jaju, V. Vasiliev. W3C.
[WEBVTT]
WebVTT, S. Pieters. W3C.
[WHATWGWIKI]
WHATWG Wiki. WHATWG.
[X121]
建议 X.121 — 公共数据网络的国际编号计划, CCITT 蓝皮书, 分册 VIII.3, 第 317-332 页.
[XFN]
XFN 1.1 配置文件, T. Çelik, M. Mullenweg, E. Meyer. GMPG.
[XHR]
XMLHttpRequest, A. van Kesteren. WHATWG.
[XKCD1288]
(非规范性) 替换, Randall Munroe. xkcd.
[XML]
可扩展标记语言, T. Bray, J. Paoli, C. Sperberg-McQueen, E. Maler, F. Yergeau. W3C.
[XMLENTITY]
(非规范性) 字符的 XML 实体定义, D. Carlisle, P. Ion. W3C.
[XMLNS]
XML 中的命名空间, T. Bray, D. Hollander, A. Layman, R. Tobin. W3C.
[XMLSSPI]
与 XML 文档关联样式表, J. Clark, S. Pieters, H. Thompson. W3C.
[XPATH10]
XML 路径语言 (XPath) 版本 1.0, J. Clark, S. DeRose. W3C.
[XSLT10]
(非规范性) XSL 转换 (XSLT) 版本 1.0, J. Clark. W3C.
[XSLTP]
(非规范性) DOM XSLT 处理器, WHATWG Wiki. 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(Googleian@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 提供。 (公共领域)

嵌入内容介绍中的壶铃摆动图片基于 一张照片, 由 kokkarina 提供。 (CC0 1.0)

Canvas演示中使用的蓝色机器人玩家精灵基于 一项作品, 由 JohnColburn 提供。 (CC BY-SA 3.0)

2013年硅谷地区FIRST机器人竞赛中148号机器人爬塔的照片基于 一项作品, 由 Lenore Edman 提供。 (CC BY 2.0)

显示 asyncdefer 如何影响 script 加载的图表基于 一篇博客文章, 由 Peter Beverloo 提供。 (CC0 1.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许可证 授权。

这是现行标准。希望查看专利审核版本的人士应查阅 现行标准审核草案