如何在运行时更改/删除CSS类定义?

时间:2009-04-08 13:38:00

标签: javascript css

我知道可以通过JavaScript在运行时添加新的CSS类定义。但...

如何在运行时更改/删除CSS类定义?

例如,假设我有以下课程:

<style>
.menu { font-size: 12px; }
</style>

我想要的是,在运行时,更改font-size类的.menu规则,以便页面中使用此类的每个元素都会受到影响。

并且,我还想知道如何删除.menu类定义。

8 个答案:

答案 0 :(得分:23)

在运行时更改CSS规则并不困难,但显然很难找到所需的规则。 PPK在quirksmode.org上快速浏览了这个。

您需要使用document.styleSheets[i].cssRules这是一个您需要解析的数组,以找到您想要的数组,然后rule.style.setProperty('font-size','10px',null);

答案 1 :(得分:17)

我在http://twelvestone.com/forum_thread/view/31411找到了一个答案,我在这里逐字逐句复制部分内容,因为我担心这个主题和非常有用的答案会消失。

翻转2006.06.26,02:45 PM - [嘎吱嘎吱的青蛙] 帖子:2470加入日期:2003.01.26

经过大约10到12个小时的搜索,阅读和修修补补,我已经完成了!我今天是CSS / JS代码忍者!

使用的JS代码如下:

<script language="JavaScript">
function changeRule(theNumber) {
    var theRules = new Array();
    if (document.styleSheets[0].cssRules) {
        theRules = document.styleSheets[0].cssRules;
    } else if (document.styleSheets[0].rules) {
        theRules = document.styleSheets[0].rules;
    }
    theRules[theNumber].style.backgroundColor = '#FF0000';
}
</script>

我在FF(Mac),Safari(Mac),O9(Mac),IE5(Mac),IE6(PC),FF(PC)上进行了测试,它们都能正常工作。 'if'语句的原因是一些浏览器使用cssRules ...一些只使用规则...而唯一的另一个头发是你不能使用“background-color”来引用样式,你有删除连字符并将连字符后的第一个字母大写。

要引用您使用“changeRule(0)”的第一个CSS规则,第二个“changeRule(1)”和第三个“changeRule(2)”等等......

我还没有发现它无法使用的浏览器.... 你说的任何话都可以用来对付你。一遍又一遍。


BillyBones 2011.01.20,11:57 AM - [在桶里] 帖子:1加入日期:2011.01.20

您好,我在这些论坛注册只是为了添加这一点,因为我无法在其他地方找到它:

function changeStyle(selectorText)
{
    var theRules = new Array();
    if (document.styleSheets[0].cssRules) {
        theRules = document.styleSheets[0].cssRules;
    } 
    else if (document.styleSheets[0].rules) {
        theRules = document.styleSheets[0].rules;
    }
    for (n in theRules)
    {
        if (theRules[n].selectorText == selectorText)   {
            theRules[n].style.color = 'blue';
        }
    }
}

这简单地使CSS规则可以通过其选择器名称而不是cssRules数组中的索引号来识别。

换句话说,您可以使用字符串参数“selectorText”执行Javascript函数,而不是难以记住的数字,并且如果添加了新样式,则容易频繁更改。

感谢您进行10到12个小时的研究,Flip,我希望我做了一个有价值的补充。

答案 2 :(得分:12)

我认为你正在寻找这个:

http://www.hunlock.com/blogs/Totally_Pwn_CSS_with_Javascript

这允许您使用javascript更改实际规则。香港专业教育学院曾经使用过它,几年前它似乎已经奏效了。

答案 3 :(得分:6)

我为想要这样做的人做了一个简单的帮助功能:

function getCSSRule(search) {
  return [].map.call(document.styleSheets, function(item) {
    return [].slice.call(item.cssRules);
  }).reduce(function(a, b) {
    return b.concat(a);
  }).filter(function(rule) {
    return rule.selectorText.lastIndexOf(search) === rule.selectorText.length - search.length;
  })[0];
}

然后,您可以这样使用它:

getCSSRule('.mydiv').style.fontSize = '20px';

看一下下面的例子:

&#13;
&#13;
function getCSSRule(search) {
  return [].map.call(document.styleSheets, function(item) {
    return [].slice.call(item.cssRules);
  }).reduce(function(a, b) {
    return b.concat(a);
  }).filter(function(rule) {
    return rule.selectorText.lastIndexOf(search) === rule.selectorText.length - search.length;
  })[0];
}

document.querySelector('button').addEventListener('click', function(e) {
  getCSSRule('.iframe').style.backgroundColor = 'orange';
});
&#13;
.iframe {
  height: 200px;
  width: 200px;
  display: inline-block;
  border: 1px solid #000;
}
&#13;
<p>
  <button>Change .iframe background-color</button>
</p>
<div class="iframe"></div>
<div class="iframe"></div>
&#13;
&#13;
&#13;

答案 4 :(得分:0)

很难找到你想要的规则,因为你必须遍历document.styleSheets [i] .cssRules数组。 (并将您的类名与selectorText属性进行比较) 所以我对这个问题的解决方案是添加一个新的CSS类,从HTML元素中删除旧的CSS类并添加这个类而不是它。

&#13;
&#13;
var length = getCssRuleLength();
var newClassName = "css-class-name" + length;

//remove preview css class from html element.
$("#your-html-element").removeClass("css-class-name");
$("#your-html-element").removeClass("css-class-name" + (length-1));

$("#your-html-element").addClass(newClassName);

//insert a css class
insertCssRule("." + newClassName + ' { max-width: 100px; }', length);


function getCssRuleLength() {
	var length = 0;
	if (document.styleSheets[1].cssRules) {
		length = document.styleSheets[1].cssRules.length;
	} else if (document.styleSheets[1].rules) { //ie
		length = document.styleSheets[1].rules.length;
	}
	return length;
}
function insertCssRule(rule, index) {
	if (document.styleSheets[1].cssRules) {
		document.styleSheets[1].insertRule(rule, index);
	} else if (document.styleSheets[1].rules) { //ie
		document.styleSheets[1].addRule(rule, index);
	}
}
&#13;
&#13;
&#13;

答案 5 :(得分:0)

这是我一直在使用的一个尴尬的简单技巧,用于动态地处理CSS类规则,这避免了复杂性(如解析规则以找到所需的规则,如预期答案所示),甚至还提供了一些额外的功能免费提供灵活性。

(一个旁注:添加此答案的先前尝试在几秒钟内被即时降低了反馈,但没有反馈,这是自动通知目标的几个自动通知目标之一我不确定短暂的弯腰反应时间是否足以说明为什么这是一个可靠的解决方案,可以很好地涵盖OP的用例,尽管如此,我还是改了一下,因为猜测可能是某种原因引起的。或缺少分号(我现在已经为他添加了),缺少不必要的花括号(也添加了),缺少关于非效果的注释(添加了)或未使用足够复杂的方法(赢得了“无法修复,甚至简化了代码。)我确信他会再次匿名打,但仍会重试,因为这是一种值得使用的干净而可靠的技术。)

注意::这种方法假定您对页面的样式有足够的控制权,以确保不会通过不同的方法创建来创建相同的类规则。 (并且它期望HEAD元素存在。)

(此方法的一个潜在成本可能是在innerHtml上重新渲染,但是由于我们无论如何都在更改CSS,因此重新绘制迫在眉睫。此外,innerHtml已针对非显示的元素,这样浏览器就可以对其进行优化,即使有其他问题也可以。)

好。由于您可以can have个任意数量的STYLE个元素,因此将动态类包装在单独的元素中是非常好的。嗯,就是这样。 :)然后,向包装器id添加一个class,或者甚至更好的 * 一个STYLE属性,以便您实际上可以访问和操纵您的类规则就像是DOM元素一样。添加/替换时,只需确保将其包裹在<style class="..."> ... </style>中即可。

奖金:您还可以将多个相关规则归为一组,并根据需要一次替换掉所有规则(进行少量修改):

function replace_class(classname, block) {
    // Remove old:
    var s = document.head.querySelector("style." + classname);
    if (s) { document.head.removeChild(s); }

    // Just delete?
    if (!block) { return; }

    // Add new:
    s = document.createElement("style");
    s.className = classname;
    s.innerHTML = ("." + classname + block); // <style class="classname">.classname{...}</style>
    document.head.appendChild(s);
}

然后更新:replace_class("menu", "{font-size: 8px;}")

或删除:replace_class("menu", null)


*因为CSS适用于 every 元素,所以您可能想知道,如果新类的STYLE带有{ display: ...。好吧,如果 it would 放在none中!但是,由于我们将其添加到BODY中,因此跳过了渲染(当然,除非您也选择显示HEAD)。或者,您也可以改用HEAD,但随后您必须发明/使用适当的作用域/前缀,为什么要保留它,为什么还要保留呢? (而且我也喜欢设置id的微妙之处,无论如何它都是一个类包装器……)

答案 6 :(得分:-1)

我在这里采用了最好的答案,并将它们结合起来,以便于使用和跨浏览器兼容性。此外,如果页面上没有样式表,或者如果css规则尚不存在,我会在错误时报错。

https://github.com/Frazer/dynamicallyAccessCSS.js

答案 7 :(得分:-1)

以下是适用于任何给定规则选择器和规则更改函数的方法:

583d9ec

使用示例:

// general function for selecting rules and applying changes
function change_css_rules(changeRuleFunc, selectorFunc) {
    [].concat.apply([], // flattens arrays
        Array.from(document.styleSheets).map(function(sheet) { // each ss
            return Array.from(sheet.cssRules).filter(function(rule) { // each rule
                return selectorFunc(rule); // only select desired rules
            });
        })
    ).map(changeRuleFunc); // change the selected rules
}