ホームページ >ウェブフロントエンド >htmlチュートリアル >Angular の繰り返しの行操作に動的効果を追加するときに発生する問題の概要 list_html/css_WEB-ITnose
「アニメーション効果」を追加することは、ユーザーにアプリケーションの動作を認識させる効果的な方法です。 「リスト」はアプリケーションで最も一般的に使用されるインターフェイス フォームであり、行の追加、行の削除、行の移動などの操作が頻繁に行われます。追加操作は非常に単純で、削除する場合は大きい値から小さい値に移動し、追加する場合は小さい値から大きい値に移動します。これは、最初に削除してから追加することを意味します。複雑な感じはなく、CSS トランジションを使用して実行する必要があります。しかし、実際には対処すべき問題がたくさんあることがわかりました。一つずつ見ていきましょう。
<div class='list'> <div class='row-1'>row-1</div> <div class='row-2'>row-2</div></div>
.list{margin:20px;background:#eee;font-size:18px;color:white;}.row-1{background:green;overflow:hidden;padding:15px;}.row-2{background:blue;padding:15px;}/*demo1*/.demo-1 .remove{-webkit-transition: height 3s linear;}.demo-1 .remove.active{height:0;}
var ele = document.querySelector('.demo-1 .row-1');ele.classList.add('remove');ele.classList.add('active');
アイデアは単純で、「削除」を追加してアニメーションを設定します。 class エフェクトには「active」を追加してcss属性を変更し、アニメーションを有効にします。
結果が期待したものと異なります: 1. アニメーションが実行されません。 2. row-1 が消えません。なぜ?まず、CSS トランジションは auto 属性に作用できません。row-1 には元々高さが設定されていないため、既存の高さから 0 へのアニメーションは生成されません。次に、height=0 はコンテンツ領域を 0 に設定するだけで、パディングは変更されていないため、row-1 は依然として 30 ピクセルのスペースを占有します。
CSS を調整します
/*demo2*/.demo-2 .row-1{height:48px;}.demo-2 .remove{-webkit-transition: height 3s linear, padding-top 3s linear;}.demo-2 .row-1.remove.active{height:0;padding-top:0;padding-bottom:0;}
今回の効果は正しく、row-1 は 48px から 0 になります。それに応じてパディングも変更されます。
CSSを修正
/*demo3*/.demo-3 .remove{-webkit-transition: -webkit-transform 3s linear,padding 0s linear 3s;}.demo-3 .row-1.remove.active{-webkit-transform-origin:0 0;-webkit-transform:scaleY(0);}
高さを設定しなくても変形によるアニメーションは問題ありません。問題は、行 1 がまだ元の場所にあり、スペースを占有しており、行 2 が上に移動していないことです。これにより、アニメーションの実行後 (高さの設定の 2 番目の例を含む)、行 1 が削除されず、非表示になります。
CSS を変更
.demo-4 .remove{-webkit-transition: height 3s linear, padding 3s linear, opacity 3s linear,color .5s linear;}.demo-4 .row-1.remove.active{padding-top:0;padding-bottom:0;color:rgba(0,0,0,0);opacity:0;}
JS を変更
var ele, l;ele = document.querySelector('.demo-4 .row-1');l = ele.addEventListener('webkitTransitionEnd', function(evt){ if (evt.propertyName === 'height') { ele.style.display = 'none'; ele.style.height = ''; ele.removeEventListener('webkitTransitionEnd', l, false); }}, false);ele.style.height = ele.offsetHeight + 'px';ele.classList.add('remove');$timeout(function(){ ele.classList.add('active'); ele.style.height = '0px';});
今回の効果は良い。注意すべき点がいくつかあります: 1.transitionEnd イベントを登録すると、アニメーションの終了をキャプチャできます。2. 複数のアニメーションを同時に実行できます。transitionEnd イベントはそれぞれの終了時に生成されます。イベントの「propertyName」からどのプロパティであるかを知ることができます。アニメーションは終了です。
CSS は JS コードを設定する必要はありません
var ele = document.querySelector('.demo-5 .row-1');Velocity(ele, 'slideUp', { duration: 1000 });
実行過程を見て高さも修正してみましたそしてパディング。ただし、速度は requestAnimationFrame 関数を使用します。比較的単純なアニメーションであれば他のライブラリを導入する必要はなく、直接書いても実行効果はほぼ同じになると思います。
CSS を調整
.demo-6 .row-1{width:100%;}.demo-6 .remove{-webkit-transition: width 3s linear;}.demo-6 .row-1.remove.active{width:0%;}
幅自体はパーセンテージで設定できますが、高さが固定されていないという問題は依然として存在します。
CSSを設定します
.demo-7 .row-1{width:100%;height:48px;}.demo-7 .remove{-webkit-transition: width 3s linear, opacity 3s ease;}.demo-7 .row-1.remove.active{width:0%;opacity:0;}
高さを固定すると、アニメーションは正常になります。その他の改善点については、前の例を参照してください。
完全な例は angular で実装されています。 Angular の実装における最初の疑問は、動的効果をいつ設定するかということです。 Angular は双方向バインディングであるため、コントローラーでオブジェクトが削除されると、インターフェイスがレンダリングされるときにオブジェクトが失われるため、データ バインディング プロセスが関与する必要があります。 Angular は ngAnimatie アニメーション モジュールを提供しています。試してみると、実際に ngRepeat リスト データ更新のアニメーション効果を完成させることができます。ただし、追加で angular-animation.js を導入する必要があります。大したことではありませんが、それでも必要ではないように感じます。また、すでに作成されているフレームワークのページにアニメーションを追加する場合、新しいモジュールを導入する必要がある場合、フレームワーク ファイルを変更する必要がありますが、これは良くないと思います。アニメーションモジュールを動的にロードしようとしたのですが失敗したので、アニメーションを制御する方法を自分で勉強しました。
angular がアニメーション モジュールをロードしない場合でも、アニメーション コントロールのインターフェイスを提供する $animate が存在します。 JS を見ると、
var fnEnter = $animate.enter, fnLeave = $animate.leave;$animate.enter = function() { var defer = $q.defer(), e = arguments[0], p = arguments[1], a = arguments[2], options = { addClass: 'ng-enter' }; fnEnter.call($animate, e, p, a, options).then(function() { $animate.addClass(e, 'ng-enter-active').then(function(){ var l = e[0].addEventListener('webkitTransitionEnd', function(){ e[0].classList.remove('ng-enter-active'); e[0].classList.remove('ng-enter'); e[0].removeEventListener('webkitTransitionEnd', l, false); defer.resolve(); }, false); }); }); return defer.promise;};$animate.leave = function() { var defer = $q.defer(), e = arguments[0]; $animate.addClass(e, 'ng-leave').then(function(){ $animate.addClass(e, 'ng-leave-active').then(function(){ var l = e[0].addEventListener('webkitTransitionEnd', function(){ fnLeave.call($animate, e).then(function(){ defer.resolve(); }); }, false); }); }); return defer.promise;};
ng-repeat はデータ更新時に $animate サービスの enters、leave、move メソッドを呼び出します。そのため、アニメーションを自分で制御したい場合は、対応するメソッドを書き換える必要があります。 。書き換える場合は$animateを使って追加する必要があります。DOMに直接設定するのは問題があります。 (この段落のAngularのロジックは比較的低レベルなのでよく分かりません。さらなる勉強が必要です。)
また、行の位置を移動する場合は、削除と挿入を行います。 $timeout を介して 2 つのダイジェスト ループに配置する必要があります。そうしないと効果が見られません。
var index = records.indexOf($scope.selected), r = records.splice(index, 1);$timeout(function(){ records.splice(index + 1, 0, r[0]);},500);
Angularのアニメーションはダイジェストサイクルと密接に関係していますが、angular-animation.jsのコードを見ても理解できなかったので、深く勉強する必要があります。