|
|
请马上登录,朋友们都在花潮里等着你哦:)
您需要 登录 才可以下载或查看,没有账号?立即注册
x
JS变通操作伪元素关键帧动画 | 马黑黑
由于伪元素在DOM中属于非实体节点,作为擅长操作DOM节点的JS,对伪元素的操作能力极其有限,比如无法直接控制伪元素的关键帧动画。请看下面的CSS和HTML代码:
<style>
#papa {
margin: auto;
width: 700px;
height: 400px;
display: grid;
place-items: center;
position: relative;
}
#papa::before {
position: absolute;
content: '';
width: 100px;
height: 100px;
background: olive;
animation: rot 10s linear infinite;
}
@keyframes rot { to { transform: rotate(360deg); } }
</style>
<div id="papa"></div>
从CSS中可以看到,id="papa" 的 div 盒子有一个 ::before 伪元素,该伪元素运行了 rot 关键帧动画,不停地自转。现在,我们的任务就是要去控制这个动画,即能够暂停动画和继续动画。
对于非伪元素,JS控制动画的方法是通过 style.animationPlayState 来实现,比如,假设 #papa 盒子运行了 rot 动画,则如下指令无障碍实现暂停和继续动画:
papa.style.animationPlayState = 'paused'; //暂停
papa.style.animationPlayState = 'running'; //继续
遗憾的是,对待 #papa 盒子的伪元素,上述指令无能为力,目前也不存在可以直接操纵伪元素关键帧动画的方法。但问题总要解决,也许可以变通一下思路。
CSS可以拥有变量,比如我们给一系列同用一个类选择器的元素预设不同的宽度,我们可以在CSS中声明一个变量 ww(变量名应该自定义):
.ball {
--ww: 100px;
width: var(--ww);
}
var(--名称) 就是CSS声明变量的方法,var 是声明关键字,小角括号里的 --名称 是固定结构,符号“--”后面紧跟变量名。CSS变量可以有初始值,--名称: 数值+单位,上述代码中的 --ww: 100px; 就是定义了变量 ww 为 100px。
随后,在JS里,可以动态地给元素设定宽度,例如,我们设置 .ball 系列盒子中的第一个的宽度为120px:
let balls = document.querySelectorAll('.ball'); //获得所有 .ball 元素操作句柄
balls[0].style.setProperty('--ww','120px');
上面,使用JS内置方法 style.setProperty(属性名,值) 改变了CSS变量 --ww 的初始值,令其宽度等于 120px。
CSS变量不止用于尺寸,还可以用于很多其他方面,关键帧动画的状态乃至于动画的名称,也都是可以的。那么,解决问题的思路就来了:我们在 #papa 盒子中声明一个 --state 变量,由于变量的可继承性,父元素的变量会被子元素所接受,我们通过改变父元素的变量值,达成可间接操纵伪元素的动画的目的。
为此,需要改装一下 #papa 盒子的 CSS 样式表:
#papa {
--state: running;
margin: auto;
width: 700px;
height: 400px;
display: grid;
place-items: center;
position: relative;
}
和文章开头提供的代码相比,这里的唯一变化是加入了 --state 变量的初始值为 runnig,表示关键帧动画的 play 状态为运行。
::before 伪元素的CSS样式也配套改动:
#papa::before {
position: absolute;
content: '';
width: 100px;
height: 100px;
background: olive;
animation: rot 10s linear infinite;
animation-play-state: var(--state);
}
仅仅是加了属性 animation-play-state ,其值用变量 var(--state) 表示,var(--state) 将响应来自于父元素的预设值,并将能响应将来JS对此值的动态改变。
为了便于演示,我们需要给HTML代码添加两个按钮,并在JS中处理按钮的点击事件:
<div id="papa">
<p style="position: absolute; bottom: 20px;">
<input id="btnpause" type="button" value=" 暂停 " />
<input id="btnplay" type="button" value=" 继续 " />
</p>
</div>
JS中,使用 style.setProperty() 方法分别处理 #papa 父盒子的预设变量 --state 的值:
<script>
btnpause.onclick = () => {
papa.style.setProperty('--state','paused'); //暂停动画
}
btnplay.onclick = () => {
papa.style.setProperty('--state','running'); //继续动画
}
</script>
效果会怎么样呢?我也没有把握,请移步二楼观看——
|
评分
-
| 参与人数 2 | 威望 +70 |
金钱 +140 |
经验 +70 |
收起
理由
|
梦缘
| + 20 |
+ 40 |
+ 20 |
很给力! |
红影
| + 50 |
+ 100 |
+ 50 |
赞一个! |
查看全部评分
|