有时我被迫以编程方式将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 } );
答案 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>