8

Is it the same if you load javascript to the page like this:

<script src="http://domain.net/script.js" type="text/javascript"></script>

and like this

<script type="text/javascript">
  document.write("<script src='http://domain.net/script.js' type='text/javascript'></script>");

I have a lot of the dependencies in js and want to configure then in as a separate array, which are just bundled in index.html in the way like:

<script type="text/javascript">
  for (i in config.files.javascripts) {
    document.write("<script src='config.files.javascripts[i]' type='text/javascript'></script>");
  }
</script>

The question is - should it work as expected so that the next file is not executed until the previous one is loaded?

This is there is no server side in the front-end I'm doing and it will also sometimes work as widget though for the dev and test we should load files unmerged and uncompressed to test.

Thanks!

lyuba
  • 6,250
  • 7
  • 27
  • 37
  • 2
    Someone once posted a complete queue to make sure the scripts are loaded in a specific order (http://stackoverflow.com/questions/4832829/import-javascript-file-from-within-javascript-synchronously). – pimvdb Mar 20 '11 at 00:11

3 Answers3

9

To answer your question: Yes, scripts loaded with document.write are guaranteed to execute in the order written.

Same applies to scripts loaded using the W3C DOM methods.

var scriptElm = document.createElement('script');
scriptElm.defer = true; // Causes faster (parallel) loading in some browsers.
scriptElm.src = 'path/to/script.js';
document.getElementsByTagName('head')[0].appendChild( scriptElm );

That said, document.write() is generally considered really bad practice (for a variety of reasons) and can lead to breakage and annoying edge-case problems later on. I, therefore, recommend that you use the W3C DOM injection shown above, if nothing else.

- - - -
Then there are script loading libraries that make this sort of resource loading easier, more elegant, and sometimes even faster. Some load scripts in parallel but execute in a predictable order - like the one already linked to by @CoBaLt2760 http://www.dustindiaz.com/scriptjs

jQuery also has a very simple method $.getScript( 'path/to/script.js' ); (documentation) that you can use. If memory serves me right, It uses simple W3C DOM injection.

Google "javascript loading" or some such, or search here on StackOverflow,com if you're interested in more links to such libraries.

Már Örlygsson
  • 14,176
  • 3
  • 42
  • 53
  • Thanks a lot for the extensive help, now I see that picking a library for this is the best solution. – lyuba Mar 20 '11 at 19:00
  • Like everybody and their cat, I've of course written my own script loader: https://github.com/maranomynet/req In my case, ease of use was the key focus. – Már Örlygsson Mar 22 '11 at 18:29
  • This doesn't seem to be the case with in-line scripts in relation to DOM addition, while `document.write` does execute them all in turn. See: http://stackoverflow.com/questions/27895299/adding-scripts-to-iframe-via-dom-insertadjacenthtml-or-document-write – Campbeln Jan 13 '15 at 09:10
1

If you are looking to load asynchronously javascript scripts, in the right order, I shall recommend you $script.js developed by the Twitter javascript lead dev http://www.dustindiaz.com/scriptjs

It's really great!!

guillaumepotier
  • 7,369
  • 8
  • 45
  • 72
  • Funny thing is that twitter itself seems to use lab.js :) – lyuba Mar 21 '11 at 12:28
  • indeed. Ded has developped his own $script.js because he wasn't fully satisfied by lab.js/ Maybe in a next Twitter code update ^^ – guillaumepotier Mar 21 '11 at 13:48
  • The overhead code needed to use *some* of these script loaders gets quite convoluted real quick. Some are also quite obtrusive in the way they require the scripts themselves to be aware of the script loading framework. "Fast" is not the only thing to worry about - ease of use is very important too. – Már Örlygsson Mar 22 '11 at 18:25
1

if your config.files.javascripts is an Array, then you shouldn't use for...in, as that syntax is intended for looping over named keys in objects.

For Arrays use a traditional C style for loop syntax:

for (var i=0; i<array.length; i++) {

So for your particular case, this should do the trick:

var headerElm = document.getElementsByTagName('head')[0],
    scripts = config.files.javascripts;

for (var i=0, l=scripts.length; i<l; i++)
{
  var scriptElm = document.createElement('script');
  scriptElm.defer = true; // causes faster (parallel) loading in some browsers.
  scriptElm.src = scripts[i];
  headerElm.appendChild( scriptElm );
}
Már Örlygsson
  • 14,176
  • 3
  • 42
  • 53