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

JBr*_*ell 897 javascript css jquery jquery-selectors pseudo-element

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

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

.span::after{ content:'foo' }
Run Code Online (Sandbox Code Playgroud)

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

小智 676

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

在HTML中:

<span>foo</span>
Run Code Online (Sandbox Code Playgroud)

在jQuery中:

$('span').hover(function(){
    $(this).attr('data-content','bar');
});
Run Code Online (Sandbox Code Playgroud)

在CSS中:

span:after {
    content: attr(data-content) ' any other text you may want';
}
Run Code Online (Sandbox Code Playgroud)

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

在HTML中:

<span>foo</span>
Run Code Online (Sandbox Code Playgroud)

在jQuery中:

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

在CSS中:

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

  • `attr()`的+1,太糟糕了我无法将它与其他属性一起使用,而不是`content`.[演示](http://jsfiddle.net/p4jDn/4/) (92认同)
  • 那是因为现在没有浏览器在CSS2之外实现了`attr()`,而在CSS2本身中,`attr()`只是为`content`属性定义的. (27认同)
  • 更新了属性参考的链接:http://www.w3.org/TR/css3-values/#attr-notation (9认同)
  • @Johannes [如果浏览器支持`:before`,它支持CSS中的`attr()`(http://caniuse.com/#feat=css-gencontent) (5认同)
  • 您是否在规范中有一个链接,用于对`content`属性使用`attr`函数?我很惊讶我从来没有听说过这个...... (2认同)
  • 5 年后仍然[不支持](https://caniuse.com/#feat=css3-attr)。 (2认同)

Bla*_*ger 455

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

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


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

1)添加/删除预定的类

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

p:before {
    content: "foo";
}
p.special:before {
    content: "bar";
}
Run Code Online (Sandbox Code Playgroud)

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

$('p').on('click', function() {
    $(this).toggleClass('special');
});
Run Code Online (Sandbox Code Playgroud)

    $('p').on('click', function() {
      $(this).toggleClass('special');
    });
Run Code Online (Sandbox Code Playgroud)
p:before {
  content: "foo";
  color: red;
  cursor: pointer;
}
p.special:before {
  content: "bar";
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 优点:易于使用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+'";');
Run Code Online (Sandbox Code Playgroud)

var str = "bar";
document.styleSheets[0].addRule('p.special:before', 'content: "' + str + '";');
Run Code Online (Sandbox Code Playgroud)
p:before {
  content: "foo";
  color: red;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

.addRule().insertRule()今天相关的方法得到了很好的支持.

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

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

var str = "bar";
$('<style>p.special:before{content:"' + str + '"}</style>').appendTo('head');
Run Code Online (Sandbox Code Playgroud)
p:before {
  content: "foo";
  color: red;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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

var str = window.getComputedStyle(document.querySelector('p'), ':before') 
           .getPropertyValue('content');
Run Code Online (Sandbox Code Playgroud)

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

document.styleSheets[0].addRule('p.special:before', 'content: "' + str+str + '";');
Run Code Online (Sandbox Code Playgroud)
p:before {
    content:"foo";
    color: red;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

我们可以更换document.querySelector('p')$('p')[0]使用jQuery时,为略短代码.

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

3)改变不同的DOM属性

您还可以在CSS中使用attr()以读取特定的DOM属性.(如果浏览器支持:before,它支持attr()为好.)通过这种结合content:在一些精心准备的CSS,我们可以改变的内容(而不是其他属性,像保证金或颜色):before:after动态:

p:before {
    content: attr(data-before);
    color: red;
    cursor: pointer;
}
Run Code Online (Sandbox Code Playgroud)

JS:

$('p').on('click', function () {
    $(this).attr('data-before','bar');
});
Run Code Online (Sandbox Code Playgroud)

$('p').on('click', function () {
    $(this).attr('data-before','bar');
});
Run Code Online (Sandbox Code Playgroud)
p:before {
    content: attr(data-before);
    color: red;
    cursor: pointer;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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

var str = "bar";

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

$('p').on('click', function () {
    $(this).attr('data-before', str);
});
Run Code Online (Sandbox Code Playgroud)

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

$('p').on('click', function() {
  $(this).attr('data-before', str);
});
Run Code Online (Sandbox Code Playgroud)
p:before {
  content: "foo";
  color: red;
  cursor: pointer;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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

  • 我正试图在psedo之后动态设置glyphicon值(即,通过它们的十六进制值).content:element(例如,content:"\ e043";).它似乎不适合我,所以我假设它不适用于glyphicons的十六进制值? (2认同)

Bol*_*ock 155

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

您只能在运行时通过CSSOM(思考window.getComputedStyle())直接访问伪元素样式,这不是jQuery之外的公开,.css()也不支持伪元素的方法.

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

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

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


小智 77

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

在jQuery中:

<script type="text/javascript">
    $('span').addClass('change');
</script>
Run Code Online (Sandbox Code Playgroud)

在CSS中:

span.change:after { content: 'bar' }
Run Code Online (Sandbox Code Playgroud)


Tem*_*fif 38

我们还可以依赖自定义属性(也就是CSS变量)来操纵伪元素.我们可以在规范中读到:

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

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

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

1)使用内联样式:

.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="box"></div>
<div class="box black" ></div>
<div class="box blue"></div>
Run Code Online (Sandbox Code Playgroud)

3)使用javascript

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

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");
Run Code Online (Sandbox Code Playgroud)
.box:before {
  content:"I am a before element";
  color:var(--color, red);
  font-size:25px;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


它也可以用于复杂的值:

.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);
}
Run Code Online (Sandbox Code Playgroud)
<div class="box"></div>
Run Code Online (Sandbox Code Playgroud)

  • 这个答案是一个关于使用 CSS 变量与 JavaScript 关联和修改伪元素的深入教程。非常感谢您抽出时间并分享这一极其有价值的技术。 (3认同)
  • @connexo 就像任何好的和现代的功能一样..它不受支持并且无法工作 https://caniuse.com/#feat=css-variables (2认同)

Iva*_*aer 37

在基督教建议的方面,你也可以这样做:

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

  • 这里应该添加一个id属性,因此可以在添加新元素之前选择和删除元素.如果没有,可能会出现很多不必要的样式节点. (2认同)

Ned*_*udi 24

以下是访问方式:之后和:在样式属性之前,在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');
Run Code Online (Sandbox Code Playgroud)

  • 不可能制作**setProperty**?我试着不行. (3认同)
  • 这是如何访问但如何更改? (3认同)

小智 11

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

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

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

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


aim*_*ano 7

谢谢你们!我设法做我想做的事:D http://jsfiddle.net/Tfc9j/42/ 在这里看看

我想让外部 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>
Run Code Online (Sandbox Code Playgroud)


Chr*_*ian 6

一种有效但不是非常有效的方法是将规则添加到具有新内容的文档中,并使用类对其进行引用。根据需要的内容,类可能需要为内容中的每个值提供唯一的ID。

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


小智 5

这是HTML:

<div class="icon">
  <span class="play">
    ::before
  </span>
</div>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


Ale*_*tau 5

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

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);
Run Code Online (Sandbox Code Playgroud)
.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%;
}
Run Code Online (Sandbox Code Playgroud)
<span id="arrow" class="arrow"></span>
Run Code Online (Sandbox Code Playgroud)

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


Ada*_*gde 5

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

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>"); 
}
}
}
Run Code Online (Sandbox Code Playgroud)

这当前添加了一个 / 或附加了一个 Style 元素,其中包含您的必要属性,该属性将影响目标元素的伪元素之后。

这可以用作

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

css.before( ... ); // to affect the before pseudo element.
Run Code Online (Sandbox Code Playgroud)

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

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

所以做你自己的实验这个和其他的!

问候 - 阿达什赫格德。


Orl*_*ter 5

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

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

setPseudoElContent('.class::after', 'Hello World!');
Run Code Online (Sandbox Code Playgroud)

或利用 ES6 特性:

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

setPseudoElContent('.class::after', 'Hello World!');
Run Code Online (Sandbox Code Playgroud)