[英]How can I use yepnope.js with $(document).ready() effectively?
I have been implementing the yepnope script loader as part of the modernizr.js library. 我一直在实现yepnope脚本加载器作为modernizr.js库的一部分。 I have successfully got jQuery to load and jQuery dependent scripts afterwards.
之后我成功地加载了jQuery以加载jQuery依赖脚本。 I am new to asynchronous loading of resources, so it's a bit new to me.
我是异步加载资源的新手,所以对我来说这有点新鲜。 I have been searching around, but haven't had much luck with the following.
我一直在四处寻找,但是下面没有太多运气。
My question is what are your opinions on how to effectively replace the functionality of $(document).ready() when working with the yepnope.js framework. 我的问题是,在使用yepnope.js框架时,您对如何有效替换$(document).ready()的功能有何看法?
My theory was to create a appropriately named function in my base library and then set that variable on my pages to an anonymous function containing my existing $(document).ready() code. 我的理论是在我的基础库中创建一个适当命名的函数,然后在我的页面上将该变量设置为包含我现有的$(document).ready()代码的匿名函数。 This variable would then be called by yepnope after all the scripts had loaded in the complete callback.
在所有脚本加载到完整回调之后,yepnope将调用此变量。
Would you agree that this is a good way of doing it, or am I approaching this entirely the wrong way? 你是否同意这是一个很好的方法,或者我是否完全以错误的方式接近这个?
(For those unaware, the asynchronous nature of yepnope.js means that the document calls $ or jQuery before the yepnope loader has finished, throwing a "$ is undefined" error <- please correct me if that is wrong.) (对于那些不知道的人,yepnope.js的异步性质意味着文档在yepnope加载器完成之前调用$或jQuery,抛出“$ is undefined”错误< - 如果错误请纠正我。)
First question, hope it's a good one. 第一个问题,希望它是一个好的。
This is the technique I use. 这是我使用的技术。 It allows me to sprinkle $(document).ready() style calls wherever I like.
它允许我在任何我喜欢的地方撒上$(document).ready()样式的调用。 Using this method, you can take a site that already uses jQuery and has existing $(document).ready() calls, and easily retrofit yepnope.
使用此方法,您可以使用已经使用jQuery并且已经存在$(document).ready()调用的站点,并轻松地改进yepnope。
First, add this line of JS, preferably in the document head, before any javascript that calls $(document).ready(): 首先,在任何调用$(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>
Then, have your yepnope jQuery test object set similar to this: 然后,让你的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]);
}
});
We create a fake $(document).ready() before jQuery loads. 我们在jQuery加载之前创建一个假的$(document).ready()。 This stores every $(document).ready() call in an array, docready.
这将每个$(document).ready()调用存储在一个数组docready中。 Then, once jQuery has loaded, we overwrite our temporary $ object with the now loaded real jQuery object.
然后,一旦jQuery加载,我们用现在加载的真实jQuery对象覆盖我们的临时$对象。 Then, we iterate through all the stored $(document).ready() calls, and execute them for real.
然后,我们遍历所有存储的$(document).ready()调用,并执行它们。
UPDATED: improved version from Chris Jones that also covers $(function() {}) style invocations. 更新:Chris Jones的改进版本,也涵盖了$(function(){})样式调用。
If load jQuery without yepnope isn't a problem for you, there is a easier way to do. 如果没有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>
script tags are loading synchronously - so if you put your yepnope in a js file and load it via script tag: 脚本标签正在同步加载 - 所以如果你把你的yepnope放在一个js文件中并通过脚本标签加载它:
<script type="text/javascript" src="/my-yepnope-stuff.js"></script>
</body>
right before the closing body tag you can be quite sure to be at $(document).ready() state. 在关闭正文标记之前,您可以确定处于$(document).ready()状态。
What you need to answer for yourself is whether it makes sense to force yepnope to load in a $(document).ready() fashion, as its main purpose is to break the synchronous loading order of script tags in the first place. 您需要自己回答的是强制yepnope以$(document).ready()方式加载是否有意义,因为它的主要目的是首先打破脚本标记的同步加载顺序。
I think that Alex Sexton solution would be correct : 我认为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");
});
}
});
Using guidance from @ezmilhouse, I thought about the best way to achieve what I was after while still keeping compatibility with our older code. 使用@ezmilhouse的指导,我想到了实现我所追求的目标的最佳方法,同时仍然保持与旧代码的兼容性。
My solution was to set up my yepnope scriptloader to load all necessary scripts in a hierarchical fashion, based on their individual dependencies. 我的解决方案是设置我的yepnope脚本加载器,以基于各自的依赖关系以分层方式加载所有必需的脚本。 Once all scripts are loaded, you can use the
complete
property of my call to yepnope to call my ready function. 加载
complete
所有脚本后,您可以使用我对yepnope的调用的complete
属性来调用我的ready函数。 This meant that the document was effectively ready and the code would work with no issues. 这意味着该文档已经有效准备好,代码可以正常工作。
I also moved my js to the base of my pages (something that I should have done a long time ago, but we had a lot of legacy pages! :) ) 我也将我的js移动到我的页面底部(我应该在很久以前做过的事情,但我们有很多遗留页面!:))
Here is an example (using false libray/script names for illustration purposes only): 这是一个示例(使用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");
}
}
});
In my page js I will assign a function to baseLib.Page.Ready
that will then be called by yepnope on complete. 在我的页面js中,我将为
baseLib.Page.Ready
分配一个函数,然后由yepnope在完成时调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.