Angular.js: アニメーションしている要素でng-show / hideが遅延します

作成日 2014年07月16日  ·  17コメント  ·  ソース: angular/angular.js

ロードスピナーのようなもので一定のアニメーションを実行していて、それをすぐに非表示または表示したい場合、これは予期された動作ではありません。

要素はng-animateによって管理されるように指示されていませんでした。通常のng-show / hideを即座に実行したいだけで、たまたま進行中のcssアニメーションは無関係であると思います。

フィドル: http

「showloader」のチェックを外し、実際に消えるまでに数秒かかることに注意してください。

アップグレードする前にローダーがアプリケーションに固定されていなかったため、これは最近の変更だと思います。 以前は1.12だったと思います。

ng-animateの使い方/使わない方法の理解に何かが欠けているに違いありませんよね? この場合、実際には使用したくないのですが、この要素を無視するために使用できれば、それでも機能します。 しかし、間違いなく驚くべき動作です。

ngAnimate broken expected use bug

最も参考になるコメント

@ tole42これは回避策です。

.YourElementClass.ng-animate { -webkit-animation: none 0s; }

全てのコメント17件

ngAnimateは、トリガーのいずれかで要素に対してアクティブになっているすべてのキーフレーム/遷移コードがngAnimateを介してアニメーション化されることを前提としているため、貪欲です。 したがって、この場合、 .loaderはngShow / ngHideとは関係ありませんが、有効なアニメーションとして選択されます。

これを回避するには、 .ng-animateクラスが要素に適用されているときに、アニメーションのスタイルを単純に消去します。

http://jsfiddle.net/PvS8k/4/

これはCSSの継承に関する問題です。 getComputedStyleだけに依存せずにスタイルを検出するためのより良い方法があれば、これらの種類の癖を回避できる可能性があります。

@matskoこの特殊なケースは実際にはリグレッションだと思います。 @SimpleAsCouldBeのプランカー、またはこのプランカーhttp://plnkr.co/edit/5cfIXfNryNOzK66q9YWL?p=previewでわかるように、1.2.17では要素はすぐには消えませんが、1.2.16では要素が消えません。します。 これは、 https://github.com/angular/angular.js/commit/55b2f0e8620465559016b424967d90a86af597c0が原因である可能性があり
これはもう少し詳しく調べる必要があると思います。 少なくとも、これに関する変更ログとドキュメントにメモがあるはずです。

回避策をありがとう、それは期待通りにトリックを行います。

2点。 1つはng-showに固有で、もう1つは一般的です。

ng-show +無限のアニメーション:

無限のアニメーションはng-showの非表示を_本当に_遅らせる必要がありますか? 秒を数えてみましたが、非表示になるのを待つのは必ずしも4秒ではありません。 時々その5または7 ...は異なるようです。 また、チェックボックスをオンとオフに切り替えると、非表示になることはありません。 ここのどこかに実際のバグが隠れていると思います。

哲学的

非寄稿者として、私はあまり言いませんが、おそらくオプトアウトはこのライブラリの正しい戦略ではありません。 JSライブラリがCSSルールに反応するのは驚くほど魔法のようなものです。要素にng-animatableタグを付ける必要がある場合は、これに対してはるかに準備ができています。

@SimpleAsCouldBeはい、ngAnimateがアニメーションにフックするように、すべてのアニメーションにanimate-クラスプレフィックスを付けるのが最善かもしれないと同じように考えてきました。

遅延に関しては、遅延があるわけではなく、ngAnimateが無限の部分をキャンセルし、アニメーションを1回だけ実行するということです。 したがって、非表示にすると、2秒* 1.5 = 3秒待機してから、タイムアウトチェックを実行し、アニメーションを閉じます。 したがって、そこにあるべきではない不必要な時間枠です。CSSスタイルの検出のみが非常に制限されています。

@Narretzは、.ng-hideスタイルが別の時間にdisplay:none値を適用したためです。 ただし、現在の修正は、すべてのアニメーションが完了した後( .ng-animateクラスが削除された後)にのみ適用されます。

以下のデモをご覧ください。 .blueクラスには2セットのセレクターがあることを確認してください。1つは.ng-animateあり、もう1つはなしです。 .blueクラスがすぐに適用されているにもかかわらず、ngAnimateはアニメーションの期限が切れていると見なし、終了タイムアウトを適用する前に3s (2秒* 1.5を思い出してください)を待ちます。 通常、それは2Sだろうが、 animationendイベントは、要素上の実際のアニメーション以来、解雇されることはありません(ありの理由は.loader無限であるとNG-クラスによってトリガされません)(または前の例のng-show)。 とはいえ、これは以前のバグ修正のために影響を受けません。
http://jsfiddle.net/PvS8k/15/

ngAnimateのナイーブさを減らし、 animated-がCSSプレフィックスとしてどこかにある場合にのみアニメーション化するのが最善の場合があります。

オプトインアニメーション処理のような重大な変更を受け入れるのであれば、それほど驚くことではない開発者エクスペリエンスを作成できると思います。

昔ながらの.animateではなく、 .ng-animateような角度固有の何かを接頭辞として付けてもかまいませんか?

私は同じ問題を抱えています:
角度が> = 12.17の場合http://jsfiddle.net/9krLr/17/
角度1.2.16ではすべてが問題ありません: http ://jsfiddle.net/EZpQQ/1/

@ tole42これは回避策です。

.YourElementClass.ng-animate { -webkit-animation: none 0s; }

ご協力いただきありがとうございます。 回避策が機能していません:(
なにが問題ですか?
http://jsfiddle.net/9krLr/21/

@ tole42私が見る限り、そのフィドルには何もアニメーション化されていません。 アニメーションはFoundationライブラリの一部ですか? より直接的な再作成の場合は、これをデバッグしやすくします。 私には同じ問題のようには見えません。

@ tole42と同じ問題が発生すると

<div ng-hide="hideme">hide me</div>

その皮にアニメーションが必要な場合は、次のようにします。

<div ng-hide="hideme" class="myanimation">hide me</div>

アプリには、表示/非表示をアニメーション化する場合と、アニメーション化したくない場合があります。 アニメーション化したくない場合は、表示/非表示になっている要素をカスタムアニメーションクラスで装飾しません。 この例では、Angularは「ng-hide」クラスを非表示の要素に追加するだけです。

モジュールにngAnimateをまったく含めない場合、これは期待どおりに機能します。要素はすぐに消えます。 しかし、ngAnimateを含めるだけで、 @ tole42が投稿した2つのフィドルに示されている動作が得られます。「ng-hide」クラスが追加された要素が実際に消えるまでに遅延があります。 アニメーションを使用しない場合は、すぐに消えるはずです。

うまくいくと思われるいくつかの回避策は次のとおりです。

.ng-hide-add {
    transition: 0s linear all;
}

または:

.ng-hide {
    display: none !important;
}

しかし、アニメーション化されていない方法で何かを単に隠そうとしている場合に、それらが必要であるというのは正しくないようです。

いくつかの追加の発見をフォローアップするためだけに...

問題を可能な限り単純なシナリオ(プレーンなdivの表示/非表示)に要約しようとしても、問題は発生しません。

@ tole42によって投稿されたフィドルで、foundation.cssが使用されていることに気付きました。この例は、入力フィールドの表示/非表示に関する問題を示しています。 私の経験は似ていましたが(入力フィールドで問題のマニフェストを確認)、bootstrap.cssを使用しました。 これらのcssファイルの両方をさらに詳しく調べると、どちらもcss遷移を入力フィールドに適用します。

これらのcss遷移は、angular-animateがそれらから期間を取得しているため、本当の原因であるように見えます。 これが、意図的にその遷移をアニメーション化しようとしていない場合でも、これらの要素を表示/非表示にするときに視覚的な遅延を引き起こす原因です。

したがって、これは必ずしもAngularが解決しようとする問題ではないと思います。 これは、他のcssライブラリでangular-animateを使用することの副作用であり、予期しないcss遷移が埋め込まれている可能性があります。

根本的な原因を突き止めるのに長い時間がかかりましたが、最終的に意味のある理由を見つけることができて良かったです。

はい、これはngAnimateの重要な問題ですが、getComputedStyleの制御がなく、他のライブラリの遷移がカスケードされているため、ngAnimateはこれを検出できません。

これを修正するには、2つの解決策があります。

1) .ng-animateクラスのスタイルを上書きします。
http://jsfiddle.net/9krLr/27/

以前は機能しなかった理由は、CSSの特異性が不足していたためです。

2) $animateProvider.classNameFilter(regex)ます。 この場合の正規表現は、ngAnimateによってトリガーされるすべてのアニメーションにハードブロックを配置し、正規表現がアニメーション化する要素に存在するclassNameと一致する場合にのみ、アニメーションの実行を許可します。

ああ、設定をプロバイダーに入れるのは良い方法です、私はそれがとても好きです、@ matsko!

@pnutshellmenace迅速な解決策に感謝します。 それは私の日を救った。

ここでの最終的な解決策が何であったかわかりません。 @matskoは述べました:

ngAnimateのナイーブさを減らし、アニメーション化された場合にのみアニメーション化するのが最善かもしれません-CSSプレフィックスとしてどこかにあります

しかし、そのような実装は見当たりません。 $animateProvider.classNameFilter(regex)調べましたが、繰り返しになりますが、回答よりも多くの質問が残っています。 これを実装する実際的な方法は何ですか?また、適用可能なクラス名が複数ある場合はどうなりますか?

ngAnimateがすべてをアニメートしたいと想定する理由はわかりません。 アニメートしたくないものは常にありますが、現在は他の方法よりもアニメートしたくないものがたくさんあります。そのため、手動でスタイリングしてトランジションを無効にします。

編集:物事を見通しに入れるこのブログエントリを見つけました...私はそれを試してみるつもりです: http

編集2: $animateProvider.classNameFilter(/enable-animate/);追加

ngAnimateに依存するサードパーティのAngularモジュールの.jsファイルを含めましたが、どういうわけか、自分のモジュールでもアニメーションがトリガーされていました。 どういうわけかngAnimateは親モジュールのスコープに影響を与えていましたか?

非同期操作に$scope.$evalAsync();を使用するこの回答をお勧めします。 うまく機能します。

このページは役に立ちましたか?
0 / 5 - 0 評価