Question

I've got a tricky little problem. I'm just starting out the design for a website with a cycling background image. At the minute it's working fine, although you can see the alternate background images loading with the first image which looks a little messy. I could pretty easily hide these images, but I feel a better solution would be to allow the first image to load before the others to speed up the page load. Unfortunately I cant work out how to incorporate this into my existing JS.

The beginnings of the site are here (it might be broken at some point, I'm still experimenting).

My current JS:

function cycleImages(){
      var $active = $('#background-cycler .active');
      var $next = ($('#background-cycler .active').next().length > 0) ? $('#background-cycler .active').next() : $('#background-cycler img:first');
      $next.css('z-index',2);//move the next image up the pile
      $active.fadeOut(1500,function(){//fade out the top image
      $active.css('z-index',1).show().removeClass('active');//reset the z-index and unhide the image
      $next.css('z-index',3).addClass('active');//make the next image the top one
      });
    }

    $(window).load(function(){
        $('#background-cycler').fadeIn(1500);//fade the background back in once all the images are loaded
          // run every 7s
          setInterval('cycleImages()', 7000);
    })

HTML:

<div id="background-cycler" >

<script type="text/javascript">
$('#background_cycler').hide();//hide the background while the images load, ready to fade in later
</script>

<img class="active" src="images/bg1.jpg" alt=""/>
<img src="images/bg2.jpg" alt=""/>
<img src="images/bg3.jpg" alt=""/>
<img src="images/bg4.jpg" alt=""/>      
<img src="images/bg5.jpg" alt=""/>
</div>

Any help you could give would be greatly appreciated!! :)

EDIT: The other problem I have is I need this on every page, but I'd rather not reload the images each time. Am I right in thinking the images will still be cached?

Was it helpful?

Solution

Here's my take at it:

http://jsfiddle.net/bortao/9TxED/

You hide the image element and only fade it in when the onload event is triggered.

And yes, all images will be cached by the browser throughout your site.

HTML

<div id="background-cycler" class="background-cycler">
    <img id="imgPrev" />
    <img id="imgNext" />
</div>

CSS

.background-cycler {
    width: 1000px;
    height: 600px;
}
.background-cycler img {
    position: absolute;
    left: 0px;
    top: 0px;
}

JS

var imgs = [
    'http://ravenstudio.co.uk/izzy/images/bg1.jpg',
    'http://ravenstudio.co.uk/izzy/images/bg2.jpg',
    'http://ravenstudio.co.uk/izzy/images/bg3.jpg',
    'http://ravenstudio.co.uk/izzy/images/bg4.jpg',
    'http://ravenstudio.co.uk/izzy/images/bg5.jpg']

var imgNext = document.getElementById("imgNext");
var imgPrev = document.getElementById("imgPrev");
var currentImg = -1;
var MAX_IMAGES = 5;
var CYCLE_DELAY = 2000;
var FADE_DELAY = 1500;

imgNext.onload = function () {
    // When finished loading:
    $(this).fadeIn(FADE_DELAY, function() {
        // When fadeIn ends:
        imgPrev.src = imgs[currentImg]; // Send current image to back
    }); // Fade in loaded image
    window.setTimeout('cycleImages()', CYCLE_DELAY + FADE_DELAY); // Set next cycle
};

cycleImages = function () {
    currentImg++;
    if (currentImg == MAX_IMAGES) currentImg = 0;
    imgNext.style.display = "none"; // Hide before loading
    imgNext.src = imgs[currentImg]; // Load new image. 
    // After imgNext finish loading, onload above will be called
}

cycleImages(); // Call the first cycle
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top