related question with unsatisfactory answers: Changing CSS Values with Javascript
Here's what I want to do. I'd like to be able to set a page element's class to some value, and have the browser animate it, for instance a table td whose background will be set to rgb(255*(cos(time)*.5+.5),0,0)
.
I can easily do this for a single element by setting a timer. But I might want to have multiple elements have this property, and having to keep track of a timer for each one isn't a great idea.
So what I'd like to do is to be able to change a CSS value from javascript.
I am looking at the code here and it strikes me as being a bit too heavy-handed for me to use from a timer. From the looks of it, each call I make to a function like changecss
has me appending an entire css rule to every single stylesheet. This is going to majorly pollute the stylesheets internally and will probably result in a runaway memory leak if I call it in a loop every 33ms.
So I'm looking for a solution that will let me zero in on the rgb color setting within the css entry corresponding to a particular class. And modify it. I don't actually need to retrieve the original setting in this case. Can this be done? I'd like to support IE9 if possible, though IE 6,7,8 already screws up my project so much that I've given up on them.
That answer has the basics. As a general solution, you need to find the last occurence of the class in a style sheet (i.e. iterate over all the style sheets to find the last occurence of the class rule), then either add a new rule after that or modify the last rule.
If you know the class only exists once, you can just get the first occurence and modify that. Or if you know the class isn't in the style sheets at all, just add it anywhere (say to the last style sheet) and go from there.
You could easily animate it by storing a reference to the rule and change it over time with setTimeout.
For example, my library routine for changing a css rule is:
/* Replace the cssText for rule matching selectorText with value
** Changes all matching rules in all style sheets
*/
function modifyStyleRule(selectorText, value) {
var sheets = document.styleSheets;
var sheet, rules, rule;
var i, j, k, l;
for (i=0, iLen=sheets.length; i<iLen; i++) {
sheet = sheets[i];
// W3C model
if (sheet.cssRules) {
rules = sheet.cssRules;
for (j=0, jLen=rules.length; j<jLen; j++) {
rule = rules[j];
if (rule.selectorText == selectorText) {
removeRule(sheet, rule);
addRule(sheet, selectorText, value);
}
}
// IE model
} else if (sheet.rules) {
rules = sheet.rules;
for (k=0, kLen=rules.length; k<kLen; k++) {
rule = rules[k];
// An alternative is to just modify rule.style.cssText,
// but this way keeps it consistent with W3C model
if (rule.selectorText == selectorText) {
removeRule(sheet, rule);
addRule(sheet, selectorText, value);
// Alternative
// rule.style.cssText = value;
}
}
}
}
}
/* Remove rule from supplied sheet
*/
function removeRule(sheet, rule) {
// W3C model
if (typeof sheet.deleteRule == 'function') {
sheet.deleteRule(rule);
// IE model
} else if (sheet.removeRule) {
sheet.removeRule(rule);
}
}
/* Add rule from supplied sheet
** Rule is added as last rule in sheet
*/
function addRule(sheet, selectorText, value) {
// W3C model
if (typeof sheet.insertRule == 'function') {
sheet.insertRule(selectorText + ' {' + value + '}', sheet.cssRules.length);
// IE model
} else if (sheet.addRule) {
sheet.addRule(selectorText, value, sheet.rules.length);
}
}
To animate a change, call the function with the same selector but different values using setTimeout.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With