A commonly requested feature for web pages is to cycle thru a list of images fading each image over the previous image. In today’s post we will use JQuery to provide this capability with the added benefit that once created we can control the list of images to cycle with HTML image tags and no JavaScript changes.
Beginning with the End in Mind
Before we get into the JavaScript let’s review the HTML. The objective is to have a list of images that rotate. We want to easily manage the list of images using standard HTML so that anyone who knows HTML can add the desired behavior even if they don’t know JavaScript.
A div tag will be used to identify the group of images to cycle thru. Inside the div tag will be the collection of image tags. In our example we will have a div tag with the id Example1 that will host three image tags. The div tag will be given the same height and width as the images so that the surrounding html won’t collapse when the image is hidden by the script.
Class names are not assigned to the images because the script will replace them. The script will use the class names current and next to track its position in the document.
<div id="Example1" style="width:50px;height:50px;"> <img src="/Images/Image1.jpg" /> <img src="/Images/Image2.jpg" /> <img src="/Images/Image3.jpg" /> </div> <div id="Example2" style="width:50px;height:50px;"> <img src="/Images/Image1.jpg" /> <img src="/Images/Image2.jpg" /> <img src="/Images/Image3.jpg" /> </div>
We will create two image cycling behaviors. The first will cause the current image to fade out and the next image to fade in. And, the second will fade the next image over the current image.
Fade Out Current Image and Fade In Next Image
We begin by creating a routine with four parameters. The first parameter is the selector which identifies which tag hosts the image tags to iterate thru. The next parameters will control the amount of time to fade the current image out, fade the next image in and how long to wait before starting the next effect.
Default values will be provided for the fading and wait arguments so that they are optional.
function fadeOutCurrentFadeInNext(selector, fadeOutTime, fadeInTime, waitTime) { //Set Defaults if Arguments Missing if (fadeOutTime == null) fadeOutTime = 2; if (fadeInTime == null) fadeInTime = fadeOutTime; if (waitTime == null) waitTime = fadeOutTime; }
Next we look to see which image tag has a class named “current”. If we are unable to find a tag we assign the “current” class name to the first image in the selector.
if (!$(selector + " .current").is(".current")) { $(selector + " img").first().addClass("current"); }
Now we are ready to initialize the image tags. Currently all image tags are visible. So the first thing we need to do is hide the image tags and show the current tag.
$(selector + " img").css("display", "none"); $(selector + " .current").css("display", "block");
Then we find the next tag. If the current image tag is the last element in the selector then the next tag is the first child element otherwise we use the next child element.
if ($(selector + " .current").is(":last-child")) $(selector + " :first-child").addClass("next"); else $(selector + " .current").next().addClass("next");
Finally we are ready to implement the transition from the current image to the next image tag element. We begin by using the jQuery fadeOut method to hide the current element tag. After the current element tag is hidden we can fade in the next element tag. Then we change the next element tag to be the current element tag.
A call to the fadeOutCurrentFadeInNext routine is made with the JavaScript setTimeout function so that the process can continue with the next image.
function fadeOutCurrentFadeInNext(selector, fadeOutTime, fadeInTime, waitTime) { //Set Defaults if Arguments Missing if (fadeOutTime == null) fadeOutTime = 2; if (fadeInTime == null) fadeInTime = fadeOutTime; if (waitTime == null) waitTime = fadeOutTime; //Make sure at least one image tag has a class name of current if (!$(selector + " .current").is(".current")) { $(selector + " img").first().addClass("current"); } //Initialize Image Tag Styling $(selector + " img").css("display", "none"); $(selector + " .current").css("display", "block"); //Identify Next Tag to Advance if ($(selector + " .current").is(":last-child")) $(selector + " :first-child").addClass("next"); else $(selector + " .current").next().addClass("next"); //Fade out current tag $(selector + " .current").fadeOut(fadeOutTime * 1000, function () { //Fade in next tag $(selector + " .next").fadeIn(fadeInTime * 1000, function () { //Remove class from current node, set next node to current $(selector + " .current").removeClass(); $(selector + " .next").removeClass().addClass("current"); //Call routine for next fade effect setTimeout("fadeOutCurrentFadeInNext('" + selector + "', " + fadeOutTime + ", " + fadeInTime + ", " + waitTime + ")", waitTime * 1000); }); }); }
Thanks to jQuery our code is clear, concise and simple to maintain. All we need to do to take advantage of the new routine is wait for the page to finish loading prior to executing the function.
$(document).ready(function () { fadeOutCurrentFadeInNext("#example1", 2); });
Fade Next Image Over Current Image
This effect is based on the previous routine and is much simpler to implement because there are fewer actions that must occur.
Once again we begin by setting default values for optional parameters. Then find the first image tag assigning the “current” class name to it.
The tags will need to be absolute positioned because they will need to be position over each other. Z-index will be utilized to move the next tag over the current tag so that as the tag fades in it hides the current tag behind itself.
Finally we fade the next tag over the current tag, advance the current tag selection and start the process over again.
function fadeNextOverCurrent(selector, fadeInTime, waitTime) { //Set Defaults if Arguments Missing if (fadeInTime == null) fadeInTime = 2; if (waitTime == null) waitTime = fadeInTime; //Make sure at least one image tag has a class name of current if (!$(selector + " .current").is(".current")) { $(selector + " img").first().addClass("current"); } //Initialize Image Tag Styling $(selector + " img").css("position", "absolute"); $(selector + " img").css("z-index", ""); $(selector + " img").css("display", "none"); $(selector + " .current").css("display", "block"); //Identify Next Tag to Advance if ($(selector + " .current").is(":last-child")) $(selector + " :first-child").addClass("next"); else $(selector + " .current").next().addClass("next"); //Set next tag styling $(selector + " .next").css("position", "absolute"); $(selector + " .next").css("z-index", "1"); //Fade in next tag over current tag $(selector + " .next").fadeIn(fadeInTime * 1000, function () { //Remove class from current node, set next node to current $(selector + " .current").removeClass(); $(selector + " .next").removeClass().addClass("current"); //Call routine for next fade effect setTimeout("fadeNextOverCurrent('" + selector + "', " + fadeInTime + ", " + waitTime + ")", waitTime * 1000); }); }
And, finally to start the effect.
$(document).ready(function () { fadeOutCurrentFadeInNext("#example1", 2); fadeNextOverCurrent("#example2", 2); });
Summary
Today we created two simple fading effects for cycling thru a list of images. The only code that the html editor needs to change is the initial function call to start the effect.
The div tag can be selected using a class name or an ID name with standard CSS syntax. Managing the list of images to cycle thru is very simple as we only need to add or remove the appropriate image tag. No need to change a JavaScript array to manage the images!
Leave a Reply