AngularJSの適応カルーセル

おそらく、すべての初心者のWeb開発者は、独自のカルーセルではなく、たくさんの松葉杖で曲線を作成する必要があります。 この資料は、フレームワークの複雑さの一部を理解し、「角度のある」カルーセルを作成する方法を読者に示すのに役立ちます。

カルーセル-Webベースのインターフェイスの要素。ユーザーが準備したスライドに情報を表示します。



カルーセルの例



ここで完成したプロジェクトを見ることができます



カルーセルのアイデアは、 z-indexの cssプロパティを使用して画面上のカードを2つのレベルで美しく整列させ、 transitionプロパティを使用してアニメーションの変更でカードのcss位置を交互に変更することです。

CSSファイルは次のようになります。

CSSを表示
el-carousel { width: 100%; margin: 0; position: relative; z-index: 20; } .el-carousel .el-card { position: absolute; background: rgba(141, 141, 141, 0.5); border:1px #e0e0e0 solid; border-radius:1px; box-shadow: 0 0 0 4px rgba(107, 108, 40, 0.25), 0 0 0 5px rgba(183, 183, 183, 0.6); -webkit-transition: all 1s ease-in-out; -moz-transition: all 1s ease-in-out; -o-transition: all 1s ease-in-out; transition: all 1s ease-in-out; z-index: 5; opacity: 0.2; cursor: pointer; } .el-carousel .sm-el-card-1 { height: 65%; width: 23%; left: 6%; bottom: 1%; z-index: 20; } .el-carousel .sm-el-card-2 { height: 70%; width: 25%; left: 2%; bottom: 7%; opacity: 0; } .el-carousel .sm-el-card-3 { height: 70%; width: 25%; left: 2%; bottom: 7%; z-index: 20; opacity: 0.8; } .el-carousel .sm-el-card-4 { height: 84%; width: 30%; left: 35%; bottom: 14%; z-index: 20; opacity: 1; background: rgba(141, 141, 141, 0.7); } .el-carousel .sm-el-card-5 { height: 70%; width: 25%; left: 73%; bottom: 7%; z-index: 20; opacity: 0.8; } .el-carousel .sm-el-card-6 { height: 70%; width: 25%; left: 73%; bottom: 7%; opacity: 0; } .el-carousel .sm-el-card-7 { height: 65%; width: 23%; left: 70.5%; bottom: 1%; } .el-carousel .sm-el-card-8 { height: 77%; width: 27%; left: 33%; bottom: 8%; } .el-carousel .sm-el-card-hide { height: 77%; width: 27%; left: 33%; bottom: 8%; opacity: 0; } .el-carousel .md-el-card-4 { height: 57%; width: 14%; left: 2%; bottom: 7%; z-index: 20; opacity: 0.6; } .el-carousel .md-el-card-5 { height: 71%; width: 16%; left: 20.5%; bottom: 11%; z-index: 20; opacity: 0.8; } .el-carousel .md-el-card-6 { height: 84%; width: 19%; left: 40.5%; bottom: 14%; z-index: 20; opacity: 1; background: rgba(141, 141, 141, 0.7); } .el-carousel .md-el-card-7 { height: 71%; width: 16%; left: 63.75%; bottom: 11%; z-index: 20; opacity: 0.8; } .el-carousel .md-el-card-8 { height: 57%; width: 14%; left: 84%; bottom: 7%; z-index: 20; opacity: 0.6; } .el-carousel .md-el-card-9 { height: 57%; width: 14%; left: 84%; bottom: 7%; opacity: 0; } .el-carousel .md-el-card-10 { height: 67%; width: 15%; left: 62%; bottom: 7%; } .el-carousel .md-el-card-1 { height: 78%; width: 18%; left: 38.7%; bottom: 9.5%; } .el-carousel .md-el-card-2 { height: 67%; width: 15%; left: 18.7%; bottom: 7%; } .el-carousel .md-el-card-3 { height: 57%; width: 14%; left: 2%; bottom: 7%; opacity: 0; } .el-carousel .md-el-card-hide { height: 78%; width: 18%; left: 38.7%; bottom: 9.5%; opacity: 0; } .el-carousel .lg-el-card-1 { height: 78.7%; width: 15%; left: 40.5%; bottom: 10%; } .el-carousel .lg-el-card-2 { height: 65%; width: 13%; left: 23.5%; bottom: 7%; } .el-carousel .lg-el-card-3 { height: 52%; width: 11%; left: 9%; bottom: 3%; } .el-carousel .lg-el-card-4 { height: 33%; width: 7%; left: 1%; bottom: 4%; z-index: 10; opacity: 0.4; } .el-carousel .lg-el-card-5 { height: 57%; width: 12%; left: 10%; bottom: 7%; z-index: 20; opacity: 0.6; } .el-carousel .lg-el-card-6 { height: 71%; width: 14%; left: 25%; bottom: 11%; z-index: 20; opacity: 0.8; } .el-carousel .lg-el-card-7 { height: 84%; width: 16%; left: 42%; bottom: 14%; z-index: 20; opacity: 1; background: rgba(141, 141, 141, 0.7); } .el-carousel .lg-el-card-8 { height: 71%; width: 14%; left: 61%; bottom: 11%; z-index: 20; opacity: 0.8; } .el-carousel .lg-el-card-9 { height: 57%; width: 12%; left: 78%; bottom: 7%; z-index: 20; opacity: 0.6; } .el-carousel .lg-el-card-10 { height: 33%; width: 7%; left: 91.32%; bottom: 4%; z-index: 10; opacity: 0.4; } .el-carousel .lg-el-card-11 { height: 52%; width: 11%; left: 77%; bottom: 3%; } .el-carousel .lg-el-card-12 { height: 65%; width: 13%; left: 59.5%; bottom: 7%; } .el-carousel .lg-el-card-hide { height: 78.7%; width: 15%; left: 40.5%; bottom: 10%; opacity: 0; }
      
      







カルーセルは適応型であるため、すべてのサイズと位置のパラメーターはパーセンテージで決定されます。

それでは、角度カルーセルを実装してみましょう。 各カルーセルカードに一意のテンプレートとアクションがあるように、ディレクティブとファクトリーを使用します。



工場を考える

クロージャーには、2つの配列を格納します。



ファクトリーは2つのメソッドaddCardaddActionを提供します。これらのメソッドは、それぞれクリック時に実行されるhtml-templateと関数を配列に追加します。 addCard関数は、2番目のオプションのパラメーターを入力として受け入れます。このパラメーターは、ブール値trueでプロミスを解決します。 これは一種の松葉杖です。これについては後で説明します。

それとは別に、依存関係の安全な接続に注意します。 詳細に入らないと、接続されている依存関係の名前を変更できません。これは、コードが縮小されるとコードが完全に壊れるからです。 したがって、格納庫では依存関係の安全な接続が提供されます-ファクトリー/コントローラー/ディレクティブ関数の代わりに、配列が渡され、その最初の要素は依存関係の文字列名を示し、接続された依存関係を持つ関数自体が最後です。 この場合、コードの最小化を恐れることはなくなりましたが、配列内の文字列依存関係をリストする順序は、関数内の依存関係を接続する順序と一致する必要があることを忘れてはなりません。

工場コードを見る
 'use strict'; (function () { angular.module('carousel') .factory('card', ['$q', function ($q) { var list = [], action = [], done = $q.defer(); //    function addCard(card, last) { if(typeof card === 'object' && card.length > 0) { list.push(card); if(last) { done.resolve(); } } } //       function addAction(foo) { action.push(foo); } //      ,   return { addCard: addCard, addAction: addAction, list: list, action: action, done: done.promise }; }]); })();
      
      







HTMLカードテンプレートディレクティブ

ここではすべてが簡単です。 ディレクティブの場合、ディレクティブが設定されている要素の属性を介して転送される3つのパラメーターを持つ分離スコープが設定されます。

ディレクティブの便宜上、転送するパラメーターの名前を変更できることに注意してください。 スコープオブジェクトのキーは、使用に便利な名前を示し、そのフィールドでは、スローのタイプ(=、@、&)を指定した後、要素の属性の名前を示します。 要素属性が二重である場合、たとえばlast-cardの場合、要素名にはラクダlastCard表記の形式で示されます。

アクションパラメータはを介して転送されます-これは、式が入力として受け入れられることを意味します。この場合、カードをクリックする機能です。

アイテム最後のパラメーターは=を介して転送されます。 入力は特定の値を取ります。これは、属性値に明示的に設定するか、ディレクティブが配置されているスコープ変数で定義して、変数要素の属性に渡すことができます。

これらのパラメータは、カードごとに個別のテンプレートを作成するのではなく、1つのテンプレートを作成し、ng-repeatディレクティブを使用して複製する場合に必要です。 アイテムデータは、 ng-repeatを使用して取得した現在のデータオブジェクトに渡されます。 最後のパラメーターには、特別な値$ lastが渡されます。この値に、 ng-repeatディレクティブは、クローンの対象となる配列のオブジェクトが最後の場合にtrueに設定します

html-template(実際にはディレクティブの内部コンテンツ)を取得するには、 transcludeパラメーターをtrueに設定します 。 同時に、5番目のパラメーターがディレクティブのリンク関数( link )に表示されます。これは、トランスクルージョン関数です。 この関数の目的はより広いことに注意してください。ただし、この場合はディレクティブの内部コンテンツを取得するためにのみ使用されます。

$ lastクローニングの最後の要素の明示的な定義で松葉杖の使用を正当化する時が来ました。 実際、 ng-repeatと組み合わせたtranscludeを使用したユーザーディレクティブは特に機能します。 これは、一連の操作によるものです。まず、要素テンプレートをアンギュラークローンし、次にユーザーディレクティブを含む優先度の低い他のディレクティブが実行され、その後、クローンテンプレートにスコープの値が入力されます。 したがって、ng-repeatがジョブを実行したことを明示的に指定しない場合、カルーセルはクローン要素の内容を含むカードを表示しません。

ディレクティブコードを表示
 'use strict'; (function () { angular.module('carousel') .directive('elCard', ['card', function(card) { return { scope: { action: '&cardAction', item: '=elCard', last: '=lastCard' }, restrict: 'A', transclude: true, link: function(scope, elem, attr, ctrl, transclude) { //         card.addAction(scope.action); //     transclude(scope, function(item) { card.addCard(item, scope.last); elem.remove(); }); } }; }]); })();
      
      







カルーセルディレクティブ

このディレクティブは、使用可能なテンプレートに従ってカルーセルを作成します。 カルーセルには3つのオプションがあります:前列の3、5、または7枚のカード。 デフォルトでは、7枚のカードが選択されていますが、カードの数を手動で決定するための要素転送パラメーターが提供されています。 カードの数に応じて、 heihtCoeffカルーセル要素の変換係数が決定されます。

このディレクティブは、次の3つの関数で構築されています。



アクティブ化および停止するために$ Intervalで moveCardsを定期的に実行する補助関数runCarouselおよびstopCarouselが提供され ます 。 別のタブに切り替えても、 $ intervalは機能し続けますが、css 遷移プロパティは機能しません。これにより、カルーセルが誤動作します。 したがって、カルーセルの開始と停止は、アクティブウィンドウの変更イベントに関連付けられています。 ディレクティブの最後で、すべてのリスナーを解くのを忘れないでください。

ディレクティブコードを表示
 'use strict'; (function () { angular.module('carousel') .directive('elCarousel', ['$window', '$compile', '$interval', 'card', function($window, $compile, $interval, card) { return { scope: { elements: '=elCarousel' }, restrict: 'A', link: function($scope, elem) { var cards = [], action = [], heightCoeff = ($scope.elements === 3) ? 2 : ($scope.elements === 5) ? 3.3 : 3.96, cardAmount = ($scope.elements === 3) ? 8 : ($scope.elements === 5) ? 10 : 12; $scope.card = []; //       elem.addClass('el-carousel'); //           ng-repeat function preStartActions() { if(card.list.length < 1) { return; } cards = card.list; action = card.action; makeCards(); } preStartActions(); card.done.then(preStartActions); //        function changeHeight() { var carouselWidth = elem.width(), carouselHeight = carouselWidth / heightCoeff; elem.css('height', carouselHeight); } angular.element($window).bind('resize', changeHeight); changeHeight(); //  DOM     function makeCards() { elem.empty(); var k = 0, cardNumber = (cards.length > cardAmount) ? cards.length : cardAmount, numClass = (cardAmount === 8) ? 'sm-' : (cardAmount === 10) ? 'md-' : 'lg-'; for(var i = 0; i < cardNumber; i++) { var div = angular.element('<div ng-click="cardAction' + i + '()" class="el-card" ng-class="card[' + i + ']"></div>'); if(i < cards.length) { div.append(cards[i].clone()); $scope['cardAction' + i] = action[i]; } else { div.append(cards[k].clone()); $scope['cardAction' + i] = action[k]; k = (k > cards.length - 2) ? 0 : k + 1; } $scope.card[i] = (i < cardAmount) ? numClass + 'el-card-' + (i + 1) : numClass + 'el-card-hide'; $compile(div)($scope); elem.append(div); } } //      function moveCards() { var lastElem = $scope.card.shift(); $scope.card.push(lastElem); } // /       var moveInterval; runCarousel(); angular.element($window).bind('blur', stopCarousel); function stopCarousel() { $interval.cancel(moveInterval); } angular.element($window).bind('focus', runCarousel); function runCarousel() { moveInterval = $interval(moveCards, 2000); } elem.bind('$destroy', function () { $interval.cancel(moveInterval); angular.element($window).unbind('blur', stopCarousel); angular.element($window).unbind('focus', runCarousel); angular.element($window).unbind('resize', changeHeight); }); } }; }]); })();
      
      







その結果、 HTMLカルーセルコードは次のようになります。

  <div el-carousel="7"> <div ng-repeat="card in cardList" el-card="card" card-action="someAction(someParam)" last-card="$last"> <span>{{card.name}}</span> <img class="image image-1" ng-src={{card.img}} alt={{card.alt}}/> </div> <div el-card card-action="otherAction(otherParam)"> <img class="image image-2" src="/app/ru/main/img/js.png" alt="javascript"/> </div> </div>
      
      





個別に記述されたテンプレートとng-repeatを使用して複製されたテンプレートの両方を使用できます。



ご清聴ありがとうございました、皆さんに幸運を。



All Articles