I personally never use $$ because when I tried it, it was noticeably slower 
than other methods.
My solution to grabbing elements from a large DOM was to override 
document.getElementsByClassName with a function that adds an extra parameter, 
tagName. This allows it to filter elements by tagName before applying any other 
filter rather than grabbing EVERY element in the DOM.

>From my unscientific tests this is considerably faster.
Example: you have a complex conglomeration of nested div, span, ul, li, a 
elements that together compose a nice tree (with parent 'tree1'). You want to 
get all of the drag handles at once.
Rather than
document.getElementsByClassName('handle','tree1');
I would use
document.getElementsByClassName('handle','tree1','span');

Already that cuts out probably half or more of the elements. That's half as 
many regular expression matches required for a few extra characters of code, 
and it is backward compatible with the original.
I have no idea why the original override in prototype doesn't do this, that 
getElementsByTagName('*') just stuck out to me like a sore thumb as a prime 
candidate for an easy improvement.

Of course if you want to filter by class and tag only you can
document.getElementsByClassName('handle',null,'span'); //or document.body but 
that is longer to type..

----------
/* override the Prototype function, this one adds a 'tag' argument and uses 
xpath where possible */
document.getElementsByClassName = function(className, parent, tagName) {
        if(document.evaluate && $(parent) && $(parent).documentElement){
                var xpathResult = document.evaluate("//"+(tagName||'*')+"[EMAIL 
PROTECTED]'"+className+"']",
                        $(parent), null, 
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
                var outArray = new Array();
                for(var i=0; i<xpathResult.snapshotLength;i++){
                        outArray[i] = xpathResult.snapshotItem(i);}
                return $A(outArray);
        }else{
                var children = ($(parent) || 
document).getElementsByTagName((tagName || '*'));
                return $A(children).inject([], function(elements, child) {
                        if (child.className.match(new RegExp("(^|\\s)" + 
className + "(\\s|$)")))
                                elements.push(Element.extend(child));
                        return elements;
                });
        }
}

Colin



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Spinoffs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-spinoffs
-~----------~----~----~----~------~----~------~--~---

Reply via email to