首页 > 解决方案 > 如何将嵌套的 javascript 对象转换为 CSS 样式的内联字符串?

问题描述

我有一个包含 CSS 样式描述的 javascript 对象。

该对象来自第三方 API,因此我无法修改该对象。

我想解析对象并将其输出为字符串。

该字符串需要可用作我的 HTML 头部的内联样式。

我需要能够将“base”和“invalid”映射到自定义类名。这些可以作为变量提供。

无效的 > 颜色需要映射到边框颜色。基本上它来自作为“颜色”的对象,但我需要将它用作边框颜色。

我已经尝试过嵌套循环,并且一直非常努力地试图找出一个优雅的解决方案来解决这个问题。

请,如果您需要更多详细信息,请问我,我会尽力回答以帮助澄清。

我收到的 JavaScript 对象:

{
    style: {
        base: {
            color: '#46a0ba',
            '::placeholder': {
                color: '#000'
            }
        },
        invalid: {
            color: 'yellow'
        }
    },
}

我需要将其输出为单行字符串:

(我把它放在多行上,以便在这里更容易阅读)

.baseClass { color: #46a0ba; }
.baseClass::placeholder {color: #000}
.invalidClass { border: 1px solid yellow; }

请参阅 CodePen,了解我目前所处的位置:

https://codepen.io/fylzero/pen/gOOvdVp

标签: javascriptcssinline-styles

解决方案


我将对象数据分为进入主规则的属性和需要单独规则的嵌套内容。对第二部分使用递归和像map()and这样的数组函数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">


推荐阅读