Pergunta

I am loading two JS files, one with many plugins, including Jquery. The 'ready()' JQuery function is in the second file.

Code:

   function downloadJSAtOnload() {

       var element = document.createElement("script");
       element.src ='<%= deferJsAll %>';
       document.body.appendChild(element);

      // second JS file load with isReady goes here
   }

   // Check for browser support of event handling capability
   if (window.addEventListener)
       window.addEventListener("load", downloadJSAtOnload, false);
   else if (window.attachEvent)
       window.attachEvent("onload", downloadJSAtOnload);
   else window.onload = downloadJSAtOnload;

You can see when I also load the second file (See comment inside the code).

The problem is that I can't control the order of execution and even so, the 'ready()' runs before JQuery is loaded, and I get an error. Is there an option to use defer loading and making sure that the Jquery files loads first and then the second is executed (the one with the ready() function)?

I am using "<%= deferJsAll %>" because I am deciding which file to serve from CDN, the gzip or plain text JS file.

Progress: I thought about just putting:

var elementApp = document.createElement("script");
elementApp.src = 'js/app.js';
document.body.appendChild(elementApp);

at the end of the first document. So when the first document finishes loading, it will then embed the second dependent JS code into the body of the document. Do you think it's a good idea?

Foi útil?

Solução

Here's a solution I used when I need to wait until some var on the page exists. It takes a name (e.g. jQuery or namespace twttr.widgets with arbitrary depth) and other self explanatory attributes. Works in production on http://www.vitalmtb.com/ when I need to wait till Facebook and Twitter widgets are loaded.

// Wait till JS object is loaded. It can be a chanined variable name.
window.whenAvailable = function (name, callback, interval, max_wait) {
    interval || (interval = 50); // ms
    max_wait || (max_wait = 5000); // ms
    var timer,
        findVarByName = function(name) {
        var index = 0,
            parts = name.split('.'),
            result = window;

        index = 0;
        try {
            while (typeof result !== "undefined" && result !== null && index < parts.length) {
                result = result[parts[index++]];
            }
        }
        catch (e) {}
        if (index < parts.length || (typeof result == 'undefined' && result === undefined)) return false;
        else return true;
    };

    timer = window.setTimeout(function() {
        if (findVarByName(name)) {
            return callback();
        } else {
            window.setTimeout(arguments.callee, interval);
        }
    }, interval);

    window.setTimeout(function() {
        clearTimeout(timer);
    }, max_wait);
}

Use:

whenAvailable('FB', $j.spotlights.a.show_social_buttons);
whenAvailable('twttr.widgets', $j.spotlights.b.show_social_buttons);

Outras dicas

You can use onload & onreadystatechange (for IE) to detect when the script is finished loading.

function loadScript(callback){
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = '<%= deferJsAll %>';
  document.body.appendChild(script);

  // exit on jQuery load.
  script.onload = function(){ callback(); };
  script.onreadystatechange = function() {
    if (this.readyState == 'complete') callback();
  }
}


loadScript(function(){
  $.getScript('<% jquery-dependent.js %>', function(){
     // jquery-dependent.js is loaded
  }
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top