在开发一个ui编辑功能,因为使用的是Vue,最开始的时候是的方法是直接将styles放在dom元素上面,当遇到伪元素就无计可施了(切没发现JS直接获取DOM伪元素的方法)。
于是就想能不能使用什么方法设置一段css样式
网络上的办法
我们可以这样:
document.styleSheets[0].insertRule('.test::before{color:green}',0)//chrome,firefox,ie9+,Edge,移动端
// 不推荐使用,实际使用过程中未生效
document.styleSheets[0].addRule('.test::before{color:green}',0)// IE 浏览器
我们还可以这样:
var style=document.createElement('style');
style.innerHTML=".test::before{color:green}";
document.head.appendChild(style);
我是在移动端使用的,实际上这两种方法都是可以的,但是我选择使用第二种,因为兼容性更好
解决兼容问题
对于兼容问题MDN上面已经给出了一个答案 https://developer.mozilla.org/zh-CN/docs/Web/API/CSSStyleSheet/insertRule
(function(Sheet_proto){
var originalInsertRule = Sheet_proto.insertRule;
if (originalInsertRule.length === 2){ // 2 个托管参数: (selector, rules)
Sheet_proto.insertRule = function(selectorAndRule){
// 首先,从规则中分离选择器
a: for (var i=0, Len=selectorAndRule.length, isEscaped=0, newCharCode=0; i !== Len; ++i) {
newCharCode = selectorAndRule.charCodeAt(i);
if (!isEscaped && (newCharCode === 123)) { // 123 = "{".charCodeAt(0)
// 其次,找到花括号
var openBracketPos = i, closeBracketPos = -1;
for (; i !== Len; ++i) {
newCharCode = selectorAndRule.charCodeAt(i);
if (!isEscaped && (newCharCode === 125)) { // 125 = "}".charCodeAt(0)
closeBracketPos = i;
}
isEscaped ^= newCharCode===92?1:isEscaped; // 92 = "\\".charCodeAt(0)
}
if (closeBracketPos === -1) break a; // No closing bracket was found!
/*else*/ return originalInsertRule.call(
this, // 想要改变的样式表
selectorAndRule.substring(0, openBracketPos), // 选择器
selectorAndRule.substring(closeBracketPos), // 规则
arguments[3] // 插入的索引
);
}
// Works by if the char code is a backslash, then isEscaped
// gets flipped (XOR-ed by 1), and if it is not a backslash
// then isEscaped gets XORed by itself, zeroing it
isEscaped ^= newCharCode===92?1:isEscaped; // 92 = "\\".charCodeAt(0)
}
// Else, there is no unescaped bracket
return originalInsertRule.call(this, selectorAndRule, "", arguments[2]);
};
}
})(CSSStyleSheet.prototype);
这段代码应该放在何处才能生效,可以自己思考一下,至于是否选择这个兼容方案大家自己选择。
插入顺序问题
这两个方法因为都是插入了一段CSS代码,CSS在解析的时候会根据引入的先后顺序和权重值来解析,导致我们插入的代码被覆盖,虽然第二种方法是插入到了head最后,一定程度上避免了这种问题,但是不能完全解决这种隐患
解决办法就是当发现或者凭经验判断样式未生效,需要在当前功能执行之后在head最后重新添加对应的CSS代码
删除无效CSS代码
- 对于第一种方法
CSSStyleSheet.deleteRule() 移除指定的CSS代码 - 对于第二种方法
可以在创建style
的时候设置一个id,可以使用document.styleSheet
来匹配id,可以是移除dom或者使用 CSSStyleSheet.deleteRule()移除指定的CSS代码
参考地址
DocumentOrShadowRoot.styleSheets
Document.styleSheetSets
CSSStyleSheet
CSSStyleSheet.insertRule()
Document.createElement()
使用 js 设置伪元素样式
JavaScript HTML DOM - 改变 CSS
JS addRule()和insertRule()方法:添加CSS样式
如何使用JS操纵伪元素
Js动态加载CSS样式文件的2种方法
网友评论