Which JavaScript-framework can search CSS stylesheet rules and edit their properties?

后端 未结 4 1143
野趣味
野趣味 2021-02-01 23:22

The Question

Which JavaScript framework (prototype, script.aculo.us, Mootools, MochiKit...) has decent CSS rule editing support?

This is abou

相关标签:
4条回答
  • 2021-02-01 23:41

    None, but please prove me wrong...

    A decent implementation would have to discuss/document the following first:

    • how it walks the CSS tree (including @imports and @media)
    • how the walk can be configured (which @media and which sheets are considered)
    • how cross domain access restrictions are handled/circumvented
    • as CSS has no IDs for the rules itself: only the selector can act as a decent rule identifiers
      • as IE8 and below split up multi-selectors, how smart is the framework to handle this?
      • IE9 is worse (see quirksmode.org)
    • as multiple rules could be selected by one selector, how are they ordered?
    • how can the rule in charge be found from a rule-set knowing the property we want to edit?

    Until the frameworks catch up, consider:

    • get the style/link node where the rule you look for is in
    • use the node.sheet to go to the CSSStyleSheet directly
    • check quirksmode.org for quirks and f... IE
    • loop over the rules to find your rule(s) via known selector
    • DOM CSSStyleRule gives you all the power you need over any style rule
    0 讨论(0)
  • 2021-02-02 00:02

    There exist libraries like postCSS, which allows you to use a modular ecosystem of plugins to change your CSS styles programatically.

    0 讨论(0)
  • 2021-02-02 00:02

    The question by Robert Siemer explained:

    This is about changing a style rule. I want to have dynamic CSS classes which change.

    I wanted to give an answer that better defines the question for the readers who are looking for a similar thing and for the writers who mixed up the issue with updating the style of an element.

    The Beef

    I think the first part of the beef is to note that the browsers do allow manipulation of the existing stylesheets, as implied in this comment and analyzed in this answer. For example, the following line modifies padding-top value from 20px to 300px on the third rule in the second stylesheet of the document:

    document.styleSheets[1].cssRules[2].style.paddingTop = '300px'
    

    ... given index.html:

    <html>
    <head>
      <link type="text/css" href="foo.css"
      <link type="text/css" href="style.css">
    <head>
    <body><h1>Bar</h1></body>
    </html>
    

    ... and style.css:

    html, body { padding: 0; margin: 0 }
    body { color: black; }
    h1 { color: gray; padding-top: 20px; }
    

    The second part of the beef is how to find rules that match a criterion. The both parts have challenges in compatibility with older browsers, as discussed by the answer. If we forget compatibility issues and focus on how such a framework should roughly work, here is my minimal implementation in vanilla JavaScript.

    Microframework

    function forEachCSSRule (iteratee) {
      var i, j, crs
      for (i = 0; i < document.styleSheets.length; i += 1) {
        crs = document.styleSheets[i].cssRules
        for (j = 0; j < crs.lenght; j += 1) {
          iteratee(crs[j])
        }
      }
    }
    
    function getCSSRulesBySelector (selectorString) {
      var matched = []
      forEachCSSRule(function (cr) {
        if (cr.selectorText.includes(selectorString)) {
          matched.push(cr)
        }
      })
      return matched
    }
    
    function getCSSRulesByStyle (styleString) {
      var matched = []
      forEachCSSRule(function (cr) {
        if (cr.cssText.includes(styleString)) {
          matched.push(cr)
        }
      })
      return matched
    }
    

    With such a framework you can for example:

    var rules = getCSSRulesByStyle('display: none')
    rules.forEach(function (rule) {
      rule.style.display = 'block'
    })
    

    ... which is something the original question requested.

    0 讨论(0)
  • 2021-02-02 00:07

    As you noted, YUI has the StyleSheet utility http://developer.yahoo.com/yui/3/stylesheet/

    Example:

    var sheet = new Y.StyleSheet(styleNode);
    sheet.set('.hover, .foo:hover', {
        background: 'red',
        color: '#fff'
    });
    

    It also supports creating stylesheets from scratch by passing the constructor a string of css rules.

    Note that the same origin policy prevents accessing the rules of remotely sourced link nodes.

    It doesn't yet support accessing the rules as an object tree or accessing specific properties of rules. It does support removing rules or properties of rules, though. Today, the best you can do for working with the rules as objects would be something like

    var style = sheet.getCssText('.foo'),
        tmp = document.createElement('div');
    
    tmp.style.cssText = sheet.getCssText('.foo');
    if (tmp.style.display) { // does the rule include a setting for display
        ...
    }
    

    Since messing with stylesheets at runtime is pretty rarely the right solution, the utility hasn't had a lot of developer focus for adding features. Feature requests are welcome, of course.

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