getComputedStyle:等待外部样式表?

时间:2015-04-17 22:40:29

标签: javascript css html5

假设您有一个外部样式表(<link>),后跟<script>。外部样式表是否始终在<script>执行之前应用,以便getComputedStyle始终遵守外部样式表的规则?

或者是否允许浏览器在应用早期样式表之前运行JavaScript?

示例:

<!doctype html>
<html>
  <head>
    <link href="/my-stylesheet.css" rel="stylesheet" />
  </head>
  <body>
    <div id="foo"></div>
    <script>
      window.getComputedStyle(document.getElementById('foo')).width
      // => "200px" due to stylesheet - is this reliable?
    </script>
  </body>
</html>

2 个答案:

答案 0 :(得分:4)

简而言之:是的,这是可靠的。

为了证明我基于nodejs创建了以下testserver:

目录:

/testserver.js
/server/index.js
/server/style.js

testserver.js创建一个节点js服务器并确保每个请求都需要两秒钟才能加载:

var express = require('express');
var app = express();
app.listen(8888);
app.use(function(req,res,next){
    setTimeout(next, 2000);
});
app.use(express.static('./server'));

我的index.html

<html>
<head>
    <link href="style.css" rel="stylesheet" />
</head>
<body>
    <div id="mydiv"></div>
<script>
console.log(window.getComputedStyle(document.getElementById('mydiv')).width);
</script>
</body>
</html>

我的style.css

#mydiv {
    position: absolute;
    background: #ff0000;
    height: 10px;
    width: 100px;
}

现在我通过启动我的服务器并调用http://localhost:8888/index.html

来测试它

在Chrome开发者工具中,时间轴如下所示: Timeline

正如您所见,index.html

之前加载了style.css文件

Javascript控制台按预期输出100pxConsole

由于事实,js-console中没有错误,唯一的输出是预期的100px我证明了这个问题的采用是真的。

编辑:现在我测试了更多: 这适用于Chrome,2s,5s和60s =&gt;作品! 此外,我在Firefox,Opera和Safari上用2s测试了它。 =&GT;作品!

抱歉,我没有IE浏览器。

编辑2:我刚做了更多研究:

我想出的行为是由W3C定义的。加载样式文件在link - 标记或style - 标记:

定义时阻止脚本执行
  

HTML解析器或XML的Document上下文中的样式表   解析器被认为是一个样式表,如果阻止脚本   元素是由Document的解析器创建的,元素是   要么是样式元素,要么是作为外部资源的链接元素   在元素时有助于样式处理模型的链接   由解析器创建,并启用了元素的样式表   当元素由解析器创建时,以及元素的样式   表格就绪标志尚未设置,并且,最后一次事件循环   到达步骤1,元素在该Document和用户代理中   还没有放弃那个特定的样式表。用户代理可以   随时放弃样式表。

     

注意:    如果是样式,在样式表加载之前放弃样式表    工作表最终仍然加载,意味着脚本可能会结束    操作信息不正确。例如,如果是样式表    将元素的颜色设置为绿色,但是检查元素的脚本    生成的样式在加载工作表之前执行,即脚本    会发现元素是黑色的(或任何默认颜色    因此,可能会做出糟糕的选择(例如决定使用黑色作为    页面上其他地方的颜色,而不是绿色)。实施者有    平衡脚本使用不正确信息的可能性    等待缓慢时无所事事的性能影响    网络要求完成。

W3C Blocking Scripts

正如this文档中所定义的那样,在解析过程中,在加载阻塞样式之前,脚本不会执行。

答案 1 :(得分:3)

如果你想确保加载了一个外部样式表,那么你可以使用窗口load事件,当外部样式表和图像等页面资源加载完毕并且页面也将有最后一个时,它会触发布局:

window.addEventListener('load', function() {
    window.getComputedStyle(document.getElementById('foo')).width
});

您还可以通过在样式表中放置适用于特定DOM元素(甚至可以隐藏)的特定且唯一的样式规则来设计测试以查看样式表是否已经加载,然后您可以获得该样式使用getComputedStyle()并查看它是否与应有的匹配。如果是,则加载样式表。如果没有,则尚未加载样式表。但是,如果你仍然需要等到它被加载,那么窗口load事件就是你想要使用的。