有什么方法来选择/操作CSS伪元素,如::before和::after(和旧版本的一个分号)使用jQuery?

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

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

我怎么能改变'foo'到'酒吧'使用香草JS或jQuery?


当前回答

有人评论说附加一个完整的样式元素到头部元素,如果你只做一次,这还不错,但如果你需要重置它不止一次,你最终会有大量的样式元素。所以为了防止这种情况,我在头部创建了一个带有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()

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

希望这能帮助那些被困在做同样事情的人。

其他回答

只需要在之前或之后设置伪样式来继承,然后用javascript设置父样式。

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

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

然后我用javascript改变了.my-style元素的颜色样式:

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

工作完成了,超级简单

你也可以将内容传递给带有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中不能选择伪元素,因为它们不是DOM的一部分。 但是你可以在父元素中添加一个特定的类,并在CSS中控制它的伪元素。

例子

jQuery:

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

在CSS中:

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

你可以使用我的插件来实现这个目的。

JQuery:

(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) { if (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 properties = ''; for (var property in parameters.argument) { if (typeof parameters.argument[property] === 'function') element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property](); else 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(); else element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property; var properties = ''; 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); }; }; return $(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] || windowStyle; } else { return windowStyle || null; }; } else { console.error('Invalid values!'); return false; }; }; $.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 { width: 480px; margin: 0 auto; border: 2px solid red; } .element::before { content: 'Old before!'; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <div class="element"></div>

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

此外,你还可以获得pseudo-element参数的值,就像在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); return '[data-pe--id="' + id + '"]::' + parameters.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); parameters.element.pseudoElements.styleSheet = styleSheet.sheet; }; }; if (parameters.element.pseudoElements[parameters.pseudoElement].properties && parameters.element.pseudoElements[parameters.pseudoElement].index) { parameters.element.pseudoElements.styleSheet.deleteRule(parameters.element.pseudoElements[parameters.pseudoElement].index); }; 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 || parameters.element.pseudoElements.styleSheet.cssRules.length || parameters.element.pseudoElements.styleSheet.length; parameters.element.pseudoElements[parameters.pseudoElement].index = newIndex; parameters.element.pseudoElements[parameters.pseudoElement].properties = parameters.argument; }; var properties = ''; 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 property in parameters.element.pseudoElements[parameters.pseudoElement].properties) { properties += property + ': ' + parameters.element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; '; }; 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 || parameters.element.pseudoElements.styleSheet.cssRules.length || parameters.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(); else parameters.element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property; var properties = ''; for (var property in parameters.element.pseudoElements[parameters.pseudoElement].properties) { properties += property + ': ' + parameters.element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; '; }; 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] || windowStyle; } else { return windowStyle || null; }; } else { console.error('Invalid values!'); return false; }; }; 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 { width: 480px; margin: 0 auto; border: 2px solid red; } .element::before { content: 'Old before!'; } <div class="element"></div>


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

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

有一些方法可以使用JavaScript和/或CSS工作区来操作这些元素;您使用哪一种取决于您的确切需求。


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

1)添加/删除一个预定的类

在这种方法中,您已经在CSS中创建了一个具有不同的:after或:before样式的类。将这个“new”类放在样式表的后面,以确保它被覆盖:

p:before {
    content: "foo";
}
p.special:before {
    content: "bar";
}

然后你可以很容易地添加或删除这个类使用jQuery(或香草JavaScript):

$('p').on('click', function() {
    $(this).toggleClass('special');
});

美元(“p”)。On('点击',函数(){ (美元).toggleClass(特殊的); }); p:{之前 内容:“foo”; 颜色:红色; 光标:指针; } p.special:{之前 内容:“酒吧”; } < script src = " https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js " > < /脚本> <p>这是一个段落 <p>这是另一段

优点:易于实现与jQuery;快速改变多个风格在一次;强制分离关注点(从HTML中隔离CSS和JS) 缺点: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。特殊:在` `之前,` `内容:` ` + STR + ` ` ` ` ` `); p:{之前 内容:“foo”; 颜色:红色; } < script src = " https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js " > < /脚本> <p class="special">这是一个段落</p> 这是另一段</p>

. addrule()和相关的. insertrule()方法目前得到了很好的支持。

作为一种变体,你也可以使用jQuery来添加一个全新的样式表到文档中,但必要的代码并不干净:

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

Var STR = "bar"; $(' <时尚> p。特殊:{之前内容:“+ str +”}> < /风格”).appendTo(头); p:{之前 内容:“foo”; 颜色:红色; } < script src = " https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js " > < /脚本> <p class="special">这是一个段落</p> 这是另一段</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。特殊:before', 'content: "' +str +str + '";'); p:{之前 内容:“foo”; 颜色:红色; } < script src = " https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js " > < /脚本> <p class="special">这是一个段落</p> 这是另一段</p>

在使用jQuery时,我们可以将document.querySelector('p')替换为$('p')[0],以获得稍短的代码。

优点:任何字符串都可以动态插入到样式中 缺点:原始样式不会被改变,只是被覆盖;重复使用(ab)可以使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('点击',函数(){ (美元).attr(“数据”、“酒吧”); }); p:{之前 内容:attr(数据); 颜色:红色; 光标:指针; } < script src = " https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js " > < /脚本> <p>这是一个段落 <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('点击',函数(){ (美元)。attr(“数据”,str); }); p:{之前 内容:“foo”; 颜色:红色; 光标:指针; } < script src = " https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js " > < /脚本> <p>这是一个段落 <p>这是另一段

优点:不会创造出无尽的额外风格 缺点:CSS中的attr只能应用于内容字符串,而不是url或RGB颜色