【问题标题】:Why are styles invisible, and style tags not re-appendable after using insertRule of CSSOM为什么样式不可见,并且样式标签在使用 CSSOM 的 insertRule 后无法重新附加
【发布时间】:2016-08-06 21:23:15
【问题描述】:

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

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

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

如果样式是在附加标签之后添加的,那么它们就可以工作。他们仍然没有显示在 Firebug 中。附加工作表时必须重新分配(重新获得?),这使它显得更加陌生。

对于不显示在 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)添加样式

不起作用:

  1. 在任何地方追加<style>
  2. 将带有style.sheet.insertRule(styleString) 的样式添加到<style>
  3. 在其他地方追加相同的<style>

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

编辑更清晰:

如果我在未修改样式表的情况下重新附加 style 元素,则样式将保留:

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

但如果我用 JS 更改了样式表,更改将被撤消:

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>

【问题讨论】:

  • 不确定问题是什么?
  • 主要是在追加样式标签后样式不适用,该样式标签已经使用 insertRule normal 添加了样式?
  • 如果正确解释问题,这将类似于div{color:green};div{color:blue} bluecolor 设置为div,因为它是最后一个声明。见stackoverflow.com/questions/1043001/…
  • 这似乎不是问题所在。如果我手动将嵌入的 <style> 添加到 html 中,然后使用 appendChild 移动它,那么该标签中的手写样式就会应用。
  • “如果我将嵌入的 是的。 html 元素处的 style 属性的特异性应优先考虑。您是否阅读了链接问题的所有答案?另请参阅stackoverflow.com/questions/2809024/points-in-css-specificityw3.org/TR/CSS2/cascade.html#specificity

标签: javascript html css cssom


【解决方案1】:

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


the specs的相关部分:

CSS (text/css) 的 更新 style 算法如下:

  1. 设元素为样式元素。

  2. 如果元素具有关联的 CSS 样式表,请删除有问题的 CSS 样式表。

  3. 如果元素不在文档中,则中止这些步骤。

  4. 如果 Should 元素的内联行为被 Content Security Policy [...] 阻止,则中止这些步骤。 [CSP]

  5. 创建具有以下属性的 CSS 样式表:...

如您所见,每次更新 <style> 元素时,都会创建一个新的 CSS 样式表,(仅当 .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)

【讨论】:

  • 谢谢。我仍然不明白是什么让手写文本内容的样式与 insertRule 添加的样式有所不同。或者我应该问为什么?对于一种方法而不是另一种方法丢弃工作表似乎没有任何目的。
  • 因为insertRuleCSSStyleSheet 对象的方法,并且不直接与<style> 元素链接。当您删除样式元素时,CSSStyleSheet 将被删除,当您将 <style> 插入回来时,您将获得一个新的、新鲜的元素。但是由于insertRule 只作用于CSSStyleSheet 而不是<style> 本身,因此您会丢失插入的所有规则。如果您想保留这些,可以使用innerHTML 属性。
  • 这仍然没有意义。那好吧。我确定这是有原因的,但我不明白。我可以看到它是如何工作的。我还是不明白为什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
相关资源
最近更新 更多