原生js获取css伪类元素并设置属性
一、伪元素有哪些
首先,先简单说一下伪元素都有哪些。伪元素有六个,分别是 ::after
、::before
、::first-line
、::first-letter
、::selection
、::backdrop
。
在各大网页中最常用的伪元素,是::after
和::before
。
这几个伪元素的语意可参考另外一篇文章《CSS伪元素选择器 总结》。
在CSS3中,建议伪元素使用两个冒号(::)语法,而不是一个冒号 (😃,目的是为了区分伪类和伪元素。大多数浏览器都支持这两种表示语法。只有 ::selection 永远只能以两个冒号开头(:😃。因为IE8只支持单冒号的语法,所以,如果你想兼容IE8,保险的做法是使用单冒号。
二、获取伪元素的属性值
获取伪元素的属性值可以使用 window.getComputedStyle()
方法,获取伪元素的CSS样式声明对象。然后利用getPropertyValue()
方法或直接使用键值
访问都可以获取对应的属性值。
语法:window.getComputedStyle(element[, pseudoElement])
参数如下:
element(Object):伪元素所在的DOM元素;
pseudoElement(String):伪元素类型。可选值有:”:after”、”:before”、”:first-line”、”:first-letter”、”:selection”、”:backdrop”;
举个例子:
// HTML代码
<div id="myId"></div>
// CSS代码
#myId:before {
content: "hello world!";
display: block;
width: 100px;
height: 100px;
background: red;
}
// JS代码
var myIdElement = document.getElementById("myId");
var beforeStyle = window.getComputedStyle(myIdElement, ":before");
console.log(beforeStyle); // [CSSStyleDeclaration Object]
console.log(beforeStyle.width); // 100px
console.log(beforeStyle.getPropertyValue("width")); // 100px
console.log(beforeStyle.content); // "hello world!"
备注:
1.getPropertyValue()
和直接使用键值
访问,都可以访问CSSStyleDeclaration Object。它们两者的区别有:
- 对于float属性,如果使用
键值
访问,则不能直接使用getComputedStyle(element, null).float,而应该是cssFloat与styleFloat; - 使用
键值
,则属性的键需要使用驼峰写法,如:style.backgroundColor
;
使用getPropertyValue(), 不用驼峰,例如:style.getPropertyValue(“border-top-color”)
; - getPropertyValue()方法在IE9+和其他现代浏览器中都支持;在IE6~8中,可以使用
getAttribute()
方法来代替;
2.伪元素默认是”display: inline”。如果没有定义display属性,即使在CSS中显式设置了width的属性值为固定的大小如”100px”,但是最后获取的width值仍是”auto”。这是因为行内元素不能自定义设置宽高。解决办法是给伪元素修改display属性为”block”、”inline-block”或其他。
三、更改伪元素的样式
方法1. 更换class来实现伪元素属性值的更改:
举个栗子:
// CSS代码
.red::before {
content: "red";
color: red;
}
.green::before {
content: "green";
color: green;
}
// HTML代码
<div class="red">内容内容内容内容</div>
// jQuery代码
$(".red").removeClass('red').addClass('green');
1234567891011121314
方法2. 操作 document.styleSheets
Document.styleSheets 只读属性,返回一个由 StyleSheet 对象组成的 StyleSheetList,每个 StyleSheet 对象都是一个文档中链接或嵌入的样式表。 ——MDN
document.styleSheets的大概结构
document.styleSheets = {
CSSStyleSheet_0: {
cssRules: {
selectorText: '', // selector名字,比如div
style: {} // 具体样式
},
rules: {},
...
},
CSSStyleSheet_1...
}
CSSStyleSheet的样子
insertRule(rule [,index])
和 deleteRule(index)
添加的rule,优先级特性跟css的一样: 先看优先级, 同优先级的index靠后的优先
document.styleSheets[0].cssRules.length // 已经定义好的 css 规则数
document.styleSheets[0].cssRules // 已经定义好的 css 规则的 array
document.styleSheets[0].cssRules // 已经定义好的 css 规则的 array
document.styleSheets[0].insertRule(cssRule, index)
let index = document.styleSheets[0].cssRules.length // 查看现有的css数组的length
document.styleSheets[0].insertRule('html::after {animation-name:test;animation-duration: 1s;animation-timing-function: ease-in-out;border: 10px solid red;}', index); // 在现有的css数组的末尾, 添加一个新的css rule
MDN官网的示例function: Function to add a stylesheet rule
/**
* Add a stylesheet rule to the document (it may be better practice to dynamically change classes, so style information can be kept in
* genuine stylesheets and avoid adding extra elements to the DOM).
* Note that an array is needed for declarations and rules since ECMAScript does not guarantee a predictable object iteration order, and since CSS is
* order-dependent.
* @param {Array} rules Accepts an array of JSON-encoded declarations
* @example
addStylesheetRules([
['h2', // Also accepts a second argument as an array of arrays instead
['color', 'red'],
['background-color', 'green', true] // 'true' for !important rules
],
['.myClass',
['background-color', 'yellow']
]
]);
*/
function addStylesheetRules (rules) {
var styleEl = document.createElement('style');
// Append <style> element to <head>
document.head.appendChild(styleEl);
// Grab style element's sheet
var styleSheet = styleEl.sheet;
for (var i = 0; i < rules.length; i++) {
var j = 1,
rule = rules[i],
selector = rule[0],
propStr = '';
// If the second argument of a rule is an array of arrays, correct our variables.
if (Array.isArray(rule[1][0])) {
rule = rule[1];
j = 0;
}
for (var pl = rule.length; j < pl; j++) {
var prop = rule[j];
propStr += prop[0] + ': ' + prop[1] + (prop[2] ? ' !important' : '') + ';\n';
}
// Insert CSS Rule
styleSheet.insertRule(selector + '{' + propStr + '}', styleSheet.cssRules.length);
}
}