我有以下结构
<ul id="tabs" class="nav nav-tabs">
<li><a href="#aaa" hashval="aaa">AAA</a></li>
<li><a href="#bbb" hashval="bbb">BBB</a></li>
<li><a href="#ccc" hashval="ccc">CCC</a></li>
<li><a href="#ddd" hashval="ddd">DDD</a></li>
</ul>
现在我通过以下代码操作锚标记,并且工作正常。
$('#tabs a[href="#ddd"]').tab('show');
我正在使用pycharm,它通过说“带ID选择器的前言”为该行添加警告。单击它时,pycharm将更改为以下
$('#tabs').find('a[href="#ddd"]').tab('show');
两者都运转良好,但我不明白其中的区别。
两者之间有什么区别或更具体地说$('#tabs a[href="#ddd"]')
和$('#tabs').find('a[href="#ddd"]')
之间的区别是什么?
答案 0 :(得分:52)
$("#tabs a")
从从右到左进行评估 - 这是Sizzle选择器引擎和querySelectorAll
的原生方向 - 即首先找到 all 页面中的锚元素,然后将其缩小到#tabs
下的那些。
$("#tabs").find("a")
- 更直观地 - 从从左到右评估,即首先找到#tabs
,然后仅下面的锚点元素
显然,后者会产生better performance,但只会累积显着;也就是说,如果您运行数千个查询。否则,差异可以忽略不计。
答案 1 :(得分:7)
如"Increase Specificity from Left to Right"中所述:
对jQuery的选择器引擎有一点了解很有用。有用 从最后一个选择器开始,在旧浏览器中,查询如:
$("p#intro em");
将每个em元素加载到一个数组中。它然后起作用的父母 每个节点并拒绝那些无法找到p#intro的节点。查询 如果您有数百个em标签,效率会特别低 页面。
根据您的文档,可以通过检索来优化查询 首先是最合格的选择者。然后它可以用作起点 儿童选择器的要点,例如
$("em", $("p#intro")); // or $("p#intro").find("em");
但Test case说$("#tabs > a")
最快
答案 2 :(得分:5)
第二个更快。 原因是jQuery的选择器引入Sizzle,它将选择从右遍历到左,而不是相反。
这意味着选择器
$('#tabs a[href="#ddd"]')
首先在DOM文档中查询标记,该标记包含设置为href
的属性 #ddd
。然后它会过滤掉所有这些,以获得每个<a>
标签。最后,它遍历每个节点的DOM树,试图找到父#tabs
。
想象一个带有href="#ddd"
的1.000个标签的网站,这将是多么缓慢。
THEN
另一个变量pycharm建议,首先找到一个元素#tabs
。这非常快,因为jQuery可以使用本机浏览器方法getElementById()
。拥有此节点后,它可以遍历 down 以查找匹配的所有标记。通过这样做,不需要检查all tags in the whole DOM-tree
。只有那些实际上在#tabs
。
有关详细信息,请查看this page in the documentation。
答案 3 :(得分:2)
效果相同:找到值#ddd
为href
的锚点,并且是#tabs
的后代。不同之处在于实现这一目标的方式。
第一个解决方案找到锚点,然后检查它们是否是#tabs
的后代。
第二个解决方案找到#tabs
,然后找到锚点。当然,哪个应该更快。
答案 4 :(得分:2)
.find()
性能更好
$('#tabs a[href="#ddd"]').tab('show');
,这就是pycharm使用.find()
$('#tabs').find('a[href="#ddd"]').tab('show');
http://vaughnroyko.com/the-real-scoop-on-jquery-find-performance/
答案 5 :(得分:2)
不同之处在于find()允许您根据您已经做出的选择过滤一组元素,如果是这样的话,返回元素数组。
$('#tabs').find('a[href=“#ddd”]');
这是一种更具体的搜索元素的方式因为你说“嘿,转到#tabs
然后找到我所有a[href=“#ddd”]
而不是你说”嘿,找我全部这个人$('#tabs a[href=“#ddd”]')
在我拥有的所有代码中。“
答案 6 :(得分:1)
虽然在大多数情况下,性能是唯一的区别,但是方法上的差异也会影响代码的结果,具体取决于您使用的选择器。
例如,$("table").find("tr:even").addClass("even");
会将“even”类添加到返回的每个单独表中的每隔一行。因此,如果“even”类使行中的文本变为粗体,并且您有两个表,每个表有3行,您将得到以下结果:
这是表一,第1行
这是表一,第二行
这是表一,第3行
这是表二,第1行
这是表二,第2行
这是表二,第3行
在这两种情况下,每个表的第1行和第3行(即“偶数”行...不会让我开始使用JQuery的even
过滤器,选择奇数行......)粗体显示。
另一方面,$("table tr:even").addClass("even");
会将“偶数”类添加到所有表中的整个行组中的每一行中。
这是表一,第1行
这是表一,第二行
这是表一,第3行
这是表二,第1行
这是表2,第2行
这是表二,第3行
在这种情况下,第二个表的第1行和第3行实际上是整个<tr>
元素组的第4行和第6行,因此它们被视为“奇数”。但是,第二个表的第二行是整个集合的第5行,因此被视为“偶数”并加粗。