Dec

6

NOTICE: the JavaScript slideshow in this article was written based on Jeremy Keith’s personal JavaScript library, to see the slideshow application I coded independently using YUI, please see this article.

http://www.lab.highub.com/javascript/slideshow/topics.gifI have coded an unobtrusive JavaScript thumbnail slideshow. It’s a slideshow of my favorite South Park characters: Kenny, Cartman and Kyle.

The demo page is at:
http://www.lab.highub.com/javascript/slideshow/list.html

This slideshow follows three main unobtrusive scripting principles:

1. Separation of JavaScript functionality (the “behavior layer”) from a Web page’s structure/content and presentation layers. Let’s take a look at the html code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html dir="ltr" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>South Park</title>
<style type="text/css" media="screen">
@import url(styles/layout.css);
</style>
<script type="text/javascript" src="scripts/addLoadEvent.js">
</script>
<script type="text/javascript" src="scripts/insertAfter.js">
</script>
<script type="text/javascript" src="scripts/moveElement.js">
</script>
<script type="text/javascript" src="scripts/prepareSlideshow.js">
</script>
</head>
<body>
<div>
<h1>My favorite South Park Characters</h1>
<p>These are kids from South Park.</p>
<ol id="linklist">
<li>
<a id="link1" href="Kenny.html">Kenny</a>
</li>
<li>
<a id="link2" href="Cartman.html">Cartman</a>
</li>
<li>
<a id="link3" href="Kyle.html">Kyle</a>
</li>
</ol>
</div>
</body>
</html>

From the source code above, we can see: a) all JavaScript files are imported from external .js files. b) there is no JavaScript within HTML body

2. Avoid the problems of traditional JavaScript programming such as browser inconsistencies and lack of scalability. Let’s take a look at the JavaScript animation function file moveElement.js:

function moveElement(elementID,final_x,final_y,interval) {
if (!document.getElementById) return false;
if (!document.getElementById(elementID)) return false;
var elem = document.getElementById(elementID);
if (elem.movement) {
clearTimeout(elem.movement);
}
if (!elem.style.left) {
elem.style.left = "0px";
}
if (!elem.style.top) {
elem.style.top = "0px";
}
var xpos = parseInt(elem.style.left);
var ypos = parseInt(elem.style.top);
if (xpos == final_x &amp;&amp; ypos == final_y) {
return true;
}
if (xpos < final_x) {
var dist = Math.ceil((final_x - xpos)/10);
xpos = xpos + dist;
}
if (xpos > final_x) {
var dist = Math.ceil((xpos - final_x)/10);
xpos = xpos - dist;
}
if (ypos < final_y) {
var dist = Math.ceil((final_y - ypos)/10);
ypos = ypos + dist;
}
if (ypos > final_y) {
var dist = Math.ceil((ypos - final_y)/10);
ypos = ypos - dist;
}
elem.style.left = xpos + "px";
elem.style.top = ypos + "px";
var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";
elem.movement = setTimeout(repeat,interval);
}

It is highly scalable, when you prepare to use this animation function, all you need to define are the four paramters: elementID, final_x, final_y, interval.

3. Graceful degradation in browsers that are unable to express the behavior layer in the desired manner. In our example, the slideshow image is created on the fly at runtime. If the user’s machine can not display JavaScript, he or she can not see the slideshow image, but the links are still functioning, so they can still go to each individual link. Below is the code inside prepareSlideshow.js. What it does is to first create the image and then assign the animation function in moveElement.js.

function prepareSlideshow() {
// Make sure the browser understands the DOM methods
if (!document.getElementsByTagName) return false;
if (!document.getElementById) return false;
// Make sure the elements exist
if (!document.getElementById("linklist")) return false;
var slideshow = document.createElement("div");
slideshow.setAttribute("id","slideshow");
var preview = document.createElement("img");
preview.setAttribute("src","topics.gif");
preview.setAttribute("alt","building blocks of web design");
preview.setAttribute("id","preview");
preview.setAttribute("class","reflect");
slideshow.appendChild(preview);
var list = document.getElementById("linklist");
insertAfter(slideshow,list);
// Get all the links in the list
var links = list.getElementsByTagName("a");
// Attach the animation behavior to the mouseover event
links[0].onmouseover = function() {
moveElement("preview",-150,0,10);
}
links[1].onmouseover = function() {
moveElement("preview",-300,0,10);
}
links[2].onmouseover = function() {
moveElement("preview",-450,0,10);
}
}
addLoadEvent(prepareSlideshow);

I was going through the main HTML file and the two main JavaScript files while explaining unobtrusive JavaScript principles, I am not going to explain the insertAfter.js and addLoadEvent.js files, because I wrote seperate articles about these two library files before, you can find the posts at: JavaScript - Load Event and JavaScript - insertAfter

And at last, let’s take a look at the CSS file:

#slideshow {
width: 150px;
height: 128px;
position: relative;
overflow: hidden;
}
#preview {
position: absolute;
}

div {
margin-left:200px;
}
div {
color:#5362FF;
}
a {
color:#5362FF;
}

One thing to note is “overflow: hidden;”, what this does is to hide areas out of the defined width. The defined width is “width: 150px;”, but the actual image size is 600px; so each time, only 150px of the image can be seen. By setting the #preview position to absolute, we move the image position so only the part of the image correspond to the rollover link will be displayed.

I will try to upadate this post to explain more more I got time. Enjoy!



Similar Posts

Comments

Name (required)

Email (required)

Website

Speak your mind

2 Comments so far

  1. hmmm on February 21, 2008 9:21 am

    I think you should give Jeremy Keith and his book “DOM Scripting” credit for this… thats the exact, to the var, same function he wrote in the book.

  2. admin on February 21, 2008 7:53 pm

    Yes, thanks for reminding me. I will take note of that.

Sponsors




Links