在阅读关于jQuery Selector性能的StackOverflow帖子时,我一遍又一遍地阅读同样的事情,说jQuery使用自下而上或从右到左方法选择器。
以此为例......
$("#dnsTitle a.save").removeClass("disabled");
根据我一直在阅读的内容,使用它更好的表现......
$("a.save #dnsTitle").removeClass("disabled");
我遇到的问题是这根本不起作用!有人可以澄清做选择器的最佳方法吗?
我正在开发一个现有项目,它有一些非常长的选择器,我正试图在可能的地方改进它们,但似乎我得到的信息不好或过时了。我正在使用jQuery 2.0
答案 0 :(得分:8)
“Bottom Up / Right to Left / Leaf to Root”的概念仅与选择器解析器的实现有关,而与使用中的选择器的顺序无关。
从使用角度来看,选择器从左到右“读取”,第一个选择器是你的根,后续的选择器是你的后代。返回与最后一个选择器匹配的元素。所以:
#dnsTitle a.save
- 查找ID为dnsTitle
的元素,并从中查找具有类a
的后代save
元素。您最终会获得a
个save
个元素。
a.save #dnsTitle
- 查找具有类a
的{{1}}元素,然后找到ID为save
的后代。您最终会得到身份dnsTitle
现在从解析的角度来看,解析选择器字符串有两种常用方法,它们是“自上而下”和“自下而上”:
自上而下/根到叶子/从左到右
如果您已经完成了数据结构课程,那么这就是您通常解析树的方法。您可以找到要启动的节点,这将是您的第一个选择器。然后,您将找到后续节点。
这种方法的一个问题是它使用递归方法并使用大量内存,尤其是在树很大的情况下。此外,回溯问题是一个问题,因为后续的选择器是后代,并且匹配的深度可能不同。下一个选择器可能匹配伟大的^ N 孙子。递归走了N步,找到了那个伟大的^ N孩子,并采取N步骤返回。
自下而上/从右到左/离开根目录
使用这种方法,解析器会查找与最后一个选择器匹配的所有元素,最后会得到一个匹配数组。使用该匹配数组,如果它们与之前的前一个选择器匹配,则对它们进行过滤。
这种方法的优点是您可以使用固定数组,而不是可变深度树。此外,您正在进行线性过滤,因为在这种情况下,节点只能有一个父节点,而自上而下处理多个子节点。这也意味着你只需要循环来完成工作,而不是递归。一个循环可以遍历每个结果,另一个循环可以遍历每个祖先,如果它与之前的前一个选择器匹配。