3

The following are the first lines of code in a <script> tag just above the closing body tag in my document (it specifies that a locally-served copy of jQuery is run in the event that Google's CDN fails):

if(!window.jQuery){
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = '/js/jquery.js';
    var scriptHook = document.getElementsByTagName('script')[0];
    scriptHook.parentNode.insertBefore(script, scriptHook);
}


jQuery(document).ready(function($){
// page behaviors
});

It does execute successfully, in the sense that if my computer is not connected to the Internet (this is a locally-served page), the local copy of jQuery is inserted. However, the document.ready() section below does not execute. I'm guessing this is because it is invoked before the fallback copy of jQuery takes effect. What's the proper practice for somehow "delaying" its execution so that either copy of jQuery will work properly?

Isaac Lubow
  • 3,557
  • 5
  • 37
  • 53
  • Possible duplicate of http://stackoverflow.com/questions/538745/how-to-tell-if-a-script-tag-failed-to-load. – jfriend00 Oct 23 '11 at 04:27
  • The answer is that you use a combination of the `onload` event and `readystatechange`. See: http://www.ejeliot.com/blog/109. – jfriend00 Oct 23 '11 at 04:28
  • Looking over that question, while the solutions might be similar, the question is quite different, IMHO. – Isaac Lubow Oct 23 '11 at 04:39
  • do we really need to plan for the event that google fails? That's like designing for the posibility that up becomes down.... – Sinetheta Oct 23 '11 at 04:41
  • 4
    @Sinetheta everything, including Google can fail. While I'm not aware on outages on AJAX APIs, Google had many outages on other services. Also, you've to consider the case of a broken network, making a remote server unreachable, even if is not down. Moreover for development this is handy, it's possible to keep on hacking code on the train or plane, without network connectivity. – stivlo Oct 23 '11 at 04:50
  • No need to use this for offline developer productivity - you can just wire in a local copy of jQuery when in development mode. You would typically be using the unminified version anyway when developing. – jfriend00 Oct 23 '11 at 05:49

5 Answers5

3

Consider using an existing script loader such as yepnope. There's an example of exactly what you're trying to do on the home page.

Michael Mior
  • 28,107
  • 9
  • 89
  • 113
1

You need to be sure that the script you are appending to the dom has finished loading before calling jQuery. You can do this with the technique described here:

if(!window.jQuery){
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = '/js/jquery.js';
    script.onreadystatechange= function () {
      if (this.readyState == 'complete') jQueryLoaded();
    }
    script.onload = jQueryLoaded;
    var scriptHook = document.getElementsByTagName('script')[0];
    scriptHook.parentNode.insertBefore(script, scriptHook);
}

function jQueryLoaded() {  };

You can also fetch the jQuery contents as an Ajax request, create a script tag with those as the body of the script and append it. That would also work.

Pablo Fernandez
  • 103,170
  • 56
  • 192
  • 232
0

Try that

<script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.2.min.js"><\/script>')</script>
<script>
    jQuery(document).ready(function($){
        // page behaviors
    });
</script>

This way the script tag will be loaded synchronously.

Andrey M.
  • 3,688
  • 3
  • 33
  • 36
0

The question "of how do I cope with my CDN failing and load a file hosted on my server" seems to come up a few times lately.

Question I'd ask is whether adding yet more js is the way to achieve the resilience and what level of resilience do the js approaches really add e.g. if the CDN is down they'll be a quick failure but how well do these approaches if the CDN is slow to respond how well do these solutions cope?

An alternative way to approach this is treat it as an infrastructure problem...

Run a CDN based on a domain/sub-domain you own. Have automated monitoring on it's availability, when it fails switch the DNS over to a backup server (anycast may provide an alternative solution too)

Andy Davies
  • 5,794
  • 2
  • 26
  • 21
-1

A php solution would be something like this:

$google_jquery = 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js';
$fp = @fsockopen($google_jquery, 'r');
if (!$fp) 
{
    echo '<script type="text/javascript" src="js/jquery.js"></script>';
} 
else
{ 
    echo '<script src="'.$google_jquery.'"></script>' }
}
Anonymous
  • 3,679
  • 6
  • 29
  • 40
  • Can you explain what the first line is doing? – Isaac Lubow Oct 23 '11 at 04:32
  • however, when the script is installed on the server, the server might be able to reach `ajax.googleapis.com`, while the browser client might not, because of a broken network path. – stivlo Oct 23 '11 at 04:33
  • had a little logical error there. it checks whether it can connect to the google jquery file now. – Anonymous Oct 23 '11 at 04:34
  • You still have the logical error to check connectivity on the server instead of checking on the client. It will work until everything is on localhost, but not in production. – stivlo Oct 23 '11 at 04:38
  • This solution adds the latency of a round trip to Google's CDN during the page generation which surely negates the benefit of using a CDN. – Andy Davies Oct 24 '11 at 10:26