在可以连续使用的对象内创建属性

时间:2013-04-10 03:31:35

标签: javascript

我是那种喜欢做很多项目的人,特别是如果它只涉及JavaScript,因为这是我的强项。

我想到了一个有趣的想法。用JavaScript编写一小块CSS。然后可以在Blob中使用这些CSS片段或以其他方式实现到网页中。

Most of the time, I do projects just for FUN and for build up in experience.

让我们更多地了解我们正在使用的内容。其中一个JavaScript样式表可能如下所示:

var sheet = {
    "h1": {
        "font-size": "24px",
            "color": "blue",
        children: {
            "a": {
                "font-size": "15px"
            }
        }
    },
    "a": {
        color: "red"
    }
};

这将返回:

h1{font-size:24px;color:blue}h1 a{font-size:15px}a{color:red}

请注意children元素中的h1属性。

这是我的嵌套方式,制作h1 a

然而,我的问题是,我怎样才能进行连续的嵌套,所以我最终会得到类似的东西:

“h1 div span a”

意味着每个嵌套的子项都需要能够使用children属性。

我到目前为止的脚本如下(属于变量sheet)。

var to = "";
for (var el in sheet) {
    var props = [];
    for (var prop in sheet[el]) {
        if(prop != "children") {
            props.push(prop + ":" + sheet[el][prop]);
        }
    }
    to += el + "{" + props.join(";") + "}";
    //----
    if (sheet[el].children) {
        for (var el2 in sheet[el].children) {
            var props = [];
            for (var prop in sheet[el].children[el2]) {
                props.push(prop + ":" + sheet[el].children[el2][prop]);
            }
            to += el + " " + el2 + "{" + props.join(";") + "}"
        }
    }
    //----
}

注释之间的部分是我用于1次嵌套的代码。

我不确定添加会有多困难。但我明白这可能并不容易。

我的完整示例在这里:http://jsfiddle.net/shawn31313/2tfnz/1

3 个答案:

答案 0 :(得分:2)

您可以非常轻松地使代码递归:

function buildCSS(stub, node){
    var to = "";
    for (var el in node) {
        var rule = stub + " " + el;
        var props = [];
        for (var prop in node[el]) {          
            if(prop != "children") {
                props.push(prop + ":" + node[el][prop]);
            }
        }
        to += rule + "{" + props.join(";") + "}";
        if (node[el].children) {
            to += buildCSS(rule, node[el].children);
        }
    }

    return to;
}

var to = buildCSS("", sheet);

这绝对可以清理,但它说明了这个想法。

http://jsfiddle.net/2tfnz/3/


您可能还会考虑对对象结构进行调整,以使代码更清晰:

var sheet = {
    "h1": {
        rules: {
            "font-size": "24px",
            "color": "blue"
        },
        children: {
            "a": {
                rules: {
                    "font-size": "15px"
                }
            }
        }
    },
    "a": {
        rules: {
            color: "red"
        }
    }
};

通过这种方式,您不需要区分名为children的属性和不属于的属性。

答案 1 :(得分:1)

http://jsfiddle.net/2tfnz/6/

将代码放在方法中,以便在找到子代时可以递归调用自身。这个允许childrendescendant属性并输出格式良好的CSS。

var sheet = {
    "h1": {
        "font-size": "24px",
        "color": "blue",
        children: {
            "a": {
                "font-size": "15px",
                descendants: {
                    "span": {
                        "font-weight": "bold"
                    }
                }
            }
        }
    },
    "a": {
        color: "red"
    }
};

function toCSS(obj, pre) {
    var str = '', pre = pre || '';

    for (var selector in obj) {
        str += pre + selector + ' {\n';

        var rules = obj[selector];
        for (var ruleKey in rules) {
            if (['descendants', 'children'].indexOf(ruleKey) > -1) continue;
            str += '  ' + ruleKey + ': ' + rules[ruleKey] + ';\n';
        }

        str += '}\n\n';

        if ('descendants' in rules) str += toCSS(rules.descendants, pre + selector + ' ');
        if ('children' in rules) str += toCSS(rules.children, pre + selector + ' > ');
    }

    return str;
}


console.log(toCSS(sheet));

答案 2 :(得分:0)

我喜欢你们所有人的代码。但是,我告诉我让代码递归的想法。

所以我做了:

        var to = "";
        for (var el in sheet) {
            var props = [];
            var nest = [el];
            var nestLookUp = {
                    "children": ">", 
                    "desendents": ""
            };
            var nests = /children|desendents/;
            var addNest = function (shh) {
                for (var found in nestLookUp) {
                    if (shh.hasOwnProperty(found)) {
                        for (var el2 in shh[found]) {
                            var props = [];
                            nest.push(nestLookUp[found]);
                            nest.push(el2);
                            for (var prop in shh[found][el2]) {
                                if (!prop.match(nests)) {
                                    props.push(prop + ":" + shh[found][el2][prop]);
                                }
                            }
                            if (props.length > 0) {
                                to += nest.join(" ").replace(/\s{2}/, " ") + "{" + props.join(";") + "}";
                            }
                            addNest(shh[found][el2]);
                            nest.pop();
                            nest.pop();
                        };
                    }
                }
            };
            for (var prop in sheet[el]) {
                if (prop != "children") {
                    props.push(prop + ":" + sheet[el][prop]);
                }
            }
            to += el + "{" + props.join(";") + "}";
            addNest(sheet[el]);
        }

@Trevor - 你对descendants的想法很好:)

我的代码比Trevors稍长,但个人更容易管理。 (39行他20岁)

我通常喜欢制作自己的代码,因为我通常会理解代码是如何工作的。

哈,看着你们的代码,我有点困惑。