1

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!

Peachy
  • 643
  • 4
  • 20
  • 31

2 Answers2

3

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

Community
  • 1
  • 1
Zach Saucier
  • 24,871
  • 12
  • 85
  • 147
  • This is very helpful, thank you. There are a couple of buggy issues with this that I can figure out. First, there is an odd skip when the images are displayed. They flash on, then off then on again. Also, there isn't an initial image loaded so the first 9 seconds all you see is blank. I've updated your jsFiddle with images so you can see. http://jsfiddle.net/4TZ29/5/ Thanks again for the help! – Peachy Oct 03 '13 at 14:43
  • Thanks - that works great! I may have to rethink the randomization though. With five images it seems like a get too many of the same images repeating. – Peachy Oct 03 '13 at 20:19
  • Like I mentioned in the edit, you can remove it from repeating right after itself using an if statement. You could even extend it to not repeating itself two or three times from itself using the same concept. Another option would be to simply add more images. Or you could just have it run in order, viewers don't mind order – Zach Saucier Oct 03 '13 at 20:25
  • 1
    One more suggestion, Some times you need to stretch image to background div, use $('#Selector').css({backgroundSize: "cover"}); http://jsfiddle.net/4TZ29/95/ – Pradeep Apr 25 '14 at 04:53
0

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/

Mafia
  • 792
  • 2
  • 19
  • 39