在网页交互场景中,经常需要为元素设置悬停时播放的动画,同时支持点击元素时中断当前悬停动画并触发新的动画效果。这种需求可以通过CSS动画属性配合JavaScript的类切换操作来实现,核心思路是利用CSS动画的播放状态控制和类名的动态修改来切换不同的动画逻辑。

实现原理
要实现点击中断悬停动画并触发新动画,需要理解两个核心点:
- CSS的
animation-play-state属性可以控制动画的播放和暂停状态,默认值为running,设置为paused可以暂停当前动画。 - 通过JavaScript动态为元素添加或移除类名,可以切换元素绑定的不同CSS动画规则,从而实现动画的切换。
基础HTML结构
首先创建一个需要添加交互效果的元素,这里以一个方块元素为例:
<div class="target-box">点击我</div>
CSS样式与动画定义
先定义元素的基础样式,以及悬停动画和点击触发的新动画:
/* 基础样式 */
.target-box {
width: 200px;
height: 200px;
background-color: #409eff;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
cursor: pointer;
/* 初始不绑定动画 */
animation: none;
animation-play-state: running;
}
/* 悬停动画:背景色渐变+缩放 */
@keyframes hover_animation {
0% {
background-color: #409eff;
transform: scale(1);
}
50% {
background-color: #67c23a;
transform: scale(1.1);
}
100% {
background-color: #409eff;
transform: scale(1);
}
}
/* 点击触发的新动画:旋转+背景色变化 */
@keyframes click_animation {
0% {
transform: rotate(0deg);
background-color: #409eff;
}
50% {
transform: rotate(180deg);
background-color: #f56c6c;
}
100% {
transform: rotate(360deg);
background-color: #409eff;
}
}
/* 悬停时绑定悬停动画 */
.target-box:hover {
animation: hover_animation 1.5s infinite;
}
/* 点击后添加的类,绑定点击动画 */
.target-box.click-active {
/* 先暂停可能存在的悬停动画 */
animation-play-state: paused;
/* 绑定点击动画,执行一次 */
animation: click_animation 1s 1;
}
JavaScript类控制逻辑
通过JavaScript监听元素的鼠标事件,动态切换类名来控制动画的切换:
// 获取目标元素
const targetBox = document.querySelector('.target-box');
// 监听鼠标移出事件,移除点击激活类,恢复悬停动画能力
targetBox.addEventListener('mouseleave', function() {
this.classList.remove('click-active');
});
// 监听点击事件,添加点击激活类,触发新动画
targetBox.addEventListener('click', function() {
// 先移除可能存在的旧点击类,确保动画重新触发
this.classList.remove('click-active');
// 触发重排,让类移除生效后再添加新类
void this.offsetWidth;
// 添加点击激活类
this.classList.add('click-active');
});
关键逻辑说明
在点击事件的代码中,先移除click-active类再重新添加,是为了解决如果连续点击时动画无法重新触发的问题。通过void this.offsetWidth触发浏览器的重排操作,让类的移除和添加被浏览器识别为两次不同的操作,从而保证每次点击都能重新执行点击动画。
当元素处于click-active类状态时,animation-play-state: paused会暂停之前可能存在的悬停动画,同时animation: click_animation 1s 1会绑定新的旋转动画,执行完成后动画停止,此时如果鼠标再次移入元素,会重新触发悬停动画,移出后点击类被移除,交互逻辑恢复正常。
常见问题与解决
- 如果点击后悬停动画仍然继续播放,需要检查
click-active类中的animation-play-state: paused是否正确设置,并且该类的优先级是否高于悬停样式的优先级。 - 如果点击动画无法重复触发,需要确认是否在点击时先移除了
click-active类,并且通过触发重排的方式让浏览器识别类的更新。 - 如果动画切换时出现闪烁,可以检查两个动画的初始状态和结束状态是否一致,避免状态跳变。