这并不像听起来那么基本,所以在阅读并理解我想要做的事情之前,请不要跳过回答: - )。
我有一个名为SineMacula
的对象,其中包含一些类似的基本函数(暂时忽略ready
函数):
(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);
通过将相关的脚本标记附加到页面的load()
,head
函数只需加载页面的所有相关插件/库。
加载页面中的所有脚本都作为回调函数运行,名为run
。这可以确保jQuery
和SineMacula
都传递给插件。
这就是问题所在,因为库被加载到SineMacula
对象中,无法检测它们是否已被加载。
例如,如果其中一个库包含一个名为setDate()
的函数插件,那么我运行:
SM.setDate()
这不一定有效,因为setDate()
函数可能尚未加载到SineMacula
对象中,因此它将返回'未捕获的TypeError ...'。
是否可以建议对SineMacula.ready()
函数进行良好的调整以检测库是否存在?
请不要对jQuery.load()
功能提出建议,我很清楚。
除非绝对必要,否则我不希望解决方案是函数load()
的回调。
我希望这是有道理的,如果不让我知道,我会发布更多信息。希望尽可能简短。
先谢谢
更新
忘记提及我有一个测试页面here,您可以在其中看到我遇到的错误并更好地了解我正在做的事情: - )
答案 0 :(得分:1)
如果我理解正确,那么它的用户会在其脚本中调用SM.run()
,然后调用SM.load()
来加载库的其他部分。
所以如果是这样的话,那么无论如何,他们的脚本将在库的任何其他部分被加载之前完成执行。
我认为您需要做的是要求用户将.run()
放在与其余代码不同的脚本中。然后,您可以使用document.write
加载其他脚本。这将导致它们加载并阻止下一个脚本,该脚本将包含用户代码的其余部分:
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>
答案 1 :(得分:1)
由于缺少某些背景信息,我不确定我是否在回答您的问题,但您可能想要使用Deferred
s:
SM.ready = ready;
function ready(callback){
var deferred = $.Deferred();
// Call the function with the Sine Macula
// and jQuery objects
jQuery(function($) {
deferred.resolve();
if (typeof(callback) === "function") {
callback(SM, $);
}
});
return deferred;
}
现在您可以执行以下操作:
SM.ready().done(function() {
// everything is now set.
});