www.htmlgoodies.com/beyond/javascript/article.php/3870076

Back to Article

JavaScript Tutorial: Build Your Own Image Viewer with Scrollbar
By Curtis Dicken
March 11, 2010

Introduction

In my last article I showed you how to make a space saving image scrollbar complete with a pseudo animation effect. In this article we are going to extend the image scrollbar into a full image viewer with scrollbar. We will add functionality to change the large image, image title and image description when you hover over the thumbnail images in the scrollbar. The key topics covered in this project include the two dimensional Array, innerHTML, setAttribute, setTimeout and onmouseover.

The JavaScript Scrollbar Code

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<title>Scroll Bar Example</title>

</head>

<body onload="javascript:preloadThumbnails()">

<script language="javascript" type="text/javascript">


// Array of image data

var imageData= new Array(10)

createTwoDimensionalArray(3);



// Image path data

imageData[0][0]="image1.png";

imageData[1][0]="image2.png";

imageData[2][0]="image3.png";

imageData[3][0]="image4.png";

imageData[4][0]="image5.png";

imageData[5][0]="image6.png";

imageData[6][0]="image7.png";

imageData[7][0]="image8.png";

imageData[8][0]="image9.png";

imageData[9][0]="image10.png";


// Image title data

imageData[0][1]="Grasslands";

imageData[1][1]="Tree Canopy";

imageData[2][1]="In the Clouds";

imageData[3][1]="Sunflower Bud";

imageData[4][1]="Morning Dew";

imageData[5][1]="Hillside Tree";

imageData[6][1]="Winter Wonderland";

imageData[7][1]="Mountain View";

imageData[8][1]="Babbling Brook";

imageData[9][1]="Wooded Trail";



// Image description data

imageData[0][2]="This is the description for the first image. Here will be where we give details on the image that is currently being viewed.";

imageData[1][2]="This is the description for the second image. Here will be where we give details on the image that is currently being viewed.";

imageData[2][2]="This is the description for the third image. Here will be where we give details on the image that is currently being viewed.";

imageData[3][2]="This is the description for the fourth image. Here will be where we give details on the image that is currently being viewed.";

imageData[4][2]="This is the description for the fifth image. Here will be where we give details on the image that is currently being viewed.";

imageData[5][2]="This is the description for the sixth image. Here will be where we give details on the image that is currently being viewed.";

imageData[6][2]="This is the description for the seventh image. Here will be where we give details on the image that is currently being viewed.";

imageData[7][2]="This is the description for the eighth image. Here will be where we give details on the image that is currently being viewed.";

imageData[8][2]="This is the description for the ninth image. Here will be where we give details on the image that is currently being viewed.";

imageData[9][2]="This is the description for the tenth image. Here will be where we give details on the image that is currently being viewed.";


// Our index, boundry and scroll tracking variables

var imageIndexFirst = 0;

var imageIndexLast = 3;

var continueScroll = 0;

var maxIndex = 9;

var minIndex = 0;


// This function creates our two dimensional array

function createTwoDimensionalArray(arraySize) {

for (i = 0; i < imageData.length; ++ i)

imageData[i] = new Array(arraySize);

}


// This function preloads the thumbnail images

function preloadThumbnails() {

imageObject = new Image();

for (i = 0; i < imageData.length; ++ i)

imageObject.src = imageData[i][0];

}



// This function changes the text of a table cell

function changeCellText(cellId,myCellData){

document.getElementById(cellId).innerHTML = myCellData;

}


// This function changes the images

function changeImage(ImageToChange,MyimageData){

document.getElementById(ImageToChange).setAttribute('src',MyimageData)

}


// This function changes the image alternate text

function changeImageAlt(ImageToChange,imageData){

document.getElementById(ImageToChange).setAttribute('alt',imageData)

}


// This function changes the image alternate text

function changeImageTitle(ImageToChange,imageData){

document.getElementById(ImageToChange).setAttribute('title',imageData)

}


// This function changes the image onmouseover

function changeImageOnMouseOver(ImageToChange,imageIndex){

document.getElementById(ImageToChange).setAttribute('onmouseover','handleThumbOnMouseOver(' + imageIndex + ');')

}


// This function hanles calling on change function

// for a thumbnail onmouseover event

function handleThumbOnMouseOver(imageIndex){

changeImage('imageLarge',imageData[imageIndex][0]);

changeCellText('imageTitleCell',imageData[imageIndex][1]);

changeCellText('imageDescriptionCell',imageData[imageIndex][2]);

changeImageAlt('imageLarge',imageData[imageIndex][1] + ' - ' + imageData[imageIndex][2]);

changeImageTitle('imageLarge',imageData[imageIndex][1] + ' - ' + imageData[imageIndex][2]);

}


// This function handles the scrolling in both directions

function scrollImages(scrollDirection) {

// We need a variable for holding our working index value

var currentIndex;

// Determine which direction to scroll - default is down (left)

if (scrollDirection == 'up')

{

// Only do work if we are not to the last image

if (imageIndexLast != maxIndex)

{

// We set the color to black for both before we begin

// If we reach the end during the process we'll change the "button" color to silver

document.getElementById('scrollPreviousCell').setAttribute('style','color: Black')

document.getElementById('scrollNextCell').setAttribute('style','color: Black')

// Move our tracking indexes up one

imageIndexLast = imageIndexLast + 1;

imageIndexFirst = imageIndexFirst + 1;

//  Change next "button" to silver if we are at the end

if (imageIndexLast == maxIndex)

{

document.getElementById('scrollNextCell').setAttribute('style','color: Silver')

}

// Changescrollbar images in a set delay sequence to give a pseudo-animated effect

currentIndex = imageIndexLast;

changeImage('scrollThumb4',imageData[currentIndex][0]);

changeImageOnMouseOver('scrollThumb4',currentIndex);

currentIndex = imageIndexLast - 1;

setTimeout("changeImage('scrollThumb3',imageData[" + currentIndex + "][0])",25);

setTimeout("changeImageOnMouseOver('scrollThumb3'," + currentIndex + ")",25);

currentIndex = imageIndexLast - 2;

setTimeout("changeImage('scrollThumb2',imageData[" + currentIndex + "][0])",50);

setTimeout("changeImageOnMouseOver('scrollThumb2'," + currentIndex + ")",50);

currentIndex = imageIndexLast - 3;

setTimeout("changeImage('scrollThumb1',imageData[" + currentIndex + "][0])",75);

setTimeout("changeImageOnMouseOver('scrollThumb1'," + currentIndex + ")",75);

// Wait and check to see if user is still hovering over button

// This pause gives the user a chance to move away from the button and stop scrolling

setTimeout("scrollAgain('" + scrollDirection + "')",1000);

}

}

else

{

// Only do work if we are not to the first image

if (imageIndexFirst != minIndex)

{

// We set the color to black for both before we begin

// If we reach the end during the process we'll change the "button" color to silver

document.getElementById('scrollPreviousCell').setAttribute('style','color: Black')

document.getElementById('scrollNextCell').setAttribute('style','color: Black')

// Move our tracking indexes down one

imageIndexLast = imageIndexLast - 1;

imageIndexFirst = imageIndexFirst - 1;

//  Change previous "button" to silver if we are at the beginning

if (imageIndexFirst == minIndex)

{

document.getElementById('scrollPreviousCell').setAttribute('style','color: Silver')

}

// Change scrollbar images in a set delay sequence to give a pseudo-animated effect

currentIndex = imageIndexFirst;

changeImage('scrollThumb1',imageData[currentIndex][0]);

changeImageOnMouseOver('scrollThumb1',currentIndex);

currentIndex = imageIndexFirst + 1;

setTimeout("changeImage('scrollThumb2',imageData[" + currentIndex + "][0])",25);

setTimeout("changeImageOnMouseOver('scrollThumb2'," + currentIndex + ")",25);

currentIndex = imageIndexFirst + 2;

setTimeout("changeImage('scrollThumb3',imageData[" + currentIndex + "][0])",50);

setTimeout("changeImageOnMouseOver('scrollThumb3'," + currentIndex + ")",50);

currentIndex = imageIndexFirst + 3;

setTimeout("changeImage('scrollThumb4',imageData[" + currentIndex + "][0])",75);

setTimeout("changeImageOnMouseOver('scrollThumb4'," + currentIndex + ")",75);

// Wait and check to see if user is still hovering over button

// This pause gives the user a chance to move away from the button and stop scrolling

setTimeout("scrollAgain('" + scrollDirection + "')",1000);

}

}

}


// This function determines whether or not to keep scrolling

function scrollAgain(scrollDirection)

{

if (continueScroll == 1)

{

scrollImages(scrollDirection);

}

}


// This function kicks off scrolling down (left)

function scrollPrevious() {

continueScroll = 1;

scrollImages('down');

}


// This function kicks off scrolling up (right)

function scrollNext() {

continueScroll = 1;

scrollImages('up');

}


// This function stops the scrolling action

function scrollStop() {

continueScroll = 0;

}


</script>

<table border="0" cellpadding="5" cellspacing="0" width="700px">

<tr>

<td align="center" colspan="6" style="font-weight: bold; font-size: 18pt; color: silver;

background-color: maroon" id="imageTitleCell">

Grasslands</td>

</tr>

<tr>

<td align="center" colspan="6" style="background-color: maroon">

<img height="400" src="image1.png" style="border-right: 1px solid; border-top: 1px solid; border-left: 1px solid;

border-bottom: 1px solid" width="400" id="imageLarge" alt="default" /></td>

</tr>

<tr>

<td align="left" colspan="6" style="padding-right: 100px; padding-left: 100px; color: white;

background-color: maroon" id="imageDescriptionCell">

This is the description for the first image. Here will be where we give details

on the image that is currently being viewed.</td>

</tr>

<tr>

<td id="scrollPreviousCell" style="color: Silver" onmouseover="scrollPrevious();" onmouseout="scrollStop();">

&lt;&lt; Previous</td>

<td>

<img id="scrollThumb1" height="100" src="image1.png" style="border-right: 1px solid; border-top: 1px solid; border-left: 1px solid;

border-bottom: 1px solid" width="100" onmouseover="handleThumbOnMouseOver(0);" /></td>

<td>

<img id="scrollThumb2" height="100" src="image2.png" style="border-right: 1px solid; border-top: 1px solid; border-left: 1px solid;

border-bottom: 1px solid" width="100" onmouseover="handleThumbOnMouseOver(1);" /></td>

<td>

<img id="scrollThumb3" height="100" src="image3.png" style="border-right: 1px solid; border-top: 1px solid; border-left: 1px solid;

border-bottom: 1px solid" width="100" onmouseover="handleThumbOnMouseOver(2);" /></td>

<td>

<img id="scrollThumb4" height="100" src="image4.png" style="border-right: 1px solid; border-top: 1px solid; border-left: 1px solid;

border-bottom: 1px solid" width="100" onmouseover="handleThumbOnMouseOver(3);" /></td>

<td id="scrollNextCell" style="color: Black" onmouseover="scrollNext();" onmouseout="scrollStop();">

Next &gt;&gt;</td>

</tr>

</table>



</body>

</html>

Review

I won’t be covering any of the topics surrounding how the image scrollbar piece works. If you want to learn more about the specific functionality of that piece please take a look at Web Developer Tutorial: Build Your Own Image Scrollbar.

Storing the Data: Creating a Two Dimensional Array

Since we are extending our image scroll bar we need a way to store and retrieve more data than just the paths to our images. We also need the image title and description. The best way to accomplish this is with a two dimensional array.

So, what is a two dimensional array? Think of it as a table. Any table you create has rows and columns. If you were to index your table you would reference each cell by its row and column number. That’s exactly what a two dimensional array is.

Now, you would think that creating a two dimensional array would be as easy as saying something like Array(10,3). While that is the case with some languages it is not that easy with JavaScript. Instead we essentially have to create and array of arrays to get our second dimension. We do this by stepping through our one dimensional imageData array and putting an array in each slot. In order to keep the viewer flexible I created a function (createTwoDimensionalArray) that does exactly that. Its parameter is the size of the second dimension and it loops through the imageData array adding the second dimension.

The array that we are using has 10 rows and 3 columns. The first column holds our image paths, the second column holds our image titles, and the third column holds our image descriptions. Notice the data assignments at the top of the script references row number then column number. I separated the data assignments into 3 sections so it is easier to see how the array works.

Function - changeCellText

This function takes care of updating our title and description data. It finds the cell to update using the same getElementById method that we use throughout our script and sets the innerHTML to the new value. The innerHTML property is what allows you to update content in your table cells.

Function - changeImageAlt

This function changes the alt property for the large image. It combines the image title and description and sets the alt value using setAttribute. Keep in mind you won’t actually be able to see this change in your standard browser.

Function - changeImageTitle

This function changes the title property for the large image. It combines the image title and description and sets the title value using setAttribute. In most browsers this will result in a tooltip with your title and description when you hover over the large image.

Function - changeImageOnMouseOver

This function is responsible for keeping our thumbnail onmouseover events straight. It changes a thumbnail’s onmouseover attribute so that when our handleThumbOnMouseOver function is called the correct row index for our image data array is sent. This function is called from the functions that change the scrollbar thumbnail images.

Function - handleThumbOnMouseOver

This function is the workhorse of our new functionality. It is responsible making the changes to src, alt, title and onmouseover attributes. It uses the row index parameter that is passed to it to find the appropriate data and then calls the changeImage function to change the image, the changeCellText function to change cell text for the title and description, and the functions that handle changing the alt and title attributes.

Updates to Scrollbar Functions

The only real change to the scrollImages function that handles the scrolling of the image scrollbar was the addition of the changeImageOnMouseOver function that updates the onmouseover attribute for the thumbnails. We call the function in the same sequence using setTimeout so that the image src and onmouseover attributes change at the same time. If we don’t keep them on the same time schedule then there is the potential that the user could hover over an image and get a different large image, title and description than the thumbnail the user hovers over. I know, this is not likely to happen but if you choose to slow down the animation effect the potential would be greater.

The HTML

The most notable changes to the HTML are the addition of cells for the title and description. Each of those cells is assigned a unique ID value so that we can manipulate them in our script. The large image is also assigned a unique ID. I also set the onmouseover attribute for each of the thumbnail images so that they would function as expected when the page is first loaded.

Conclusion

With this script you now have a fully functional image viewer with scrollbar. The script can easily be placed in a JavaScript library for distributed use. You could also extend the functionality even more by adding other specialized data to your two dimensional array like the date the image was taken or a link to a web page. Happy coding!