jQuery Sprite Slideshow…because I wanted to see if I could do it with less

So, a very cool guy, and one of my few posters, Joesph McCullough (a link to his site is in my blog roll on the right – Do It By Hand) is getting into jQuery. He posted a slideshow that he wrote, and I wanted to see if I could do it…but with less code. To be honest, his code looks daunting. I can read it and see what he is doing, but I can’t imagine writing that. Joe, when you read this, props to you for getting that to work. Basically, it is using 1 sprite image positioned using CSS, and then jQuery to move the wrapping div to the left so that it looks like it is showing a bunch of different images.

Click here for the demo.

Now on to the code!

First off, here is the html. It is basically the same thing Joseph has done, and pretty much the same structure I used on my slider on the home page of this blog.

<div id="slideContainer">
	<div id="slideWrap">
    	<div class="slide one"></div>
        <div class="slide two"></div>
        <div class="slide three"></div>
        <div class="slide four"></div>
    </div>
</div>

Easy stuff so far. Although if I didn’t want to put content in any of the slides, I would elimate the divs with the class of “slide” and just move the wrap. Less html that way. But for argument’s sake, lets just say I wanted to put some text in each slide div. Now, each of those slides also has a second class, which is used to move the background sprite image. Here is the CSS:

#slideContainer {
	width: 100px;
	height: 100px;
	overflow: hidden;
	border: 1px #000000 solid;
	margin: 20px auto;
	position: relative;
}
 
#slideWrap {
	height: 100px;
	position: absolute;
	top: 0;
	left: 0;
}
 
.slide {
	width: 100px;
	height: 100px;
	float: left;
	background: url(../images/sprite.jpg) no-repeat 0 0;
}
 
.two { background: url(../images/sprite.jpg) no-repeat -100px 0; }
.three { background: url(../images/sprite.jpg) no-repeat -200px 0; }
.four { background: url(../images/sprite.jpg) no-repeat -300px 0; }

That was the easy part. Now onto the jQuery:

$(document).ready(function() {
	var slides = $('.slide');
	var numberSlides = slides.length;
	var slideWidth = $('.slide').width();
	var wrap = $('#slideWrap')
 
	wrap.width(numberSlides * slideWidth);
 
	function moveMent() {
		for(r=0; r<100; r++) {
			for(i=0; i<numberSlides-1; i++) {
				wrap
					.delay(3000)
					.fadeTo(500, 0)
					.animate({				 
						left : '-=100px'
					})
					.fadeTo(500, 1)	
			}
			wrap.delay(3000).fadeTo(500, 0).animate({left : '0'}).fadeTo(500, 1);
		}
	};
 
	moveMent();	
 
});

Now, what is all that crap doing? Here we go, line by line…
Line:
1) The document ready – when loaded do this stuff

2) Create a variable – ‘slides’, which returns ALL the divs with the class ‘slide’

3) Create a variable – ‘numberSlides’, returns how many of those divs there are (4 in this case)

4) Create a variable – ‘slideWidth’, returns the width of 1 individual div with the class of ‘slide’ (100px)

5) Create a variable – ‘wrap’, this is so I don’t have to keep typing $(‘#slideWrap’) a billion times

6) Since I didn’t give the #slideWrap div a width, I have to find it, by getting the number of slides (4) * slideWidth (100px) which equal 400. If I added more slides, this number would increase.

7) Create a function called moveMent (I know, generic, but whatever)

8- Start a loop – r is a generic variable…starts as 0, and each time the loop runs add 1 to it. Keep running through the loop as long as r is less than 100. I could increase that to whatever number I want. This is just to demo it.

9) Another loop – same thing, but do this as long as i is less than the number of slides-1. (I don’t actually want to go to 4, or I would show a blank slide).

10 – *this is everything attached to wrap in the loop) Within the second loop – don’t do crap for 3 seconds, fade it out at a speed of 1/2 a second, move ‘wrap’ an additional 100px to the left from where it was, fade in at a speed of 1/2 a second.

Add 1 to i, repeat until loop is done. In this case, at the 4th slide. Loop finishes.

11) We’ll call the ‘wrap.delay(3000)…..’ line 11. Do nothing for 3 seconds, fade out, move the wrapper back to left: 0, fade in.

At this point, add 1 to r, then start the whole thing again.

12) Call the function called moveMent. Without calling it, nothing is going to happen.

I’m sure I can tighten this up even further, but I would say I accomplished my goal in doing what Joseph did, but with less. I am going to guess that Joseph actually knows more straight javascript than I do, based on his code, which I envy, and thanks for your post, cause it inspired me to see if I could create the same thing.

Tags: ,

8 Responses to “jQuery Sprite Slideshow…because I wanted to see if I could do it with less”

  1. Thanks a lot for this! Your way is a lot more concise. I wasn’t aware of the fadeTo method, that’ll be handy to know.

    The only minor note I have is that you could change wrap.width(numberSlides * 100) to wrap.width(numberSlides * slideWidth) for the sake of reusability.

    Once again, very cool, thanks a bunch.

  2. jcDesigns says:

    Bah…I pasted the earlier version into my post. If you look at the actual demo’s page, you will see that is what I actually did. Thanks for mentioning that, I corrected the post’s code.

  3. Hey Jeremy, I have a question. I noticed that my slideshow actually doesn’t work properly in IE8. It doesn’t do the fade out effect, it just “changes slides”. Do you know what in my code could possibly be causing that? Would changing the animate opacity to fadeTo help? Thanks! And congrats on the affiliate. I sure wouldn’t mind having one.

  4. jcDesigns says:

    Hey Joseph, I got your message…looking through your code right now. Here are a few things I’m noticing…

    1) the }); at the end should be taken out. You get an error with it in. The whole function actually ends above the line where you are calling spriteSlideShow at the end.

    2) you keep calling containerDiv like it is a variable, but you never set it to be the id of slideshow, unless I am not seeing that. Also, once a variable is declared, you can drop the $() from it. So it is just containerDiv =

    3) You can drop the get() also, don’t need that in jQuery for what you are doing.

    4) Where you are calling numberOfSlides =, get slide out of the $()…its already a variable…don’t need it. Should be var numberOfSlides = slide (and I think you are looking for length here, not size)…and the length doesn’t need the () at the end.

    I think what is confusing me the most is the $(containerDiv)…I know from looking at your code, that it should be the div with an id of slideshow, but slideshow is never called, and containerDiv is never set to it.

    Go over that js with a fine tooth comb. Like I said before, I think you are using a more straight javascript way of thinking, and not a jQuery way of thinking.

    Check out my demo link that I have in my most, and look at the js. There is actually very little code getting that to work. I think the best bet, and this is how I did mine….ditch the looping and get the animation working first. THEN add the loop.

    Also, try giving the opacity an actual number rather than show or hide. That could be your problem too.

  5. Hey, thanks for taking the time to respond.

    1) The }); at the end is for the jquery document.ready ( $(function(){ ). Doesn’t that need to be closed?

    2) I set the containerDiv to the id of slideshow in the function call itself
    spriteSlideShow($(‘#slideshow’), 1, 1, 1);

    which I basically treated as a shortcut for
    var containerDiv = document.getElementById(“slideshow”);
    spriteSlideShow(containerDiv, 1, 1, 1);

    3) I’ll be sure to drop the get, thanks

    4) I’ll be sure to use length from now on. The () at the end are just remnants from C++ class

    From what I understood, in order to use the member functions of the jquery library, the object has to be enclosed in the $(). Is this correct? That’s why I have everything wrapped in the $() operators over and over again. So would

    containerDiv.css(blah: blah)

    be legal, or would only

    $(containerDiv).css(blah: blah)

    be legal?

    And in the code containerDiv can actually be any div. It doesn’t look for the id of slideshow, I tried to avoid that for reusability purposes. (In case I had more than one slideshow on a page, I’d like to be able to call the same slideshow function, but just pass in a different div object and different parameters, etc)

    This was my first jquery creation, so I’m not surprised that it turned out pretty messy. I’ll try to clean it up. Thanks for all the help once again!

  6. jcDesigns says:

    1) You are correct. I ignored the top of your js file with all the comments. So you have all the commented stuff within the js file, and the document.ready call above that. So ignore what I said about that.

    2)See, this is what happens when I look at crap late at night. So you are passing the ID into the function from the function call at the bottom. Starting to make more sense.

    You are also correct about the containerDiv enclosure….I thought at first you were using a variable, and forgot to declare it or something.

    I will look at it again tonight, now that I have a better understanding of what is going on. As far as IE goes, I didn’t check, but I know IE has problems with commas being where they shouldn’t. check that first.

  7. [...] has come up with a much more elegant implementation of this sprite slideshow. Please view his post on the jQuery Sprite Slideshow. Filed under: JavaScript/jQuery Leave a comment Comments (1) Trackbacks (1) ( subscribe to [...]

  8. [...] has come up with a much more elegant implementation of this sprite slideshow. Please view his post on the jQuery Sprite Slideshow. Subscribe via [...]

Leave a Reply