2014年3月7日金曜日

AngularJSのngShowとngAnimateでフェードイン・フェードアウト処理をするには?

AngularJSのngShowによる表示・非表示の自動処理と同時にngAnimateを使ってフェードイン・フェードアウト処理をするにはどうしたらいいだろう?まずはデモ。



ngAnimateでアニメーション処理を行うには、まずscriptタグでライブラリを読み込んでおく必要がある。



それだけではまだダメで、さらにこのような感じでモジュールとして指定する必要がある。

var app = angular.module('app', ['ngAnimate']);

ngAnimateのアニメーションは完全にCSSの設定によって行われる。つまり、CSSのアニメーションが設定されたクラスが追加されたり削除されたりすることでアニメーションが行われる。

ここでのポイントは、どのようなCSSクラスがどのようなタイミングで追加されたり削除されるかだ。詳しくはここに書いてある。
AngularJS: ngAnimate.$animate
AngularJS: ngShow

ざっくり言うと、このようになる。

ng-show="true"になる時
  1. 「ng-hide-remove」(隠すが削除される=表示される)が追加される
  2. 「ng-hide-remove-active」が追加される
  3. アニメーションが開始される
  4. アニメーションが終了する
  5. これらのクラスが削除される

ng-show="false"になる時
  1. 「ng-hide-add」(隠すが追加される=非表示にされる)が追加される
  2. 「ng-hide-add-active」が追加される
  3. アニメーションが開始される
  4. アニメーションが終了する
  5. これらのクラスが削除される

ということで、例えば「fadeIn」というクラスでフェードインさせるとすれば、「fadeIn.ng-hide-remove」クラスでアニメーションの初期設定とopacity=0の設定を行い、「fadeIn.ng-hide-remove.ng-hide-remove-active」クラスでopacity=1の設定を行い、HTMLのタグのclassに「fadeIn」を追加する。

同様に、例えば「fadeOut」というクラスでフェードアウトさせるとすれば、「fadeOut.ng-hide-add」クラスでアニメーションの初期設定とopacity=1の設定を行い、「fadeOut.ng-hide-add.ng-hide-add-active」クラスでopacity=0の設定を行い、HTMLのタグのclassに「fadeOut」を追加する。

フェードイン・フェードアウトを両方行いたければ、これまで設定したCSSクラスをそのまま利用し、HTMLのタグのclassに「fadeIn」と「fadeOut」を追加するだけでいい。

このようにAngularJSのngShowとngAnimateでフェードイン・フェードアウト処理が行えるようになれば、jQueryなどで行うよりDOM依存度を少なくできるし、コーディングも楽になるし、バグの発生率も少なくなると思う。

もうangularでのやり方が分かったので問題無くなったけど、jQueryやJSのみでやる場合にはHTMLのイベントにonshowとかonhideとかがあると良いなと思った。