Attribute selectors now supported
I’ve updated document.getElementsBySelector to support CSS2 and CSS3 attribute selectors, as described here. Attribute selectors allow you to match elements based on any attribute using a variety or different rules including begins-with, ends-with, contains and more. The new version is tested in Mozilla, Phoenix and IE5/Windows (and I’m almost certain it works in IE6). There is a slight bug in Opera 7 preventing the ends-with selector from working which I have been unable to track down—any Opera javascript experts out there?
It has been pointed out that the function does not have the capability to deal with chained selectors such as div#main.layoutDiv. I have no intention of supporting this kind of advanced CSS syntax—one of my principle design aims is to keep the code short and simple, and implementing a full parser would add a lot of bulk and complexity without significantly improving the utility of the function.
gilmae - 27th March 2003 19:03 - #
Tom Gilder - 28th March 2003 01:07 - #
Harry Fuecks - 28th March 2003 11:53 - #
kusor - 28th March 2003 15:36 - #
Hello Mr. Willison, and other users of this function,
I've found this function fantastically useful, and am a big fan of the Behaviour utilisation. I found what I think is a bug in your implementation, though; three and a half years later, care to see it and a suggested fix?
Here are your lines 92-102:
for (var h = 0; h < currentContext.length; h++) { var elements; if (tagName == '*') { elements = getAllChildren(currentContext[h]); } else { elements = currentContext[h].getElementsByTagName(tagName); } for (var j = 0; j < elements.length; j++) { found[foundCount++] = elements[j]; } }I've found this will cause an error in Behaviour if I attempt a rule such as this:
#NonExistantElement childElement. The error arises from the 'else' branch in the code snippet above attempting to call getElementsByTagName from anullobject, the NonExistantElement. I've used this as a solution:for (var h = 0; h < currentContext.length; h++) { var elements = new Array; if (tagName == '*') { elements = getAllChildren(currentContext[h]); } else { //Handle the case where our currentContext does not exist, e.g. an errant element ID rule entered in a behaviour-sheet. if(currentContext[h]) elements = currentContext[h].getElementsByTagName(tagName); } for (var j = 0; j < elements.length; j++) { found[foundCount++] = elements[j]; } }No context? No problem, just work with
elementsas a 0-length array.This function's a great piece of work. Thanks for writing this version to begin with.
--Alex
Alex Nelson - 18th September 2006 19:47 - #