Bug? Prototype, IE, getElementsByClassName, and "length"

I've been swearing like a foul-tempered pirate at IE a lot this week. This was one of the problems, something that seems to be a bug in the popular Prototype framework. Hopefully, my posting it here will save someone else much frustration.

So, I have this form/datagrid thing. I want to have a button that clears the fields (not a reset, which would set them to the default state, I want them blank.) For various reasons, getByClassName seemed the best way to deal with this.

Everything was fine on Moz/Firefox. Safari seems fine. But IE...

Some detective work later, it seems that the problem is caused by *another* field on the page. (With it, problems; without it, no problems.) More detective work suggests that the problem is the field's name ("length").

More precisely, it seems getElementsByClassName in IE (6 and 7, at least) will fail to gather elements (returns zero-length array) if there is an input on the page with 'name="length"'.

Solutions: Change the name of the input, or use the optional parent argument to avoid it.

More: Looking at the getElementsByClassName declaration in prototype.js, I'd guess this is really a problem with $A or getElementsByTagName, but that's as far as I got.

Demo

Permalink • Posted in: javascript, prototype, tech stuff, webComments (4)

Comments

Chris Dolan Nov 3, 2006

Just a wild speculation: the form element called "length" is interfering with the form method called length() which is the count of elements? After all, if you have you can usually access it via form.foo.

Chris Dolan Nov 3, 2006

Doh, that was supposed to be <input name="foo">

Joshua Nov 3, 2006

Actually, as it turns out, that's sort of it.

I posted a message similar to this on the Rails-Spinoffs list. As Christophe Porteneuve explains here, the problem is an intersection between IE's "dot-id" child access (where "dot-id" includes "dot-name") and HTMLCollection, which is the object being returned by getElementsByTagName (not actually an Array, as I had previously believed).

Eric Fields Feb 13, 2007

I encountered the same issue. I had this:

itemDivs = galleryRoot.getElementsByClassName("item");
attachChecks = galleryRoot.getElementsByClassName("checkbox");

which didn't quite work in IE. I don't know if this was the best workaround but I used the $$() utility, which grabs elements by css selector. The end result was this:

itemDivs = $$(".item");
attachChecks = $$(".checkbox");

This was nice because it's less code and it "just worked," but I'm not positive that it was the right solution.

The Prototype API documentation that this utility is also very resource heavy, unnoticable on modern-day super-browsers but would be likely to kill portable devices (which is also the case with, um, most javascript...).

Thanks for the post!