2017年答案
function parseCSSText(cssText) {
var cssTxt = cssText.replace(/\/\*(.|\s)*?\*\//g, " ").replace(/\s+/g, " ");
var style = {}, [,ruleName,rule] = cssTxt.match(/ ?(.*?) ?{([^}]*)}/)||[,,cssTxt];
var cssToJs = s => s.replace(/\W+\w/g, match => match.slice(-1).toUpperCase());
var properties = rule.split(";").map(o => o.split(":").map(x => x && x.trim()));
for (var [property, value] of properties) style[cssToJs(property)] = value;
return {cssText, ruleName, style};
}
描述
将以下cssText
(字符串)传递给函数:
.mybox {
display: block;
width: 20px;
height: 20px;
background-color: rgb(204, 204, 204);
}
...将会返回以下对象:
{ cssText: ... ,
ruleName: ".mybox",
style: {
"": undefined,
display: "block",
width: "20px",
height: "20px",
backgroundColor: "rgb(204, 204, 204)"
}
}
用户还可以传递包含
cssText
的内容,例如:
display: block; width: 20px; height: 20px; background-color: rgb(204, 204, 204);
特点:
- 既可与CSSRule.cssText一起使用,也可与CSSStyleDeclaration.cssText一起使用。
- 将CSS属性名称(
background-color
)转换为JS属性名称(backgroundColor
)。它甚至处理非常不规则的名称,例如back%gr- -ound---color: red;
(转换为backGrOundColor
)。
- 通过单个调用
Object.assign(document.body.style, parseCSSText(cssText).style)
,使现有CSSStyleDeclarations(如document.body.style
)进行大规模修改。
- 当属性名称没有值(没有冒号的条目)时,也不会失败,反之亦然。
- 更新于2017-09-28:在规则名称中也处理换行符,折叠空格。
- 更新于2017-09-28:处理注释(
/*...*/
)。
特点:
- 如果规则中的最后一个CSS声明以分号结尾,则返回的样式将包括一个空名称的属性
""
和一个undefined
值,反映了分号后面的空字符串。我认为这是正确的行为。
- 如果属性值(字符串文字)包括冒号或分号或CSS注释,例如
div :: before {content:'test:test2; / * test3 * /';}
,则该函数将返回错误结果。我不知道如何避免这种情况。
- 目前,它会将带有前缀的属性名(例如
-somebrowser-someproperty
)不正确地转换为SomebrowserSomeproperty
而不是somebrowserSomeproperty
。我想找到一种解决方法,既不会破坏代码的简洁性,又能够达到目的。
实时示例
function parseCSSText(cssText) {
var cssTxt = cssText.replace(/\/\*(.|\s)*?\*\//g, " ").replace(/\s+/g, " ");
var style = {}, [,ruleName,rule] = cssTxt.match(/ ?(.*?) ?{([^}]*)}/)||[,,cssTxt];
var cssToJs = s => s.replace(/\W+\w/g, match => match.slice(-1).toUpperCase());
var properties = rule.split(";").map(o => o.split(":").map(x => x && x.trim()));
for (var [property, value] of properties) style[cssToJs(property)] = value;
return {cssText, ruleName, style};
}
Example:
var sty = document.getElementById("mystyle");
var out = document.getElementById("outcome");
var styRule = parseCSSText(sty.innerHTML);
var outRule = parseCSSText(out.style.cssText);
out.innerHTML =
"<b>⦁ CSS in #mystyle</b>: " + JSON.stringify(styRule) + "<br>" +
"<b>⦁ CSS of #outcome</b>: " + JSON.stringify(outRule);
console.log(styRule, outRule);
<style id="mystyle">
.mybox1,
.mybox
{
display: block;
width: 20px; height: 20px;
background-color:
rgb(204, 204, 204);
-somebrowser-someproperty: somevalue;
}
</style>
<div id="outcome" style="
display: block; padding: 0.5em;
background-color: rgb(144, 224, 224);
">...</div>
<b style="color: red;">Also inspect the browser console.</b>
calc()
或rgba()
等函数符号?你想要如何生成变量名?对于选择器div > section:first-child ~ p:hover
,变量名会是什么样子? - Anders Marzi TornbladbackgroundColor
而不是background-color
,对吗? :) - Alan H.