最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 你知道被标准化的 HTML 标签有多少个吗?

    正文概述 掘金(千竹)   2020-12-28   738

    一、前言

    前些天 winter 老师直播问了一个问题,你知道现在有多少个被标准化的 HTML 标签吗?这是个很有意思的问题。写了这么久的 HTML,那到底有多少个被标准化的 HTML标签呢?

    二、获取 HTML 标签

    首先,我们访问 HTML 标准文档,这张表格中整理了所有的 HTML 标签。我们可以将它们黏贴到编辑器中,看到总共有 109 行。如果你粗略的浏览下,你应该会发现,h1h2一直到 h6 都是放在一起的。所以目前标准化的所有标签是 114 个。

    到这里,我们的查询任务已经完成了。但是我们就止于此吗?不。

    三、HTML 标签是怎么对应其 DOM 接口的?

    思路是这样的:我们先从规范中整理出所有标签对应的接口,然后再从 window 对象中获取到所有 DOM 接口,最后再将它们进行比较,看看规范与具体浏览器实现的对应关系。

    (1)从规范中查询所有定义的接口列表

    规范中 这样定义 HTML 中的 elements。

    意思是说, DOM 中 HTML 元素的节点必须实现规范相关部分中列出的接口,并将这些接口公开给脚本。也就是说,所有的 HTML 标签都会有对应的 DOM 接口。因此,我们根据前面获取到的标签表格依次去查询标签描述就可以得出所有的接口列表。

    规范在描述所有标签时给出了对应的 IDL(Interface description language) 。比如,打开一个 span 标签查看它 DOM interface 的描述:

    [Exposed=Window]
    interface HTMLSpanElement : HTMLElement {
      [HTMLConstructor] constructor();
    };
    

    可以看到 span 标签的 DOM 接口是 HTMLSpanElement,并且继承自 HTMLElement 接口。

    最终得到的接口列表如下:

    // 对应已知的 DOM interface,除 HTMLElement 外 63 个。
    const preList = [
                    // multi element 6
                    // 'HTMLElement',
                    'HTMLQuoteElement',
                    'HTMLTableSectionElement',
                    'HTMLTableCellElement',
                    'HTMLTableColElement',
                    'HTMLHeadingElement',
                    'HTMLModElement',
                    // root element 1
                    'HTMLHtmlElement',
                    // metadata 8
                    'HTMLBaseElement',
                    'HTMLHeadElement',
                    'HTMLLinkElement',
                    'HTMLMetaElement',
                    'HTMLCanvasElement',
                    'HTMLStyleElement',
                    'HTMLTitleElement',
                    'HTMLScriptElement',
                    // inline-text-semantics 5
                    'HTMLAnchorElement',
                    'HTMLBRElement',
                    'HTMLDataElement',
                    'HTMLSpanElement',
                    'HTMLTimeElement',
                    // forms 14
                    'HTMLButtonElement',
                    'HTMLDataListElement',
                    'HTMLFieldSetElement',
                    'HTMLFormElement',
                    'HTMLInputElement',
                    'HTMLLabelElement',
                    'HTMLLegendElement',
                    'HTMLMeterElement',
                    'HTMLOptGroupElement',
                    'HTMLOptionElement',
                    'HTMLOutputElement',
                    'HTMLProgressElement',
                    'HTMLSelectElement',
                    'HTMLTextAreaElement',
                    // text-content 8
                    'HTMLDivElement',
                    'HTMLDListElement',
                    'HTMLHRElement',
                    'HTMLLIElement',
                    'HTMLOListElement',
                    'HTMLParagraphElement',
                    'HTMLPreElement',
                    'HTMLUListElement',
                    // content-sectioning-root 1
                    'HTMLBodyElement',
                    // interactive-element 3
                    'HTMLDetailsElement',
                    'HTMLDialogElement',
                    'HTMLMenuElement',
                    // tabular-data 3
                    'HTMLTableCaptionElement',
                    'HTMLTableElement',
                    'HTMLTableRowElement',
                    // web-components 2
                    'HTMLSlotElement',
                    'HTMLTemplateElement',
                    // image-multimedia-embedded-content 12
                    'HTMLAreaElement',
                    'HTMLAudioElement',
                    'HTMLImageElement',
                    'HTMLMapElement',
                    'HTMLTrackElement',
                    'HTMLVideoElement',
                    'HTMLEmbedElement',
                    'HTMLIFrameElement',
                    'HTMLObjectElement',
                    'HTMLParamElement',
                    'HTMLPictureElement',
                    'HTMLSourceElement'
                ];
    

    (2)从浏览器中获取所有接口列表

    从上面的定义中注意到,规范规定所有的接口都会暴露给脚本。这样我们就可以从 window 上获取到所有属性,然后从中过滤出来所有继承自 HTMLElement 接口的对象。获得所有接口后再进行转换一下打印出来。

    // 获取 window 上的继承自 HTMLElement 的 interface
    const windowIntList = [...new Set(Object.getOwnPropertyNames(window)
                         .map(name => window[name] && window[name].prototype)
                         .filter(o => o instanceof HTMLElement)
                         .map(name => {
                         	return Object.prototype.toString.call(name).replace(/\[object|\]| /g, ''); 
                         }))];
                         
    // output:
    // Array(72)
    // 0: "HTMLOptionElement"
    // 1: "HTMLImageElement"
    // 2: "HTMLAudioElement"
    // 3: "HTMLVideoElement"
    // 4: "HTMLUnknownElement"
    // 5: "HTMLUListElement"
    // 6: "HTMLTrackElement"
    // 7: "HTMLTitleElement"
    // 8: "HTMLTimeElement"
    // 9: "HTMLTextAreaElement"
    // 10: "HTMLTemplateElement"
    // 11: "HTMLTableSectionElement"
    // 12: "HTMLTableRowElement"
    // 13: "HTMLTableElement"
    // 14: "HTMLTableColElement"
    // 15: "HTMLTableCellElement"
    // 16: "HTMLTableCaptionElement"
    // 17: "HTMLStyleElement"
    // 18: "HTMLSpanElement"
    // 19: "HTMLSourceElement"
    // 20: "HTMLSlotElement"
    // 21: "HTMLShadowElement"
    // 22: "HTMLSelectElement"
    // 23: "HTMLScriptElement"
    // 24: "HTMLQuoteElement"
    // 25: "HTMLProgressElement"
    // 26: "HTMLPreElement"
    // 27: "HTMLPictureElement"
    // 28: "HTMLParamElement"
    // 29: "HTMLParagraphElement"
    // 30: "HTMLOutputElement"
    // 31: "HTMLOptGroupElement"
    // 32: "HTMLObjectElement"
    // 33: "HTMLOListElement"
    // 34: "HTMLModElement"
    // 35: "HTMLMeterElement"
    // 36: "HTMLMetaElement"
    // 37: "HTMLMenuElement"
    // 38: "HTMLMediaElement"
    // 39: "HTMLMarqueeElement"
    // 40: "HTMLMapElement"
    // 41: "HTMLLinkElement"
    // 42: "HTMLLegendElement"
    // 43: "HTMLLabelElement"
    // 44: "HTMLLIElement"
    // 45: "HTMLInputElement"
    // 46: "HTMLIFrameElement"
    // 47: "HTMLHtmlElement"
    // 48: "HTMLHeadingElement"
    // 49: "HTMLHeadElement"
    // 50: "HTMLHRElement"
    // 51: "HTMLFrameSetElement"
    // 52: "HTMLFrameElement"
    // 53: "HTMLFormElement"
    // 54: "HTMLFontElement"
    // 55: "HTMLFieldSetElement"
    // 56: "HTMLEmbedElement"
    // 57: "HTMLDivElement"
    // 58: "HTMLDirectoryElement"
    // 59: "HTMLDialogElement"
    // 60: "HTMLDetailsElement"
    // 61: "HTMLDataListElement"
    // 62: "HTMLDataElement"
    // 63: "HTMLDListElement"
    // 64: "HTMLContentElement"
    // 65: "HTMLCanvasElement"
    // 66: "HTMLButtonElement"
    // 67: "HTMLBodyElement"
    // 68: "HTMLBaseElement"
    // 69: "HTMLBRElement"
    // 70: "HTMLAreaElement"
    // 71: "HTMLAnchorElement"
    // length: 72
    

    经过以上操作获得 72 个继承自 HTMLElement 接口的接口。

    (3)preListwindowIntList 的比较

    我们得到的 preListwindowIntList 各自的个数为 63 和 72。但是前面算出来的标签确是 114 个。不是每个标签都有对应的接口吗?难道这三个算出来的个数不应该是一样的吗?

    如果你也自己去整理了 preList,那你一定知道 其中不仅有很多标签具有相同接口,而且还有大量标签的接口都是基础接口 HTMLElement。如果你没有整理也没有关系,下面是我整理的对应关系:

    接口个数标签
    HTMLQuoteElement2qblockquoteHTMLTableSection3theadtbodytfootHTMLTableCell2tdthHTMLTableCol2colcolgroupHTMLHeadingElement6h1h2h3h4h5h6HTMLModElement2delinsHTMLElement40addressarticleasidefooterheaderhgroupnavsectionmainsummarynoscriptabbrbbdibdocitecodedfnemikbdmarkrbrprtrtcrubyssmapsmallstrongsubsupuvarwbrdddtfigurefigcaption

    由此我们可以得出 preList 的总个数为 63 加上 HTMLElement 接口的个数再加上其它接口重复的个数:63 + 40 + 1 + 2 + 1 + 1 + 5 + 1 = 114 个。欧克,对上了,完美。:)

    通过比较, preList 中所有的元素都在 windowIntList 中。windowIntList 中则比 preList 多出了这些接口:

    // HTMLUnknownElement
    // HTMLShadowElement
    // HTMLMediaElement
    // HTMLMarqueeElement
    // HTMLFrameSetElement
    // HTMLFrameElement
    // HTMLFontElement
    // HTMLDirectoryElement
    // HTMLContentElement
    

    又经过一番翻天覆地的查找,发现上述列表除了 HTMLMediaElementHTMLUnknownElement 其它的都是已经废弃了的接口。HTMLMediaElement 接口则是其它多媒体的底层接口。它们的继承关系是这样的:

    你知道被标准化的 HTML 标签有多少个吗?

    至于 HTMLUnknownElement 接口,它代表着一个无效的 HTML 元素,继承自 HTMLElement 接口。当我们使用一个无效的标签时,仍然可以对其操作及样式设置。

    <!DOCTYPE html>
    <html>
        <style>
            test {
                color: red;
            }
        </style>
        <body>
            <test>nihao</test>
        </body>
        <script>
            {
                const dom = document.getElementsByTagName('test')[0];
                console.log(dom instanceof HTMLUnknownElement)
                // output: true
            }
        </script>
    </html>
    
    
    

    四、最后

    很可能当你阅读到这篇文章时被标准化的 HTML 已经不是这个数字了。但是没关系,希望这篇文章能为你提供思路。最后,有空的话,一定要自己去动手操作一下,这样可以理解的更深刻哦~


    推荐一个网站:在线查阅 HTML 标签

    系统信息:
    OS:macOS Catalina 10.15.7
    Browser Version: Chrome 87.0.4280.88(正式版本) (x86_64)


    起源地下载网 » 你知道被标准化的 HTML 标签有多少个吗?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元