load jQuery from source
What I like to do is to drop my local jquery.js and have
it hosted somewhere else. But what if Google is down? So
let's code a fallback that uses another source if jQuery
is "still" not loaded...
I made this test case but it does not seem to work, maybe
someone can help me out:
http://jsfiddle.net/RBz4n
This works fairly well (from HTML5 Boilerplate):
<!-- Grab Google CDN's jQuery. fall back to local if necessary -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.4.2.js"%3E%3C/script%3E'))</script>
Here is a pure javascript solution that starts out by detecting if jQuery is available. If not, it tries the CDN version. If that's not available, it tries the local version. Handles 404 errors. I use this in a solution that doesn't know whether the website has included jQuery.
<script>
if (typeof jQuery === "undefined") {
loadjQuery("//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js", verifyJQueryCdnLoaded);
} else
main();
function verifyJQueryCdnLoaded() {
if (typeof jQuery === "undefined")
loadjQuery("script/jquery-1.6.1.js", main);
else
main();
}
function loadjQuery(url, callback) {
var script_tag = document.createElement('script');
script_tag.setAttribute("src", url)
script_tag.onload = callback; // Run callback once jQuery has loaded
script_tag.onreadystatechange = function () { // Same thing but for IE
if (this.readyState == 'complete' || this.readyState == 'loaded') callback();
}
script_tag.onerror = function() {
loadjQuery("script/jquery-1.6.1.js", main);
}
document.getElementsByTagName("head")[0].appendChild(script_tag);
}
function main() {
if (typeof jQuery === "undefined")
alert("jQuery not loaded.");
$(document).ready(function () {
// Rest of your code here...
});
}
</script>
The problem with your script is that you're not waiting for the script to load before testing whether jQuery has been loaded. Use something like this instead:
function loadScript(src, callback) {
var head=document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.onreadystatechange = function () {
if (this.readyState == 'complete' || this.readyState == 'loaded') {
callback();
}
}
script.onload = callback;
script.src = src;
head.appendChild(script);
}
function isjQueryLoaded() {
return (typeof jQuery !== 'undefined');
}
function tryLoadChain() {
var chain = arguments;
if (!isjQueryLoaded()) {
if (chain.length) {
loadScript(
chain[0],
function() {
tryLoadChain.apply(this, Array.prototype.slice.call(chain, 1));
}
);
} else {
alert('not loaded!');
}
} else {
alert('loaded!');
}
}
tryLoadChain(
'https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js',
'http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.4.min.js',
'mine.js');
The problem
If you use Firebug and see where jQuery gets loaded you can see taht Google successfully loaded it. Why it doesn't seem to work? Because requests are asynchronous and while your script runs synchronously it executes all steps before the first script gets loaded.
So:
- jQuery not present.
- Add SCRIPT element to load from Google (browser sends a request and continues execution of the script)
- jQuery not present add another source
- ...
etc etc.
Solution
What you should do is attach to onLoad
event of your script loading elements and check for jQuery after they've loaded.
Script executes lightning fast compared to sending a request out to some server on the internet and getting results back for processing.
Additional notes
As I've read you're going to have problems detecting 404s using this technique. Suggested way would be to use Ajax (XHR) and then attach script element and add received content to it. This would be the most reliable way of doing it for all browsers.
Roger's answer is rediculous. Here, use this instead, its 2 lines.
<script>window.jQuery || document.write('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"><\/script>')</script>
<script>window.jQuery || document.write('<script src="Content/Scripts/jquery-1.9.1.min.js"><\/script>')</script>