昨天在开发中,使用animation时,碰到一个问题:
切换className时,其中一个className定义的动画不起作用,经过对animation对进一步了解后,终于解决该问题。
不起作用的原因是因为,在第一个className定义的动画执行完毕后,目标元素动画所需要的动画属性未定义,所以才造成动画失效。
简单的例子(本例子只是为了演示animation,故不考虑兼容性):
DOM结构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>animation-demo</title>
</head>
<style>
.click-me {
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 200px;
height: 200px;
border-radius: 10px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-mz-border-radius: 10px;
background-color: blue;
color: #fff;
line-height: 200px;
text-align: center;
}
.click-me.animation-target {
background-color: gray;
transform: translateX(500%);
-webkit-transform: translateX(500%);
}
.click-me.animation-target.active {
animation: fadeIn 1s linear both;
-webkit-animation: fadeIn 1s linear both;
-moz-animation: fadeIn 1s linear both;
-ms-animation: fadeIn 1s linear both;
}
.click-me.animation-target.hidden {
animation: fadeOut 1s linear both;
-webkit-animation: fadeOut 1s linear both;
-moz-animation: fadeOut 1s linear both;
-ms-animation: fadeOut 1s linear both;
}
@keyframes fadeIn {
form {
transform: translateX(500%);
-webkit-transform: translateX(500%);
-moz-transform: translateX(500%);
-ms-transform: translateX(500%);
}
to {
transform: translateX(100%);
-webkit-transform: translateX(100%);
-moz-transform: translateX(100%);
-ms-transform: translateX(100%);
}
}
@keyframes fadeOut {
form {
transform: translateX(100%);
-webkit-transform: translateX(100%);
-moz-transform: translateX(100%);
-ms-transform: translateX(100%);
}
to {
transform: translateX(500%);
-webkit-transform: translateX(500%);
-moz-transform: translateX(500%);
-ms-transform: translateX(500%);
}
}
</style>
<body>
<a href="javascript:;" class="click-me" id="clickMe" data-click='false'>点我执行动画</a>
<a href="javascript:;" class="click-me animation-target"></a>
<script>
document.getElementById('clickMe').addEventListener('click', function () {
console.log(typeof document.getElementById('clickMe').dataset.click)
if (document.getElementById('clickMe').dataset.click === 'false') {
document.querySelector('.animation-target').setAttribute('class', ('click-me animation-target' + ' active'));
document.getElementById('clickMe').setAttribute('data-click', 'true');
} else {
document.querySelector('.animation-target').setAttribute('class', ('click-me animation-target' + ' hidden'));
document.getElementById('clickMe').setAttribute('data-click', 'false');
}
});
</script>
</body>
</html>
在这个情况下,className切换到hidden时,animation是不起作用的,这时,是因为.animation-targe
元素的transform
属性值跟添加.active
样式后的值不一致,所以,当添加.hidden
时,.animation-targe
元素直接跳到动画结束的状态。
现在,让我们修改一下js代码,为.animation-targe
元素指定动画结束后的transform
属性值。
代码如下:
setTimeout(function () {
document.querySelector('.animation-target').style.transform = 'translateX(100%)';
},1000);
添加定时的原因是为了设置延迟添加样式,如果不添加setTImeout
定时器,.animation-targe
元素将直接移动到指定位置(定时器的时间跟动画时间一致
)。
附上完整的JS代码:
<script>
document.getElementById('clickMe').addEventListener('click', function () {
console.log(typeof document.getElementById('clickMe').dataset.click)
if (document.getElementById('clickMe').dataset.click === 'false') {
document.querySelector('.animation-target').setAttribute('class', ('click-me animation-target' + ' active'));
setTimeout(function () {
document.querySelector('.animation-target').style.transform = 'translateX(100%)';
},1000);
document.getElementById('clickMe').setAttribute('data-click', 'true');
} else {
document.querySelector('.animation-target').setAttribute('class', ('click-me animation-target' + ' hidden'));
document.getElementById('clickMe').setAttribute('data-click', 'false');
setTimeout(function () {
document.querySelector('.animation-target').style.transform = 'translateX(500%)';
},1000);
}
});
</script>