如何将嵌套的 javascript 对象转换为 CSS 样式的内联字符串?
How can I convert a nested javascript object into an inline string of CSS styles?
我有一个 javascript 对象,其中包含 CSS 样式的描述。
这个对象来自第三方API,所以我无法修改这个对象。
我想解析对象并将其输出为字符串。
字符串需要在我的 HTML 的头部用作内联样式。
我需要能够将 "base" 和 "invalid" 映射到自定义 class 名称。这些可以作为变量提供。
无效的 > 颜色需要映射到边框颜色。基本上它来自对象 "color",但我需要将它用作边框颜色。
我已经尝试过嵌套循环,但在试图找到解决这个问题的优雅解决方案时一直非常困惑。
如果您需要更多详细信息,请问我,我会尽我所能回答以帮助澄清。
我收到的JavaScript对象:
{
style: {
base: {
color: '#46a0ba',
'::placeholder': {
color: '#000'
}
},
invalid: {
color: 'yellow'
}
},
}
我需要它作为单行字符串输出:
(我把它放在多行中只是为了让这里更容易阅读)
.baseClass { color: #46a0ba; }
.baseClass::placeholder {color: #000}
.invalidClass { border: 1px solid yellow; }
在此处查看我目前所在位置的 CodePen:
我将对象数据分成进入主规则的属性和需要单独规则的嵌套内容。对第二部分使用递归和数组函数,如 map()
和 join()
,我们得到:
const inputStyle = {
base: {
color: '#46a0ba',
padding: '0.5em',
'font-size': '14pt',
'::placeholder': {
color: '#000'
},
':hover': {
color: 'red'
}
},
invalid: {
color: 'yellow'
}
};
function rules(className, obj) {
const allProps = Object.entries(obj);
const directProps = allProps.filter(([key, value]) => typeof value == 'string');
const pseudoProps = allProps.filter(([key, value]) => typeof value == 'object');
const directStyle = `.${className} { ${directProps.map(([key, value]) => `${key}: ${value};`).join(' ')} }`;
const pseudoStyle = pseudoProps.map(([key, value]) => rules(className + key, value)).join(' ');
return [directStyle, pseudoStyle].join(' ');
}
function appendStyle(baseName, invalidName, styleObj) {
const styleElement = document.createElement("style");
styleElement.textContent = [rules(baseName, styleObj.base), `.${invalidName} { border: 1px solid ${styleObj.invalid.color}; }`].join(' ');
document.head.append(styleElement);
}
appendStyle("baseClass", "invalidClass", inputStyle);
body {
background-color: #eee;
}
<input class="baseClass" placeholder="placeholder">
<input class="baseClass invalidClass" value="hello">
我有一个 javascript 对象,其中包含 CSS 样式的描述。
这个对象来自第三方API,所以我无法修改这个对象。
我想解析对象并将其输出为字符串。
字符串需要在我的 HTML 的头部用作内联样式。
我需要能够将 "base" 和 "invalid" 映射到自定义 class 名称。这些可以作为变量提供。
无效的 > 颜色需要映射到边框颜色。基本上它来自对象 "color",但我需要将它用作边框颜色。
我已经尝试过嵌套循环,但在试图找到解决这个问题的优雅解决方案时一直非常困惑。
如果您需要更多详细信息,请问我,我会尽我所能回答以帮助澄清。
我收到的JavaScript对象:
{
style: {
base: {
color: '#46a0ba',
'::placeholder': {
color: '#000'
}
},
invalid: {
color: 'yellow'
}
},
}
我需要它作为单行字符串输出:
(我把它放在多行中只是为了让这里更容易阅读)
.baseClass { color: #46a0ba; }
.baseClass::placeholder {color: #000}
.invalidClass { border: 1px solid yellow; }
在此处查看我目前所在位置的 CodePen:
我将对象数据分成进入主规则的属性和需要单独规则的嵌套内容。对第二部分使用递归和数组函数,如 map()
和 join()
,我们得到:
const inputStyle = {
base: {
color: '#46a0ba',
padding: '0.5em',
'font-size': '14pt',
'::placeholder': {
color: '#000'
},
':hover': {
color: 'red'
}
},
invalid: {
color: 'yellow'
}
};
function rules(className, obj) {
const allProps = Object.entries(obj);
const directProps = allProps.filter(([key, value]) => typeof value == 'string');
const pseudoProps = allProps.filter(([key, value]) => typeof value == 'object');
const directStyle = `.${className} { ${directProps.map(([key, value]) => `${key}: ${value};`).join(' ')} }`;
const pseudoStyle = pseudoProps.map(([key, value]) => rules(className + key, value)).join(' ');
return [directStyle, pseudoStyle].join(' ');
}
function appendStyle(baseName, invalidName, styleObj) {
const styleElement = document.createElement("style");
styleElement.textContent = [rules(baseName, styleObj.base), `.${invalidName} { border: 1px solid ${styleObj.invalid.color}; }`].join(' ');
document.head.append(styleElement);
}
appendStyle("baseClass", "invalidClass", inputStyle);
body {
background-color: #eee;
}
<input class="baseClass" placeholder="placeholder">
<input class="baseClass invalidClass" value="hello">