load jQuery from external source if not loaded
Asked Answered
P

5

7

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

Passer answered 23/12, 2010 at 23:37 Comment(3)
Can you please be a little more explicit with what you want to do?Allyson
Google being down would result in the internet imploding. No worries.Careworn
A CDN such as Google's is highly unlikely to go down. Coding around such an unlikely event will probably just pollute your code :(Keslie
F
7

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>
Fanaticism answered 13/1, 2011 at 22:44 Comment(1)
That's a beaut! Thanks a ton! That's exactly what I was looking for!Cynosure
D
4

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>
Dateless answered 16/4, 2012 at 20:33 Comment(2)
I tried to use something like this while writing a bookmarklet to be used with JIRA. The "typeof jQuery === 'undefined'" test always failed. It turned out that JIRA was using some scripts that use jQuery, like FancyBox, which caused "jQuery" to be defined as a function, but "$" still wasn't defined. I changed the test in the condition and jQuery would be loaded properly.Handy
Wow. I've never seen so much code used to solve such a simple problem. You must love typing... :)Keslie
A
2

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');
Agger answered 24/12, 2010 at 0:9 Comment(2)
mhhh - i can even delete tryLoadChain's sources and your script still alerts: loaded... not working for mePasser
no it doesn't. Change the first URL so you'll get a 404. It will just stop executing. At least it did for me.Tenno
T
1

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:

  1. jQuery not present.
  2. Add SCRIPT element to load from Google (browser sends a request and continues execution of the script)
  3. jQuery not present add another source
  4. ...

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.

Tenno answered 23/12, 2010 at 23:59 Comment(1)
so a setTimeOut before checking if jQuery is loaded can help?Passer
B
0

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>
Blooper answered 22/5, 2013 at 18:45 Comment(4)
There are a lot of good ways to append a script node to the DOM. document.write is not among them.Jobber
@editor - Care to explain? Because almost all the answers posted here rely on document.write() and this seems to be the standard way of doing this.Keslie
#803354 In short, because it gives you the ability to write directly to the page, it is very easily abused, and if misabused, potentially a security hole. It got downvoted here because there are usually nicer ways to do the same thing. As a side note, for a large project, look into AMD style loading, possibly with something like require.js.Blooper
@RobertChrist - By the way, in that post itself it says that this is one of the legitimate uses of document.write..Guesswork

© 2022 - 2024 — McMap. All rights reserved.