究竟如何getElementsByClassName工作在Chrome?,特别是w.r.t. NodeLists &;延

How exactly does getElementsByClassName work in Chrome?, specifically w.r.t. NodeLists & DOMs

本文关键字:NodeLists 特别是 getElementsByClassName 工作 Chrome 究竟      更新时间:2023-09-26

以下所有结果均使用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加载后的。我找到了这样的解释:

在调用getElementsByTagName时,可能不存在任何输入元素,但由于NodeLists是动态的,当文档加载时,元素将包含所有28个输入。

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

此外,还有[item:function, namedItem:function]变为[a.someClass.someOtherClass, a.someclass.someOtherClass]的问题,这是上述不能解释的。

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

可以看到,getElementsByClassName返回一个HTMLCollection——也就是说,一个实时查询引用。

发生的事情是,在DOM准备好之后,您在控制台中扩展live引用,但在 DOM准备好之前记录它。因为它是一个活动引用,当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元素。

Nodelist是HTMLcollection的超集。具体来说,Nodelist是创建HTMLcollection的构造函数。

var list = document.getElementsByClassName("classname"); console.log(list) 现在您将看到:

__proto__ : NodeList();
console.log(NodeList) //-> function NodeList()

所以HTMLcollection只是一个包含元素而不是文本的nodeList。(Nodelist可以包含文本)要创建一个nodelist,你必须使用以下方法:Node.childNodes元素。班级名册

和可能的递归构建