简体   繁体   中英

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.

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;

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>

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')

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM