When does a dynamically loaded JavaScript library become available?

I wrote a JavaScript library to use FileSaver.js and its associated libraries. However, I do not want to always download FileSaver.js whenever someone wants to use my library. And I don’t want to force them to load all the various JavaScript libraries associated with FileSaver with the tags themselves script(or even download one of mine that will do this).

Instead, I would prefer something like this. When they call my function createImage, it first does the following:

function createImage(image, name) {
  if (typeof(saveAs) !== 'function') {
    var element = document.createElement('script');
    element.async = false;
    element.src = 'FileSaver.js';
    element.type = 'text/javascript';
    (document.getElementsByTagName('head')[0]||document.body).appendChild(element);
  }
  // now do the saveImage code
}

The problem is that after the above, the function saveAsis not yet defined. Only after my createImageis the final function completed saveAs.

+4
5

. AMD - , , . AMD - , - require.js - AMD.

, , require.js . , / (, java, # python). " ", , ?

, , .

2015

. - , , Webpack Browserify, , (webpack ). npm AMD .

+9

, , script . , ie < 7.

Mootools Asset.javascript :

var loadScript = function (source, properties) {
    properties || (properties = {});
    var script = document.createElement('script');
    script.async = true;
    script.src = source;
    script.type = 'text/javascript';
    var doc = properties.document || document, load = properties.onload || properties.onLoad;
    return delete properties.onload, delete properties.onLoad, delete properties.document, 
    load && (script.addEventListener ? script.addEventListener("load", load) : script.attachEvent("readystatechange", function() {
        [ "loaded", "complete" ].indexOf(this.readyState) >= 0 && load.call(this);
    })), script.set(properties).appendChild(doc.head);
}

loadImage :

function createImage(image, name) {
  function createImg() {
      // now do the saveImage code
  }
  if (typeof(saveAs) !== 'function') {
     loadScript("FileSaver.js", {onLoad: createImg});//load library
  }
  else {
     createImg();
  }
}

.

+1
0

, AMD ( meh...)

FileSaver.js

requirejs config/main.js:

(function() {
    // REMEMBER TO DUPLICATE CHANGES IN GRUNTFILE.JS
    requirejs.config({
        paths: {
            "jquery": "PATH/jquery.min", // NO .js
            "lib.filesaver" : "PATH/FileSaver", // NO .js
            "shim.blob" : "PATH/Blob" // NO .js
        },
        shim: {
            "lib.filesaver": {deps: ["shim.blob"]}
        }
    });

    define([
        "jquery"
    ], function(
        $
        ) {
            $(document).ready(function() {
                // start up code...
            });
        return {};
        });
})();

Blob.js/jquery Filersaver

I also created IEShim for pre IE10

define([], function () {
    /**
     * @class IEshims
     * container for static IE shim functions
     */
    var IEShims = {
        /**
         * saveFile, pops up a built in javascript file as a download
         * @param {String} filename, eg doc.csv
         * @param {String} filecontent eg "this","is","csv"
         */
        saveAs: function (filename, filecontent, mimetype ) {
            var w = window.open();
            var doc = w.document;
            doc.open( mimetype,'replace');
            doc.charset = "utf-8";
            doc.write(filecontent);
            doc.close();
            doc.execCommand("SaveAs", null, filename);
        }
    };
    return IEShims;
});

And finally, when I want to use Fileaver, make it necessary (along with IEShim for bad browsers)

define([
"lib.filesaver",
"IEShims"
],
function (
    FileSaver, // it empty, see saveAs global var
    IEShims
    ) {
...
    var fileName = "helloworld.txt";
    var fileContents = "Me haz file contents, K Thx Bye";
    var mimeType = "text/plain";
    if(saveAs) {
        var blob = new Blob(
            [fileContents],
            {type: mimeType + ";charset=" + document.characterSet}
        );
        saveAs(blob, fileName);
    } else {
        IEShims.saveAs(fileName, fileContents,mimeType );
    }
    ...
};
0
source

The simplest answer is to put your code in the handler of the onloadcreated tag script:

<script>
  var firstScript = document.getElementsByTagName('script')[0],
      js = document.createElement('script');
  js.src = 'https://cdnjs.cloudflare.com/ajax/libs/Snowstorm/20131208/snowstorm-min.js';
  js.onload = function () {
    // do stuff with your dynamically loaded script
    snowStorm.snowColor = '#99ccff';
  };
  firstScript.parentNode.insertBefore(js, firstScript);
</script>
Run codeHide result

Uploading scripts dynamically in this way is done by Facebook .

0
source

All Articles