2010-05-24 46 views
5

我们可以使用closest(selector)来查找匹配选择器的第一个祖先元素。它将向上移动 DOM树,直到它找到匹配的选择器。但是,如果我想要在下调 DOM树,直到它找到匹配选择器?有没有这样做的jQuery功能?还是我需要使用广度优先搜索来实现?如何用jQuery找到最接近的后代(匹配选择器)?

举个例子。对于下面的DOM树,

<div id="main"> 
    <div> 
     <ul><!-- I want to match this ul --> 
      <li> 
       <ul><!-- but not this ul --> 
       </ul> 
      </li> 
     </ul> 
     <ul><!-- and match this ul --> 
     </ul> 
    </div> 
</div> 

如何做类似$('#main').closestDescendants('ul')

回答

1

像这样的东西可能就足够了:

$('#main ul:not(#main ul ul)') 

如果你需要更多的东西,然后准确您可以使用each()来迭代元素列表,计算到#main的最短路径,并过滤掉路径比这更长的元素。

+0

这要求您有一些锚点#main,而不是将其定位到某个上下文元素。有没有一种方法可以编写它,以便它只相对于一个范围,并且它不匹配匹配基于高于上下文范围的祖先的元素? – 2011-03-06 01:42:59

0

您想要匹配的元素是否始终是div的孩子?如果是这样,你可以使用.children('ul')语法来匹配。这将是最好把一个ID /类的DIV,这样你就可以做到以下几点...

$('#menu').children('ul'); 

<div id="main"> 
    <div id="menu"> 
     <ul><!-- I want to match this ul --> 
      <li> 
       <ul><!-- but not this ul --> 
       </ul> 
      </li> 
     </ul> 
     <ul><!-- and match this ul --> 
     </ul> 
    </div> 
</div> 
+0

$('#main')和它最近的ul后代之间的高低差别可能会有所不同,并且只有$('#main')具有确定的id。 – powerboy 2010-05-24 03:41:27

0

我有同样的问题,需要一个更通用的解决方案,所以我写了一个函数,并决定把它打包为jQuery plugin。我知道这个帖子很老,但请看看,让我知道你的想法。

1

因此,最接近的儿童插件链接被打破了我。这里有一个实现:

$.fn.nearest = function(selector) { 
    var nearest = $(), node = this, distance = 10000; 
    node.find(selector).each(function(){ 
     var n = $(this), 
      d = n.parentsUntil(node).size(); 
     if (d < distance) { 
      distance = d; 
      nearest = n; 
     } else if (d == distance) { 
      nearest = nearest.add(this); 
     } 
    }); 
    return nearest; 
}; 
+1

在jQuery的传统中,如果选择器失败,返回undefined并不是标准。最好返回一个空的jQuery对象。在上面的代码片段中,正确初始化'nearest',即:用'var nearest = $()'替换'var nearest'。 – eleotlecram 2012-10-26 11:15:12

+0

你说得对,很好。 – 2012-10-26 15:39:06

+0

jQuery的前一个插件数据库丢失了。 “clostestChild”插件现在可以在名为“closestDescendant”的新插件数据库中使用http://plugins.jquery.com/closestDescendant/ – TLindig 2013-04-09 20:46:23