CSS和延期的JS执行顺序

时间:2018-02-24 20:05:15

标签: javascript css

例如,我在<head>中有一个具有此类结构的网页,我猜这很常见:

<link rel="stylesheet" href="styles.css"> // here goes big css bundle
<script defer src="main.js"></script> // relatively small javascript bundle with defer attribute

页面上有<span id="element"></span>

CSS包含#element { display: none; } JS包包含(在这里使用jquery):

$(document).ready(() => {
  console.log($('#element').css('display'));
});

结果会不时发生变化。有时JS比CSS更早执行,结果是'inline',有时候JS会执行,结果是'none',就像我想要的那样。

我希望我的JS包非阻塞,所以我使用deffered属性。我无法简单地将我的JS包放在页面的末尾,因为我使用了turbolinks并且doesn't allow me to do it

window:load也不是最好的选择,因为它不仅会在css中被解雇,而且会下载包括图像在内的所有资源。

所以我希望JS不会阻塞并在CSS之后执行以获得一致且可预测的结果。也许我能做些什么?

2 个答案:

答案 0 :(得分:1)

一个选项是为link元素添加一个load事件处理程序,然后将脚本插入到头部。由于脚本是动态添加的,it will automatically be async。因此,它将是非阻塞的并在加载CSS后执行。

<link id="stylesheet" rel="stylesheet" href="styles.css">

<script>
  var link = document.getElementById('stylesheet');

  link.addEventListener('load', function () {
    var script = document.createElement('script');
    script.src = 'main.js';
    document.head.appendChild(script);
  });
</script>

但是,这可能会导致您遇到问题。如果样式表被缓存,则它可能不会发出加载事件(因为它已经加载)。对于这样的情况,你可以try checking for link.sheet.cssRules

<link>元素上加载活动似乎historically be a troublesome issue,所以我不知道这会有多好。< / p>

Here is a CodePen通过检查link.sheet.cssRules来演示JS加载。它目前适用于Chrome,FireFox和Edge。

答案 1 :(得分:1)

我找到了另一个解决方案。您可以使用一些代码向<head>添加不带src属性的脚本,例如空<script>//</script>的空注释 就是这样。现在所有脚本,甚至是延迟的脚本,都会等待样式应用 我不确定它是如何工作的,但我认为延迟脚本在没有src的脚本之后排队,标准必须等待css应用。