Skip to content

Instantly share code, notes, and snippets.

@mythz
Created March 8, 2011 17:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mythz/860649 to your computer and use it in GitHub Desktop.
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
/*
* 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