为啥这个 HTML 标记在加载正文之前就将正文作为它的 lastChild
Posted
技术标签:
【中文标题】为啥这个 HTML 标记在加载正文之前就将正文作为它的 lastChild【英文标题】:Why is this HTML tag has body as its lastChild even before the body is loaded为什么这个 HTML 标记在加载正文之前就将正文作为它的 lastChild 【发布时间】:2017-07-06 02:04:53 【问题描述】:我感觉这可能与对象引用有关,但这里是:
我有以下代码:
<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,但那里的第二个控制台是主体标签而不是头部。
那么,为什么第一个控制台语句在 html 中显示正文?还是与浏览器有关?谢谢
【问题讨论】:
【参考方案1】:getElementsByTagName
会给你一个live HTMLCollection。这意味着,当底层 DOM 发生变化时,函数返回的实时集合也会发生变化。
HTML DOM 中的 HTMLCollection 是活动的;它会在基础文档更改时自动更新。
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection
所以最初,在记录发生时,body 标记仍未被解析。如果您可以在解析正文之前检查控制台输出,您就不会在那里看到它。
但是当您真正在控制台中检查 HTMLCollection 时,body 已经被解析并因此被显示(因为 HTMLCollection 再次处于活动状态)。
如果您想“中断”实时连接,您可以使用数组扩展运算符将 HTMLCollection 转换为标准数组:
const collection = [...liveCollection];
很明显,第二个 console.log 打印了 head 标签,因为当它被记录时,它确实是最后一个孩子。
仅供参考
getElementsByClassName
等其他常见的 DOM 查询函数也为您提供实时集合。
【讨论】:
我认为你的答案是正确的。我刚刚添加了我的,因为你的有点令人困惑。也许你可以用更多的解释来更新你的 querySelectorAll() 返回静态集合,而不是实时集合。 这与是否liveCollection无关...只是一般来说,当您扩展控制台中记录的对象时,您会获得其当前状态,而不是当前状态已被记录...您可以记录document.documentElement
并获得完全相同的结果...【参考方案2】:
正如@scarySize 提到的,当您在第一个console.log
上记录html 标记时,它实际上记录了实时HTMLCollection。
所以最初,在记录发生时,body 标记仍未被解析。因此,如果您可以在解析正文之前检查控制台输出,您就不会在那里看到它。
但是当您真正在控制台中检查 HTMLCollection 时,body 已经被解析并因此被显示(因为 HTMLCollection 再次处于活动状态)。
很明显,第二个console.log
打印头标签,因为在它被记录时,它确实是最后一个孩子。
【讨论】:
以上是关于为啥这个 HTML 标记在加载正文之前就将正文作为它的 lastChild的主要内容,如果未能解决你的问题,请参考以下文章
GWT:在页面准备好之前开始运行(或者正文资源不会阻止运行 gwt)?