making .closest() faster on common selectors to improve performance of event delegation.

making .closest() faster on common selectors to improve performance of event delegation.


Hi,
The principle of .closest( selector ) is that it cycles through the
ancestors of an event target until it finds an element corresponding
to the event target, or hits the root.
To check for an element matching the selectors it uses the .is
( selector ) function which collects all elements corresponding to the
selector and cycles through them to find if "this" is any of those
elements.
If my memories about my algorithm lectures are correct, the complexity
of this algorithm is O(n²). Only in the case of a selector of the form
"#id" we have an O(n) complexity.
However, there is another range of selectors that could be checked
with an O(n) algorithm: selectors such as "div", ".class" and
"div.class". In those cases, .is( selector ) is not needed because we
can directly check the ancestor's nodeType and className.
Reducing the complexity of the .closest() function is particularly
important when using event delegation with the mouseover and mouseout
events: those events fire really often as the user moves his/her
mouse, and the function needs to be used twice: one to check the the
target is in the selector, and one to check that the related target is
in a different ancestor.
I propose a new implementation of .closest() that is able to detect
those selectors and use them to "fast-check" ancestors. The last
parsed selector is cached to further improve the performances (I'm
just not sure where to cache the parsed selector).
The code is available as a gist: http://gist.github.com/168158
and can be tested here: http://www.lrbabe.com/sdoms/closest/
Together with the recent addition of the "context" parameter
in .closest(), it makes one of the most efficient event delegation
helper out there.
Feedback would be much appreciated,
Regards,
lrbabe