CSSのtransitionでのアニメーション完了後にJavaScriptで処理をしたいことがよくあるので、いい実装方法がないか調べてみました。
よくやっていたやり方
個人的によくやっていたのは、setTimeout()でアニメーションに設定した時間だけ待つ方法です。
ボタンをクリックするとアニメーションして、アニメーション後にalertを表示するサンプルで試してみます。
HTML
<button id="start">アニメーション実行</button> <div class="sample"></div>
.is-animationが付くとアニメーションが実行されます。
CSS
.sample {
width: 100px;
height: 100px;
background: #E74C3C;
transition: width 2s;
}
.sample.is-animation {
width: 500px;
}
ボタンをクリックしたタイミングで.is-animationを追加します。
さらにsetTimeout()でアニメーションで設定した時間だけ待ってからalertを表示させます。
JavaScript
$(function() {
$('#start').on('click', function() {
$('.sample').addClass('is-animation');
setTimeout(function() {
alert('完了');
}, 2000);
});
});
setTimeout()でのデモページ
実装自体はこれでも問題なさそうですが、スマホでずれる場合があるのと、時間を調整する際にCSSとJavaScriptで2か所(×アニメーション数分)修正する必要があるため、少し手間になります。
transitionの場合
調べてみると、transitionendというイベントで、transitionでのアニメーション終了時に処理を実行できるようです。
JavaScript
$(function() {
$('#start').on('click', function() {
$('.sample').addClass('is-animation');
});
$('.sample').on('transitionend', function() {
alert('完了');
});
});
transitionendの対応ブラウザはこちら
IE10からの対応で、Android4.3以下など一部ブラウザではベンダープレフィックスの対応が必要になります。
例えば、webKit向けのベンダープレフィックスを合わせて指定する場合、以下のように設定します。
JavaScript
$(function() {
$('#start').on('click', function() {
$('.sample').addClass('is-animation');
});
$('.sample').on('transitionend webkitTransitionEnd', function() {
alert('完了');
});
});
animationの場合
animationの場合、animationendというイベントで実行できるようです。
HTML
<div class="sample2"></div>
CSS
.sample2 {
width: 100px;
height: 100px;
background: #999;
-webkit-animation: sample 1s;
animation: sample 1s;
}
@-webkit-keyframes sample {
from {
width: 100px;
}
to {
width: 500px;
}
}
@keyframes sample {
from {
width: 100px;
}
to {
width: 500px;
}
}
JavaScript
$(function() {
$('.sample2').on('animationend', function() {
alert('完了');
});
});
ベンダープレフィックスを合わせて指定したい場合、以下のように設定します。
JavaScript
$(function() {
$('.sample2').on('animationend webkitAnimationEnd', function() {
alert('完了');
});
});
注意点ですが、animation-iteration-countがinfiniteだとイベントが発生しないようです。
HTML
<div class="sample3"></div>
CSS
.sample3 {
width: 100px;
height: 100px;
background: #999;
-webkit-animation: sample 1s infinite;
animation: sample 1s infinite;
}
@-webkit-keyframes sample {
from {
width: 100px;
}
to {
width: 500px;
}
}
@keyframes sample {
from {
width: 100px;
}
to {
width: 500px;
}
}
JavaScript
$(function() {
$('.sample3').on('animationend', function() {
alert('完了');
});
});
animation-iteration-countにinfiniteを設定した場合のデモページ
【参考サイト】
- transitionend | MDN
- animationend | MDN
- javascript – Is there a callback on completion of a CSS3 animation? – Stack Overflow
コメントが承認されるまで時間がかかります。