with Imagination: by Dustin Diaz

./with Imagination

A JavaScript, CSS, XHTML web log focusing on usability and accessibility by Dustin Diaz

getElementsByClass

Friday, August 12th, 2005

I’ve found a few good one’s out there. But none I was satisfied with. So with all due respect. I wrote my own:

getElementsByClass Function

function getElementsByClass(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\\\s)"+searchClass+"(\\\\s|$)");
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

How it works

It’s simple. It works just how you think getElementsByClass would work, except better.

  1. Supply a class name as a string.
  2. (optional) Supply a node. This can be obtained by getElementById, or simply by just throwing in “document” (it will be document if don’t supply a node)). It’s mainly useful if you know your parent and you don’t want to loop through the entire D.O.M.
  3. (optional) Limit your results by adding a tagName. Very useful when you’re toggling checkboxes and etcetera. You could just supply “input“. Or, if you’re like me, and you said Good Bye to IE5, you can use the “*” asterisk as a catch-all (meaning ‘any element).

See getElementsByClass() in action Have Fun!

42 Responses to “getElementsByClass”

  1. Patrick Fitzgerald

    I haven’t tested this, but it looks like it might match partial class names - so if you specify “foo” it will match “foo” and “foobar”. Perhaps the regexp should have \b (backslash b) to indicate a word boundary? Of course you can always specify that in the searchClass parameter.

  2. Justin P

    I’ve yet to need such a function, but I have thought it would be nice to have one in the toolbox at least a couple times (found a workaround both times).

    Have you ever used the getElementsBySelector()? It’s kinda like your function, but on major steroids. I first saw it referenced in an ALA article a year or so ago, looks pretty slick but again, I’ve never had the need for it.

  3. Mike Purvis

    Hmm, my Firefox isn’t grokking that RegEx object.

    Perhaps I’ll stick to one of these, for now.

  4. Dustin Diaz

    I wanted to present this function because I used it for endable/disabling input sets (Later Post).

    This is just a quick way to reference any group of tags that you need without hassle.

  5. Dustin Diaz

    Patrick & Mike. You have solid points. It hadn’t occurred to me until now that it would match partials (which is what I wanted it to do in the beginning).

    I originally had this:

    if ( els[i].className == searchClass )

    but then that would crash foo == ‘foo bar’ (which, I would want to match.

    Maybe I’ll add the \b word-boundary or just pull an indexOf() or split()

  6. Jason Beaird

    That’s a handy function. I really don’t do a lot of javascript work but I had a friend help me write something similar the other day for a greasemonkey script. It loops through the mapping page on geocaching dot com removing all instances of disabled=”disabled” so you can zoom in and out on their maps without a premium membership. :) Looking forward to your post on enabling/disabling input sets to see how similar your function is to the one may friend and I wrote.

  7. Dustin Diaz

    Looking forward to your post on enabling/disabling input sets to see how similar your function is to the one may friend and I wrote.

    It’s a work in progress. I’m trying to make it as highly scalable as possible so that anyone can plug it into their page and be on their way. I’d also like to add the functionality of disabling children an optional parameter rather than hardcoded. Most likely a separate function you could call from the constructor.

  8. Cristobal Dabed

    I composed a similar code, with functions I found and modified a bit(not that much) the first from Oreilly Javascript book(don’t remember exact which one) and the second from the S5 slideshow javascript code.

    /**
    * Gets all the Elements by given Class
    * Name
    *
    * @param string name Name of the css class
    * to look for
    * @param object node The node you want to
    * start from,start at
    * root if no one is
    * specified
    *
    * @returns array Returns an array
    * containing all the nodes
    * given by the specified
    * className
    */
    function getElementsByClass(name,node){
    var elements = new Array();
    if(!node) node = document.body;
    if (node.nodeType == 1 /*Node.ELEMENT_NODE*/){ // Check if n is an Element
    var children = node.childNodes;
    for(var i=0, n = children.length; i

  9. Dustin Diaz

    Alrighty. I’ve made one final edit. I took Patrick’s advice and added the \b word boundary filter to the RegExp. Notice it needs to be passed into the object as a string literal so the backslash needs to be escaped as well. Hence the double backslash.

    This seems to now be full proof for the most part and highly portable. There could namely be a few more exceptions that have to do with bad argument passing, but this assumes, for the most part, that the developer knows enough to get it working properly.

  10. Joseph

    I’m don’t do much JS, but I believe there’s a small typo in the code supplied above, which explains at least why it wouldn’t work on firefox (see comment #3 from Mike). The Regular Expression object is created with “RegEx”, though I believe it should be named “RegExp”. Which is the way the class is written on the example page.

    Nice piece of work.

  11. Dustin Diaz

    Good catch joseph,
    I went ahead and edited it appropriately.

  12. Jeff Minard, Web Developer

    LinkJax 1.0

    Looking to hop on that AJAX bandwagon? Here’s an extremely simple, unobtrusive library that will get your pages AJAX’ed and rolling in less than 30 minutes….

  13. Jonathan Snook

    Y’know, it’s funny how we all end up doing something similar.

  14. Dustin Diaz

    Jonathan,
    it’s because we’re the inovative one’s. ;)
    The fact that we are all doing the same thing goes to show that we’re doing something right and thinking on the same level. Good job as well :D

  15. Matt Schinckel

    Hey, this was exactly what I needed.

    Except, I made one slight change: I ordered the arguments differently, so I can skip node and tag, if necessary.

    function getElementsByClass(searchClass,tag,node)

    I figure I’m more likely to want to limit by tag, rather than by node, but I’m new to this.

    Then I have a could of checks against undefined, and set them to reasonable defaults.

    By the way, I use the same theme.

  16. wayne-0

    Doesn’t handle multiple class names in the class string :( the Dojo implementation is a bit slow and this looked perfect, if it handled multiple classes. Excellent otherwise, very fast.

    :)

    w

  17. Jules Manson

    Simply ingenius except for one thing… it only gives me lemons. Please take a look at my code to see what I may be doing wrong. It gives me errors on internet explorer 6.0 with Windows and Firefox 1.0 only ignores it. Here is my entire test page. Thank you so much for taking a few moments out of your long day to help out a beginner inspired by your brilliance.

    TEST JAVASCRIPT

    BODY {margin:30px; background:#000; color:#FFF; font-size:20px;}
    .bold {font-weight:bold;} .lemon {color:#FF0;} .lemonade {color:#FFB;} .lime {color:#0F0;}

    var i,ce,ceLen;
    ce = getElementsByClass('document','lemon','DIV');
    ceLen = ce.length;
    for(i=0;i

    1. Lemon text should change to lime.
    2. Bold lemonade text should not change.

  18. Dustin Diaz

    Jules,
    Did you see the test page? This has surely been tested by many folks and I’ve used it in several places not only on my personal website, but in Y! code as well…so I know it works.

  19. thinsoldier

    for the hundredth-millionth time I ask….
    Where/when/how/who do we submit these functions to so that they will someday become an official part of the standardized javascript stuff?

    After all there’s an official getElementByID, getElementsByName(), getElementsByTagName…It’s moronic for there not to be a finalized and official getElementsByClass instead of everyone having to write their own and then find out it’s already been done by 300+ other people.

  20. thinsoldier

    maybe I’m using it wrong but this refuses to work for me.
    Firefox if give off errors like

    node has no properties
    and
    node.getElementsByTagName is not a function

    very weird.

  21. thinsoldier

    think maybe you could shoot me an email on this?
    I’ve given up on yours, it refues to work. I have no idea what I’m doing wrong.

    this worked fine tho

    function getElementsByClassName(node, classname)
    {
    var a = [];
    var re = new RegExp(’(^| )’+classname+’( |$)’);
    var els = node.getElementsByTagName(”*”);
    for(var i=0,j=els.length; i

  22. Dustin Diaz

    hey there thinsoldier,
    I updated the function above to make it so the 2nd and 3rd arguments are optional. But still, it should have worked. What browser are you using?

  23. ye pog

    If this becomes a repeat post I’m sorry. I got a funky error page, so I wasn’t sure if my first post, (on your top ten list page) worked.

    I can’t seem to get this to work. I’m only a very amateur Javascript user- I mainly use it to complement CSS to make my websites a little more interesting. I pasted the getElementsByClass function into my script.js file, but whenever I use it, Firefox tells me that the function is undefined. Pardon my stupidity, but how would one properly link this to say a onmouseover event handler? I can do that much for my own functions, but not with this. Also, can I use this like getElementsByClass(’class’).style.[...] to change styles for a whole class? I know that you can do that with Javascript altering CSS, but getElementsByClass would be more handy, since there’s the optional tag argument.

    I apologize for my lack of basic knowledge, but this excites me so much that I want to know how to use it!

  24. Dustin Diaz

    getElementsByClass returns an array. Thus the ‘Elements’ is what you’re collecting. So you can’t explicitely call a property straight off the array. You need to do the following:

    var myEls = getElementsByClass('myClass');
    for ( i=0;i<myEls.length;i++ ) {
    // do stuff here with myEls[i]
    }

  25. thinsoldier

    I’ll give it another try. Using firefox and IE btw.

  26. koooer’s Blog » Blog Archive » getElementsByClass

    [...] On Road 各类Linux/Unix的下载地址 » getElementsByClass from function getElementsByClass(searchClass,node,tag) { var classElements = new Array(); if ( [...]

  27. http://www.2mdc.com/blogs/programacion-web/5

    [...] ción, que resulta de una generalización de la función getElementByClass que podemos encontrar en http://www.dustindiaz.com/getelementsbyclass/, nos permite llenar ese hueco con la ventaja adicional de que podemos utilizar atributos no definidos en [...]

  28. GetElementsByAttribute

    [...] ción, que resulta de una generalización de la función getElementByClass que podemos encontrar en http://www.dustindiaz.com/getelementsbyclass/, nos permite llenar ese hueco con la ventaja adicional de que podemos utilizar atributos no definidos en [...]

  29. GetElementsByAttribute()

    [...] ción, que resulta de una generalización de la función getElementByClass que podemos encontrar en http://www.dustindiaz.com/getelementsbyclass/, nos permite llenar ese hueco con la ventaja adicional de que podemos utilizar atributos no definidos en [...]

  30. Collapsable effects with Script.aculo.us

    [...] e Element object, even the getElementsByClassName prototype so you won’t need to use my own custom function for t [...]

  31. Forget addEvent, use Yahoo!’s Event Utility

    [...] Alright, so I know what you’re thinking. Does that mean I can use Dustin’s getElementsByClass function and pass in the array which will, in return, assign listeners to the object collection? Indeed my dear beloved friends. Indeed. [...]

  32. Episode 05: The State of JavaScript

    [...] Both Dustin and Jonathan have their respective versions of a getElementsByClassName function. [...]

  33. getElementsByClassName Deluxe Edition | Muffin Research Labs

    [...] Dustin Diaz’s getElementsByClass [...]

  34. » Class Names and JavaScript » Hvassing.com

    [...] I’ve managed to do the first two, or rather Dustin Diaz managed to do the first bit. The problem is that I have five different class names that I want to have either the original colour or to be plain black. Thus, with five classes there is a lot of code if one want to do it the hard way, and I haven’t found the easy way yet. The second problem is that the changing back algorithm is not pretty — at all. Code overhead is a major issue here. [...]

  35. The “add a class name” JavaScript widget philosophy with “Fantasticulator”

    [...] Without looking under the hood of any library that requires you to add a class name to your document to receive the super-cool functionality, it’s fairly obvious what needs to get done. Like any other getElementsByClassName function, you need to supply a class name, a tag name, and a root node. And to generalize things to a base level that gives the implementer the most amount of flexibility, you must start at the document root then crawl all the way to the bottom checking each and every node for a class name. To say the least… that’s bad. Client-side performance of the “add a class name” philosophy is reason-nuf (reason enough) to avoid implementing this style of widget-making. [...]

  36. RamonPage.com . Web na ponta do lápis » Blog Archive » Mostrar-esconder conteúdo via DOM

    [...] Após, foi preciso apenas uma função para localizar a classe lang-eng e efetuar as alterações nas páginas em que ela foi instanciada. Utilizei como base o script getElementByClass do Dustin Diaz. A partir daí, otimizei o script para chegar ao resultado que gostaria. [...]

  37. Chumby.net » Blog Archive » Netflix Queue Randomizer

    [...] All of the sort order input boxes on the Netflix Queue page has a class of “o”. The first for loop at line 6 goes through all of the input elements in the HTML, checks for className=”o” and stores all of those elements in an array.  This is pretty the same as doing var q = document.getElementsByClass(”o”). [...]

  38. JS, just it : Parte 2 - Implementando o getElementsByClassName » Angeruzzi.com

    [...] Esta função já é bem comum e é encontrada nas mais variadas bibliotecas de JavaScript com diversas implementações. Aprecio as versões de vários autores como a do Robert Nyman e a do Dustin Diaz, porém prefiro utilizar uma que desenvolvi de acordo com as necessidades que foram surgindo. Além do mais ela está num formato bem simples e didático [...]

  39. John Resig - getElementsByClassName Speed Comparison

    [...] Dustin Diaz’s getElementsByClass [...]

  40. aNieto2K | Comparativas de getElementsByClassName

    [...] Dustin Diaz’s getElementByClass [url] [...]

  41. getElementsByClassName Speed Comparison « outaTiME

    [...] Dustin Diaz’s getElementsByClass [...]

  42. Trantor Prime » The getElementsByClass function

    [...] There are many versions of this, but I always use the one by Dustin Diaz. Here is the link to his original article [...]

Get "JavaScript Design Patterns"

"As a web developer, you'll already know that JavaScript™ is a powerful language, allowing you to add an impressive array of dynamic functionality to otherwise static web sites. But there is more power waiting to be unlocked--JavaScript is capable of full object-oriented capabilities, and by applying OOP principles, best practices, and design patterns to your code, you can make it more powerful, more efficient, and easier to work with alone or as part of a team."

Buy JS Design Patterns from Amazon.com Buy JS Design Patterns from Apress

Submit a Prototype

All content copyright © 2003 - 2007 under the Creative Commons License. Wanna know something? Just ask.

About | Archives | Blog Search

[x] close

Loading...

Submit a prototype

By checking this prototype I agree that I am not submitting false credentials, pornography, or a hate crime website. I also understand that by submitting my entry I may or may not be accepted, and if accepted, my entry may be taken down at any given time if I violate these terms.