I am looking to select the common parent of multiple nested elements for which I only know the inner text.
For example, in the following code:
<unknown>
<unknown class="unknown">
....
<unknown>
<unknown>Sometext</unknown>
</unknown>
<unknown>
<unknown>Sometext</unknown>
</unknown>
<unknown>
<unknown>Sometext</unknown>
</unknown>
....
</unknown>
</unknown>
I would like to get the closest element (common parent) that has class unknown in this scenario. I do not know the actual tags or class names. I only know that the nest element contains the "Sometext". I know this can be done through a loop using jQuery/Javascript, but is there a CSS selector that I can use with jQuery to find this? I tried using a combination of closest(), parents(), parentsUntil() but I can't seem to get to this element.
Thank you!
First, you need to ensure you only match the leaf nodes (nodes with no child nodes), so use:
:not(:has(*))
So to find all the exact matches (just the leaf nodes), use:
var matches = $(':not(:has(*))').filter(function () {
return $(this).text() == "Sometext";
});
or just using a combined filter on all elements (with an added check for 0 children):
var matches = $('*').filter(function () {
return !$(this).children().length && $(this).text() == "Sometext";
});
Note: I have not yet tested which of these two options is fastest.
Then you need to find the first ancestor (of the first match), that contains all the matches:
var commonparent = matches.first().parents().filter(function () {
return $(this).find(matches).length == matches.length;
}).first();
JSFiddle: http://jsfiddle.net/TrueBlueAussie/v4gr1ykg/
Based on David Thomas' suggestion, here it is as a pair of jQuery extensions (commonParents()
and commonParent()
) that may be of future use for people:
To find all common parents of a jQuery collection use `commonParents()':
$.fn.commonParents = function (){
var cachedThis = this;
return cachedThis.first().parents().filter(function () {
return $(this).find(cachedThis).length === cachedThis.length;
});
};
JSFiddle: (commonParents): http://jsfiddle.net/TrueBlueAussie/v4gr1ykg/3/
To find the closest common parent of a jQuery collection use commonParent()
:
$.fn.commonParent = function (){
return $(this).commonParents().first();
};
JSFiddle: (commonParent): http://jsfiddle.net/TrueBlueAussie/v4gr1ykg/2/
Notes:
first()
in commonParent
with the commonParents
filter()
and it only calls the code in commonParents
until a first match is made, so commonParent
does not need to be made more efficient.