queryAll 和 querySelectorAll 有啥区别
Posted
技术标签:
【中文标题】queryAll 和 querySelectorAll 有啥区别【英文标题】:What's the difference between queryAll and querySelectorAllqueryAll 和 querySelectorAll 有什么区别 【发布时间】:2014-06-09 18:58:31 【问题描述】:definitions from the DOM Standard 似乎几乎一模一样,我不明白其中的区别。
queryAll
和 querySelectorAll
有什么区别。
DOM 标准的求值逻辑如下,但我不够聪明,看不懂。
query
& queryAll
要将相对选择器字符串 relativeSelectors 与集合匹配,请运行以下步骤:
让 s 是从 relativeSelectors 中针对 set 解析相对选择器的结果。 [选择器]
如果 s 失败,则抛出 javascript TypeError。
返回使用 :scope 元素集评估选择器 s 的结果。 [选择器]
query(relativeSelectors) 方法必须返回运行匹配相对选择器字符串relativeSelectors 与由上下文对象组成的集合的第一个结果,如果结果为空列表,则返回null。
queryAll(relativeSelectors) 方法必须返回一个 Elements 数组,该数组使用运行结果将相对选择器字符串 relativeSelectors 与由上下文对象组成的集合相匹配。
querySelector
& querySelectorAll
要将选择器字符串选择器与节点进行范围匹配,请运行以下步骤:
让 s 成为解析选择器选择器的结果。 [选择器]
如果 s 失败,则抛出 JavaScript TypeError。
使用作用域根节点和作用域方法范围过滤,返回针对节点根计算选择器 s 的结果。 [选择器]。
querySelector(selectors) 方法必须返回针对上下文对象运行范围匹配选择器字符串选择器的第一个结果,如果结果为空列表,则返回 null。
querySelectorAll(selectors) 方法必须返回针对上下文对象运行范围匹配选择器字符串选择器的静态结果。
【问题讨论】:
【参考方案1】:2016 年更新
queryAll
已从 DOM 规范中删除
目前queryAll
和querySelectorAll
之间最重要的区别是queryAll
(以及query
)已从 DOM 规范中删除。
DOM 规范的当前版本位于:
http://dom.spec.whatwg.org/注意:https://www.w3.org/TR/dom/ 是 DOM 标准的过时分支 (有关更多信息,请参阅 WHATWG Wiki 和 the comment by Domenic 上的 Fork tracking)。
最后提及
包含query
和queryAll
的最新版本于2016 年3 月15 日发布:
删除
下一个版本不会在任何地方提及query
或queryAll
:
当前规格
query
或 queryAll
的所有出现
在 DOM 标准 were commented out 中,由 Anne van Kesteren 于 2016 年 3 月 29 日撰写。
当前的 DOM 规范(截至 2016 年 7 月)根本没有提及 query
或 queryAll
:
querySelector
和 querySelectorAll
在部分
4.2.6 Mixin ParentNode.
目前看来唯一可靠的API是querySelector
和querySelectorAll
(有关更多详细信息,请参阅 this answer)并根据 this discussion on GitHub query
和 queryAll
在浏览器中实现内置的 JavaScript 子类之前将不可用,即使那样它也不太可能返回实时Elements[] 数组,如the answer by BoltClock 中所述。
浏览器支持
截至 2016 年 6 月,MDN 上没有提及 query
和 queryAll
:
另一方面,querySelector
和 querySelectorAll
有据可查并得到广泛支持:
querySelector
/querySelectorAll
的浏览器支持根据 Can I use 截至 2016 年 6 月:
(有关最新信息,请参阅:http://caniuse.com/queryselector)
没有关于query
和queryAll
的支持信息。
更多信息
有关querySelector
和querySelectorAll
的使用和浏览器支持的更多信息,另请参阅this answer。
【讨论】:
您的链接都指向最新的 DOM 标准的过时分支dom.spec.whatwg.org。有关详细信息,请参阅wiki.whatwg.org/wiki/Fork_tracking。 (我们一再要求 W3C 停止复制和重新命名我们的规范,但他们没有。) @Domenic 感谢您提供信息。我更新了答案,现在所有链接都指向 dom.spec.whatwg.org,并且我在 w3c.org 上添加了关于过时分叉的注释。我不知道 w3c fork 已经过时了。感谢您指出。 @Domenic:我注意到规范根本没有提到相对选择器。是否有任何计划允许 querySelector 和 querySelectorAll 接受相对选择器?我很高兴完全删除了令人困惑的新名称,但我不喜欢每次都必须在我的向下钻取选择器前面加上 :scope。 @Domenic:没关系 - 我发现让 qSA 接受相对选择器会破坏当前的行为(参见element.querySelectorAll('E F')
与 element.querySelectorAll(':scope E F')
)。我现在明白为什么首先添加了新方法......
@BoltClock 我是否正确理解 qSA
与 :scope
放置在选择器的开头“修复”该行为,即它的行为与预期的一样(仅选择 @ 的后代987654380@)?【参考方案2】:
query()
和 queryAll()
接受相对选择器字符串,而 querySelector()
和 querySelectorAll()
不接受。相对选择器基本上是一个选择器,它可能是部分的并以组合器开头:
var parentNode = document.getElementById('parentNode'); // document.querySelector('#parentNode');
// Find .childNode elements that are direct descendants (children) of parentNode
// This cannot be done with querySelectorAll() using the existing reference to parentNode
parentNode.queryAll('> .childNode');
// querySelectorAll does allow getting all descendants of parentNode though
parentNode.querySelectorAll('.childNode');
但更重要的是,queryAll()
返回一个 live Elements[]
数组,而 querySelectorAll()
返回的 NodeList
是静态的,这意味着该列表中的节点在更改时不会更新制作它们各自的 DOM 元素。
就它们的功能而言,query()
和 queryAll()
可能更类似于在 Selectors API level 2 中定义的 find()
和 findAll()
— 您还可以在其中找到相对选择器的定义 — 因为两者方法组接受并使用相对选择器。请注意,findAll()
也返回一个静态的NodeList
,因此它们仍然不完全相同。
【讨论】:
添加每个函数返回的内容也很重要。一个返回一个Elements
数组,其中包含活动节点,另一个返回一个静态NodeList
。
@OozeMeister:好点子。这也是queryAll()
与findAll()
不同的原因。我将编辑我的答案。
感谢您的解释。请注意,query()
和 queryAll()
的当前 polyfill barberboy/dom-elements 不支持相对选择器。 jsbin & github issue
更新:barderboy/dom-elements 现在支持相对选择器! jsbin
@Nux:不,不是。这样做是将 .childNode 元素与恰好与 parentNode 引用具有相同标记名称的父元素匹配,这根本不意味着它们是 parentNode 的子元素。例如,如果 parentNode 是一个 div 并且它的 .childNode 后代是嵌套在其中的另一个 div 的子节点,这样整个结构可以由选择器 div#parentNode > div > .childNode
表示,则该语句将匹配该 .childNode,即使它是不是父节点的子节点。 qSA 等效项为 parentNode.querySelectorAll(':scope > .childNode');
。以上是关于queryAll 和 querySelectorAll 有啥区别的主要内容,如果未能解决你的问题,请参考以下文章