This is not as basic as it sounds, so please do not skip to answering before you have read and understood what I am trying to do :-).
I have an object called SineMacula
which contains a few base functions like so (ignore the ready
function for the moment):
(function(global, $){
// MOST CODE STRIPT OUT HERE */
/**
* Sine Macula Run
* Makes it easy to write plugins for the Sine Macula library
*
* @param function callback
*/
SM.run = run;
function run(callback){
// Call the function with the Sine Macula
// and jQuery objects
callback(SM, $);
}
/**
* Sine Macula Ready
* Executes code once the Sine Macula and jQuery
* libraries are ready
*
* @param function callback
*/
SM.ready = ready;
function ready(callback){
// Call the function with the Sine Macula
// and jQuery objects
jQuery(function($) {
callback(SM, $);
});
}
/**
* Sine Macula Load
* Load the Sine Macula Libraries and Plugins
* into the current document
*
* The options:
* - package: the package of libraries to load
* - packageURL: a remote source to load the package details from
* - libraries: any additional libraries to load
*
* @param object parameter The options for the Sine Macula load
*/
SM.load = load;
function load(options){
// BUILD A QUERY HERE
// ...
// Complete the url by appending the query
url = '//libraries.sinemaculammviii.com/'+query;
// Append the script tag to the end of the document
script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
$('head')[0].appendChild(script);
}
})(this, this.jQuery);
The load()
function simply loads in all relevant plugins/libraries for the page by appending a relevant script tag to the head
of the page.
All the scripts in the loaded pages are run as a callback to the function called run
. This ensures that both jQuery
and SineMacula
are passed through to the plugins.
This is where the issue lies, because the libraries are being loaded into the SineMacula
object, there is no way to detect whether they have been loaded or not.
For example, if one of the libraries contains a function plugin called setDate()
, and I run:
SM.setDate()
This will not necessarily work because the setDate()
function may not have been loaded into the SineMacula
object yet and therefore it will return an 'Uncaught TypeError...'.
Can anybody advise of a good adaptation to the SineMacula.ready()
function to detect whether or not the libraries are present?
Please do not make suggestions to do with the jQuery.load()
function, I am well aware of it.
I do not want the solution to be a callback of the function load()
, unless absolutely necessary.
I hope this makes sense, if not let me know and I will post more info. Wanted to keep it as brief as possible.
Thanks in Advance
UPDATE
Forgot to mention that I have a testing page here where you can see the error I am getting and get a better understanding of what I am doing :-)
If I understand correctly, its the user that invokes SM.run()
from within their script, which then calls SM.load()
, which loads other parts of the library.
So if that's the case, then no matter what, their script will finish executing before any other parts of the library can be loaded.
I think what you'd need to do is have a requirement that the user have their .run()
in a separate script from the rest of their code. Then you can use document.write
to load the other scripts. This will cause them to load and block the next script, which would contain the rest of the user's code:
function load(options){
// BUILD A QUERY HERE
// ...
// Complete the url by appending the query
document.write('<scr' + 'ipt type="text/javascript" ',
' src="//libraries.sinemaculammviii.com/' + query,
'"><\/scr' + 'ipt>');
}
<script type="text/javascript" src="/path/to/your/lib.js"></script>
<script type="text/javascript">
SineMacula.load('all');
</script>
<!-- The document.write will write the new script here, and it will be loaded
syncronously, so it will block. -->
<script type="text/javascript">
// code that uses the loaded library parts
</script>