2

Is the DOM always ready when my external scripts have finished loading?

<head>
    <script type="text/javascript" src="base.js"></script>
</head>

Inside base.js, I have an object that loads external scripts. It uses the following method to do so:

var head = document.getElementsByTagName("head")[0],
    scriptElement = document.createElement("script");

scriptElement.type = "text/javascript";
scriptElement.onreadystatechange = function () {
    if (this.readyState === "complete") onModuleLoaded();
};
scriptElement.onload = onModuleLoaded;
scriptElement.src = "externalScript.js";
head.appendChild(scriptElement);

Now, when all external scripts have been loaded, a callback function is called. My question is: Is this callback function suitable to place the rest of my javascript code in? This code needs the DOM to be ready.

My scripts also use jQuery. But I don't think I can use

$(document).ready(function () { ... });

because in my tests that fires before my scripts have been loaded. However, I do not know if this will always be the case. If it will, my callback function is suitable for my DOM-manupilating javascript code.

But if it is possible that my scripts can be loaded before the DOM is ready to be manipulated, I need to find another way.

Thank you for reading!

MPS
  • 131
  • 14
  • Always include your as well as external js files at the end of the html file .ie before the closing body tag and include user script file at the last. – kailash yogeshwar Oct 28 '15 at 12:27
  • If you're using jQuery, why not use [`$.getScript`](http://api.jquery.com/jQuery.getScript/) rather than doing your own browser-inconsistency workarounds (`onreadystatechange` vs. `onload`)? Also, IIRC, there are browsers that fire *both*, so you could get two calls to `onModuleLoaded`; if you don't switch to `getScript`, you might want a flag (if you don't already have one). – T.J. Crowder Oct 28 '15 at 12:29
  • I did not know about the $.getScript method,I am very new to jQuery. Although maybe I should have searched better for a jQuery solution. I will next time. – MPS Oct 28 '15 at 12:44

2 Answers2

2

Check jQuery.holdReady(). If you will try to load external js via getScript then you can easily do that.

Delay the ready event until a custom plugin has loaded:

$.holdReady( true );
$.getScript( "externalScript.js", function() {
  $.holdReady( false );
});
Deepak Biswal
  • 4,280
  • 2
  • 20
  • 37
1

Is the DOM always ready when my external scripts have finished loading?

Probably, yes. No.

Dynamically-added script elements load their scripts asynchronously. You're quite correct that you can't use jQuery's ready callback because it looks at when the DOM defined by the main HTML is fully loaded, which may well be before your additional scripts have loaded.

I'd be really, really surprised if the main DOM weren't loaded before your onModuleLoaded callback was called. So probably, yes, it'll be ready. Color me surprised. I ran the experiment, and guess what? It's possible for the script load and callback to happen before the rest of the page has been processed. (This is why I test my assumptions.)

But if you're worried there may be edge cases around it, you could always use ready within your callback. If jQuery has already fired the ready callbacks and you hook another one, jQuery calls it right away.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thank you! That is well explained. That is a good thing to know that jQuery still calls the callback, even after the event has been fired. I think the $.holdReady(true) is very descriptive though. – MPS Oct 28 '15 at 12:42
  • @MPS: Agreed, `holdReady` is a good way to address your problem. – T.J. Crowder Oct 28 '15 at 12:43