so i use one js file to load multiple html and js files whenever they are needed. I have a working code for plenty modules. In the example below you can see the first two modules. All of them look exactly the same. Now i want to "outsource" recurring code into a function with parameters so that the code-amount overall gets minimized. Since i have never done something like this before i could need some help (i am learning js at the moment). I would realy appreciate some help.
//first module
if (moduleID === "placeone") {
var isLoaded = 0;
if (isLoaded) {
console.log("file already loaded");
returnValue = new PlaceOneModule(id, moduleInitialData);
}
$("#placeone").load("html/modules/PlaceOneModule.html", function (response, status, xhr) {
console.log("PlaceOneModule.html" + " " + status);
$.getScript("js/modules/PlaceOneModule.js").done(function () {
console.log("PlaceOneModule.js geladen");
isLoaded = 1;
returnValue = new PlaceOneModule(id, moduleInitialData);
}).fail(function () {
console.log("PlaceOneModule.js nicht geladen");
});
});
}
//second module
if (moduleID === "placetwo") {
var isLoaded = 0;
if (isLoaded) {
console.log("file already loaded");
returnValue = new PlaceTwoModule(id, moduleInitialData);
}
$("#placetwo").load("html/modules/PlaceTwoModule.html", function (response, status, xhr) {
console.log("PlaceTwoModule.html" + " " + status);
$.getScript("js/modules/PlaceTwoModule.js").done(function () {
console.log("PlaceTwoModule.js geladen");
isLoaded = 1;
returnValue = new PlaceTwoModule(id, moduleInitialData);
}).fail(function () {
console.log("PlaceTwoModule.js nicht geladen");
});
});
}
The question is rather complex to answer, as there are many things to account for.
var cache = {};
function module(name, target, done) {
if (!(name in cache)) {
return $(target).load('html/modules/' + name + '.html', function(response, status, xhr) {
console.log(name + '.html ' + status);
$.getScript('js/modules/' + name + '.js')
.done(function() {
console.log(name + '.js geladen');
cache[name] = window[name];
done(null, cache[name]);
})
.fail(function() {
var message = name + '.js nicht geladen';
cache[name] = function() {
console.error(message);
};
done(message);
});
});
}
setTimeout(function() {
done(null, cache[name]);
}, 0);
}
I'll try to explain my train of thought behind this:
var cache = {} - you will need something to keep track of each individual modulefunction module(name, target, done) {
name would be the base name of your module, e.g. PlaceTwoModule, this was already used consistently across the html and js files and the js function nametarget would be the selector where the html file should be loadeddone) argumentif (!(name in cache)) - if the module is not yet cached, it requires some fetching, so the load is triggered first thingload completes, it will fire the $.getScript
$.getScript works out, the name will be assumed to be in window and a reference is stored in the cache variable, after that, the done callback is invoked (with the function as second argument).$.getScript didn't work out, we add a function to the cache, which does nothing more than telling you it will not work, after that, the done callback is invoked (with an error as first argument).name did exist in the cache, we will be calling the done callback right after we exit the module functionSo, how to use this?
It now boils down to calling the module function
module('#placeone', 'PlaceOneModule', function(error, PlaceModule) {
if (error) throw new Error(error);
var instance = new PlaceModule(id, initial);
// ...
}
I have used the common function(error, value) {..} signature for the callback function, which always has the error as first argument (allowing for other arguments to be added and made optional).
There are some caveats/assumptions worth mentioning:
module are still loadingtarget you invoke module with, it will only load 'once' (well, see the previous line ;-) )window) scope in order to keep the example simple, keep in mind to not 'pollute the global scope'This has become a rather elaborate answer, I hope I explained every step involved sufficiently.