Javascript / convert CSS style string into JS object

后端 未结 10 982
粉色の甜心
粉色の甜心 2021-01-04 08:41

We\'d like to convert a CSS style entered as string into a JS object.

E.g.,

 var input = \" border:solid 1px; color:red \";

expec

相关标签:
10条回答
  • 2021-01-04 08:54

    You could use the Javascript split function: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/split

    First split the string with ; as the separator, and then for each result split with :, placing the items in an object as you go.

    e.g.

    var result = {},
        attributes = input.split(';');
    
    for (var i = 0; i < attributes.length; i++) {
        var entry = attributes[i].split(':');
        result[entry.splice(0,1)[0]] = entry.join(':');
    }
    
    0 讨论(0)
  • 2021-01-04 08:56

    Now you can use a third-party library such as style-to-object. For example:

    import parse from 'style-to-object';
    
    const input = " border:solid 1px; color:red ";
    parse(input); // => {border: "solid 1px", color: "red"}
    
    0 讨论(0)
  • 2021-01-04 08:59

    something like this should get you pretty close:

    var input = " border:solid 1px; color:red ";
    var output = '{' + input.replace(/([\w-.]+)\s*:([^;]+);?/g, '\n    $1:"$2",') + '\n}';
    

    ...turns

    " border:solid 1px; color:red "
    

    into

    { 
        border:"solid 1px", 
        color:"red ",
    }
    
    0 讨论(0)
  • 2021-01-04 09:07

    A very simple one:

    var regex = /([\w-]*)\s*:\s*([^;]*)/g;
    var match, properties={};
    while(match=regex.exec(cssText)) properties[match[1]] = match[2].trim();
    

    https://regex101.com/r/nZ4eX5/1

    0 讨论(0)
  • 2021-01-04 09:16

    Just for fun and for completeness…

    I haven't checked cross-browser compatibility (only tried in Chrome), and it has some quirks:

    var input = "font-weight:bold; color: blue; margin: 0 15px";
    
    var e = document.createElement("div");
    e.setAttribute("style", input);
    
    var output = {};
    
    for (var i = 0; i < e.style.length; i++) {
      var name = e.style[i];
      var value = e.style.getPropertyValue(name);
      output[name] = value;
    }
    

    The quirk is that even though we passed in a single margin declaration, we get an object like

    {
      color: "blue",
      font-weight: "bold",
      margin-bottom: "0px",
      margin-left: "15px",
      margin-right: "15px",
      margin-top: "0px",
    }
    

    This might be a good or a bad thing depending on what you're after.

    0 讨论(0)
  • 2021-01-04 09:17

    If you want a tagged template literal syntax that works easily with React, you could do

    const camelCase = str => str.replace(/-(.)/g, (_,p) => p.toUpperCase())
    
    const css2obj = (strings, ...vals) => {
      const css = strings.reduce((acc, str, i) => acc + str + (vals[i] || ''), '')
      const r = /(?<=^|;)\s*([^:]+)\s*:\s*([^;]+)\s*/g, o = {}
      css.replace(r, (m,p,v) => o[camelCase(p)] = v)
      return o
    }
    
    const center = 'center'
    
    const reactInlineCSS = css2obj`
      align-items: ${center};
      justify-content: ${center};
    `
    
    console.log(reactInlineCSS)

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