将CSS-Object转换为样式标记

时间:2016-12-23 14:25:27

标签: javascript jquery html css typescript

有时我被迫以编程方式将DOM样式添加到DOM中(如果你需要一个理由:想象一下编写一个带有自己样式的小ui小部件但是应该只包含一个* .js文件为了更容易处理)。在这种情况下,我更喜欢使用对象表示法在我的脚本代码中定义样式,而不是使用混合规则,属性和标记的一个大字符串。

var thumbHoverStyle = {
    "background-color": "rgba(211, 211, 211, 0.5)",
    "cursor": "pointer"
};

var thumbHoverStyle = "<style> .thumb:hover { background-color: rgba(211, 211, 211, 0.5); cursor: pointer; } </style>";

这样的css-object可以很容易地与JQuery's .css() function一起使用,但是只要我想设置一个css pseudo-class(在我的例子中:悬停),问题就会开始。在这种情况下,我无法使用JQuery .css()函数,而是回退到我的DOM中插入相应的样式标记。

var thumbHoverStyleTag = toStyleTag( { ".thumb:hover": thumbHoverStyle } );
_root.append(thumbHoverStyleTag);

我用google搜索和stackoverflowed但找不到将我的css-object转换为样式标记的实用程序函数。 最后我编写了自己的函数(我可能会将它作为这个问题的答案),但我仍然想知道是否有一个库函数。 实现这一目标的最优雅方法是什么?

修改

我在TypeScript中的实现:

function appendPxIfNumber(value: any): string
{
    return (typeof value === "number") ? "" + value + "px" : value;
}

function toStyleTag(rulesObj: any)
{
    var combinedRules: string = "";
    for (var selector in rulesObj)
    {
        var cssObject = rulesObj[selector];
        var combinedProperties = "";
        for (var prop in cssObject) {
            var value = cssObject[prop];
            combinedProperties += `${prop}: ${appendPxIfNumber(value)};` + "\n";
        }
        combinedRules += ` ${selector} {${combinedProperties}}` + "\n";
    }
    return $(`<style>${combinedRules}</style>`);
}

用法示例:

var styleTag = toStyleTag( { ".thumb": thumbStyle, ".thumb:hover": thumbHoverStyle } );

4 个答案:

答案 0 :(得分:3)

这是一个与原始样式对象一起使用的工作示例: 我会将JSON转换为CSS。并定义一个应该设置样式的目标请记住,没有应该设置样式的选择器...所以我添加了一个targetSelector

var targetSelector='.thumb:hover',
    styleObj = {
      "background-color": "rgba(211, 211, 211, 0.5)",
      "cursor": "pointer"
    },

    // Convert the JSON into CSS
    styleTagContent = JSON.stringify(styleObj,null,'\t')
                          .replace(/"/g,'')
                          .replace(/,\n/g,';')
                          .replace(/\}/g, ';}')  



  $('<style>'+targetSelector+styleTagContent+'</style>').appendTo('head');

这是一个有效的Plunk,看看它是如何运作的。

答案 1 :(得分:1)

我的函数toStyleTag()背后的方法是首先使用for...in statement迭代styleTag并检查styleTag selector styleTag[selector] }。然后我hasOwnProperty()对对象accumulator执行reduce()返回的数组,currentValue styleTag[selector][currentValue]]加入:styles属性)和property: rule(规则)分开cssRules。这样做可以使var styleSheet = document.styleSheets[0]; function toStyleTag(styleTag) { for(var selector in styleTag) { if(styleTag.hasOwnProperty(selector)) { let styles = Object.keys(styleTag[selector]).reduce(function(accumulator, currentValue) { return accumulator.concat([currentValue, styleTag[selector][currentValue]].join(':')); }, []); styleSheet.insertRule(selector + '{' + styles.join(';') + '}', styleSheet.cssRules.length); } } } var thumbHoverStyle = { 'background-color': 'rgba(211, 211, 211, 0.5)', 'cursor': 'pointer' }; toStyleTag({ '.thumb:hover': thumbHoverStyle });成为<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="thumb"> <img src="http://placehold.it/350x350"> </div>形式的字符串数组。现在这是我们需要使用Object.keys()的格式,我们使用它来将新的CSS规则插入到当前样式表中。请注意,我正在抓取$elements.doSomething(continuation); 的长度以找到索引+ 1,这样我们就可以在样式表的最后插入这个新规则,以确保它不会被覆盖。

continuation
doSomething

答案 2 :(得分:0)

我很想:

  • thumbHoverStyle上添加mouseover() CSS对象;和
  • 将其替换为thumbDefaultStyle
  • 上的mouseout() CSS对象

var thumbStyle = {
    "width" : "100px",
    "height" : "100px",
    "text-align" : "center",
    "line-height" : "100px",
    "background-color": "rgb(211, 211, 211)"
};

var thumbHoverStyle = {
    "color" : "rgb(255,255,255)",
    "background-color": "rgb(255, 0, 0)",
    "cursor": "pointer"
};

var thumbDefaultStyle = {
    "color" : "rgb(0,0,0)",
    "background-color": "rgb(211, 211, 211)",
    "cursor": "default"
};

$(document).ready(function(){

    $('div').css(thumbStyle);

    $('input[type="checkbox"]').change(function(){

        if ($('input[type="checkbox"]').prop('checked')) {

            $('div').mouseover(function(){
                $(this).css(thumbHoverStyle);
            });

            $('div').mouseout(function(){
                $(this).css(thumbDefaultStyle);
            });
        }

        else {

            $('div').mouseover(function(){
                $(this).css(thumbDefaultStyle);
            });

            $('div').mouseout(function(){
                $(this).css(thumbDefaultStyle);
            });
        }
    });
});
div, button {
display: inline-block;
margin-right: 24px;
vertical-align: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>Hover Me</div>
<input type="checkbox" />Activate New Hover Behaviour

答案 3 :(得分:0)

我想再试一次,因为这是一个引人入胜的问题。

这是我放在一起的原生javascript解决方案:

var thumbStyle = {
    "width" : "100px",
    "height" : "100px",
    "text-align" : "center",
    "line-height" : "100px",
    "background-color": "rgb(211, 211, 211)"
};

var thumbHoverStyle = {
    "color" : "rgb(255,255,255)",
    "background-color": "rgb(255, 0, 0)",
    "cursor": "pointer"
};

var dynamicStyle = document.createElement('style');
document.head.appendChild(dynamicStyle);
var dynamicStyleSheet = dynamicStyle.sheet;

function addStyles(selector, cssStyleObject) {
    var properties = Object.keys(cssStyleObject);
    properties.forEach(function(property){
        var value = cssStyleObject[property];
      
        var dynamicRule = selector + ' {' + property + ': ' + value + ';}';
      
        dynamicStyleSheet.insertRule(dynamicRule, dynamicStyleSheet.cssRules.length);
    });
}

// Add styles dynamically by stating a selector and the name of a CSS Style Object

addStyles('div', thumbStyle);
addStyles('div:hover', thumbHoverStyle);
<div>Hover Me</div>