Javascript 如果我不需要结果列表中CSS选择器的粒度,为什么我想要静态节点列表/HTMLCollection而不是“活动”节点列表?

Javascript 如果我不需要结果列表中CSS选择器的粒度,为什么我想要静态节点列表/HTMLCollection而不是“活动”节点列表?,javascript,dom,nodelist,selectors-api,Javascript,Dom,Nodelist,Selectors Api,我通常听说这是因为实时节点列表不好,这决定querySelectorAll返回一个静态HTMLCollection。为什么人们认为现场节点列表是件坏事?代码示例可能会帮助我更好地理解这一点 如果,每当我想在任何计算中使用缓存的节点集合的值时,该集合恰好不是一个过时的快照,那么我并不认为这是一件坏事 我完全理解使用CSS选择器字符串选择元素有多有用,但如果我在获取该集合后才能够可靠地对其运行代码,那么它似乎没有实时节点列表有用。实时节点列表还不错,但如果您不习惯,它们的行为可能会令人困惑。特别是如

我通常听说这是因为实时节点列表不好,这决定querySelectorAll返回一个静态HTMLCollection。为什么人们认为现场节点列表是件坏事?代码示例可能会帮助我更好地理解这一点

如果,每当我想在任何计算中使用缓存的节点集合的值时,该集合恰好不是一个过时的快照,那么我并不认为这是一件坏事


我完全理解使用CSS选择器字符串选择元素有多有用,但如果我在获取该集合后才能够可靠地对其运行代码,那么它似乎没有实时节点列表有用。

实时节点列表还不错,但如果您不习惯,它们的行为可能会令人困惑。特别是如果你把它们看作数组,它们就不是数组了

考虑一个将页面中的div数加倍的经典示例。这里有三种尝试:

// Example 1 (doesn't work)
for(var i = 0; i < document.querySelectorAll("div").length ; i++){
    document.body.appendChild(document.createElement("div"));
}

// Example 2 (works)
var divs = document.querySelectorAll("div");
for(var i = 0; i < divs.length ; i++){
    document.body.appendChild(document.createElement("div"));
}

// Example 3 (doesn't work)
var divs = document.getElementsByTagName("div");
for(var i = 0; i < divs.length; i++){
    document.body.appendChild(document.createElement("div"));
}
示例1显然是一个无限循环。每次迭代,它都会重新检查页面中的div数

示例2按预期工作,因为节点列表已经被缓存了。当然,最好只是缓存长度

示例3与示例2类似。许多人都希望它以同样的方式工作,因为节点列表是缓存的。但由于节点列表是活动的,它实际上是另一个无限循环。这让一些人感到困惑

此外,如果函数返回静态节点列表,则可以在每次需要时重新查询DOM。这可能比将live列表转换为静态列表更简单。

live NodeList检索速度更快,因此性能更高 静态节点列表的性能较差

例如,在querySelectorquerySelectorAll和getElementById之间

在相同条件下,使用getElementsByTagName比使用querySelectorAll更好


至少我从微软官方培训指南中读到了用JavaScript和CSS3在HTML5中编程

谢谢你的回答。首先,到目前为止,我还不知道任何div加倍的经典例子。实际用例是什么?第二,如果我碰巧发现这种“行为”是可以理解的,顺便说一句,我是可以理解的;我仍然不明白为什么静态节点列表更可取。第三,在某些情况下,编写返回静态节点列表的函数可能会很昂贵,IMHO仍然回避这个问题,…为什么?@bodine 1:用例可能会在页面底部添加一个引用部分,包含页面中的所有链接,即所有锚元素的副本。如果你不小心的话,你可能会得到一个无限循环。2:通常不是。3:是的。实时列表被认为是危险的主要原因是很多人不理解它们