'getElemsByClassName' Implemented in several ways

Benchmark created by ht_ask on


Description

There are three methods how to implement 'getElemsByClassName'. One is getting all elements by specifying an asterisk in the argument of getElemsByTagName. Two is recursively searching nodeList from childNodes. The other is using XPath but limitted browsers are supporting one. (However, the former method is not able to specify a parent element but I think it is not be a problem so much in the case of getting class name.)

Preparation HTML

<div class="parent">
        <div class="child a">a.text</div>
        <div class="child b">b.text</div>
</div>

Setup

// Case of using getElementsByTagName
    function getElementsByClassName_A(className) {
        var elements = [];
        var haystacks = document.getElementsByTagName('*');
        for (var i = 0; i < haystacks.length; ++i)
                if (hasClassName(haystacks[i], className)) elements.push(haystacks[i]);
    
        function  hasClassName(element, className) {
                var classes = element.className.split(' ');
                for (var i = 0; i < classes.length; ++i)
                        if (classes[i] === className) return true;
                return false;
        }
        return elements;
    }
    
    // Case of recursively searching nodeList
    function getElementsByClassName_B(element, className) {
        var elements = [];
        (function(element) {
                var childNodes;
                if (element.nodeType === 1 && hasClassName(element, className))
                        elements.push(element);
                if ((childNodes = element.childNodes) !== null) 
                        for (var i = 0; i < childNodes.length; ++i) arguments.callee(childNodes[i]);
        })(element);
    
        function  hasClassName(element, className) {
                var classes = element.className.split(' ');
                for (var i = 0; i < classes.length; ++i)
                        if (classes[i] === className) return true;
                return false;
        }
        return elements;
    }
    
    // Case of using XPath
    function getElementsByClassName_C(element, className) {
        var elements = [];
        var xpath = document.evaluate(
                './/*[contains(concat(" ", @class, " "), "' + className + '")]',
                element, null, XPathResult.ANY_TYPE, null
        );
        for (var item = xpath.iterateNext(); item; item = xpath.iterateNext())
                elements.push(item);
        return elements;
    }

Test runner

Ready to run.

Testing in
TestOps/sec
Case of using getElementsByTagName
getElementsByClassName_A('child');
ready
Case of recursively searching nodeList
getElementsByClassName_B(document, 'child');
ready
Case of using XPath
getElementsByClassName_C(document, 'child');
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.

  • Revision 1: published by ht_ask on