CSS和延期的JS执行顺序

问题描述 投票:2回答:2

例如,我在<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更早执行,结果是'内联',有时JS稍后执行,结果是'none',就像我想要的那样。

我希望我的JS包是非阻塞的,所以我使用deferred属性。我无法简单地将我的JS包放在页面的末尾,因为我使用turbolinks和qazxsw poi。

doesn't allow me to do it也不是最佳选择,因为它不仅会在css下被解雇,而且所有资源都将被下载,包括图像。

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

javascript css
2个回答
1
投票

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

it will automatically be async

但是,这可能会导致您遇到问题。如果样式表被缓存,则它可能不会发出加载事件(因为它已经加载)。对于这样的情况,你可以<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通过检查Here is a CodePen展示JS装载。它目前适用于Chrome,FireFox和Edge。


1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.