为什么使用CSSOM的insertRule后样式不可见,样式标签不能重新追加

Why are styles invisible, and style tags not re-appendable after using insertRule of CSSOM

如果我使用 insertRule 通过 CSSOM 添加样式,我注意到两件事。

在 Firebug 中查看时添加的样式不会出现在 html 中。

如果将样式标签附加(例如:从头部移动到主体)到另一个元素,添加的样式将不起作用(发生在 Firefox 中,并且 Chrome)。

如果在附加标签后添加样式,它们就可以工作。它们仍然没有显示在 Firebug 中。附加 sheet 时必须重新分配(重新获取?)这使得它看起来更加陌生。

Firebug 中没有显示这可能是 Firebug 的一个怪癖,但未动态添加的常规样式会显示。

对于追加后样式不起作用,我想知道这是否是标准,因为这发生在 Firefox 和 Chrome 中。查看标准,我没有看到任何关于此的信息。除非我不明白他们。

var style = document.createElement('style'),
    sheet = style.sheet;
document.head.appendChild(style);
//When line 6 is un-commented the styles work
//if line 8 is also commented out.
//document.querySelector('.container').appendChild(style);
//Get the sheet when line 6 is un-commented
sheet = style.sheet
sheet.insertRule('.test{color: red}');
document.querySelector('.container').appendChild(style);
//styles don't apply after the previous line

为清楚起见编辑:

如果您将 <style></style> 标签附加到 html 的 <head></head>,您可以使用 style.sheet.insertRule(styleString) 应用样式,添加的样式将应用于文档。

如果您已经将 <style></style> 附加到 <head></head>,如 <head><style></style></head>,并尝试将 <style></style> 附加到其他地方,如 <div><style></style></div> 所有样式已丢失,请勿再次申请。

这正常吗?

代码流程:

作品:

  1. 附加<style>任意位置
  2. 使用 style.sheet.insertRule(styleString)
  3. 添加样式

无效:

  1. 附加<style>任意位置
  2. style.sheet.insertRule(styleString) 的样式添加到 <style>
  3. 在其他地方附加相同的 <style>

我的另一个问题是添加到 <style></style> 的样式不会显示在 Firebug 中,即使它们已应用于文档。

编辑更清晰:

如果我在未修改样式的情况下重新附加 style 元素sheet,样式将保持不变:

var style = document.querySelector('style');
document.head.appendChild(style);
* {color: red}
<p>Hello world</p>

但是如果我用 JS 改变了样式sheet,改变就会被撤销:

var style = document.querySelector('style'),
    sheet = style.sheet;
sheet.insertRule('* {color: red}', 0);
document.head.appendChild(style); //Comment this line out, and this works.
/* CSS rules will be inserted with JS */
<p>Hello world</p>

这是因为 <style> 元素在附加到文档时只有 sheet 属性。
因此,当您移动它或将其从文档中删除时,它们的 sheet 属性 将设置回 null。您使用 insertRule 方法应用于它的每个规则都将消失,因为它们不在 <style>innerHTML.


the specs 的相关部分:

The update a style block algorithm for CSS (text/css) is as follows:

  1. Let element be the style element.

  2. If element has an associated CSS style sheet, remove the CSS style sheet in question.

  3. If element is not in a Document, then abort these steps.

  4. If the Should element's inline behavior be blocked by Content Security Policy [...] then abort these steps. [CSP]

  5. Create a CSS style sheet with the following properties: ...

如您所见,每次更新 <style> 元素时,都会创建一个新的 CSS 样式 sheet,(仅当 .3.4 没有阻塞进程)。


小演示:

var style = document.createElement('style');
console.log('before being appended : '+ style.sheet)
document.body.appendChild(style); 
console.log('after being appended : '+ style.sheet)
document.body.removeChild(style);
console.log('after being removed : '+ style.sheet)