javascript-$(document).ready()是否也可以使用CSS?

我已经在$(document).ready()上执行了一个脚本,该脚本应该在布局中垂直对齐块元素。 90%的时间,它可以正常工作。 但是,对于这额外的10%,发生以下两种情况之一:

  • 进行居中的时间明显滞后,并且块元素跳入位置。 这可能与性能有关-页面的尺寸通常很大,并且有大量的JavaScript可以一次执行。

  • 居中将完全弄乱,并且图块元素将被向下推得太远或不够。 似乎是试图计算高度,但测量结果不正确。

是否有任何理由为什么不能在DOM就绪状态下执行脚本就将所有正确的CSS值注入DOM中呢? (所有CSS都通过<link><head>中)。

另外,这是引起问题的脚本(是的,直接从此处获取):

 (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);

谢谢。

Bryan M. asked 2020-02-13T23:05:43Z
5个解决方案
63 votes

从1.3发行说明中:

ready()方法不再尝试对等待所有样式表加载提供任何保证。 而是应在页面上的脚本之前包含所有CSS文件。 更多信息

从ready(fn)文档中:

注意:请确保所有样式表都包含在脚本之前(尤其是那些调用ready函数的样式表)。 这样做将确保在开始执行jQuery代码之前正确定义所有元素属性。 否则,将导致零星的问题,尤其是在基于WebKit的浏览器(例如Safari)上。

请注意,以上内容甚至与实际渲染CSS无关,因此当您插入ready时,仍可能会看到屏幕变化。但这应该可以避免出现问题。

实际上,我发现将CSS放在JS之上可以解决所有问题,这有点奇怪。 CSS是异步加载的,因此可以在CSS仍在下载时开始和完成JS加载。 因此,如果以上是解决方案,那么将暂停执行任何JS代码,直到所有较早的请求完成为止?

我做了一些测试,实际上,有时JS会延迟到CSS加载完成为止。 我不知道为什么,因为瀑布表明JS在下载CSS之前就已经完成了加载。

有关一些HTML及其结果(请延迟10秒),请参见JS Bin;有关瀑布结果,请参见webpagetest.org。 它使用来自Steve Souders的cuzillion.com的一些脚本来模仿缓慢的响应。 在瀑布中,对ready的引用是CSS。 因此,在Internet Explorer中,在请求CSS之后,第一个外部JS就开始加载(但是CSS将需要另外10秒钟才能完成)。 但是第二个$(this).height()标记也要等到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> 

Waterfall with a single external JS script

在获取jQuery之后,使用第二个外部JS进行的另一项测试显示,只有在CSS加载后,才开始下载第二个JS。 在这里,第一个引用ready是CSS,第二个是JS:

Waterfall with two external JS scripts

将样式表移至所有JS之下确实表明JS(包括ready函数)运行的时间要早得多,但即使如此,jQuery应用类(当JS运行时仍不知道)在我的Safari快速测试中正确使用了 和Firefox。 但是,像$(this).height()这样的事情在那时会产生错误的值,这是有道理的。

但是,其他测试表明,在加载之前定义的CSS之前,停止JS并不是通用规则。 使用外部JS和CSS似乎有些组合。 我不知道这是怎么回事。

最后说明:由于JS Bin从裸URL(例如jsbin.com/aqeno)运行时,每个脚本中都包含Google Analytics(分析),因此JS Bin实际上更改了测试结果。似乎编辑URL上的Output选项卡例如 jsbin.com/aqeno/edit不包含其他Google Analytics(分析)内容,并且肯定会产生不同的结果,但是该URL很难使用webpagetest.org进行测试。 strager是更好理解的一个良好开始,但是我还有很多问题...还请注意Steve Souders的IE8并行脚本加载使事情变得更加复杂(上面的瀑布是使用IE7创建的。)

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

Arjan answered 2020-02-13T23:06:49Z
15 votes

CSS / JavaScript / JQuery排序不适用于我,但以下内容可以:

$(window).load(function() { $('#abc')...} );
Martin Dvorak answered 2020-02-13T23:07:09Z
6 votes

当所有DOM节点均可用时,将触发DOM ready。 它与CSS无关。 尝试先放置样式,或尝试以其他方式加载。

fphilipe answered 2020-02-13T23:07:29Z
4 votes

据我所知,当加载DOM时会触发ready事件-这意味着所有阻止请求(即JS)均已加载,并且DOM树已完全绘制。 与大多数其他浏览器相比,IE中的就绪状态依赖于较慢的事件触发器(document.readyState更改与DOMContentLoaded),因此计时也取决于浏览器。

非阻塞请求(例如CSS和图像)的存在是完全异步的,并且与就绪状态无关。 如果您处于需要此类资源的位置,则需要依靠良好的旧onload事件。

annakata answered 2020-02-13T23:07:55Z
4 votes

根据HTML5,DOMContentLoaded是一个普通的DOM ready事件,没有考虑样式表。 但是,HTML5解析算法要求浏览器将脚本的执行推迟到加载所有以前的样式表之前。 (DOMContentLoaded和样式表)

在莫利(2010)的测试中,

  • IE和Firefox阻止所有后续脚本执行,直到加载样式表
  • Webkit仅对外部脚本阻止了后续执行(<script src>
  • Opera没有阻止任何脚本的后续执行

现在,所有现代浏览器都支持DOMContentLoaded(2017),因此它们现在可能已经对此行为进行了标准化。

sam answered 2020-02-13T23:08:37Z
translate from https://stackoverflow.com:/questions/1324568/is-document-ready-also-css-ready