0

Right up front: this project doesn't use JQuery.

We have some third-party JavaScript; it's big and hairy and doesn't need to be used often, so we're dynamically loading it only when we need to:

function loadBigHairyCode()
{
    var file = document.createElement('script')
    file.setAttribute("type","text/javascript")
    file.setAttribute("src","path/to/big/ugly/script/file.js")
    document.getElementsByTagName("head")[0].appendChild(file)

    magic_needs_to_happen_here
}

The script loading works fine, including some corresponding CSS that's not shown here.

The loaded file defines a constructor function (call it UglyGlobalFunc) which we use elsewhere in the usual way (var foo = new UglyGlobalFunc(....)). The problem is, because the rest of that file is kinda ugly, we need to fix it up a bit so that it sucks less. Specifically, at the point where I've shown "magic needs to happen here" above, I want to write the equivalent of

UglyGlobalFunc.prototype.BodgeBodgeBodge = function() {....}

just as if I were editing the underlying file.

But that fails, because at that point in the code, UglyGlobalFunc is undefined, which makes sense. Same for a simple level of indirection like window.UglyGlobalFunc.proto.... So my questions are:

  1. Are the dynamically loaded contents even accessible at that point of execution (where magic needs to happen)? Or do they not become "real" until after loadBigHairyCode() returns and the browser goes through some kind of refresh cycle?

  2. If yes, then how do I access them? Some kind of getGlobalVariableByName("string") function?

  3. If not, then... aieee. How do normal sane people go about doing that kind of thing?

2 Answers 2

4

You may try this

function loadBigHairyCode()
{
    var file = document.createElement('script')
    file.onreadystatechange= function () { // works in IE
        if (this.readyState == 'complete') MyFunc();
    }
    file.onload= MyFunc;
    file.type="text/javascript";
    file.src="path/to/big/ugly/script/file.js";
    document.getElementsByTagName("head")[0].appendChild(file)
}

function MyFunc(){
    //....
}

Update: You may read this.

Sign up to request clarification or add additional context in comments.

2 Comments

Yep, looks better now : ). I'll remove my previous comment, it's irrelevant now.
@Teemu, This way the script doesn't block page loading, called async.
3

When you create a <script> element like that, you have to bind to its onload event, which is fired as soon as it's loaded and available for use.

Another option is to just use document.write('<script src="..."></script>'); to have it loaded synchronously. Then you can use it in the following line. Just make sure to do that before the page finishes loading, or your whole document will be overwritten.

2 Comments

Oh, I didn't realize that individual script elements could even HAVE their own events like that. (I am not a web guy.) Thanks to everyone who answered!
@TiStrga <img> elements have that event too (might be useful).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.