DOM系列:动态添加CSS样式规则

在上一节中学习了如何通过JavaScript来修改CSS样式。简单地说:查询CSS样式(即计算样式),设置单个样式(设置的是行内样式),设置多个样式(通过类来设置样式)。即:

  • 通过DOM Element对象的getAttribute()setAttribute()removeAttribute()等方法修改元素的style属性

  • 通过对元素节点的style来读写行内CSS样式

  • 通过style对象的cssText属性来修改全部的style属性

  • 通过style对象的setProperty()getPropertyValue()removeProperty()等方法来读写行内CSS样式

  • 通过window.getComputedStyle()方法获得浏览器最终计算的样式规则

  • 通过classNameclassList给元素添加或删除类名,配合样式文件来修改元素样式

可以说上面这些都是通过DOM元素来增、删、改、查CSS样式。事实上我们还可以通过脚本化CSS这种技术来控制样式。这种方式,可以让我们的页面更加的快速和高效。那就是直接通过JavaScript动态地添加和删除样式表中的某些样式,用来取代不断地查询DOM元素,并应用各种样式。接下来咱们就来学习脚本化样式表相关的知识。

DOM系列:动态添加CSS样式规则_第1张图片

获取样式表

你可以选择任意的样式表来添加样式规则。众所周知,引用CSS样式常见的方式主要有三种:

  • 在元素行内添加样式

  • var myStyleSheet = document.getElementById('myStyle').sheet; myStyleSheet instanceof StyleSheet // true

    前面也提到过了document对象的styleSheets属性,可以返回当前页面的所有StyleSheet实例。StyleSheet实例有以下属性。

    StyleSheet.disabled

    StyleSheet.disabled返回一个布尔值,表示该样式表是否处于禁用状态。手动设置disabled属性为true,等同于在元素里面,将这张样式表设为alternate stylesheet,即该样式表将不会生效

    
    
    
        
            StyleSheet
            
        
    
        
    
            
                       

    当你单击“修改颜色”按钮时,可以看到idstyle

    在浏览器开发者工具中,我们可以看到添加了新的

    DOM系列:动态添加CSS样式规则_第15张图片

    注意,添加规则和删除规则不能在 CSSRuleList 实例操作,而要在它的父元素 StyleSheet 实例上,通过StyleSheet.insertRule()StyleSheet.deleteRule()操作。

    虽然CSSRule对象表示样式表中的每一条规则,但实际上,CSSRule是一个供其他多种类型继承的基类型,其中最常见的就是CSSStyleRule类型,表示样式信息。其他规则还包括@import@font-face@page@charset

    CSSRule

    一条CSS规则包括两个部分:CSS选择器和样式声明:

    DOM系列:动态添加CSS样式规则_第16张图片

    JavaScript通过CSSRule接口操作CSS规则。一般通过CSSRuleList接口(StyleSheet.cssRules)获取CSSRule实例。

    CSSRule实例有自己的属性:

    CSSRule.cssText

    CSSRule.cssText属性返回当前规则的文本,比如:

    
    
    
    

    DOM系列:动态添加CSS样式规则_第17张图片

    如果规则是加载(@import)其他样式表,cssText属性返回@import 'url'。比如基于上例稍做修改:

    
    

    CSSRule.parentStyleSheet

    CSSRule.parentStyleSheet属性返回当前规则所在的样式表对象(StyleSheet实例),还是基于上面的示例做一点小修改:

    let sheet = document.getElementById('style').sheet
    let ruleList = sheet.cssRuleslet rule = ruleList[0]
    
    console.log(rule.parentStyleSheet === sheet) // => true
    
    CSSRule.parentRule

    CSSRule.parentRule属性返回包含当前规则的父规则,如果不存在父规则(即当前规则是顶层规则),则返回null

    let sheet = document.getElementById('style').sheet
    let ruleList = sheet.cssRules
    
    for (let i = 0; i < ruleList.length; i++) {
        console.log(ruleList[i].parentRule)
    }
    

    DOM系列:动态添加CSS样式规则_第18张图片

    父规则最常见的情况是,当前规则包含在@media规则代码块之中。比如下面这个示例:

    
    
    let sheet = document.getElementById('style').sheet
    let ruleList = sheet.cssRules
    
    for (let i = 0; i < ruleList.length; i++) {    
        console.log(ruleList[i].parentRule)    
        console.log(ruleList[i].cssText)    
        console.log(ruleList[i].cssRules[i].cssText)
    }
    

    DOM系列:动态添加CSS样式规则_第19张图片

    CSSRule.type

    CSSRule.type属性返回一个整数值,表示当前规则的类型。

    最常见的类型有以下几种。

    • 普通样式规则(CSSStyleRule 实例)

    • @import规则

    • @media规则(CSSMediaRule 实例)

    • @font-face规则

    CSSStyleRule

    如果一条 CSS 规则是普通的样式规则(不含特殊的 CSS 命令),那么除了 CSSRule 接口,它还部署了 CSSStyleRule 接口。

    CSSStyleRule 接口有以下两个属性。

    CSSStyleRule.selectorText

    CSSStyleRule.selectorText属性返回当前规则的选择器。

    
    
    let sheet = document.getElementById('style').sheet
    let ruleList = sheet.cssRules
    
    for (let i = 0; i < ruleList.length; i++) {    
        console.log(ruleList[i].selectorText)
    }
    

    注意,这个属性是可写的。

    CSSStyleRule.style

    CSSStyleRule.style属性返回一个对象(CSSStyleDeclaration 实例),代表当前规则的样式声明,也就是选择器后面的大括号里面的部分。

    CSSStyleDeclaration 实例的cssText属性,可以返回所有样式声明,格式为字符串。

    添加一个新的样式表

    在Web页面中添加样式表有两种方式。一种是通过在HTML文档内部添加