使用 javascript(或 jQuery)选择和操作 CSS 伪元素,例如 ::before 和 ::after
是否有任何方法可以使用 jQuery 选择/操作 CSS 伪元素,例如
::before
和
::after
(以及带有一个分号的旧版本)?
例如,我的样式表具有以下规则:
.span::after{ content:'foo' }
如何使用原始 JS 或 jQuery 将“foo”更改为“bar”?
您还可以使用数据属性将内容传递给伪元素,然后使用 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 解决方法来操作这些元素;您使用哪种方法取决于您的确切要求。
我将从被广泛认为是“最佳”的方法开始:
1) 添加/删除预定的类
在这种方法中,您已经在 CSS 中创建了一个具有不同
:after
或
:before
样式的类。将此“新”类放置在样式表的稍后位置以确保其可覆盖:
p:before {
content: "foo";
}
p.special:before {
content: "bar";
}
然后,您可以使用 jQuery(或原生 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>
- 优点: 使用 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 = "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()
和相关的
.insertRule()
方法
如今得到了相当好的支持。
作为一种变体,您还可以使用 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>
如果我们谈论的是“操纵”值,而不仅仅是添加值,我们还可以使用不同的方法
读取
现有的
: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>
我们可以将
document.querySelector('p')
替换为
$('p')[0]
使用 jQuery 时,代码会稍微短一些。
- 优点: 任何字符串都可以动态插入样式中
- 缺点: 原始样式不会改变,只会被覆盖;重复(滥用)使用会使 DOM 任意增大
3) 更改不同的 DOM 属性
您还可以
在 CSS 中使用
attr()
来读取特定的 DOM 属性。 (
如果浏览器支持
:before
,那么它也支持
attr()
。
)通过在一些精心准备的 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 {
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>
如果无法提前准备好 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>
- 优点: 不会创建无尽的额外样式
-
缺点:
CSS 中的
attr
只能应用于内容字符串,而不能应用于 URL 或 RGB 颜色
尽管伪元素像其他真实的 DOM 元素一样由浏览器通过 CSS 进行呈现,但是伪元素本身并不是 DOM 的一部分,因为伪元素,顾名思义,不是真正的元素,因此您无法直接使用 jQuery(或者
任何
JavaScript API,甚至
选择器 API
)来选择和操作它们。这适用于您尝试使用脚本修改其样式的任何伪元素,而不仅仅是
::before
和
::after
。
您只能在运行时通过 CSSOM(例如
window.getComputedStyle()
)直接访问伪元素样式,jQuery 除了
.css()
之外不公开该方法,该方法也不支持伪元素。
不过,您总是可以找到其他解决方法,例如:
-
将样式应用于一个或多个任意类的伪元素,然后在类之间切换(请参阅 seucolega 的答案 举个简单的例子)——这是惯用的方式,因为它使用简单的选择器(伪元素不是)来区分元素和元素状态,这是它们的预期使用方式
-
通过更改文档样式表来操纵应用于所述伪元素的样式,这更像是一种黑客行为