I should mention that this particular approach (which is basically the same as the previous messages with appendChild/prependChild) is dangerous right now with jquery 1.3.2 and below.
There's a bug that's been patched for upcoming 1.3.3 which allows jquery to *properly* detect if it's loaded to a page after dom-ready. But in 1.3.2 and before, if you happen to add the jquery script after dom-ready event has occurred, jquery will never recognize this, and will just keep waiting forever to detect dom-ready. This would cause any subsequenty logic wrapped in $(document).ready(...) blocks to never execute, since jquery never sees the dom-ready event happen. So, wait until 1.3.3 to attempt such things, or you will possibly have these race conditions between jquery loading after the page's dom- ready event. Lastly, the above calls to my little "addScript" could be replaced with the more robust and performant LABjs tool. :) On Oct 10, 11:20 am, getify <[email protected]> wrote: > Couldn't there be a special URL for a CDN, like an "are you alive" > type url, that we load first, and then, if that works (and quickly), > we proceed to load the other files. If not, the CDN is assumed to be > "down" (or at least too slow), so we failover to loading local > versions. > > This is a really rough sketch of an idea, and admittedly pretty ugly, > but I think it might work (or something close to it). > > Here's a working example: http://test.getify.com/cdn-failover/ > > That example fakes a CDN alive check by calling a URL called > "cdnalive" which will randomly choose to: > 1. return a 404 > 2. delay 5 seconds to respond > 3. respond right away with a simple script snippet that says "var > googlecdn = true;" > > If the Google CDN implemented a check url such as that, you could call > it to test if the CDN was gonna respond quickly, and then decide to > where to load scripts from accordingly. > > The logic is very simple (though it looks a little bit complicated). > Basically, just set a 2 (or whatever length) second timeout, then try > to load the "alive" check url. If it loads in time, and successfully > (defining the "googlecdn" variable), proceed to load the scripts from > the CDN. Otherwise, load the scripts from the local copies. > > And here's the code for those who want to see it: > > <script type="text/javascript"> > function initScripts() { > // jquery and jquery-ui are now loaded, go for it! > alert("jQuery and jQueryUI loaded!"); > > } > > var aliveFailed = null, cdnFailed = false; > > (function(global){ > aliveFailed = setTimeout(function(){ > cdnFailed = true; > addScript("jquery.min.js", // load scripts from local instead > function(){ > addScript("jquery-ui.min.js", > initScripts > ); > } > ); > },2000); // only wait 2 seconds for CDN to respond, otherwise pull > from local copies > > var head = document.getElementsByTagName("head"), // this is a > "live" DOM collection, so will update whenever HEAD is ready > script_done = {}; > > global.addScript = function(src,onload) { > var args = arguments; > if (head[0] == null) { // head not ready yet > setTimeout(function(){addScript.apply(null,args);},25); > } > var script = document.createElement("script"); > script.type = "text/javascript"; > script.onload = script.onreadystatechange = function(){ > if (!(script.readyState && script.readyState!=="complete" && > script.readyState!=="loaded") && typeof script_done[script.src] === > "undefined") { // successful load detected > script_done[this.src] = true; > script.onload = script.onreadystatechange = null; > onload(); > } > }; > script.src = src; > head[0].appendChild(script); > }})(window); > > </script> > <script rel="googlecdnalive" src="[**http://ajax.googleapis.com/alive? > **]" type="text/javascript"></script> > <script type="text/javascript"> > if (!cdnFailed && typeof googlecdn !== "undefined") { // > 'googlecdn' defined in the cdn alive check > clearTimeout(aliveFailed); > addScript("http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/ > jquery.min.js", // CDN is up, pull scripts from there > function(){ > addScript("http://ajax.googleapis.com/ajax/libs/jqueryui/ > 1.7.2/jquery-ui.min.js", > initScripts > ); > } > ); > } > </script> > > On Oct 10, 11:02 am, Steven Black <[email protected]> wrote: > > > > > I just tested this in a variety of ways and both John's and Phil's > > methods work great and you're right: appendChild and prependChild both > > work. > > > Cool! > > > **--** Steve > > > On Oct 9, 10:44 pm, Michael Geary <[email protected]> wrote: > > > > prependChild or appendChild wouldn't make any difference; they're both > > > asynchronous. > > > > Regarding that sub-packet-sized package with a fast timeout, how would you > > > implement that short of recompiling the browser? :-) > > > > -Mike > > > > On Fri, Oct 9, 2009 at 6:54 PM, Steven Black <[email protected]> > > > wrote: > > > > > First of all, thanks @jresig because that's just way too elegant. I > > > > was anticipating something far more complex. > > > > > A couple of questions: > > > > > Ifhttp://cdn/jQuery.jsfails, we want the local-domain jQuery.js to > > > > load next, BEFORE the any other subsequent script which is likely a $ > > > > (function(){}) or a call for plugin, both of which have a jQuery > > > > predicate. So I don't sense that Phil's ...('head')[0].appendChild > > > > (script) would work reliably. Am I wrong about that? Does this > > > > really work as you expect, Phil? I would expect a prependChild(), no? > > > > > Second, Dave raises another crux of the matter: we need to bail to the > > > > failover ASAP, ideally within a second or two. It's almost as if we > > > > need the CDNs to also provide a sub-packet-sized package we could > > > > request, wrapped inside a very short timeout to bail to the failover. > > > > > **--** Steve > > > > > On Oct 9, 9:10 am, Dave Methvin <[email protected]> wrote: > > > > > > I took this great idea and went ahead implementing it on a few > > > > > > sites I > > > > > > maintain using different syntax. > > > > > > It's more than a syntax change; it's entirely different semantics. > > > > > Your version fetches a copy of jQuery asynchronously. If there is > > > > > a .ready() handler below that block of code, jQuery may not be loaded > > > > > by the time it is reached and you'll get errors. By using > > > > > document.write and a script tag, you can be guaranteed that the > > > > > browser won't proceed to run any code below it until it either loads > > > > > the script or gets an error back from the request (like a 404 or a > > > > > timeout). > > > > > > I'd think the timeout situation is the most likely outcome when > > > > > Google's CDN is down, which means the user will see a blank screen for > > > > > 30 to 60 seconds before it even reaches the document.write anyway. So > > > > > it seems like you'd need to load the Google CDN version asynchronously > > > > > to prevent that. But that raises the question of what to show the user > > > > > while it's trying to find a reachable version of jQuery...- Hide > > > > > quoted text - > > > - Show quoted text -- Hide quoted text - > > - Show quoted text - --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "jQuery Development" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/jquery-dev?hl=en -~----------~----~----~----~------~----~------~--~---
