4

I am trying to find the index of a css rule .widget-area in a stylesheet.

This is how I'm doing it, but it returns undefined:

function findStyle(){
var myStylesheet=document.styleSheets[8].cssRules[".widget-area"];
console.log(myStylesheet);
};

If I leave out .cssRules[".widget-area"] it returns all the rules of the stylesheet, but there are thousands of them.

Anyone knows how to do this? Thanks.

Community
  • 1
  • 1
Lele
  • 81
  • 7
  • This just seems like a bad idea. What's the end goal? – isherwood Apr 19 '16 at 20:57
  • 2
    `console.log(document.styleSheets[8])` and figure out out what the key actually is. – Marc B Apr 19 '16 at 20:57
  • @isherwood I need to dynamically erase the css rule I am trying to find the index of. The parent theme will be updated frequently and I need to keep this particular rule inactive. – Lele Apr 19 '16 at 22:37
  • It just seems very fragile. If anything changes in the stylesheet it breaks. Why not override the class in a normal cascade fashion? – isherwood Apr 20 '16 at 01:26
  • If you need to keep one particular rule inactive, could you not simply remove that rule? Or, potentially, use a very specific selector to apply the rule - based on a dynamic class on the `` element - which can be removed from that element to prevent the selector from matching? As isherwood says, you seem to be focusing on a fragile, complex solution to a problem that could be solved much more easily than by parsing your css programmatically. – David Thomas Jun 10 '18 at 10:27

2 Answers2

1

getStyleRuleIndexBySelector function will find the index of a specific rule. Take into account that this searches by selector only, and there could be more than one rules per selector.

// create a dummy stylesheet which we'll search a key by value
var style = document.createElement("style")
style.appendChild(document.createTextNode(""))
document.head.appendChild(style);

// insert some rules
style.sheet.insertRule('.first{ color:red }', style.sheet.cssRules.length);
style.sheet.insertRule('.second{ color:green }', style.sheet.cssRules.length);
style.sheet.insertRule('div span a{ color:blue }', style.sheet.cssRules.length);
style.sheet.insertRule('.second{ display:none; left:1px; }', style.sheet.cssRules.length);

// get the rules
var rules = style.sheet.cssRules;

function getStyleRuleIndexBySelector(selector, prop){
  var result = [], i,
      value = (prop ? selector + "{" + prop + "}" : selector).replace(/\s/g, ''), // remove whitespaces
      s = prop ? "cssText" : "selectorText";
  
  for( i=0; i < rules.length; i++ )
    if( rules[i][s].replace(/\s/g, '') == value)
      result.push(i);
      
  return result;
}

console.log(  getStyleRuleIndexBySelector('.second' )  );
console.log(  getStyleRuleIndexBySelector('.second', 'display:none; left:1px;')  );
vsync
  • 118,978
  • 58
  • 307
  • 400
-1

I think you are using .cssRules as a function but it is an object. So if you want to look for a custom rule you should use something like this:

var targetRule;
var rules = document.styleSheets[8].cssRules;

for (i=0; i<rules.length; i++){
  if (rules[i].selectorText.toLowerCase() == ".widget-area"){ 
    targetRule = rules[i];
    break;
  }
}
axl-code
  • 2,192
  • 1
  • 14
  • 24
  • Thanks for answering. I tried it and got this "Uncaught TypeError: Cannot read property 'toLowerCase' of undefined" from the console. Any idea why? – Lele Apr 19 '16 at 22:47