有什么方法可以使用 jQuery选择/操作 CSS 伪元素,例如::before
和::after
(以及带有一个分号的旧版本)?
例如,我的样式表具有以下规则:
.span::after{ content:'foo' }
如何使用 vanilla JS 或 jQuery 将 'foo' 更改为 'bar'?
有什么方法可以使用 jQuery选择/操作 CSS 伪元素,例如::before
和::after
(以及带有一个分号的旧版本)?
例如,我的样式表具有以下规则:
.span::after{ content:'foo' }
如何使用 vanilla JS 或 jQuery 将 'foo' 更改为 'bar'?
您还可以将内容传递给具有 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';
}
您会认为这将是一个简单的问题,jQuery 可以做任何其他事情。不幸的是,问题归结为一个技术问题:css :after 和 :before 规则不是 DOM 的一部分,因此不能使用 jQuery 的 DOM 方法进行更改。
有一些方法可以使用 JavaScript 和/或 CSS 变通方法来操作这些元素;您使用哪一种取决于您的确切要求。
我将从广泛认为的“最佳”方法开始:
在这种方法中,你已经在用不同的你的CSS创建一个类:after
或:before
样式。稍后将这个“新”类放在您的样式表中以确保它覆盖:
p:before {
content: "foo";
}
p.special:before {
content: "bar";
}
然后,您可以使用 jQuery(或 vanilla JavaScript)轻松添加或删除此类:
$('p').on('click', function() {
$(this).toggleClass('special');
});
:before
或的内容:after
不是完全动态的可以使用 JavaScript 将样式直接添加到文档样式表,包括:after
和:before
样式。jQuery 没有提供方便的快捷方式,但幸运的是 JS 并没有那么复杂:
var str = "bar";
document.styleSheets[0].addRule('p.special:before','content: "'+str+'";');
.addRule()
并且相关.insertRule()
方法在今天得到了相当好的支持。
作为一种变体,您还可以使用 jQuery 向文档中添加一个全新的样式表,但所需的代码并不简洁:
var str = "bar";
$('<style>p.special:before{content:"'+str+'"}</style>').appendTo('head');
如果我们谈论的是“操作”值,而不仅仅是添加到它们,我们还可以:after
:before
使用不同的方法读取现有的或样式:
var str = window.getComputedStyle(document.querySelector('p'), ':before')
.getPropertyValue('content');
我们可以在使用 jQuery 时替换document.querySelector('p')
为$('p')[0]
,以获得稍短的代码。
您还可以在 CSS 中使用attr()
来读取特定的 DOM 属性。(如果浏览器支持:before
,它支持attr()
为好。)通过这种结合content:
在一些精心准备的CSS,我们可以改变的内容(而不是其他属性,像保证金或颜色):before
和:after
动态:
p:before {
content: attr(data-before);
color: red;
cursor: pointer;
}
JS:
$('p').on('click', function () {
$(this).attr('data-before','bar');
});
如果 CSS 不能提前准备,这可以与第二种技术结合使用:
var str = "bar";
document.styleSheets[0].addRule('p:before', 'content: attr(data-before);');
$('p').on('click', function () {
$(this).attr('data-before', str);
});
attr
在 CSS 中只能应用于内容字符串,不能应用于 URL 或 RGB 颜色虽然它们通过 CSS 被浏览器渲染,就好像它们就像其他真正的 DOM 元素一样,但伪元素本身并不是 DOM 的一部分,因为伪元素,顾名思义,不是真正的元素,因此你不能直接使用 jQuery(或任何JavaScript API,甚至不是Selectors API)选择和操作它们。这适用于您尝试使用脚本修改其样式的任何伪元素,而不仅仅是::before
和::after
。
您只能在运行时通过 CSSOM (think window.getComputedStyle()
)直接访问伪元素样式,它不会被 jQuery Beyond公开.css()
,该方法也不支持伪元素。
不过,您总是可以找到其他方法来解决它,例如:
将样式应用于一个或多个任意类的伪元素,然后在类之间切换(请参阅seucolega 的快速示例的答案)——这是惯用的方式,因为它使用简单的选择器(伪元素不是)来区分元素和元素状态,它们的使用方式
通过更改文档样式表来操纵应用于所述伪元素的样式,这更像是一种黑客行为
您不能在 jQuery 中选择伪元素,因为它们不是 DOM 的一部分。但是你可以给父元素添加一个特定的类,并在 CSS 中控制它的伪元素。
在 jQuery 中:
<script type="text/javascript">
$('span').addClass('change');
</script>
在 CSS 中:
span.change:after { content: 'bar' }
我们还可以依靠自定义属性(又名 CSS 变量)来操作伪元素。我们可以在规范中读到:
自定义属性是普通属性,所以可以在任何元素上声明,用普通的继承和级联 规则解析,可以用@media等条件规则设置条件,可以在HTML的样式属性中使用,可以读取或设置使用 CSSOM等。
考虑到这一点,想法是在元素内定义自定义属性,伪元素将简单地继承它;因此我们可以很容易地修改它。
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) 使用 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)使用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)使用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>
它也可以用于复数值:
.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>
您可能会注意到我正在考虑语法var(--c,value)
wherevalue
是默认值,也称为回退值。
从相同的规范我们可以读到:
可以使用 var() 函数将自定义属性的值替换为另一个属性的值。var() 的语法是:
var() = var( <custom-property-name> [, <declaration-value> ]? )
该函数的第一个参数是要替换的自定义属性的名称。函数的第二个参数(如果提供)是回退值,当引用的自定义属性无效时,该值用作替代值。
然后:
要在属性值中替换 var():
- 如果由
var()
函数的第一个参数命名的自定义属性被动画污染,并且该var()
函数正在动画属性或其一个常用属性中使用,则将该自定义属性视为具有此算法其余部分的初始值。- 如果由
var()
函数的第一个参数命名的自定义属性的值不是初始值,则将var()
函数替换为相应的自定义属性的值。- 否则,如果
var()
函数将回退值作为其第二个参数,则用var()
回退值替换该函数。如果var()
回退中有任何引用,也请替换它们。- 否则,包含该
var()
函数的属性在计算值时无效。
如果我们不设置自定义属性或将其设置为initial
OR 它包含无效值,则将使用回退值。initial
如果我们想将自定义属性重置为其默认值,则使用可能会有所帮助。
有关的