get document.styleSheets by name instead of index?
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>
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')
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;
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.