我需要在JavaScript中动态创建一个CSS样式表类,并将其分配给一些HTML元素,如- div,表,span, tr等,以及一些控件,如asp:Textbox,下拉列表和数据列表。
这可能吗?
要是有样品就好了。
我需要在JavaScript中动态创建一个CSS样式表类,并将其分配给一些HTML元素,如- div,表,span, tr等,以及一些控件,如asp:Textbox,下拉列表和数据列表。
这可能吗?
要是有样品就好了。
当前回答
简单地说,这在“所有浏览器”(特别是IE8/7)上都兼容:
function createClass(name,rules){
var style = document.createElement('style');
style.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(style);
if(!(style.sheet||{}).insertRule)
(style.styleSheet || style.sheet).addRule(name, rules);
else
style.sheet.insertRule(name+"{"+rules+"}",0);
}
createClass('.whatever',"background-color: green;");
最后一位将类应用于一个元素:
function applyClass(name,element,doRemove){
if(typeof element.valueOf() == "string"){
element = document.getElementById(element);
}
if(!element) return;
if(doRemove){
element.className = element.className.replace(new RegExp("\\b" + name + "\\b","g"));
}else{
element.className = element.className + " " + name;
}
}
这里还有一个小测试页面:https://gist.github.com/shadybones/9816763
关键的一点是,样式元素有一个“styleSheet”/“sheet”属性,你可以用它来添加/删除规则。
其他回答
为了搜索者的利益;如果你正在使用jQuery,你可以做以下事情:
var currentOverride = $('#customoverridestyles');
if (currentOverride) {
currentOverride.remove();
}
$('body').append("<style id=\"customoverridestyles\">body{background-color:pink;}</style>");
显然,你可以改变内部css为任何你想要的。
有些人更喜欢纯JavaScript,但它可以工作,并且在动态编写/覆盖样式方面非常健壮。
我在这里看了一些答案,我找不到任何自动添加一个新的样式表,如果没有,如果不是简单地修改一个现有的已经包含所需的样式,所以我做了一个新函数(应该跨所有浏览器工作,虽然没有测试,使用addRule和除了基本的本地JavaScript,让我知道它是否工作):
function myCSS(data) {
var head = document.head || document.getElementsByTagName("head")[0];
if(head) {
if(data && data.constructor == Object) {
for(var k in data) {
var selector = k;
var rules = data[k];
var allSheets = document.styleSheets;
var cur = null;
var indexOfPossibleRule = null,
indexOfSheet = null;
for(var i = 0; i < allSheets.length; i++) {
indexOfPossibleRule = findIndexOfObjPropInArray("selectorText",selector,allSheets[i].cssRules);
if(indexOfPossibleRule != null) {
indexOfSheet = i;
break;
}
}
var ruleToEdit = null;
if(indexOfSheet != null) {
ruleToEdit = allSheets[indexOfSheet].cssRules[indexOfPossibleRule];
} else {
cur = document.createElement("style");
cur.type = "text/css";
head.appendChild(cur);
cur.sheet.addRule(selector,"");
ruleToEdit = cur.sheet.cssRules[0];
console.log("NOPE, but here's a new one:", cur);
}
applyCustomCSSruleListToExistingCSSruleList(rules, ruleToEdit, (err) => {
if(err) {
console.log(err);
} else {
console.log("successfully added ", rules, " to ", ruleToEdit);
}
});
}
} else {
console.log("provide one paramter as an object containing the cssStyles, like: {\"#myID\":{position:\"absolute\"}, \".myClass\":{background:\"red\"}}, etc...");
}
} else {
console.log("run this after the page loads");
}
};
然后在上面的函数中或其他任何地方添加这两个helper函数:
function applyCustomCSSruleListToExistingCSSruleList(customRuleList, existingRuleList, cb) {
var err = null;
console.log("trying to apply ", customRuleList, " to ", existingRuleList);
if(customRuleList && customRuleList.constructor == Object && existingRuleList && existingRuleList.constructor == CSSStyleRule) {
for(var k in customRuleList) {
existingRuleList["style"][k] = customRuleList[k];
}
} else {
err = ("provide first argument as an object containing the selectors for the keys, and the second argument is the CSSRuleList to modify");
}
if(cb) {
cb(err);
}
}
function findIndexOfObjPropInArray(objPropKey, objPropValue, arr) {
var index = null;
for(var i = 0; i < arr.length; i++) {
if(arr[i][objPropKey] == objPropValue) {
index = i;
break;
}
}
return index;
}
(注意,在它们中我都使用了for循环而不是.filter,因为CSS样式/规则列表类只有一个length属性,而没有.filter方法。)
然后叫它:
myCSS({
"#coby": {
position:"absolute",
color:"blue"
},
".myError": {
padding:"4px",
background:"salmon"
}
})
让我知道它是否适用于您的浏览器或给出一个错误。
一个可以帮助您完成任务的有趣项目是JSS。
JSS是一个CSS的创作工具,它允许你使用JavaScript以一种声明性的、无冲突的和可重用的方式描述样式。它可以在浏览器、服务器端或在构建时在Node中编译。
JSS库允许您使用.attach()函数在DOM/head部分中进行注入。
Repl在线版本评估。
更多关于JSS的信息。
一个例子:
// Use plugins.
jss.use(camelCase())
// Create your style.
const style = {
myButton: {
color: 'green'
}
}
// Compile styles, apply plugins.
const sheet = jss.createStyleSheet(style)
// If you want to render on the client, insert it into DOM.
sheet.attach()
通过查看答案,最明显和最直接的是缺少:使用document.write()写出你需要的CSS块。
下面是一个例子(在codepen上查看:http://codepen.io/ssh33/pen/zGjWga):
<style>
@import url(http://fonts.googleapis.com/css?family=Open+Sans:800);
.d, body{ font: 3vw 'Open Sans'; padding-top: 1em; }
.d {
text-align: center; background: #aaf;
margin: auto; color: #fff; overflow: hidden;
width: 12em; height: 5em;
}
</style>
<script>
function w(s){document.write(s)}
w("<style>.long-shadow { text-shadow: ");
for(var i=0; i<449; i++) {
if(i!= 0) w(","); w(i+"px "+i+"px #444");
}
w(";}</style>");
</script>
<div class="d">
<div class="long-shadow">Long Shadow<br> Short Code</div>
</div>
这是我在Angular中行之有效的方法: 在HTML中,我有按钮与编程创建的CSS与特定的ID:
<button [id]="'hoverbutton1'+item.key" [ngClass]="getHoverButtonClass()">
<mat-icon class="icon">open_in_new</mat-icon>
</button>
在typescript中,我创建了CSS,并将其分配给给定ID的特定元素:
addClasses(){
var style1 = document.createElement('style');
style1.innerHTML = '.hoverbutton'+this.item.key+' { display: none; }';
document.getElementsByTagName('head')[0].appendChild(style1);
}
getHoverButtonClass() {
return "hoverbutton"+this.item.key
}
通过这种方式,我可以创建尽可能多的CSS类,并将它们单独分配给元素。:)