Tuesday, August 02, 2005

Subtleties of getElementsBySelector

I should point out that my implementation of getElementsBySelector corrects a couple of subtle bugs in the original version. For one thing, the original version searches for nodes of the form #foo by using document.getElementById; this results in finding the outermost node in the entire document whose ID matches, even if searching a subtree. Since ID's are not guaranteed to be unique, this can produce the wrong node.

An even more subtle bug in the original version is that multiple copies of the same node may appear in the result array. For example, the selector '.foo .bar .mumble', when applied to the following tree:
<div class="foo">
<div class="bar">
<div class="bar">
<div class="mumble">mumble</div>
</div>
</div>
</div>
...produces two copies of the mumble node, because it finds it by following two different paths. By contrast, my implementation visits each node in the entire document tree exactly once, so it is guaranteed to produce either 0 or 1 copy of each node in the result array.

1 comment:

Anonymous said...

"this results in finding the outermost node in the entire document whose ID matches, even if searching a subtree. Since ID's are not guaranteed to be unique, this can produce the wrong node."

Are you kidding??

Speaking of the "id" attribute, W3C has this to say: "This attribute assigns a name to an element. This name must be unique in a document."

(See the spec)

This functionality is further underscored by the fact that there is no "node.getElementById()" method available, it always must be used as "document.getElementById()".

The purpose of "id" is to assign a unique identity to an element. If you don't want uniqueness, that's what "class" is for.

The bottom line is that IDs are guaranteed to be unique, unless you make a practice of breaking the rules of valid XHTML. If you run into a case where getElementsBySelector() catches the wrong element by ID, then the proper place to fix the problem is to make sure all of your ID attributes are uniquely-named, not in fixing the "bug" which pointed out your error.

Don't fix what isn't broken. If anything, your changes to this function simply make is easier for people to ignore the standards which have made the web relatively simple to code for in recent years. That's not good!

-www.kramers.ws