Async Script Loader with Callback

var Loader = function () { }
Loader.prototype = {
    require: function (scripts, callback) {
        this.loadCount      = 0;
        this.totalRequired  = scripts.length;
        this.callback       = callback;

        for (var i = 0; i < scripts.length; i++) {
    loaded: function (evt) {

        if (this.loadCount == this.totalRequired && typeof this.callback == 'function');
    writeScript: function (src) {
        var self = this;
        var s = document.createElement('script');
        s.type = "text/javascript";
        s.async = true;
        s.src = src;
        s.addEventListener('load', function (e) { self.loaded(e); }, false);
        var head = document.getElementsByTagName('head')[0];


var l = new Loader();
    function() {
        // Callback
        console.log('All Scripts Loaded');

Reference URL


  1. Mufeed Ahmad
    Permalink to comment#

    i request you to provide these code with demo… will help us a lot..

    thank you for your help.

  2. Jerome Covington
    Permalink to comment#

    Thanks I just borrowed the writeScript method and trimmed it down a bit. Surprising how many times I do async loading and always forget the exact way to create the script element etc. Thanks!

  3. Michiel Van Laere
    Permalink to comment#

    Maybe good to mention that “addEventListener” is not supported in IE8 or lower.
    They use “attachEvent”. You can support IE like this:

    if(s.addEventListener) {
    s.addEventListener(‘load’, function (e) { self.loaded(e); }, false);
    } else if(s.attachEvent) {
    s.attachEvent(‘load’, function (e) { self.loaded(e); }

    Or if you are using jQuery you can use:

    jQuery(s).load(function(e) { self.loaded(e); });


    • jockchou
      Permalink to comment#

      But script tag have not ‘load’ event. you should use ‘onreadystatechange’ to listene the scripts load.
      if (s.addEventListener) {
      s.addEventListner(‘load’, function(e) {
      //callback here
      }, false);
      } else {
      s.onreadystatechange = function() {
      if (s.readyState in {loaded: 1, complete: 1}) {
      //callback here

      //some code

      function loadScript(url, callback){
      var script = document.createElement(“script”);
      script.type = “text/javascript”;
      script.charset = “utf8”;
      if (script.readyState) {//IE
      script.onreadystatechange = function() {
      if (script.readyState == ‘loaded’ || script.readyState == ‘complete’) {
      script.onreadystatechange = null;
      if (typeof callback === ‘function’) {
      } else {//other browers
      script.onload = function() {
      script.onload = null;
      if (typeof callback === ‘function’) {
      script.src = url;

  4. David Vespoli
    Permalink to comment#

    @jockchou : your comment about using onreadystatechange instead as the trigger for the callback helped me get this working in IE8. Thanks!

  5. Daniel Bammer
    Permalink to comment#

    This snippet didn’t really work out for me but jQuery.getScript() workes like a charm!

    • Howard Brown
      Permalink to comment#

      I’m running on a local server while I investigate using the JQuery.UI.Datepicker plugin. The plugin requires a few patches and I’d like to wrap the datepicker’s library code load and the patches into a wrapper script that the page using the datepicker plugin can include, so allow the wrapper script to load the library, I’m trying to use the JQuery.getScript call, but I’m running into the following error:

      jquery-1.12.4.js:10254 XMLHttpRequest cannot load file:///D:/Users/.../Datepicker Widget.js?_=1469194829595.
      Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.send @ jquery-1.12.4.js:10254
      Datepicker Widget.html:118 Uncaught TypeError: $(...).datepicker is not a function

      I believe that this is caused because my site is hosted locally, so doesn’t have a HTTP or HTTPS protocol prefix in the URL for the file that I’m trying to load. For local includes, is there a simple to I get this to work that doesn’t require that I register my own domain? After I am finished testing the datepicker my code will be moved to a server that has it’s own HTTP URL so this probably won’t be an issue then, but in the meantime or for other local projects I’d like to better understand how to make this all work.

    • Flimm
      Permalink to comment#

      The success callback for jQuery.getScript is called once the script has been downloaded, but it’s not guaranteed to be called after the script has been executed.

  6. Ankit G.
    Permalink to comment#

    A little advanced javascript loader based on this technique but with a little extra feature that it does not re download a script in any case.

    • Tony
      Permalink to comment#

      Well that’s a shame, this turns out to be a 404, is it a private repo? Would be interesting to see how you’ve gone about this :)

    • Ankit G.
      Permalink to comment#

      @Tony I have deleted that repository but If you want then I can repost it for you. Do you still want it?

    • Tony
      Permalink to comment#

      Hey Ankit, That would be good thanks :) Although why not use github gist?

    • Swaminathan
      Permalink to comment#

      @Ankit Please repost the repo. It would be very useful

  7. Howard Brown
    Permalink to comment#

    Ankit G., I too would be very interested in seeing the repository that you deleted.

    Would you or anyone else know if these solutions, your and the $.getScript, will load JavaScript files and CSS files, too.

    Also, because I’m new to all of this please let me ask about when to use the call-back feature. If I use these methods to include a Javascript file in the page header area, do I execute it with the call-back, perhaps using a document.ready event, or must the execution be done in the page body?

    I currently am trying to load the JQuery.UI Datepicker library and some patching functions that modify some of the basic behaviours of datepicker, which requires that I run the library and patch functions before I can use them in my page body to create the datepicker controls. In my current code the datepicker’s library and JQuery are loaded with tags in the page header, but the patch functions are in tags in the page body, where they are created and then executed. I want to put the datepicker library load and the patch functions in a wrapper script file. The script could probably be loaded normally using the tag in the page header. This all would look sort of like the following:

          The following wrapper files contains the $.getScript( 'JQuery.UI.Datepicker URL') and
          several patch functions that modify the datepicker object created by the getScript loader.
        <!-- Code that uses the patched datepicker -->
    The wrapper would be structured something like:
    /* *********************************************************
          Using $.getScript to load the JQuery.UI.Datepicker and
          then defining the patch functions needed to modify the
          datepickers behaviours.
         ********************************************************* */
    $.getScript( 'JQuery.UI.Datepicker URL' ...
    /* Define Patch functions */
    function Patch1() { ... }
    function PatchN() { ... }
    /* Execute Patch functions */
    /* End of Wrapper file */

    If structured this way and the datepicker and patching functions had code that was executed using the call-back feature, would this work?

    Alternatively, I could call the functions using the document.ready event using code in the wrapper file, if that was simpler.

    Howard Brown

Leave a Comment

Posting Code

We highly encourage you to post problematic HTML/CSS/JavaScript over on CodePen and include the link in your post. It's much easier to see, understand, and help with when you do that.

Markdown is supported, so you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences like this:

  function example() {
    element.innerHTML = "<div>code</div>";

We have a pretty good* newsletter.