使用jQuery选择和操作CSS伪元素,例如:: before和:: after

时间:2011-02-18 12:53:11

标签: javascript jquery css jquery-selectors pseudo-element

有没有办法使用jQuery选择/操作CSS伪元素,例如::before::after(以及带有一个分号的旧版本)?

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

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

如何使用jQuery将'foo'更改为'bar'?

24 个答案:

答案 0 :(得分:662)

您还可以使用data属性将内容传递给伪元素,然后使用jQuery来操作:

在HTML中:

<span>foo</span>

在jQuery中:

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

在CSS中:

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

如果你想阻止'其他文字'出现,你可以将它与seucolega的解决方案结合起来:

在HTML中:

<span>foo</span>

在jQuery中:

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

在CSS中:

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

答案 1 :(得分:434)

你认为这将是一个简单的问题,jQuery可以做的其他事情。不幸的是,问题归结为一个技术问题: css:after和:在规则不属于DOM之前, 因此无法使用jQuery的DOM进行更改方法

使用JavaScript和/或CSS解决方法操纵这些元素的方法;您使用哪一个取决于您的确切要求。


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

1)添加/删除预定的等级

在这种方法中,您已经在CSS中创建了一个具有不同:after:before样式的类。稍后将这个“新”类放在样式表中,以确保它覆盖:

p:before {
    content: "foo";
}
p.special:before {
    content: "bar";
}

然后,您可以使用jQuery(或vanilla JavaScript)轻松添加或删除此类:

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

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

<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并不复杂:

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

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

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

.addRule() and the related .insertRule() methods今天得到了相当好的支持。

作为一种变体,您还可以使用jQuery在文档中添加一个全新的样式表,但必要的代码不是更清晰:

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

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

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

如果我们谈论的是“操纵”价值,而不只是添加它们,我们也可以read the existing :after or :before styles使用不同的方法:

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

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

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

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

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

  • 优点:任何字符串都可以动态插入到样式
  • 缺点:原始样式不会被改变,只是被覆盖;重复(ab)使用可以使DOM增长任意大

3)更改不同的DOM属性

您还可以use attr() in your CSS来读取特定的DOM属性。 (If a browser supports :before, it supports attr() as well.)通过在一些精心准备的CSS中将其与content:相结合,我们可以更改内容(但 不是其他属性, 就像边距一样动态:before:after

p:before {
    content: attr(data-before);
    color: red;
    cursor: pointer;
}

JS:

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

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

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

如果无法提前准备CSS,可以将其与第二种技术结合使用:

var str = "bar";

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

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

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

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

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

  • 优点:不创造无穷无尽的额外风格
  • CSS中的
  • 缺点: attr只能应用于内容字符串,而不是网址或RGB颜色

答案 2 :(得分:156)

虽然它们是由浏览器通过CSS呈现的,就好像它们就像其他真正的DOM元素一样,但伪元素本身不是DOM的一部分,因为顾名思义,伪元素不是真正的元素,因此你不能直接使用jQuery(或任何 JavaScript API)来选择和操作它们,甚至不能Selectors API。这适用于您尝试使用脚本修改其样式的任何伪元素,而不仅仅是::before::after

你只能在运行时通过CSSOM(想象window.getComputedStyle())直接访问伪元素样式,这不是jQuery超出.css()的公开,这是一种不支持伪元素的方法

你可以随时找到其他方法,例如:

  • 将样式应用于一个或多个任意类的伪元素,然后在类之间切换(请参阅seucolega's answer以获取快速示例) - 这是惯用的方式,因为它使用了简单的选择器(哪些伪元素不是)区分元素和元素状态,它们的使用方式

  • 通过更改文档样式表来操作应用于所述伪元素的样式,这更像是一个黑客攻击

答案 3 :(得分:77)

您无法在jQuery中选择伪元素,因为它们不是DOM的一部分。 但是你可以在父元素中添加一个特定的类,并在CSS中控制它的伪元素。

EXAMPLE

在jQuery中:

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

在CSS中:

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

答案 4 :(得分:37)

根据克里斯蒂安的建议,你也可以这样做:

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

答案 5 :(得分:24)

我们也可以依靠custom properties (aka CSS variables)来操纵伪元素。我们可以在specification中读到:

  

自定义属性是普通属性,因此可以声明它们   任何元素都使用正常继承级联解决   规则,可以使用@media和其他条件规则进行条件化,可以在 HTML的样式属性中使用,可以使用CSSOM读取或设置等等。

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

请注意,您认为相关的所有浏览器(例如IE 11)可能无法使用CSS变量:https://caniuse.com/#feat=css-variables

1)使用内联样式

.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}
<div class="box"></div>
<div class="box" style="--color:blue;--content:'I am a blue element'"></div>
<div class="box" style="--color:black"></div>
<div class="box" style="--color:#f0f;--content:'another element'"></div>

2)使用CSS和类

.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;
}
<div class="box"></div>
<div class="box black" ></div>
<div class="box blue"></div>

3)使用javascript

document.querySelectorAll('.box')[0].style.setProperty("--color", "blue");
document.querySelectorAll('.box')[1].style.setProperty("--content", "'I am another element'");
.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}
<div class="box"></div>
<div class="box"></div>

4)使用jQuery

$('.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");
.box:before {
  content:"I am a before element";
  color:var(--color, red);
  font-size:25px;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>

它也可以用于复杂的值:

.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);
}
<div class="box"></div>

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

根据相同的规范,我们可以阅读:

  

可以使用var()函数将自定义属性的值替换为另一个属性的值。 var()的语法是:

     

var() = var( <custom-property-name> [, <declaration-value> ]? )

     

该函数的第一个参数是要替换的自定义属性的名称。该函数的第二个参数(如果提供)是一个回退值,当引用的自定义属性无效时,该值用作替换值

后来:

  

在属性值中替换var():

     
      
  1. 如果var()函数的第一个参数指定的自定义属性受动画污染,并且动画属性或其中一个longhands中正在使用var()函数,请处理自定义属性因为它具有该算法其余部分的初始值。
  2.   
  3. 如果var()函数的第一个参数指定的自定义属性的值不是初始值,则将var()函数替换为相应自定义属性的值。
  4.   
  5. 否则,如果var()函数的回退值作为其第二个参数,则将var()函数替换为回退值。如果后备中有任何var()引用,也请替换它们。
  6.   
  7. 否则,包含var()函数的属性在计算值时间无效。
  8.   

如果我们不设置自定义属性或我们将其设置为initial或者它包含无效值,则将使用回退值。如果我们想要将自定义属性重置为其默认值,则initial的使用会很有用。

相关

How to store inherit value inside a CSS custom property (aka CSS variables)?

CSS custom properties (variables) for box model

答案 6 :(得分:23)

以下是访问方式:在和之前:在样式属性之前,在css中定义:

// 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');

答案 7 :(得分:11)

如果你想完全通过CSS操作sudo元素之前的:: before或::,你可以做JS。见下文;

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

注意<style>元素如何具有ID,如果您的样式动态更改,可以使用该ID删除它并再次附加到它。

这样,在JS的帮助下,你的元素就是你想要它的样式。

答案 8 :(得分:5)

一种有效但不是非常有效的方法是使用新内容向文档添加规则并使用类引用它。根据需要,类可能需要内容中每个值的唯一ID。

$("<style type='text/css'>span.id-after:after{content:bar;}</style>").appendTo($("head"));
$('span').addClass('id-after');

答案 9 :(得分:5)

这是HTML:

<div class="icon">
  <span class="play">
    ::before
  </span>
</div>

'之前'的计算风格为content: "VERIFY TO WATCH";

这是我的两行jQuery,它使用添加额外类来专门引用此元素的想法,然后附加样式标记(带有!important标记)来更改sudo-element的内容值的CSS:

$("span.play:eq(0)").addClass('G');

$('body').append("<style>.G:before{content:'NewText' !important}</style>");

答案 10 :(得分:4)

谢谢大家! 我设法做我想做的事:D http://jsfiddle.net/Tfc9j/42/ 看看这个

我希望外部div的不透明度与内部div的不透明度不同,并且通过单击somwewhere进行更改;) 谢谢!

   $('#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%;
}


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

    </div>   


</div>

答案 11 :(得分:3)

这不实用,因为我没有为现实世界的用途写这个,只是为了给你一个可以实现的例子。

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 /或附加一个Style元素,其中包含必要的属性,这将对Pseudo元素之后的目标元素产生影响。

这可以用作

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

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

as after:and before:伪元素不能通过DOM直接访问,目前无法自由编辑css的Specific值。

我的方式只是一个例子而且它不适合练习,你可以修改它尝试一些你自己的技巧并使其正确用于现实世界。

你自己和其他人一起做实验!

问候 - Adarsh Hegde。

答案 12 :(得分:2)

为什么在只需追加style

时添加类或属性
$('head').append('<style>.span:after{ content:'changed content' }</style>')

答案 13 :(得分:2)

我总是添加自己的utils函数,如下所示。

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

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

或使用ES6功能:

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

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

答案 14 :(得分:2)

您可以在伪元素的样式表中创建虚假属性或使用现有属性并继承

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);
.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%;
}
<span id="arrow" class="arrow"></span>

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

答案 15 :(得分:1)

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

以下是我的建议。让我们假设你的HTML是这样的:

<div id="something">Test</div>

然后你设置它:在CSS之前设计它:

#something:before{
   content:"1st";
   font-size:20px;
   color:red;
}
#something{
  content:'1st';
}

请注意我还在元素中设置了content属性,以便您以后可以轻松将其取出。 现在有一个button点击,你想要改变颜色:before到green,它的font-size改为30px。您可以按如下方式实现:

在某个班级.activeS上定义一个具有所需风格的CSS:

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

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

<button id="changeBefore">Change</button>
<script>
    $('#changeBefore').click(function(){
        $('#something').addClass('activeS');
    });
</script>

如果您只想获得:before的内容,可以按以下方式完成:

<button id="getContent">Get Content</button>
<script>
    $('#getContent').click(function(){
        console.log($('#something').css('content'));//will print '1st'
    });
</script>

最终,如果您想通过jQuery动态更改:before内容,您可以按如下方式实现:

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

点击“changeBefore”按钮上方会将:before的{​​{1}}内容更改为“22”,这是一个动态值。

我希望它有所帮助

答案 16 :(得分:1)

我创建了一个jQuery插件来添加css-pseudo规则,例如对特定元素使用.css()

  • 插件代码和测试用例为here
  • 将用例作为简单的CSS图像弹出窗口here

用法:

$('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!"'
  });

答案 17 :(得分:0)

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

答案 18 :(得分:0)

您可以将我的插件用于此目的。

JQuery的:

&#13;
&#13;
(function() {
  $.pseudoElements = {
    length: 0
  };

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

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

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

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

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

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

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

        if (typeof parameters.argument === 'object') {
          parameters.argument = $.extend({}, parameters.argument);

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

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

          var properties = '';

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

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

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

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

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

          var properties = '';

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

          element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index);
        };
      };

      return $(parameters.elements);
    } else if (parameters.argument !== undefined && parameters.property === undefined) {
      var element = $(parameters.elements).get(0);

      var windowStyle = window.getComputedStyle(
        element, '::' + parameters.pseudoElement
      ).getPropertyValue(parameters.argument);

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

  $.fn.cssBefore = function(argument, property) {
    return setPseudoElement({
      elements: this,
      pseudoElement: 'before',
      argument: argument,
      property: property
    });
  };
  $.fn.cssAfter = function(argument, property) {
    return setPseudoElement({
      elements: this,
      pseudoElement: 'after',
      argument: argument,
      property: property
    });
  };
})();

$(function() {
  $('.element').cssBefore('content', '"New before!"');
});
&#13;
.element {
  width: 480px;
  margin: 0 auto;
  border: 2px solid red;
}

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

<div class="element"></div>
&#13;
&#13;
&#13;

应该指定值,如jQuery.css的正常函数

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

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

JS:

&#13;
&#13;
(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!"');
&#13;
.element {
  width: 480px;
  margin: 0 auto;
  border: 2px solid red;
}

.element::before {
  content: 'Old before!';
}
&#13;
<div class="element"></div>
&#13;
&#13;
&#13;

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

答案 19 :(得分:0)

其他人评论过将head元素附加到一个完整的样式元素,如果你只做一次但是如果你需要多次重置它,你最终会得到大量的样式元素。因此,为了防止我在头部创建了一个带有id的空白样式元素,并替换它的innerHTML,如下所示:

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

然后JavaScript看起来像这样:

var pseudo = document.getElementById("pseudo");

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

setHeight()

现在在我的情况下,我需要根据另一个元素的高度来设置before元素的高度,并且它会在调整大小时改变,所以使用这个我可以在每次调整窗口大小时运行setHeight()它将会正确替换<style>

希望帮助那些被困的人试图做同样的事情。

答案 20 :(得分:0)

我利用CSS:root中定义的变量来修改:after(对:before也是如此)伪元素 ,尤其是要更改{{1}中定义的样式background-color的{​​{1}}值和另一个anchor.sliding-middle-out:hover:after)的content值以下demo通过使用JavaScript / jQuery生成随机颜色:

HTML

anchor

CSS

#reference

JS / jQuery

<a href="#" id="changeColor" class="sliding-middle-out" title="Generate a random color">Change link color</a>
<span id="log"></span>
<h6>
  <a href="https://stackoverflow.com/a/52360188/2149425" id="reference" class="sliding-middle-out" target="_blank" title="Stack Overflow topic">Reference</a>
</h6>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/davidmerfield/randomColor/master/randomColor.js"></script>

答案 21 :(得分:0)

我为您提供了一些简单而有效的东西。

    <style> 
    .case-after:after { // set your properties here like eg: 
        color:#3fd309 !important; 
     } 
     .case-before:before { // set your properties here like eg: 
        color:#151715 !important; 
     }
 </style>
  // case for after
    $('#button-id').on('click', function() {
        $(".target-div").toggleClass('case-after');
    });

     // case for before
    $('#button-id').on('click', function() {
        $(".target-div").toggleClass('case-before');
    });

答案 22 :(得分:0)

我第一次在给出自己的答案之前没有阅读所有给出的答案,所以我希望这不会让我陷入......

就我而言,这是附加到 adivbutton 元素的图标所需要的,它们的工作方式与 <i class="icon-class"></i> 有点不同,因为没有 { {1}} 类。不过添加 icon-class 会破坏样式。

相反,我向它们添加了一个 class="icon-class" 属性,其中包含应该在 data-icon 中的值,然后这个相当简单的 JavaScript 负责其余的工作。

element::before { content: "HERE" }

代码解释:

  • 选择具有指定属性 ( { const fakeIcons = document.querySelectorAll('[data-icon]') for (const iconElement of fakeIcons) { const fakeClass = 'fake-' + Array.from(Array(20), () => Math.floor(Math.random() * 36).toString(36)).join('') const beforeContent = iconElement.getAttribute('data-icon') iconElement.classList.add(fakeClass) const style = document.createElement('style') style.type = 'text/css' style.innerHTML = ` .${fakeClass}::before { content: "${beforeContent}" !important; } ` document.getElementsByTagName('head')[0].appendChild(style) } } ) 的所有元素
  • 遍历它们
  • 随机生成一个以data-icon开头的类名,后面跟着一个随机的字母数字串
  • 获取 fake- 属性的值
  • 向元素添加随机生成的类
  • data-icon 伪元素创建样式,将内容设置为先前获取的值
  • ::before HTML 元素的末尾添加样式

答案 23 :(得分:-1)

以下解决方案告诉您如何使用 javascript attr 属性更新伪元素。

在 HTML 中添加一个属性,您可以使用带有 setAttribute 的 javascript 操作该属性。

<div 
 id="inputBoxParent" 
 count="0">
      ...
</div>

使用js更新

inputBoxParent.setAttribute('count', value.length)

CSS - 在伪元素中添加内容为 attr(attributeName)

.input-box-container::after{
  content: attr(count);
}

大功告成!!!

const inputBoxParent = document.getElementById("inputBoxParent");
const handleOnChange = (value) => {
  inputBoxParent.setAttribute('count', value.length)
}
.input-box-container {
  position: relative;
  width: 200px;
}
.input-box-container::after{
  position: absolute;
  bottom: 8px;
  right: 10px;
  height: 10px;
  width: 20px;
  content: attr(count);
}
<h4> Type some text inside the box and click outside to see resule i.e. pseudo element content change</h4>
<div 
  id="inputBoxParent" 
  class="input-box-container" 
  count="0">
  <input 
    type="text" 
    id="inputBox" 
    placeholder="type some thing" 
    onchange="handleOnChange(this.value)" />
</div>