未闭合/错误嵌套的 HTML 标签超出了它们的父标签

Unclosed / misnested HTML tags extend past their parent

我 运行 在 HTML 标签未关闭时使用了一些有趣的功能。有时浏览器会插入额外的开始和结束标记以进行补偿,有时它只会插入结束标记。这最好通过示例来解释:

带有 <sup> 标签:

first text node
<div> This is a parent div <sup>superscript tag starts IN parent</div> text OUTSIDE node of parent

加上<s>标签:

first text node
<div> This is a parent div <s>strikethrough tag starts IN parent</div> text OUTSIDE node of parent

正如您在第一个示例中看到的那样,浏览器会在其父标签关闭之前自动关闭 <sup> 标签。但是,在第二个示例中,浏览器似乎在其父 结束之前关闭 <s> 标记,然后插入 另一个 在父项之后 <s> 开始。

我查看了 <s> and the <sup> 规范 - 我似乎找不到任何关于浏览器如何解释和处理未闭合标签的具体信息。至少没有任何内容可以解释此功能。

我想知道这是因为我正在使用的实时降价解析器 - 用户可能无法在解析源代码之前完成他们的标签。

我想知道浏览器如何处理这些事情,这样我就可以为该用例编写代码。目前,浏览器以不同的方式处理关闭不同的标签(正如您在我的示例中看到的那样)。

有谁知道浏览器为什么这样做?或者至少知道作用相同的元素列表?

感谢 @Ankith Amtange 我找到了发生的事情的 explanation。我会在这里写出来供以后的读者使用。

<s> 标签超出其父标签,因为它是一个 格式元素 <sup> 标签自动关闭,因为浏览器期望在父元素结束之前有一个结束 </sup> 标签。

HTML 解析器在其堆栈中以不同方式处理元素,这些元素分为以下类别 (source):

Special elements

  • The following elements have varying levels of special parsing rules: HTML's address, applet, area, article, aside, base, basefont, bgsound, blockquote, body, br, button, caption, center, col, colgroup, dd, details, dir, div, dl, dt, embed, fieldset, figcaption, figure, footer, form, frame, frameset, h1, h2, h3, h4, h5, h6, head, header, hgroup, hr, html, iframe, img, input, isindex, li, link, listing, main, marquee, meta, nav, noembed, noframes, noscript, object, ol, p, param, plaintext, pre, script, section, select, source, style, summary, table, tbody, td, template, textarea, tfoot, th, thead, title, tr, track, ul, wbr, and xmp; MathML's mi, mo, mn, ms, mtext, and annotation-xml; and SVG's foreignObject, desc, and title.

Formatting elements

  • The following HTML elements are those that end up in the list of active formatting elements: a, b, big, code, em, font, i, nobr, s, small, strike, strong, tt, and u.

Ordinary elements

  • All other elements found while parsing an HTML document.

解释(来自链接规范):

讨论最多的错误标记示例如下:

<p>1<b>2<i>3</b>4</i>5</p>

此标记的解析很简单,直到“3”。此时,DOM 看起来像这样:

─html
 ├──head
 └──body
    └──p
       ├──"1"
       └──b
          ├──"2"
          └──i
             └──"3"

这里,开放元素栈上有五个元素:htmlbodypbi。活动格式元素列表只有两个:bi。插入方式为“体内”。

接收到标签名称为“b”的结束标签令牌后,调用“采用代理算法”。这是一个简单的例子,因为格式化元素是 b 元素,并且 没有最远的块 。因此,开放元素堆栈最终只有三个元素:htmlbodyp,而活动格式化元素列表只有一个:iDOM 树此时未修改。

下一个标记是一个字符(“4”),触发活动格式元素的重建,在本例中只是 i 元素。因此,为“4”文本节点创建了一个新的 i 元素。在还接收到“i”的结束标记令牌并插入“5”文本节点后,DOM 如下所示:

─html
 ├──head
 └──body
    └──p
       ├──"1"
       ├──b
       │  ├──"2"
       │  └──i
       │     └──"3"
       ├──i
       │  └──"4"
       └──"5"