Javascript dynamic script loading via functions… h

2019-09-08 08:02发布

问题:

At present, I have a javascript callable functions (without adding global variables) that add scripts to the head.

Onload is useful for pages after the site loaded initially, but I'm waiting to load larger scripts until they're needed considering many won't need them.

The following code works for some scripts, but not for some larger ones...

function include(script) {
    var head= document.getElementsByTagName('head')[0];
    var newScript= document.createElement('script');
    newScript.type= 'text/javascript';
    newScript.src= script;
    head.appendChild(newScript);
}
function doThething(){
    include('foo');
    include('bar');
    if(document.readyState === "complete") {
        // do something needing foo and bar
    } else {
        window.addEventListener("onload", function () { 
            // do something needing foo and bar
        }
    }
}

With some scripts, the above works fine and dandy. With others (especially largers ones that client doesn't have)it tries to execute before foo has loaded. I can't change foo because it's a larger off-site public library.

How can I make it make the dom wait for the new stuff to finish loading and kick off an onload again, or otherwise ensure that foo is loaded before I doTheThing?

回答1:

You want a script onload, not a document onload. See the accepted answer here:

'onload' handler for 'script' tag in internet explorer

This is the code to admire:

var head = document.getElementsByTagName("head")[0] || document.documentElement;
var script = document.createElement("script");
if ( s.scriptCharset ) {
    script.charset = s.scriptCharset;
}
script.src = s.url;

// Handle Script loading
    var done = false;

// Attach handlers for all browsers
script.onload = script.onreadystatechange = function() {
    if ( !done && (!this.readyState ||
            this.readyState === "loaded" || this.readyState === "complete") ) {
        done = true;
        jQuery.handleSuccess( s, xhr, status, data );
        jQuery.handleComplete( s, xhr, status, data );

        // Handle memory leak in IE
        script.onload = script.onreadystatechange = null;
        if ( head && script.parentNode ) {
            head.removeChild( script );
        }
    }
};

// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
// This arises when a base node is used (#2709 and #4378).
head.insertBefore( script, head.firstChild );