javascript - getElementsByClassName 在 Chrome 中究竟是如何工作的?,特别是 w.r.t.节点列表和 DOM

标签 javascript google-chrome getelementsbyclassname

以下所有结果均使用 Google Chrome v36 及其控制台获得。

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

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

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

[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 完成加载,如下所示:

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

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

[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 加载。我找到了 this explanation :

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 属性,这对我来说似乎不正确, 因为它仍然有有限的可数元素。

此外,还有[item:function, namedItem:function] 变成[a.someClass.someOtherClass, a.someclass.someOtherClass]的问题,以上不解释。

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

最佳答案

如您所见,getElementsByClassName 返回一个 HTMLCollection - 即,您的查询的实时引用。

发生的事情是,您在 DOM 准备就绪后在控制台中扩展实时引用,但在 DOM 准备好之前记录它。因为它是一个live 引用,通过在 DOM 就绪时扩展,当 HTMLCollection 引用内存中的对象时,它看到 DOM 就绪并从完成DOM。

但是,如果您在暂停执行 Javascript 的同时扩展了引用(这可以通过 debugger 之类的东西来完成),这就是您将得到的结果:

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

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

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

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

关于javascript - getElementsByClassName 在 Chrome 中究竟是如何工作的?,特别是 w.r.t.节点列表和 DOM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25276315/

相关文章:

javascript - 如何使用 getElementsByClassName 确定所选下拉选项的值?

javascript - c3-angular-directive-c3 图表的多个类别和标签

Javascript 在 Chrome 中返回 null,在源代码中返回 HTML 元素

javascript - 我可以在过滤器函数之后执行回调(或类似的操作)吗?

css - Chrome 不支持 BUTTON 标签的 "writing-mode"?

javascript - 如何获取子节点值并更改值

javascript - ReactJS - 让 JSX 将 Prop 值识别为导入类

php - Google Chrome 将文件 .xml 重命名为 .download

windows - 是否可以为 windows 映射 Vim 键绑定(bind),就像 chrome 的 vimium 一样

javascript - GetElementsByClassName 和正则表达式