getElementsByClassName在Chrome中到底如何工作?特别是w.r.t.节点列表和DOMs [英] How exactly does getElementsByClassName work in Chrome?, specifically w.r.t. NodeLists & DOMs

查看:98
本文介绍了getElementsByClassName在Chrome中到底如何工作?特别是w.r.t.节点列表和DOMs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下所有结果都是使用Google Chrome v36&它的控制台.

All of the following results were obtained using Google Chrome v36 & its console.

在调试Wordpress插件时,我发现运行此Javascript片段

While debugging a Wordpress plugin, I discovered that running this little Javascript snippet

console.log(document.getElementsByClassName("switch-tmce"))
console.log(document.getElementsByClassName("switch-tmce").length)

将记录以下内容(在页面加载完成后进行扩展):

would log the following (expanded after the page finished loading):

[item: function, namedItem: function]
    0: a#ninja_forms_field_10-tmce.hide-if-no-js.wp-switch-editor.switch-tmce
    1: a#ninja_forms_field_15-tmce.hide-if-no-js.wp-switch-editor.switch-tmce
    length: 2
    ninja_forms_field_10-tmce: a#ninja_forms_field_10-tmce.hide-if-no-js.wp-switch-editor.switch-tmce
    ninja_forms_field_15-tmce: a#ninja_forms_field_15-tmce.hide-if-no-js.wp-switch-editor.switch-tmce
    __proto__: HTMLCollection
0

如果我调整了代码段以等待DOM完成加载,如下所示:

If I adjusted the snippet to wait for the DOM to finish loading like so:

window.addEventListener("DOMContentLoaded", function() {
    console.log(document.getElementsByClassName("switch-tmce"))
    console.log(document.getElementsByClassName("switch-tmce").length)
}, false);

然后它将记录以下内容(在页面加载完成后展开):

it would then log the following (expanded after the page finished loading):

[a#ninja_forms_field_10-tmce.hide-if-no-js.wp-switch-editor.switch-tmce, a#ninja_forms_field_15-tmce.hide-if-no-js.wp-switch-editor.switch-tmce, ninja_forms_field_10-tmce: a#ninja_forms_field_10-tmce.hide-if-no-js.wp-switch-editor.switch-tmce, ninja_forms_field_15-tmce: a#ninja_forms_field_15-tmce.hide-if-no-js.wp-switch-editor.switch-tmce, item: function, namedItem: function]
    0: a#ninja_forms_field_10-tmce.hide-if-no-js.wp-switch-editor.switch-tmce
    1: a#ninja_forms_field_15-tmce.hide-if-no-js.wp-switch-editor.switch-tmce
    length: 2
    ninja_forms_field_10-tmce: a#ninja_forms_field_10-tmce.hide-if-no-js.wp-switch-editor.switch-tmce
    ninja_forms_field_15-tmce: a#ninja_forms_field_15-tmce.hide-if-no-js.wp-switch-editor.switch-tmce
    __proto__: HTMLCollection
2

我无法理解的只是这里到底发生了什么-特别是为什么 length 属性仅返回正确"的原因,可以这么说,之后DOM加载.我发现了这种解释:

What I'm having trouble understanding is just what exactly is happening here - in particular, why the length property only returns "correctly", so to speak, after the DOM loads. I've found this explanation:

可能是,在调用getElementsByTagName时,不存在任何输入元素,但是由于NodeList是动态的,因此在文档加载时,元素将包含全部28个输入.

It might be, that while calling getElementsByTagName, no input elements exist, but since NodeLists are dynamic, when the document loads, elements will contain all 28 inputs.

但是我读这句话是说getElementsByTagName解析NodeList直到它可以解析DOM,并且在解析DOM时只能返回 length 属性,这对我来说似乎不对,因为它仍然具有有限的可数元素.

but I'm reading that as saying that getElementsByTagName parses the NodeList until it can parse the DOM, and can only return the length property when parsing the DOM, which doesn't seem right to me, since it still has finite countable elements.

此外,还有 [item:function,namedItem:function] 更改为 [a.someClass.someOtherClass,a.someclass.someOtherClass] 的问题,上面没有解释.

Moreover, there's also the matter of [item:function, namedItem:function] changing to [a.someClass.someOtherClass, a.someclass.someOtherClass], which the above doesn't explain.

因此,我的问题是: length 属性没有设置(不存在?),直到加载之后, getElementsByClassName 到底发生了什么?原型保持不变?这与为什么输出从 [item:function,namedItem:function] 更改为 [a.someClass.someOtherClass,a.someclass.someOtherClass] 有什么关系?

Hence my question: What exactly is happening under the hood with getElementsByClassName that the length property is not set (does not exist?) until after the DOM loads, despite that the prototype remains the same? How is this related to/why does the output change from [item:function, namedItem:function] to [a.someClass.someOtherClass, a.someclass.someOtherClass]?

推荐答案

如您所见, getElementsByClassName 返回 HTMLCollection -即 live 您查询的参考.

As you can see, getElementsByClassName returns a HTMLCollection - that is, a live reference for your query.

正在发生的事情是,在DOM准备就绪之后,您正在控制台中扩展 live 引用,但是在DOM准备就绪之前 对其进行了记录.因为它是一个 live 引用,所以当DOM准备就绪时,通过扩展,当 HTMLCollection 引用内存中的对象时,它会看到DOM准备就绪并从内存中提取.完成的DOM.

What's happening is that you're expanding the live reference in the console after the DOM is ready, but logging it before the DOM is ready. Because it is a live reference, by expanding when the DOM is ready, when the HTMLCollection references the object in the memory, it sees that the DOM is ready and pulls from the finished DOM.

但是,如果您在暂停执行Java脚本的同时扩展了引用(可以使用 debugger 之类的方法来完成此操作),那么您将获得以下信息:

If, however, you expanded the reference while having paused the execution of the Javascript (this can be done with something like debugger), this is what you would get:

[item: function, namedItem: function]
    length: 0
    __proto__: HTMLCollection
0

因为那时DOM还没有准备好.

because the DOM would not yet be ready then.

这就是为什么第一个记录的引用显示为 [item:function,namedItem:function] 的原因,因为当您记录它时,DOM还没有准备好.DOM准备就绪后,将其记录为 [a.someClass.someOtherClass,a.someClass.someOtherClass] .

That's why the first logged reference showed up as [item: function, namedItem: function], because when you logged it, the DOM wasn't ready. Once the DOM was ready, it was logged as [a.someClass.someOtherClass, a.someClass.someOtherClass].

不过,输出的长度只是一个数字,而不是对象引用,并且按原样记录,这就是为什么它在DOM准备就绪之前打印0并在DOM准备就绪之后打印2的原因-因为这完全是 发生了什么,因为在DOM准备就绪之前没有DOM元素.

The length output, though, is just a number, not an object reference, and logs as is, which is why it prints 0 before the DOM is ready and 2 after it is - because that's exactly what's happening, since there are no DOM elements before the DOM is ready.

这篇关于getElementsByClassName在Chrome中到底如何工作?特别是w.r.t.节点列表和DOMs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆