何时使用querySelectorAll

9

我写了一段示例代码

var as = toArray(document.getElementsByClassName("false")).filter(function (el) {
    return el.tagName === "A";
});

我在考虑将其替换为

var as = document.querySelectorAll("a.false");

现在阅读以下事实:

  • 假装浏览器支持不是问题(我们有 shim 和 polyfill)。
  • 假设你不是处于通用的 jQuery 思维模式中,你应该使用 QSA 来获取每个元素。
  • 我会写 qsa 而不是 document.querySelectorAll,因为我懒。

问题:我何时应该优先使用 QSA 而不是普通方法?

很明显,如果您正在执行 qsa("a")qsa(".class")qsa("#id"),那么您正在做错事,因为有更好的方法(按标记名称、按类名、按 ID)。

当然,qsa("div > p.magic") 也是一个明智的用例。

问题:但是 qsa("tagName.class") 是否是 QSA 的一个好用例呢?

另外还有一些叫做 NodeIterator 的东西。

我曾就 QSA vs NodeIterator 提出过问题。


顺便提一下,NodeIterator非常慢。 - Raynos
1
嗯,我认为在 getElementsByTagNameAndClassName() 可用之前,querySelectorAll("a.false") 是有意义且比从 toArray()filter() 的链式调用更易读的。 - Frédéric Hamidi
@FrédéricHamidi 另外一个 .filter 调用也慢得要死。 - Raynos
确实,除非有一个假设的 getElementsByTagNameAndClassName() 函数出现,否则你在 querySelectorAll() 之外没有太多选择,不是吗? - Frédéric Hamidi
3个回答

2

当getElementById、getElementsByName和getElementsByClassName无法正常工作时,应使用QSA,因为您的选择器较为复杂。

使用QSA与DOM解析取决于个人偏好以及您将要对返回的数据集进行的操作。


1
如果浏览器支持不是问题,我就会无处不用它。为什么要使用4种不同的方法 (...byId,...byTagName,...byClassName),如果你可以只使用一种。
QSA似乎较慢(... byId),但仍然只需要几毫秒甚至更少。大多数情况下,您只需要调用它几次,因此不是问题。当您遇到速度瓶颈时,您可以随时将QSA替换为适当的其他方法。

你所说的“慢”,是指慢了约两百倍。我已经知道对于简单选择器来说,QSA 是很蠢的(如上所述)。 - Raynos
1
@Raynos,你不应该只看它们相对的速度,而应该看一个调用需要多少毫秒。在FX7中getElementById只需要0.0001ms,而QSA则需要0.02ms。除非你需要选择成千上万个元素,否则最终用户不会注意到任何差异。 - Gerben
哇!毫秒很重要!0.02毫秒已经很慢了。那是20微秒的时间。最多我只想进行100微秒的计算。 - Raynos
为什么是100微秒?人类最多只能检测到200毫秒。因此,您可以执行大量的JS并仍允许引擎在200毫秒内重新绘制页面。 - Gerben
1
这完全取决于你在做什么。如果你只需要在一个静态页面上附加一些基本逻辑,那么使用几个 QSA 调用完全可以,并且会节省开发时间。如果你正在处理数千个 DOM 元素和一些复杂的逻辑,则必须考虑性能。我不会说做其中之一是“愚蠢”的,这只是取决于你的需求。 - Sasha Chedygov

0

请使用jsperf.com进行此类测试。 - Raynos
抱歉,这是链接:http://jsperf.com/qsa-vs-regular-js - Will

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接