重学前端 35 # HTML标准分析

简介: 重学前端 35 # HTML标准分析

一、介绍


由于阅读标准有一定门槛,需要了解一些机制,这一篇介绍怎么用 JavaScript 代码去抽取标准中我们需要的信息。



二、HTML 标准


2.1、标准是如何描述一个标签的


1、采用 WHATWGliving standard 标准

WHATWG:超文本应用技术工作组;排版引擎比较;网页超文本技术工作小组;网络超文本应用技术工作组;(来自有道的翻译)


Categories:
    Flow content.
    Phrasing content.
    Embedded content.
    If the element has a controls attribute: Interactive content.
    Palpable content.
Contexts in which this element can be used:
    Where embedded content is expected.
Content model:
    If the element has a src attribute: zero or more track elements, then transparent, but with no media element descendants.
    If the element does not have a src attribute: zero or more source elements, then zero or more track elements, then transparent, but with no media element descendants.
Tag omission in text/html:
    Neither tag is omissible.
Content attributes:
    Global attributes
    src — Address of the resource
    crossorigin — How the element handles crossorigin requests
    poster — Poster frame to show prior to video playback
    preload — Hints how much buffering the media resource will likely need
    autoplay — Hint that the media resource can be started automatically when the page is loaded
    playsinline — Encourage the user agent to display video content within the element's playback area
    loop — Whether to loop the media resource
    muted — Whether to mute the media resource by default
    controls — Show user agent controls
    width — Horizontal dimension
    height — Vertical dimension
DOM interface:
    [Exposed=Window, HTMLConstructor]
    interface HTMLVideoElement : HTMLMediaElement {
      [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;
    };


2、上面代码描述分为六个部分

   Categories:标签所属的分类。

   Contexts in which this element can be used:标签能够用在哪里。

   Content model:标签的内容模型。

   Tag omission in text/html:标签是否可以省略。

   Content attributes:内容属性。

   DOM interface:用 WebIDL 定义的元素类型接口。




三、用代码分析 HTML 标准


HTML 标准描述用词非常的严谨,这给我们抓取数据带来了巨大的方便。

3.1、第1步:打开HTML标准网站

打开单页面版 HTML 标准 https://html.spec.whatwg.org/


3.2、第2步:获取元素文本

打开控制台执行下面代码:

Array.prototype.map.call(document.querySelectorAll(".element"), e=>e.innerText);


输出结果是107个元素:

// 大概就是这样子的,我截取了一部分
(107) ["Categories:↵None.↵Contexts in which this element c…: HTMLElement {↵  // also has obsolete members↵};", "Categories:↵None.↵Contexts in which this element c…ctor]↵interface HTMLHeadElement : HTMLElement {};", "Categories:↵Metadata content.↵Contexts in which th…nt {↵  [CEReactions] attribute DOMString text;↵};", …]
[0 … 99]
[100 … 106]
length: 107
__proto__: Array(0)


3.3、第3步:组装元素名

在第2步的基础上可以发现,返回的元素是没有元素名的,这一步主要是通过id属性获取,然后组装起来

var elementDefinations = Array.prototype.map.call(document.querySelectorAll(".element"), e => ({
  text:e.innerText,
  name:e.childNodes[0].childNodes[0].id.match(/the\-([\s\S]+)\-element:/)?RegExp.$1:null}));
console.log(elementDefinations);


输出结果:

// 大概就是这样子的,我截取了一部分
(107) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …]
[0 … 99]
[100 … 106]
length: 107
__proto__: Array(0)
// 但是{}里面就是类似这样的
{
    name: "html"
    text: "Categories:↵None.↵Contexts in which this element can be ....."
}


3.4、第4步:拆分文本

1、categories

把这些不带任何条件的 category 先保存起来,然后打印出来其它的描述看看:

for(let defination of elementDefinations) {
  //console.log(defination.name + ":")
  let categories = defination.text.match(/Categories:\n([\s\S]+)\nContexts in which this element can be used:/)[1].split("\n");
  defination.categories = [];
  for(let category of categories) {
    if(category.match(/^([^ ]+) content./))
      defination.categories.push(RegExp.$1);
    else
      console.log(category)  
  }
}


输出结果:

2 None.
 If the element is allowed in the body: flow content.
 If the element is allowed in the body: phrasing content.
 If the itemprop attribute is present: flow content.
 If the itemprop attribute is present: phrasing content.
2 Sectioning root.
3 If the element's children include at least one li element: Palpable content.
 None.
 If the element's children include at least one name-value group: Palpable content.
2 None.
 Sectioning root.
 None.
 If the element has an href attribute: Interactive content.
 ...


2、Content Model

先处理掉最简单点的部分,就是带分类的内容模型,再过滤掉带 If 的情况、Text 和 Transparent。

for(let defination of elementDefinations) {
  //console.log(defination.name + ":")
  let categories = defination.text.match(/Categories:\n([\s\S]+)\nContexts in which this element can be used:/)[1].split("\n");
  defination.contentModel = [];
  let contentModel = defination.text.match(/Content model:\n([\s\S]+)\nTag omission in text\/html:/)[1].split("\n");
  for(let line of contentModel)
    if(line.match(/([^ ]+) content./))
      defination.contentModel.push(RegExp.$1);
    else if(line.match(/Nothing.|Transparent./));
    else if(line.match(/^Text[\s\S]*.$/));
    else
      console.log(line)
}


输出结果:

A head element followed by a body element.
One or more h1, h2, h3, h4, h5, h6 elements, optionally intermixed with script-supporting elements.
3 Zero or more li and script-supporting elements.
Either: Zero or more groups each consisting of one or more dt elements followed by one or more dd elements, optionally intermixed with script-supporting elements.
......


3.5、第5步:编写 check 函数


有了 contentModel 和 category,要检查某一元素是否可以作为另一元素的子元素,就可以判断一下两边是否匹配。


1、设置索引

var dictionary = Object.create(null);
for(let defination of elementDefinations) {
  dictionary[defination.name] = defination;
}


2、check函数

function check(parent, child) {
  for(let category of child.categories)
    if(parent.contentModel.categories.conatains(category))
      return true;
  if(parent.contentModel.names.conatains(child.name))
      return true;
  return false;
}

参考资料:https://html.spec.whatwg.org/

目录
相关文章
|
15天前
|
JavaScript 前端开发 开发者
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第27天】在前端开发领域,Vue.js和Angular是两个备受瞩目的框架。本文对比了两者的优劣,Vue.js以轻量级和易上手著称,适合快速开发小型到中型项目;Angular则由Google支持,功能全面,适合大型企业级应用。选择时需考虑项目需求、团队熟悉度和长期维护等因素。
21 1
|
16天前
|
JavaScript 前端开发 API
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第26天】前端技术的飞速发展让开发者在构建用户界面时有了更多选择。本文对比了Vue.js和Angular两大框架,介绍了它们的特点和优劣,并给出了在实际项目中如何选择的建议。Vue.js轻量级、易上手,适合小型项目;Angular结构化、功能强大,适合大型项目。
16 1
|
22天前
|
JavaScript 前端开发 算法
前端优化之超大数组更新:深入分析Vue/React/Svelte的更新渲染策略
本文对比了 Vue、React 和 Svelte 在数组渲染方面的实现方式和优缺点,探讨了它们与直接操作 DOM 的差异及 Web Components 的实现方式。Vue 通过响应式系统自动管理数据变化,React 利用虚拟 DOM 和 `diffing` 算法优化更新,Svelte 通过编译时优化提升性能。文章还介绍了数组更新的优化策略,如使用 `key`、分片渲染、虚拟滚动等,帮助开发者在处理大型数组时提升性能。总结指出,选择合适的框架应根据项目复杂度和性能需求来决定。
|
1月前
|
XML 前端开发 JavaScript
前端开发进阶:从HTML到React.js
【10月更文挑战第9天】前端开发进阶:从HTML到React.js
|
2月前
|
Web App开发 存储 移动开发
前端基础(十七)_HTML5新特性
本文概述了HTML5的关键新特性,包括canvas图形绘制、多媒体的`video`和`audio`元素、本地存储功能、语义化标签(如`header`、`footer`、`nav`等)及其新增表单控件和属性(如`url`、`email`、`date`类型输入框等)。这些改进增强了网页的功能性和用户体验。
39 1
前端基础(十七)_HTML5新特性
|
1月前
|
Java BI API
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
这篇文章介绍了如何在Spring Boot项目中整合iTextPDF库来导出PDF文件,包括写入大文本和HTML代码,并分析了几种常用的Java PDF导出工具。
404 0
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
|
1月前
|
前端开发 JavaScript 数据安全/隐私保护
【前端基础篇】HTML零基础速通2
【前端基础篇】HTML零基础速通
18 2
|
1月前
|
Web App开发 移动开发 前端开发
【前端基础篇】HTML零基础速通1
【前端基础篇】HTML零基础速通
28 1
|
2月前
|
前端开发
前端基础(二)_HTML常用标签(块级标签、行级标签、行块级标签)
本文详细介绍了HTML中的常用标签,包括块级标签(如`h1`至`h6`、`p`、`div`等)、行级标签(如`span`、`b`、`strong`、`i`、`em`、`sub`、`sup`、`del`、`a`等),以及行块级标签(如`img`)。文章解释了这些标签的用途、特点和基本用法,并通过示例代码展示了如何在HTML文档中使用它们。
111 1
|
2月前
|
前端开发 程序员
【前端web入门第二天】01 html语法实现列表与表格_合并单元格
本文介绍了HTML中的列表与表格的使用方法。列表包括无序列表(`<ul>`嵌套`<li>`)、有序列表(`<ol>`嵌套`<li>`)和定义列表(`<dl>`嵌套`<dt>`和`<dd>`)。
60 19