Simple image rotation script I am writing a simple image rotation script. Users press either the prev or next button to view the previous or next images. It works well, but the code looks over the top. Is there a way I can reduce the amount of code used?

index.php

&lt;div id="container"&gt;
&lt;img src="pic1" id="pic1" class="top-pic" alt="" /&gt;
&lt;img src="pic2" id="pic2" alt="" /&gt;
&lt;img src="pic3" id="pic3" alt="" /&gt;
&lt;img src="pic4" id="pic4" alt="" /&gt;
&lt;/div&gt;

&lt;input type="button" name="prev" id="prev" value="prev" /&gt;
&lt;input type="button" name="next" id="next" value="next" /&gt;


jQuery

$('#next').click(function(){
    if($('#pic1').hasClass('top-pic')){
        $('#pic1').removeClass('top-pic');
        $('#pic2').addClass('top-pic');
    }else if($('#pic2').hasClass('top-pic')){
        $('#pic2').removeClass('top-pic');
        $('#pic3').addClass('top-pic');
    }else if($('#pic3').hasClass('top-pic')){
        $('#pic3').removeClass('top-pic');
        $('#pic4').addClass('top-pic');
    }else if($('#pic4').hasClass('top-pic')){
        $('#pic4').removeClass('top-pic');
        $('#pic1').addClass('top-pic');
    }

});

$('#prev').click(function(){
    if($('#pic1').hasClass('top-pic')){
        $('#pic1').removeClass('top-pic');
        $('#pic4').addClass('top-pic');
    }else if($('#pic4').hasClass('top-pic')){
        $('#pic4').removeClass('top-pic');
        $('#pic3').addClass('top-pic');
    }else if($('#pic3').hasClass('top-pic')){
        $('#pic3').removeClass('top-pic');
        $('#pic2').addClass('top-pic');
    }else if($('#pic2').hasClass('top-pic')){
        $('#pic2').removeClass('top-pic');
        $('#pic1').addClass('top-pic');
    }

});
You can use jQuery's .next() and .prev()

function nextPic() {
  var current = $("#container .top-pic");
  var next = current.next("img");
  if( next.length === 0 ) {
    next = $("#container img:first");
  }
  current.removeClass("top-pic");
  next.addClass("top-pic");
}

function prevPic() {
  var current = $("#container .top-pic");
  var prev = current.prev("img");
  if( prev.length === 0 ) {
    prev = $("#container img:last");
  }
  current.removeClass("top-pic");
  prev.addClass("top-pic");
}

$('#next').click(nextPic);
$('#prev').click(prevPic);


Or, avoiding the duplication:

function switchTopPic(direction) {
  var map = { prev: 'last', next: 'first' },
      current = $("#container .top-pic"),
      target = current[direction]("img");
  if( target.length === 0 ) {
    target = $("#container img")[map[direction]]();
  }
  current.removeClass("top-pic");
  target.addClass("top-pic");
}

$('#next').click(function () { switchTopPic("next") });
$('#prev').click(function () { switchTopPic("prev") });


Or given the markup in the question, the last little bit could just be:

$('#next, #prev').click(function () { switchTopPic(this.id) });


Either way, it should handle an arbitrary number of images (including none at all), and it doesn't require a top-pic to be set ahead of time. All state information is kept in the markup, and does not require the image IDs to be sequential (they don't even need an ID at all).

Edit: Here's a jsfiddle