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:
$('#button').click(function(){
$('.selected + .section, .section:eq(0)')
.last().addClass('selected')
.siblings('.selected').removeClass('selected');
});
http://jsfiddle.net/userdude/9UFD2/
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.