我一直在实现yepnope脚本加载器作为modernizr.js库的一部分。之后我成功地加载了jQuery以加载jQuery依赖脚本。我是异步加载资源的新手,所以对我来说这有点新鲜。我一直在四处搜寻,但以下情况并不好运。
我的问题是,在使用yepnope.js框架时,您对如何有效替换$(document).ready()的功能有何看法?
我的理论是在我的基础库中创建一个适当命名的函数,然后在我的页面上将该变量设置为包含我现有的$(document).ready()代码的匿名函数。在所有脚本加载到完整回调之后,yepnope将调用此变量。
您是否同意这是一种很好的方式,或者我是否完全以错误的方式接近这一点?
(对于那些不知道的人,yepnope.js的异步性质意味着文档在yepnope加载器完成之前调用$或jQuery,抛出“$ is undefined”错误< - 如果错误请纠正我。)
第一个问题,希望它是一个好问题。
答案 0 :(得分:11)
这是我使用的技术。它允许我在任何我喜欢的地方撒上$(document).ready()样式的调用。使用此方法,您可以使用已经使用jQuery并且已经存在$(document).ready()调用的站点,并轻松地改进yepnope。
首先,在调用$(document).ready()的任何javascript之前,最好在文档头中添加这一行JS。
<script>
var docready=[],$=function(o){function r(fn){docready.push(fn);}if(typeof o === 'function') r(o);return{ready: r}};
</script>
然后,将你的yepnope jQuery测试对象设置为类似于:
yepnope({
load: '//ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js',
complete: function() {
$ = jQuery;
for(n in docready) $(document).ready(docready[n]);
}
});
我们在jQuery加载之前创建一个假的$(document).ready()。这将每个$(document).ready()调用存储在一个数组docready中。然后,一旦jQuery加载,我们用现在加载的真实jQuery对象覆盖我们的临时$对象。然后,我们遍历所有存储的$(document).ready()调用,然后执行它们。
更新:Chris Jones的改进版本,也涵盖$(function(){})样式调用。
答案 1 :(得分:11)
如果没有yepnope加载jQuery对你来说不是问题,那么有一种更简单的方法。
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
$.holdReady(true);
yepnope.load({
load: [
'placeholder.js',
'jquery-ui.min.js'
],
complete: function (){
$.holdReady(false);
}
});
</script>
答案 2 :(得分:1)
脚本标签正在同步加载 - 所以如果你把你的yepnope放在一个js文件中并通过脚本标签加载它:
<script type="text/javascript" src="/my-yepnope-stuff.js"></script>
</body>
在关闭正文标记之前,您可以确定处于$(document).ready()状态。
你需要自己回答的是强迫yepnope以$(document).ready()方式加载是否有意义,因为它的主要目的是首先打破脚本标记的同步加载顺序
答案 3 :(得分:0)
使用来自@ezmilhouse的指导,我想到了实现我所追求的目标的最佳方式,同时仍保持与旧代码的兼容性。
我的解决方案是设置我的yepnope脚本加载器,以基于各自的依赖关系以分层方式加载所有必需的脚本。加载完所有脚本后,您可以使用我调用yepnope的complete
属性来调用我的ready函数。这意味着该文档已经准备就绪,代码可以正常工作。
我也把我的js移到了我的页面底部(很久以前我应该做的事情,但是我们有很多遗留页面!:)
这是一个例子(使用虚假的libray /脚本名称仅用于说明目的):
yepnope({
test: baseLib.debug,
yep: { "max": "/version2/res/jquery/jquery-1.5.2.js" },
nope: { "min": "/version2/res/jquery/jquery-1.5.2.min.js" },
callback: {
"max": function (url, result, key) {
baseLib.Log("jQuery full loaded.");
},
"min": function (url, result, key) {
baseLib.Log("jQuery min loaded.");
}
},
complete: function () {
if (window.$) {
yepnope({
test: base.debug,
yep: {
"anotherscript": "script/url/here.js",
"anotherscript2": "script/url/here2.js"
},
nope: {
"anotherscript": "script/url/here-min.js",
"anotherscript2": "script/url/here2-min.js"
},
both: {
"anotherscript3": "script/url/here3.js"
},
callback: {
"anotherscript": function (url, result, key) {
baseLib.Log("anotherscript " + (result ? "Max" : "Min") + " loaded.");
},
"anotherscript2": function (url, result, key) {
baseLib.Log("anotherscript2 " + (result ? "Max" : "Min") + " loaded.");
},
"anotherscript3": function (url, result, key) {
baseLib.Log("anotherscript3 loaded.");
}
},
complete: function () {
baseLib.Log("Scripts Loaded");
baseLib.Page.Ready();
}
});
}
else {
baseLib.Log("Could not load jQuery. No further jQuery dependent files loaded.", "error");
}
}
});
在我的页面js中,我将为baseLib.Page.Ready
分配一个函数,然后由yepnope在完成时调用。
答案 4 :(得分:0)
我认为Alex Sexton solution是正确的:
yepnope({
load: '//ajax.googleapisOFFLINE.com/ajaxX/libs/jquery/1.7.1/jquery.min.js',
callback: function () {
if (!window.jQuery) {
yepnope('/js/jquery-1.7.1.min.js');
}
},
complete: function () {
$(function(){
$("div.whatever").css("color","red");
});
}
});