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

使用javascript(或jQuery)选择和操作CSS伪元素,如::before和::after,javascript,jquery,css,jquery-selectors,pseudo-element,Javascript,Jquery,Css,Jquery Selectors,Pseudo Element,是否有任何方法可以使用jQuery选择/操作CSS伪元素,例如::before和::after以及带有一个分号的旧版本 例如,我的样式表有以下规则: .span::在{content:'foo'}之后 如何使用vanilla JS或jQuery将“foo”更改为“bar”?虽然浏览器通过CSS呈现这些元素,就好像它们是其他真实的DOM元素一样,但伪元素本身并不是DOM的一部分,因为顾名思义,伪元素不是真实的元素,因此,您不能直接使用jQuery或任何JavaScriptAPI来选择和操作它们,甚

是否有任何方法可以使用jQuery选择/操作CSS伪元素,例如::before和::after以及带有一个分号的旧版本

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

.span::在{content:'foo'}之后
如何使用vanilla JS或jQuery将“foo”更改为“bar”?

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

您只能在运行时通过CSSOM think window.getComputedStyle直接访问伪元素样式,jQuery beyond.css也不支持伪元素,它不会公开

但是,您始终可以找到其他解决方法,例如:

将样式应用于一个或多个任意类的伪元素,然后在类之间切换查看一个快速示例-这是惯用的方法,因为它使用了简单的选择器,这些伪元素不区分元素和元素状态,它们的使用方式是这样的

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


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

在jQuery中:

<script type="text/javascript">
    $('span').addClass('change');
</script>
$('span').hover(function(){
    $(this).attr('data-content','bar');
});
$('span').hover(function(){
    $(this).addClass('change').attr('data-content','bar');
});

您还可以将内容传递给带有数据属性的伪元素,然后使用jQuery来处理:

在HTML中:

<span>foo</span>
<span>foo</span>
在CSS中:

跨度:之后{ 内容:attrdata内容“您可能需要的任何其他文本”; } 如果您想阻止“其他文本”出现,可以将其与seucolega的解决方案结合起来,如下所示:

<div id="something">Test</div>
<style id="pseudo"></style>
在HTML中:

<span>foo</span>
<span>foo</span>
在CSS中:

改变:之后{ 内容:attrdata内容“您可能需要的任何其他文本”; }
一种有效但不是很有效的方法是向文档中添加一个具有新内容的规则,并使用类引用它。根据需要,该类可能需要内容中每个值的唯一id

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

按照Christian的建议,你也可以:

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

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

有一些方法可以使用JavaScript和/或CSS变通方法来操作这些元素;您使用哪一种取决于您的具体要求

我将从被广泛认为是最好的方法开始:

1添加/删除预定类别 在这种方法中,您已经使用不同的:after或:before样式在CSS中创建了一个类。稍后将此新类放置在样式表中,以确保其覆盖:

p:before {
    content: "foo";
}
p.special:before {
    content: "bar";
}
然后,您可以使用jQuery或vanilla JavaScript轻松添加或删除此类:

$('p').on('click', function() {
    $(this).toggleClass('special');
});
$'p'。单击,函数{ $this.toggleClass'special'; }; p:以前{ 内容:富,; 颜色:红色; 光标:指针; } p、 特别:以前{ 内容:酒吧; } 这是一段

这是另一段。

以下是HTML:

<div class="icon">
  <span class="play">
    ::before
  </span>
</div>
“之前”的计算样式为内容:验证以观看

下面是我的两行jQuery,它使用的思想是添加一个额外的类来专门引用这个元素,然后附加一个带有!用于更改sudo元素内容值的CSS的重要标记:

$span.play:eq0.addClass'G'


$'body'.append.G:在{content:'NewText'!important}之前

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

jQuery('head').append('<style id="mystyle" type="text/css"> /* your styles here */ </style>');
请注意元素是如何具有ID的,如果样式发生动态更改,可以使用该ID删除元素并再次附加到元素

通过这种方式,在JS的帮助下,您的元素通过CSS完全符合您的风格。

谢谢大家! 我设法做到了我想要的:D 来看看

我想让外部div的不透明度与内部div的不透明度不同,只需单击此处即可更改; 谢谢


以下是访问css中定义的:after和:before样式属性的方法:

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

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

var=false; //启用颜色切换 设置间隔函数{ var color=切换为“红色”:“暗色”; var元素=document.getElementById'arrow'; 元素styl e、 背景颜色=颜色; //管理伪元素的css //使用继承。 element.style.borderLeftColor=颜色; 切换=!转换; }, 1000; .阿罗{ /*设置虚拟属性*/ 左边框颜色:红色; 背景色:红色; 宽度:1米; 高度:1米; 显示:内联块; 位置:相对位置; } .阿罗:之后{ 边框顶部:1米实心透明; 右边框:1em实心透明; 边框底部:1米实心透明; 左边框:1米实心透明; /*继承财产*/ 边框左颜色:继承; 内容:; 宽度:0; 身高:0; 位置:绝对位置; 左:100%; 前-50%; }
这是不实际的,因为我写这篇文章不是为了现实世界的使用,只是为了给你们一个可以实现的例子

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

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

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

所以,你自己做实验,这和其他


问候-阿达斯·赫格德

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


这里有很多答案,但没有任何答案可以帮助操纵:before或:after的css,甚至不是公认的答案

下面是我打算怎么做。假设您的HTML如下所示:

<div id="something">Test</div>
<style id="pseudo"></style>
请注意,我还在元素本身中设置了content属性,以便以后可以轻松地将其取出。 现在有一个按钮点击,你想把:before的颜色改为绿色,字体大小改为30px。您可以通过以下方式实现这一点:

<button id="changeBefore">Change</button>
<script>
    $('#changeBefore').click(function(){
        $('#something').addClass('activeS');
    });
</script>
<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>
在某些类上定义具有所需样式的css。活动:

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

<button id="changeBefore">Change</button>
<script>
    $('#changeBefore').click(function(){
        $('#something').addClass('activeS');
    });
</script>
<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>
最终,如果您希望动态更改:在jQuery创建内容之前,您可以通过以下方式实现:

<button id="changeBefore">Change</button>
<script>
    $('#changeBefore').click(function(){
        $('#something').addClass('activeS');
    });
</script>
<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内容变成'22',这是一个动态值

我希望这会有帮助 $'.span'.attr'data-txt',foo'; $'.span'。单击函数{ $this.attr'data-txt',任何其他文本; } .span{ } .span:在{ 内容:ATRTDATA txt; }
你可以使用我的插件来达到这个目的

JQuery:

作用{ $.pseudoElements={ 长度:0 }; var setPseudoElement=函数参数{ 如果typeof parameters.argument==='object'| | parameters.argument!==未定义&¶meters.property!==未定义{ 对于parameters.elements.get的var元素{ 如果!element.pseudoElements element.pseudoElements={ 样式表:null, 之前:{ 索引:null, 属性:null }, 之后:{ 索引:null, 属性:null }, id:null }; 变量选择器=函数{ 如果element.pseudoElements.id!==null{ 如果numberRelation.getAttribute'data-pe-id'!==element.pseudoElements.id element.setAttribute'data-pe-id',element.pseudoElements.id; 返回“[data pe id=”+element.pseudoElements.id+”]::”+parameters.pseudoElement; }否则{ 变量id=$.pseudoElements.length; $.pseudoElements.length++ element.pseudoElements.id=id; 元素。setAttribute'data-pe-id',id; 返回“[data pe id=”+id+”]::”+parameters.pseudoElement; }; }; if!element.pseudoElements.styleSheet{ if document.styleSheets[0]{ element.pseudoElements.styleSheet=document.styleSheets[0]; }否则{ var styleSheet=document.createElement'style'; document.head.appendChildstyleSheet; element.pseudoElements.styleSheet=styleSheet.sheet; }; }; if element.pseudoElements[parameters.pseudoElement].properties&&element.pseudoElements[parameters.pseudoElement].index{ element.pseudoElements.styleSheet.deleteRuleelement.pseudoElements[parameters.pseudoElement].index; }; 如果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属性=; 对于parameters.argument中的var属性{ 如果参数类型为.ar gument[属性]=“函数” element.pseudoElements[parameters.pseudoElement].properties[property]=parameters.argument[property]; 其他的 element.pseudoElements[parameters.pseudoElement].properties[property]=parameters.argument[property]; }; 用于element.pseudoElements[parameters.pseudoElement].properties中的var属性{ properties+=property+':'+element.pseudoElements[parameters.pseudoElement].properties[property]+'!important;'; }; element.pseudoElements.styleSheet.addRuleselector,属性,元素.pseudoElements[参数.pseudoElement].索引; }如果参数为else.argument!==未定义的¶meters.property!==未定义{ 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={}; }; 如果typeof parameters.property==“函数” element.pseudoElements[parameters.pseudoElement].properties[parameters.argument]=parameters.property; 其他的 element.pseudoElements[parameters.pseudoElement].properties[parameters.argument]=parameters.property; var属性=; 用于element.pseudoElements[parameters.pseudoElement].properties中的var属性{ properties+=property+':'+element.pseudoElements[parameters.pseudoElement].properties[property]+'!important;'; }; element.pseudoElements.styleSheet.addRuleselector,属性,元素.pseudoElements[参数.pseudoElement].索引; }; }; 返回$parameters.elements; }如果参数为else.argument!==未定义&¶meters.property==未定义{ var element=$parameters.elements.get0; var windowStyle=window.getComputedStyle 元素“::”+参数。伪元素 .getPropertyValueparameters.argument; if-element.pseudoElements{ 返回$parameters.elements.get0.pseudoElements[parameters.pseudoElement].properties[parameters.argument]| | windowStyle; }否则{ 返回windowStyle | | null; }; }否则{ 控制台。错误“无效值!”; 返回false; }; }; $.fn.cssBefore=函数参数,属性{ 返回集合伪元素{ 要素:这,, 伪元素:'之前', 论点:论点, 物业:物业 }; }; $.fn.cssAfter=函数参数,属性{ 返回集合伪元素{ 要素:这,, 伪元素:“在”, 论点:论点, 物业:物业 }; }; }; $function{ $'.element'.cssBefore'content','newbefore!'; }; .元素{ 宽度:480px; 保证金:0自动; 边框:2倍纯红; } .element::之前{ 内容:“以前老了!”; }
其他人评论说,在head元素中附加一个完整的样式元素,如果只执行一次,这也不错,但是如果需要多次重置它,那么最终将得到大量样式元素。为了防止这种情况,我在head中创建了一个带有id的空白样式元素,并将其innerHTML替换为如下所示:

<div id="something">Test</div>
<style id="pseudo"></style>
现在,在我的例子中,我需要它来根据另一个元素的高度设置一个before元素的高度,它将在调整大小时更改,因此使用它,我可以在每次调整窗口大小时运行setHeight,它将正确替换

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

我们也可以依靠它来操纵伪元素。我们可以在报纸上看到:

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

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

1使用内联样式:

.盒子:以前{ 内容:var内容,我是一个before元素; 颜色:var颜色,红色; 字体大小:25px; }
我总是添加我自己的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!');

我使用CSS中定义的变量来修改:after,这同样适用于:before伪元素,特别是要更改由.slide middle out:hover:after定义的样式化锚定的背景颜色值,以及下面使用JavaScript/jQuery生成随机颜色的另一个锚定引用的内容值:

HTML

JS/jQuery

我已经创建了一个jQuery pl ugin添加css伪规则,如对特定元素使用.css

插件代码和测试用例是 用例作为简单的css图像弹出窗口 用法:

$‘身体’ .css{ 背景颜色:“白色” } .cssPseudo'after'{ 内容:“attrtitle,您应该尝试将图片悬停,然后单击它。”, 位置:'绝对', 上:20,左:20 } .cssPseudo'悬停:在''{ 内容:“现在将图片悬停,然后单击它!” };
我有一些不同的东西给你,简单有效

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

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

在HTML中添加一个属性,可以使用带有setAttribute的javascript对其进行操作

<div 
 id="inputBoxParent" 
 count="0">
      ...
</div>
CSS-在伪元素中将内容添加为attributeName

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

const inputBoxParent=document.getElementByIdinputBoxParent; const handleOnChange=值=>{ inputBoxParent.setAttribute'count',value.length } .输入框容器{ 位置:相对位置; 宽度:200px; } .输入框容器::之后{ 位置:绝对位置; 底部:8px; 右:10px; 高度:10px; 宽度:20px; 内容:计数; } 在框内键入一些文本,然后单击外部以查看结果,即伪元素内容更改

规范中是否有针对content属性使用attr函数的链接?我很惊讶,我从来没有听说过这个…+1的attr,太糟糕了,我不能使用它与其他属性以外的内容。这是因为现有的浏览器还没有在CSS2之外实现attr,而在CSS2本身中,attr只是为content属性定义的。更新了属性引用的链接:@Johannes我做了一些应该适合你的东西:我讨厌stackoverflow上的评论,我将在评论者问你为什么不以完全相反的方式做呢?,但是:在某一点上,人们应该意识到代码设计问题,并用一个span或其他东西替换那个伪元素。我想你们知道我指的是什么。公认的答案非常好。但是如果你想达到以下任何一点,答案是行不通的:1。通过JS更改:before的样式。2.更改:before by JS的内容如果需要,请查看我的答案。请参阅@Learner Now所有这些都有一个答案:我正在尝试动态设置glyphicon值,即通过::after psedo中的十六进制值。内容:元素,例如内容:\e043;。它似乎对我不起作用,所以我假设它对glyphicons的十六进制值也不起作用?@user2101068你应该把它作为一个新问题发布。我必须查看您正在使用的所有代码。Blazemonger,谢谢您的快速回复。不幸的是,代码太多了,要剪掉相关代码需要花费相当多的努力。我已经花了12个多小时试着完成这项工作,这是我最后的努力。我需要减少损失。我希望您在使用代码片段之前的第3部分中描述的技术时,能够验证我的假设re:hex值。我可以在内容元素中插入十六进制字符串,但它显示glyphicon十六进制值的文本,而不是实际的glyphicon。没有看到所有代码的印象?@user2101068不使用十六进制字符串;而是将实际的Unicode字符复制并粘贴到HTML属性中。关于解决方案2和3.实际上,如果使用:document.styleSheets[0]。insertRulerule,index,则可以防止样式表过度增长,然后使用此索引可以在不需要时删除规则:document.styleSheets[0]。deleteRuleindexHere应添加一个id属性,以便在添加新的元素之前可以选择并删除该元素。如果没有,可能会出现许多不必要的样式节点。很遗憾,您的示例不起作用,但这就成功了。const setPseudoElContent=selector,value=>{const style=document.createElement'style';style.innerHTML=${selector}{${value};};document.head.appendChildstyle;}不要尝试追加,最好使用html。注意:在这里,每次处理一次单击时,都要向头部追加一个样式标记。在添加新代码之前,我会编写一种删除旧代码的方法。@akalata是的,该代码需要jQuery 3.x版。。我用jQuery添加了更多的细节和另一种选择;这在IE 11中会有怎样的表现?@connexo喜欢任何好的和现代的功能。。它不受支持,也不适用于Ofc。我知道,由于IE11仍然非常相关,所以我在回答的介绍部分错过了这条信息。这个回答是一个关于使用CSS变量使用JavaScript关联和修改伪元素的深入教程。非常感谢您的时间和分享这些非常宝贵的技术。除了在内容上,对attr的支持非常少。您可以在caniuse.com上查询:根变量和css变量的支持更好,但由于对它的支持是非常新的,所以还没有广泛传播。也可以在caniuse.com上查看对它的支持
<div 
 id="inputBoxParent" 
 count="0">
      ...
</div>
inputBoxParent.setAttribute('count', value.length)
.input-box-container::after{
  content: attr(count);
}