Monday, September 21, 2009

One Function To Trap Them All

This is a quick one. This technique could have some side-effect I am not aware about but I've never seen it so far in any library. Talking about LiveMonitor I have successfully tested same concept to create faster implementation of some of my DOM common code, not yet updated in vice-versa.

document.getElementsByClassName Example


(function(childNodes){

/* Another (C) WebReflection Silly Idea */

// how to re-use them all, just an example
if(!document.getElementsByClassName)
document.getElementsByClassName = function getElementsByClassName(className){
for(var
re = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"),
ret = [], i = 0, l = 0, length = childNodes.length, node;
i < length; ++i
){
if((node = childNodes[i]).nodeType === 1 && re.test(node.className))
ret[l++] = node
;
};
return ret;
}
;

// let the magic happen
})(document.getElementsByTagName("*"));

What we have here?
  1. A trapped live object, probably used in 90% of selector libraries, but performed via scope resolution (the document) and a function execution (the getElementsByTagName method) over all nodes ("*")
  2. a theoretically zero performances impact to retrieve again every node, being live there is no need to refresh it, and being trapped run-time, it will contain few nodes during the first execution
  3. a single scope able to create N functions based on one of the most common created HTMLCollection


What do you think?

Labels: , , , , ,

12 Comments:

Anonymous Anonymous said...

Nice approach. Cool way to write your for loop also.

21 September, 2009 22:42  
Blogger fearphage said...

I like the thought process here. Good idea.

21 September, 2009 23:00  
Blogger Andrea Giammarchi said...

@fearphage thanks again for the nodeType suggestion (and the silly typo for the className) :D

Cheers guys

21 September, 2009 23:55  
Blogger Samer Ziadeh said...

Hey I don't understand the regex

(?:\\s|^) doesn't that mean you're checking for character before the beg. of the line?

22 September, 2009 00:58  
Blogger Aaron Heckmann said...

Any benchmarks yet?

22 September, 2009 02:26  
Blogger Andrea Giammarchi said...

Samer, that means look for a space or it starts with and look for a space after or it ends with.
The question mark is to avoid RegExp result cache.

Aaraon, not yet, what I expect is better loop performances, what I need to test, is if a wrapped live collection, the biggest one, slows down somehow the angine a la DOMNodeInserted. I think no, but I am not sure yet.

Regards

22 September, 2009 08:45  
Blogger Andrea Giammarchi said...

OK, no slowdown at all, and actually no benefits as well. The problem is that I am basing my tests with wrong timers, so it's 0 or it's 15/16, I cannot truly understand if I it is worth it. In any case, as document.getElementsByClassName, it's really fast :D

22 September, 2009 11:35  
Blogger J5 said...

Can you elaborate on the tests you're doing? I don't understand what you mean by "The problem is that I am basing my tests with wrong timers, so it's 0 or it's 15/16"

22 September, 2009 21:15  
Blogger Andrea Giammarchi said...

J% I am taking the classic W3C page used in Taskspeed and others tests.

I put the function on the top, zero differences.

Then I perform a couple of searches, and I take time for each search.

Under windows, timers are almost useless, cause the result for a call that took 8 ms, for example, will always e 15 or 16, and never 8. This problem has been explained in John Resig blog few months (years?) ago :)

22 September, 2009 21:47  
Anonymous Nicolas said...

I like your approach very much, thanks for sharing :)

22 September, 2009 23:25  
OpenID maxart said...

It doesn't behave like a live collection... At least on IE8 SM. And it seems obvious to me, since ret is nothing more than an array.
Am I missing something?

If you want something like a static node list, you can check for querySelectorAll, which is provided by IE8 and should be a lot faster.

Massimo

22 December, 2009 15:39  
Blogger Andrea Giammarchi said...

you are missing the childNodes variables ... please read again, test, understand, and ask more if necessary. Regards

22 December, 2009 16:16  

Post a Comment

Links to this post:

Create a Link

<< Home