John Smith
John Smith

Reputation: 721

JavaScript access CSS class by its name?

I have to access CSS class by name, and the code below works. However if I try hui["myclass"] or hui[".myclass"] instead of hui[0] it cannot find it.

function change_class() {
  var hui = document.styleSheets[0].rules || document.styleSheets[0].cssRules;
  hui[0].style["color"] = "#ff0000"
}
.myclass {
  color: #00aa00;
}
<div class="myclass" onclick="change_class()">Some Text</div>

EDIT: I need to be able to acess as i described on line 1 i dont want to acess trough individual elements on page, but directly to stylesheet by class name.

So you all saying i cannot access to stylesheet by class name only by index?

Upvotes: 7

Views: 13881

Answers (6)

Bhargav
Bhargav

Reputation: 71

To access the class from javascript you just need to create a classist, if it's not there.

document.querySelector("myDiv").classList.add("className");

This adds the new class to the div with the specified class name.

Else:

document.querySelector(".className");

Upvotes: 0

Detlef Lindenthal
Detlef Lindenthal

Reputation: 45

Yes, Bergi is right:
You first have to build an index for the style list.
BUT take care:
If there is more than 1 stylesheet you first have to loop over the stylesheets. So I like to improve Bergis solution:

var styleBySelector = {};
for (var j=0; j<document.styleSheets.length; j++)   {
  var styleList = document.styleSheets[j].rules || document.styleSheets[j].cssRules;
  for (var i=0; i<styleList.length; i++)
    styleBySelector[styleList[i].selectorText] = styleList[i].style;
 }

// And then invoke or set the style you wish like this:
styleBySelector[".myStyle"].color = "#ff0000";

Upvotes: 1

David Thomas
David Thomas

Reputation: 253308

To change the established rules, this is one approach:

// the [2] index is only because that's where JS Fiddle
// puts the user-entered CSS (from the CSS panel).
var sheets = document.styleSheets[2].rules,
    classString = 'body',
    props = ['color'], // requires a 1:1 relationship between two arrays...ugh
    to = ['#0f0'];

for (var i = 0, len = sheets.length; i < len; i++) {
    if (sheets[i].selectorText == classString) {
        for (var c = 0, leng = props.length; c < leng; c++) {
            sheets[i].style[props[c]] = to[c];
        }
    }
}​

JS Fiddle demo.

And a slightly improved alternative (an object rather than two arrays, that require a 1:1 relationship):

var sheets = document.styleSheets[2].rules,
    classString = 'body',
    propsTo = {
        'color': '#0f0'
    };

for (var i = 0, len = sheets.length; i < len; i++) {
    if (sheets[i].selectorText == classString) {
        for (var prop in propsTo) {
            if (propsTo.hasOwnProperty(prop)) {
                sheets[i].style[prop] = propsTo[prop];
            }
        }
    }
}​

JS Fiddle demo.

Upvotes: 0

Bergi
Bergi

Reputation: 664307

No, you can't access them by the selector - it's a simple list. You first had to build an index for it:

// assuming those are the right rules (ie from the right stylesheet)
var hui = document.styleSheets[0].rules || document.styleSheets[0].cssRules;

var styleBySelector = {};
for (var i=0; i<hui.length; i++)
    styleBySelector[hui[i].selectorText] = hui[i].style;

// now access the StyleDeclaration directly:
styleBySelector[".myclass"].color = "#ff0000";

Of course this is not a fool-proof method, there could be

  • multiple selectors like .myClass, .myOtherClass
  • multiple occurences of one selector (though it doesn't matter, the last declaration overwrites previous styles anyway)

and instead of blindly assigning the color property you first should check for existence of the declaration.

Upvotes: 8

Chris Sobolewski
Chris Sobolewski

Reputation: 12925

document.getElementsByClassName('myclass');

will return an array of elements which match.

You could also use something along the lines of:

<body>
    <div id="changethese">
        <div class="myclass" onclick="change_class()">Some Text</div>
    </div>
    <div class="myclass">div two</div>
</body>

Javascript:

var changeTheseDivs = document.getElementById('changethese');
changeTheseDivs.getElementsByClassName('myclass')

To change only the class within the selected div.

However, support for this method only works back to IE9, so if JQuery is an option, it might be best to use that.

Edit:

I believe I misread, it looks like you want to change the actual CSS rule itself as opposed to changing CSS on the elements. You could, in theory, write a function that will find rules by name for you and change their properties. I guess it would look something like this (untested, should work):

function findAndChangeCSSRule(ruleName, newRule, newProperty){
    var mysheet=document.styleSheets[0];
    var myrules=mysheet.cssRules? mysheet.cssRules: mysheet.rules
    for (i=0; i<myrules.length; i++){
        if(myrules[i].selectorText.toLowerCase()==ruleName){
             targetrule=myrules[i];
             break;
        }
    }
    targetrule.style[newRule.toString()]=newProperty;
}

then call it with:

findAndChangeCSSRule('my_class', 'color', 'red')    

Upvotes: 0

pozs
pozs

Reputation: 36214

(document.styleSheets[0].cssRules || document.styleSheets[0].rules)[0].style.color = '#ff0000' should work.

Quirksmode CSSOM (DOM CSS) compatibility table

Upvotes: -1

Related Questions