虽然题目里写的是伪元素
,不过这篇文章主假如说::before
和::after
,其他几个伪元素(::first-letter
、::first-line
、::selection
等)由于没有content
属性,所以本文一笔带过,实在要领是一样的。
伪元素的重点在于一个伪,虽然它们能够被浏览器衬着引擎辨认并准确衬着,然则伪元素自身并非DOM元素,所以没法被js直接操纵——因而任何基于JS直接拔取DOM元素的CSS变动要领对伪元素都不起作用。(JQ看似全能,这个题目上是直接就栽了。由于JQ的挑选符都是基于DOM元素)关于JS和JQ挑选器,能够参考这两篇文档: Selectors API Level 1、jQuery Selectors
猎取伪元素的属性值
虽然JS里没有能够直接操纵伪元素的挑选符,然则猎取其CSS属性的要领照样有的。
window.getComputedStyle
应用window.getComputedStyle
要领挑选到伪元素,然后应用getPropertyValue
要领猎取对应的属性的值。
依据MDN的文档,
window.getComputedStyle(element[, pseudoElt]);
此要领包含两个参数,一个是元素自身另一个是元素的伪元素。
js语法实例(完整DEMO在线链接):
var div=document.querySelector('div');
var fontSize=window.getComputedStyle(div,'::before').getPropertyValue('font-size');//猎取before伪元素的字号大小
关于这个要领,详解能够参考这篇文章:
猎取元素CSS值之getComputedStyle要领熟习
变动伪元素的属性值
window.getComputedStyle
要领虽然能够猎取到伪元素的属性值,然则依据该要领名字也晓得其只能猎取CSS款式,并没法变动css属性,那末假如想要用js动态变动伪元素属性值的话,该怎样处置惩罚呢?
思绪有以下几个:
js变动
data-*
属性值来变动伪元素的content
值建立多个
class
,经由过程切换class
来到达转变款式的目标应用CSSStyleSheet的
insertRule
要领来增添款式应用内部css款式的高优先级来掩盖外部css
以上完成思绪的引荐水平顺次递减
应用DOM的data-*
属性来变动content
的值
data-*
是HTML5新增的DOM元素属性,作用大抵能够明白为标记。详细用法能够参考MDN的这篇文章.而伪元素的content
属性值除了通例赋值外,另有一种特别的attr()
要领来猎取。
HTML:
<div class="test" data-text="TEXT" data-color="red"></div>
CSS:
.test::before{
content: attr(data-text);
}
效果:
TEXT
别的content
实在能够多个attr连写,而且attr()内的能够是DOM元素的恣意属性(比方class
等,以至非W3C规范属性也支撑,不过不引荐这么做)所以很轻易凑一些模版笔墨。像下面这类写法也是完整没题目的。注重用空格衔接,不要用”+”号。
EXAM:
.test::before {
content: '我的类是' attr(class) '想要变成' attr(data-color);
}
虽然W3C给
attr()
给予了无穷能够性,包含color
,width
等属性在将来都有愿望用这个要领变动,然则现在只要content
支撑该要领,其他的都照样草稿状况,还没有有浏览器支撑。之所以把这个要领放在第一位只是由于比拟别的完成手段来讲,这个要领真的太简朴太文雅。
然则假如真的想要改伪元素里的color
等元素呢?
变动class
来完成伪元素款式的变动
把这个要领放到引荐位第二位预计会被很多人骂我:“卧槽,这么简朴又没逼格的方法你居然放到第二位!太没水平了”。不过再看完背面两种要领后也许你会对这类意见有所改变。
这个要领的长处是简朴好用且无兼容性题目。瑕玷是多了一些实在用途不大的class
,很像是jQuery类挑选器中毒患者的做法;别的不适合多状况的场景(比方及时转变伪元素笔墨大小等)。
完成过于简朴就不贴代码了。
前面的class切换大法
能够让人觉得不愉快,这里来个嵬峨上(伪)点的要领:
应用CSSStyleSheet的insertRule
要领来增添款式
这部份内容和W3C规范连累比较多,加上较冷门,没多少人关注,个人现在啃不动规范,所以这部份内容不会做深入分析,明白能够也会有题目,望指正。
CSSStyleSheet是浏览器寄存页面内一切css款式表的对象要领(不包含行内款式),每一个link
和style
标签都代表一个CSSStyleSheet对象,猎取他们能够用document.styleSheets
要领。(须要注重的是虽然styleSheets
要领返回的效果把link
标签引进的外部款式也算进去了,然则非IE浏览器没方法猎取到他们的cssRules
属性,只要内嵌的style
标签内的元素能够被猎取到)
document.styleSheets[0].insertRule('.test::before{color:green}',0)//chrome,firefox等非IE浏览器运用
document.styleSheets[0].addRule('.test::before{color:green}',0)//IE系列浏览器运用
/* 虽然部份浏览器也能够经由过程id来指定,'document.styleSheets.id.insertRule()'这类写法在chrome和IE下都行得通,然则firefox会返回'undefined',所以发起照样运用index值来猎取stylesheet */
.insertRule
的语法是stylesheet.insertRule(rule, index)
,另一个参数是index
,意义是在对应的styleSheets里的cssRules
款式表中的位置,这个值越大则款式优先级越高,然则值不能超过当前款式表划定规矩(cssRules
)长度(CSS中先定义的款式老是会被后定义的掩盖就是这个缘由。),当值小于cssRules
长度时,增添的款式划定规矩会插进去到index
值定义的位置,之前其他的划定规矩顺次顺延。
addrule
和insertRule
要领本质上没区分,只是后者不被IE浏览器辨认,所以前者作为浏览器兼容要领存在。(下文为节约篇幅,以insertRule
要领指代此两种要领。)
上面的代码看似简朴一行,然则却不是每次都有用的。缘由有以下几点:
document.styleSheets
虽然根据style
和link
的递次返回对应的StyleSheetList
,然则第一个假如是link
而不是style
,前面讲过此时没法猎取对应的cssRules
,则document.styleSheets[0].cssRules
为null
,insertRule
要领不起作用。(此状况只针对非IE浏览器,IE浏览器一般,然则定义的早每每意味着被背面的款式掩盖,所以意义不大)同上,假如页面内没有内嵌款式的
style
标签,则insertRule
要领也没法发挥作用。index
值不够大的话很有能够会早于css文件最先的定义位置,致使被掩盖。因而有个折中方法就是给增添的款式增添!important
,虽然我个人比较恶感这么做。
因而可知此要领的局限性,然则这类要领的文雅的地方在于避免了直接写内嵌款式,而是经由过程css api来做变动。比拟下面的要领来讲,轻微好点。
然则这类要领彷佛局限性有点大啊?
HEAD
中增添style
标签强迫掩盖初始属性
这个要领是应用内部css款式的高优先级来掩盖外部css,优点是简朴易明白,完成简朴。害处就是吃相太丢脸,过于粗犷。
var style=document.createElement('style');
style.innerHTML=".test::before{color:green}";//增添款式内容的话也能够用上面提到过的`insertRule`,相对例子里的硬编码会更文雅点。
document.head.appendChild(style);
看到这里能够有些人回响反映过来了,实在加style
标签这类要领能够是insertRule
完成要领的大前提——由于不是一切页面一最先都有内嵌的style
款式的。这类要领虽然不是很好,然则有时候却又确确实实是必需的——比方“拖动滑块转变伪元素内笔墨大小”这个需求。
演习
功用需求
拖动滑块转变伪元素内的笔墨大小
且伪元素内随时显现当前字号
经由过程一个按钮能够转变伪元素内笔墨色彩
这个需求能够将本文前面提到的四种转变伪元素款式的要领都塞进去。详细完成参照DEMO,不再做详细分析:
http://codepen.io/chitanda/pen/OVBJEw/
参考文献
getComputedStyle()
attr-notation
CSSRules