如何有效地使用yepnope.js和$(document).ready()?

我一直在实现yepnope脚本加载器作为modernizr.js库的一部分。 之后我成功地加载了jQuery以加载jQuery依赖脚本。 我是异步加载资源的新手,所以对我来说这有点新鲜。 我一直在寻找,但以下没有太多运气。

我的问题是,在使用yepnope.js框架时,您对如何有效地替换$(document).ready()的function有何看法?

我的理论是在我的基础库中创建一个适当命名的函数,然后在我的页面上将该变量设置为包含我现有的$(document).ready()代码的匿名函数。 在所有脚本加载到完整回调中之后,yepnope将调用此变量。

你是否同意这是一个很好的方法,或者我是否完全以错误的方式接近这个?

(对于那些不知道的人,yepnope.js的异步性质意味着文档在yepnope加载器完成之前调用$或jQuery,抛出“$ is undefined”错误< – 如果错误,请纠正我。)

第一个问题,希望它是一个好问题。

如果没有yepnope加载jQuery对你来说不是问题,那么有一种更简单的方法。

  

这是我使用的技术。 它允许我在任何我喜欢的地方撒上$(document).ready()样式的调用。 使用此方法,您可以使用已经使用jQuery的站点并且已经存在$(document).ready()调用,并且可以轻松地改进yepnope。

首先,在任何调用$(document).ready()的javascript之前,最好在文档头中添加这行JS;

  

然后,让你的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(){})样式调用。

脚本标签正在同步加载 – 所以如果你把你的yepnope放在一个js文件中并通过脚本标签加载它:

    

在关闭正文标记之前,您可以确定处于$(document).ready()状态。

你需要自己回答的是强制yepnope以$(document).ready()方式加载是否有意义,因为它的主要目的是首先打破脚本标记的同步加载顺序。

使用来自@ezmilhouse的指导,我想到了实现我所追求的目标的最佳方法,同时仍然保持与旧代码的兼容性。

我的解决方案是设置我的yepnope脚本加载器,以基于各自的依赖关系以分层方式加载所有必需的脚本。 加载所有脚本后,您可以使用我的调用yepnope的complete属性来调用我的ready函数。 这意味着该文档已经准备就绪,代码可以正常工作。

我也将我的js移动到我的页面底部(我应该在很久以前做过的事情,但我们有很多遗留页面!:))

这是一个示例(使用false libray / script名称仅用于说明目的):

 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在完成时调用。

我认为Alex Sexton 解决方案是正确的:

 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"); }); } }); 
Interesting Posts