前言
去年我为公司内部开发了一个浏览器插件,当时为了加快开发进度,我没有选用现成的插件框架,而是直接使用原生 JavaScript 搭配 Rollup
进行打包。由于这是一个浏览器插件,我不可避免地需要对页面元素进行操作,比如添加按钮、调整颜色等。刚开始,我采取的做法是直接向元素上添加style
。这种方法一开始还算可行,但随着插件更新,组件增加,直接添加style
变得更加繁琐且不优雅。
例如,手动添加样式的方法如下所示:
function addStyle(container, styles) {
Object.keys(styles).forEach((key)=>{
container.style[key] = styles[key]
})
}
const divEle = document.createElement('div')
addStyle(divEle, {
color: white;
backgroundColor: #333;
})
这种情况下,我开始思考是否有更为合适的方法可以通过 JavaScript 动态创建类样式。当时由于时间紧迫以及不影响功能性,我没有再去深入研究。今天,我将分享一种优雅的方法——使用CSSStyleSheet
添加css 类样式
传统添加类样式
通常,如果需要通过 JavaScript 动态添加新的类样式,我们会操作<style>
元素。我们创建一个<style>
元素,添加 css 内容,并将其添加到文档的<head>
部分。以下为示例代码:
const style = document.createElement('style');
style.type = 'text/css';
style.innerText = '.new-class { color: red; }';
document.head.appendChild(style);
尽管这种方法可以向文档中添加类样式,但它有限制,比如不易进行类规则的新增、删除等操作。
CSSStyleSheet
CSSStyleSheet
是用于表示文档内部或外部样式表的一个接口,它是浏览器提供的Web API的一部分。与传统的样式管理方式相比,CSSStyleSheet允许开发者以编程方式动态地操作样式,增加、修改或删除CSS规则。
基本用法
- 获取样式表对象
- 对于内联样式,可以通过
<style>
元素的sheet
属性直接获取。 - 对于链接的样式表,可以通过
document.styleSheets
集合访问。
- 对于内联样式,可以通过
// 内联样式表
var styleElement = document.createElement('style');
document.head.appendChild(styleElement);
var styleSheet = styleElement.sheet;
// 链接样式表
var linkedStyleSheet = document.styleSheets[0]; // 例子中取第一个样式表
- 插入CSS规则
- 使用
insertRule
方法插入新规则。
- 使用
styleSheet.insertRule('.new-class { background: yellow; }', 0);
- 查找 CSS 规则
- 遍历
styleSheet.cssRules
判断选择器名称是否一致,一致则返回索引。
- 遍历
const rules = styleSheet.cssRules;
let index;
for (let i = 0; i < rules.length; i++) {
if (rules[i].selectorText === '.new-class') {
index = i;
break;
}
}
- 删除CSS规则
- 通过指定要删除的规则的索引,使用
deleteRule
方法。
- 通过指定要删除的规则的索引,使用
styleSheet.deleteRule(0);
- 更新CSS规则
styleSheet.cssRules
可以获取指定索引下的样式,同时进行更新
const rules = styleSheet.cssRules;
rules[0].style.backgroundColor = 'blue'; // 将背景颜色改为蓝色
核心用法
- 动态更新样式:无需删除
<style>
标签重新创建,直接使用insertRule
和deleteRule
动态修改。 - 应用响应式风格:依据不同屏幕尺寸或设备特性动态添加或更新媒体查询规则。
- 主题化定制:用户可以选择主题风格,通过替换或添加规则来改变网站的主题。
与传统方式的区别和优点:
相比操作 textContent 或 innerHTML
传统方法:
通过获取<style>
元素的textContent
或innerHTML
属性,然后追加或修改字符串来改变样式规则,这种方式简单直接。
CSSStyleSheet方法优势:
- 性能提升:操作
CSSStyleSheet
避免了直接解析字符串的步骤,减少了不必要的性能消耗,因为浏览器可以直接操作已解析的样式表对象。 - 更高的效率:直接通过
insertRule
和deleteRule
可以精确地添加或删除规则,无须重新解析整个样式字符串,这意味着操作可以更快完成。
细粒度控制
传统方法:
通过字符串追加或修改时,难以定位具体的规则,尤其是在复杂的样式表中。
CSSStyleSheet方法优势:
CSSStyleSheet
允许开发者精确地操作具体的规则,不论是新增、修改或是删除,都可以直接指向目标规则进行操作。
错误处理
传统方法:
在操作字符串时,错误可能导致整个样式字符串无效化,而且难以定位问题所在。
CSSStyleSheet方法优势:
使用CSSStyleSheet
时,由于每次操作的是具体的规则,出错时容易定位并处理问题,提升了代码的可靠性。
动态样式切换和管理
传统方法:
需要替换或修改大量的字符串内容来实现风格切换,过程繁琐且易错。
CSSStyleSheet方法优势:
CSSStyleSheet
简化了样式的动态切换和管理流程,例如主题切换可以通过直接操作规则集合来轻松实现,大大降低了复杂性。
规则级别操作
传统方法
当为多个DOM元素应用样式时,需要遍历每个元素并修改其style
属性,这在文档大型且元素多时效率较低。
CSSStyleSheet方法优势:
CSSStyleSheet
允许开发者在CSS规则级别进行操作,这意味着可以一次性修改多个元素的样式,无需遍历单个元素,极大地提升了修改大范围样式时的效率。
浏览器兼容性
当前大多数现代浏览器均支持使用CSSStyleSheet
。
结语
CSSStyleSheet
提供了一种强大的方法来以程序化的方式管理和操作网页的样式。无论是小规模的样式调整,还是大规模的样式系统设计,CSSStyleSheet 都是一个很有用的 API,可以帮助你高效的维护和更新你的网站风格。
参考资料
- MDN CSSStyleSheet: https://developer.mozilla.org/docs/Web/API/CSSStyleSheet