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

Javascript 何时将样式表添加到document.styleSheets,javascript,jquery,css,google-chrome,stylesheet,Javascript,Jquery,Css,Google Chrome,Stylesheet,我试图使用javascript动态添加css样式表规则,类似于示例2 它在大多数情况下都能工作,但似乎存在一种竞争条件,使得它在(至少)Chrome(15.0.874和17.0.933)中有时会失败。当缓存为空(或已清除)时,这种情况很少发生 这是我能把范围缩小到的。首先,我通过将外部样式表附加到来加载它,然后创建一个新的样式表(在这里我将添加规则)。然后我打印document.styleSheets的长度(立即和1秒后) 可能使用document.styleSheets.length==0进

我试图使用javascript动态添加css样式表规则,类似于示例2

它在大多数情况下都能工作,但似乎存在一种竞争条件,使得它在(至少)Chrome(15.0.874和17.0.933)中有时会失败。当缓存为空(或已清除)时,这种情况很少发生

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

可能使用
document.styleSheets.length==0进行计算

请注意,如果不先加载外部CSS文件,则不会发生这种情况。

这应该会有所帮助:“”


例如“例2”。当你调用addStylesheetRules()时,如果加载了样式表,它就会中断,当然这是在Chrome中。

如果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

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

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

我想问一下,您期望的最终结果是什么。在什么情况下,您希望将规则“注入”到css文件中,而不是首先将其写入css文件中?我也在动态添加样式表……但仅在$(文档)之后才添加.ready已启动…@Kees:我提供的代码正在
$(文档)中完成所有工作。ready
。这就是
$(function(){…});
所做的。@Sotkra我们有一个开发人员工作流(不一定合理),在这个工作流中,只修改您正在处理的JS文件比修改JS和(共享)文件更容易CSS文件,因此我提供了一个函数
addRule(…)
,允许开发人员为js文件生成的页面动态添加规则。通常它们会在以后合并到CSS文件中。另一个原因是动态样式更改;请看一看,示例2并不总是有效。例如,如果我(或另一个js库)在调用
addStylesheetRules()
之前,只添加了一个外部样式表。
$(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);
});
var s = document.styleSheets[document.styleSheets.length - 1];