JS如何获取CSS属性

6,088 阅读5分钟

这是我参与8月更文挑战的第1天,活动详情查看: 8月更文挑战

前言

今天在项目中处理一个CSS样式的时候遇到了一个问题:如何用JS去获取CSS自定义属性。一时之间我竟然想不起来怎么用JS去拿到这个属性。

我们知道CSS自定义属性的写法比较特殊,需要两个减号开始(--my-name: red;),那怎么访问它呢??直接style访问??getComputedStyle??--my-name的驼峰命名怎么写??

带着这些疑问开始查资料,写这篇文章来总结一下。

看一个简单的例子:

<html>
<head>
    <meta charset="utf-8">
    <style>
        :root{
            --my-val: red;
            --in-val: 10px;
        }
        #ele{
            background-color: var(--my-va);
            font-weight: 500;
            border: 1px solid #ccc;
            width: 300px;
            float: right;
            
        }
    </style>
    <link href="test.css" rel="stylesheet" type="text/css">
</head>
<body>
    <div id="ele" 
    style="--height-val:200px;height:var(--height-val);border-radius:var(--in-val);text-align: center;">
        测试获取CSS属性
    </div>
</body>
</html>

外部文件:test.css

#ele {
    color: blue;
}

style对象

直接通过style对象去设置和访问样式属性是很常用的一种方式,它返回一个CSSStyleDeclaration对象。

看下边的代码:

window.onload= function() {
    let ele = document.getElementById('ele');

    //直接使用style访问,需要驼峰命名
    console.log(ele.style.height);    //var(--height-val)
    console.log(ele.style.borderRadius);   //var(--in-val)
    console.log(ele.style['text-align']);      //center
    console.log(ele.style.backgroundColor);  //不能获取标签内样式
    console.log(ele.style.color);   //不能获取外部文件样式
    console.log(ele.style.cssText);
    console.log(ele.style['--height-val']);  //不能获取自定义属性
    
    //通过style设置属性
    ele.style.width = '200px';
    ele.style['line-height'] = '200px';

执行结果如下:

image.png

  • style对象只能获取到行内样式(style属性)

  • 如果CSS属性有连字符,则需要用驼峰命名或者中括号来访问。

  • float属性(JavaScript保留字)比较特殊,google可以直接写float,但是IE和火狐无效,IE需要使用styleFloat,非IE可以使用cssFloat访问

  • style对象有一个cssText属性获取了设置在行内的所有样式属性

  • style对象是无法直接访问自定义属性的。

  • 如果样式属性的是由var函数获取的,则style对象直接将var函数原封不动的返回,不会自己去计算。

  • 可以直接通过style对象来设置CSS属性值

getComputedStyle

getComputedStyle也是比较常用的一个方法,它返回一个CSSStyleDeclaration对象。

语法:

let style = window.getComputedStyle(element, [pseudoElt]);

参数:

  • element:必选,要获取样式的元素。
  • pseudoElt:可选,伪元素的字符串。必须对普通元素省略或设置为null

看一下用getComputedStyle访问样式属性:

window.onload= function() {
    let ele = document.getElementById('ele');
    let computedValue = getComputedStyle(ele) || document.defaultView.getComputedStyle(ele);
    
    console.log(computedValue.width);   //300px   访问内部样式
    console.log(computedValue.borderRadius);  //10px    行内样式
    console.log(computedValue['text-align']);  //center  
    console.log(computedValue.color);   // rgb(0, 0, 255)
    console.log(computedValue.backgroundColor);  //rgb(255, 0, 0)  返回var函数的计算结果
    console.log(computedValue['--height-val']);  //undefined  无法访问自定义属性
    console.log(computedValue.cssFloat);  //right 
    
    //只能读不能写
    computedValue.width = '200px';
}

执行结果如下:

image.png

  • getComputedStyle只支持样式的读取不支持改写

  • getComputedStyle获取的样式是浏览器最终渲染效果的样式,包含了内联样式(行内),内部样式(style标签),外部样式(link标签)。

  • 与style对象一样,具有连字符的属性需要用驼峰命名或中括号

  • 对于属性值设置为var函数的,getComputedStyle会直接返回var函数的计算结果

  • 一般来说getComputedStyle可以直接通过window对象调用,但是在firefox3.6上访问子框架内的样式时,必须使用document.defaultView.getComputedStyle

  • IE9以下不支持getCoumputedStyle,使用currentStyle对象读取元素的最终显示样式。

getAttribute/setAttribute

getAttribute是一个比较特殊的方法,它返回元素指定的属性值,如果不存在则返回null或空字符串''。

既然是访问元素的属性值,那关css样式有什么关系呢??虽然不能去访问某个具体的样式属性,但是可以访问元素的style属性(行内样式),如果给元素设置了style属性,则返回一个string,否则返回null

getAttribute/setAttribute是一个兼容性比较好的方法,IE的支持度也很好。

let ele = document.getElementById('ele');

//获取元素的style属性
console.log(ele.getAttribute('style'));

//直接设置style
ele.setAttribute('style', 'width: 200px;--hg: 100px;height:var(--hg);');

执行结果如下:

image.png

  • getAttribute/setAttribute主要是通过元素节点的属性名称来获取元素的属性值,所以可以用该方法可以获取元素节点的style属性值。但是一般不用这个方法来获取和设置样式属性。
  • 通过getAttribute获得的style属性的值与style对象的cssText

getPropertyValue

getPropertyValue也可以用来请求css属性的值,但是它不能直接通过元素节点访问,而是作为CSSStyleDeclaration对象的一个方法。所以使用getPropertyValue需要与style对象或者getComputedStyle方法配合使用。

let ele = document.getElementById('ele');

//通过style获取CSSStyleDeclaration对象
let eleStyle = ele.style;
console.log(eleStyle.getPropertyValue('text-align'));   //center
console.log(eleStyle.getPropertyValue('height'));       //var(--height-val)
console.log(eleStyle.getPropertyValue('--height-val'));  //200px


//通过getComputedStyle获取CSSStyleDeclaration对象
let computedValue = getComputedStyle(ele) || document.defaultView.getComputedStyle(ele);
console.log(computedValue.getPropertyValue('background-color'));  //rgb(255, 0, 0)
console.log(computedValue.getPropertyValue('color'));   //rgb(0, 0, 255)
console.log(computedValue.getPropertyValue('float'));   //right
console.log(computedValue.getPropertyValue('--in-val'));   //10px


//通过cssRules的style对象来获取CSSStyleDeclaration
let eleDec = document.styleSheets[1].cssRules[0].style;
console.log(eleDec.getPropertyValue('color'));   //blue

执行结果:

image.png

  • 使用getPropertyValue方法,需要先获取CSSStyleDeclaration对象。

  • getPropertyValue方法可以直接访问属性不需要修改属性名称(包括连字符属性和float),不需要对元素属性进行驼峰命名等的转化。

  • getPropertyValue方法可以访问自定义属性

stylesheets

通过document.stylesheets可以获取CSS样式表。每个CSS样式表中有一个cssRules属性(只读),返回一个CSSRuleList。

加入CSSStyleSheet中的几种常见写法:

  • 文档中的<style>和<link>元素
  • 使用@import导入的样式
let sheets = document.styleSheets;
for(let i=0; i<sheets.length; i++) {
    console.log(sheets);
    let ruleList = sheets[i].cssRules;
    for(let j=0; j<ruleList.length; j++) {
        console.log(ruleList[j]);
        console.log(ruleList[j].style);
    }

}

执行结果如下:

image.png

我们也可以使用insertRule去添加样式规则,stylesheet.insertRule(rule, [, index]);在IE9以下的浏览器中是不支持inserRule的,需要使用addRule方法:addRule(selector,rule,[,index]),具体的细节这里就不多说了。

总结

获取CSS样式属性的方法有很多种,但是CSSStyleDeclaration.getPropertyValue是一种兼容性较好的写法,它不需要转换属性名称,也可以直接访问自定义属性。

最后,发现有时候设置!important好像会失效,看到网上推荐用setProperty,写法:element.style.setProperty(propertyName, value, priority);

参考文章

JS设置CSS样式的几种方式

CSSStyleSheet