A Simple JavaScript Slideshow
Suppose you wanted to create a simple picture slideshow using JavaScript: The page displays the first picture, and when you click on it the next picture replaces it. You can continue to click and view all of the pictures in the slideshow. The obvious way to do this is to change the .src attribute of an image object, and that will work finebut here you'll take a look at a different approach that uses the W3C DOM to make a more flexible slideshow.
The HTML File
First, you'll need an HTML document that defines the page and where the images will appear. Before you start on the scripting, take a look at the HTML file in Listing 19.4.
Listing 19.4. The HTML File for the Slideshow
<html>
<head>
<title>Image Slideshow Test</title>
<script language="javascript" type="text/javascript"
src="slideshow.js">
</script>
</head>
<body>
<h1>Image Slideshow Test</h1>
<img class="slide" src="pic1.jpg" width="400" height="300">
<img class="slide" src="pic2.jpg" width="400" height="300">
<img class="slide" src="pic3.jpg" width="400" height="300">
<img class="slide" src="pic4.jpg" width="400" height="300">
<img class="slide" src="pic5.jpg" width="400" height="300">
<p>Click the image to view the next slide.</p>
</body>
</html>
|
You might notice something peculiar about this document: All five of the images are included with <img> tags. If you load the document into a browser before you add the JavaScript file, you'll see all five images on the page at once.
The slideshow.js script is included with the <script> tag in the header. This script will hide all but the first image, and allow the images to be shown one at a time. This is an example of unobtrusive scriptingusers without JavaScript can see the images just fine, although they'll have to scroll the page, and they'll miss the nifty slideshow feature.
Because the markup of this example uses ordinary <img> tags, we've used a special class="slide" attribute on the slide images. The script will check for this class to determine which images belong to the slideshow because there's a good chance you'll have other images on the page.
This is a flexible way to create a slideshowyou can change the order of the slides simply by rearranging the HTML, and you can add more slides just by adding more images with the right class value.
By the Way
See Hour 15 for more information about keeping JavaScript unobtrusive and optional.
The JavaScript File
The script that brings the slideshow to life is shown in Listing 19.5. The script consists of two basic functions: MakeSlideShow(), which rearranges the images into a slideshow, and NextSlide(), which responds to a click and advances to the next image.
Listing 19.5. The JavaScript File for the Slideshow
var numslides=0,currentslide=0;
var slides = new Array();
function MakeSlideShow() {
// find all images with the class "slide"
imgs=document.getElementsByTagName("img");
for (i=0; i<imgs.length; i++) {
if (imgs[i].className != "slide") continue;
slides[numslides]=imgs[i];
// hide all but first image
if (numslides==0) {
imgs[i].style.display="block";
} else {
imgs[i].style.display="none";
}
imgs[i].onclick=NextSlide;
numslides++;
} // end for loop
} // end MakeSlideShow()
function NextSlide() {
slides[currentslide].style.display="none";
currentslide++;
if (currentslide >= numslides) currentslide = 0;
slides[currentslide].style.display="block";
}
// create the slideshow when the page loads
window.onload=MakeSlideShow;
|
Let's take a look at how this script works:
The first lines define three global variables: numslides to store the current number of slides, currentslide to keep track of the current slide, and the slides array to store the image objects for each slide. The MakeSlides() function starts by using getElementsByTagName() to find all of the images on the page, and iterates through the array with a for loop. The first if statement in the loop checks the className attribute of the image, and if it does not belong to the slide class, the loop is continued without any action. The next statements store the image in the slides array, and then check numslides for a value of zero, meaning the first image in the array. For the first image, the display attribute is set to block; for all others, display is set to none so that only one image is visible at a time. The final statements in the loop set the image's onclick event handler to the NextSlide() function and increment the numslides variable. The NextSlide() function first hides the current slide by setting its display property to none. Next, it increments currentslide. The if statement resets currentslide to zero when the last slide is clicked on. Finally, the new slide is displayed by setting its display property to block. The final line of the script sets an onLoad event handler for the window to run the MakeSlideShow() function. This rearranges the images into a slideshow as soon as the page loads.
To test the script, save it as slideshow.js in the same folder as the HTML document you created previously, and load the HTML document into a browser. Figure 19.4 shows the script in action with the first image displayed.
Did you Know?
You might see a brief flicker when you load the page and the five images display before being hidden by the script. You can eliminate this by adding a display:none rule in CSS for the slide class, making all of the images invisible until the script displays the first one.
|
Although the slideshow example works, the transitions between images are instantaneoussomewhat of a utilitarian effect. With a bit more code, you can use JavaScript and the CSS positioning properties to create an animated transition between the slides.
By the Way
See Hour 13, "Using the W3C DOM," for information about the CSS positioning properties used in this example.
The HTML for this example is similar to that of the basic slideshow, with two differences: First, the images are enclosed in a <div> element with the id attribute "slideshow". This element will be used to make the transition between slides work. Second, a <link> tag in the header specifies a style sheet, slideshow2.css, because this example will require some CSS styles. The HTML document is shown in Listing 19.6.
Listing 19.6. The HTML File for the Animated Slideshow
<html>
<head>
<title>Animated Slideshow Test</title>
<script language="javascript" type="text/javascript"
src="slideshow2.js">
</script>
<link rel="stylesheet" type="text/css" href="slideshow2.css">
</head>
<body>
<h1>Animated Slideshow Test</h1>
<div id="slideshow">
<img class="slide" src="pic1.jpg" width="400" height="300">
<img class="slide" src="pic2.jpg" width="400" height="300">
<img class="slide" src="pic3.jpg" width="400" height="300">
<img class="slide" src="pic4.jpg" width="400" height="300">
<img class="slide" src="pic5.jpg" width="400" height="300">
</div>
<p>Click the image to view the next slide.</p>
</body>
</html>
|
As before, if you load this document into a browser without the JavaScript or CSS files, it will display all five images on the page.
You'll need a bit of CSS to set things up for the slideshow. The style sheet will set the initial position of the images and set the positioning properties so that the animation will work. The CSS file for this example is shown in Listing 19.7. Save the file as slideshow2.css in the same folder as the HTML document you created previously.
Listing 19.7. The CSS File for the Animated Slideshow
img.slide {
position: absolute;
left:0;
top:0;
}
#slideshow {
position: relative;
overflow: hidden;
width: 400;
height: 300;
}
|
The #slideshow rule defines the styles for the <div> element that encloses the images. The position: relative rule enables positioning for the element and its children, while leaving it where it landed in the page by default. The overflow property hides the part of an image that lies outside the <div>, so the new image can "slide in" from the side. Finally, the width and height properties make the <div> as large as the images so that the slideshow is always one size.
The img.slide rule sets up the styles for the images themselves. The position property is set to absolute. In combination with the relative value on the <div>, this means that the image is positioned relative to its parent. It is set to left: 0 and top: 0, which positions each image at the upper-left corner of the <div>to begin, all of the images will be on top of each other, so only one will be visible.
Instead of using the display property, the animated slideshow will use the z-index property (zIndex in JavaScript). This controls which of the overlapping images is "on top." To change slides, the script will set the new image to be on the top of the stack and position it off the right edge of the <div>, and then gradually slide both the old and new slides to the left until the new one is the only one visible.
Now that you have the HTML and CSS files, all that remains is the script. Listing 19.8 shows the JavaScript file for the animated slideshow.
Listing 19.8. The JavaScript File for the Animated Slideshow
// Global variables
var numslides=0;
var currentslide=0,oldslide=4;
var x = 0;
var slides = new Array();
function MakeSlideShow() {
// find all images with the class "slide"
imgs=document.getElementsByTagName("img");
for (i=0; i<imgs.length; i++) {
if (imgs[i].className != "slide") continue;
slides[numslides]=imgs[i];
// stack images with first slide on top
if (numslides==0) {
imgs[i].style.zIndex=10;
} else {
imgs[i].style.zIndex=0;
}
imgs[i].onclick=NextSlide;
numslides++;
} // end for loop
} // end MakeSlideShow()
function NextSlide() {
// Set current slide to be under the new top slide
slides[currentslide].style.zIndex=9;
// Move older slide to the bottom of the stack
slides[oldslide].style.zIndex=0;
oldslide = currentslide;
currentslide++;
if (currentslide >= numslides) currentslide = 0;
// start at the right edge
slides[currentslide].style.left=400;
x=400;
// Move the new slide to the top
slides[currentslide].style.zIndex=10;
AnimateSlide();
}
function AnimateSlide() {
// Lower moves slower, higher moves faster
x = x - 25;
slides[currentslide].style.left=x;
// previous image moves off the left edge
// (comment the next line for a different effect)
slides[oldslide].style.left=x-400;
// repeat until slide is at zero position
if (x > 0) window.setTimeout("AnimateSlide();",10);
}
// create the slideshow when the page loads
window.onload=MakeSlideShow;
|
Here's how this script differs from the original slideshow script:
An oldslide global variable has been added to keep track of the previous slide, so it can be moved out as the new slide moves in. Another global variable, x, will store the current horizontal position of the sliding image. Instead of using the display property, the MakeSlideShow() function sets the zIndex property to 10 for the first image and to zero for the others. The NextSlide() function works differently. First, it sets the current slide's zIndex property to 9, so it is the second one in the stack. (See the Did You Know? sidebar at the end of this section for the reason.) Next, it sets zIndex to zero for the old slide to move it to the bottom. It then assigns the oldslide value for next time, and increments the current slide as before. NextSlide() finishes by setting the new slide's left property to 400, and the x variable to the same value. The slide will start off the right edge of the <div> and gradually become visible as it moves to the left. It then sets zIndex to 10 for the new slide to put it on top of the stack. Last, it calls the new AnimateSlide() function to make the transition. AnimateSlide() handles the animation. It starts by subtracting 25 from the value of x and setting the current slide's left property to that value. It also sets the position of the old slide 400 pixels to the left of the current one, so it slides out of the frame as the new one slides in. The last line in AnimateSlide() checks x, and if it has not yet reached zero, it uses setTimeout() to call itself after a brief (10 millisecond) delay. This function will be called repeatedly until the new slide reaches its final resting place on the left side.
Did you Know?
The reason for setting the old slide's zIndex to 9 instead of 10 is to allow you to try a different transition effect. If you remove the slides[oldstyle].style.left assignment in AnimateSlide(), the old slide will stay in one place while the new slide moves over it.
To try out the animated slideshow, make sure you have all three files in the same folder: the HTML document, the style sheet (slideshow2.css), and the JavaScript file (slideshow2.js). Load the HTML document into a browser; then click on the image to advance the slideshow.
The AnimateSlide() function uses a lot of code, but on a reasonably fast machine, the transition will be very fast, taking about half a second. If you want to slow it down to see what's going on, change the 25 value in AnimateSlide() to a lower numbera value of 1 will make the transition extremely slow. Figure 19.5 shows the slideshow in action, halfway between the first slide and the second.
|
|
Main Menu
|