js 修改伪类元素的样式

这是一个骚操作…因为目前为止 js 还没有提供可以直接设置伪类的 API,但是程序界流传着这样一句话:任何解决不了的问题都可以引入一个第三方去解决

有一种思路是:

  1. js 添加自定义 style 属性
  2. css 中读取并使用该属性的值

以下面场景为例:

需求是给右侧伪类元素随机添加颜色(这个场景也许不太恰当,完全可以另外写一个 div,这里只为了演示说明)
image.png

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<div class="demo"></div>
<button style="margin: 30px 150px;">随机切换背景色</button>

<style>
* {
box-sizing: border-box;
}

body {
margin: 0 auto;
min-height: 100vh;
width: 500px;
}

.demo {
margin-top: 40px;
position: relative;
width: 200px;
height: 200px;
background-color: lightgreen;
}

.demo::after {
content: '伪类元素';
display: block;
position: absolute;
top: 0;
left: 100%;
margin-left: 20px;
height: 160px;
width: 160px;
padding: 20px;
background-color: lightgrey;
}
</style>

添加 style 自定义属性

按照文章最开始讲的思路,我们第一步需要使用 js 给 dom 元素的 style 添加自定义属性

1
2
3
4
5
6
7
8
9
10
const colors = ['lightpink', 'lightblue', 'lightgoldenrodyellow', 'lightgrey'];
let i = 0;
const btn = document.querySelector('button');
btn.addEventListener('click', () => {
console.log(123);
const element = document.querySelector('.demo');
/* 添加自定义属性 */
element.style.setProperty('--bg-color', colors[i % 4]);
i++;
});

css 使用自定义属性值

这里需要用到 css 的 var() 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
.demo::after {
content: '伪类元素';
display: block;
position: absolute;
top: 0;
left: 100%;
margin-left: 20px;
height: 160px;
width: 160px;
padding: 20px;
/* 使用 --bg-color 属性值 */
background-color: var(--bg-color, lightgrey);
}

我们可以看下添加后的 css 样式

image.png

最终完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<div class="demo"></div>
<button style="margin: 30px 150px;">随机切换背景色</button>

<script>
const colors = ['lightpink', 'lightblue', 'lightgoldenrodyellow', 'lightgrey'];
let i = 0;
const btn = document.querySelector('button');
btn.addEventListener('click', () => {
console.log(123);
const element = document.querySelector('.demo');
element.style.setProperty('--bg-color', colors[i % 4]);
i++;
});
</script>

<style>
* {
box-sizing: border-box;
}

body {
margin: 0 auto;
min-height: 100vh;
width: 500px;
}

.demo {
margin-top: 40px;
position: relative;
width: 200px;
height: 200px;
background-color: lightgreen;
}

.demo::after {
content: '伪类元素';
display: block;
position: absolute;
top: 0;
left: 100%;
margin-left: 20px;
height: 160px;
width: 160px;
padding: 20px;
background-color: var(--bg-color, lightgrey);
}
</style>