CSS parser for JavaScript?

后端 未结 7 1071
既然无缘
既然无缘 2020-12-13 19:45

Update 2018: This question was asked long before PostCSS existed, and I would have probably used that.

I\'d like to par

相关标签:
7条回答
  • 2020-12-13 19:57

    No need use external css parser,we can use native css parser

       
    var sheetRef=document.getElementsByTagName("style")[0];
    
    console.log("----------------list of  rules--------------");
    for (var i=0; i<sheetRef.sheet.cssRules.length; i++){
    
    
    var sheet = sheetRef.sheet ? sheetRef.sheet : sheetRef.styleSheet;
    
    
    if (sheet.cssRules.length > 0) {
    //console.log(sheet.cssRules[i]);
      console.log(sheet.cssRules[i].selectorText);
      console.log(sheet.cssRules[i].cssText);
    
                    }}
    .red{
    
    color:red;
    }

    To Insert Rule

    var sheetRef=document.getElementsByTagName("style")[0];
    var sheet = sheetRef.sheet ? sheetRef.sheet : sheetRef.styleSheet;
    sheet.insertRule('.foo{color:red;}', 0);
    

    To Remove Rule all browsers, except IE before version 9

    var sheetRef=document.getElementsByTagName("style")[0];
    var sheet = sheetRef.sheet ? sheetRef.sheet : sheetRef.styleSheet;
    sheet.removeRule (0);
    

    To Delete Rule all browsers, except IE before version 9

    var sheetRef=document.getElementsByTagName("style")[0];
    var sheet = sheetRef.sheet ? sheetRef.sheet : sheetRef.styleSheet;
    sheet.deleteRule (0);
    

    To add Media

      function AddScreenMedia () {
                var styleTag = document.getElementsByTagName("style")[0];
    
                    // the style sheet in the style tag
                var sheet = styleTag.sheet ? styleTag.sheet : styleTag.styleSheet;
    
                if (sheet.cssRules) {   // all browsers, except IE before version 9
                    var rule = sheet.cssRules[0];
                    var mediaList = rule.media;
    
                    alert ("The media types before adding the screen media type: " + mediaList.mediaText);
                    mediaList.appendMedium ("screen");
                    alert ("The media types after adding the screen media type: " + mediaList.mediaText);
                }
                else {  // Internet Explorer before version 9
                        // note: the rules collection does not contain the at-rules
                    alert ("Your browser does not support this example!");
                }
            }
      @media print {
                body {
                    font-size: 13px;
                    color: #FF0000;
                }
              }
    some text
    <button onclick="AddScreenMedia ();">Add screen media</button>

    To get rules

     
    var sheetRef=document.getElementsByTagName("style")[0];
    
    console.log("----------------list of  rules--------------");
    for (var i=0; i<sheetRef.sheet.cssRules.length; i++){
    
    
    var sheet = sheetRef.sheet ? sheetRef.sheet : sheetRef.styleSheet;
    
    
    if (sheet.cssRules.length > 0) {
    //console.log(sheet.cssRules[i]);
      console.log(sheet.cssRules[i].selectorText);
      console.log(sheet.cssRules[i].cssText);
      
      console.log(sheet.cssRules[i].style.color)
      console.log(sheet.cssRules[i].style.background)
        console.log(sheet.cssRules[i].style)
    
                    }}
    .red{
    
    color:red;
    background:orange;
    }
    <h1>red</h1>

    0 讨论(0)
  • 2020-12-13 19:59

    Also worth mentioning is LESS. While it is primarily a (fantastic) extension to CSS, the LESS parser does give you access to the AST.

    A pure CSS stylesheet is also a valid LESS stylesheet, so you can start with what you have now and ease in to LESS' extensions.

    0 讨论(0)
  • 2020-12-13 20:00

    Edit

    I ended up using this library which was light enough for my implementation (provided in Kemal Dağ's answer). Other options were too heavy for the client-side implementation I was after.

    https://github.com/jotform/css.js

    Original Content

    a paid nerd's original answer worked great until I hit media queries.

    I had to add some recursion and this is what I ended up with.

    Forgive me for the TypeScript.

    TypeScript Implementation

    private scopeCSS(css: string): CSS.Stylesheet {
      let ast: CSS.Stylesheet = CSS.parse(css);
      let stylesheet: CSS.StyleRules|undefined = ast.stylesheet;
      if (stylesheet) {
        let rules: Array<CSS.Rule|CSS.Media> = stylesheet.rules;
        let prefix = `[data-id='sticky-container-${this.parent.id}']`;
    
        // Append our container scope to rules
        // Recursive rule appender
        let ruleAppend = (rules: Array<CSS.Rule|CSS.Media>) => {
          rules.forEach(rule => {
            let cssRule = <CSS.Rule>rule;
            let mediaRule = <CSS.Media>rule;
            if (cssRule.selectors !== undefined) {
              cssRule.selectors = cssRule.selectors.map(selector => `${prefix} ${selector}`);
            }
            if (mediaRule.rules !== undefined) {
              ruleAppend(mediaRule.rules);
            }
          });
        };
    
        ruleAppend(rules);
      }
      return ast;
    }
    

    Babel'ized Vanilla JS Implementation

    function scopeCSS(css, prefix) {
      var ast = CSS.parse(css);
      var stylesheet = ast.stylesheet;
      if (stylesheet) {
        var rules = stylesheet.rules;
        // Append our container scope to rules
        // Recursive rule appender
        var ruleAppend = function(rules) {
          rules.forEach(function(rule) {
            if (rule.selectors !== undefined) {
              rule.selectors = rule.selectors.map(function(selector) {
                return prefix + " " + selector;
              });
            }
            if (rule.rules !== undefined) {
              ruleAppend(rule.rules);
            }
          });
        };
        ruleAppend(rules);
      }
      return ast;
    }
    
    0 讨论(0)
  • 2020-12-13 20:13

    Here is our open source CSS parser css.js

    Here is a simple parsing example :

    <script type="text/javascript">
        var cssString = ' .someSelector { margin:40px 10px; padding:5px}';
        //initialize parser object
        var parser = new cssjs();
        //parse css string
        var parsed = parser.parseCSS(cssString);
    
        console.log(parsed);
    </script>
    

    To stringify parsed data structure into CSS string after editing

    var newCSSString = parser.getCSSForEditor(parsed);
    

    Main features of our CSS parser is :

    • It is lightweight.
    • It outputs easy to understand javascript object. No complex AST.
    • It is battle tested(and unit tested also) and constantly used in our products(JotForm Form Designer).
    • It supports media queries, keyframes and font-face rules.
    • It preserves comments while parsing.
    0 讨论(0)
  • 2020-12-13 20:13

    http://www.glazman.org/JSCSSP/

    http://jsfiddle.net/cYEgT/

    sheet is sort of like an AST.

    0 讨论(0)
  • 2020-12-13 20:14

    Update: I previously mentioned JSCSSP, which is buggy seems to be abandoned. Obviously enough, the css module on NPM is the best:

    css = require 'css'
    
    input = '''
      body {
        font-family: sans-serif;
      }
      #thing.foo p.bar {
        font-weight: bold;
      }
    '''
    
    obj = css.parse input
    sheet = obj.stylesheet
    
    for rule in sheet.rules
      rule.selectors = ('#XXX ' + s for s in rule.selectors)
    
    console.log css.stringify(obj)
    

    Output:

    #XXX body {
      font-family: sans-serif;
    }
    #XXX #thing.foo p.bar {
      font-weight: bold;
    }
    
    0 讨论(0)
提交回复
热议问题