-->

dynamic script tag loading is not working as expec

2019-04-15 19:32发布

问题:

We have an application that uses both the google closure and dojo libraries. We have the following in our index page which works as expected:


<script type="text/javascript" src="runtime/src/lib/google-closure-rev26/closure/goog/base.js"></script>
<script type="text/javascript" src="runtime/src/lib/dojo_release_132_src/dojo/dojo.js"></script>
<script type="text/javascript" src="runtime/src/core/loader.js"></script>

We would like to use only one script tag in the actual html source. So we tried to do the following:


<head>
   <script type="text/javascript" src="runtime/src-bootstrap.js"></script>
</head>

and then in src-bootstrap.js:


var head = document.getElementsByTagName("head")[0];

var s1 = document.createElement("script");
s1.type = "text/javascript";
s1.src = "runtime/src/lib/google-closure-rev26/closure/goog/base.js";


var s2 = document.createElement("script");
s2.type = "text/javascript";
s2.src = "runtime/src/lib/dojo_release_132_src/dojo/dojo.js";

var s3 = document.createElement("script");
s3.type = "text/javascript";
s3.src = "runtime/src/core/loader.js";

head.appendChild(s1);
head.appendChild(s2);
head.appendChild(s3);

However, this doesn't work in FF. core/loader.js runs before dojo is loaded completely. Any ideas why this doesn't work?

回答1:

For this type of mechanism, you'd be better off using document.write() to include your scripts. The technique you're currently using is suited to lazy-loading scripts, and it downloads and executes the scripts asynchronously: http://www.nczonline.net/blog/2009/06/23/loading-javascript-without-blocking/

...or you could have a build process that actually concatenates these files, and just request the one script, which would save on the number of requests too, as what you've actually done is increased the number of requests.



回答2:

My guess would be that because you are creating the elements through the DOM, instead of having them as markup, the browser doesn't wait for one script to be finished before executing the next (as would be the case in a straight <script></script><script></script>setup).

How about appending the scripts in a cascaded form (Google closure appends s2 at its end, Dojo s3) or, as Lee Kowalkowski suggests, writing <script> commands using document.write()?



回答3:

Generally Speaking - add a namespace under window, and edit your external resources-

  1. leave one action.js or main.js file locally, that will be added a method, preferably under global scope (meaning under window..).

  2. edit your external resource, adding 1 extra line at the end, calling for a method on action.js or main.js, when the loading will be done, the "callback like" will execute that method you've been adding to the DOM previously. it works very much like JSONProtocol.

  3. it works wonders even with with the most complex combination of dynamically loaded resources.

see the example for this very similar solution provided for dynamically loading the Google-Closure-Library on another thread (https://stackoverflow.com/a/17226714/257319)