Peachy
Peachy

Reputation: 653

Change jQuery slideshow script to rotate background image defined in css class

I'm using a simple piece of jQuery to rotate through (and randomize) a series of images. I'm wondering how difficult it would be to adjust it to rotate through background images that are defined by a class.

The script looks like this:

<script type="text/javascript">
        jQuery.jQueryRandom = 0;
        jQuery.extend(jQuery.expr[":"],
        {
            random: function(a, i, m, r) {
                if (i == 0) {
                    jQuery.jQueryRandom = Math.floor(Math.random() * r.length);
                };
                return i == jQuery.jQueryRandom;
            }
        });        

        $(function() {
          $('#slideshow img').not(':random').hide(); //hide all images except one initially
          setInterval(function(){
            $('#slideshow img:visible').fadeOut('slow')
              .siblings('img:random').fadeIn('slow') //find a random image
               .end().appendTo('#slideshow');}, 
            9000); //2 second interval
        });
</script>

HTML is:

<div id="slideshow">
  <img src="banner1.jpg" />
  <img src="banner2.jpg" />
  <img src="banner3.jpg" />
  <img src="banner4.jpg" />
  <img src="banner5.jpg" />
</div>

CSS

<style type="text/css">
#slideshow {
    width: 100%;
    position: relative;
    }

#slideshow img {
    top: 0;
    left: 0;
    width: 100%;
    height: auto;
    position: absolute;
    }
</style>

So, what i'd like to do, but can't figure out is have the images rotate as a background applied to a class. So, instead of having all the images defined in the html, the would rotate through a class like this:

.slideshow {

  background: url(banner1.jpg) no-repeat bottom center;

}

Is this possible with some adjustments to the script above? Any pitfalls in this method?

Thanks!

Upvotes: 1

Views: 8186

Answers (2)

Mafia
Mafia

Reputation: 792

Improving on @Jack Saucier's answer, the code below iterates through the array items & does not repeat an image in succession:

var bgArray = ['http://upload.wikimedia.org/wikipedia/en/5/59/500_x_300_Ramosmania_rodriguesii_(Rubiaceae).jpg', 
             'http://upload.wikimedia.org/wikipedia/commons/5/5c/New-Withrow-Gym-500-X-300.jpg', 
             'http://inspirationfeed.com/wp-content/uploads/2010/10/22551-500x300.jpg', 
             'http://inspirationfeed.com/wp-content/uploads/2010/12/11619912483527701-500x300.jpg', 
             'http://westernstatescat.com/system/images/BAhbBlsHOgZmIigyMDExLzEyLzIwLzA5LzAwLzMzLzgwNi81MDB4MzAwLmpwZw/500x300.jpg'
           ];
var now = 0;

setInterval(function(){
        // Array of backgrounds
        now = (now+1) % bgArray.length;

        $('#slideshow').fadeOut('slow', function() { 
            $(this).css('background-image', 'url("' + bgArray[now] + '")').fadeIn('slow');
    })  
    }, 3000); // 3 second interval

LIVE PREVIEW: http://jsfiddle.net/4u0pq1a5/

Upvotes: 0

Zach Saucier
Zach Saucier

Reputation: 25954

Use an array of URLs as opposed to referencing elements and apply them to the background using jQuery's .css. It'd look like this

var imgArray = ['banner1.jpg', 
                'banner2.jpg', 
                'banner3.jpg', 
                'banner4.jpg', 
                'banner5.jpg'
               ]
var nextBG = "url(" + imgArray[Math.floor(Math.random() * imgArray.length)] + ") no-repeat bottom center";
$('#slideshow').css("background", nextBG);              

setInterval(function(){
    nextBG = "url(" + imgArray[Math.floor(Math.random() * imgArray.length)] + ") no-repeat bottom center";
    $('#slideshow').fadeOut('slow', function() { 
        $(this).css("background", nextBG).fadeIn('slow'); })                   
}, 3000); // 3 second interval

Working jsFiddle

If you wanted to have multiple slideshows it'd be the same but you'd change the ID to a class and either use a forEach or you could do .slideshow:eq(0) for each of them. You'd also have to generate the random image a second time. If you're looking for this please let me know

However, to do this well it is more complex than it seems, it would be best to load the images before hand. You could either load them in a hidden element like this post says or you could use jQuery to preload them like this other post says

Edit: Upon first posting I accidentally had $('#slideshow img') from the original which I changed. The sudden appearing before the fadeOut was due to .css not queing behind the .fadeOut, so I remedied the issue by changing the background URL in the callback function of fadeOut

If you don't want the same image to appear repeat directly after itself you can compare the position of the current image in the image array to the position of the next image in the image array within the setInterval

Upvotes: 3

Related Questions