[英]Why does document.getElementsByName return a NodeList while document.getElementsByClassName returns an HTMLCollection?
This seems confusing, but I bet I am missing something fundamental.这似乎令人困惑,但我敢打赌我错过了一些基本的东西。
Interestingly enough, the W3Schools docs are wrong and say both methods return an HTMLCollection: https://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp https://www.w3schools.com/jsref/met_doc_getelementsbyname.asp <- incorrect有趣的是,W3Schools 文档是错误的,并说这两种方法都返回一个 HTMLCollection: https : //www.w3schools.com/jsref/met_document_getelementsbyclassname.asp https://www.w3schools.com/jsref/met_doc_getelementsbyname.asp <- 不正确
The Mozilla docs are correct in that byName returns a NodeList while byClassName returns an 'array like' object, aka HTMLCollection. Mozilla 文档是正确的,因为 byName 返回一个 NodeList 而 byClassName 返回一个“类似数组”的对象,也就是 HTMLCollection。
Found this out when I tried to run forEach on the output of byClassName and it failed.当我尝试在 byClassName 的输出上运行 forEach 时发现了这一点,但它失败了。
In short, because the specification says so.简而言之,因为规范是这样说的。 For
getElementsByName
:对于
getElementsByName
:
The
getElementsByName(name)
method takes a string name, and must return a live NodeList containing all the HTML elements in that document that have a name attribute whose value is equal to the name argument (in a case-sensitive manner), in tree order.getElementsByName(name)
方法采用字符串名称,并且必须返回一个活动NodeList,其中包含该文档中具有 name 属性的所有 HTML 元素,其值等于 name 参数(以区分大小写的方式),按树顺序排列. When the method is invoked on a Document object again with the same argument, the user agent may return the same as the object returned by the earlier call.当使用相同的参数再次在 Document 对象上调用该方法时,用户代理可能返回与先前调用返回的对象相同的对象。 In other cases, a new NodeList object must be returned.
在其他情况下,必须返回一个新的 NodeList 对象。
For getElementsByClassName
:对于
getElementsByClassName
:
The
getElementsByClassName(classNames)
method, when invoked, must return the list of elements with class names classNames forthis
.该
getElementsByClassName(classNames)
方法被调用时,必须返回与类名类名的元素列表this
。
(where this
is usually document
), and where the "list of elements" is constructed by : (
this
通常是document
),并且“元素列表”由以下内容构建:
The list of elements with class names classNames for a node root is the HTMLCollection returned by the following algorithm.....
节点根的类名为 classNames 的元素列表是由以下算法返回的HTMLCollection .....
Similarly, querySelectorAll
returns a static NodeList.同样,
querySelectorAll
返回一个静态NodeList。
Interestingly enough, the W3Schools docs are wrong
有趣的是,W3Schools 文档是错误的
Not surprising - w3schools is notoriously not very reliable.不足为奇 - w3schools 是出了名的不太可靠。 Better to reference MDN or official specifications.
最好参考 MDN 或官方规范。
It's important to keep in mind the difference between the collections.记住集合之间的差异很重要。 On recent browsers, like you've encountered, there exists a
NodeList.prototype.forEach
method.在最近的浏览器上,就像您遇到的那样,存在一个
NodeList.prototype.forEach
方法。 No such method exists for HTMLCollections. HTMLCollections 不存在这样的方法。 Some of the collections are static, while some are live.
一些集合是静态的,而一些是实时的。 The live collections (like with
getElementsByClassName
) can mutate themselves while you're iterating over them (unlike static collections and arrays), but the static collections (like with querySelectorAll
) won't mutate themselves.实时集合(如
getElementsByClassName
)可以在您迭代它们时自行变异(与静态集合和数组不同),但静态集合(如querySelectorAll
)不会自行变异。
But, note that although only NodeLists have a forEach
method, both collections have a Symbol.iterator
property which you can iterate over with for..of
:但是,请注意,虽然只有 NodeLists 有
forEach
方法,但两个集合都有一个Symbol.iterator
属性,你可以用for..of
迭代:
for (const elm of document.getElementsByName('foo')) { // ... } for (const elm of document.getElementsByClassName('foo')) { // ... } console.log('No errors');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.