Lodder
Lodder

Reputation: 19733

jQuery - Loop through images

I have 3 images in a set, which I'd like to loop through 3 times. On the last loop, I would like the last image to stay put and not change.

So far, I have got the following:

HTML:

<div class="banners">
    <img src="http://placehold.it/250/27B700/ffffff?text=first" alt="" />
    <img src="http://placehold.it/250/000CB7/ffffff?text=second" alt="" />
    <img src="http://placehold.it/250/ff0000/ffffff?text=last" alt="" />
</div>

JS:

$(document).ready(function() {

    var intId;
    var $banners = $('.banners');
    var timeout  = 16000;

    $banners.find('img:gt(0)').hide();

    function imageRotation() 
    {
        var $current = $banners.find('img:visible');
        var $next = $current.next();

        if ($next.length == 0) 
        {
            $next = $banners.find('img:eq(0)');
        }

        $current.fadeOut();
        $next.fadeIn();
    }

    intId = setInterval(function() {
        imageRotation();
    }, 2000);

    setTimeout(function() {
        clearInterval(intId);
    }, timeout);

});

Currently, I'm using a timeout of 16000 to determine the loop count and last image the rotation lands on.

This works on Firefox, but doesn't work on some browsers and is not a reliable approach.

Can anyone shed some light as to how to have exactly 3 loops and land on the last image of the set?

Am I right in assuming that I'd have to create a variable and update that variable once the last image of the set has come and gone?

Here is a JSFiddle for a live preview

Upvotes: 4

Views: 2908

Answers (3)

Tahir Ahmed
Tahir Ahmed

Reputation: 5737

Take a look at the snippet below:

$(document).ready(function () {
    var images = $('.banners > img');
    var numImages = images.length;
    var innerLoopIterator = 0;
    var outerLoopIterator = 0;
    var numOuterLoops = 3;
    var stayTime = 400;
    images.hide();
    function rotateImage() {
        images.eq(innerLoopIterator)
            .fadeIn()
            .delay(stayTime)
        	.queue(function(next) {
                innerLoopIterator += 1;
                if (innerLoopIterator >= numImages) {
                    innerLoopIterator = 0;
                    outerLoopIterator += 1;
                }
            	if (outerLoopIterator < numOuterLoops) { next(); rotateImage(); }
        	})
            .fadeOut();
    }
    rotateImage();
});
.banners {
    margin: 0 auto;
    width: 250px;
    height: 250px;
    position: relative;
    margin-right: 10px;
    float: left;
}
.banners img {
    position: absolute;
    top: 0;
    left: 0;
    display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="banners">
    <img src="http://placehold.it/250/27B700/ffffff?text=first" alt="" />
    <img src="http://placehold.it/250/000CB7/ffffff?text=second" alt="" />
    <img src="http://placehold.it/250/ff0000/ffffff?text=last" alt="" />
</div>

Upvotes: 1

Pete
Pete

Reputation: 58412

Try this:

$(document).ready(function () {
    var sage_intId;
    var $sage_banners = $('.banners');
    var sage_timeout = 16000;
    var loopCount = 0;

    $sage_banners.find('img:gt(0)').hide();

    function sage_imageRotation() {
        var $current = $sage_banners.find('img:visible');
        var $next = $current.next();

        if ($next.length == 0) {
            $next = $sage_banners.find('img:eq(0)');
            loopCount++;
        }

        if (loopCount < 3) {
            $current.fadeOut();
            $next.fadeIn();
            setTimeout(sage_imageRotation, 2000);
        }
    }

    setTimeout(sage_imageRotation, 2000);
});

Updated fiddle

Or with a data variable to set the number of loops

Upvotes: 1

Arun P Johny
Arun P Johny

Reputation: 388316

You can try a counter like

$(document).ready(function() {

  var sage_intId, $sage_banners = $('.banners'),
    $imgs = $sage_banners.find('img'),
    counter = 0;

  $imgs.slice(1).hide();

  function sage_imageRotation() {
    var $current = $imgs.filter(':visible'),
      $next = $current.next();

    if ($next.length == 0) {
      $next = $sage_banners.find('img:eq(0)');
    }

    $current.fadeOut();
    $next.fadeIn();

    if ($next.is($imgs.last())) {
      if (++counter > 2) {
        clearInterval(sage_intId);
      }
    }
  }

  sage_intId = setInterval(function() {
    sage_imageRotation();
  }, 500);
});
.banners {
  margin: 0 auto;
  width: 250px;
  height: 250px;
  position: relative;
  margin-right: 10px;
  float: left;
}
.banners img {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="banners">
  <img src="http://placehold.it/250/27B700/ffffff?text=first" alt="" />
  <img src="http://placehold.it/250/000CB7/ffffff?text=second" alt="" />
  <img src="http://placehold.it/250/ff0000/ffffff?text=last" alt="" />
</div>

Upvotes: 2

Related Questions