Javascript 使用 jQuery 选择和操作 CSS 伪元素,例如 ::before 和 ::after
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5041494/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Selecting and manipulating CSS pseudo-elements such as ::before and ::after using jQuery
提问by JBradwell
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 jQuery?
如何使用 jQuery 将 'foo' 更改为 'bar'?
采纳答案by Nick Kline
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';
}
回答by Blazemonger
You'd think this would be a simple question to answer, with everything else that jQuery can do. 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.
您会认为这将是一个简单的问题,jQuery 可以做任何其他事情。不幸的是,问题归结为一个技术问题:css :after 和 :before 规则不是 DOM 的一部分,因此不能使用 jQuery 的 DOM 方法进行更改。
There areways to manipulate these elements using JavaScript and/or CSS workarounds; which one you use depends on your exact requirements.
有一些方法可以使用 JavaScript 和/或 CSS 变通方法来操作这些元素;您使用哪一种取决于您的确切要求。
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. Place this "new" class later in your stylesheet to make sure it overrides:
在这种方法中,你已经在用不同的你的CSS创建一个类:after
或:before
样式。稍后将这个“新”类放在您的样式表中以确保它覆盖:
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; quickly alters multiple styles at once; enforces separation of concerns (isolating your CSS and JS from your HTML)
- Cons:CSS must be pre-written, so the content of
:before
or:after
isn't completely dynamic
- 优点:易于使用 jQuery 实现;一次快速改变多种风格;强制分离关注点(将 CSS 和 JS 与 HTML 隔离)
- 缺点: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. jQuery doesn't provide a convenient shortcut, but fortunately the JS isn't that complicated:
可以使用 JavaScript 将样式直接添加到文档样式表,包括:after
和:before
样式。jQuery 没有提供方便的快捷方式,但幸运的是 JS 并没有那么复杂:
var str = "bar";
document.styleSheets[0].addRule('p.special:before','content: "'+str+'";');
var str = "bar";
document.styleSheets[0].addRule('p.special:before', 'content: "' + str + '";');
p:before {
content: "foo";
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p class="special">This is a paragraph</p>
<p>This is another paragraph</p>
.addRule()
and the related .insertRule()
methodsare 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 readthe existing :after
or :before
stylesusing 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 时替换document.querySelector('p')
为$('p')[0]
,以获得更短的代码。
- 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 CSSto read a particular DOM attribute. (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:
您还可以在 CSS 中使用attr()
来读取特定的 DOM 属性。(如果浏览器支持:before
,它支持attr()
为好。)通过这种结合content:
在一些精心准备的CSS,我们可以改变的内容(而不是其他属性,像保证金或颜色):before
和: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
- 优点:不会创造无穷无尽的额外风格
- 缺点:
attr
在 CSS 中只能应用于内容字符串,不能应用于 URL 或 RGB 颜色
回答by BoltClock
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 anyJavaScript APIs for that matter, not even the Selectors API). This applies to any pseudo-elements whose styles you're trying to modify with a script, and not just ::before
and ::after
.
虽然它们通过 CSS 被浏览器渲染,就好像它们就像其他真正的 DOM 元素一样,但伪元素本身并不是 DOM 的一部分,因为伪元素,顾名思义,不是真正的元素,因此你不能直接使用 jQuery(或任何JavaScript API,甚至不是Selectors API)选择和操作它们。这适用于您尝试使用脚本修改其样式的任何伪元素,而不仅仅是::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 直接访问伪元素样式(think window.getComputedStyle()
),它不会被 jQuery Beyond公开.css()
,该方法也不支持伪元素。
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 answerfor 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
Manipulating the styles being applied to said pseudo-elements, by altering the document stylesheet, which is much more of a hack
将样式应用于一个或多个任意类的伪元素,然后在类之间切换(请参阅seucolega 的快速示例的答案)——这是惯用的方式,因为它使用简单的选择器(伪元素不是)来区分元素和元素状态,它们的使用方式
通过更改文档样式表来操纵应用于所述伪元素的样式,这更像是一种黑客行为
回答by Gustavo Sousa
You can't select pseudo elements in jQuery because they are not part of DOM. But you can add an specific class to the father element and control its pseudo elements in CSS.
您不能在 jQuery 中选择伪元素,因为它们不是 DOM 的一部分。但是你可以给父元素添加一个特定的类,并在 CSS 中控制它的伪元素。
In jQuery:
在 jQuery 中:
<script type="text/javascript">
$('span').addClass('change');
</script>
In CSS:
在 CSS 中:
span.change:after { content: 'bar' }
回答by Temani Afif
We can also rely on custom properties (aka CSS variables)in order to manipulate pseudo-element. We can read in the specificationthat:
我们还可以依靠自定义属性(又名 CSS 变量)来操作伪元素。我们可以在规范中读到:
Custom properties are ordinary properties, so they can be declared on any element, are resolved with the normal inheritanceand cascaderules, 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)
wherevalue
是默认值,也称为回退值。
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. The syntax of var() is:
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.
可以使用 var() 函数将自定义属性的值替换为另一个属性的值。var() 的语法是:
var() = var( <custom-property-name> [, <declaration-value> ]? )
该函数的第一个参数是要替换的自定义属性的名称。函数的第二个参数(如果提供)是回退值,当引用的自定义属性无效时,该值用作替代值。
And later:
然后:
To substitute a var() in a property's value:
- If the custom property named by the first argument to the
var()
function is animation-tainted, and thevar()
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.- If the value of the custom property named by the first argument to the
var()
function is anything but the initial value, replace thevar()
function by the value of the corresponding custom property.- Otherwise, if the
var()
function has a fallback value as its second argument, replace thevar()
function by the fallback value. If there are anyvar()
references in the fallback, substitute them as well.- Otherwise, the property containing the
var()
function is invalid at computed-value time.
要在属性值中替换 var():
- 如果由
var()
函数的第一个参数命名的自定义属性被动画污染,并且该var()
函数正在动画属性或其一个常用属性中使用,则将自定义属性视为具有此算法其余部分的初始值。- 如果由
var()
函数的第一个参数命名的自定义属性的值不是初始值,则将var()
函数替换为相应的自定义属性的值。- 否则,如果
var()
函数将回退值作为其第二个参数,则用var()
回退值替换该函数。如果var()
回退中有任何引用,也请替换它们。- 否则,包含该
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. The use of initial
can be helpful in case we want to reset a custom property to its default value.
如果我们不设置自定义属性或将其设置为initial
OR 它包含无效值,则将使用回退值。initial
如果我们想将自定义属性重置为其默认值,则使用可能会有所帮助。
Related
有关的
How to store inherit value inside a CSS custom property (aka CSS variables)?
如何在 CSS 自定义属性(又名 CSS 变量)中存储继承值?
CSS custom properties (variables) for box model
Please note that CSS variables might not be available in all browsers you consider relevant (e.g. IE 11): https://caniuse.com/#feat=css-variables
请注意,并非所有您认为相关的浏览器都提供 CSS 变量(例如 IE 11):https: //caniuse.com/#feat=css-variables
回答by Ivan Chaer
In the line of what Christian suggests, you could also do:
按照 Christian 的建议,您还可以执行以下操作:
$('head').append("<style>.span::after{ content:'bar' }</style>");
回答by Nedudi
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');
回答by Nedudi
IF you want to to manipulate the ::before or ::after sudo elements entirely through CSS, you could do it JS. See below;
如果你想完全通过 CSS 操作 ::before 或 ::after sudo 元素,你可以用 JS 来做。见下文;
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 完全按照您想要的样式进行设置。
回答by Christian
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');
回答by aimiliano
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>