Created
December 10, 2011 22:16
-
-
Save patik/1456711 to your computer and use it in GitHub Desktop.
Customized Zepto for fake selectors
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
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<style> .hidden { display: none; } </style> | |
<script src="zepto.custom.js"></script> | |
<script> | |
$(document).ready(function(e) { | |
// This should print 2 results: #div3 and #div4 | |
console.log("visible:", $("div:visible")); | |
// This should print 3 results: #div1, #div2, and #div5 | |
console.log("hidden:", $("div:hidden")); | |
}); | |
</script> | |
</head> | |
<body> | |
<div class="hidden" id="div1"> | |
<div id="div2"></div> | |
</div> | |
<div id="div3"></div> | |
<div id="div4"> | |
<div style="display:none;" id="div5"></div> | |
</div> | |
</body> | |
</html> |
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
var Zepto = (function() { | |
// | |
// ... snipped the Zepto code for brevity ... | |
// | |
// Custom selectors | |
// Each method takes an array/list and returns an array of matching elements | |
// Method names match the custom selector name (eg, hidden() is for :hidden) | |
$.customSelectors = { | |
hidden: function(elems) { | |
var matches = [], len = elems.length, i = 0; | |
while (i < len) { | |
if ($.customSelectors.test.hidden(elems[i])) { | |
matches.push(elems[i]); | |
} | |
i++; | |
} | |
return matches; | |
}, | |
visible: function(elems) { | |
var matches = [], len = elems.length, i = 0; | |
while (i < len) { | |
if ($.customSelectors.test.visible(elems[i])) { | |
matches.push(elems[i]); | |
} | |
i++; | |
} | |
return matches; | |
}, | |
// This contains the Boolean functions which test a single element | |
// Which means you can't create a fake selector div:test unless you rename this... | |
test: { | |
// Pulled from jQuery and trimmed down to the basics | |
hidden: function(elem) { | |
var width = elem.offsetWidth, | |
height = elem.offsetHeight; | |
return (width === 0 && height === 0) || ((elem.style.display || $(elem).css("display")) === "none"); | |
}, | |
visible: function(elem) { | |
return !$.customSelectors.test.hidden(elem); | |
} | |
} | |
} | |
$.qsa = $$ = function(element, selector) { | |
var found, standard = "", custom = ""; | |
// Look for a colon to indicate the presence of a custom selector | |
if (selector && ~selector.indexOf(":")) { | |
standard = selector.split(":")[0]; | |
custom = selector.split(":")[1]; | |
} | |
if (custom.length && custom in $.customSelectors) { | |
// First find all elements matching the non-custom selector(s) | |
found = standard.length ? $$(element, standard) : $$(element); | |
// Then filter that result by testing against the custom selector | |
return $.customSelectors[custom](found); | |
} | |
else { | |
// No function exists for this selector, so we can't perform a query | |
return emptyArray; | |
} | |
} | |
else { | |
// This is the original, untouched code from $.qsa | |
return (element === document && idSelectorRE.test(selector)) ? | |
( (found = element.getElementById(RegExp.$1)) ? [found] : emptyArray ) : | |
slice.call( | |
classSelectorRE.test(selector) ? element.getElementsByClassName(RegExp.$1) : | |
tagSelectorRE.test(selector) ? element.getElementsByTagName(selector) : | |
element.querySelectorAll(selector) | |
); | |
} | |
} | |
// ... futher down ... | |
$.fn = { | |
// ... functions snipped for brevity ... | |
filter: function(selector){ | |
return $([].filter.call(this, function(element){ | |
var custom = ""; | |
// Look for a colon to indicate the presence of a custom selector | |
if (selector && ~selector.indexOf(":")) { | |
custom = selector.split(":")[1]; | |
} | |
if (custom.length && custom in $.customSelectors.test) { | |
return $.customSelectors.test[custom](element); | |
} | |
else { | |
return element.parentNode && $$(element.parentNode, selector).indexOf(element) >= 0; | |
} | |
})); | |
}, | |
// ... the rest of $.fn | |
}; | |
// | |
// ... the rest of the Zepto code snipped for brevity ... | |
// | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have a pull open in Zepto that creates a function that checks whether or not an element matches a selector(using the speedy native matchesSelector), if that gets accepted that would probably be a good spot to put code like this