简体   繁体   中英

How can I convert a nested javascript object into an inline string of CSS styles?

I have a javascript object that contains descriptions for CSS styles.

This object comes from a third-party API, so I am not able to modify the object.

I'd like to parse and output the object to a string.

The string needs to be useable as a inline styles in the head of my HTML.

I need to be able to map "base" and "invalid" to custom class names. These can be provided as variables.

The invalid > color needs to be mapped to a border color. Basically it comes from the object as "color", but I need to use it as a border color.

I've tried nesting loops and have just been extremely stuck trying to figure out an elegant solve to this problem.

Please, if you need more detail, ask me and I'll answer as best I can to help clarify.

The JavaScript Object I receive:

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

I need this to output as a sinlge-line string:

(I'm putting this on multiple lines to just make it easier to read here)

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

See CodePen of where I am at so far here:

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

I'm separating the object data into properties that go into the main rule and nested stuff that needs separate rules. Using recursion for the second part and Array functions like map() and join() , we get:

 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">

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM