jQuery:包含x的最高级元素



我正在寻找一种方法来选择包含某个元素的元素,然后过滤结果以仅获得最高级别。很难解释,但用一个例子让它变得更容易:

<div id="one">
    <div id="two">
        <div id="three" class="find-me"></div>
    </div>
</div>
<div id="four">
    <div id="five" class="find-me"></div>
</div>

在本例中,我希望我的集合包含# 1和# 4。如果我尝试这样做:

var elements = $('div').has('.find-me');

我得到了元素# 1,# 2和# 4。

注意:"最高级"指的是第一个选择器中最顶层的元素,在本例中是$('div')

好吧,什么是highest level的定义,是有点模糊,因为在实践中,如果有任何.find-me在您的页面最高级别的父将是html标签!这是没用的。

通过更具体地定义你的问题,你可以为这个highest-definition提出一个更清晰的定义,例如说the farthest div parent等,为了遍历元素的父元素,你可以使用.parents().closest()方法。

var farthestDiv = $(".find-me").parents("div").last();

显然,如果find-me不止出现一次,那么需要在.each()循环中运行它。

见下面的例子:http://jsfiddle.net/GsQDb/3/

假设这里的"top level"是指body标签的直接后代,那么您可以使用这一行。它查找具有.find-me类的所有对象,然后在父类中搜索作为body标记后代的标记(这将是顶层)。

$(".find-me").parents("body > *")

您可以在这里看到它的工作原理:http://jsfiddle.net/jfriend00/9LF6u/

这样做有以下优点:

  1. 任何类型的标签都可以是顶级标签(不只是div)
  2. 它应该是一个更快的方法来做到这一点,因为它找到.find-me对象(这将是一个快速的操作在大多数浏览器内部通过getElementsByClassName),只是走到他们的父层次结构。
  3. 它自动处理重复,所以一个给定的顶级项目将永远不会被列出超过一次。
  4. 如果你想改变顶层的定义(例如容器对象),你可以改变传递给.parents(selector)方法的选择器来反映这个变化。

使用filter过滤掉第一个选择器后不匹配的元素。例子:

var elements = $('div.find-me').filter(function(idx){ 
    return !$(this).parents('div.find-me').length;
});

这将做你想要的,它将首先找到元素,然后找到最高的元素,并创建一个jQuery对象的最高元素。

var elements = $('div.find-me'), highest = [];
elements.each( function(){
var parent = this, body = document.body;
    while( parent && parent.parentNode !== body ) {
    parent = parent.parentNode;
    }
    if( $.inArray( parent, highest ) < 0 ) {
    highest.push( parent );
    }
});
highest = jQuery( highest );

jsfiddle:

http://jsfiddle.net/D3jC8/2/

如果你把它们放在一个大的容器div中,你可以使用:

$('.container div.find-me').parents($('.container').children());

这应该可以工作,虽然我现在没有机会测试它。

如果没有,请告诉我,因为还有更复杂的解决方案。

你能给最顶端的div分配一个类吗?如果是这样,你可以这样做:

var elements = $("div.topMost").has(".find-me");
$(".find-me").map(function() {
  return $(this).parents("div").last().get();
});

最新更新