Do we have getElementsByClassName in javascript?

i will have to iterate through all tags and then collect all elements which are having the same class as specified.

Yes. There are a couple of ways to improve the function from the page you linked, though:

  • RegExp-escape class names passed in so that it isn’t broken by punctuation in the class name. For example a call to getElementsByClassName('ab.cd') shouldn’t match class="abxcd".

  • The HTML5 specification that defines getElementsByClassName allows multiple space-separated class names, all of which have to be present on the element to match. Implement this.

  • optionally, allow a hint of tag name to be passed in to narrow down the number of elements the function has to look through for the common case where only one type of tag is affected. (This will do nothing on a real browser-native getElementsByClassName call, so you shouldn’t rely on it to filter out elements you don’t want.)

Example implementation:

if (!('getElementsByClassName' in document)) {
    document.getElementsByClassName= function(classnames, taghint) {
        var exps= classnames.split(/\s+/).map(function(name) {
            name= name.replace(/([/\\^$*+?.()|[\]{}])/g, '\\$1');
            return new RegExp('(^|\\s)'+name+'(\\s|$)');
        });
        var els= this.getElementsByTagName(taghint || '*');
        var matches= [];
        for (var i= 0, n= this.length; i<n; i++)
            var el= els[i];
            if (exps.every(function(exp) {
                return exp.test(el.className);
            }))
                matches.push(el);
        }
        return matches;
    };
}

However this does also use a couple of ECMAScript Fifth Edition (or JavaScript 1.6) Array methods which IE doesn’t yet have either, so you’d have to add fallback implementations for those, too:

if (!('map' in Array.prototype)) {
    Array.prototype.map= function(mapper, that) {
        var other= new Array(this.length);
        for (var i= 0, n= this.length; i<n; i++)
            if (i in this)
                other[i]= mapper.call(that, this[i], i, this);
        return other;
    };
}

if (!('every' in Array.prototype)) {
    Array.prototype.every= function(tester, that) {
        for (var i= 0, n= this.length; i<n; i++)
            if (i in this && !tester.call(that, this[i], i, this))
                return false;
        return true;
    };
}

Leave a Comment