$(document).ready()也是CSS准备好了吗?
我有一个脚本在$(document).ready()上执行,它应该在我的布局中垂直alignment块元素。 90%的时间,它的工作没有问题。 然而,额外的10%发生了两件事情之一:
-
做对中所需的时间有明显的滞后,块单元跳到位。 这可能只是性能相关 – 因为页面大小通常很大,并且有相当数量的javascript一次执行。
-
居中将完全混乱,块元素将推倒得太远或不够远。 看来好像它试图计算高度,但得到不正确的测量。
是否有任何理由为什么在DOM准备好执行脚本不会有所有正确的CSS值注入DOM呢? (所有的CSS都通过<link>
在<head>
<link>
)。
此外,这是导致问题的脚本(是的,这是直接从这里 ):
(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);
谢谢。
从1.3发行说明 :
ready()方法不再试图保证等待所有样式表被加载。 相反,所有的CSS文件应该包含在页面上的脚本之前。 更多信息
从ready(fn)文档 :
注意:请确保所有样式表都包含在脚本之前(尤其是那些调用ready函数的样式表)。 这样做将确保在jQuery代码开始执行之前正确定义所有元素属性。 不这样做会导致零星的问题,特别是在基于WebKit的浏览器,如Safari。
请注意,上面的内容甚至不是关于实际渲染 CSS的,所以你可能仍然会在ready()
开始的时候看到屏幕的变化。但是这样可以避免你的问题。
其实,我觉得把JS放在JS上面会解决所有的问题有点奇怪。 CSS是asynchronous加载的,所以JS加载可以在CSS下载的时候开始和结束 。 所以如果上面的解决scheme,那么执行任何JS代码,然后停止,直到所有先前的请求已完成?
我做了一些testing,实际上, 有时 JS会延迟到CSS加载。 我不知道为什么,因为瀑布显示,在下载完CSS之前,JS已经完成了加载。
查看JS Bin了解一些HTML 及其结果 (这有10秒的延迟),并查看webpagetest.org 的瀑布结果 。 这使用了Steve Souders的cuzillion.com的一些脚本来模仿缓慢的反应。 在瀑布中,对resource.cgi
的引用是CSS。 因此,在Internet Explorer中,第一个外部JS开始在请求CSS后立即加载(但CSS将需要10秒才能完成)。 但是第二个<script>
标签在CSS完成加载之前不会被执行:
<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>
获得jQuery之后,第二个外部JS的另一个testing 表明 ,第二个JS的下载不会在CSS加载之前启动。 在这里, resource.cgi
的第一个引用是CSS,第二个是JS:
在JS 下面移动样式表确实表明JS(包括ready
函数)运行得更早,但即使如此,jQuery应用的类(在JS运行时仍然是未知的)在Safari的快速testing中正确使用和Firefox。 但是,像$(this).height()
这样的东西在当时会产生错误的值。
然而, 额外的testing表明, 这是不是一个通用的规则,直到先前定义的CSS加载JS停止 。 似乎有一些使用外部JS和CSS的组合。 我不知道这是如何工作的。
最后说明:由于JS Bin在每个脚本中包含Google Analytics,因此在从裸露的URL(例如jsbin.com/aqeno)运行时, testing结果实际上是由JS Bin更改的 …似乎在编辑URL上的“输出”选项卡jsbin.com/aqeno/edit不包含额外的Google Analytics(分析)function,当然会得出不同的结果,但该url很难使用webpagetest.org进行testing。为了更好的理解, 这是一个好的开始,但是我还有很多问题需要解决……另外请注意Steve Souders的IE8并行脚本加载(Parallel Script Loading) ,使事情变得更加复杂(上面的瀑布是使用IE7创build的)。
也许应该简单地相信发行说明和文档…
CSS / JavaScript / JQuerysorting对我来说不起作用,但是下面是:
$(window).load(function() { $('#abc')...} );
当所有的DOM节点都可用时,DOM准备好了。 它与CSS无关。 尝试定位之前的样式或尝试加载它不同。
就我所知,ready事件是在DOM被加载的时候触发的 – 这意味着所有的阻塞请求(即JS)都被加载,并且DOM树被完全绘制。 IE中的就绪状态依赖于比大多数其他浏览器更慢的事件触发器(document.readyState更改vs DOMContentLoaded),所以时间依赖于浏览器。
非阻塞请求(如CSS和图像)的存在是完全asynchronous的,与就绪状态无关。 如果您处于需要这种资源的位置,则需要依靠良好的旧加载事件。
根据HTML5,DOMContentLoaded是一个简单的DOM就绪事件,没有考虑到样式表。 但是 ,HTML5parsingalgorithm要求浏览器推迟脚本的执行,直到加载所有以前的样式表为止。 ( DOMContentLoaded和样式表 )
在molily的testing中(2010) ,
- IE和Firefox阻止了所有后续的脚本执行,直到样式表加载
- Webkit只对外部脚本(
<script src>
)阻止后续执行 - Opera没有阻止任何脚本的后续执行
所有的现代浏览器现在都支持DOMContentLoaded (2017),所以他们现在可能已经规范了这种行为。