巧用 getComputedStyle

之前学这个 API 的时候一直不知道时候才用得上这个函数,今天总算是被我用到了,也发现其有着很巧妙的功能。
简介
先说说用法吧。这个函数是 Window
对象提供的,所以直接调用即可。第一个参数传入要获取样式的元素。返回的是计算后的样式对象,可以根据这个对象来获取计算好的样式值。
下面就是获取计算好的背景颜色。
console.log(getComputedStyle(div).backgroundColor)
问题
假如有如下 HTML 结构:
<div class="container myColor"></div>
现在我们引入了别人的库,里面有 CSS 代码:
div.container {
background: red;
}
而我们 CSS 代码如下:
.myColor{
background: green;
}
.container {
height: 100px;
width: 100px;
}
所以上面的代码最终会是一个红色的 div
,因为 UI 库里的 div.container
的优先级高于 .myColor
。
现在需求是:如何只能用 JS 代码来使得这个 div
变成绿色呢?
分析
只能用 JS 改变样式那么只好用 div.style.backgroundColor = 'green'
来设置内联样式喽。但是不能硬编码直接写等于 green 呀,要是 .myColor
变其他颜色,我们代码又得重写。
所以现在问题变成了:如何通过 JS 代码获取带有 .myColor
类的背景色呢?
可以这么想:现在没有单纯的 .myColor
的元素,我可以创建一个呀,然后用上面的 getComputedStyle
去获取背景色。用完了再把这个元素移除就好了。
编码
有了想法后,JS 代码就很简单了。就是
- 创建临时元素如
div
- 将要计算的类写到元素上,同时设置
display = none
使得元素不可见 - 将临时元素添加到
document.body
里 - 在一段时间后获取计算后的属性,并将其添加到内联元素上
- 最后移除元素
let tempDiv = document.createElement("div");
tempDiv.style.display = 'none';
tempDiv.className = "myColor";
document.body.appendChild(tempDiv);
setTimeout(() => {
let myColor= getComputedStyle(tempDiv).backgroundColor;
let div = document.querySelector(".container");
div.style.backgroundColor = myColor;
tempDiv.remove();
}, 100);
要注意的是这里要设置延时。为毛呢?因为你总得给定时间让别人算这个样式值吧。在将创建好的 div
添加到 document.body
里,是需要一点时间让页面去计算样式的。我这里简单测试了一下,小于 10ms 就不能获取计算后的值了,所以保险起见用 100ms 是足够的。
总结
样式覆盖一直是前端很麻烦的问题,要是别人的库覆盖自己写好的样式真的会爆炸。当然有很多方法去用解决,这里的 getComputedStyle
只是其中之一。