简体   繁体   English

$('#tabs a')和$('#tabs')之间的区别.find('a')

[英]Difference between $('#tabs a') and $('#tabs').find('a')

I have following structure 我有以下结构

<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>

Now I am operating on the anchor tag by following code and which is working fine. 现在我通过以下代码操作锚标记,并且工作正常。

$('#tabs a[href="#ddd"]').tab('show');

I am using pycharm which adds warning for the line by saying "Preface with ID selector". 我正在使用pycharm,它通过说“带ID选择器的前言”为该行添加警告。 When I click it, pycharm changes to following 单击它时,pycharm将更改为以下内容

$('#tabs').find('a[href="#ddd"]').tab('show');

Both are working fine but I don't understand the difference. 两者都工作正常,但我不明白其中的区别。

What is the difference in both or more specifically what is difference between $('#tabs a[href="#ddd"]') and $('#tabs').find('a[href="#ddd"]') ? 两者之间有什么区别或者更具体地说$('#tabs a[href="#ddd"]')$('#tabs').find('a[href="#ddd"]')之间的差异$('#tabs a[href="#ddd"]') $('#tabs').find('a[href="#ddd"]')

$("#tabs a") evaluates from right to left - which is the native direction of both Sizzle selector engine and querySelectorAll - ie first it finds all of the anchor elements in the page and then narrows it down to those under #tabs . $("#tabs a") 从右到左进行评估 - 这是Sizzle选择器引擎和querySelectorAll的原生方向 - 即首先它找到页面中的所有锚元素,然后将其缩小到#tabs下的那些。

$("#tabs").find("a") evaluates - more intuitively - from left to right , ie first it finds #tabs , and then only the anchor elements under it. $("#tabs").find("a") 从左到右评估 - 更直观 - 即首先找到#tabs ,然后找到它下面的锚元素。

Clearly the latter would yield better performance , but it would only be noticeable accumulatively; 显然,后者会产生更好的表现 ,但只会累积显着; that is, if you run thousands of queries. 也就是说,如果您运行数千个查询。 Otherwise, the difference is negligible. 否则,差异可以忽略不计。

As stated in "Increase Specificity from Left to Right" : “从左到右增加特异性”中所述

A little knowledge of jQuery's selector engine is useful. 对jQuery的选择器引擎有一点了解很有用。 It works from the last selector first so, in older browsers, a query such as: 它首先从最后一个选择器开始工作,因此在旧版浏览器中,查询如下:

 $("p#intro em"); 

loads every em element into an array. 将每个em元素加载到一个数组中。 It then works up the parents of each node and rejects those where p#intro cannot be found. 然后它会处理每个节点的父节点并拒绝那些无法找到p#intro的节点。 The query will be particularly inefficient if you have hundreds of em tags on the page. 如果页面上有数百个em标记,则查询效率会特别低。

Depending on your document, the query can be optimized by retrieving the best-qualified selector first. 根据您的文档,可以通过首先检索最佳限定选择器来优化查询。 It can then be used as a starting point for child selectors, eg 然后它可以用作子选择器的起点,例如

 $("em", $("p#intro")); // or $("p#intro").find("em"); 

But Test case says $("#tabs > a") would be fastest 测试用例表示$("#tabs > a")将是最快的

The second one is MUCH quicker. 第二个更快。 The reason being jQuery's selector enginge Sizzle , which traverses the selection from right to left , not vice versa. 原因是jQuery的选择器引入了Sizzle ,它从右遍历选择,而不是相反。

This means that the selector 这意味着选择器

$('#tabs a[href="#ddd"]')

First queries the DOM document for a tag, which contains the attribute href set to #ddd . 首先在DOM文档中查询标记,该标记包含设置为#ddd属性 href It then filteres out all of them, to get every one that is a <a> tag. 然后它会过滤掉所有这些,以获得每个<a>标签。 At last, it traverses up the DOM tree for every node, trying to find a parent #tabs . 最后,它遍历每个节点的DOM树,试图找到父#tabs

Imagine a site with 1.000 tags with href="#ddd" , how tremendously slow that would be. 想象一个拥有1.000标签的网站,其中href="#ddd" ,这将是多么缓慢。

THEN. 然后。

The other variation pycharm suggest, is to first locate a element #tabs . pycharm提出的另一个变体是首先找到一个元素#tabs This is super-quick, since jQuery can utilize the native browser method getElementById() . 这非常快,因为jQuery可以使用本机浏览器方法getElementById() Having this node, it can traverse down to find all tags that are matching. 拥有此节点后,它可以向下遍历以查找匹配的所有标记。 By doing this, not all tags in the whole DOM-tree , needs to be checked. 通过这样做,不需要检查all tags in the whole DOM-tree Only those which actually are in #tabs . 只有那些实际上在#tabs

For further information, please check out this page in the documentation . 有关详细信息,请查看文档中的此页面

The effect is the same: Find anchors that have the value #ddd as href and are a descendant of #tabs . 效果是相同的:找到值为#dddhref锚点,它们是#tabs的后代。 The difference lies in the way to achieve this. 不同之处在于实现这一目标的方式。

The first solution finds the anchors and then checks if they are a descendant of #tabs . 第一个解决方案找到锚点,然后检查它们是否是#tabs的后代。

The second solution finds #tabs and then finds the anchors. 第二个解决方案找到#tabs ,然后找到锚点。 Which should be faster, of course. 当然,哪个应该更快。

.find() is better performance wise as compared to your first selector 与第一个选择器相比, .find()的性能更好

$('#tabs a[href="#ddd"]').tab('show');

, that is why pycharm changes it to the selector using .find() ,这就是pycharm使用.find()将其更改为选择器的.find()

$('#tabs').find('a[href="#ddd"]').tab('show');

http://vaughnroyko.com/the-real-scoop-on-jquery-find-performance/ http://vaughnroyko.com/the-real-scoop-on-jquery-find-performance/

The difference is that find() allows you to filter on a set of elements based on a selection you've already made, returning and array of elements if that's the case. 不同之处在于find()允许您根据已经做出的选择过滤一组元素,如果是这种情况,则返回元素数组。

$('#tabs').find('a[href=“#ddd”]');

And it's a more specific way of searching for an element because you are saying "hey, go to #tabs and find me all a[href=“#ddd”] in there" instead of you saying "hey, find me all this guys $('#tabs a[href=“#ddd”]') in all the code that i have." 而且这是一种更具体的搜索元素的方式因为你说“嘿,去#tabs并在那里找到我所有a[href=“#ddd”] ”而不是你说“嘿,找到我所有这些人$('#tabs a[href=“#ddd”]')在我拥有的所有代码中。“

While, in most cases, the performance is the only difference, the difference in approach can also affect the outcome of your code, depending on what selectors you are using. 虽然在大多数情况下,性能是唯一的区别,但是方法的差异也会影响代码的结果,具体取决于您使用的选择器。

For example, $("table").find("tr:even").addClass("even"); 例如, $("table").find("tr:even").addClass("even"); will add the "even" class to the every other row in each individual table that gets returned. 将“even”类添加到返回的每个单独表中的每隔一行。 So, if the "even" class makes the text in the rows bold and you have two tables, each with 3 rows, you would get the following result: 因此,如果“even”类使行中的文本变为粗体,并且您有两个表,每个表有3行,您将得到以下结果:


this is table one, row 1 这是表1,第1行

this is table one, row 2 这是表1,第2行

this is table one, row 3 这是表一,第3行


this is table two, row 1 这是表2,第1行

this is table two, row 2 这是表2,第2行

this is table two, row 3 这是表二,第3行


In both cases, the 1st and 3rd row of each table (ie, the "even" rows . . . don't get me started on JQuery's even filter, selecting the odd rows . . .) are bolded. 在这两种情况下,每个表的第1行和第3行(即“偶数”行...不会让我开始使用JQuery的even过滤器,选择奇数行......)都是粗体。

On the other hand, $("table tr:even").addClass("even"); 另一方面, $("table tr:even").addClass("even"); will add the "even" class to every other row in the entire group of rows from all tables combined. 将“even”类添加到所有表组合的整个行组中的每一行。


this is table one, row 1 这是表1,第1行

this is table one, row 2 这是表1,第2行

this is table one, row 3 这是表一,第3行


this is table two, row 1 这是表2,第1行

this is table two, row 2 这是表2,第2行

this is table two, row 3 这是表二,第3行


In this situation, the the 1st and 3rd row of second table are actually the 4th and 6th rows of the entire group of <tr> elements, so they are treated as "odd". 在这种情况下,第二个表的第1行和第3行实际上是整个<tr>元素组的第4行和第6行,因此它们被视为“奇数”。 The 2nd row of the second table, however, is the 5th row of the entire collection and, thus, is treated as "even" and is bolded. 但是,第二个表的第二行是整个集合的第5行,因此被视为“偶数”并加粗。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM