Trying to fire the onload event on script tag
Asked Answered
A

3

148

I'm trying to load a set of scripts in order, but the onload event isn't firing for me.

    var scripts = [
        '//cdnjs.cloudflare.com/ajax/libs/less.js/1.3.3/less.min.js',
        '//cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.0-rc.3/handlebars.min.js',
        MK.host+'/templates/templates.js'
    ];

    function loadScripts(scripts){
        var script = scripts.shift();
        var el = document.createElement('script');
        el.src = script;
        el.onload = function(script){
            console.log(script + ' loaded!');
            if (scripts.length) {
                loadScripts(scripts);
            }
            else {
                console.log('run app');
                MK.init();
            }
        };

        $body.append(el);
    }

    loadScripts(scripts);

I guess native events like el.onload don't fire when jQuery is used to append the element to the DOM. If I use native document.body.appendChild(el) then it fires as expected.

Accumulator answered 26/4, 2013 at 7:23 Comment(1)
visit:thi link:#4846262 This is use fuullLanugo
B
196

You should set the src attribute after the onload event, f.ex:

el.onload = function() { //...
el.src = script;

You should also append the script to the DOM before attaching the onload event:

$body.append(el);
el.onload = function() { //...
el.src = script;

Remember that you need to check readystate for IE support. If you are using jQuery, you can also try the getScript() method: http://api.jquery.com/jQuery.getScript/

Burke answered 26/4, 2013 at 7:34 Comment(13)
that actually doesn't fix it. But if i just use document.body.appendChild(el) instead of $('body').append(el); then the onload event fires as expected.Accumulator
I’m not sure how to "fix" your code, but best practice is to append the script to the <head>, attach the onload handler and then the src attribute. In that order.Burke
i think jQuery is not firing the native onload. (see edit in question).Accumulator
@Accumulator I think you think wrong. jQuery doesn’t disable native events. It’s the ordering that is important, as I already mentioned. See this example: jsbin.com/ucegij/1/editBurke
can you help me understand why the ordering is important?Accumulator
@David Why not append the element last, as recommended in places like html5rocks.com/en/tutorials/speed/script-loading ? That should make the order you add the event listener and set the src in irrelevant.Confiscable
I'm curious: Why is it important to attach an element to the DOM before setting the onload and src attributes?Seedman
Its not important. Scripts start loading when appended to the document. Images or other medias will start loading as soon as the src attribute is added. So for scripts the order won't make a difference.Hux
Still helped me, almost exactly 6 years after original answer. Nice!Montemontefiascone
The order does not matterRelly
If the script is cached, then as soon as you add the src the item is loaded and onload does not fire. Adding the onload before the src will ensure that onload fires for cached scripts.Quisling
Remember that onLoad not triggered if the script already in DOM. So you should also previously check the sources of existing scripts and their readyState (to make sure that they are fully loaded in current moment).Nate
Mozilla documentation: developer.mozilla.org/de/docs/Web/API/…Vast
Q
16

I faced a similar problem, trying to test if jQuery is already present on a page, and if not force it's load, and then execute a function. I tried with @David Hellsing workaround, but with no chance for my needs. In fact, the onload instruction was immediately evaluated, and then the $ usage inside this function was not yet possible (yes, the huggly "$ is not a function." ^^).

So, I referred to this article : https://developer.mozilla.org/fr/docs/Web/Events/load and attached a event listener to my script object.

var script = document.createElement('script');
script.type = "text/javascript";
script.addEventListener("load", function(event) {
    console.log("script loaded :)");
    onjqloaded(); // in fact, yourstuffscript() function
});
script.src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js";
document.getElementsByTagName('head')[0].appendChild(script);

For my needs, it works fine now. Hope this can help others :)

Quasimodo answered 11/2, 2021 at 18:38 Comment(1)
It did not work on chrome, the script loaded but the event was not being triggered.Tourbillion
M
1

The working way to load scripts in order (ie. wait until one is loaded, then load another one, etc...)

The following script is added to html page:

<script type="text/javascript">

    document.addEventListener("DOMContentLoaded", (event) => {

        function fn(src) {
            return new Promise(resolve => { // promise is initiated
                const script = document.createElement("script"); // creates <script> tag
                // script.async = true is not required since Promise is used
                script.onload = resolve; // promise will resolve on load event
                script.setAttribute("src", src); // will set srs="link to your source file here"
                document.getElementsByTagName('body')[0].appendChild(script); // append the created <script> tag to <body>
            });
        }

        const url = [ // order of script tags
            "/script1.js", 
            "/script2.js",
            "/script3.js"
        ];

        Promise.resolve(fn(url[0])) // wait until url[0] is resolved, then
            .then(() => fn(url[1])) // call and wait until url[1] is resolved, then
            .then(() => fn(url[2])) // call url[2]

    });

</script>

Important to return result in each ".then" using "() =>" This is called Chaining:

Always return results, otherwise callbacks won't catch the result of a previous promise (with arrow functions, () => x is short for () => { return x; })

Result on loaded html page:

<body>
    <!-- your html -->
    <script src="/script1.js"></script>
    <script src="/script2.js"></script>
    <script src="/script3.js"></script>
</body>

chrome developer tools

Moyra answered 13/7, 2023 at 14:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.