将 CSS 对象转换为样式标签



有时我被迫以编程方式将CSS样式添加到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 对象可以很容易地与 JQuery 的 .css() 函数一起使用,但是一旦我想设置一个 css 伪类的样式(在我的示例中:hover),麻烦就开始了。在这种情况下,我无法使用 JQuery.css()函数,我回退到将相应的样式标签插入我的 DOM 中。

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

我用谷歌搜索并堆叠溢出,但找不到将我的 css 对象转换为样式标签的实用程序函数。 最后我写了我自己的函数(我可能会提供它作为这个问题的答案),但我仍然想知道是否有一个库函数。 实现此目的的最优雅的方法是什么?

编辑

我在 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 } );

下面是一个与 origin style 对象一起工作的示例: 我将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 看看它是如何工作的。

我的函数toStyleTag()背后的方法是,它styleTag首先使用 for...在语句中并检查styleTag是否具有selector的 OwnProperty() 。然后,我通过在对象上执行 Object.keys() 来减少 () 返回的数组,styleTag[selector],我通过连接要:分离的currentValue(属性)和styleTag[selector][currentValue]](规则)来连接accumulator。这样做可以styles成为property: rule形式的字符串数组。这是现在我们需要使用的格式 insertRule(),我们用它来将新的 CSS 规则插入到当前样式表中。请注意,我正在抓取cssRules的长度以查找索引 + 1,以便我们可以在样式表的最末尾插入此新规则以确保它不会被覆盖。

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>

我很想:

  • mouseover()上添加一个thumbHoverStyleCSS 对象;和
  • 将其替换为thumbDefaultStyleCSS 对象mouseout()

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

我想再试一次,因为这是一个有趣的问题。

这是我整理的原生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>

最新更新