6

I'm dynamically loading jQuery and jQuery UI into a page, and I need to know when jQuery UI has successfully extended jQuery.

At the moment I'm using the readystate of the script element that loads jQuery UI to trigger the running of my code, but I think that at that point, the script has loaded, but jQuery UI hasn't been properly initialised.

Is the only choice to poll until $.ui is defined?

Here's the code that I'm currently wrestling with:

(load_ui = (callback) ->
    script2 = document.createElement("script")
    script2.type = "text/javascript"
    script2.src = "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.js"
    script2.onload = script2.onreadystatechange = ->
      console.log 'readystate:', @readystate
      if @readystate == "loaded" or @readystate == "complete"
        console.log "jquery ui is loaded"
        callback ($ = window.jQuery).noConflict(1), done = 1
        $(script,script2).remove()
    document.documentElement.childNodes[0].appendChild script2
    console.log 'jquery ui script element appended to page'
(window, document, req_version, callback, $, script, done, readystate) ->
  if not ($ = window.jQuery) or req_version > $.fn.jquery or callback($)
    console.log "begin loading jquery"
    script = document.createElement("script")
    script.type = "text/javascript"
    script.src = "http://ajax.googleapis.com/ajax/libs/jquery/" + req_version + "/jquery.min.js"
    script.onload = script.onreadystatechange = ->
      if not done and (not (readystate = @readyState) or readystate == "loaded" or readystate == "complete")
        console.log "jquery is loaded, now loading jquery ui"
        load_ui(callback)        

    document.documentElement.childNodes[0].appendChild script
    console.log 'jquery script element appended to page'
) window, document, "1.6.1", ($, L) ->
    console.log $
    console.log $.ui.version

For some reason the readystate of the jquery ui script element just returns undefined.

Acorn
  • 49,061
  • 27
  • 133
  • 172

3 Answers3

6

I think this will do exactly what you need, add more dependency as much as you like.

(function () {
        function getScript(url, success) {
            var script = document.createElement('script');
            script.src = url;

            var head = document.getElementsByTagName('head')[0];
            var completed = false;
            script.onload = script.onreadystatechange = function () {
                if (!completed && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
                    completed = true;
                    success();
                    script.onload = script.onreadystatechange = null;
                    head.removeChild(script);
                }
            };
            head.appendChild(script);
        }

        getScript("Scripts/jquery-1.6.1.js", function () {
            getScript("Scripts/jquery-ui-1.8.11.js", function () {
                alert($.ui);
            });
        });
})();

Tested with IE7, IE8, IE9, Firefox, Safari, Chrome and Opera

Beygi
  • 1,918
  • 1
  • 16
  • 22
  • Nice solution! Just one question : why do you remove the `script` from the `head` when it's loaded? What does it change? – Maen Mar 21 '13 at 15:06
  • It works very nice on most pages but it doesn't work on Wikipedia pages. Can you make it work on Wikipedia? Thanks. – BearCode Mar 19 '14 at 03:26
  • for success() I got always this message in Chrome:Uncaught TypeError: undefined is not a function . Why did I get this message? – suther Mar 26 '14 at 12:42
0
<script src="jquery ui"></script>
<!-- jQuery UI has been initialized -->
<script src="my source"></script>
Raynos
  • 166,823
  • 56
  • 351
  • 396
  • I'm not loading my script from an external source, only jquery and jquery ui are being loaded externally. – Acorn Jul 01 '11 at 16:44
  • 1
    The OP mentioned they are dynamically loading jQuery and jQuery UI. I'm taking that to mean that they aren't included as ` – Davy8 Jul 01 '11 at 16:46
  • I'm loading them by inserting script tags into the document, and running my code when they are loaded. (at least that's what I'm attempting to do) – Acorn Jul 01 '11 at 17:03
0

I used this code on some project to ensure that some scripts run sequentially. It did not work on IE (and I didn't have time to debug), but worked fine on everything else.

var node = document.createElement("script");
$.extend(node, {
    type: 'text/javascript',
    charset: 'utf-8',
    async: false,
    defer: true,
    src: /*...*/
});
$(node).bind('load', loadedCallback);
$('head')[0].appendChild(node);
Tgr
  • 27,442
  • 12
  • 81
  • 118
  • How do you load a resource without inserting it into the DOM? – Acorn Jul 01 '11 at 17:02
  • @Acorn: you can't, I remembered wrong about that part. See updated answer (an async loader for something I did not finish; probably needs some tweaking for IE compatibility). – Tgr Jul 01 '11 at 17:25