Created
March 8, 2011 17:54
-
-
Save mythz/860649 to your computer and use it in GitHub Desktop.
jQuery is very slow at handling poor browsers, this script added a 7.8x perf improvement
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
/* | |
* Faster jQuery DOM traversal for <= IE7. | |
* Usage: | |
* $Q() is a drop-in replacement for $(). Returns same jQuery object. | |
* | |
* //$Q = $; //Un-comment, to switch to use jQuery for benchmark comparisons | |
* My avg benchmarks in IE7 for traversing a 20x30 table was: | |
* 786ms vs 6140.67ms - Chrome can do it natively in 28ms | |
* | |
* Limitations: | |
* Requires an Id (i.e. #) or Tag Name (e.g. INPUT) in each child selector. | |
* Requires jQuery and returns a $() | |
* | |
* Valid Examples: | |
* - TBODY TD.c1 INPUT | |
* - TH.c1 STRONG | |
* - #btnSubmit SPAN | |
* - TBODY INPUT[name='chkProcess'] | |
* - TBODY INPUT[type='text'] | |
*/ | |
//NOTE: first-draft, adds vars to global namespace: doc, $id, $tag, $el, $find, $Q | |
var doc = document, $id = function(id) { return doc.getElementById(id); }, | |
$tag = function(tag) { return doc.getElementsByTagName(tag); } | |
function $el(sel) | |
{ | |
if (typeof sel == 'string') | |
{ | |
return sel.charAt(0) == '#' | |
? $id(sel.substring(1)) | |
: $tag(sel)[0]; | |
} | |
return sel; | |
} | |
function $find(rootEl, tagSel) | |
{ | |
var parts = tagSel.split('.'), tag = parts[0], cls = parts.length == 2 && parts[1]; | |
var el = $el(rootEl); | |
var filterPos = tag.indexOf('['), filterName, filterValue; | |
if (filterPos != -1) { | |
parts = tag.substring(filterPos + 1, tag.length - 1).split('='); | |
filterName = parts[0], filterValue = parts.length == 2 && parts[1]; | |
if (filterValue && filterValue.charAt(0) == "'") { | |
filterValue = filterValue.substring(1,filterValue.length-1); | |
} | |
tag = tag.substring(0,filterPos); | |
} | |
var els = el.getElementsByTagName(tag); | |
if (!cls && !filterName) return els; | |
var results = []; | |
for (var i=0,len=els.length; i<len; i++) { | |
var childEl = els[i]; | |
if ((!cls || (childEl.className && childEl.className.indexOf(cls) != -1)) | |
&& (!filterName || childEl[filterName] == filterValue)) | |
{ | |
results.push(childEl); | |
} | |
} | |
return results; | |
} | |
function $Q(selector) { | |
if (document.querySelectorAll) return $(selector); //shortcut to native eval in jQuery for decent browsers | |
var els = [], resultSet = [[document]]; | |
var args = selector.split(' '); | |
for (var i=0,len=args.length;i<len;i++) { | |
var parentSet = resultSet[i]; | |
if (parentSet.length == 0) return $([]); //short-circuit | |
var sel = args[i], results = []; | |
if (sel.charAt(0) === '#') { | |
resultSet.push([document.getElementById(sel.substring(1))]); | |
continue; | |
} | |
for (var j=0,jlen=parentSet.length;j<jlen; j++) { | |
var els = $find(parentSet[j], sel); | |
for (var k=0,klen=els.length; k<klen; k++) { | |
results.push(els[k]); | |
} | |
} | |
resultSet.push(results); | |
} | |
return resultSet.length > 1 ? $(resultSet.pop()) : $([]); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment