getElementsByClassName without jQuery

In addition to “addClass, removeClass and hasClass without jQuery” article I wrote an example implementation of getElementsByClassName() method to catch a collection of objects, referencing them by their class name, when you can’t or don’t want to use jQuery and it’s superb class-selectors.

In original JavaScript definition there are functions getElementsByTagName() and getElementById(), but there is now such function (or equivalent) like getElementsByClassName(). Many modern browsers has introduced this function (for example starting from Firefox 3 you can use it), but there is no such function in original JS definition and you’re using build-in ones on your own risk.

To counteract this risk, I decided to use my own declaration of such function instead. So I’ve googled just a little bit and found this piece of code:

document.getElementsByClassName = function(cl)
{
    var retnode = [];
    var myclass = new RegExp('\b'+cl+'\b');
    var elem = this.getElementsByTagName('*');

    for (var i = 0; i < elem.length; i++)
    {
        var classes = elem[i].className;
        if (myclass.test(classes)) retnode.push(elem[i]);
    }

    return retnode;
};

Original version works fine. I don’t know regular expressions (and even more — I don’t like complicating easy things), I rewrote them to version presented below. Also, if you may occasionally run into Internet Explorer’s idiotic on-load bug, you’ll find my version, without regular expressions, the only one working:

document.getElementsByClassName = function(className, objectType)
{
    objectType = (objectType != "") ? objectType : "*";

    var objects = [];
    var objectsArray = document.getElementsByTagName(objectType);

    for(e in objectsArray) if((typeof objectsArray[e].className === "string") && (objectsArray[e].className !== "") && (document.hasClass(objectsArray[e], className))) objects.push(objectsArray[e]);

    return objects;
};

The for loop might look scary at first sight, but in general it does not do too much magic. It simply iterates over each element of objects array, checks if particular object has a class that is a string (which means, that an object exists; this is again thanks to stupid Internet Explorer, which were returning not existing elements in objectsArray), if object’s class isn’t empty and if so – it finally checks if particular object has the same class, as we’re looking for. If all conditions are met, loop is pushing objects array with this new object.

I’m a total regular expressions newbie. And I also don’t need them here (they’re just complicating things that are easy). So, my version of this function satisfy me enough. But if you still need to use regular expressions and want to avoid stupid IE problem, you may consider replace() function, which works also on regular expressions.

You can also notice, that I have enhanced original version (above) of this function, with an ability of providing object type. If you’re looking for a class given to a specific type of objects only, this could be much faster, then specifying “*” (or “”) as last parameter, which will search through all objects in your page.

And here you have an example of using above function:

function bindEventToGridViewRows()
{
    var oddsArray = document.getElementsByClassName('odd', 'tr');
    var evenArray = document.getElementsByClassName('even', 'tr');
    var objectsArray = oddsArray.concat(evenArray);

    for(e in objectsArray)
    {
        anObject = objectsArray[e];

        if(typeof anObject !== "undefined") anObject.onclick = onGridViewSelectionChange;
    }
}

Call to this function in onload page of body element in one of my pages is attaching specific onClick handler to all table rows in one of my tables in that page.

You may also be interested in “addClass, removeClass and hasClass without jQuery” article.

Leave a Reply