Ωmega
Ωmega

Reputation: 43673

How to change CSS Parameter with JavaScript?

I know it is not common way to modify CSS classes... but anyway >> I have the following function to change CSS parameter with JavaScript:

function changeCSSParameter(classId, param, value)
{
  var CSSRules;
  if (document.all)
  {
    CSSRules = 'rules';
  }
  else if (document.getElementById)
  {
    CSSRules = 'cssRules';
  }
  for (var i = 0; i < document.styleSheets[0][CSSRules].length; i++)
  {
    var classes = document.styleSheets[0][CSSRules][i].selectorText.split(/\s*,\s*/);
    for (var j = 0; j < classes.length; j++)
    {
      if (classes[j] == classId)
      {
        document.styleSheets[0][CSSRules][i].style.setProperty(param, value, '');
      }
    }
  } 
}

However this function would not work as I wish if style classes are defined in groups, such as

.first, .second
{
  color: red;
}

...because any change would apply to both classes. How can I solve this issue? Please advice.

No jQuery, please, just old-fashion JavaScript.

Upvotes: 1

Views: 489

Answers (1)

Scott Sauyet
Scott Sauyet

Reputation: 50797

My first question is how sure you are about the inference that the existence of document.all implies that a stylesheet will have a rules property and its nonexistence implies that it will have a cssRules property? Because that seems rather sketchy to me? What is it based on?

But assuming that it is a reasonable inference, why in the world are you making that CSSRules calculation on every call to your function? Calculate it once at start-up and store it, returning your function inside a closure that contains the value.

That said, on to your main problem...

Your code will only work if the individual selectors (inside the comma-separated groups of selectors) are single class selectors such as .myClass. Anything even slightly more complicated, such as div.myClass won't work, correct? If that's all you're trying to do, I think I have a (fairly obnoxious, but workable) solution: On encountering a comma-separated solution where one of them is a match, write new rules for each of the selectors, cloning the existing rule. Then for the one that matches your class name, change the relevant property. Finally, remove the original rule.

It's not fun, and it makes several assumptions that are clearly not warranted in the general case, but look like they might match what you're trying to do in your code.

Hey, I did say it was obnoxious! :-)

Upvotes: 1

Related Questions