每个vs智能选择器

时间:2013-05-26 22:55:21

标签: javascript jquery

什么是更好的使用,它自己的每个功能或使用一些智能选择器来做同样的事情。

示例:

每项功能

$('nav#mainNav > ul > li > ul').each(function(){
   $(this).closest('li').addClass('hasSub'); 
});

SELECTOR

var addClass = $('nav#mainNav > ul > li > ul').closest('li').addClass('hasSub');

这两个都做同样的事情,但是有没有任何意义去做另一个?

4 个答案:

答案 0 :(得分:2)

当应用不同元素之间的逻辑时,应该使用显式迭代(.each)。否则,隐式迭代就可以了。

您的代码示例几乎与.each API页面完全相同:

  

注意:大多数返回jQuery对象的jQuery方法也会循环   通过jQuery集合中的元素集 - 一个已知的过程   作为隐式迭代。发生这种情况时,通常不需要   使用.each()方法显式迭代。


例如,您可以使用ul对{{1}应用逻辑测试,而不是使用选择器来选择嵌套在li内的.each并遍历一个级别。包含li s:

的s
ul

虽然这更加冗长,但它的确基本相同。


对于代码 - 高尔夫目的,正如评论和Bergi的回答中所提到的,$('#mainNav > ul > li').each(function() { if ($(this).children('ul').length) { $(this).addClass('hasSub'); } }); 将是实现此目的的最短途径,而无需li:has(ul)调用。虽然.closest()与子选择器基本上不相同 - :has查找后代(各种级别深),而:has查找直接子项(深度为1级) - 我相信它应该有效以及这个特定用例。

答案 1 :(得分:1)

  

这两个都做同样的事情,但是有没有任何意义去做另一个?

是。第二个更短,性能更高(因为.each在内部从这些方法调用)。绝对没有理由在这里加入each - 它与使用.each(function(){ $(this).addClass(…); })一样毫无意义。

是的,也许你正在寻找:has selector,这会更加缩短你的表达:

$('#mainNav > ul > li:has(ul)').addClass('hasSub');

如果您想确保ul是列表项的直接子项,您仍然可能希望使用评论中的建议(closest(li)始终是评论的直接父级。 UL):

$('nav#mainNav > ul > li > ul').parent().addClass('hasSub');

答案 2 :(得分:1)

您可以使用jQuery .has()方法,而不是更好地阅读:

var addClass = $('nav#mainNav > ul > li').has('ul').addClass('hasSub');

答案 3 :(得分:1)

大多数jQuery方法将对元素集合进行操作,并自动迭代,就像您使用.each()一样。因此,在这种简单的情况下,通常不会使用.each()

但是,如果您需要根据每个元素执行多个操作,则可能需要使用.each()。 E.g。

$('nav#mainNav > ul > li > ul').each(function () {
    $(this).closest('li').addClass('hasSub');
    $(this).closest('.otherClass').removeClass('.otherClass');
});

.each()

但我相信.end()使意图更清晰(尽管缩进,就像这样,也做得非常好)。