Created
August 14, 2009 23:53
-
-
Save louisremi/168158 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(jQuery){ | |
// This shortTermMemory will contain the last parsed simple selector. | |
// To be usefull it needs to be accessed faster than it would take to re-parse the selector. | |
// Selectors are to complex to serve as keys of a hash, and a bi-dimensional array would be too slow. | |
// I'm wondering if .data() would be fast enough for that purpose. | |
var shortTermMemory = []; | |
jQuery.fn.extend({ | |
closest: function( selector, context ) { | |
var pos, closer = 0, re, split, | |
// Fetch the last succesfully parsed selector | |
memory = shortTermMemory; | |
// We are lookig for simple selectors such as "div", ".class" or "div.class" | |
// If the selector has not previously been parsed | |
if (selector != memory[0]) { | |
// We will parse the selector and stop parsing as soon as possible, to do as few tests as possible | |
split = selector.split('.'); | |
if (split.length < 3) { | |
re = /^(?:[\w\u00c0-\uFFFF-]|\\.)*$/; | |
// The selector begins with a tag (memory[1] = TAG) or with a "." (memory[1] = true) | |
if (memory[1] = split[0] != ""? (re.test(split[0])? split[0] : false) : true) { | |
// The second part of the selector is a class (memory[2] = class) or there is no second part (memory[2] = true) | |
if(memory[2] = split[1]? (re.test(split[1])? " " + split[1] + " " : false) : true) { | |
// If we arrived that far, we found a simple selector | |
memory[0] = selector; | |
shortTermMemory = memory; | |
} | |
} | |
} | |
} | |
// If we haven't memorized the new selector, it wasn't simple | |
if(selector != memory[0]) { | |
// discard the memory | |
memory[0] = false; | |
// check for a position selector | |
pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null; | |
} | |
return this.map(function(){ | |
var cur = this; | |
while ( cur && cur.ownerDocument && cur !== context ) { | |
// the selector was a position | |
if ( pos? pos.index(cur) > -1 : ( | |
// the selector was simple | |
memory[0]? ( (memory[1] === true || jQuery.nodeName(cur, memory[1])) && (memory[2] === true || (" " + cur.className + " ").indexOf(memory[2]) != -1)) | |
// The selector was complex | |
: jQuery(cur).is(selector))) { | |
jQuery.data(cur, "closest", closer); | |
return cur; | |
} | |
cur = cur.parentNode; | |
closer++; | |
} | |
}); | |
} | |
}); | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment