cod*_*boy 6 html javascript dom htmlcollection
document.scripts返回一个HTMLCollection包含文档中所有脚本列表的对象。同样,document.getElementsByTagName("script")返回另一个HTMLCollection对象,其中包含文档中所有脚本的列表。
我预计以下陈述是正确的,但事实并非如此。
document.scripts === document.getElementsByTagName("script") // false
Run Code Online (Sandbox Code Playgroud)
这两者不相等的原因是什么?
好吧,我在这里找不到理论推理,但似乎在某些情况下这些可能并不严格等效,并且实现必须牢记这一点。例如,在 Chromium 中,实现是不同的,真正有趣的事实是两者都是缓存集合:
// renderer/core/dom/document.cc
HTMLCollection* Document::scripts() {
return EnsureCachedCollection<HTMLCollection>(kDocScripts);
}
// renderer/core/dom/container_node.cc
HTMLCollection* ContainerNode::getElementsByTagName(
const AtomicString& qualified_name) {
DCHECK(!qualified_name.IsNull());
if (GetDocument().IsHTMLDocument()) {
return EnsureCachedCollection<HTMLTagCollection>(kHTMLTagCollectionType,
qualified_name);
}
return EnsureCachedCollection<TagCollection>(kTagCollectionType,
qualified_name);
}
Run Code Online (Sandbox Code Playgroud)
这不仅仅是scripts:所有文档 HTMLCollection 属性(表单、小程序、图像等)都被包装到EnsureCachedCollection<HTMLCollection>.
然而,对于标签来说,它是EnsureCachedCollection<HTMLTagCollection>. 虽然 HTMLTagCollection 是 TagCollection 的子级(TagCollection 又是 HTMLCollection 的子级),但它们是不同的缓存。
现在,按照我期望缓存的工作方式,相同的请求应该给出相同的结果......除非您命中不同的缓存。在这种情况下,相同的结果不仅意味着值相等,还意味着对象相等。
这就是为什么您在后续调用document.getElementsByTagName('script')和后续调用之间获得严格等价document.scripts- 但不能跨这些调用。
更新:检查@Alohci 答案,它给出了一个很好的例子,说明这些请求的结果实际上何时会有所不同。
这是一个给出不同结果的示例。document.scripts 返回HTMLElement脚本集,其中 getElementsByTagName("script") 返回所有 scriot 元素的集,无论命名空间如何。
(StackSnippets 逻辑向文档添加了两个脚本元素,超出了此处示例代码中显示的元素。)
console.log('There are ' + document.scripts.length + ' document.scripts elements');
console.log('There are ' + document.getElementsByTagName("script").length + ' document.getElementsByTagName("script") elements');Run Code Online (Sandbox Code Playgroud)
<script>console.log('foo');</script>
<svg><script>console.log('bar');</script></svg>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
88 次 |
| 最近记录: |