主要通过更换 css 上的 animation 来实现涟漪效果。

但是大部分的实现方法会增加一个空白节点,

所以想出通过操作伪元素的方案来做。

代码如下

在线体验

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
.input {
padding: 5em 10em;
border-radius: 0.3em;
position: relative;
background-color: rgb(189, 86, 86);
display: inline-block;
overflow: hidden;
}

.input1::after {
content: "";
display: block;
width: 6px;
height: 6px;
border-radius: 50%;
position: absolute;
/* transition: all 0.4s ease-in-out; */
z-index: 1111;
transform: scale(0);
/* top: 0;
left: 0; */
/* animation: spin 01s linear; */
background-color: rgba(0, 0, 0, 0.45);
}

@keyframes spin {
0% {
transform: scale(0);
background-color: rgba(0, 0, 0, 0.45);
}

100% {
transform: scale(150);
background-color: transparent;
}
}
</style>
</head>

<body>
<div onclick="fn(event)" class="input input1">
这是一个按钮
</div>
<script>
// 这是一个操作伪元素样式的方法
function ruleSelector(selector) {
function uni(selector) {
return selector.replace(/::/g, ":");
}
// es6
return Array.from(document.styleSheets)
.reduce((a, b) => {
return a.concat(Array.from(b.cssRules));
}, [])
.filter(x => {
return x.selectorText === selector;
});
// es5
// return Array.prototype.filter.call(Array.prototype.concat.apply([], Array.prototype.map.call(document.styleSheets, function (x) {
// return Array.prototype.slice.call(x.cssRules);
// })), function (x) {
// return uni(x.selectorText) === uni(selector);
// });
}

function fn(e) {
ruleSelector(".input1::after")[0].style.top = e.offsetY - parseInt(ruleSelector(".input1::after")[0].style.width,
10) / 2 + "px";
ruleSelector(".input1::after")[0].style.left = e.offsetX - parseInt(ruleSelector(".input1::after")[0].style
.height, 10) / 2 + "px";
ruleSelector(".input1::after")[0].style.animation = '';
setTimeout(() => { // 不这样做会被合并
ruleSelector(".input1::after")[0].style.animation = 'spin .5s linear';
})

}
</script>
</body>

</html>