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.