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

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

通过DOM Element对象的、和等方法修改元素的属性

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

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

通过对象的、、等方法来读写行内CSS样式

通过方法获得浏览器最终计算的样式规则

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

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

获取样式表

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

在元素行内添加样式

标签内部的样式

标签引入的外部样式

在使用和添加样式时,可以在HTML标签中在对应的标签上添加属性,然后直接通过这个DOM元素的属性就可以取得对象。样式表也可以通过遍历到:

letsheets = document.styleSheets;

类型表示的是样式表,其也是一个对象,而且是一个类数组对象,它继承自。

StyleSheet接口

接口代表网页的一张样式表,包括元素加载的样式表和元素内嵌的样式表。

对象的属性,可以返回当前页面的所有实例 ——所有样式表。它是一个类似数组的对象。

letsheets = document.styleSheets;

for(leti =; i

如果是元素嵌入的样式表,还有另一种获取实例的方法,就是这个节点元素的属性。

// HTML 代码为

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

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

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

StyleSheet#box{

background-color:red!important;}

修改颜色letsheets = document.styleSheets

letbtn = document.getElementById('btn') btn.addEventListener('click',function(){ sheets[].disabled = !sheets[].disabled })

当你单击“修改颜色”按钮时,可以看到为的中样式并没生效;只有再次点击时才将生效。

注意,是一个可读,可写的的属性,该属性只能通过JavaScript设置,不能在HTML语句中设置。

返回样式表的网址。对于内嵌样式表,该属性返回。该属性是一个只读属性。

letsheets = document.styleSheets;

for(leti =; i

属性返回一个类似数组的对象:实例,表示适用媒介的字符串。表示当前样式表是用于屏幕,还是打印设备或手持设备,或各种媒介适用。该属性只读,默认值是。

当你想在屏幕上显示的时候,你肯定不能把CSS规则加到打印样式表中。你可以仔细的看一下CSSStyleSheet对象的属性信息:

比如下面这样,咱们可以打印出一个页面中所有样式表对应的媒介:

letsheets = document.styleSheets;

for(leti =; i

实例的方法,用于增加媒介;方法用于删除媒介。

sheets[].media.appendMedium ='all'

sheets[1].media.appendMedium ='screen'

sheets[2].media.appendMedium ='print'

for(let i =; i

sheets[2].media.deleteMedium ='print'

for(let i =; i

属性返回样式表的属性。

属性返回样式表的属性,通常是。

CSS 的命令允许在样式表中加载其他样式表。属性返回包含了当前样式表的那张样式表。如果当前样式表是顶层样式表,则该属性返回。

属性返回对象所在的 DOM 节点,通常是或。对于那些由其他样式表引用的样式表,该属性为。

for(let i =; i

属性指向一个类似数组的对象(实例),里面每一个成员就是当前样式表的一条 CSS 规则。使用该规则的属性,可以得到 CSS 规则对应的字符串。

for(let i =; i

每条 CSS 规则还有一个属性,指向一个对象,用来读写具体的 CSS 命令。

for(let i =; i

有些样式表是通过规则输入的,它的属性会返回一个实例,代表那行规则。如果当前样式表不是通过引入的,属性返回。

CSSStyleSheet实例方法

实例方法有和。

方法用于在当前样式表的插入一个新的 CSS 规则。

#box{

background-color:green;width:100px;height:100px;}

letsheet = document.getElementById('style').sheet sheet.insertRule('#box',) sheet.insertRule('p ',1)

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

方法可以接受两个参数,第一个参数是表示CSS规则的字符串,这里只能有一条规则,否则会报错;第二个参数是该规则在样式表的插入位置(从开始),该参数可选,默认为(即默认插入在样式表的头部)。注意,如查插入位置大于现在规则的数目,会报错。该方法的返回值是新插入规则的位置序号。

注意,浏览器对脚本在样式表里面插入规则有很多限制。所以,这个方法最好放在里使用。

因为并不是所有的浏览器都支持方法,所以最好创建一个函数来处理规则的插入。比如下面这样的一个函数:

functionaddCSSRule(sheet, selector, rules, index){if('inserRule'inshhet) { sheet.insertRule(selector +'{'+ rules +'}', index) }elseif('addRule'insheet) { sheet.addRule(selector, rules, index) }}

// 使用方式

addCSSRule(document.styleSheets[],'header','float: left')

方法和方法刚好相反,主要用来在样式表里移除一条规则,它的参数是该条规则在对象中的位置。该方法没有返回值。

document.styleSheets[0].deleteRule(1);

CSSRuleList 接口

接口是一个类似数组的对象,表示一组CSS规则,成员都是实例。我们一般可以通过属性来获取实例。

letsheet = document.getElementById('style').sheet

letcrl = sheet.cssRulescrlinstanceofCSSRuleList// => true

console.log(crl)

实例里面,每一条规则(实例)可以通过或者拿到。CSS规则的条数通过拿到:

#box{

background-color:green;width:100px;height:100px;}p{

color:red;}

letsheet = document.getElementById('style').sheet

letcrl = sheet.cssRules

console.log(crl.length)

for(leti =; i

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

虽然对象表示样式表中的每一条规则,但实际上,是一个供其他多种类型继承的基类型,其中最常见的就是类型,表示样式信息。其他规则还包括、、和。

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

JavaScript通过接口操作CSS规则。一般通过接口()获取实例。

实例有自己的属性:

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

#box{

background-color:green;width:100px;height:100px;}p{color:red;}

letsheet = document.getElementById('style').sheet

letruleList = sheet.cssRules

for(leti =; i

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

@importurl('//www.w3cplus.com/css/reset.css')#box{

background-color:green;

width: 100px;

height: 100px; }

p{

color:red;}

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

letsheet = document.getElementById('style').sheet

letruleList = sheet.cssRulesletrule = ruleList[]console.log(rule.parentStyleSheet === sheet)// => true

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

letsheet = document.getElementById('style').sheet

letruleList = sheet.cssRules

for(leti =; i

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

@supports (display: flex){

@mediascreen and (min-width:900px){

#box{

display:flex;}} }

let sheet = document.getElementById('style').sheetlet ruleList = sheet.cssRulesfor (let i = 0; i

console.log(ruleList[i].parentRule)

console.log(ruleList[i].cssText)

console.log(ruleList[i].cssRules[i].cssText)}

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

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

普通样式规则( 实例)

规则

规则( 实例)

规则

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

CSSStyleRule 接口有以下两个属性。

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

#box{

width:100px;}

let sheet = document.getElementById('style').sheetlet ruleList = sheet.cssRulesfor (let i = 0; i

console.log(ruleList[i].selectorText)}

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

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

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

添加一个新的样式表

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

我们可以通过下面两种方式来动态添加新样式表。先来看方法一:

letsheet = document.createElement('style')sheet.setAttribute('media','screen')sheet.innerHTML ='body'

document.head.appendChild(sheet)

另外一种方式就是将其封装成一个函数:

letsheet = (function(){letstyle = document.createElement('style') document.head.appendChild(style)returnstyle})()

另一种是添加外部样式表,即在文档中添加一个节点,然后将属性指向外部样式表的 。

let linkElm = document.createElement('link');linkElm.setAttribute('rel', 'stylesheet');linkElm.setAttribute('type', 'text/css');linkElm.setAttribute('href', 'reset-min.css');document.head.appendChild(linkElm);

总结

动态添加规则到样式表是高效的手段,可能比你想象的还要简单。请记住这种方案,可能在你的下一个大应用中需要使用,因为它能在代码和元素处理这两方面避免你掉进坑里。借着如何动态创建样式表的机会,文章对有关于动态创建样式表涉及到的相关API做了一些简单的描述。

由于自己是JavaScript的初学者,如果文章中有描述不对之处,还请各路大婶拍正。欢迎各位爷打个赏,鼓励我继续创作一些优质的教程。(^_^)

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180626B1X8NL00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励