$(document).ready() 也准备好 CSS 了吗?

IT技术 javascript jquery css
2021-02-01 01:34:07

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

  • 居中所需的时间明显滞后,并且块元素跳转到位。这可能只是与性能有关 - 因为页面大小通常很大,并且有相当数量的 javascript 正在执行。

  • 居中会完全搞砸,块元素要么向下推得太远,要么不够远。看起来好像它试图计算高度,但测量结果不正确。

是否有任何理由在 DOM-ready 上执行脚本不会将所有正确的 CSS 值注入到 DOM 中?(所有 CSS 都在<head>via a 中<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);

谢谢。

5个回答

1.3 发行说明

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

ready(fn) 文档中

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

请注意,以上内容甚至与实际渲染CSS无关,因此您可能仍然会在ready()启动时看到屏幕发生变化。但它应该可以避免出现问题。

其实我觉得有点奇怪,把CSS放在JS上面就可以解决所有问题。CSS 是异步加载的,因此 JS 加载可以在 CSS 仍在下载的同时开始和完成因此,如果以上是一个解决方案,那么执行任何 JS 代码都会暂停,直到所有较早的请求都完成?

我做了一些测试,确实,有时JS 会延迟到 CSS 加载完成。我不知道为什么,因为瀑布显示JS在CSS下载完成之前很久就已经完成加载。

见JS斌的一些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> 

带有单个外部 JS 脚本的瀑布

获取 jQuery 后使用第二个外部 JS 进行的另一个测试表明,在 CSS 加载之前,不会开始下载第二个 JS。在这里,第一个引用resource.cgi是 CSS,第二个是 JS:

带有两个外部 JS 脚本的瀑布

将样式表移到所有 JS下方确实表明 JS(包括ready函数)运行得更早,但即使如此,在 Safari 和火狐。但是这样的事情$(this).height()在那个时候会产生错误的值是有道理的

然而,额外的测试表明,在加载之前定义的 CSS 之前停止 JS 并不是通用规则使用外部 JS 和 CSS 似乎有一些组合。我不知道这是如何工作的。

最后说明:由于 JS Bin 在从裸 URL 运行时在每个脚本中包含 Google Analytics(如jsbin.com/aqeno测试结果实际上是由 JS Bin 更改的......似乎编辑 URL 上的输出选项卡如jsbin.com/aqeno/edit不包括额外的 Google Analytics 内容,并且肯定会产生不同的结果,但是该 URL 很难使用网页测试.org 进行测试。对Firefox 中的样式表阻止下载和 IE 中的 JavaScript 执行的参考strager是一个更好的理解的良好开端,但我还有很多问题……还要注意 Steve Souders 的IE8 Parallel Script Loading使事情变得更加复杂。(上面的瀑布是使用 IE7 创建的。)

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

@Bryan,我认为你的问题,尤其是IE8 Parallel Script Loading,会让我在接下来的几周睡得更糟......允许使用提供的 CSS),这确实表明在 JavaScript之后$(this).height();加载 CSS 时可能会产生零,但之前加载时似乎没问题但是,不知道为什么,恐怕每个浏览器的行为可能不同:jsbin.com/ofola/edit
2021-03-15 01:34:07
Cuzillion ( stevesouders.com/cuzillion ) 应该可以帮助您了解不同类型的对象是如何在不同浏览器中加载的。
2021-03-23 01:34:07
......但这仍然不是最终的答案如果事情在<head><body>? 考虑到Firefox 中样式表阻止下载和 IE 中的 JavaScript 执行(那么,其他浏览器呢?)和IE8 并行脚本加载,我想这个垂直对齐脚本可能会出现很多问题。顺便说一句:后者在 IE8 中的瀑布流在pagestest.org/result/090825_24AP上没有显示并行加载,看起来像在pagestest.org/result/090825_24AQ 上的IE7
2021-03-23 01:34:07
浏览器下载异步样式表,但阻止脚本低于他们从执行,直到样式表已加载。他们猜测作者会希望在后续脚本中查询样式信息,因此他们必须阻止执行以保证样式可用。
2021-03-30 01:34:07
@sam 它实际上会阻塞直到元素被渲染,所以 js 可以查询值,而不仅仅是在样式表加载之前。这称为布局垃圾,它是性能问题的常见来源。
2021-04-09 01:34:07

CSS/JavaScript/JQuery 排序对我不起作用,但以下内容适用:

$(window).load(function() { $('#abc')...} );
我测试过,在 Opera 和 Chrome 中加载外部样式表时,css/js 重新排序并没有为我修复它。
2021-03-21 01:34:07
同样在这里。我在 IE9 中遇到了在样式呈现之前运行 js 的问题,但是用这个替换 $(document).ready 解决了我的问题。奇怪的。不管怎么说,还是要谢谢你 :)
2021-03-22 01:34:07
甚至 jquery 写道:“虽然 JavaScript 提供了用于在呈现页面时执行代码的加载事件,但在完全接收所有资产(例如图像)之前不会触发此事件。” api.jquery.com/ready所以我也会尝试使用这个来解决
2021-03-28 01:34:07
这是核选项。负载事件经常发生的方式不是以后DOM就绪-只考虑重形象资产的影响,Facebook的内部框架等。如果一个脚本被延迟,直到加载事件后,可能直到其执行需要多少秒。
2021-04-01 01:34:07

当所有 DOM 节点都可用时,DOM 就绪会触发。它与 CSS 无关。尝试在之前定位样式或尝试以不同的方式加载它。

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

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

上面的链接已成为令人困惑的方式,说明 iframe 脚本可能会被父项中的样式表阻止。我误会了吗?严重地!
2021-03-14 01:34:07
我不是对你投反对票的人,但你可能想看看这个:stevesouders.com/cuzillion/...
2021-03-15 01:34:07
在今天做一些测试时,我了解到以某种方式下载 CSS 可能会阻塞(用于执行一些 next<script>标签,而不是用于触发ready函数本身)。但是,如果这是拒绝投票的原因,那么我也很想看到一些解释。会让我免于做一些测试......
2021-03-21 01:34:07
CSS 下载是非阻塞的,但它们可以阻塞后续脚本的执行
2021-04-13 01:34:07

根据 HTML5,DOMContentLoaded 是一个简单的 DOM 就绪事件,不考虑样式表。但是,HTML5 解析算法要求浏览器推迟脚本的执行,直到加载了所有先前的样式表。DOMContentLoaded 和样式表

莫莉的测试 (2010) 中

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

所有现代浏览器现在都支持 DOMContentLoaded (2017),所以他们现在可能已经标准化了这种行为。