Last year I needed a function to change CSS rules for one of my projects, so I put together a function called changeCSS() which allowed me to change, add or delete a CSS rule. I looked at various resources and the work was heavily influenced by code from David Flanagan and Shawn Olson. It worked great for all the cases I needed it in my project. My plan was to rigorously test it to make sure it worked in other cases I hadn’t used then post it here, but over time it has become clear that isn’t going to happen. So I decided I’d just put it out here as “yet another semi-tested but handy function” that people can look at for reference.
Anywhere, here is the function.
var exfer = window.exfer || {};
exfer.changeCSS = function (selector, stylename, value) {
var ss, rules;
// make sure there is a stylesheet available
if (document.styleSheets.length <= 0) {
if (document.createStyleSheet) {
document.createStyleSheet();
} else {
var styleTag = document.createElement("style");
styleTag.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(styleTag);
}
}
// convert the stylename to camel case if necessary
ccstylename = (stylename || "").replace(/\-(\w)/g, function (m, c) { return (c.toUpperCase()); });
ccstylename = (ccstylename == 'float') ? 'cssFloat' : ccstylename;
selector = selector.toLowerCase();
// loop to delete or change the css
for (var i = 0; i < document.styleSheets.length; i++) {
ss = document.styleSheets[i];
try {
rules = ss.cssRules || ss.rules;
} catch (e) {
rules = []
}
for (var j = 0, len = rules.length; j < len; j++) {
if (rules[j].selectorText && rules[j].selectorText.toLowerCase() == selector) {
if (value != null) {
rules[j].style[ccstylename] = value;
} else {
if (ss.deleteRule) {
ss.deleteRule(j);
} else if (ss.removeRule) {
ss.removeRule(j);
} else {
// poor man's delete
rules[j].style.cssText = "";
}
}
return;
}
}
}
if (stylename && value) {
// if the selector wasn't found and isn't supposed to be deleted then add it
ss = document.styleSheets[0];
rules = ss.cssRules || ss.rules;
if (ss.insertRule) {
ss.insertRule(selector + "{" + stylename + ":" + value + "; }", rules.length);
} else if (ss.addRule) {
ss.addRule(selector, stylename + ":" + value + ";", rules.length);
} else {
throw new Error("Selector not found and add/insert rule not supported.");
}
}
};
Below is a test div that starts bold and you can change the color. You can even delete the whole rule and remake it.
exfer.changeCSS(”#changediv”, “background-color”, “yellow”);
exfer.changeCSS(”#changediv”, “background-color”, “green”);
exfer.changeCSS(”#changediv”, “background-color”, “”);
exfer.changeCSS(”#changediv”, “background-color”);
Overall I think it is a handy function. I did my minimal testing in IE6/7, FF2, Opera 9, and Safari 3 all in Windows.



5 Comments
I found out the hard way that addRule doesn’t support multiple selectors separated by “,”, where insertRule does. I ended up splitting the selector on the comma character and adding separate rules for each segment.
That’s a good point I hadn’t considered. Thanks for pointing it out.
Looks to me like the closing “}” on the try statement is missing.
Right you are. Somehow that got stripped out when I pasted it in to WordPress. Should be fixed now. :)
not working in Chrome
Post a Comment