I'm having a really hard time trying to figure out something which I believe should be relatively simple.
I need to get the next occurrence of a class (div.content), which could appear anwhere in the DOM
Below is some simplified markup which represents what I have:
<div class="container">
<div class="content">
Example content #1 <a href="#" class="next">Next</a>
</div>
<div class="content">
Example content #2 <a href="#" class="next">Next</a>
</div>
</div>
<div class="container">
<div class="content">
Example content #1 <a href="#" class="next">Next</a>
</div>
<div class="content">
Example content #2 <a href="#" class="next">Next</a>
</div>
</div>
Showing the next content
div within a given container
works fine, the problem comes when I try to get from the last content
div in a container
to the first content
div in the next container
.
A couple of important points:-
By default, only the first
content
div is visible, the rest are hidden, though I need a solution that would work if for instance the secondcontent
div in the fourthcontainer
is visible.Only one
content
div will ever be visible.
The only solution I've managed to come up with so far seems extremely cumbersome, although it does work.
$('.next').click(function() {
$theContent = $(this).parent('.content');
$theContent.hide();
if ($theContent.next('.content').length) {
$theContent.next('.content').show();
} else if ($theContent.parent('.container').next('.container')
.children('.content').length
) {
$theContent.parent('.container').next('.container')
.children('.content:first').show();
} else {
// reached the end or something went wrong
}
});
The major downside to this is that it relies on having the above DOM structure, I'd convinced myself that a method would exist for selecting the next element with a given class, regardless of where it appeared in the DOM.
Ideally I'd like a solution which doesn't rely on any given DOM structure, if that's not possible, any alternative solutions would be helpful!
Here's a fiddle with the above example
Sorry for the long-winded question!
how about this:
JSFIDDLE
It turns out that this is indeed a very simple task. By passing a selector to jQuery's
index()
method, you're able to get the index of the current element, relative to its collection:Then the
content
div can be targeted directly:Only DOM dependency with the existing code, is a.next must be an immediate child of .content.
Working jsFiddle example here
Turns out a simpler (less verbose) way to write it is exactly how you had it minus the function arguments:
EDIT 2:
I tried all of my solutions extensively but they were flawed. In short I think you pretty have the simplest way of doing it. Unless maybe a jQuery expert could chime in on this and show us a better way.
Here's my last proposal:
The ideal solution would be to use
closest()
, but the problem is that it's not behaving the way I expected because of their separation by containers. In jQuery's example they use an unordered list. Well yeah, this is much easier because you can distinguish between node types (e.g.li
vsul
) and simply do.next('li')
. Here you are using alldiv
s. And for some reason.closest('.content')
doesn't work once the end of the first container is reached!