为什么这个HTML标记甚至在加载正文之前都将body作为其lastChild

时间:2017-02-16 19:19:02

标签: javascript html parsing dom browser

我觉得这可能与对象引用有关但在这里是:

我有以下代码:

<html>
    <head>
        <script type="text/javascript">
            console.log(document.getElementsByTagName("html"));
            console.log(document.getElementsByTagName("html")[0].lastChild);
       </script>
   </head>

   <body><h1>Hello</h1></body>
</html>

在控制台中,当我展开返回的第一个集合时,我可以看到它将body作为其子节点(lastChild),即使尚未解析body元素。但是在第二个对象中它显示了head标签,这是预期的。

现在,在这里发布这个问题时,我创建了这个pen,但在那里第二个控制台是body标签,而不是头部。

那么,为什么第一个控制台语句在html中显示正文?或者是否必须对浏览器做些什么?感谢

2 个答案:

答案 0 :(得分:1)

getElementsByTagName会为您提供直播 HTMLCollection。这意味着,当底层DOM发生变化时,函数返回的实时集合也会发生变化。

  

HTML DOM中的HTMLCollection是实时的;当基础文档发生变化时,它会自动更新。

https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection

所以最初,在记录发生时,仍然没有解析body标记。如果你可以在解析正文之前检查控制台输出,那么你就不会在那里看到它。

但是当你真正检查控制台中的HTMLCollection时,身体已经被解析并因此被显示(因为,再次,HTMLCollection是活的)。

如果要“中断”实时连接,可以使用数组扩展运算符将HTMLCollection转换为标准数组:

const collection = [...liveCollection];

显然,第二个控制台。标记头标记,因为在记录时,它确实是最后一个孩子。

FYI

其他常见的DOM查询函数(如getElementsByClassName)也可以为您提供实时集合。

答案 1 :(得分:1)

正如@scarySize所提到的,当您在第一个console.log上记录html标记时,它实际上记录了实时HTMLCollection。

所以最初,在记录发生时,仍然没有解析body标记。因此,如果你可以在解析正文之前检查控制台输出,那么你就不会在那里看到它。

但是当你真正检查控制台中的HTMLCollection时,body已被解析并因此被显示(因为,再次,HTMLCollection是活的)。

显然,第二个console.log打印头标记,因为在记录时,它确实是最后一个孩子。