[英]Selecting and manipulating CSS pseudo-elements such as ::before and ::after using javascript (or jQuery)
有没有办法使用 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');
});
$('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>
:before
或:after
内容不是完全动态的可以使用 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>
当使用 jQuery 时,我们可以用$('p')[0]
替换document.querySelector('p')
,以获得更短的代码。
您还可以在 CSS 中使用attr()
来读取特定的 DOM 属性。 (如果浏览器支持:before
,它也支持attr()
。 )通过将其与content:
结合起来content:
在一些精心准备的 CSS 中,我们可以更改:before
的内容(但不能更改其他属性,例如边距或颜色)和:after
动态: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>
attr
仅适用于内容字符串,不适用于 URL 或 RGB 颜色虽然它们通过 CSS 被浏览器渲染,就好像它们就像其他真正的 DOM 元素一样,但伪元素本身并不是 DOM 的一部分,因为伪元素,顾名思义,不是真正的元素,因此你不能直接使用 jQuery(或任何JavaScript API,甚至不是Selectors API )选择和操作它们。 这适用于您尝试使用脚本修改其样式的任何伪元素,而不仅仅是::before
和::after
。
您只能在运行时通过 CSSOM 直接访问伪元素样式(想想window.getComputedStyle()
),除了.css()
之外,jQuery 不会公开它,该方法也不支持伪元素。
不过,您总是可以找到其他方法来解决它,例如:
将样式应用于一个或多个任意类的伪元素,然后在类之间切换(请参阅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)
语法var(--c,value)
其中value
是默认值,也称为回退值。
从相同的规范我们可以读到:
可以使用 var() 函数将自定义属性的值替换为另一个属性的值。 var() 的语法是:
var() = var( <custom-property-name> [, <declaration-value> ]? )
该函数的第一个参数是要替换的自定义属性的名称。 函数的第二个参数(如果提供)是回退值,当引用的自定义属性无效时,该值用作替代值。
然后:
要在属性值中替换 var():
- 如果由
var()
函数的第一个参数命名的自定义属性被动画污染,并且var()
函数正在动画属性或其一个常用属性中使用,则将自定义属性视为具有其初始值这个算法的其余部分。- 如果
var()
函数的第一个参数命名的自定义属性的值不是初始值,则将var()
函数替换为相应自定义属性的值。- 否则,如果
var()
函数将回退值作为其第二个参数,则将var()
函数替换为回退值。 如果回退中有任何var()
引用,也替换它们。- 否则,包含
var()
函数的属性在计算值时无效。
如果我们不设置自定义属性或将其设置为initial
值或它包含无效值,则将使用回退值。 如果我们想将自定义属性重置为其默认值,则使用initial
值会很有帮助。
有关的
按照 Christian 的建议,您还可以执行以下操作:
$('head').append("<style>.span::after{ content:'bar' }</style>");
这是访问 :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 完全按照您想要的样式进行设置。
谢谢你们! 我设法做我想做的事:D http://jsfiddle.net/Tfc9j/42/在这里看看
我想让外部 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>
一种有效但不是很有效的方法是将规则添加到具有新内容的文档并使用类引用它。 根据需要,该类可能需要为内容中的每个值提供一个唯一的 id。
$("<style type='text/css'>span.id-after:after{content:bar;}</style>").appendTo($("head"));
$('span').addClass('id-after');
这是 HTML:
<div class="icon">
<span class="play">
::before
</span>
</div>
'before' 上的计算样式是content: "VERIFY TO WATCH";
这是我的两行 jQuery,它使用了添加一个额外类来专门引用此元素的想法,然后附加一个样式标记(带有 !important 标记)以更改 sudo 元素内容值的 CSS:
$("span.play:eq(0)").addClass('G');
$('body').append("<style>.G:before{content:'NewText' !important}</style>");
您可以创建一个假属性或使用现有属性并在伪元素的样式表中继承它。
var switched = false; // Enable color switching setInterval(function () { var color = switched ? 'red' : 'darkred'; var element = document.getElementById('arrow'); element.style.backgroundColor = color; // Managing pseudo-element's css // using inheritance. element.style.borderLeftColor = color; switched = !switched; }, 1000);
.arrow { /* SET FICTIONAL PROPERTY */ border-left-color:red; background-color:red; width:1em; height:1em; display:inline-block; position:relative; } .arrow:after { border-top:1em solid transparent; border-right:1em solid transparent; border-bottom:1em solid transparent; border-left:1em solid transparent; /* INHERIT PROPERTY */ border-left-color:inherit; content:""; width:0; height:0; position:absolute; left:100%; top:-50%; }
<span id="arrow" class="arrow"></span>
它似乎不适用于“内容”属性:(
这是不切实际的,因为我不是为现实世界的使用而写的,只是为了给你一个可以实现的例子。
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 的特定值。
我的方式只是一个例子,它不利于实践,你可以修改它尝试一些你自己的技巧,使其适合现实世界的使用。
所以做你自己的实验这个和其他的!
问候 - 阿达什赫格德。
我总是添加我自己的 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!');
这里有很多答案,但没有答案有助于操纵: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 的颜色更改为绿色,将字体大小更改为 30px。 您可以通过以下方式实现:
在某些类.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',这是一个动态值。
我希望它有帮助
当您可以将style
附加到头部时,为什么还要添加类或属性
$('head').append('<style>.span:after{ content:'changed content' }</style>')
为此,您可以使用我的插件。
查询:
(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 的正常功能中一样
另外,你还可以获取伪元素参数的值,就像在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 伪规则,例如对特定元素使用.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!"'
});
$('.span').attr('data-txt', 'foo'); $('.span').click(function () { $(this).attr('data-txt',"any other text"); })
.span{ } .span:after{ content: attr(data-txt); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div class='span'></div>
其他人评论说用完整的样式元素附加到 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()
现在,在我的情况下,我需要它来根据另一个元素的高度设置一个 before 元素的高度,并且它会在调整大小时发生变化,因此使用它我可以在每次调整窗口大小时运行setHeight()
并且它将替换<style>
适当地。
希望能帮助那些试图做同样事情的人。
我使用CSS
中:root
定义的变量来修改:after
(同样适用于:before
)伪元素,特别是更改由.sliding-middle-out:hover:after
定义的样式anchor
的background-color
值.sliding-middle-out:hover:after
和以下演示中另一个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("");
}
);
我第一次在给出自己的答案之前没有阅读所有给出的答案,所以我希望这不会让我陷入……
在我的例子中,这是附加到a
、 div
和button
元素的图标所需要的,它的工作方式与<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)
}
}
代码解释:
data-icon
)的所有元素fake-
开头的类名,后跟一个随机的字母数字字符串data-icon
属性的值::before
伪元素将内容设置为先前获取的值创建样式<head>
HTML 元素的末尾添加样式下面的解决方案告诉您如何使用 javascript attr属性更新伪元素。
在 HTML 中添加一个属性,您可以使用带有 setAttribute 的 javascript 操作该属性。
<div
id="inputBoxParent"
count="0">
...
</div>
用js更新
inputBoxParent.setAttribute('count', value.length)
CSS - 在伪元素中添加内容为 attr(attributeName)
.input-box-container::after{
content: attr(count);
}
你完成了!!!
const inputBoxParent = document.getElementById("inputBoxParent"); const handleOnChange = (value) => { inputBoxParent.setAttribute('count', value.length) }
.input-box-container { position: relative; width: 200px; } .input-box-container::after{ position: absolute; bottom: 8px; right: 10px; height: 10px; width: 20px; content: attr(count); }
<h4> Type some text inside the box and click outside to see resule ie pseudo element content change</h4> <div id="inputBoxParent" class="input-box-container" count="0"> <input type="text" id="inputBox" placeholder="type some thing" onchange="handleOnChange(this.value)" onkeyup="handleOnChange(this.value)" /> </div>
只需在之前或之后设置伪样式即可继承,然后使用 javascript 设置父样式。
因此,例如我想更改 :before 的颜色样式,然后我设置:
.my-style::before{
color: inherit;
}
然后我只需使用 javascript 更改.my-style元素上的颜色样式:
document.querySelector(".my-style").style.color = red;
大功告成,超级简单
我有一些不同的东西给你,它既简单又有效。
<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');
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.