Login Register

IE6/7 Problem with dojo.addOnLoad

We have encountered a problem in our current development where dojo.addOnLoad executed correctly in Firefox but not in IE. We load the cross-domain dojo 0.9 from the AOL CDN and then load our script, which verifies the presence of Dojo (it has been loaded), then includes some of our modules using dojo.require(...) which get loaded. In our script that has the dojo.require(...) call, the immediate next call is for dojo.addOnLoad. In Firefox this gets executed, and the script runs, in IE, nothing happens (both 6 & 7).

I have included bellow the relevant information (company name has been removed for privacy)

The following block of code is in a script that is included in a page:

djConfig = {
    isDebug: false,
    useXDomain: true,
    xdWaitSeconds: 10,
    baseUrl: "http://{company CDN}/",
    modulePaths: {
      cws: "http://{company CDN/path to}/cws",
      cust: "http://{company CDN/path to}/cust",
      dojo_xd: "http://o.aolcdn.com"
    }
  };

We have also defined a special method that helps us ensure that loading of scripts takes place in the order we want them to take place:

function import(module, src, callback) {
      var s = document.createElement("script");
      s.type = "text/javascript";
      s.onload = s.onreadystatechange = function() {
        if (s.readyState && s.readyState != "loaded" && s.readyState != "complete") return;
        s.onreadystatechange = s.onload = null;
        if (callback) callback();
      };
      s.src = djConfig.modulePaths[module] + "" + src;
      document.getElementsByTagName("head")[0].appendChild(s);
    }

And we then proceed to actual load the scripts in the order we want them loaded:

import("dojo_xd", "/dojo/0.9.0/dojo/dojo.xd.js.uncompressed.js",
      function() { import("cust", "/{path to customer initalization file}.js"); }
    );

Inside of the customer initialization file is what we have:

if (typeof dojo != "undefined") {
  dojo.require("{desired module}");
  function loaded() {
    var ad = factory_method({company code});
  }

  dojo.addOnLoad(loaded);
}

This method that is referenced to by dojo.addOnLoad never seems to be called inside of IE. We verified this through some alert boxes in order to trace execution path. We can see that dojo is loaded, and further more that the dojo.require(...) gets executed as we have examined in fiddler that the packages get loaded and their dependencies get loaded as well.

The xdomain loader does

The xdomain loader does effectively what you are trying to do with your import function, except the xdomain loader does not use the readystate test, since there were reports that it was unreliable or not fired in cache situations for IE.

Also, Dojo normally assumes it is loaded as part of the page load (via a normal script tag in the HTML source and not via a script element dynamically created and added to the head). Dojo tries to bind to the DOMContentLoaded event (or the rough equivalent in IE) and I can see where if it is loaded after the fact, via the import call, that it will miss the DOMContentLoaded trigger, and therefore addOnLoad calls may not be called.

I suggest instead of doing that custom import work, just do a Dojo xdomain build that includes your cws and cust directories in the profile. That will generate .xd.js files that allow you to just do a regular dojo.require() for the modules you need, and addOnLoad callbacks should be called as expected. You can still use Dojo from the CDN, just configure the modulePaths correctly for the cws and cust prefixes.

Also, be sure to load dojo.xd.js from the CDN via a regular script tag specified in the HTML source.

Well... the requirement for

Well... the requirement for this project is to load everything asynchronously and on-demand - included Dojo core library, so we can't really include it using normal script tags.

The issue seems to be in _xdNotifyLoaded function - it checks _initFired flag before calling _callLoaded.
The only place in the code that sets this flag is _loadInit function - so we just called dojo._loadInit() before calling dojo.addOnLoad() and that fixed the problem.

Still - I guess I'm going to file an issue for this as I believe this use-case should be supported out of the box.