I'm looking for a way to select elements that contain a certain element and then filter the results to get only the highest level. Difficult to explain but made easier with an example:
<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>
In this case, I would want my set to contain #one and #four. If I try to do something like this:
var elements = $('div').has('.find-me');
I get elements #one, #two and #four.
Note: By 'highest level' relates to the topmost element in the first selector, $('div') in this case.
Well the definition of what the highest level is, is a bit ambiguous because in practice if there is any .find-me in your page the highest level parent would be html tag! which is useless.
By defining your problem more specifically you can come up with a clearer definition for this highest-definition and for example say the farthest div parent et. and in order to traverse parents of an element you can use .parents() and .closest() methods.
var farthestDiv = $(".find-me").parents("div").last();
obviously if you have more than one occurances of find-me you need to run this in a .each() loop.
see an example here: http://jsfiddle.net/GsQDb/3/
Assuming by "top level", you mean a direct descendant of the body tag, you can use this one liner. It finds all objects with a .find-me class, then searches the parents for a tag that is a descendant of the body tag (which will be the top level).
$(".find-me").parents("body > *")
You can see it work here: http://jsfiddle.net/jfriend00/9LF6u/
This has these advantages:
.find-me objects (which will be a fast operation internally in most browsers via getElementsByClassName) and just walks up their parent hierarchy..parents(selector) method to reflect that change.use filter to filter out elements that don't match what you want after your first selector. example:
var elements = $('div.find-me').filter(function(idx){
return !$(this).parents('div.find-me').length;
});
This will do what you want, it will find the elements first and then find the highest elements of those and create a jQuery object of the found highest elements.
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/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With