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.
As more and more browsers start supporting querySelector and querySelectorAll (including IE8b2), does getElementsByClassName still serve much purpose?
There’s a really nasty bug in the implementation of getElementsByClassName in WebKit. See https://bugs.webkit.org/show_bug.cgi?id=19974 for more details. There’s a workaround but it makes it more difficult to use it right now.
“I suggest that participants in this thread reacquaint themselves with the discussion in the previous one before having it again.” We need an acronym for that…
whoa there. sorry if this comes across as “harsh” but i think i’m missing something fundamental (or maybe the WG is). i’m very confused on why an HTML group would be attempting to specify ECMAScript functions (assuming you’re even talking about ECMA/Javascript… the actual usage is never mentioned anywhere I could find).
when and why did you decide to go this route (specifying DOM APIs and scripting language behavior) in the first place? does the “ML” part of “HTML” confuse you? 😉 having a DOM “interface” as a property collection with accessor tags (private, readonly, etc), i can understand. but methods, i think, are out of your “jurisdiction”. also, the link to the specification just starts throwing around “document.getElementByClassName(‘foo’)” as if you can call it from anywhere. “document.getElementByClassName()” then?? not likely.
and “quirks mode” is in your specification? seriously? you’re making displaying things inconsistently a language feature??
techinically IE doesn’t even support EMCA/JavaScript at all, it supports JScript, right? so are you now telling ECMA, JScript, VBScript, Python, BF, and any other client-side language I can get a browser to support that they need to implement certain functions to be HTML5-compliant? my scripting language might not even HAVE a DOM, my language might not even ALLOW “getElementsByClassName” as an identifier, or pass “parameters” and return values in the way ECMAscript does. i think this API stuff is a little outside your scope, honestly. and tends to “freeze out” scripting language developers who want to do things any other way than the ECMAScript way.
Dustin: The WHATWG isn’t just “the HTML group” — we’re defining a number of things, including the HTML language, its APIs, and its syntaxes.
Originally “HTML5” was actually called “Web Applications 1.0”, and indeed “web-apps” is still in the document’s URL. We renamed it as part of the cooperation effort with the W3C.
Regarding quirks mode, our goal is to write a (group of) specification(s) that defines everything you need to implement a Web browser, and quirks mode is part of that, whether we like it or not, so it is defined.
Regarding JScript vs JavaScript vs ECMAScript: The names are really a red herring; JScript and JavaScript are ECMAScript in the same way that Mozilla’s HTML or CSS implementations and IE’s HTML or CSS implementations are HTML and CSS. That is, there are bugs and vendor-specific variances, but by and large they’re the same thing.
Regarding ECMAScript vs other languages: The HTML5 spec is mostly language-agnostic, it just uses WebIDL to define the interfaces.
It may be obvious, but non-native
getElementsByClassName()
does not return a live NodeList, but an array. In some cases this may lead to different results in different browsers.[…] The Road to HTML 5: getElementsByClassName() […]