0

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

例子:

每个功能

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

选择器

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

两者都做同样的事情,但是这样做有什么意义吗?

4

4 回答 4

2

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

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

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


例如,除了使用选择器来选择ul嵌套在s 中li的 s 并向上遍历一个级别,您还可以使用对包含 s 的 s.each应用逻辑测试:liul

$('#mainNav > ul > li').each(function() {
   if ($(this).children('ul').length) {
       $(this).addClass('hasSub'); 
   }
});

虽然这更冗长,但它基本上做同样的事情。


正如评论和Bergi的回答中提到的那样,出于代码高尔夫的目的,这li:has(ul)将是实现这一目标的最短方法,而无需.closest()致电。虽然:has与子选择器本质上不同 -:has寻找后代(不同级别的深度)同时>寻找直接的孩子(1级深度) - 我相信它应该适用于这个特定的用例。

于 2013-05-26T23:05:37.340 回答
1

两者都做同样的事情,但是这样做有什么意义吗?

是的。第二个更短且性能更高(因为.each无论如何都会从这些方法内部调用)。绝对没有理由在each此处合并 - 它与使用.each(function(){ $(this).addClass(…); }).

顺便说一句,也许您正在寻找:hasselector,这将进一步缩短您的表达:

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

如果您想确定ul是列表项的直接子项,您仍可能需要使用评论中的建议(theclosest(li)始终是 ul 的直接父项):

$('nav#mainNav > ul > li > ul').parent().addClass('hasSub');
于 2013-05-26T23:02:55.163 回答
1

您可以改用 jQuery .has()方法,这样读起来会更好:

var addClass = $('nav#mainNav > ul > li').has('ul').addClass('hasSub');
于 2013-05-26T23:04:20.557 回答
1

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

但是,如果您需要基于每个元素执行多个操作,则可能需要使用.each(). 例如

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

可以.each()不用使用来写这个.end()

$('nav#mainNav > ul > li > ul')
    .closest('li').addClass('hasSub').end()
    .closest('.otherClass').removeClass('.otherClass');

但我相信.each()会使意图更清晰(尽管像这样的缩进也做得很好)。

于 2013-05-26T23:04:27.813 回答