I\'m using ZeptoJS for my web app, but I\'d like to fall back to jQuery if the browser doesn\'t support Zepto. Since IE is the only major browser not supported at the moment
This is an old topic, but it's what came up for me, and I was not happy with the solution overall. Someone in a comment above mentioned that the official zepto test will result in zepto going to FireFix 3.6 instead of JQuery, which I would prefer to avoid if at all possible.
So, my thought was...test to see if it supports some HTML5 feature AND if it's not IE. This may mean that the larger jQuery will go to more browsers than it should, but I would prefer "working" bloated code to a quick download of nothing. So, anyway, taking the isCanvasSupported() method from Modernizer and the __proto__
test recommended by zepto, I'm thinking this might be a good solution (haven't had a chance to actually test yet):
var isHtml5AndNotIE = function() {
var elem = document.createElement('canvas');
return '__proto__' in {} && !!(elem.getContext && elem.getContext('2d'));
};
Then, just use that method in the document.write() as in the examples above or wherever you are defining the path to jquery/zepto.
The only two browser versions that I could see in a quick cross-reference that support canvas but aren't supported by zepto are: * IOS Safari 3.2 (4+ is supported by Zepto) * Android 2.1 (2.2+ is supported by Zepto)
http://zeptojs.com/#platforms
http://caniuse.com/#feat=canvas
Don't use the conditional comments, it's not going to be supported by IE10. This is the recommended approach from the zepto documentation:
Load Zepto on modern browser and jQuery on IE
<script>
document.write('<script src=' +
('__proto__' in {} ? 'zepto' : 'jquery') +
'.js><\/script>')
</script>
Zepto doesn't work in IE because IE doesn't support prototype, so this is exactly the right way to check.
The script above do a dynamical load but the logic is
<script>
if ('__proto__' in {}) {
// This is NOT IE
} else {
// This is IE
}
</script>
You should raise the bar a bit so not only IE8 will get jQuery, but also other older browsers. Zepto for example requires features such as Array.prototype.some.
Zepto requires much the same features as picoQuery (which is an alternative to Zepto). In picoQuery, they do like this:
if (Array.isArray) {
// Modern browser
// (FF4+, IE9+, Safari 5+, Opera 10.5+, Konq 4.9+, Chrome 5+, etc)
document.write("<script src='/js/zepto.min.js'></script>");
}
else {
document.write("<script src='/js/jquery.js'></script>");
}
From compatibility tables we have that any browser that supports Array.isArray also supports querySelectorAll(), addEventListener(), dispatchevent, Array.prototype.indexOf and Array.prototype.some - all which are used in Zepto
picoQuery describes this choice here: http://picoquery.com/the_fallback
<script>
document.write('<script src=' + ('__proto__' in {} ? 'zepto' : 'jquery') + '.js><\/script>')
</script>
This is the recommended method on zepto.js official site. See http://zeptojs.com/#download
While many of the existing answers work fine when loading Zepto.js via an additional request, I have a situation where I know Zepto will suffice most of the time and I just want to merge it in with my scripts and lazily load jQuery if needed. I put together a small wrapper for Zepto will do just that.
It runs the "offical" '__proto__' in ... test and lazy loads jQuery if it fails. If it succeeds, then it continues loading Zepto.
I found that IE8 would blow up if Zepto was even loaded. This fixes that by skipping the rest of the module.
For the optimistic case, there isn't any additional script requests. For the jQuery path, well, those users weren't exactly getting the fast experience anyway.
This is the way I do it:
<script type="text/javascript">
if(top.execScript){ // true only in IE
document.write("<script src='/js/jquery.js'>\x3C/script>");
}
else{
document.write("<script src='/js/zepto.min.js'>\x3C/script>");
}
</script>