一般来说,我知道在使用一个 css 源(可能需要也可能不需要多个文件)时更改网站样式的两种方法。
- 定义大量类
.blueBorder、.redBorder 等,并使用 JavaScript,根据需要在元素上添加和删除类。
- 或定义类并再次使用 JavaScript,更改这些类的定义。
可以混合使用这两种方法,但我不确定为什么要这样做。
这是使用第二种方法的JSFIDDLE。
我决定使用纯 JavaScript 解决方案,而不是使用 jQuery,因为它的选择器的强大功能会使编码变得更简单(我猜)。然而,我没有写其中的肉。可以在 here 找到由 Patrick Hunlock 编写的函数 getCSSRule。函数的每一行都有注释。但是,我只是因为包装问题而删除了 Fiddle 中的 cmets。
该函数返回一个指向 CSS 规则的指针,然后可以轻松地对其进行操作。例如:
// get a class rule (in production code check return value for valid result)
var r = getCSSRule('.primaryColor');
// change its definition
r.style.backgroundColor = "#f00";
所有分配有primaryColor 类的元素将在执行上述2 行时将其背景颜色更改为红色(#f00)。没有其他要求。
注意样式表中节点的名称与 CSS 规则不完全相同(backgroundColor 与 background-color)。我知道这里的很多人不喜欢 w3Schools.com 网站,但是在寻找样式对象参考时,我找到了一个。你可以找到它here
这里是代码:
开始 CSS 样式:
<style type="text/css">
#box1 {width: 50%; height: 200px; margin: 40px auto; padding-top: 20px;}
#box2 {width: 50%; height: 120px; margin: 20px auto 20px; padding: 10px;}
.primaryColor {background-color: #f00;}
.primaryBorder {border: 10px solid #000;}
.secondaryColor {background-color: #ff0;}
.secondaryBorder {border: 5px solid #fff;}
.t {color: #f00;}
</style>
HTML:
<div id="box1" class="primaryColor primaryBorder">
<div id="box2" class="secondaryColor secondaryBorder"><p class="t">Theme Demonstration</p>
</div>
</div>
<form style="margin: 40px auto; width:50%">
<div role="radio" style="text-align:center" aria-checked="false">
<input type="radio" name="theme" CHECKED value="theme1" onClick="setThemeOne()" >Theme 1
<input type="radio" name="theme" value="theme2" onClick="setThemeTwo()" >Theme 2
<input type="radio" name="theme" value="theme3" onClick="setThemeThree()">Theme 3
</div>
</form>
还有好东西,JavaScript:
function getCSSRule(ruleName, deleteFlag) {
ruleName=ruleName.toLowerCase();
if (document.styleSheets) {
for (var i=0; i<document.styleSheets.length; i++) {
var styleSheet=document.styleSheets[i];
var ii=0;
var cssRule=false;
do {
if (styleSheet.cssRules) {
cssRule = styleSheet.cssRules[ii];
} else {
cssRule = styleSheet.rules[ii];
}
if (cssRule) {
if (cssRule.selectorText.toLowerCase()==ruleName) {
if (deleteFlag=='delete') {
if (styleSheet.cssRules) {
styleSheet.deleteRule(ii);
} else {
styleSheet.removeRule(ii);
}
return true;
} else {
return cssRule;
}
}
}
ii++;
} while (cssRule)
}
}
return false;
}
function setThemeOne() {
var r = getCSSRule('.primaryColor');
r.style.backgroundColor = "#f00";
r = getCSSRule('.primaryBorder');
r.style.border = "10px solid #000;";
r = getCSSRule('.secondaryColor');
r.style.backgroundColor = "#ff0";
r = getCSSRule('.secondaryBorder');
r.style.border = "5px solid #fff";
r = getCSSRule('.t');
r.style.color = "#000";
};
function setThemeTwo() {
var r = getCSSRule('.primaryColor');
r.style.backgroundColor = "#ff0";
r = getCSSRule('.primaryBorder');
r.style.border = "10px solid #ccc;";
r = getCSSRule('.secondaryColor');
r.style.backgroundColor = "#f00";
r = getCSSRule('.secondaryBorder');
r.style.border = "5px solid #000";
r = getCSSRule('.t');
r.style.color = "#ccc";
};
function setThemeThree() {
var r = getCSSRule('.primaryColor');
r.style.backgroundColor = "#ccc";
r = getCSSRule('.primaryBorder');
r.style.border = "10px solid #000;";
r = getCSSRule('.secondaryColor');
r.style.backgroundColor = "#000";
r = getCSSRule('.secondaryBorder');
r.style.border = "5px solid #fff";
r = getCSSRule('.t');
r.style.color = "#fff";
};
兼容性说明
我已经在 IE11 和当前版本的 Chrome 中测试过这个特定示例。但是,自 2011 年左右以来,我已经在一个站点上部署了类似的代码,当时该站点支持回到 IE7 或 IE8 的浏览器(不记得了)并且没有曾经报告过一个问题。但我现在看到我确实为 Chrome 修补了getCSSRule 函数。 (对于当前版本,我不必这样做。)这是补丁:
if (cssRule){ //If we found a rule...
// [KT] 04/24/2012 - added condition to check for undefined selector for Chrome
if ((cssRule.selectorText != undefined) && cssRule.selectorText.toLowerCase()==ruleName)){//match rule Name?