Rodrixar

Tuesday, April 13

How to JavaScript: Prototype Slideshow Tutorial

Javascript Slideshow: A Web 2.0 Tutorial (a prototype tutorial)




Here's a quick Prototype tutorial for those looking for a simple javascript slideshow. This is not intended to be a JQuery discussion or tutorial, but a quick prototype tutorial. The desired result is an efficient, useful javascript slideshow coded in prototype js.

Before we get started, be sure to download the external Prototype files. In this amazing web 2.0 tutorial we'll use the effects.js and prototype.js files. In addition to this prototype tutorial, visit the official site of Prototype or learn more about Javascript .

Demo

For a quick demo on what the final product of this prototype tutorial is to look like, please refer to the header of this very blog (Rodrixar). Image changes after 3.5 seconds.

1. The goal

Our goal in this prototype tutorial is to come up with a javascript slideshow. The way it will work is that you'll have one image displaying, then after a predetermined amount of time (4 seconds in my example) the image will fade out and a different image will be showing behind it, and after another 4 seconds that image will fade out and a new one will display behind it. Then when the last image fades out, the first image will display.

The code design will be as follows:

  • An array will hold the filename for each image to be displayed
  • There will be 2 image elements on screen at all times, both stacked atop each other
  • A timer will call our main function every 4 seconds
  • This function perform the following tasks:
    1. Fade the top image so the image behind it will display
    2. After the fading effect is done, the front image will be the same as the back image (his step will be invisible to the human eye)
    3. Then the back image will be assigned a different value (it will display the next image in the array)
    4. Lastly, we'll check if we've hit the end of the array. If so have, we'll be sure the back image displays the first image of the array so the loop continues forever and ever (or until the person viewing your slideshow clicks away from your page)
  • The function will set the timer to come back in another 4 seconds

2. The setup

First thing we'll do is set up the HTML file. Though this is a prototype tutorial and a web 2.0 tutorial, I'll assume you could use the extra explanation. So open up your favorite text editor and be sure to have the following lines of code:


<html>
<head>

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript" src="effects.js"></script>

<script type="text/javascript">

</script>

<style type="text/css">
#iSlideShell { width: 250px; height: 250px; position: relative; }
#iSlideShell img { position: absolute; }
</style>

</head>

<body>

<div id="iSlideShell">
<img id="iSlideBack" src="img1.jpg"/>
<img id="iSlideFront" src="img1.jpg"/>
</div>

</body>
</html>

This is our basic HTML setup. Be sure the external javascript files are referenced right (that the link points to the right directory where you have the files saved). Also, be sure the the images in the <img> tags point to first 2 images you'd like displayed. Note that the top image (the one that will show first) is the one in the second <img> tag (since they're stacked through the css position absolute command). Make sure also that the <div> has the same height and width as the images in your slideshow. If the images you use aren't the same dimension we'll need to make a few slight adjustments to the <div> but this won't be covered in this prototype tutorial.

Now we'll set up the images we'll be using in our slideshow.

3. The Javascript

Inside the Javascript tags in the HTML code we'll set up the following variables:

var i = 0;
var iSlides = new Array("img1", "img2", "img3", "img4", "img5");

These will be our variables. The i will keep track of where we are as we loop through the array (iSlides), which is a list of all the images we want to display. Note that you don't include the file extension in the array, but only the filename. For this javascript tutorial you will need to use images of the same file type.


Next we'll add our function, which I'll call iAnimate. I'm not sure why I have the tendency of adding the letter "i" to the front of my variables and function. Maybe it's because iLike it :)

function r$(id) { return document.getElementById(id); }

function iAnimate()
{

r$('iSlideFront').show();
r$('iSlideBack').show();
r$('iSlideFront').fade();
r$("iSlideFront").src = r$("iSlideBack").src;

i == (iSlides.length - 1) ? i = 0 : i++;
r$("iSlideBack").src = "img/" + iSlides[i] + ".jpg";

setTimeout('iAnimate()', 4000);
}

window.onload = iAnimate;

The function "r$" may look like Prototype and/or JQuery, but all it is is a shortcut function I created so I don't have to type "document.getElementById()" over and over...

The first thing the function does is be sure both images are showing. In Prototype (and in JQuery), when you "hide" or "fade" (or "fadeOut") and element, that elements changes opacity gradually and finally has its css attribute "display" set to "none". By calling the show() function, we make sure the display for both images is set to "block". Once that's done, we fade the front image.

Then we make sure the front image is the same as the back image. This may seem pointless the very first time the function is called, since no visible change takes place, but once the first image fades, this is important.

The next step is to find out what the next image is in the array, and assign that to the back image. The conditional statements ? : checks if the variable i is equal to the total amount of images in the array minus 1. The reason it's (length - 1) is because the first image in the array is represented by iSlides[0] (zero is the first element in an array in Javascript). If this statement returns true, that means we've displayed the last image in the array, so now we must display the first one. That's when the assignment i = 0 gets called. If the statement returns false, we increment i by 1.

The back image (iSlideBackthen gets assigned the next image of the array, and the timer is set to explode in 4000 milliseconds, or 4 whole seconds. Once those 4 seconds are counted by the computer's clock, iAnimate() is called again, and the fun starts all over!

4. Conclusion

This is all there is to it. My goal was to make this as simple as possible, but making this javascript slideshow more robust shouldn't be too difficult with some basic understanding of javascript, prototype, html, or css.

One of the main benefits the code provided in this javascript slideshow (other than, but because of its simplicity) is the fact that the only images loaded are the ones currently displayed. Most prototype tutorials and JQuery tutorials I've seen load all images as the page loads (longer loading times), then they do what they must. In this javascript slideshow, if the user leaves the page after only 3 images have loaded, that's all the loading the code will do. This will save you resources and loading time.

Any questions, feel free to post in this prototype tutorial.

5. The Code

Here's the complete code for those of you reading my prototype tutorial that are mindful of the mileage on your mouse and your daily keystroke allowance:

<html>
<head>

<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript" src="effects.js"></script>

<script type="text/javascript">
var i = 0;
var iSlides = new Array("img1", "img2", "img3", "img4", "img5");

function r$(id) { return document.getElementById(id); }

function iAnimate()
{
r$('iSlideFront').show();
r$('iSlideBack').show();
r$('iSlideFront').fade();
r$("iSlideFront").src = r$("iSlideBack").src;

i == (iSlides.length - 1) ? i = 0 : i++;
r$("iSlideBack").src = "img/" + iSlides[i] + ".jpg";

setTimeout('iAnimate()', 4000);
}

window.onload = iAnimate;
</script>

<style type="text/css">
#iSlideShell { width: 250px; height: 250px; position: relative; }
#iSlideShell img { position: absolute; }
</style>

</head>

<body>

<div id="iSlideShell">
<img id="iSlideBack" src="img1.jpg"/>
<img id="iSlideFront" src="img1.jpg"/>
</div>

</body>
</html>

Prototype Tutorial

8 comments:

  1. great tutorial! i'm trying to implement it on a site, however, it's immediately switching to the NEW back image (instead of pausing on the first one for the full 4 seconds). what did i do wrong?

    http://www.storesonlinepro.com/store/3668838

    also, it doesn't appear to work in chrome (may be my CMS screwing with things?)

    ReplyDelete
  2. russell,
    looking at your link it looks like the code works fine in chrome. i'm not sure why it's skipping the first image. one difference between our codes is this: my front and back slides are set to display "shark.jpg". then, in my image array, this is the order that I have them:

    var iSlides = ("AURORA", "shark", "...");

    notice that shark.jpg is the SECOND element in my array.

    looking at your code, you display 1.jpg for both front and back slides (as it should be), but your array is in a different order:

    var iSlides = new Array("1", "2", "3", "4", "5");

    try having your array be = ("2", "1", "3", "4", "5").

    This should do the trick.

    Thanks,

    Rodrigo

    ReplyDelete
  3. actually, upon closer examination of my own code, this is the order in which the array of slides is to be set:

    var iSlides = new Array();

    iSlides[0] = The last image in slideshow

    iSlides[1] = The first image; the same as in the original front and back slides

    iSlides[1+] = The second, third, fourth, etc images.

    In your case, Russell, the array should be set to (assuming you want the images to rotate in the order 1, 2, 3, 4, and 5):

    Array("5", "1", "2", "3", "4");

    ReplyDelete
  4. works perfectly. thanks again for this tutorial!

    ReplyDelete
  5. Hi i was wondering if there were any other effects for the slide? and how to get it to work as well.

    thanks

    ReplyDelete
  6. Fizz - There are several other effects we can add to this script (such as slide the top picture to the side - or top or bottom - like an old school PowerPoint presentation, add a carousel effect, blur effects, etc), but from my research I've found that adding the extra features would require you to use the Scriptaculous library WITH your Prototype library. From experience, I've found it more efficient to switch to JQuery when such effects are desired.

    If Prototype is all you have to work with, then a simple fade-in-fade-out slide show like this one isn't so bad. But if you want more, you'd have to add additional libraries... so I guess what I'm saying is that I'll be writing a few tutorials on that soon... yay :)

    Check back in a few days for that...

    ReplyDelete
  7. Hi Rodrigo, thank you for this excellent post. I have written my own version of this in jQuery:
    http://robertmarkbramprogrammer.blogspot.com/2010/09/jquery-slideshow.html

    StrangelyThis doesn't seem to render correctly in Chrome 7.0.517.8 dev. It is flickering between the two images, as though I am actually seeing show(), which I shouldn't. They should be immediate.
    $('#slideShowFront').show();
    $('#slideShowBack').show();

    The standalone version looks fine in this version of Chrome though: http://robertmarkbram.appspot.com/content/javascript/jQuery/example_slideshow.html

    ReplyDelete
  8. ^^ Too bad chrome is in version 12 now. No flickering at all.

    ReplyDelete