繁体   English   中英

何时将样式表添加到document.styleSheets

[英]When is a stylesheet added to document.styleSheets

我试图动态地添加使用javascript CSS样式表规则,类似例子2 这里

它大部分时间都有效,但似乎有一种竞争条件,有时会导致(至少)Chrome(15.0.874和17.0.933)失败。 当缓存为空(或已被清除)时,它很少发生。

这就是我能够将其缩小到的范围。 首先,我通过将其附加到<head>来加载外部样式表,然后创建一个新的样式表(我将在其中添加规则)。 然后我打印document.styleSheets的长度(立即和1秒后)。

$(function() {
    // it doesn't happen if this line is missing.
    $("head").append('<link rel="stylesheet" type="text/css"'+
                     'href="/css/normalize.css" />');

    var stylesheet = document.createElement("style");
    stylesheet.setAttribute("type", "text/css");
    document.getElementsByTagName('head')[0].appendChild(stylesheet);

    var b = $('body');
    b.append(document.styleSheets.length).append('<br/>');
    setTimeout(function() {
        b.append(document.styleSheets.length).append('<br/>');
    }, 1000);
});

(在http://jsfiddle.net/amirshim/gAYzY/13/上播放)

当缓存清除时,它有时打印2然后4 (jsfiddle添加它自己的2个css文件),这意味着它不会立即将任何样式表添加到document.styleSheets ...但可能等待外部文件加载。

这是预期的吗?

如果是这样, MDN上的示例2 (以及其他许多其他内容)是否已损坏? 从第27行开始:

var s = document.styleSheets[document.styleSheets.length - 1];

可以使用document.styleSheets.length == 0进行评估

请注意,当我不首先加载外部CSS文件时,不会发生这种情况。

如果JavaScript位于CSS下面的页面中(它几乎总是如此),HTML解析器必须等待JS执行,直到JS和CSS完全加载和解析,因为JS可能会请求样式信息(Chrome只会在虽然脚本实际上这样做了)。 这有效地使得几乎在所有情况下加载外部CSS都是阻塞的。 当您稍后通过JavaScript插入它们或者页面中没有JS'(或者JS被加载非阻塞)时,CSS异步加载意味着它们被加载和解析而不会阻​​止DOM的解析。 因此,documents.stylesheets计数仅在工作表进入DOM之后才会更新,并且只有在完全加载和解析之后才会发生。

在这种情况下,可能会涉及一些时间差异。 考虑到大多数浏览器只有有限数量的管道来加载数据(有些只有两个像IE6,大多数有6个,有些甚至有12个像IE9),样式表的加载被添加到队列的末尾以便加载。 浏览器仍然在加载东西,因为你在DOMReady上调用了你的功能。 这导致样式表在一秒钟之后没有被完全加载和解析,因此不会影响document.stylesheets.length。

我在网上遇到的所有样式表示例都假定dom已完全解析并加载。 OffDOM样式表甚至不允许插入或检查规则,因为它们可以具有@import规则并且必须从外部加载,因此对于浏览器来说,很难确定何时可以安全地与工作表交互,除非它们'完全加载并解析。 OffDOM样式表会公开一个空的图纸属性,但在将图纸添加到DOM之前不会让您与它进行交互。

我总是发现最好动态插入样式表并执行该表中的所有更改并单独保留document.stylesheets。 这具有很大的优势,当您以相同的特异性覆盖样式时,由于插入错误的工作表,您不会遇到麻烦。 由于document.stylesheets是一个实时nodeList,因此每次调用该函数时,document.stylesheets [2]都可以指向另一个工作表(除非存储在var中)。 因此,我倾向于使用动态插入的工作表,只对该工作表进行操作。

这应该有所帮助:' 什么时候样式表真正加载 '

至于'例2'。 如果在调用addStylesheetRules()时加载样式表,它会破坏,当然这是在Chrome中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM