是$(document).ready()还是CSS准备好了? [英] Is $(document).ready() also CSS ready?

查看:280
本文介绍了是$(document).ready()还是CSS准备好了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本执行$(document).ready(),它应该垂直对齐块元素在我的布局。 90%的时间,它工作没有问题。但是,对于额外的10%,发生以下两种情况之一:




  • 定心,块元件跳入位置。这可能只是性能相关的 - 因为页面大小通常很大,并且有大量的JavaScript一次执行。


  • 混乱,块元素将被推下太远或不够远。




是否有任何理由要执行DOM-ready上的脚本不会有所有正确的CSS值注入到DOM呢? (所有CSS都位于< head> 通过< link> )。



此外,这里是导致问题的脚本(是的,它是直接从与第二个外部JS后获得jQuery,显示,它不是一个通用规则,JS暂停到早期已定义的CSS已加载。似乎有一些使用外部JS和CSS的组合。



最后一个注意事项:由于JS Bin在裸网址上运行时会在每个脚本中包含Google Analytics(分析)(如 jsbin.com/aqeno 测试结果实际上是由JS Bin 改变的...看来编辑网址上的输出标签(例如 jsbin.com/aqeno/edit )不包含其他Google Analytics(分析)事实,并且肯定会产生不同的结果,但是这个URL很难使用webpagetest.org测试。对样式表阻止 strager 中提供的Firefox和JavaScript执行中的下载是一个更好的理解的好开始,但我有很多问题...还要注意Steve Souders的 IE8并行脚本加载,使事情更复杂。 (上面的瀑布是使用IE7创建的)



也许人们应该相信发行说明和文档...


I've got a script executing on $(document).ready() that's supposed to vertically align block element in my layout. 90% of the time, it works without issue. However, for that extra 10% one of two things happens:

  • There's an obvious lag in the time it takes to do the centering, and the block elements jump into position. This could simply be performance related - as the page size is often large and there is a fair amount of javascript that is executing at once.

  • The centering will completely mess up, and the block element will either pushed down too far or not far enough. It appears as if it tried to calculate the height, but was getting improper measurements.

Is there any reason why executing a script on DOM-ready would not have all the correct CSS values injected into the DOM yet? (all CSS is in the <head> via a <link>).

Also, here's the script that's causing the issue (yes, it's been taken straight from here):

 (function ($) {
    // VERTICALLY ALIGN FUNCTION
    $.fn.vAlign = function() {
      return this.each(function(i) {
        var ah = $(this).height();
        var ph = $(this).parent().height();
        var mh = (ph - ah) / 2;
        $(this).css('margin-top', mh);
      });
    };
  })(jQuery);

Thanks.

解决方案

From the 1.3 release notes:

The ready() method no longer tries to make any guarantees about waiting for all stylesheets to be loaded. Instead all CSS files should be included before the scripts on the page. More Information

From the ready(fn) documentation:

Note: Please make sure that all stylesheets are included before your scripts (especially those that call the ready function). Doing so will make sure that all element properties are correctly defined before jQuery code begins executing. Failure to do this will cause sporadic problems, especially on WebKit-based browsers such as Safari.

Note that the above is not even about actually rendering the CSS, so you may still see the screen change when ready() kicks in. But it should save you from problems.

Actually, I find it a bit strange that just putting the CSS above the JS will solve all issues. The CSS is loaded asynchronously, so JS loading can start and finish while the CSS is still being downloaded. So if the above is a solution, then executing any JS code is then halted until all earlier requests have completed?

I did some testing, and indeed, sometimes JS is delayed until the CSS is loaded. I don't know why, because the waterfall shows that the JS has completed loading long before downloading the CSS has finished.

See JS Bin for some HTML and its results (this has a 10 second delay), and see webpagetest.org for its waterfall results. This uses some script from Steve Souders' cuzillion.com to mimic slow responses. In the waterfall, the reference to resource.cgi is the CSS. So, in Internet Explorer, the first external JS starts to load right after the CSS was requested (but that CSS will take another 10 seconds to finish). But the second <script> tag is not executed until the CSS has finished loading as well:

<link rel="stylesheet" type="text/css" href=".../a script that delays.cgi" />

<script type="text/javascript" src=".../jquery.min.js"></script> 

<script type="text/javascript"> 
  alert("start after the CSS has fully loaded"); 
  $(document).ready(function() { 
    $("p").addClass("sleepcgi"); 
    alert("ready"); 
  });         
</script> 

Another test with a second external JS after getting jQuery, shows that the download of the second JS is not started until the CSS has loaded. Here, the first reference to resource.cgi is the CSS, the second the JS:

Moving the stylesheet below all JS indeed shows that the JS (including the ready function) runs much earlier, but even then the jQuery-applied class --which is yet unknown when the JS runs-- is used correctly in my quick tests in Safari and Firefox. But it makes sense that things like $(this).height() will yield wrong values at that time.

However, additional testing shows that it is not a generic rule that JS is halted until earlier defined CSS is loaded. There seems to be some combination with using external JS and CSS. I don't know how this works.

Last notes: as JS Bin includes Google Analytics in each script when running from the bare URL (like jsbin.com/aqeno, the test results are actually changed by JS Bin... It seems that the Output tab on the edit URL such as jsbin.com/aqeno/edit does not include the additional Google Analytics things, and surely yields different results, but that URL is hard to test using webpagetest.org. The reference to Stylesheets Block Downloads in Firefox and JavaScript Execution in IE as given by strager is a good start for a better understanding, but I got many questions left... Also note Steve Souders' IE8 Parallel Script Loading to make things even more complicated. (The waterfalls above are created using IE7.)

Maybe one should simply believe the release notes and documentation...

这篇关于是$(document).ready()还是CSS准备好了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆