检索或更改伪元素的css规则

8

编辑 2015-10-07 1624 CST

该问题已被标记为可能重复 - 我发布它的原因是其他问题的答案没有提供我想要的所有信息,并且我想要一种简单直接的方法来实现它。我可以控制样式表和规则的顺序,以便引用正确的规则。我还想得到有关此方法在将来是否会出现问题的反馈。

请查看我下面发布的评论,了解我为什么不接受可能重复问题的答案的其他原因。

** 原始问题如下 **

我搜索了类似于这样的问题,并找到了一些涉及部分问题但没有回答如何检索和更改像::before::after这样的伪元素的CSS值的问题。

我在来这里之前用谷歌搜索过网络,基本上我发现没有理想的方法来做到这一点。

我找到了一种方法,在FF 40、IE 9和Chrome 45.0.2454.101 m中都有效,但我想知道是否忽略了某些可能导致我的方法在某些情况下出现问题的东西。

我在这里和其他网站上看到的有关访问或更改伪元素的CSS值的答案说,您不能直接访问这些项目,因为它们不是“DOM的一部分”且“DOM的外面”。

他们说,改变它们的唯一方法就是创建一个新规则,并将其附加到现有规则以覆盖编码值。

下面是演示该方法的代码片段:

function changeColor () { // Flip psedo element's background color
 var newColor,
  currentColor;
 
    // Get the current color
 currentColor= document.styleSheets[0].cssRules[0].style.backgroundColor;  
 
    // flip the color
 newColor = (currentColor== "red") ? "aqua" : "red";         
 
     // Change the color
    document.styleSheets[0].cssRules[0].style.backgroundColor = newColor;     
    
    // put color in top message
    document.getElementById("colorIs").innerHTML = newColor;
  
    // display colors  
 document.getElementById("displayColors").innerHTML = 
   "Pevious color was " + currentColor + 
            ", changed to " + newColor + ".";  
            
    // Change background of button (not needed but thought I'd throw it in)
    document.getElementById("changeButton").style.backgroundColor = newColor;                      
}
#testDiv::before {
      background-color: aqua;
   content: "psedo element ";
  }

#changeButton {
 background-color: aqua;
}
<div id="testDiv">
  This divsion has an pseudo ::before element whose background color is
  <span id="colorIs">
  aqua
 </span>
  <br>
  <br> Click "Display and Flip Color" to display the colors
  <br> and flip the color from aqua and red and vice versa.
</div>
<br>
<form method="post">
  <input id="changeButton" name="change" type="button" value="Display and Flip Color" onclick="changeColor();">
</form>
<br>
<div id="displayColors">
</div>

我意识到这取决于我知道样式表及其规则的顺序,但我可以控制它。
这似乎与我看到的答案相矛盾,那些答案说伪元素的CSS项目不属于DOM的一部分,因此无法访问。
这种方法是否可能是由于浏览器或DOM更改而出现在我阅读的答案之后?
这种方法未来可能会出现什么问题?
不同版本的各种浏览器的用户是否可以尝试片段并告诉我它是否有效?
鲍勃
编辑2015-10-08 1352 CST
我修改了访问伪元素样式的方法,以便能够直接引用相关样式表,无论定义的顺序如何。
我要更改代码片段,但我不知道如何给CSS“样式表”赋予ID。
相反,我将告诉您如何修改它。
1) 分离定义使用的元素的CSS,并将其放入单独的文件中。
2) 在引用CSS文件的<link标签上编写id =。在这种情况下,我将使用id =“colorFlipFlop”
3) 将JavaScript更改为从这个引用或更改样式:
currentColor = document.styleSheets[0].cssRules[0].style.backgroundColor;

document.styleSheets[0].cssRules[0].style.backgroundColor = newColor;

致:

var beforeIndex = 0; // give a name to the index, in cssRules, of the rule we want to get and change.

var styleSheetObject = document.getElementById("colorFlipFlop"); // get a reference to the stylesheet object

currentColor = styleSheetObject.sheet.cssRules[beforeIndex].style.backgroundColor;   // get current pseudo element background color

styleSheetObject.sheet.cssRules[beforeIndex].style.backgroundColor = newColor; // set new background color

我会在CSS和Javascript中完整记录所有这些内容,如果我认为有必要的话,在HTML中也会加注释,用尽可能多的注释来解释我正在做什么,如何做,以及为什么我要这样做。我称其为评论的WHW(谁、何、为什么)。我认为这使功能更易管理且更加牢固。
现在,您不再需要知道样式表对象的索引,因为每个元素都被清晰地分离出来,而且它仍然提供了一种直接访问和更改伪元素样式的方法,而无需创建和附加新规则。
在发布此编辑之前,我将制作一个包含CSS、JavaScript和HTML的文件,以实现代码段所做的事情并展示新的方法。我会将所有内容放在一个文件中,以便更容易地创建和FTP到网站。在真实的代码中,我会使用单独的CSS、JavaScript和HTML文件。
您可以在http://thetesting.site/flipFlopColor.html找到它。
那么,你觉得怎么样?

另一种简单的方法是添加一个样式标签,并将文本设置为正确的 CSS 规则。 - charlietfl
我认为这是一个非常好的问题,特别是对于新手来说,经过了深入的研究。值得点赞。虽然预先定义CSS并简单地向父元素添加类可能更容易。这也很可能是charlietfl试图传达的信息。这里有一个小例子:http://tinyurl.com/pr6sud8。 - Shikkediel
我忘记了补充一点 - 如果保持样式表作为第一个并且我想要的规则作为表中的第一个规则变得太困难,我将退而求其次,通过循环遍历样式表,然后再循环遍历cssRules来找到我需要的规则。我已经开始在<style>和<link>标签上放置id =以帮助识别正确的标签,如果我发现必须搜索它们。 - SimonT
你为什么想要这样做?高级用例是什么?对于混淆样式表来解决问题,这是极其罕见的。几乎总有更简洁的方法。 - user663031
显示剩余6条评论
1个回答

2

通过操作 CSSRule 而不是 DOM 元素,是一种晦涩但完全有效(并且已经标准化)的更改元素样式的方式。这很晦涩,因为它很难,需要嵌套循环遍历所有样式表中的所有规则,以找到要更改的规则。而且这也很晦涩,因为它并不是非常有价值 - 通常可以通过访问 DOM 元素的 style 属性来实现相同的效果。

但是,在伪元素中,没有 DOM 元素。伪元素是样式规则的产物,因此操纵伪元素的唯一方法是通过样式规则。人们建议添加样式规则,因为这比查找样式规则并进行编辑更容易。但是查找和编辑它是完全有效的。

您可以通过添加样式规则一次,并保留对该规则的引用并对其进行后续编辑,从而兼顾两全。


我同意,找到你想要更改的规则可能会复杂化事情。如果你忘记了并在样式表中添加了一个规则,而这个规则本应该出现在你预期的特定位置上,或者放置了另一个样式表在你要针对的样式表之前,那么这个方案就会失败。但是,我非常喜欢我的方法,不是因为我自己设计的,而是因为它看起来非常直观。我正在探索是否有一种方式可以以某种方式记录下我想要更改的规则的索引值,最好是在样式表本身中。我将更新我的问题或发布关于我的发现的其他评论。 - SimonT
@SimonT - 就我个人而言,我非常喜欢你的方法,并且过去已经推荐过它。但是,请注意不要通过硬编码索引来定位规则。在此评论线程中,与我使用不同操作系统的用户其样式表或规则的索引与我预期的不同。最好依靠找到规则一次(或动态创建规则),然后保留对该规则的引用,而不是硬编码预期的索引。 - gilly3
看一下我问题底部的编辑。我发现了一种引用正确样式表的方法,而不需要知道它定义的顺序,因此也就不需要知道它在样式表对象中的索引。请告诉我你对修改后的方法有何看法。 - SimonT
@Shikkediel,这正是我所做的,阅读我在问题底部的编辑。 - SimonT
确实,我漏了那个。看起来是一个不错的方法。 - Shikkediel
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接