ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

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

我做了一些适合你的东西:gist.github.com/yckart/5563717
我讨厌我要写的关于stackoverflow的评论(评论者问你为什么不以完全相反的方式做呢?),但是:在某些时候应该意识到代码设计问题并用一个替换那个伪元素跨度什么的。我想你知道我指的是什么。
接受的答案非常好。虽然如果你试图达到以下任何一点,答案将不起作用: 1. 通过 JS 更改 :before 的样式。 2.通过JS更改:之前的内容如果需要,请参阅我的回答。
@Learner 现在所有这些都有一个答案:stackoverflow.com/a/49618941/8620333

E
Eric

您还可以使用 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';
}

您是否在规范中有针对 content 属性使用该 attr 函数的链接?我很惊讶我从来没有听说过这个...
attr() +1,太糟糕了,我无法将它与 content 以外的其他属性一起使用。 Demo
这是因为目前还没有浏览器在 CSS2 之外实现 attr(),而在 CSS2 本身中,attr() 只为 content 属性定义。
属性参考的更新链接:w3.org/TR/css3-values/#attr-notation
B
Blazemonger

你会认为这将是一个简单的问题,jQuery 可以做的所有其他事情都可以回答。不幸的是,问题归结为一个技术问题:css :after 和 :before 规则不是 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:之前{内容:“foo”;红色;光标:指针; } p.special:before { 内容:“酒吧”; }

这是一个段落。

< 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 = "酒吧"; document.styleSheets[0].addRule('p.special:before', 'content: "' + str + '";'); p:之前{内容:“foo”;红色; }

这是一段< /p>

这是另一段

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

作为一种变体,您还可以使用 jQuery 将全新的样式表添加到文档中,但必要的代码并不简洁:

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

var str = "酒吧"; $('').appendTo('head'); p:之前{内容:“foo”;红色; }

这是一段< /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');控制台.log(str); document.styleSheets[0].addRule('p.special:before', 'content: "' + str+str + '";'); p:之前{内容:“foo”;红色; }

这是一段< /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 { 内容: attr(data-before);红色;光标:指针; }

这是一个段落。

< 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 = "酒吧"; document.styleSheets[0].addRule('p:before', 'content: attr(data-before) !important;'); $('p').on('click', function() { $(this).attr('data-before', str); }); p:之前{内容:“foo”;红色;光标:指针; }

这是一个段落。

< p>这是另一段。

优点:不会创造无穷无尽的额外样式

缺点:CSS 中的 attr 只能应用于内容字符串,不能应用于 URL 或 RGB 颜色


我正在尝试在 ::after psedo 中动态设置 glyphicon 值(即,通过它们的十六进制值)。内容:元素(例如,内容:“\e043”;)。它似乎对我不起作用,所以我假设它也不适用于字形图标的十六进制值?
@user2101068 你应该把它作为一个新问题发布。我必须查看您正在使用的所有代码。
Blazemonger,感谢您的快速回复..不幸的是,有相当多的代码,剪掉相关代码需要相当多的努力。我已经花了 12 多个小时试图完成这项工作,这是我最后一次努力让它工作。我需要减少损失。我希望您能够在使用上面#3 中描述的技术时验证我的假设:十六进制值(在代码片段之前)。我可以在内容元素中插入十六进制字符串,但它显示的是 glyphicon hex 值的文本,而不是实际的 glyphicon。没有看到所有代码的印象?
@user2101068 不要使用十六进制字符串;而是将实际的 Unicode 字符复制并粘贴到 HTML 属性中。 jsfiddle.net/mblase75/Lcsjkc5y
关于解决方案 2. & 3. 实际上,如果您使用:document.styleSheets[0].insertRule(rule, index),您可以防止样式表(过度)增长,然后使用此索引您可以在不需要时删除规则:document.styleSheets[0].insertRule(rule, index) styleSheets[0].deleteRule(index)
B
BoltClock

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

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

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

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

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


i
isherwood

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

EXAMPLE

在 jQuery 中:

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

在 CSS 中:

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

T
Temani Afif

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

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

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

1)使用内联样式:

.box:before { content:var(--content,"我是前元素");颜色:var(--颜色,红色);字体大小:25px; }

2) 使用 CSS 和类

.box:before { content:var(--content,"我是前元素");颜色:var(--颜色,红色);字体大小:25px; } .blue { --color:blue; --content:'我是蓝色元素'; } .black { --color:black; }

3) 使用 javascript

document.querySelectorAll('.box')[0].style.setProperty("--color", "blue"); document.querySelectorAll('.box')[1].style.setProperty("--content", "'我是另一个元素'"); .box:before { content:var(--content,"我是前元素");颜色:var(--颜色,红色);字体大小:25px; }

4) 使用 jQuery

$('.box').eq(0).css("--color", "blue"); /* 具有自定义属性的 css() 函数仅适用于 jQuery vesion >= 3.x 旧版本我们可以使用样式属性来设置值。如果您已经定义了内联样式,请注意! */ $('.box').eq(1).attr("style","--color:#f0f"); .box:before { content:"我是前元素";颜色:var(--颜色,红色);字体大小:25px; }

它也可以用于复杂值:

.box { --c:"内容"; --b:线性梯度(红色,蓝色); --s:20像素; --p:0 15px; } .box:before { 内容:var(--c);背景:var(--b);颜色:#fff;字体大小: calc(2 * var(--s) + 5px);填充:var(--p); }

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

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

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

var() = var( [, ]? )

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

然后:

要在属性值中替换 var():

如果由 var() 函数的第一个参数命名的自定义属性被动画污染,并且 var() 函数正在用于动画属性或它的一个普通属性,则将自定义属性视为具有其初始值该算法的其余部分。如果 var() 函数的第一个参数命名的自定义属性的值不是初始值,则将 var() 函数替换为相应自定义属性的值。否则,如果 var() 函数有一个备用值作为其第二个参数,则将 var() 函数替换为备用值。如果后备中有任何 var() 引用,也请替换它们。否则,包含 var() 函数的属性在计算值时无效。

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

有关的

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

CSS custom properties (variables) for box model


@akalata 是的,代码需要 jQuery 版本 3.x .. 我添加了更多细节和 jQuery 的另一个替代方案;)
这将如何在 IE 11 中执行?
@connexo 喜欢任何优秀的现代功能 .. 它不受支持且无法使用caniuse.com/#feat=css-variables
Ofc 我知道,并且由于 IE 11 仍然非常相关,因此我在您答案的介绍部分中错过了那条信息。
这个答案是关于使用 CSS 变量与 JavaScript 关联和修改伪元素的深入教程。非常感谢您抽出宝贵时间分享这项极其宝贵的技术。
I
Ivan Chaer

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

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

这里应该添加一个 id 属性,以便在添加新元素之前可以选择和删除元素。如果没有,可能会出现很多不必要的样式节点。
不幸的是,您的样品没有用,但它做到了。 const setPseudoElContent = (选择器,值) => { const style = document.createElement('style');样式.innerHTML = ${selector} {${value}; }; document.head.appendChild(style); }
N
Nedudi

这是访问 :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');

这是如何访问但如何更改?
佚名

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

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

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

这样,在 JS 的帮助下,您的元素就可以通过 CSS 实现您想要的样式。


C
Christian

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

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

a
aimiliano

谢谢你们!我设法做我想做的事: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>

不尝试 append,使用 html 最好防止
注意:每次处理这些点击时,您都会在头部附加一个样式标签。在添加新的之前,我会编写一种删除旧的方法。
C
Coyote

这是HTML:

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

“之前”的计算样式为 content: "VERIFY TO WATCH";

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

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

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


A
Alexander Shutau

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

变种切换=假; // 启用颜色切换 setInterval(function () { var color = connected ? 'red' : 'darkred'; var element = document.getElementById('arrow'); element.style.backgroundColor = color; // 管理伪元素css // 使用继承 element.style.borderLeftColor = color;switched = !switched; }, 1000); .arrow { /* 设置虚构属性 */border-left-color:red;背景颜色:红色;宽度:1em;高度:1em;显示:内联块;位置:相对; } .arrow:after {border-top:1em 实心透明; border-right:1em 实心透明; border-bottom:1em 实心透明;左边框:1em 实心透明; /* 继承属性 */ border-left-color:inherit;内容:””;宽度:0;高度:0;位置:绝对;左:100%;最高:-50%; }

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


A
Adarsh Hegde

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

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

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

这可以用作

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

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

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

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

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

问候 - Adarsh Hegde。


O
Orlandster

我总是添加自己的 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!');

G
Gaurav Aggarwal

只需将 style 附加到头部,为什么还要添加类或属性

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

A
Abhay Maurya

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

这是我建议的方法。让我们假设你的 HTML 是这样的:

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

然后你在 CSS 中设置它的 :before 并像这样设计它:

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

请注意,我还在元素本身中设置了 content 属性,以便您以后可以轻松地将其取出。现在点击 button,您希望将 :before 的颜色更改为绿色,并将其字体大小更改为 30 像素。您可以按如下方式实现:

在某些类 .activeS 上定义具有所需样式的 css:

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

现在您可以通过将类添加到您的 :before 元素来更改 :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”按钮会将 #something:before 内容更改为动态值“22”。

我希望它有帮助


Y
Yuri

您可以为此目的使用我的插件。

查询:

(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) { i f (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 属性 = ''; for (var property in parameters.argument) { if (typeof parameters.argument[property] === 'function') element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property]();否则 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();否则 element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property; var 属性 = ''; 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); }; };返回 $(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] ||窗口样式; } else { 返回窗口样式 ||无效的; }; } else { console.error('无效值!');返回假; }; }; $.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 { 宽度:480px;边距:0 自动;边框:2px 纯红色; } .element::before { 内容:'以前的旧!'; }

应该指定值,就像在 jQuery.css 的普通函数中一样

此外,还可以获取伪元素参数的值,就像在jQuery.css的普通函数中一样:

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

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); 返回'[data-pe--id="' + id + '"]:: ' + 参数.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);参数.element.pseudoElements.styleSheet = styleSheet.sheet; }; };如果(参数。指数); }; 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 ||参数.element.pseudoElements.styleSheet.cssRules.length ||参数.element.pseudoElements.styleSheet.length; parameters.element.pseudoElements[parameters.pseudoElement].index = newIndex; parameters.element.pseudoElements[parameters.pseudoElement].properties = parameters.argument; }; var 属性 = ''; 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属性。 '; }; 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 ||参数.element.pseudoElements.styleSheet.cssRules.length ||参数.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();否则参数.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property; var 属性 = ''; for(参数中的var属性。 '; }; 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] ||窗口样式; } else { 返回窗口样式 ||无效的; }; } else { console.error('无效值!');返回假; }; }; 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 { 宽度:480px;边距:0 自动;边框:2px 纯红色; } .element::before { 内容:'以前的旧!'; }

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


B
BananaAcid

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

插件代码和测试用例在这里

用例作为简单的 css 图像弹出在这里

用法:

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


T
Tariq Javed

$('.span').attr('data-txt', 'foo'); $('.span').click(function () { $(this).attr('data-txt',"any other text"); }) .span{ } .span:after{ content: attr(data -文本); }


T
Tony

其他人评论了用完整的样式元素附加到 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()

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

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


R
Riccardo Volpe

我利用 CSS:root 中定义的变量来修改 :after(同样适用于 :beforepseudo-element,特别是更改 background-color 的值由 .sliding-middle-out:hover:after 定义的样式化 anchor 和以下 demo 中另一个 anchor (#reference) 的 content 值,它使用 JavaScript/jQuery 生成随机颜色:

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

: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

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

除了 content 之外,对 attr() 的支持非常稀缺。你可以检查 caniuse.com 。 :root 和 css-variables 支持更好,但由于对它的支持是相当新的,因此尚未普及。 (也可以在 caniuse.com 上查看对它的支持)
s
s3c

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

在我的情况下,附加到 adivbutton 元素的图标需要这样做,它们的工作方式与 <i class="icon-class"></i> 有点不同,因为它们没有 icon-class 类。但是添加 class="icon-class" 破坏了样式。

相反,我为它们添加了一个 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)
        }
    }

代码解释:

选择具有指定属性的所有元素(数据图标)

遍历它们

随机生成一个以 fake- 开头的类名,后跟一个随机的字母数字字符串

获取数据图标属性的值

将随机生成的类添加到元素

为 ::before 伪元素创建样式,将内容设置为先前获取的值

在 HTML 元素的末尾添加样式


S
Sumit

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

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

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

用js更新

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

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

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

你完成了!

常量 inputBoxParent = document.getElementById("inputBoxParent"); const handleOnChange = (value) => { inputBoxParent.setAttribute('count', value.length) } .input-box-container { position: relative;宽度:200px; } .input-box-container::after{ 位置:绝对;底部:8px;右:10px;高度:10px;宽度:20px;内容:attr(计数); }

在框内输入一些文本,然后在外面点击查看resule,即伪元素内容变化


C
Coding_snakeZ

我有一些不同的东西给你,它既简单又有效。

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

A
Alex Stephens

只需将伪之前或之后设置为具有继承样式,然后使用javascript设置父样式。

因此,例如,我想更改 :before 的颜色样式,然后设置:

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

然后我只需使用 javascript 更改 .my-style 元素的颜色样式:

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

大功告成,超级简单


嗯,一个完全可以接受的简单答案,无缘无故被否决,没有评论。这个网站在慢慢退化???