Presentation Lists

This page demonstrates how you can use DHTML to assist in a presentation using lists. This script will add a handler to your "Next Page" link to reveal list items one at a time, and finally advance to the next page when all items are revealed. If the browser does not have Javascript enabled, the list will be displayed all at once and the "Next Page" link will work as expected.

A non-DHTML alternative is to have multiple pages, each revealing the next item on the list. However, if you need to change the wording in an item, each of those pages needs to be changed. Also, if you add or remove items, the previous/next links need to be changed, as well as the wording of the list items.

General Concepts

This script is intended to be usable in several pages, and has some limitations as described in the annotated source code. It works well with CSS to change the appearance of the lists.

When the HTML page which uses this snippet loads, the window's onload event calls a function which sets the class of all but the first item in the target list. This class can change the appearance in any way desired, either hiding the item or changing the font to be very faded. An onclick event handler is added to the "Next Page" link which traps when that link is used. If there are still hidden items, the next item will be revealed and the link will not be followed. If all the items have already been revealed, the link will be followed.

You can try this snippet with the list below, and advance to the next item by clicking on the "Next" link. The "Reset List" link will change the list to be the same as when the page was first loaded. If all of the items are revealed and you click on the "Next" link, you will see no action (because the actual link destination is set to the current page), but when actually using this snippet, the link will be followed to whatever you set it to be.

Reset List

CSS

The CSS we use only has one small rule, which dims the text color of the item that uses it:

.hidden {
    color: #ccc;
    background: transparent;
}

The background is set because it's good practice to set both at the same time.

HTML

The HTML source for the list itself is straightforward. The only addition is to set the id attribute of the list to target, so our DHTML code knows how to find it. Similarly, our only addition to the "Next" link is to set the id attribute to next.

<ul id="target">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
</ul>
<p><a id="next" href="#">Next</a></p>

Javascript

Our Javascript file defines the function used when the "Next" link is clicked, the initialization function which is called when the page is loaded, and binds the window's onload event to our initialization function.

function doadvance () {
    var ul = document.getElementById ('target');
    for (var i = 0; i < ul.childNodes.length; ++i) {
	var c = ul.childNodes[i];
	if (c.tagName == 'LI' && c.className == 'hidden') {
	    c.className = '';
	    return false;
	}
    }
    return true;
}

function clickadvance () {
    if (! document.getElementById)
        return;
    var ul = document.getElementById ('target');
    var a = document.getElementById ('next');
    if (! ul || ! a)
	return;
    var didone = 0;
    for (var i = 0; i < ul.childNodes.length; ++i) {
	var c = ul.childNodes[i];
	if (c.tagName == 'LI')
	    if (didone++ && c.className != 'nohide')
		c.className = 'hidden';
    }
    a.onclick = doadvance;
}

window.onload = clickadvance;

Working from the last part of the script, the window's onload event gets set to the clickadvance initialization function. You could set the body's onload event instead, but you would need to do so in the actual body tag, since the body isn't created until after the document's head section has been fully read in.

clickadvance()

This function checks that the browser is capable of doing the DHTML we require, and only initializes things if it can.

We first test if the document.getElementById() function is available. If it isn't, we silently fail. If it is, we look for the list we'll be manipulating, as well as the "Next" link which will trigger our click event handler. Another reason for actually using and testing getElementById() is older Opera versions return true for testing if the function exists, but they don't actually implement it. By testing the return value, we know that the function actually works. Also, if either the list or the next link are incorrectly defined on the page, we'll not enable our DHTML function.

Once we've determined that we can use DHTML for the current browser, we loop through all the items in that list (which we assume to be either a <ul> or <ol> list). We make sure that we only apply the hidden class if the child is a list item, and only if the item doesn't not already have a class of nohide declared. Beware that if any other class is declared, it will get overwritten when the class name is set to hidden. If you wish to have multiple classes, the assignment needs to be changed to append the hidden class, and the doadvance() function also needs to be changed to only remove the hidden class.

Another test we do when we loop over the list items is to skip the first item, so that it will not be hidden too.

The last line of the function sets the onclick handler of the "Next" link to our doadvance() function.

doadvance()

This function is called when the "Next" link is clicked. We do not test whether getElementById() exists or even if our search for the target list succeeds, because we have already done so in clickadvance(), and this function will not get called unless the tests in that function succeed. However, if you have other scripts on the page which can possibly remove the target list, you should make this function also test the object returned when looking for our list.

Once we've found our list, we iterate over the list items, skipping those which are other kinds of objects. When we find the first one with a class of hidden, we clear the class and return false, which causes the "Next" link to not be followed.

If we find no hidden list items, we return true, which tells the browser to follow the link.