Search code examples
javascriptonload

How to know once a dynamically added script is parsed/loaded/executed?


I am trying to dynamically load a JavaScript file and, once it is loaded, run a function that is inside the file. In my main HTML, I basically have:

function load_javascript(js_file)
{
    function load_js_callback(example)
    {
        console.log("function " + function_in_js_file + " is " + typeof(function_name));
        if (typeof(function_in_js_file) == "undefined")
        {
            window.setTimeout(load_js_callback(example), 500);
            return false;
        }
        function_in_js_file(example);
    }

    var jstag = document.createElement("script");
    document.head.appendChild(jstag);

    // Browsers:
    jstag.onload=load_js_callback("example");
    // Internet Explorer:
    jstag.onreadystatechange = function() {
        if (this.readyState == 'complete') {
            load_js_callback("example");
        }
    }
    jstag.setAttribute('src',js_file);
}

load_javascript("/js/example.js");

From what I can find on the internet (https://stackoverflow.com/a/3248500 and https://stackoverflow.com/a/16231055) this should work, but the jstag.onload runs before the function_in_js_file is defined, so I need the window.setTimeout to check again until the function is defined.

Ideally, I would like to get rid of that timeout. Is there any way to know when the file has been completed loaded/parsed/executed (I'm not sure which is the right term) and the function is defined, ideally without changing the dynamic file? I have also tried putting the document.head.appendChild(jstag); after the jstag.setAttribute, but with the same results.


Solution

  • The reason it's running before the script loads is because:

    var jstag = document.createElement("script");
    document.head.appendChild(jstag);
    
    // Browsers:
    jstag.onload=load_js_callback("example");
    

    Is assigning the return value of load_js_callback to jstag.onload. The onload handler wants a function:

    var jstag = document.createElement("script");
    document.head.appendChild(jstag);
    
    // Browsers:
    jstag.onload=function() { load_js_callback("example"); };
    

    As pointed out in the other comments, all this guarantees is that the browser has downloaded the script.