我正在寻找一种方法来选择包含某个元素的元素,然后过滤结果以仅获得最高级别。很难解释,但用一个例子让它变得更容易:
<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/
这样做有以下优点:
- 任何类型的标签都可以是顶级标签(不只是div)
- 它应该是一个更快的方法来做到这一点,因为它找到
.find-me
对象(这将是一个快速的操作在大多数浏览器内部通过getElementsByClassName
),只是走到他们的父层次结构。 - 它自动处理重复,所以一个给定的顶级项目将永远不会被列出超过一次。
- 如果你想改变顶层的定义(例如容器对象),你可以改变传递给
.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();
});