延迟脚本的运行,直到加载完所有资产



简要说明

这并不像听起来那么基本,所以在你阅读并理解我要做的事情之前,请不要跳过回答:-)。

我有一个名为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运行。这确保了jQuerySineMacula都被传递到插件。

问题

这就是问题所在,因为库正在加载到SineMacula对象中,所以无法检测它们是否已加载。

例如,如果其中一个库包含一个名为setDate()的函数插件,并且我运行:

SM.setDate()

这不一定有效,因为setDate()函数可能尚未加载到SineMacula对象中,因此它将返回"Uncaught TypeError…"。

有人能建议对SineMacula.ready()函数进行良好的调整,以检测库是否存在吗?

请不要对jQuery.load()功能提出建议,我很清楚。

除非绝对必要,否则我不希望解决方案是函数load()的回调。

我希望这是有意义的,如果不让我知道,我会发布更多的信息。希望尽可能简短。

提前感谢

更新

忘了提一下,我在这里有一个测试页面,你可以在那里看到我得到的错误,并更好地了解我在做什么:-)

如果我理解正确,是用户从他们的脚本中调用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>

不确定我是否在回答你的问题,因为缺少一些上下文,但你可能想使用Deferreds:

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.
});

最新更新