Conditionally load javascript (external and internal) and keep the execution order

I am looking for a way to conditionally load and maintain the execution order of some javascript files (external and internal) without any library dependency. Basically, what I want to do is download them only if the browser supports localStorage.

Here is basically my shell:

if (window.localStorage) {
//load up JS only if it needed
    var body = document.getElementsByTagName('body')[0],
        js1 = document.createElement('script'),
        js2 = document.createElement('script'),
        js3 = document.createElement('script'),
        js4 = document.createElement('script'),
        js5 = document.createElement('script');

    js1.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js';
    js2.src = 'http://www.google.com/jsapi';
    js3.src = 'my_file1.js';
    js4.src = 'my_file2.js';
    js5.src = 'my_file3.js';

    body.appendChild(js1);
    body.appendChild(js2);
    body.appendChild(js3);
    body.appendChild(js4);
    body.appendChild(js5);
} else { 
    //no localStorage support, display messaging
}

I tried dynamically adding script nodes via createElement / body.appendChild, but they don't seem to work.

Is there an easy way to achieve this? Now everything works, but IE6 and IE7 users load the script, they are not even executed, which I want to fix.

+3
source share
3

script . , . :.

if (window.localStorage) {
    // Load the local storage stuff; once loaded, it'll call
    // `doTheNextThing`
    var script = document.createElement('script');
    script.type = "text/javascript";
    script.src = /* ... the URL of the script ... */;
    document.body.appendChild(script); // Or append it to `head`, doesn't matter
                                       // and `document.body` is convenient
}
else {
    // Skip loading it
    setTimeout(doTheNextThing, 10);
}

function doTheNextThing() {
    // ...
}

... script localStorage stuff doTheNextThing — , localStorage, script doTheNextThing, , , . , ( setTimeout) : , , (, , , , IE).

. , script, , . , ( window, window.jQuery), - ():

// Load the script designated by `src`, poll for the appearance
// of the symbol `name` on the `window` object. When it shows
// up, call `callback`. Timeout if the timeout is reached.
function loadAndWait(src, name, timeout, callback) {
    var stop, script;

    // Do nothing if the symbol is already defined
    if (window[name]) {
        setTimeout(function() {
            callback("preexisting");
        }, 10);
    }
    else {
        // Load the script
        script = document.createElement('script');
        script.type = "text/javascript";
        script.src = src;
        document.body.appendChild(script);

        // Remember when we should stop
        stop = new Date().getTime() + timeout;

        // Start polling, long-ish initial interval
        setTimeout(poll, 150);
    }

    function poll() {
         if (window[name]) {
             // Got it
             callback("loaded");
         }
         else if (new Date().getTime() > stop) {
             // Time out
             callback("timeout");
         }
         else {
             // Keep waiting, shorter interval if desired
             setTimeout(poll, 75);
         }
    }
}

... jQuery:

loadAndWait(
    "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",
    "jQuery",
    10000, // ten seconds or whatever
    function(result) {
        // ...do the next one if result !== "timeout"
    }
 );

loadAndWait , :

loadThese(
    [
        {   src:    "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",
            symbol: "jQuery"
        },
        {
            src:     "http://the-next-one",
            symbol:  "nextSymbol"
        }
    ],
    doTheNextThing
);

function loadThese(scripts, callback) {
    var index = 0;
    run("okay");

    function run(result) {
        var entry;

        if (result === "timeout") {
            callback(result);
        }
        else if (index < scripts.length) {
            entry = scripts[index++];
            loadAndWait(entry.src, entry.symbol, 10000, run);
        }
        else {
            callback("loaded");
        }
    }
}

loadThese run script .

, , , .

, : , , ? , , . script , . 50k ? , , ... , (, !), ...

. , , localStorage. , CDN, script ( , ), . . () CDN , , . . " HTTP" YUI ( "", ). .

+5

onload . - :

function loadScripts(index) {
    return function () {
        var e = document.createElement('script');
        e.src = scripts[index];
        document.body.appendChild(e);

        if (index + 1 < scripts.length) {
            e.onload = loadScripts(index + 1)
        }
    };
}

:

loadScripts(0)();
+2

I came to use this code. Both main functions (addEvent and load_javascript) are on the Internet.
However, I did not try to reduce the size of the uploaded file: this is the only way to load resources. So, perhaps the idea proposed by Šime Vidas makes sense to you.

addEvent = function(elm, evType, fn, useCapture) {
    //Credit: Function written by Scott Andrews
    //(slightly modified)
    var ret = 0;

    if (elm.addEventListener) {
        ret = elm.addEventListener(evType, fn, useCapture);
    } else if (elm.attachEvent) {
        ret = elm.attachEvent('on' + evType, fn);
    } else {
        elm['on' + evType] = fn;
    }

    return ret;
};


    var left_to_load = 0;
    function init() {
        --left_to_load;
        if (left_to_load > 0) {
            return;
        }

        // all scripts are loaded now
        // proceed with your logic
    }

    // load js file and call function when done
    function load_javascript(src, callback) {
        var a = document.createElement('script');
        a.type = 'text/javascript';
        a.src = src;
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(a, s);

        ++left_to_load;
        addEvent(a, 'load', callback, false);
    }



load_javascript('url1', init);
load_javascript('url2', init);
...
0
source

Source: https://habr.com/ru/post/1770421/


All Articles