动态追加的html修改样式,DOM系列:动态添加CSS样式规则

在上一节中学习了如何通过JavaScript来修改CSS样式。简单地说:查询CSS样式(即计算样式),设置单个样式(设置的是行内样式),设置多个样式(通过类来设置样式)。即:通过DOM Element对象的getAttribute()、setAttribute()和removeAttribute()等方法修改元素的style属性

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

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

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

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

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

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

AAffA0nNPuCLAAAAAElFTkSuQmCC

获取样式表

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

标签引入的外部样式

在使用

AAffA0nNPuCLAAAAAElFTkSuQmCC

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

StyleSheet接口

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

document对象的styleSheets属性,可以返回当前页面的所有StyleSheet实例 —— 所有样式表。它是一个类似数组的对象。let sheets = document.styleSheets;for (let i = 0; i < sheets.length; i++) {

console.log(sheets[i])

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

如果是var myStyleSheet = document.getElementById('myStyle').sheet;

myStyleSheet instanceof StyleSheet // true

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

StyleSheet.disabled

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

StyleSheet

#box {                background-color: red !important;

}

修改颜色

let sheets = document.styleSheets            let btn = document.getElementById('btn')

btn.addEventListener('click', function(){

sheets[0].disabled = !sheets[0].disabled

})        

当你单击“修改颜色”按钮时,可以看到id为style的

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

StyleSheet.href

StyleSheet.href返回样式表的网址。对于内嵌样式表,该属性返回null。该属性是一个只读属性。let sheets = document.styleSheets;for (let i = 0; i < sheets.length; i++) {

console.log(sheets[i].href)

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

StyleSheet.media

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

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

AAffA0nNPuCLAAAAAElFTkSuQmCC

比如下面这样,咱们可以打印出一个页面中所有样式表对应的媒介:let sheets = document.styleSheets;for (let i = 0; i < sheets.length; i++) {

console.log(sheets[i].media)

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

MediaList实例的appendMedium方法,用于增加媒介;deleteMedium方法用于删除媒介。sheets[0].media.appendMedium = 'all'sheets[1].media.appendMedium = 'screen'sheets[2].media.appendMedium = 'print'for (let i = 0; i < sheets.length; i++) {

console.log(sheets[i].media)

}

AAffA0nNPuCLAAAAAElFTkSuQmCCsheets[2].media.deleteMedium = 'print'for (let i = 0; i < sheets.length; i++) {

console.log(sheets[i].media)

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

StyleSheet.title

StyleSheet.title属性返回样式表的title属性。

StyleSheet.type

StyleSheet.type属性返回样式表的type属性,通常是text/css。

StyleSheet.parentStyleSheet

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

StyleSheet.ownerNode

StyleSheet.ownerNode属性返回StyleSheet对象所在的 DOM 节点,通常是或

console.log(sheets[i].ownerNode)

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

StyleSheet.cssRules

StyleSheet.cssRules属性指向一个类似数组的对象(CSSRuleList实例),里面每一个成员就是当前样式表的一条 CSS 规则。使用该规则的cssText属性,可以得到 CSS 规则对应的字符串。for (let i = 0; i < sheets.length; i++) {

console.log(sheets[0].cssRules[i].cssText)

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

每条 CSS 规则还有一个style属性,指向一个对象,用来读写具体的 CSS 命令。for (let i = 0; i < sheets.length; i++) {

console.log(sheets[0].cssRules[i].style)

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

StyleSheet.ownerRule

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

CSSStyleSheet实例方法

CSSStyleSheet实例方法有insertRule()和deleteRule()。

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

#box {        background-color: green;

width: 100px;

height: 100px;

}

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

sheet.insertRule('#box{border: 2px solid orange}', 0)

sheet.insertRule('p {color: black}', 1)

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

AAffA0nNPuCLAAAAAElFTkSuQmCC

CSSStyleSheet.insertRule方法可以接受两个参数,第一个参数是表示CSS规则的字符串,这里只能有一条规则,否则会报错;第二个参数是该规则在样式表的插入位置(从0开始),该参数可选,默认为0(即默认插入在样式表的头部)。注意,如查插入位置大于现在规则的数目,会报错。该方法的返回值是新插入规则的位置序号。注意,浏览器对脚本在样式表里面插入规则有很多限制。所以,这个方法最好放在try ... catch里使用。

因为并不是所有的浏览器都支持CSSStyleSheet.insertRule方法,所以最好创建一个函数来处理规则的插入。比如下面这样的一个函数:function addCSSRule(sheet, selector, rules, index) {

if ('inserRule' in shhet) {

sheet.insertRule(selector + '{' + rules + '}', index)

} else if ('addRule' in sheet) {

sheet.addRule(selector, rules, index)

}

}// 使用方式addCSSRule(document.styleSheets[0], 'header', 'float: left')

CSSStyleSheet.deleteRule方法和CSSStyleSheet.insertRule方法刚好相反,主要用来在样式表里移除一条规则,它的参数是该条规则在cssRules对象中的位置。该方法没有返回值。document.styleSheets[0].deleteRule(1);

CSSRuleList 接口

CSSRuleList接口是一个类似数组的对象,表示一组CSS规则,成员都是CSSRule实例。我们一般可以通过StyleSheet.cssRules属性来获取CSSRuleList实例。let sheet = document.getElementById('style').sheetlet crl = sheet.cssRules

crl instanceof CSSRuleList // => trueconsole.log(crl)

AAffA0nNPuCLAAAAAElFTkSuQmCC

CSSRuleList实例里面,每一条规则(CSSRule实例)可以通过rules.item(index)或者rules[index]拿到。CSS规则的条数通过rules.length拿到:

#box {        background-color: green;

width: 100px;

height: 100px;

}

p {        color: red;

}

let sheet = document.getElementById('style').sheet    let crl = sheet.cssRules

console.log(crl.length)    for (let i = 0; i 

console.log(crl[i])

console.log(crl[i] instanceof CSSRule)

}

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

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

CSSRule

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

AAffA0nNPuCLAAAAAElFTkSuQmCC

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

CSSRule实例有自己的属性:

CSSRule.cssText

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

#box {        background-color: green;

width: 100px;

height: 100px;

}

p {        color: red;

}

let sheet = document.getElementById('style').sheet    let ruleList = sheet.cssRules    for (let i = 0; i 

console.log(ruleList[i].cssText)

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

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

@import url('//www.w3cplus.com/css/reset.css')

#box {        background-color: green;        width: 100px;        height: 100px;

}    p {        color: red;

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

CSSRule.parentStyleSheet

CSSRule.parentStyleSheet属性返回当前规则所在的样式表对象(StyleSheet实例),还是基于上面的示例做一点小修改:let sheet = document.getElementById('style').sheetlet ruleList = sheet.cssRuleslet rule = ruleList[0]

console.log(rule.parentStyleSheet === sheet) // => true

CSSRule.parentRule

CSSRule.parentRule属性返回包含当前规则的父规则,如果不存在父规则(即当前规则是顶层规则),则返回null。let sheet = document.getElementById('style').sheetlet ruleList = sheet.cssRulesfor (let i = 0; i 

console.log(ruleList[i].parentRule)

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

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

@supports (display: flex) {        @media screen and (min-width: 900px) {            #box {                display: flex;

}

}

}let sheet = document.getElementById('style').sheet

let ruleList = sheet.cssRules

for (let i = 0; i 

}

AAffA0nNPuCLAAAAAElFTkSuQmCC

CSSRule.type

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

最常见的类型有以下几种。普通样式规则(CSSStyleRule 实例)

@import规则

@media规则(CSSMediaRule 实例)

@font-face规则

CSSStyleRule

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

CSSStyleRule 接口有以下两个属性。

CSSStyleRule.selectorText

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

#box {        width: 100px;

}let sheet = document.getElementById('style').sheet

let ruleList = sheet.cssRules

for (let i = 0; i 

}

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

CSSStyleRule.style

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

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

添加一个新的样式表

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

我们可以通过下面两种方式来动态添加新样式表。先来看方法一:let sheet = document.createElement('style')

sheet.setAttribute('media', 'screen')

sheet.innerHTML = 'body{color:red}'document.head.appendChild(sheet)

另外一种方式就是将其封装成一个函数:let sheet = (function () {

let style = document.createElement('style')

document.head.appendChild(style)    return style

})()

另一种是添加外部样式表,即在文档中添加一个节点,然后将href属性指向外部样式表的 URL。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做了一些简单的描述。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当使用`append()`方法动态添加元素并同时添加CSS样式时,需要注意以下几点: 1. 确保添加CSS样式的选择器与现有的样式不冲突; 2. 确保CSS样式在元素添加DOM树之后才定义,否则新添加的元素不会应用这些样式; 3. 如果需要在添加元素后立即应用CSS样式,可以使用`setTimeout()`方法或者异步加载样式表的方式。 下面是一个示例代码: ```html <style> .red { color: red; } </style> <div id="container"> <p class="red">Hello World</p> </div> <script> // 添加一个新的段落元素,并在其后添加CSS样式 var p = document.createElement('p'); p.textContent = 'New Paragraph'; p.style.color = 'red'; // 添加CSS样式 document.getElementById('container').append(p); </script> ``` 在上面的代码中,我们使用`createElement()`方法创建一个新的段落元素,并为其添加样式`color: red`。由于样式是在元素添加DOM树之前定义的,因此新添加的元素会应用这些样式。如果需要异步加载样式表,可以使用以下代码: ```html <style> .red { color: red; } </style> <div id="container"> <p class="red">Hello World</p> </div> <script> // 添加一个新的段落元素,并在其后添加CSS样式 var p = document.createElement('p'); p.textContent = 'New Paragraph'; document.getElementById('container').append(p); // 异步加载样式表 var link = document.createElement('link'); link.rel = 'stylesheet'; link.href = 'path/to/styles.css'; document.head.append(link); </script> ``` 在上面的代码中,我们先添加了一个新的段落元素,然后使用`createElement()`方法创建一个`link`元素,并设置其`rel`属性为`stylesheet`,`href`属性为样式表的路径。最后,将`link`元素添加到`head`元素中,样式表会异步加载并应用到新添加的元素上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值