关于javascript:选择和操作CSS伪元素,例如:: before和::之后使用jQuery

Selecting and manipulating CSS pseudo-elements such as ::before and ::after using jQuery

有没有任何方式来选择/操控CSS伪元素(如::before::after和旧版有一个半结肠)使用jQuery?

例如,我的样式表有以下规则:

1
.span::after{ content:'foo' }

Mi-24变更"foo""酒吧使用jQuery?


您还可以将内容传递给具有数据属性的伪元素,然后使用jquery来操作:

在HTML中:

1
<span>foo</span>

在jQuery中:

1
2
3
$('span').hover(function(){
    $(this).attr('data-content','bar');
});

在CSS中:

1
2
3
span:after {
    content: attr(data-content) ' any other text you may want';
}

如果要防止"其他文本"出现,可以将其与Seucolega的解决方案结合起来,如下所示:

在HTML中:

1
<span>foo</span>

在jQuery中:

1
2
3
$('span').hover(function(){
    $(this).addClass('change').attr('data-content','bar');
});

在CSS中:

1
2
3
span.change:after {
    content: attr(data-content) ' any other text you may want';
}


您可能会认为这是一个简单的问题要回答,jquery可以做的其他一切。不幸的是,问题归结为一个技术问题:css:after和:before规则不属于DOM,因此不能使用jquery的DOM方法更改规则。

有一些方法可以使用javascript和/或css解决方案来操作这些元素;您使用哪种解决方案取决于您的确切需求。

我将从广泛认为的"最佳"方法开始:

1)添加/删除预定类别

在这种方法中,您已经使用不同的:after:before样式在CSS中创建了一个类。稍后将这个"新"类放在样式表中,以确保它重写:

1
2
3
4
5
6
p:before {
    content:"foo";
}
p.special:before {
    content:"bar";
}

然后您可以使用jquery(或普通的javascript)轻松地添加或删除这个类:

1
2
3
$('p').on('click', function() {
    $(this).toggleClass('special');
});

1
2
3
    $('p').on('click', function() {
      $(this).toggleClass('special');
    });
1
2
3
4
5
6
7
8
p:before {
  content:"foo";
  color: red;
  cursor: pointer;
}
p.special:before {
  content:"bar";
}
1
2
3
4
5
6
7
8
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">

<p>
This is a paragraph.
</p>
<p>
This is another paragraph.
</p>

  • 优点:易于使用jquery实现;一次快速改变多种样式;强制分离关注点(将CSS和JS与HTML隔离)
  • 缺点:CSS必须预先编写,所以:before:after的内容不是完全动态的

2)直接在文档样式表中添加新样式

可以使用javascript直接向文档样式表添加样式,包括:after:before样式。jQuery没有提供方便的快捷方式,但幸运的是,JS没有那么复杂:

1
2
var str ="bar";
document.styleSheets[0].addRule('p.special:before','content:"'+str+'";');

1
2
var str ="bar";
document.styleSheets[0].addRule('p.special:before', 'content:"' + str + '";');
1
2
3
4
p:before {
  content:"foo";
  color: red;
}
1
2
3
4
5
6
7
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">

<p class="special">This is a paragraph
</p>
<p>
This is another paragraph
</p>

目前,.addRule()和相关的.insertRule()方法得到了很好的支持。

作为一种变体,您也可以使用jquery向文档中添加一个全新的样式表,但所需的代码并不干净:

1
2
var str ="bar";
$('<style>p.special:before{content:"'+str+'"}</style>').appendTo('head');

1
2
var str ="bar";
$('<style>p.special:before{content:"' + str + '"}</style>').appendTo('head');
1
2
3
4
p:before {
  content:"foo";
  color: red;
}
1
2
3
4
5
6
7
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">

<p class="special">This is a paragraph
</p>
<p>
This is another paragraph
</p>

如果我们谈论的是"操纵"这些值,而不仅仅是添加这些值,我们还可以使用不同的方法读取现有的:after:before样式:

1
2
var str = window.getComputedStyle(document.querySelector('p'), ':before')
           .getPropertyValue('content');

1
2
3
4
var str = window.getComputedStyle($('p')[0], ':before').getPropertyValue('content');
console.log(str);

document.styleSheets[0].addRule('p.special:before', 'content:"' + str+str + '";');
1
2
3
4
p:before {
    content:"foo";
    color: red;
}
1
2
3
4
5
6
7
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">

<p class="special">This is a paragraph
</p>
<p>
This is another paragraph
</p>

在使用jquery时,我们可以用$('p')[0]替换document.querySelector('p'),代码稍微短一些。

  • 优点:任何字符串都可以动态插入样式
  • 缺点:原始样式没有改变,只是被重写;重复使用(ab)可以使dom任意增大

3)更改不同的dom属性

也可以在CSS中使用attr()来读取特定的dom属性。(如果浏览器支持:before,它也支持attr())在一些精心准备的css中,通过将其与content:结合使用,我们可以动态更改:before:after的内容(但不能更改其他属性,如边距或颜色):

1
2
3
4
5
p:before {
    content: attr(data-before);
    color: red;
    cursor: pointer;
}

JS:

1
2
3
$('p').on('click', function () {
    $(this).attr('data-before','bar');
});

1
2
3
$('p').on('click', function () {
    $(this).attr('data-before','bar');
});
1
2
3
4
5
p:before {
    content: attr(data-before);
    color: red;
    cursor: pointer;
}
1
2
3
4
5
6
7
8
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">

<p>
This is a paragraph.
</p>
<p>
This is another paragraph.
</p>

如果不能提前准备好CSS,可以将其与第二种技术结合起来:

1
2
3
4
5
6
7
var str ="bar";

document.styleSheets[0].addRule('p:before', 'content: attr(data-before);');

$('p').on('click', function () {
    $(this).attr('data-before', str);
});

1
2
3
4
5
6
var str ="bar";
document.styleSheets[0].addRule('p:before', 'content: attr(data-before) !important;');

$('p').on('click', function() {
  $(this).attr('data-before', str);
});
1
2
3
4
5
p:before {
  content:"foo";
  color: red;
  cursor: pointer;
}
1
2
3
4
5
6
7
8
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">

<p>
This is a paragraph.
</p>
<p>
This is another paragraph.
</p>

  • 优点:不会创造无限的额外风格
  • 缺点:CSS中的attr只能应用于内容字符串,不能应用于URL或RGB颜色。


尽管浏览器通过CSS呈现这些元素,就好像它们与其他真实的DOM元素一样,但伪元素本身并不属于DOM,因为顾名思义,伪元素不是真实的元素,因此不能直接使用jquery(或任何与此相关的javascript API,甚至不能使用selec)来选择和操作它们。Tor API)。这适用于您试图用脚本修改其样式的任何伪元素,而不仅仅是::before::after

您只能在运行时通过cssom(想想window.getComputedStyle())直接访问伪元素样式,而jquery在.css()之外没有公开它,这也是一种不支持伪元素的方法。

但是,您总是可以找到其他方法,例如:

  • 将样式应用于一个或多个任意类的伪元素,然后在类之间切换(参见Seucolega的快速示例答案)-这是惯用的方法,因为它使用简单的选择器(伪元素不是)来区分元素和元素状态,以及它们的使用方式。

  • 通过修改文档样式表来操纵应用于所述伪元素的样式,这更像是一种黑客行为。


不能在jquery中选择伪元素,因为它们不是dom的一部分。但是您可以向父元素添加一个特定的类,并在CSS中控制它的伪元素。

例子

在jQuery中:

1
2
<script type="text/javascript">
    $('span').addClass('change');

在CSS中:

1
span.change:after { content: 'bar' }


按照克里斯蒂安的建议,你也可以:

1
$('head').append("<style>.span::after{ content:'bar' }</style>");


我们也可以依赖自定义属性(也就是CSS变量)来操作伪元素。我们可以在说明书中看到:

Custom properties are ordinary properties, so they can be declared on
any element, are resolved with the normal inheritance and cascade
rules, can be made conditional with @media and other conditional rules, can be used in HTML’s style attribute, can be read or set using the CSSOM, etc.

考虑到这一点,我们的想法是在元素中定义自定义属性,而伪元素将简单地继承它;因此我们可以很容易地修改它。

请注意,CSS变量可能不适用于您认为相关的所有浏览器(例如,IE 11):https://canius.com/feat=css变量

1)使用内联样式:

1
2
3
4
5
.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}
1
 

2)使用CSS和类

1
2
3
4
5
6
7
8
9
10
11
12
13
.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}

.blue {
  --color:blue;
  --content:'I am a blue element';
}
.black {
  --color:black;
}
1
 

3)使用javascript

1
2
document.querySelectorAll('.box')[0].style.setProperty("--color","blue");
document.querySelectorAll('.box')[1].style.setProperty("--content","'I am another element'");
1
2
3
4
5
.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}
1
 

4)使用jQuery

1
2
3
4
5
6
$('.box').eq(0).css("--color","blue");
/* the css() function with custom properties works only with a jQuery vesion >= 3.x
   with older version we can use style attribute to set the value. Simply pay
   attention if you already have inline style defined!
*/

$('.box').eq(1).attr("style","--color:#f0f");
1
2
3
4
5
.box:before {
  content:"I am a before element";
  color:var(--color, red);
  font-size:25px;
}
1
<script src="https://code.jquery.com/jquery-3.3.1.min.js">

它还可以与复杂值一起使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.box {
  --c:"content";
  --b:linear-gradient(red,blue);
  --s:20px;
  --p:0 15px;
}

.box:before {
  content: var(--c);
  background:var(--b);
  color:#fff;
  font-size: calc(2 * var(--s) + 5px);
  padding:var(--p);
}
1
 

您可能会注意到,我考虑的语法是var(--c,value),其中value是默认值,也称为回退值。

从相同的规范中,我们可以看到:

The value of a custom property can be substituted into the value of another property with the var() function. The syntax of var() is:

var() = var( [, ]? )

The first argument to the function is the name of the custom property to be substituted. The second argument to the function, if provided, is a fallback value, which is used as the substitution value when the referenced custom property is invalid.

后来:

To substitute a var() in a property’s value:

  • If the custom property named by the first argument to the var() function is animation-tainted, and the var() function is being used in the animation property or one of its longhands, treat the custom property as having its initial value for the rest of this algorithm.
  • If the value of the custom property named by the first argument to the var() function is anything but the initial value, replace the var() function by the value of the corresponding custom property.
  • Otherwise, if the var() function has a fallback value as its second argument, replace the var() function by the fallback value. If there are any var() references in the fallback, substitute them as well.
  • Otherwise, the property containing the var() function is invalid at computed-value time.
  • 如果不设置自定义属性,或者将其设置为initial或包含无效值,则将使用回退值。如果我们想将自定义属性重置为其默认值,使用initial可能会有所帮助。

    相关的

    如何将继承值存储在CSS自定义属性(又称CSS变量)中?

    框模型的CSS自定义属性(变量)


    以下是访问CSS中定义的样式属性:在样式属性之后和之前:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Get the color value of .element:before
    var color = window.getComputedStyle(
        document.querySelector('.element'), ':before'
    ).getPropertyValue('color');

    // Get the content value of .element:before
    var content = window.getComputedStyle(
        document.querySelector('.element'), ':before'
    ).getPropertyValue('content');


    如果您想完全通过css操作sudo元素的::before或::after,可以使用js。见下文;

    1
    jQuery('head').append('<style id="mystyle" type="text/css"> /* your styles here */ </style>');

    请注意,

    ");


    谢谢大家!我做了我想做的:D网址:http://jsfiddle.net/tfc9j/42/给你看看

    我想让外部DIV的不透明度不同于内部DIV的不透明度,并通过单击somwewhere;)进行更改。谢谢!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
       $('#ena').on('click', function () {
            $('head').append("<style>#ena:before { opacity:0.3; }</style>");
        });

    $('#duop').on('click', function (e) {

            $('head').append("<style>#ena:before { opacity:0.8; }</style>");

         e.stopPropagation();
        });

    #ena{
        width:300px;
        height:300px;
        border:1px black solid;
        position:relative;
    }
    #duo{
        opacity:1;
        position:absolute;
        top:50px;
      width:300px;
        height:100px;
          background-color:white;
    }
    #ena:before {
        content: attr(data-before);
        color: white;
        cursor: pointer;
        position: absolute;
        background-color:red;
        opacity:0.9;
        width:100%;
        height:100%;
    }



       
            <p>
    ena p
    </p>
            <p id="duop">duoyyyyyyyyyyyyyy p
    </p>


    这是不实际的,因为我写这篇文章并不是为了现实世界的需要,只是为了给你一个可以实现的例子。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    css = {
    before: function(elem,attr){

    if($("#cust_style") !== undefined){
    $("body").append("<style>" + elem +":before {"  + attr + "} </style>");
    } else {
     $("#cust_style").remove();
    $("body").append("<style>" + elem +":before {"  + attr + "} </style>");
    }

    }, after: function(elem,attr){
    if($("#cust_style") !== undefined){
    $("body").append("<style>" + elem +":after {"  + attr + "} </style>");

    } else { $("#cust_style").remove();
    $("body").append("<style>" + elem +":after {"  + attr + "} </style>");
    }
    }
    }

    当前添加的a/或附加一个样式元素,该元素包含您所需的属性,这些属性将影响目标元素后面的伪元素。

    这个可以用作

    1
    css.after("someElement"," content: 'Test'; position: 'absolute';") // editing / adding styles to :after

    1
    css.before( ... ); // to affect the before pseudo element.

    和after:and before:pseudo元素一样,不能通过dom直接访问,目前无法自由编辑css的特定值。

    我的方法只是一个例子,它不适合实践,你可以修改它,尝试一些你自己的技巧,使它适合真实世界的使用。

    所以,用这个和其他方法做你自己的实验吧!

    谨致问候-阿达尔什·赫格德。


    当你只需要在head上附加一个style时为什么要添加类或属性?

    1
    $('head').append('<style>.span:after{ content:'changed content' }</style>')

    我总是添加我自己的utils函数,看起来是这样的。

    1
    2
    3
    4
    5
    function setPseudoElContent(selector, value) {    
        document.styleSheets[0].addRule(selector, 'content:"' + value + '";');
    }

    setPseudoElContent('.class::after', 'Hello World!');

    或利用ES6功能:

    1
    2
    3
    4
    5
    const setPseudoElContent = (selector, value) => {    
        document.styleSheets[0].addRule(selector, `content:"${value}";`);
    }

    setPseudoElContent('.class::after', 'Hello World!');


    您可以创建一个伪属性或使用现有属性,并在伪元素的样式表中继承它。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var switched = false;

    // Enable color switching
    setInterval(function () {
        var color = switched ? 'red' : 'darkred';
        var element = document.getElementById('arrow');
        element.style.backgroundColor = color;
       
        // Managing pseudo-element's css
        // using inheritance.
        element.style.borderLeftColor = color;
       
        switched = !switched;
    }, 1000);
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    .arrow {
        /* SET FICTIONAL PROPERTY */
        border-left-color:red;
       
        background-color:red;
        width:1em;
        height:1em;
        display:inline-block;
        position:relative;
    }
    .arrow:after {
        border-top:1em solid transparent;
        border-right:1em solid transparent;
        border-bottom:1em solid transparent;
        border-left:1em solid transparent;
       
        /* INHERIT PROPERTY */
        border-left-color:inherit;
       
        content:"";
        width:0;
        height:0;
        position:absolute;
        left:100%;
        top:-50%;
    }
    1
    <span id="arrow" class="arrow"></span>

    它似乎不适用于"内容"属性:(


    我已经创建了一个jquery插件来添加CSS伪规则,比如对特定元素使用.css()

    • 插件代码和测试用例在这里
    • 将用例作为简单的CSS图像弹出窗口显示在此处

    用途:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $('body')
      .css({
        backgroundColor: 'white'
      })
      .cssPseudo('after', {
        content: 'attr(title)", you should try to hover the picture, then click it."',
        position: 'absolute',
        top: 20, left: 20  
      })
      .cssPseudo('hover:after', {
        content: '"Now hover the picture, then click it!"'
      });

    这里有很多答案,但没有一个答案可以帮助操纵:before:after的CSS,甚至没有一个被接受的答案。

    我建议这样做。假设您的HTML如下所示:

    1
    Test

    然后,在css中设置它的:before,并将其设计为:

    1
    2
    3
    4
    5
    6
    7
    8
    #something:before{
       content:"1st";
       font-size:20px;
       color:red;
    }
    #something{
      content:'1st';
    }

    请注意,我在元素本身中也设置了content属性,这样您以后可以很容易地将其取出。现在有一个button点击它,你想把:before的颜色改为绿色,字体大小改为30px。您可以实现以下目标:

    在某个类.activeS上使用所需样式定义CSS:

    1
    2
    3
    4
    .activeS:before{
       color:green !important;
       font-size:30px !important;
     }

    现在,您可以通过将类添加到:before元素来更改:before样式,如下所示:

    1
    2
    3
    4
    5
    <button id="changeBefore">Change</button>

        $('#changeBefore').click(function(){
            $('#something').addClass('activeS');
        });

    如果您只想获取EDOCX1[1]的内容,可以这样做:

    1
    2
    3
    4
    5
    <button id="getContent">Get Content</button>

        $('#getContent').click(function(){
            console.log($('#something').css('content'));//will print '1st'
        });

    最后,如果您希望通过jquery动态地更改:before内容,可以实现如下所示:

    1
    2
    3
    4
    5
    6
    7
    <button id="changeBefore">Change</button>

        var newValue = '22';//coming from somewhere
        var add = '<style>#something:before{content:"'+newValue+'"!important;}</style>';
        $('#changeBefore').click(function(){
            $('body').append(add);
        });

    单击上面的"changebefore"按钮,将#something:before内容更改为动态值'22'。

    我希望它有帮助。


    1
    2
    3
    4
     $('.span').attr('data-txt', 'foo');
            $('.span').click(function () {
             $(this).attr('data-txt',"any other text");
            })
    1
    2
    3
    4
    5
    .span{
    }
    .span:after{
      content: attr(data-txt);
     }
    1
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">


    你可以使用我的插件。

    jQuery:

    16

    1
    2
    3
    4
    5
    6
    7
    8
    9
    .element {
      width: 480px;
      margin: 0 auto;
      border: 2px solid red;
    }

    .element::before {
      content: 'Old before!';
    }
    1
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js">

    应该指定这些值,如jquery.css的常规函数中所示。

    此外,还可以获取伪元素参数的值,如jquery.css的常规函数:

    1
    console.log( $(element).cssBefore(parameter) );

    JS:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    (function() {
      document.pseudoElements = {
        length: 0
      };

      var setPseudoElement = function(parameters) {
        if (typeof parameters.argument === 'object' || (parameters.argument !== undefined && parameters.property !== undefined)) {
          if (!parameters.element.pseudoElements) parameters.element.pseudoElements = {
            styleSheet: null,
            before: {
              index: null,
              properties: null
            },
            after: {
              index: null,
              properties: null
            },
            id: null
          };

          var selector = (function() {
            if (parameters.element.pseudoElements.id !== null) {
              if (Number(parameters.element.getAttribute('data-pe--id')) !== parameters.element.pseudoElements.id) parameters.element.setAttribute('data-pe--id', parameters.element.pseudoElements.id);
              return '[data-pe--id="' + parameters.element.pseudoElements.id + '"]::' + parameters.pseudoElement;
            } else {
              var id = document.pseudoElements.length;
              document.pseudoElements.length++

                parameters.element.pseudoElements.id = id;
              parameters.element.setAttribute('data-pe--id', id);

              return '[data-pe--id="' + id + '"]::' + parameters.pseudoElement;
            };
          })();

          if (!parameters.element.pseudoElements.styleSheet) {
            if (document.styleSheets[0]) {
              parameters.element.pseudoElements.styleSheet = document.styleSheets[0];
            } else {
              var styleSheet = document.createElement('style');

              document.head.appendChild(styleSheet);
              parameters.element.pseudoElements.styleSheet = styleSheet.sheet;
            };
          };

          if (parameters.element.pseudoElements[parameters.pseudoElement].properties && parameters.element.pseudoElements[parameters.pseudoElement].index) {
            parameters.element.pseudoElements.styleSheet.deleteRule(parameters.element.pseudoElements[parameters.pseudoElement].index);
          };

          if (typeof parameters.argument === 'object') {
            parameters.argument = (function() {
              var cloneObject = typeof parameters.argument.pop === 'function' ? [] : {};

              for (var property in parameters.argument) {
                cloneObject[property] = parameters.argument[property];
              };

              return cloneObject;
            })();

            if (!parameters.element.pseudoElements[parameters.pseudoElement].properties && !parameters.element.pseudoElements[parameters.pseudoElement].index) {
              var newIndex = parameters.element.pseudoElements.styleSheet.rules.length || parameters.element.pseudoElements.styleSheet.cssRules.length || parameters.element.pseudoElements.styleSheet.length;

              parameters.element.pseudoElements[parameters.pseudoElement].index = newIndex;
              parameters.element.pseudoElements[parameters.pseudoElement].properties = parameters.argument;
            };

            var properties = '';

            for (var property in parameters.argument) {
              if (typeof parameters.argument[property] === 'function')
                parameters.element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property]();
              else
                parameters.element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property];
            };

            for (var property in parameters.element.pseudoElements[parameters.pseudoElement].properties) {
              properties += property + ': ' + parameters.element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
            };

            parameters.element.pseudoElements.styleSheet.addRule(selector, properties, parameters.element.pseudoElements[parameters.pseudoElement].index);
          } else if (parameters.argument !== undefined && parameters.property !== undefined) {
            if (!parameters.element.pseudoElements[parameters.pseudoElement].properties && !parameters.element.pseudoElements[parameters.pseudoElement].index) {
              var newIndex = parameters.element.pseudoElements.styleSheet.rules.length || parameters.element.pseudoElements.styleSheet.cssRules.length || parameters.element.pseudoElements.styleSheet.length;

              parameters.element.pseudoElements[parameters.pseudoElement].index = newIndex;
              parameters.element.pseudoElements[parameters.pseudoElement].properties = {};
            };

            if (typeof parameters.property === 'function')
              parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property();
            else
              parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property;

            var properties = '';

            for (var property in parameters.element.pseudoElements[parameters.pseudoElement].properties) {
              properties += property + ': ' + parameters.element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
            };

            parameters.element.pseudoElements.styleSheet.addRule(selector, properties, parameters.element.pseudoElements[parameters.pseudoElement].index);
          };
        } else if (parameters.argument !== undefined && parameters.property === undefined) {
          var windowStyle = window.getComputedStyle(
            parameters.element, '::' + parameters.pseudoElement
          ).getPropertyValue(parameters.argument);

          if (parameters.element.pseudoElements) {
            return parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] || windowStyle;
          } else {
            return windowStyle || null;
          };
        } else {
          console.error('Invalid values!');
          return false;
        };
      };

      Object.defineProperty(Element.prototype, 'styleBefore', {
        enumerable: false,
        value: function(argument, property) {
          return setPseudoElement({
            element: this,
            pseudoElement: 'before',
            argument: argument,
            property: property
          });
        }
      });
      Object.defineProperty(Element.prototype, 'styleAfter', {
        enumerable: false,
        value: function(argument, property) {
          return setPseudoElement({
            element: this,
            pseudoElement: 'after',
            argument: argument,
            property: property
          });
        }
      });
    })();

    document.querySelector('.element').styleBefore('content', '"New before!"');
    1
    2
    3
    4
    5
    6
    7
    8
    9
    .element {
      width: 480px;
      margin: 0 auto;
      border: 2px solid red;
    }

    .element::before {
      content: 'Old before!';
    }
    1
     

    github:https://github.com/yuri-spivak/managing-the-properties-of-pseudo-elements/


    有人评论说要用一个完整的样式元素附加到head元素,如果你只做一次,那也不错,但是如果你需要多次重设它,你最终会得到大量的样式元素。为了防止我在头部创建了一个带有ID的空白样式元素,并像这样替换它的innerhtml:

    1
    <style id="pseudo"></style>

    然后,javascript将如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    var pseudo = document.getElementById("pseudo");

    function setHeight() {
        let height = document.getElementById("container").clientHeight;
        pseudo.innerHTML = `.class:before { height: ${height}px; }`
    }

    setHeight()

    现在,在我的例子中,我需要它来根据另一个元素的高度设置before元素的高度,并且它会随着调整大小而改变,所以使用它,我可以在每次调整窗口大小时运行setHeight(),并且它会正确地替换