-2

In my project, I am loading some js and css files by default in index.html file. But I need to load some other js/css files using javascript later (dynamically) and then after those dynamic files are loaded successfully, I need to call a callback function.

I checked jQuery.getScript(), which is calling callback function after each file is loaded but not all files are loaded.

I tried this:

function loadFiles(payload, callbackFunc) {
    var head = document.head || document.getElementsByTagName("head")[0];
    var fileref = null;
    if (payload.js) {
        var js = payload.js;
        for (var i = 0; i < js.length; i++) {
            var file = this.getPath("files", js[i]);
            if (!file.loaded) {
                var fileref = document.createElement('script');
                fileref.setAttribute("type", "text/javascript");
                fileref.setAttribute("src", file.path);
                fileref.onreadystatechange = callbackFunc;
                fileref.onload = callbackFunc;
                head.appendChild(fileref);
                file.loaded = true;
            }
        }
    }
    if (payload.css) {
        var css = payload.css;
        for (var i = 0; i < css.length; i++) {
            var file = this.getPath("files", css[i]);
            if (!file.loaded) {
                var fileref = document.createElement('link');
                fileref.setAttribute("rel", "stylesheet");
                fileref.setAttribute("type", "text/css");
                fileref.setAttribute("href", file.path);
                fileref.onreadystatechange = callbackFunc;
                fileref.onload = callbackFunc;
                head.appendChild(fileref);
                file.loaded = true;
            }
        }
    }
}

Please someone help me on how to solve this issue.

Answer:

Somehow the below answers didn't work for me. I wasn't able to see the dynamically added scripts in developer tool of chrome. So, I ended up modifying my above code by referring @jfriend00's answer:

function loadFiles(list, fn){
    var counter = 0;
    var head = document.head || document.getElementsByTagName("head")[0];
    for (var i = 0; i < list.length; i++) {
        var fileref = document.createElement('script');
        fileref.setAttribute("type", "text/javascript");
        fileref.setAttribute("src", list[i]);
        fileref.onload = function(){
            counter++;
            if(counter === list.length){
                fn();
            }
        }
        head.appendChild(fileref);
    }
    if(list.length === 0){
        fn();
    }
}
Community
  • 1
  • 1
Mr_Green
  • 40,727
  • 45
  • 159
  • 271
  • 4
    `$.getScript()` sounds like it is exactly what you require so I don't see why it wouldn't work. Can you please add the code you've tried to your question. – Rory McCrossan Mar 24 '15 at 07:37
  • also any error in console ? – NullPoiиteя Mar 24 '15 at 07:39
  • no errors, it is just that the same call back is being called for each loaded file. – Mr_Green Mar 24 '15 at 07:39
  • 3
    i am unable to find `$.getScript` :/ – NullPoiиteя Mar 24 '15 at 07:40
  • @NullPoiиteя I didn't use it. I just checked the example where only one file is being loaded at a time but not an array (_which is my requirement_) – Mr_Green Mar 24 '15 at 07:41
  • Do you want to call callback function only once when all are loaded? – jcubic Mar 24 '15 at 07:41
  • @RoryMcCrossan Using that I can only load one file at a time. – Mr_Green Mar 24 '15 at 07:41
  • Since you're loading multiple files, you can keep a counter, increment the counter when each file is loaded and only call the callback when the counter reaches the total indicating that all files have been loaded. – jfriend00 Mar 24 '15 at 07:41
  • 2
    The first result in google for [jquery getscript multiple](https://www.google.com.au/?gws_rd=ssl#q=jquery+getscript+multiple) seems to provide the exact answer you seek: http://stackoverflow.com/questions/11803215/how-to-include-multiple-js-files-using-jquery-getscript-method – Christian Mar 24 '15 at 07:41
  • @jcubic yes... I think I am not clear in explanation. – Mr_Green Mar 24 '15 at 07:42
  • @ChristianVaarga thanks that seems to work. will check in deep soon. – Mr_Green Mar 24 '15 at 07:47
  • how Community♦ closed this question ? so 5 close votes no longer required to close question ? – NullPoiиteя Mar 24 '15 at 07:51
  • @NullPoiиteя community asked me whether this post is dup of the other.. I said yes. and this got closed. – Mr_Green Mar 24 '15 at 07:54
  • @NullPoiиteя - users with a certain number of privilege points in questions with a common tag to the one in question can close a question as a duplicate unilaterally (with one single vote). If you think that is done in err, you can vote to reopen and/or flag for moderator attention. Though, in this case it appears the action may have been taken by a moderator of some sort since the user Community doesn't look like a regular user. – jfriend00 Mar 25 '15 at 08:17
  • @jfriend00 thanks for information , its all clear now :) – NullPoiиteя Mar 25 '15 at 08:28

2 Answers2

3

Here's a way to use $.getScript() to load multiple files using a counter:

function getScripts(list, fn) {
    var cntr = list.length;
    for (var i = 0; i < list.length; i++) {
        $.getScript(list[i], function() {
            --cntr;
            if (cntr === 0) {
                fn();
            }
        });
    }
}

getScripts(["file1.js", "file2.js"], function() {
    // all scripts loaded here
});

Here's a way using promises:

function getScripts(list) {
    var promises = [];
    for (var i = 0; i < list.length; i++) {
        promises.push($.getScript(list[i]));
    }
    return $.when.apply($, promises);
}


getScripts(["file1.js", "file2.js"]).then(function() {
    // all scripts loaded here
});

You can use these same concepts for your CSS files.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
2

To call callback function only once you need to do this check:

var count = 0;
fileref.onload = function() {
    if (payload.js.length + payload.css.length == ++count) {
        callbackFunc();
    }
};
jcubic
  • 61,973
  • 54
  • 229
  • 402