Josh Earl
Josh Earl

Reputation: 18361

How can I delay the execution of a script block until after an external script has loaded?

I'm trying to dynamically insert and execute a couple of scripts, and I think I'm hitting a race condition where the second is trying to execute before the first is loaded.

The project I'm working on has an unusual requirement: I am unable to modify the page's HTML source. It's compiled into an app for localization purposes.

Therefore, I'm unable to insert <script> tags like I normally would to link in JavaScript files.

It turns out that the client wants to use a hosted web font, so I decided to build and append the two required <script> tags dynamically in an already-linked JavaScript file.

The <script> blocks are appending correctly in the head of the document, but function in the second block seems to be firing before the external script linked in the first <script> tag is fully loaded, and it's throwing an undefined error.

Here's the relevant piece of code:

document.getElementsByTagName("head")[0];
var tag = document.createElement('script');
tag.setAttribute("src", "http://use.typekit.com/izj3fep.js");
document.getElementsByTagName("head")[0].appendChild(tag);

try {
        Typekit.load(); // This is executing too quickly!

    } catch(e){
        console.log("Hosted fonts failed to load: " + e);
}

I tried moving the try block to the window.onload event, but that fires before any of this code is called.

I guess I could dynamically load jQuery and then use it's ready event, but that seems pretty heavy-handed. I'm hesitant to pull in a library on this project, as the client has a lot of custom JavaScript that could potentially clash with it.

What else can I try?

Upvotes: 1

Views: 3025

Answers (4)

Petar Sabev
Petar Sabev

Reputation: 858

Combining the scripts into one big seems to be the easiest solution.

Upvotes: 0

benesch
benesch

Reputation: 5269

Are you using jQuery? If not, I highly recommend it. It'll make your life so much easier:

$.getScript('http://use.typekit.com/izj3fep.js', function(data, textStatus){
   try {
        Typekit.load(); //executes properly now!
    } catch(e) {
        console.log("Hosted fonts failed to load: " + e);
    }
});

Upvotes: 0

Matt Greer
Matt Greer

Reputation: 62057

You need to hook into the script element's onload event and execute your code there:

document.getElementsByTagName("head")[0];
var tag = document.createElement('script');

tag.onload = onTagLoaded;

tag.setAttribute("src", "http://use.typekit.com/izj3fep.js");
document.getElementsByTagName("head")[0].appendChild(tag);

function onTagLoaded() {
    try {
        Typekit.load(); // This is executing too quickly!
    } catch(e){
         console.log("Hosted fonts failed to load: " + e);
    }
}

Upvotes: 1

Alex M
Alex M

Reputation: 3513

You can load it with yepnope ( http://yepnopejs.com/ ). I know it's a library, but it's very light (free if your client is already using modernizr). It's well worth it. Hopefully the client doesn't have another yepnope function, and you don't have to worry about the clash.

Upvotes: 1

Related Questions