Extending the DOM: an example

About five years ago, Stephen Howard created a little JavaScript utility library that is, in its simplicity, a beautiful masterpiece, because it extends many DOM functionalities and makes common tasks trivial. I'd like to spend some words on the DOMCreate utility. Stephen says:

It has been fairly common in code I've had to write to create one or more html elements and subsequently set many of their attributes, append children and register event listeners. Rather than write line after line of <element.property='foo'> and element.onevent=function(){}, DOM.Element.Create allows a more declarative approach to defining new elements.

DOM.Element.Create does not export any methods by default, but allows you to export either of the methods described below.

The first method is createElement:

Pass a tagName and an associative array of attributes to this method and get back the correpsonding element. attribute names are not checked for validity, allowing the possibility of adding custom attributes to an element.

createElement: function(tagName,attributes) {
        if( !tagName ) return null;
        var element = document.createElement(tagName);
        if( !element ) return null;

        return DOM.Element.Create.updateElement(element,attributes)
}

This method first creates a given element through the W3C DOM method createElement and then adds a list of attributes to the newly created element by calling the updateElement method, which is as follows:

updateElement: function(element,attributes) {
        if( !element ) return null;

        for( var attr in attributes ) {
            switch(attr) {
            case 'style':
                for( var property in attributes[attr] ) 
                    element.style[property] = attributes[attr][property];
                break;

            case 'events':
                for( var event in attributes[attr] ) 
                    addListener(element, event, attributes[attr][event] );
                break;

            case 'childNodes':
                for( var i = 0; i < attributes[attr].length; i++ ) {
                    var child = attributes[attr][i];

                    if( child ) {
                        if( typeof child == 'string' )
                            child = document.createTextNode( child );

                        element.appendChild( child );
                    }
                }
                break;

            default:
                element.setAttribute(attr,attributes[attr]);
            }
        }

        return element;
    }


This method accepts an element and a list of attributes as its arguments. Attributes can be CSS styles, events or child nodes. For each type of attributes, an action is performed through a switch statement. If no attribute name is provided, the method uses the W3C DOM method setAttribute to set a default attribute for the element. The main problem, however, is that this method uses two for...in loops to do its job, which can sometimes be expensive in terms of JavaScript performance. Nevertheless, this is a great example of a useful technique for extending the DOM.

Leave a Reply

Note: Only a member of this blog may post a comment.