Javascript

Bad DOM

Oliver Brown
— This upcoming video may not be available to view yet.

The Dom Scripting Taskforce says adding non-standard markup to page using Javascript is OK. Well I wouldn’t call it a “best practice” but from a personal point of view I can’t see a practical disadvantage.

For me the problems with bad markup come from trying to parse it automatically (using PHP’s SimpleXML object for instance). Since the javascript will basically only affect the page a human sees and not a machine, many of the disadvantages of non-standard markup fade away.

How I wrote the list thingy in Javascript

Oliver Brown
— This upcoming video may not be available to view yet.

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.

Cunning closures

Oliver Brown
— This upcoming video may not be available to view yet.

I just wrote a nifty bit of Javascript to allow nested lists to be displayed as a tree with little buttons to hide and show parts. It’s incredibly simple to use.

Firstly include the javascript file with a script tag (obviously). Then put a span element around the list you want to be undisplayable that has the class tree (in fact it can be any element with the correct class).

The clever bit (for me at least) is that it uses a closure to do this. Explaining what a closure is is difficult to do quickly but it involves a function returning a function that is altered by the values passed to the function (the first one). It’s being used right now in my sidebar to display “pages”.

I quite like JavaScript

Oliver Brown
— This upcoming video may not be available to view yet.

For a long time I hated JavaScript. I think I’m beginning to like it now. The following works perfectly in Firefox and works slightly less well in IE6. http://brownab1.miniserver.com/reborn/demo.php.

To use just click and drag. Or in IE6 press the button, drag then press again.

Should Galaxia use Ajax?

Oliver Brown
— This upcoming video may not be available to view yet.

I used JavaScript once succesfully and it goes to my head…

I read a book on doing XML stuff with JavaScript and thought “Very clever. But Why?”. Well apparently it’s taking off. It’s how Google Maps works.

And if you didn’t know (I didn’t; reading blogs is actually helping me) Ajax stands for Asynchronous Javascript and XML.

It would mean you’d just drag the map to scroll in Galaxia… :D

In hindsight. No. Too much effort and too many other things I need to do…