Changing a CSS rule-set from Javascript

前端 未结 8 1002
甜味超标
甜味超标 2020-11-22 04:54

Is it possible to make changes to a CSS rule-set dynamically (i.e. some JS which would change a CSS rule-set when the user clicks a widget)

This particular CSS rule-

相关标签:
8条回答
  • 2020-11-22 05:40

    The APIs for editing stylesheets with JS are, sadly, not consistent across browsers. The YUI Stylesheet Utility attempts to smooth over these differences so you could just use that. You could also look at the source code to figure out how it works if you don't want to use YUI itself.

    0 讨论(0)
  • 2020-11-22 05:41

    While setAttribute is nice, there is a standard way of doing this across most browsers:

    htmlElement.className = 'someClass';
    

    To do it over many elements, you will need a cross browser solution:

    function getElementsByClassName( className, context, tagName ) {
      context = context || document;
      if ( typeof context.getElementsByClassName === 'function' )
        return context.getElementsByClassName( className );
    
      if ( typeof context.getElementsByTagName !== 'function' )
        return [];
    
      var elements = typeof tagName === 'string' ? context.getElementsByTagName( tagName ) :
        context.getElementsByTagName('*'),
      ret = [];
      for ( var i = 0, il = elements.length; i < il; i++ )
        if ( elements[ i ].className.match( className ) )
          ret.push( elements[ i ] );
    
      return ret;
    }
    
    var elements = getElementsByClassName('someClass');
    
    for ( var i = 0, il = elements.length; i < il; i++ )
      elements[ i ].className = 'newClass';
    

    You may want to replace the line:

    if ( elements[ i ].className.match( className ) )
    

    With some Regular Expression, but you will have to escape special characters in that case.

    0 讨论(0)
  • 2020-11-22 05:50

    This is a modern version based on Totally Pwn CSS with Javascript. It's ES6 I hope don't mind.

    function getCSSRule(ruleName) {
        ruleName = ruleName.toLowerCase();
        var result = null;
        var find = Array.prototype.find;
    
        find.call(document.styleSheets, styleSheet => {
            result = find.call(styleSheet.cssRules, cssRule => {
                return cssRule instanceof CSSStyleRule 
                    && cssRule.selectorText.toLowerCase() == ruleName;
            });
            return result != null;
        });
        return result;
    }
    

    This function returns a CSSStyleRule that you can use like this:

    var header = getCSSRule('#header');
    header.style.backgroundColor = 'red';
    

    Also document.styleSheets list references of the CSSStylesSheets Objects. Other way to acces a specific sytleSheet in the page is by assigning an id to the style or link element in the html code, and get it in javascript using document.getElementById('my-style').sheet. This are some useful methods:

    Major Browsers and IE9+ : insertRule(), deleteRule(), removeProperty().

    Major Browsers, Firefox? and IE9+ : setProperty().

    <stye id="my-style" ...
    ....
    var myStyle = document.getElementById('my-style').sheet
    myStyle.insertRule('#header { background: red; }', 0);
    

    It is also possible to dynamically create a new style element to store dynamic created styles, I think should be way to avoid conflicts.

    0 讨论(0)
  • 2020-11-22 05:53

    Depending on what you're trying to achieve, a better solution might be to change/add a class to a containing element (body would do!), and define classes accordingly.

    .yourclass { color: black }
    #wrapper.foo .yourclass { color: red }
    #wrapper.bar .yourclass { color: blue }
    

    then you can just use

    document.getElementById('wrapper').className='foo';
    

    (or your chosen js framework's wrapper for the same) to change everything with class yourclass inside whatever your wrapper element is.

    0 讨论(0)
  • 2020-11-22 05:55

    give your style tag an id, like <style id="ssID"> if someonelse is making your styles for you tell THAT person to give the style tag an id - that way you can access it directly without scrambling around wondering what its index is

    // create a hash table
    var cssHash = {};
    
    // loop through and populate the hash table
    for (let i in (r = ss0.sheet.rules)) {
    
        // selectorText is the name of the rule - set the value equal to the rule
        cssHash[r[i].selectorText] = r[i];
    
    }
    

    now you have a hash table for everything in the style sheet - note that some values will be undefined, but not for any of the things you care about

    if you have, for instance, a class called #menuItem and you want to change its color to black, do this

    cssHash['#menuItem'].style.color = #000;
    

    that line will set the color of the style of the rule whose index was looked up in the hash table (cssHash) by the name '#menuItem'

    more importantly, you probably have several different classes that you want to change all at once kind of like when you switched majors in college

    let's say you have four different classes and you want to set all of their background colors to the same value, that some user selected from an input

    the color selector tag is <input id="bColor" type="color"> and the class rules you want to change are called #menuItem .homeAddr span and #vacuum:hover

    // create a listener for that color selector
    bColor.addEventListener('input', function (e) {
    
      // loop through a split list of the four class names
      '#menuItem .homeAddr span #vacuum:hover'.split(' ').forEach(function (obj) {
    
        // use the hash table to look up the index of each name
        // and set the background color equal to the color input's value
        cssHash[obj].style.backgroundColor = bColor.value;
    
      });
    
    }, false); // false added here for the sake of non-brevity
    
    0 讨论(0)
  • 2020-11-22 05:56

    You can edit CLASS in document styleshets as follows

    [...document.styleSheets[0].cssRules].find(x=> x.selectorText=='.box')
         .style.background= 'red';
    

    function edit() {
      [...document.styleSheets[0].cssRules].find(x=> x.selectorText=='.box')
        .style.background= 'red';
    }
    .box {
      margin: 10px;
      padding: 10px;
      background: yellow;
    }
    <button onclick="edit()" >Click me</button>
    <div class="box" >My box 1</div>
    <div class="box" >My box 2</div>
    <div class="box" >My box 3</div>

    0 讨论(0)
提交回复
热议问题