我将以下文字作为JavaScript字符串
.mybox {
display: block;
width: 20px;
height: 20px;
background-color: rgb(204, 204, 204);
}
我想转换为JavaScript对象
var mybox = {
'display': 'block',
'width': '20px',
'height': '20px';
'background-color': 'rgb(204, 204, 204)';
};
任何想法或已制作的脚本?
答案 0 :(得分:9)
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};
} /* updated 2017-09-28 */
将以下cssText
(字符串)传递给函数:
.mybox {
display: block;
width: 20px;
height: 20px;
background-color: rgb(204, 204, 204);
}
...将提供以下对象:
{ cssText: ... /* the original string including new lines, tabs and spaces */,
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);
特点:
background-color
)到JS属性名称(backgroundColor
)。
它处理甚至非常不稳定的名字,
例如back%gr- -ound---color: red;
(转换为backGrOundColor
)。document.body.style
)使用
一个电话
Object.assign(document.body.style, parseCSSText(cssText).style)
。/*...*/
)。怪癖:
""
的空属性
一个undefined
值,反映了后面的空字符串
分号。我认为这是一种正确的行为。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};
} /* updated 2017-09-28 */
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); /* Inspect result in the console. */
&#13;
<style id="mystyle">
.mybox1, /* a comment
and new lines
to step up the game */
.mybox
{
display: block;
width: 20px; height: 20px;
background-color: /* a comment
and a new line */
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>
&#13;
答案 1 :(得分:6)
这是解析器的开始,可以做你想要的。当然它需要工作,特别是如果你想处理可能提供的任何通用CSS。这假设输入css是按照您提供的方式编写的,第一行是属性的名称,最后一行是'}',依此类推。
如果您不想只处理基本属性,编写复杂的解析器并不是一件容易的事。例如,如果您声明如下内容,那该怎么办?
input[type="text"],
table > tr:nth-child(2),
#link a:hover {
-webkit-transition: width 2s; /* Safari and Chrome */
}
这是有效的CSS,但是如何从中提取有效的javascript变量名?如何将-webkit-transition
转换为有意义的属性名称?整个任务闻起来就像你做错了。我没有在解析器上工作,而是在处理一个更稳定的解决方案。
顺便说一句,这是您可以从以下开始的代码:
var s = '.mybox {\n';
s += 'display: block;\n';
s += 'width: 20px;\n';
s += 'height: 20px;\n';
s += 'background-color: rgb(204, 204, 204);\n';
s += '}\n';
// split css by line
var css_rows = s.split('\n');
// filter out empty elements and strip ';'
css_rows = css_rows.filter(function(x){ return x != '' }).map(function(x){ return x.trim().replace(';', '') });
// create object
var json_name = css_rows[0].trim().replace(/[\.\{\ \#]/g, '');
eval('var ' + json_name + ' = {};');
// remove first and last element
css_rows = css_rows.splice(1, css_rows.length-2)
for (elem in css_rows)
{
var elem_parts = css_rows[elem].split(':');
var property_name = elem_parts[0].trim().replace('-', '');
var property_value = elem_parts[1].trim();
eval(json_name + '.' + property_name + ' = "' + property_value + '";');
}
答案 2 :(得分:1)
如果CSS文档包含在html文档中,以便实际加载样式声明,您可以像这样在Javascript中逐步执行所有样式:
// Get all style sheet documents in this html document
var allSheets = document.styleSheets;
for (var i = 0; i < allSheets.length; ++i) {
var sheet = allSheets[i];
// Get all CSS rules in the current style sheet document
var rules = sheet.cssRules || sheet.rules;
for (var j = 0; j < rules.length; ++j) {
var rule = rules[j];
// Get the selector definition ("div > p:first-child" for example)
var selector = rule.selectorText;
// Create an empty object to put the style definitions in
var result = {};
var style = rule.style;
for (var key in style) {
if (style.hasOwnProperty(key)) {
result[key] = style.cssText;
}
}
// At this point, you have the selector in the
// selector variable (".mybox" for example)
// You also have a javascript object in the
// result variable, containing what you need.
// If you need to output this as json, there
// are several options for this.
}
}
如果这不是您想要的,就像您要解析CSS文档并创建JavaScript源文件一样,您需要查看词法解析器,CSS文档对象模型,JSON序列化以及类似的东西......
答案 3 :(得分:0)
我在使用LeafLet尝试将CSS样式与JavaScript代码分开时遇到了同样的问题......我最终得到了这个:
local mod_arg = { }
for k, v in pairs(arg) do
if v:find"'" then
mod_arg[k] = '"'..v..'"'
elseif v:find'[%s$`><|#]' then
mod_arg[k] = "'"..v.."'"
else
mod_arg[k] = v
end
end
local command = table.concat(mod_arg, ' ', -1, #mod_arg)
print(command)
这会产生这样的结果: