简体   繁体   English

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

[英]Selecting and manipulating CSS pseudo-elements such as ::before and ::after using javascript (or jQuery)

Is there any way to select/manipulate CSS pseudo-elements such as ::before and ::after (and the old version with one semi-colon) using jQuery?有没有办法使用 jQuery 选择/操作 CSS 伪元素,例如::before::after (以及带有一个分号的旧版本)?

For example, my stylesheet has the following rule:例如,我的样式表有以下规则:

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

How can I change 'foo' to 'bar' using vanilla JS or jQuery?如何使用 vanilla JS 或 jQuery 将“foo”更改为“bar”?

You could also pass the content to the pseudo element with a data attribute and then use jQuery to manipulate that:您还可以将内容传递给具有 data 属性的伪元素,然后使用 jQuery 来操作它:

In HTML:在 HTML 中:

<span>foo</span>

In jQuery:在 jQuery 中:

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

In CSS:在 CSS 中:

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

If you want to prevent the 'other text' from showing up, you could combine this with seucolega's solution like this:如果您想防止出现“其他文本”,您可以将其与 seucolega 的解决方案相结合,如下所示:

In HTML:在 HTML 中:

<span>foo</span>

In jQuery:在 jQuery 中:

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

In CSS:在 CSS 中:

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

You'd think this would be a simple question to answer, with everything else that jQuery can do.您会认为这将是一个简单的问题,jQuery 可以做任何其他事情。 Unfortunately, the problem comes down to a technical issue: css :after and :before rules aren't part of the DOM, and therefore can't be altered using jQuery's DOM methods.不幸的是,问题归结为一个技术问题: css :after 和 :before 规则不是 DOM 的一部分,因此不能使用 jQuery 的 DOM 方法进行更改。

There are ways to manipulate these elements using JavaScript and/or CSS workarounds;一些方法可以使用 JavaScript 和/或 CSS 变通方法来操作这些元素; which one you use depends on your exact requirements.您使用哪一种取决于您的确切要求。


I'm going to start with what's widely considered the "best" approach:我将从广泛认为的“最佳”方法开始:

1) Add/remove a predetermined class 1) 添加/删除预定的类

In this approach, you've already created a class in your CSS with a different :after or :before style.在这种方法中,您已经在 CSS 中创建了一个具有不同:after:before样式的类。 Place this "new" class later in your stylesheet to make sure it overrides:稍后将这个“新”类放在您的样式表中以确保它覆盖:

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

Then you can easily add or remove this class using jQuery (or vanilla JavaScript):然后,您可以使用 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>

  • Pros: Easy to implement with jQuery;优点:易于使用 jQuery 实现; quickly alters multiple styles at once;一次快速改变多种风格; enforces separation of concerns (isolating your CSS and JS from your HTML)强制分离关注点(将 CSS 和 JS 与 HTML 隔离)
  • Cons: CSS must be pre-written, so the content of :before or :after isn't completely dynamic缺点: CSS 必须预先编写,因此:before:after内容不是完全动态的

2) Add new styles directly to the document's stylesheet 2) 直接在文档的样式表中添加新样式

It's possible to use JavaScript to add styles directly to the document stylesheet, including :after and :before styles.可以使用 JavaScript 直接向文档样式表添加样式,包括:after:before样式。 jQuery doesn't provide a convenient shortcut, but fortunately the JS isn't that complicated: 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 are fairly well-supported today. .addRule()和相关的.insertRule()方法今天得到了很好的支持。

As a variation, you can also use jQuery to add an entirely new stylesheet to the document, but the necessary code isn't any cleaner:作为一种变体,您还可以使用 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>

If we're talking about "manipulating" the values, not just adding to them, we can also read the existing :after or :before styles using a different approach:如果我们谈论的是“操作”值,而不仅仅是添加到它们,我们还可以使用不同的方法读取现有的:after:before样式

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>

We can replace document.querySelector('p') with $('p')[0] when using jQuery, for slightly shorter code.当使用 jQuery 时,我们可以用$('p')[0]替换document.querySelector('p') ,以获得更短的代码。

  • Pros: any string can be dynamically inserted into the style优点:任何字符串都可以动态插入到样式中
  • Cons: original styles aren't altered, just overridden;缺点:原始样式不会改变,只是被覆盖; repeated (ab)use can make the DOM grow arbitrarily large重复(ab)使用可以使 DOM 增长任意大

3) Alter a different DOM attribute 3) 改变不同的 DOM 属性

You can also to use attr() in your CSS to read a particular DOM attribute.您还可以在 CSS 中使用attr()来读取特定的 DOM 属性。 ( If a browser supports :before , it supports attr() as well. ) By combining this with content: in some carefully-prepared CSS, we can change the content (but not other properties, like margin or color) of :before and :after dynamically: 如果浏览器支持:before ,它也支持attr() )通过将其与content:结合起来content:在一些精心准备的 CSS 中,我们可以更改:before的内容(但不能更改其他属性,例如边距或颜色)和:after动态:after

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

JS: 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>

This can be combined with the second technique if the CSS can't be prepared ahead of time:如果 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>

  • Pros: Doesn't create endless extra styles优点:不会创造无穷无尽的额外风格
  • Cons: attr in CSS can only apply to content strings, not URLs or RGB colors缺点: CSS 中的attr仅适用于内容字符串,不适用于 URL 或 RGB 颜色

Although they are rendered by browsers through CSS as if they were like other real DOM elements, pseudo-elements themselves are not part of the DOM, because pseudo-elements, as the name implies, are not real elements, and therefore you can't select and manipulate them directly with jQuery (or any JavaScript APIs for that matter, not even the Selectors API ).虽然它们通过 CSS 被浏览器渲染,就好像它们就像其他真正的 DOM 元素一样,但伪元素本身并不是 DOM 的一部分,因为伪元素,顾名思义,不是真正的元素,因此你不能直接使用 jQuery(或任何JavaScript API,甚至不是Selectors API )选择和操作它们。 This applies to any pseudo-elements whose styles you're trying to modify with a script, and not just ::before and ::after .这适用于您尝试使用脚本修改其样式的任何伪元素,而不仅仅是::before::after

You can only access pseudo-element styles directly at runtime via the CSSOM (think window.getComputedStyle() ), which is not exposed by jQuery beyond .css() , a method that doesn't support pseudo-elements either.您只能在运行时通过 CSSOM 直接访问伪元素样式(想想window.getComputedStyle() ),除了.css()之外,jQuery 不会公开它,该方法也不支持伪元素。

You can always find other ways around it, though, for example:不过,您总是可以找到其他方法来解决它,例如:

  • Applying the styles to the pseudo-elements of one or more arbitrary classes, then toggling between classes (see seucolega's answer for a quick example) — this is the idiomatic way as it makes use of simple selectors (which pseudo-elements are not) to distinguish between elements and element states, the way they're intended to be used将样式应用于一个或多个任意类的伪元素,然后在类之间切换(请参阅seucolega 的快速示例的答案)——这是惯用的方式,因为它使用简单的选择器(伪元素不是)来区分元素和元素状态,它们的使用方式

  • Manipulating the styles being applied to said pseudo-elements, by altering the document stylesheet, which is much more of a hack通过更改文档样式表来操纵应用于所述伪元素的样式,这更像是一种黑客行为

You can't select pseudo elements in jQuery because they are not part of DOM.您不能在 jQuery 中选择伪元素,因为它们不是 DOM 的一部分。 But you can add a specific class to the parent element and control its pseudo elements in CSS.但是你可以给父元素添加一个特定的类,并在 CSS 中控制它的伪元素。

EXAMPLE例子

In jQuery:在 jQuery 中:

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

In CSS:在 CSS 中:

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

We can also rely on custom properties (aka CSS variables) in order to manipulate pseudo-element.我们还可以依靠自定义属性(又名 CSS 变量)来操作伪元素。 We can read in the specification that:我们可以在规范中读到:

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.自定义属性是普通属性,所以可以在任何元素上声明,用普通的继承级联规则解析,可以用@media等条件规则设置条件,可以在HTML的样式属性中使用,可以读取或设置使用 CSSOM等。

Considering this, the idea is to define the custom property within the element and the pseudo-element will simply inherit it;考虑到这一点,想法是在元素内定义自定义属性,伪元素将简单地继承它; thus we can easily modify it.因此我们可以很容易地修改它。

1) Using inline style : 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) Using CSS and classes 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) Using javascript 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) Using jQuery 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>


It can also be used with complex values:它也可以用于复数值:

 .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>

You may notice that I am considering the syntax var(--c,value) where value is the default value and also called the fallback value.您可能会注意到,我正在考虑使用var(--c,value)语法var(--c,value)其中value是默认值,也称为回退值。

From the same specification we can read:从相同的规范我们可以读到:

The value of a custom property can be substituted into the value of another property with the var() function.可以使用 var() 函数将自定义属性的值替换为另一个属性的值。 The syntax of var() is: var() 的语法是:

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

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.函数的第二个参数(如果提供)是回退值,当引用的自定义属性无效时,该值用作替代值

And later:然后:

To substitute a var() in a property's value:要在属性值中替换 var():

  1. 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.如果由var()函数的第一个参数命名的自定义属性被动画污染,并且var()函数正在动画属性或其一个常用属性中使用,则将自定义属性视为具有其初始值这个算法的其余部分。
  2. 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.如果var()函数的第一个参数命名的自定义属性的值不是初始值,则将var()函数替换为相应自定义属性的值。
  3. Otherwise, if the var() function has a fallback value as its second argument, replace the var() function by the fallback value.否则,如果var()函数将回退值作为其第二个参数,则将var()函数替换为回退值。 If there are any var() references in the fallback, substitute them as well.如果回退中有任何var()引用,也替换它们。
  4. Otherwise, the property containing the var() function is invalid at computed-value time.否则,包含var()函数的属性在计算值时无效。

If we don't set the custom property OR we set it to initial OR it contains an invalid value then the fallback value will be used.如果我们不设置自定义属性或将其设置为initial值或它包含无效值,则将使用回退值。 The use of initial can be helpful in case we want to reset a custom property to its default value.如果我们想将自定义属性重置为其默认值,则使用initial值会很有帮助。

Related有关的

How to store inherit value inside a CSS variable (aka custom property)?如何在 CSS 变量(又名自定义属性)中存储继承值?

CSS custom properties (variables) for box model盒子模型的 CSS 自定义属性(变量)

按照 Christian 的建议,您还可以执行以下操作:

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

Here is the way to access :after and :before style properties, defined in css:这是访问 :after 和 :before 样式属性的方法,在 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');

IF you want to to manipulate the ::before or ::after sudo elements entirely through CSS, you could do it JS.如果你想完全通过 CSS 操作 ::before 或 ::after sudo 元素,你可以用 JS 来做。 See below;见下文;

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

Notice how the <style> element has an ID, which you can use to remove it and append to it again if your style changes dynamically.请注意<style>元素如何具有 ID,如果您的样式动态更改,您可以使用它删除它并再次附加到它。

This way, your element is style exactly how you want it through CSS, with the help of JS.这样,在 JS 的帮助下,您的元素可以通过 CSS 完全按照您想要的样式进行设置。

Thank you all!谢谢你们! i managed to do what i wanted :D http://jsfiddle.net/Tfc9j/42/ here take a look我设法做我想做的事:D http://jsfiddle.net/Tfc9j/42/在这里看看

i wanted to have the opacity of an outer div to be different from the opacity of the internal div and that change with a click somwewhere ;) Thanks!我想让外部 div 的不透明度与内部 div 的不透明度不同,并且在某处单击即可更改 ;) 谢谢!

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

one working but not very efficient way is to add a rule to the document with the new content and reference it with a class.一种有效但不是很有效的方法是将规则添加到具有新内容的文档并使用类引用它。 depending on what is needed the class might need an unique id for each value in content.根据需要,该类可能需要为内容中的每个值提供一个唯一的 id。

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

Here is the HTML:这是 HTML:

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

Computed style on 'before' was content: "VERIFY TO WATCH"; 'before' 上的计算样式是content: "VERIFY TO WATCH";

Here is my two lines of jQuery, which use the idea of adding an extra class to specifically reference this element and then appending a style tag (with an !important tag) to changes the CSS of the sudo-element's content value:这是我的两行 jQuery,它使用了添加一个额外类来专门引用此元素的想法,然后附加一个样式标记(带有 !important 标记)以更改 sudo 元素内容值的 CSS:

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

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

You may create a fake property or use an existing one and inherit it in the pseudo-element's stylesheet.您可以创建一个假属性或使用现有属性并在伪元素的样式表中继承它。

 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>

It seems it doesn't work for "content" property :(它似乎不适用于“内容”属性:(

This is not practical as i did not write this for real world uses, just to give you a example of what can be achieved.这是不切实际的,因为我不是为现实世界的使用而写的,只是为了给你一个可以实现的例子。

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>"); 
}
}
}

this currently add's a / or appends a Style element which contains your necessary attribute's which will take affect on the target element's after Pseudo element.这当前添加了一个 / 或附加了一个 Style 元素,其中包含您的必要属性,该属性将在伪元素之后对目标元素产生影响。

this can be used as这可以用作

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

and

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

as after: and before: pseudo elements are not directly accessible through DOM it is currently not possible to edit the Specific values of the css freely.如 after: 和 before: 伪元素不能通过 DOM 直接访问,目前无法自由编辑 css 的特定值。

my way was just a example and its not good for practice, you can modify it try some of your own tricks and make it correct for real world usage.我的方式只是一个例子,它不利于实践,你可以修改它尝试一些你自己的技巧,使其适合现实世界的使用。

so do your own experimentation's with this and others!所以做你自己的实验这个和其他的!

regards - Adarsh Hegde.问候 - 阿达什赫格德。

I'm always adding my own utils function, which looks like this.我总是添加我自己的 utils 函数,它看起来像这样。

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

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

or make use of ES6 Features:或利用 ES6 特性:

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

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

There are many answers here but no answer helps to manipulate the css of :before or :after , not even the accepted one.这里有很多答案,但没有答案有助于操纵:before:after的css,甚至没有被接受的。

Here is how I propose to do it.这是我建议的方法。 Lets suppose your HTML is like this:假设你的 HTML 是这样的:

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

And then you are setting its :before in CSS and designing it like:然后你在 CSS 中设置它的 :before 并将其设计为:

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

Please notice I also set content attribute in element itself so that you can take it out easily later.请注意,我还在元素本身中设置了content属性,以便您以后可以轻松地将其取出。 Now there is a button clicking on which, you want to change the color of :before to green and its font-size to 30px.现在点击一个button ,您想将 :before 的颜色更改为绿色,将字体大小更改为 30px。 You can achieve that as follows:您可以通过以下方式实现:

Define a css with your required style on some class .activeS :在某些类.activeS上定义具有所需样式的 css:

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

Now you can change :before style by adding the class to your :before element as follows:现在您可以通过将类添加到您的 :before 元素来更改 :before 样式,如下所示:

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

If you just want to get content of :before , it can be done as:如果您只想获取:before内容,可以这样做:

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

Ultimately if you want to dynamically change :before content by jQuery, You can achieve that as follows:最终,如果您想通过 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>

Clicking on above "changeBefore" button will change :before content of #something into '22' which is a dynamic value.单击上面的“changeBefore”按钮会将#something内容:before更改为'22',这是一个动态值。

I hope it helps我希望它有帮助

当您可以将style附加到头部时,为什么还要添加类或属性

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

You can use my plugin for this purpose.为此,您可以使用我的插件。

JQuery:查询:

 (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!"'); });
 .element { width: 480px; margin: 0 auto; border: 2px solid red; } .element::before { content: 'Old before!'; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <div class="element"></div>

The values should be specified, as in the normal function of jQuery.css应该指定值,就像在 jQuery.css 的正常功能中一样

In addition, you can also get the value of the pseudo-element parameter, as in the normal function of jQuery.css:另外,你还可以获取伪元素参数的值,就像在jQuery.css的普通函数中一样:

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

JS: JS:

 (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!"');
 .element { width: 480px; margin: 0 auto; border: 2px solid red; } .element::before { content: 'Old before!'; }
 <div class="element"></div>


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

I have created a jQuery plugin to add css-pseudo rules like using .css() for specific elements.我创建了一个 jQuery 插件来添加 css 伪规则,例如对特定元素使用.css()

  • plugin code and test case is here插件代码和测试用例在这里
  • use case as simple css image popup here使用情况下,简单的CSS图像弹出这里

usage:用法:

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

 $('.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>

Someone else commented on appending to the head element with a full style element and that's not bad if you're only doing it once but if you need to reset it more than once you'll end up with a ton of style elements.其他人评论说用完整的样式元素附加到 head 元素,如果你只做一次也不错,但如果你需要多次重置它,你最终会得到大量的样式元素。 So to prevent that I created a blank style element in the head with an id and replace the innerHTML of it like this:所以为了防止我在头部创建了一个带有 id 的空白样式元素,并像这样替换它的 innerHTML:

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

Then the JavaScript would look like this:然后 JavaScript 将如下所示:

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

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

setHeight()

Now in my case I needed this to set the height of a before element based on the height of another and it will change on resize so using this I can run setHeight() every time the window is resized and it will replace the <style> properly.现在,在我的情况下,我需要它来根据另一个元素的高度设置一个 before 元素的高度,并且它会在调整大小时发生变化,因此使用它我可以在每次调整窗口大小时运行setHeight()并且它将替换<style>适当地。

Hope that helps someone who was stuck trying to do the same thing.希望能帮助那些试图做同样事情的人。

I made use of variables defined in :root inside CSS to modify the :after (the same applies to :before ) pseudo-element , in particular to change the background-color value for a styled anchor defined by .sliding-middle-out:hover:after and the content value for another anchor ( #reference ) in the following demo that generates random colors by using JavaScript/jQuery:我使用CSS:root定义的变量来修改:after (同样适用于:before伪元素,特别是更改由.sliding-middle-out:hover:after定义的样式anchorbackground-color.sliding-middle-out:hover:after和以下演示中另一个anchor ( #reference ) 的content值,该演示使用 JavaScript/jQuery 生成随机颜色:

HTML HTML

<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>

CSS CSS

:root {
    --anchorsFg: #0DAFA4;
}
a, a:visited, a:focus, a:active {
    text-decoration: none;
    color: var(--anchorsFg);
    outline: 0;
    font-style: italic;

    -webkit-transition: color 250ms ease-in-out;
    -moz-transition: color 250ms ease-in-out;
    -ms-transition: color 250ms ease-in-out;
    -o-transition: color 250ms ease-in-out;
    transition: color 250ms ease-in-out;
}
.sliding-middle-out {
    display: inline-block;
    position: relative;
    padding-bottom: 1px;
}
.sliding-middle-out:after {
    content: '';
    display: block;
    margin: auto;
    height: 1px;
    width: 0px;
    background-color: transparent;

    -webkit-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -moz-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -ms-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -o-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
}
.sliding-middle-out:hover:after {
    width: 100%;
    background-color: var(--anchorsFg);
    outline: 0;
}
#reference {
  margin-top: 20px;
}
.sliding-middle-out:before {
  content: attr(data-content);
  display: attr(data-display);
}

JS/jQuery JS/jQuery

var anchorsFg = randomColor();
$( ".sliding-middle-out" ).hover(function(){
    $( ":root" ).css({"--anchorsFg" : anchorsFg});
});

$( "#reference" ).hover(
 function(){
    $(this).attr("data-content", "Hello World!").attr("data-display", "block").html("");
 },
 function(){
    $(this).attr("data-content", "Reference").attr("data-display", "inline").html("");
 }
);

The first time I'm not reading all given answers before giving my own, so I hope this doesn't bite me in the ...我第一次在给出自己的答案之前没有阅读所有给出的答案,所以我希望这不会让我陷入……

In my case this was needed for icons attached to a , div and button elements, which worked a bit differently than the <i class="icon-class"></i> since, there was no icon-class class on them.在我的例子中,这是附加到adivbutton元素的图标所需要的,它的工作方式与<i class="icon-class"></i>有点不同,因为它们没有icon-class类。 Adding class="icon-class" broke styling though.但是添加class="icon-class"破坏了样式。

Instead I added a data-icon attribute to them with the value of what was supposed to be in element::before { content: "HERE" } and then this fairly simple JavaScript took care of the rest.相反,我向它们添加了一个data-icon属性,其值应该是element::before { content: "HERE" } ,然后这个相当简单的 JavaScript 处理了其余的事情。

    {
        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)
        }
    }

Code explained:代码解释:

  • select all elements with the designated attribute ( data-icon )选择具有指定属性( data-icon )的所有元素
  • loop through them循环它们
  • randomly generate a class name starting with fake- , followed by a random alphanumeric string随机生成一个以fake-开头的类名,后跟一个随机的字母数字字符串
  • get data-icon attribute's value获取data-icon属性的值
  • add randomly generated class to the element将随机生成的类添加到元素
  • create style for ::before pseudo-element setting content to previously fetched value::before伪元素将内容设置为先前获取的值创建样式
  • add styling to the end of <head> HTML element<head> HTML 元素的末尾添加样式

The below solution tells how you can update pseudo-elements with javascript attr attribute.下面的解决方案告诉您如何使用 javascript attr属性更新伪元素。

add an attribute in HTML which you can manipulate with javascript with setAttribute.在 HTML 中添加一个属性,您可以使用带有 setAttribute 的 javascript 操作该属性。

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

update with js用js更新

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

CSS - in pseudo-element add content as attr(attributeName) CSS - 在伪元素中添加内容为 attr(attributeName)

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

And you are done!!!你完成了!!!

 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 ie 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)" onkeyup="handleOnChange(this.value)" /> </div>

Just set the pseudo before or after to have a style of inherit, then set the parent style with javascript.只需在之前之后设置伪样式即可继承,然后使用 javascript 设置父样式。

So, for example I want to change the color style of the :before, then i set the:因此,例如我想更改 :before 的颜色样式,然后我设置:

.my-style::before{
color: inherit;
}

Then I just change the color style on the .my-style element with javascript:然后我只需使用 javascript 更改.my-style元素上的颜色样式

document.querySelector(".my-style").style.color = red;

job done, super simple大功告成,超级简单

I have something different stuff for you which is easy and effective.我有一些不同的东西给你,它既简单又有效。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM