vsync
vsync

Reputation: 130145

get document.styleSheets by name instead of index?

document.styleSheets is used with an index,
but what If I want to use stylesheet.insertRule with a specific CSS file ?

I know the file's name, which is injected to a page and at some point via JS.

Upvotes: 36

Views: 50672

Answers (5)

vsync
vsync

Reputation: 130145

Use this, and keep in mind:

For security reasons, Opera and Mozilla will not allow you to access the cssRules collection of a stylesheet from another domain or protocol. Attempting to access it will throw a security violation error

function setStyleRule (selector, rule, sheetName) {
    var sheets = document.styleSheets,
        stylesheet = sheets[(sheets.length - 1)];
    
    for( var i in document.styleSheets ){
        if( sheets[i].href && sheets[i].href.indexOf(sheetName + ".css") > -1 ) {
            stylesheet = sheets[i];
            break;
        }
    }
    
    if( stylesheet.addRule )
        stylesheet.addRule(selector, rule);

    else if( stylesheet.insertRule )
        stylesheet.insertRule(selector + ' { ' + rule + ' }', stylesheet.cssRules.length);
}

Update - shorter code:

function getSetStyleRule(sheetName, selector, rule) {
    var stylesheet = document.querySelector('link[href*=' + sheetName + ']')

    if( stylesheet ){
        stylesheet = stylesheet.sheet
        stylesheet.insertRule(selector + '{ ' + rule + '}', stylesheet.cssRules.length)
    }

    return stylesheet
}

// Usage example
getSetStyleRule('main', 'body', 'background:red')

Upvotes: 48

Erisan Olasheni
Erisan Olasheni

Reputation: 2905

Without jquery:

function addRule(stylename, selector, rule) {

  var stylesheet = document.querySelector(`link[href$="${stylename}.css"]`)

  if( stylesheet.addRule )
          stylesheet.addRule(selector, rule);

      else if( stylesheet.insertRule )
          stylesheet.insertRule(selector + ' { ' + rule + ' }', stylesheet.cssRules.length);
        
     }
     
// example use

addRule('styles.css', '.color', 'red')

Upvotes: 1

Intervalia
Intervalia

Reputation: 10945

Here is a minor adjustment to the answer by vsync.

function addRule(stylesheetId, selector, rule) {
  var stylesheet = document.getElementById(stylesheetId);

  if (stylesheet) {
    stylesheet = stylesheet.sheet;

    if (stylesheet.addRule) {
      stylesheet.addRule(selector, rule);
    } else if (stylesheet.insertRule) {
      stylesheet.insertRule(selector + ' { ' + rule + ' }', stylesheet.cssRules.length);
    }
  }
}

Once you get the DOM object through document.getElementById you can use the 'sheet' property to access the actual styleSheet. So just make sure that you provide an ID for the styleSheet you want to change. Even if it is an external CSS file, just give it an ID.

And here is my test code:

var index = 0;
var items = [
  { selector: "h1", rules: "color:#3333BB;font: bold 18px Tahoma;padding: 12px 0 0 0;" },
  { selector: "p", rules: "padding:0;margin:0;background-color:#123456;color:#ABCDEF;"},
  { selector: "b", rules: "font-weight:normal;"},
  { selector: "i", rules: "color:#66FF66;" }
];

function addRule(stylesheetId, selector, rule) {
  var stylesheet = document.getElementById(stylesheetId);

  if (stylesheet) {
    stylesheet = stylesheet.sheet;

    if (stylesheet.addRule) {
      stylesheet.addRule(selector, rule);
    } else if (stylesheet.insertRule) {
      stylesheet.insertRule(selector + ' { ' + rule + ' }', stylesheet.cssRules.length);
    }
  }
}

$(document).ready(function () {
  $("button").click(function () {
    addRule("myStyles", items[index].selector, items[index].rules);
    index++;
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<style id="myStyles">
  div
  {
    border: solid 1px black;
    width: 300px;
    height: 300px;
  }
</style>
<button>Click Me 4 times slowly</button>
<div>
  <h1>test</h1>
  <p>Paragraph One</p>
  <p>Paragraph with <b>bold</b> and <i>Italics</i></p>
  <p>Paragraph 3</p>
</div>

Upvotes: 6

suncat100
suncat100

Reputation: 2194

Why so complicated? You can get a specific document stylesheet by ID or URL without looping through all the stylesheets in the document: var mysheet = $('link#id')[0].sheet; ... or ... var mysheet = $('link[href="/css/style.css"]')[0].sheet;

Upvotes: 25

Vitor
Vitor

Reputation: 19

This happened because of the address of CSS is different of the adress of the page. To fix is just make the both have the some adress.

Upvotes: 1

Related Questions