How I wrote the list thingy in Javascript

It is assumed you know basic Javascript before reading this and know what the DOM is.

First the source code:

function setUp() {
    var myULs = document.getElementById('tree').getElementsByTagName('ul');
    for (var i = 1; i < myULs.length; i++) {
        var toggleObject = document.createElement('a');
        toggleObject.innerHTML = '+ ';
        myULs\[i\].parentNode.insertBefore(toggleObject, myULs\[i\].parentNode.firstChild);
        toggleObject.onclick = eventCaller(toggleObject, myULs\[i\]);
    }
}

function eventCaller(toggleButton, list) {
    list.style.display = 'none';
    return function() {
        if (list.style.display == 'none') {
            list.style.display = '';
            toggleButton.innerHTML = '- ';
        } else {
            list.style.display = 'none';
            toggleButton.innerHTML = '+ ';
        }
    }
}

onload = setUp;

First, how function setUp works.

var myULs = document.getElementById('tree').getElementsByTagName('ul');

To use the code you need an element with the id of “tree” surrounding the list you want it to work. This code just gets a collection of ul tags with in the id="tree" tag. This collection is looped through using a for loop.

var toggleObject = document.createElement('a');
toggleObject.innerHTML = '+ ';

This creates a new anchor a element and sets the text inside to a plus sign. I probably shouldn’t use innerHTML but it makes things simpler.

myULs[i].parentNode.insertBefore(toggleObject, myULs[i].parentNode.firstChild);

This looks messy but is really simple. _someNode_.insertBefore adds a node to _someNode_ before some child of _someNode_. In this case we want our newly created anchor tag to be the first child of the ul’s parent. (i.e. place the link before the ul and before any text as well).

toggleObject.onclick = eventCaller(toggleObject, myULs[i]);

The onclick event is then set to some function. It is important to realise the onclick is not set to eventCaller but the function eventCaller returns.

function eventCaller(toggleButton, list)

The function is called with two arguments: a list and the link before it that will toggle the display of the list.

list.style.display = 'none';

First we just set the list to not display by default.

Then the clever bit, we return a function.

What the function does is simple, it toggles the display style attribute of the list and changes the “button” between plus and minus signs.

But the function is different for each list. Because the function is declared within another function, this new anonymous function still has the scope of the function that created it. This means each copy of this new function has different list and toggleButton variables.