来补充一下,新的方案,不考虑兼容的话,css变量是最好的方案。
==============================================================================================
方案一:
使用element换肤方案,原理是less变量,预先提取所有文件的less文件,在线上用js替换less变量,添加到文档上。
方案二:
使用stylesheet
/**
* @desc 换肤方法
* @param {object} colorData 需要替换颜色的键值对
*/
changeColors(colorData) {
window.onload=function(){
console.log("开始换肤"+(new Date()).valueOf())
var styleSheets=document.styleSheets
var styleSheet;
//预处理,兼容原先color配置文件,16进制转换为rgb,支持rgba和rgb逗号后需要空格,不支持16进制透明度
//后续支持css全局变量可以按照需求转变
var newColorData={}
for(var key in colorData){
var newkey;
if (key.substr(0, 1) == "#"){
key = key.substring(1);
key = key.toLowerCase();
var b = new Array();
for (var x = 0; x < 3; x++) {
b[0] = key.length == 6 ? key.substr(x * 2, 2) : key.substr(x * 1, 1) + key.substr(x * 1, 1);
b[3] = "0123456789abcdef";
b[1] = b[0].substr(0, 1);
b[2] = b[0].substr(1, 1);
b[20 + x] = b[3].indexOf(b[1]) * 16 + b[3].indexOf(b[2])
}
newkey="rgb\\("+b[20]+",\\s"+b[21]+",\\s"+b[22]+"\\)"
newColorData[newkey] = colorData['#'+key]
}else if(key.substr(0, 1) == "@"){
switch(key){
//需要匹配的自定义字段
case "@primary-color":newColorData["rgb\\(53,\\s152,\\s219\\)"] = colorData[key];break;
default: break;
}
}else if(key.substr(0, 3) == "rgb"){
newkey=key.replace(/[(]/g,"\\(").replace(/[ ]/g,"\\s").replace(/[)]/g,"\\)")
newColorData[newkey] = colorData[key]
}
}
var regtest;
var longStr = ''
for(let i=0;i<styleSheets.length;i++){
styleSheet = styleSheets[i]
for(let j=0;j<styleSheet.cssRules.length;j++){
longStr += styleSheet.cssRules[j].cssText+"&"
}
}
for(var key in newColorData){
regtest = new RegExp(key,'g')
longStr=longStr.replace(regtest,newColorData[key])
}
longStr=longStr.split('&')
var flag=0
for(let i=0;i<styleSheets.length;i++){
styleSheet = styleSheets[i]
for(let j=0;j<styleSheet.cssRules.length;j++){
styleSheet.insertRule(longStr[flag++],j)
styleSheet.deleteRule(j+1)
}
}
console.log("换肤结束"+ (new Date()).valueOf())
}
}
}
优点
无需扫描提取所有样式,减少了打包体积,避免了样式覆盖,允许使用scoped。 使用方便,直接引用方法无需额外配置。
速度快。
缺点
不支持style内联样式,暂时不支持@XXX全局变量。 未经测试的稳定性。
预设申明
方法里没写,可以自行添加css全局变量来实现色值变量
//换肤举例
{
"#f8f8f8":"#0000ff",
"rgb(250, 250, 250)":"#0000ff",
"@primary-color":"#0000ff"
}