Reputation: 7853
I have a DOM structure like this:
<div id="one" class="center">
<div id="two" class="wrap">
<div id="three" class="west">
<div id="four" class="center"></div>
</div>
<div id="five" class="center"></div>
</div>
</div>
It's about a automatically generated layout. Now i'd like to adress specific elements like a path but ignore all "wrap" elments in between.
For example:
center/center
should yield #five
center/west
should yield #three
center/west/center
should yield #four
I tried using two different selectors:
$('.center .center')
but instead of returning #five
it returns [#four, #five]
which is of course correct for this selector but not what i want here.
$('.center > .center')
this one returns #five
which is what i want but when i try to apply the same form of selector to (2.) or (3.) like this: $('.center > .west')
it will return nothing because of the .wrap
element in between.
So a long explanation for a simple question. Is there a way to get something like:
$('.center .center').lowestDepth()
Upvotes: 1
Views: 149
Reputation: 669
EDIT2: Sorted it.
EDIT: Just noticed it's not actually doing it the way I expected it :D will try to improve and update.
I've come up with a solution. It works for the current structure, but haven't tested with different structure:
function findStuff(arg1, arg2, arg3) {
if ($('.' + arg1).children('.' + arg2).length == 0) {
if ($('.' + arg1).children().first().attr('class') != arg2) {
if(arg3 == null) {
findStuff($('.' + arg1).children().first().attr('class'), arg2, null);
} else {
findStuff($('.' + arg1).children().first().attr('class'), arg2, arg3);
}
}
} else {
if(arg3 != null) {
findStuff(arg2, arg3, null);
} else {
$('.' + arg1).children('.' + arg2).css('background-color', 'red');
}
}
}
$(document).ready(function () {
findStuff("center", "center", null);
});
https://jsfiddle.net/vhs4c0cp/1/
First it looks for the first 2 sets of arguments and if there is a third argument, once the first element matching the original arg1 and arg2 is found, it will call itself with 2 new arguments.
Upvotes: 1
Reputation: 4509
There is not really a built-in function in jQuery to do this out of the box, the .closest - method is somewhat similar, it just traverses up the DOM.
What you could do is call a function recursively and filter on the direct childs of an element and do so, until you found your closest element.
I made a quick jsFiddle to show this.
function lowestDepth(selector, elem){
var childElements = elem.children();
var filteredElements = childElements.filter(selector);
if(filteredElements.length === 0){
return lowestDepth(selector, childElements);
} else {
return filteredElements.eq(0);
}
}
var elements = $('#one .west');
var ldelement = lowestDepth('.center', elements);
.children()
traverses one level down in the DOM and returns matched elements, you could even pass a selector to it to filter elements in the same step, but I think the example is clearer this way.
The elements
variable defines the "starting point", the first argument passed is the selector that the function looks for.
Note that this is a quick example to show you the idea behind this, this could be polished and optimized.
Upvotes: 1