以下所有结果均使用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:
可能是,在调用getElementsByTagName时,不存在任何输入元素,但由于NodeLists是动态的,因此当文档加载时,元素将包含所有28个输入。
但是我正在读它说getElementsByTagName解析NodeList直到它可以解析DOM,并且只能在解析DOM时返回length
属性,这对我来说似乎不对,因为它仍然有有限的可数元素。
此外,还有[item:function, namedItem:function]
更改为[a.someClass.someOtherClass, a.someclass.someOtherClass]
的问题,上述内容无法解释。
因此我的问题是:尽管原型保持不变,但是在{DOM}加载之后getElementsByClassName
属性未设置(不存在?)的情况下究竟发生了什么? ?这与/为什么输出从length
变为[item:function, namedItem:function]
?
答案 0 :(得分:5)
如您所见,getElementsByClassName
会返回HTMLCollection
- 即查询的实时参考。
在DOM准备就绪后,您正在控制台中扩展 live 引用,但在 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并且在它之后打印2 - 因为它是完全发生了什么,因为在DOM准备好之前没有DOM元素。
答案 1 :(得分:1)
Nodelist是HTMLcollection的超集。具体来说,Nodelist是制作HTMLcollection的构造函数。
var list = document.getElementsByClassName("classname");
console.log(list)
现在您将看到:
__proto__ : NodeList();
console.log(NodeList) //-> function NodeList()
因此HTMLcollection只是一个包含元素而不是文本的nodeList。 (Nodelist可以包含文本) 要形成节点列表,您必须使用以下方法: Node.childNodes Element.classList
可能还有一些建立它的递归。