R·ex / Zeng


音游狗、安全狗、攻城狮、业余设计师、段子手、苦学日语的少年。

【教程】用JavaScript控制CSS规则

注意:本文发布于 3558 天前,文章中的一些内容可能已经过时。

兼容性:IE≥9

难度:中等

有时候网页要适配多种分辨率,我们自然想到用百分比来控制大小。但是百分比不是万能的。例如,你想让一屏幕显示十行表格,但是你并不知道屏幕有多高,因此需要用 JavaScript 的 window.innerHeight 获取屏幕高度。但是如何修改 CSS 呢?

第一种方法:直接设置某元素的属性

document.getElementById('xxx').style.height = window.innerHeight / 10 + 'px';

元素的 style 属性是一个 CSS 集合,里面的内容可以直接调。对于 margin-left 这样的复合词,要用 marginLeft 代替。注意要用小驼峰写法(第一个单词小写,其余的单词首字母大写,中间无连字符)。

此方法唯一的不足之处在于,每次只能修改一个元素的样式。

第二种方法:修改元素拥有的 class 的样式

表示之前不会。经过各种搜索之后,在 这个网站 上找到了解决方案。大体内容是这样如下。

document 这个大的对象里,有个叫 styleSheets 的数组,是引入的 CSS 文件列表,例如 document.styleSheets[0] 是引入的第一个文件。用 Chrome 的终端看一下效果:

样式表

其中 disabled 表示该样式表是否启用,href 是样式表路径……其实我们关心的是 rules 的值。

CSS规则

很清楚了吧,这就是一条条 CSS 的规则。其中对象的 style 跟上一个方法的 style 是一个东西,可以直接调用了。例如我要把这个 .popupdisplay 设成 block,可以这么写:

document.styleSheets[0].rules[2].style.display = 'block';

有点麻烦呢。更麻烦的是,在 IE 中对 rules 的解释还不一样(一般比 Chrome 多出几条,不知道为什么),还有在 Firefox 中压根就没有 rules 这个东西,取而代之的是 cssRules!浏览器们,能不能统一一下标准啊……

不过还好,可以写一段 JavaScript 来简化工作(代码经我简化过,与网站上的代码功能完全相同):

function getStyle(sname) {
    var rules;
    for (var i = 0; i < document.styleSheets.length; i++) {
        if (!(rules = document.styleSheets[i].cssRules))
            rules = document.styleSheets[i].rules;
        for (var j = 0; j < rules.length; j++)
            if (rules[j].selectorText == sname)
                return rules[j].style;
    }
}

解释一下用法好了。sname 是我们需要找的 CSS 选择器(例如 .icon_add),返回的结果是最终的那个 style,所以用起来很简单,例如:getStyle('.icon_add').display = 'block'。当然副作用还是有的,毕竟是直接调用我们的 CSS 文件,所以当我们的选择器比较特殊的时候(例如 html, body, #content > div),我们必须完整地敲出这个选择器(只敲 body 是没法匹配的哦)。

下面的内容是解释代码含义的,没兴趣的可以跳过了。

首先,外层循环是在枚举 styleSheets 数组的元素,里面那个 if 是为了兼容 Firefox 的(我没有犯将 == 打成 = 的错误,那里就是 =)——如果没有 cssRules 的话,就用 rules 吧。

内层循环就是枚举 rules 啦,用 selectorText 跟你的 sname 进行比较,如果相同的话就返回该条规则的 style,用起来很方便的。

Disqus 加载中……如未能加载,请将 disqus.com 和 disquscdn.com 加入白名单。

这是我们共同度过的

第 3077 天