Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

JavaScript 操作样式表(StyleSheet)

  JavaScript对单个元素样式的操作很简单,只要操作元素上的style属性就可以了。但是有时候仅操作单个元素的样式无法达到我们需要的效果。当需要批量修改一大堆元素的样式时如果遍历修改就很浪费资源,这时候就可以直接操作样式表来实现批量修改样式。
  样式表实际上也是一个DOM节点,一般分为两种,一种是使用LINK标签引入的外部样式表文件,另一种是直接在文档中使用STYLE标签储存的样式表数据。它们必须存在与文档中才会生效,比如下面的代码我把样式表的标签删除了之后,它设置的样式也会失效。
<style id="s1">
div {color:blue;}
</style>
<style id="s2">
div {font-size:64px;}
</style>
<div>www.web-tinker.com</div>
<script>
//删除s2这个样式表元素
var s2=document.getElementById("s2");
s2.parentNode.removeChild(s2);
</script>

  s2这个STYLE元素被删除了,它设置的字体大小就失效了;而s1没有被删除,它设置的颜色可以生效。这里测试的是STYLE标签,LINK标签的删除也会让LINK引用的样式表文件失效,这里就不测试了。
  无论是STYLE标签设置的样式表还是LINK标签引用的外部样式表文件,当它们生效时候我们都可以在document.styleSheets中访问它们。这个对象是一个拟数组,里面包含了当前文档中的所有样式表。可以根据下标来获取某个样式表对象(CSSStyleSheet)。样式表对象的具体文档可以参考MDN上的(文章末尾有链接)。
  从这个样式表对象开始,后面的部分就存在巨大的浏览器差异了,先来看看IE8-的情况。我们可以访问样式表上rules这个属性来访问这个样式表中的每一个CSS规则对象。但是,在IE8-上通过rules访问到的CSS规则对象我们只能修改它的样式,而无法修改选择器(CSS规则是由样式和选择器组成的)。我们来看个测试代码
<style>
div {color:red;}
</style>
<div>www.web-tinker.com</div>
<script>
var s,r;
s=document.styleSheets[0];
r=s.rules[0];
r.style.color="blue"; //这句可以生效
r.selectorText="body"; //这句会错误
</script>

  修改样式的语句确实生效了,但是修改选择器的则错误。另外,IE8-下我们还无法单独插入或删除一条规则。但是可以直接操作整个样式表的CSS文本,通过从样式表的cssText属性来操作。下面是测试代码,这个测试就不截图了,只是把字体变成了蓝色而已。
<style>
table {color:red;}
</style>
<div>www.web-tinker.com</div>
<script>
var s;
s=document.styleSheets[0];
s.cssText="div {color:blue;}";
</script>
  总的来说,IE8-下的样式表对象对操作单个CSS规则我们能做的只有修改它的样式而已,功能很弱。不过修改整个样式表的CSS文本就很容易。如果实际项目中真有这样的需求,我们就可以换一下思维。把需要经常操作的样式单独存放的一个样式表中,这样就可以方便的操作了。
  接着是IE9+和现代浏览器的版本,或者说W3C标准。这个版本中样式表是通过cssRules这个属性来访问里面规则的。样式表对象还提供了insertRule和deleteRulell来插入或删除规则,这使得对样式表的规则更丰富。我们只要知道规则在这个样式表中的序号就可以删除它。插入规则时也需要带序号,因为CSS规则的优先级是和顺序有关的。下面就写个简单的例子吧。 <style>
div {color:red;}
div {font-size:32px;}
</style>
<div>www.web-tinker.com</div>
<script>
var s;
s=document.styleSheets[0];
//删除第二条样式,注意下标从0开始
s.deleteRule(1);
//在所有样式之前插入一条
s.insertRule("div {color:green;}",0);
//在所有样式之后插入一条
s.insertRule("div {color:blue;}",s.cssRules.length);
</script>

  删除样式的方法参数就是一个下标而已,没啥好说的。而插入样式时第二个参数是需要插入的样式插入后的位置,或者说,是在目标位置的上方插入的(貌似所有的insert都是上方插入的)。如果还觉得不明白自己修改改例子中的参数试试就知道。
  虽然这个标准的样式表对规则的插入删除很容易操作,但是要操作整个样式表的所有样式字符串就没那么容易了。如果真要操作,需要通过样式表所在的DOM节点来找出相应的STYLE元素,操作元素的textContent来修改整个样式表的字符串。而且使用LINK引入的样式表文件就无法操作了。下面是例子,测试结果和上一个测试一样的,我就不截图了。
<style>
table {color:red;}
</style>
<div>www.web-tinker.com</div>
<script>
var s;
s=document.styleSheets[0];
s.ownerNode.textContent="div {color:blue}";
</script>
  这个标准还有一个特点,还记得IE8-上CSS规则对象只能修改属性而不能修改选择器吗?这个标准的对象就可以修改选择器。下面是测试代码。 <style>
table {color:blue;}
</style>
<div>www.web-tinker.com</div>
<script>
var s;
s=document.styleSheets[0];
//把原来table的选择器改为div的
s.cssRules[0].selectorText="div";
</script>
  这个运行结果用大拇指猜都能猜到,和上一个测试的结果一样,文字变成蓝色的,我就不截图了。
  好了,到这里就把JavaScript对样式表的基本操作都整理了一遍,貌似内容很多了。不过这也只是皮毛,因为CSS3中有些东西已经脱离了选择器本身的概念,CSS规则变得未必是由一个选择器和一个样式构成的,所以处理起来会更复杂。后面的东西我也懒的研究了,反正目前对CSS3的奇葩需求也不高,等到以后真遇到问题了再再来研究吧~

参考:
  https://developer.mozilla.org/en-US/docs/DOM/CSSStyleSheet
  https://developer.mozilla.org/en-US/docs/DOM/CSSStyleRule
  http://msdn.microsoft.com/en-us/library/ie/ms535871.aspx
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^