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
コメントが承認されるまで時間がかかります。