Javascript getElementsByClassName在Chrome中究竟是如何工作的?特别是w.r.t.节点列表&;DOMs
以下所有结果都是使用谷歌ChromeV36及其控制台获得的 在调试Wordpress插件时,我发现运行这个小Javascript片段Javascript getElementsByClassName在Chrome中究竟是如何工作的?特别是w.r.t.节点列表&;DOMs,javascript,google-chrome,getelementsbyclassname,Javascript,Google Chrome,Getelementsbyclassname,以下所有结果都是使用谷歌ChromeV36及其控制台获得的 在调试Wordpress插件时,我发现运行这个小Javascript片段 console.log(document.getElementsByClassName("switch-tmce")) console.log(document.getElementsByClassName("switch-tmce").length) 将记录以下内容(在页面完成加载后展开): 如果我将代码段调整为等待DOM完成加载,如下所示: window.a
console.log(document.getElementsByClassName("switch-tmce"))
console.log(document.getElementsByClassName("switch-tmce").length)
将记录以下内容(在页面完成加载后展开):
如果我将代码段调整为等待DOM完成加载,如下所示:
window.addEventListener("DOMContentLoaded", function() {
console.log(document.getElementsByClassName("switch-tmce"))
console.log(document.getElementsByClassName("switch-tmce").length)
}, false);
然后它将记录以下内容(在页面完成加载后展开):
我很难理解这里到底发生了什么-特别是为什么length
属性在DOM加载后只返回“正确”的结果。我发现:
可能在调用getElementsByTagName时,不存在任何输入元素,但由于节点列表是动态的,因此在加载文档时,元素将包含所有28个输入
但我认为getElementsByTagName解析NodeList直到它能够解析DOM,并且在解析DOM时只能返回length
属性,这在我看来是不对的,因为它仍然有有限的可数元素
此外,还有[item:function,namedItem:function]
更改为[a.someClass.someOtherClass,a.someClass.someOtherClass]
的问题,上面没有解释
因此我的问题是:
getElementsByClassName
的引擎盖下到底发生了什么事情,即在加载DOM之后,才设置length
属性(不存在?),尽管原型保持不变?这与输出从[item:function,namedItem:function]
更改为[a.someClass.someOtherClass,a.someClass.someOtherClass]
有什么关系?如您所见,getElementsByClassName
返回一个HTMLCollection
,即查询的实时引用
发生的情况是,在DOM准备好之后,您在控制台中扩展live引用,但在DOM准备好之前记录它。因为它是一个活动引用,所以当DOM就绪时,当HTMLCollection
引用内存中的对象时,它会展开,从而看到DOM就绪并从完成的DOM中提取
但是,如果您在暂停Javascript执行的同时扩展了引用(这可以通过调试器之类的工具完成),您将得到以下结果:
[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(“类名”);
console.log(列表)
现在您将看到:
__proto__ : NodeList();
console.log(NodeList) //-> function NodeList()
所以HTMLcollection只是包含元素而不是文本的节点列表。(节点列表可以包含文本)
要形成节点列表,必须使用以下方法:
Node.childNodes
元素类列表
可能需要一些递归来构建它。嗯,这里有一些深入的思考。想在ECMAScript上工作吗?在“但是长度输出只是一个数字,而不是一个对象引用”中,您丢失了我。如果在DOM完成加载之前没有DOM元素,那么在DOM完成加载之前返回的console.log(document.getElementsByClassName(“switch tmce”)
是什么?当你说“那个类没有DOM元素”时,你指的是什么“类”?如果我不清楚,很抱歉。那么,让我们再试一次:P查询结果是一个对象。因此,当您执行console.log
时,它会打印对对象的引用。当您单击查看由console.log
打印的对象内容时,它从对象的当前状态获取数据,而不是从您console.log
it时的状态获取数据。但是,数字不是对象,因此它打印的是值本身,而不是对数字的引用。明白了吗?试着编写调试器
在控制台之后。在DOMContentReady
事件之外记录日志。然后,打开控制台中打印的对象,它将为空。因为调试器代码>停止javascript执行。因此,打印对象的当前状态将为空。是的,这确实有意义。现在我明白你的意思了!那么,getElementsByClassName
在DOM完成加载之前返回的究竟是什么呢?它仍然返回[item:function,namedItem:function]
,除非它只是一个占位符?在本例中,它是一个HTMLCollection
对象。列表是一个htmlcollection。
[item: function, namedItem: function]
length: 0
__proto__: HTMLCollection
0
__proto__ : NodeList();
console.log(NodeList) //-> function NodeList()