Take the 2-minute tour ×

I have 3 divs with same class, i am adding class 'selected' to NEXT DIV on click and removing it from previous class, its working fine but I want to loop it

Currently its going from 1 --> 2 --> 3, I want it to loop, 3-->1, please help...


<div id="all">
<div class="section selected">ONE</div>
<div class="section">TWO</div>
<div class="section">THREE</div>
<br />
<a href="javascript:;" id="button">CLICK</a>





JS Fiddle Link : http://jsfiddle.net/madhuri2987/KK66g/2/

share|improve this question
add comment

3 Answers

up vote 3 down vote accepted

The simplest way would just be to check whether .next() exists and if not "select" the first.

var $next = $('.section.selected').removeClass('selected').next('.section');
if ($next.length) {
else {


share|improve this answer
Oh! Wow, thanks a ton :) –  itsMe Mar 26 '13 at 3:01
Explosion Pills, would you mind taking a look at my answer? I'm wondering what you think. What you have above was my first thought, before you posted it, so I moved to trying a different method. –  Jared Farrish Mar 26 '13 at 4:34
@JaredFarrish it's a cool solution, but I'd just be a bit worried about the dependency on the selector actually building the collection in order (e.g. what would stop it from making .section:eq(0) last at any time? You also end up with way more method calls –  Explosion Pills Mar 26 '13 at 13:43
That's the same issue I have, I'm not sure of the mechanism for .last(). I wouldn't say it's freewheeling with methods; it has one more than yours, and that's if you don't count the reselect in the else... –  Jared Farrish Mar 26 '13 at 14:58
@JaredFarrish you're right, I miscounted –  Explosion Pills Mar 26 '13 at 15:19
show 1 more comment

I'm not sure if I should claim this works in every case, but I've always wondered if it were possible to progress to the first on last not being valid. This is what I worked out:

    $('.selected + .section, .section:eq(0)')


What this does is first select the .section which is after .selected:

.selected + .section

I also add a secondary selector to make sure and get at least one match:

, .section:eq(0)

The above represents the first $('.section')[0], in this relatively simple example. Then I use .last() on the result of the compound selection, giving me either result [1] (for what would be a valid .next() match), or [0] for a first match (see, .last() will give both first and last if there's only one result in the list).

Although the selectors are ordered seemingly opposite to using .last(), this seems to work instead of .first(), for which I do not necessarily understand the reason why that is so. This is whichever order the selectors are in, so I ordered them the way they made sense in the selection.

Then, the rest is simple. Add a class to whichever the selector returned .last(), then find the .siblings() to that (newly) selected .section with .selected (the only other one would be the one we're selecting away from) and remove it's .selected class.

It seems to work. I suppose I'd like to hear any comments as to whether this is reliable or not.

share|improve this answer
This is one of the most confusing aspects of :eq(), :first and :last for me. I have no idea how these selectors work when used in contexts such as selector groups (like the one you have here), and when preceding a combinator (e.g. .foo:eq(0) .bar). I'm guessing what happens here is that :eq(0) takes the first out of the entire expression .selected + .section, .section, even if you place .section:eq(0) first. It seems bizarre, but that's the only reasonable explanation I can come up with for it. –  BoltClock Mar 26 '13 at 4:52
I see what you're suggesting. That since the :eq(0) is in there, it sees that as the first result, regardless of the rest of the selector statement. I guess it makes some kind've sense (?), but it's odd that it wouldn't return the result of the selectors in the order given (and I'm about to try to test this with document.querySelectorAll() to see if it matches). I had never considered that what the selection had stated could come back in a different order than given, more or less the one ordered by the indices of elements (is that right?). –  Jared Farrish Mar 26 '13 at 4:56
document.querySelectorAll() will never match for the simple reason that :eq() is not a valid CSS selector (it's simply a JS API to a browser's native CSS selector engine). That said, document.querySelector('.selected + .section, .section') (without the All) will work like :eq(0)/:first: jsfiddle.net/BoltClock/9UFD2/2 I gather that elements are always returned in the order as they appear in the DOM. –  BoltClock Mar 26 '13 at 4:59
Well then, never mind (I was thinking it was an actual selector, but I get it confused with nth-child()). I should probably take a look at the jQuery definition. That one part is the one part I'm not quite sure how it would play in reality. –  Jared Farrish Mar 26 '13 at 5:00
api.jquery.com/eq-selector simply says it takes the 0-based index of an element within a set of matches. In that case, one may as well use $('.selected + .section, .section').eq(0).last() instead, since it's extremely confusing in selector syntax. (Side note: I hate jQuery's messed-up selector syntax.) –  BoltClock Mar 26 '13 at 5:04
show 3 more comments

I did a simple code like this

var i=0;
    if(i == $('.section').length) {$('.section.selected').removeClass('selected');$($('.section')[0]).addClass('selected');i=0;}
share|improve this answer
add comment

Your Answer


