The Road to HTML 5: getElementsByClassName()
Welcome back to my semi-regular column, "The Road to HTML 5," where I'll try to explain some of the new elements, attributes, and other features in the upcoming HTML 5 specification.
The feature of the day is getElementsByClassName()
. Long desired by web developers and implemented in Javascript libraries like Prototype, this function does exactly what it says on the tin: it returns a list of elements in the DOM that define one or more classnames in the class
attribute. getElementsByClassName()
exists as a method of the document
object (for searching the entire DOM), as well as on each HTMLElement
object (for searching the children of an element).
The HTML 5 specification defines getElementsByClassName()
:
The
getElementsByClassName(classNames)
method takes a string that contains an unordered set of unique space-separated tokens representing classes. When called, the method must return a liveNodeList
object containing all the elements in the document, in tree order, that have all the classes specified in that argument, having obtained the classes by splitting a string on spaces. If there are no tokens specified in the argument, then the method must return an emptyNodeList
. If the document is in quirks mode, then the comparisons for the classes must be done in an ASCII case-insensitive manner, otherwise, the comparisons must be done in a case-sensitive manner.
A Brief History of getElementsByClassName()
- September 2005: getElementsByClassName() Implementation Questions and followups discuss whether
getElementsByClassName()
should take a string with multiple classnames, and if so, what that would mean. Despite early protests, it was eventually decided thatgetElementsByClassName()
should take multiple classnames in a single string, separated by spaces, and that the function should return elements that define all of given classnames. - February 2006: "I see this is still an open issue."
- October 2006: "This omnibus edition of your WHATWG mail includes replies to 50 or so separate e-mails about getElementsByClassName()."
- February 2007: "I landed support for this on the Mozilla trunk, and it will appear in upcoming Firefox alphas and betas. The array argument turned out to be quite a pain to implement, so we cut it." Ian Hickson responds: "I've changed the spec to use a space-separated list. ... I've dropped the array form altogether."
- March 2007: John Resig puts Firefox 3's implementation to the test in getElementsByClassName Speed Comparison.
- July 2007: "I suggest that participants in this thread reacquaint themselves with the discussion in the previous one before having it again." Good luck with that.
- September 2007: "A popular and useful feature [in Opera 9.5] will be the addition of native support for getElementByClassName from HTML5."
- December 2007: "Last week WebKit joined upcoming versions of Firefox and Opera in supporting [getElementsByClassName]."
- December 2007: "Currently getElementsByClassName is specified as always being case sensitive. This would be fine, except that the primary other use of html class names (CSS selector matching) is only case sensitive in standards mode. This leads to situations ... in which CSS and getElementsByClassName match different results."
- July 2008: Ian Hickson responds: "I've made it consistent with how classes work in CSS (case-insensitive for quirks and case-sensitive otherwise)."
Can We Use It?
Yes We Can! As you can tell from the timeline, getElementsByClassName()
is supported natively in Firefox 3, Opera 9.5, Safari 3.1, and all versions of Google Chrome. It is not available in any version of Microsoft Internet Explorer. (IE 8 beta 2 is the latest version as of this writing.) To use it in browsers that do not support it natively, you will need a wrapper script. There are many such scripts; I myself am partial to Robert Nyman's Ultimate GetElementsByClassName. It uses the native getElementsByClassName()
method in modern browsers that support it, then falls back to the little-known document.evaluate()
method, which is supported by older versions of Firefox (since at least 1.5) and Opera (since at least 9.27). If all else fails, Robert's script falls back to recursively traversing the DOM and collecting elements that match the given classnames.
And in conclusion
getElementsByClassName()
is well-supported across all modern browsers except IE, and a performance-optimized open source wrapper script can cover IE and older browsers.