问题 Javascript /将CSS样式字符串转换为JS对象


我们想将作为字符串输入的CSS样式转换为JS对象。

例如。,

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

预期的JS对象:

 {
    border:"solid 1px",
    color:"red"
 }

当然,样式条目的数量是无限的,以及样式的名称(边框,颜色,字体,z-index等)。谢谢。


3064
2018-03-01 15:29


起源

测试表明,只有jAndy和mjac的答案才能正常运行。其他人忘记了空白。 - kirilloid
jsperf.com/style-tag-to-object 比较一些已发布的答案 - CodeToad


答案:


您可以使用Javascript拆分功能: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/split

首先拆分字符串 ; 作为分隔符,然后为每个结果分割 :,将物品放在物体中。

例如

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(':');
}

2
2018-03-01 15:33



如果有的话就行不通 ':' 在CSS值。例如。 background-image: url('http://example.com/image.png')。通过仅在第一个上拆分来修复 ':',例如 entry = attributes[i].split(/:(.+)/)。 - Peter Le Bek
简短而简单,但它不能很好地处理空间。常见的css用法在冒号之后有一个空格,例如 'background: red' ......但这会产生 { background: ' red' } (注意之前不必要的空间 红) - James Lawson
如果这失败了 ; 存在于 content: "..." 属性 - matsko


一个非常简单的:

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


7
2017-10-09 04:46



只是一个注意事项:它应该没什么关系,但请注意 match[2] 不会在右侧修剪。 :-) - nunocastromartins
编辑,谢谢。 - shuji


所有的答案似乎需要大量的分裂 - 为什么不进行比赛并一次性获得所有对?

function cssSplit(str){
    var O= {},
    S= str.match(/([^ :;]+)/g) || [];
    while(S.length){
        O[S.shift()]= S.shift() || '';
    }
    return O;
}

2
2018-03-01 16:26



拆分有什么问题?是的,你可以说它需要(稍微)一点,但我怀疑我们在这里谈论成千上万的css属性。即便如此,我敢打赌你的匹配计算强度相近 S=str.split(/[ :;]+/);。 - Jeff B
此解决方案需要更长时间,导致转换速度缓慢。但是代码的大小较小。 - kirilloid
不要在Regexp中使用空格,请使用 \s 代替: [^\s:;] - Roko C. Buljan


在功能形式:

var styleInput = " border:solid 1px; color:red ";

var result = styleInput.split(';').reduce(function (ruleMap, ruleString) {
    var rulePair = ruleString.split(':');
    ruleMap[rulePair[0].trim()] = rulePair[1].trim();

    return ruleMap;
}, {});

在将字符串用作对象键之前修剪字符串。


2
2018-03-01 15:42



不需要修剪空白......假设...... cl.ly/392n3b0j2U2I2f232G2S - jondavidjohn
Trim并非在所有浏览器中都可用 - kirilloid
@jondavidjohn并非所有浏览器都是相同的。 ({" trimmed":1}).trimmed  - > undefined - kirilloid
修剪需要JS 1.8.1,但这不在问题的范围内。 - Michael Clark


只是为了好玩和完整......

我没有检查过跨浏览器兼容性(仅在Chrome中尝试过),它有一些怪癖:

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;
}

怪癖是即使我们传入一个单一的 margin 声明,我们得到一个像这样的对象

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

根据你所追求的目标,这可能是好事也可能是坏事。


1
2017-07-02 23:18





const css2obj = css => {
	
  const r = /(?<=^|;)\s*([^:]+)\s*:\s*([^;]+)\s*/g, o = {};
  css.replace(r, (m,p,v) => o[p] = v);
  return o;
	
}

console.log( css2obj("z-index: 4; opacity:1; transition-duration: 0.3s;") )

如果你想转换 dash-case JS表示的CSS属性 camelCase, 代替 p 使用 p.replace(/-(.)/g, (m,p) => p.toUpperCase())


Oldschool JS:

function cssToObj(css) {
    var obj = {}, s = css.toLowerCase().replace(/-(.)/g, function (m, g) {
        return g.toUpperCase();
    }).replace(/;\s?$/g,"").split(/:|;/g);
    for (var i = 0; i < s.length; i += 2)
        obj[s[i].replace(/\s/g,"")] = s[i+1].replace(/^\s+|\s+$/g,"");
    return obj;
}


console.log( cssToObj("z-index: 4; opacity:1; transition-duration: 0.3s;") );


1
2017-07-01 05:32





这样的事情会让你非常接近:

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

...转弯

" border:solid 1px; color:red "

{ 
    border:"solid 1px", 
    color:"red ",
}

0
2018-03-01 15:41





这是我将CSS字符串转换为对象的函数:

function cssConverter(style) {
    var result = {},
        attributes = style.split(';'),
        firstIndexOfColon,
        i,
        key,
        value;

    for(i=0; i<attributes.length; i++) {
        firstIndexOfColon = attributes[i].indexOf(":");
        key = attributes[i].substring(0, firstIndexOfColon);
        value = attributes[i].substring(firstIndexOfColon + 1);

        key = key.replace(/ /g, "");
        if(key.length < 1){
            continue;
        }

        if(value[0] === " "){
            value = value.substring(1);
        }

        if(value[value.length - 1] === " "){
            value = value.substring(0, value.length - 1);
        }

        result[key] = value;
    }

    return result;
};

0
2017-08-29 09:59