Onsen UIのカルーセルを使って、スワイプで切り替えるタブを作ってみました。
サンプルコード
タブとカルーセル部分はng-repeatで表示するようにしています。
HTML
<ons-navigator var="myNavigator"> <ons-page> <div class="contents"> <div class="tab-switch"> <div class="tab-switch_inner" ng-style="tabPoint"> <div class="tab-switch_item" ng-repeat="belong in belongData.belongs" ng-click="changeTab($index)" ng-class="{active: belong.isActive}">{{belong.name}}</div> </div> </div> <ons-carousel var="tab" swipeable auto-scroll ng-style="tabHeight"> <ons-carousel-item ng-repeat="belong in belongData.belongs"> <ons-list> <ons-list-header>{{belong.name}}</ons-list-header> <ons-list-item ng-repeat="actor in actorData.actors | filter:{ belong: belong.name }">{{actor.name}}</ons-list-item> </ons-list> </ons-carousel-item> </ons-carousel> </div> </ons-page> </ons-navigator>
CSS
.contents { max-width: 640px; margin: 0 auto; } .tab-switch { overflow-x: auto; } .tab-switch_inner { display: table; position: relative; } .tab-switch_item { display: table-cell; overflow: hidden; padding: 5px; border-left: #ccc 1px solid; white-space: nowrap; text-overflow: ellipsis; max-width: 100px; cursor: pointer; } .tab-switch_item.active { background: #999; } ons-carousel-item { height: auto !important; }
JavaScript
var app = angular.module('app', ['onsen']); app.controller('app_Ctrl', function($scope, $timeout, $http) { $scope.belongData = ''; $scope.actorData = ''; $scope.tabHeight = {}; // jsonデータの取得 $http.get('belongData.json').success(function(data) { // 1番目のタブを選択した状態にする data['belongs'][0]['isActive'] = true; // 取得したデータを格納 $scope.belongData = data; $timeout(function() { // タブの更新 tab.refresh(); }); }).error(function() { alert('取得失敗'); }); $http.get('actorData.json').success(function(data) { // 取得したデータを格納 $scope.actorData = data; $timeout(function() { // タブの更新 tab.refresh(); // カルーセルの高さを設定 $scope.tabHeight = { height: document.getElementsByTagName('ons-carousel-item')[0].clientHeight + 'px' }; }); }).error(function() { alert('取得失敗'); }); // タブをクリックしたとき $scope.changeTab = function(index) { tab.setActiveCarouselItemIndex(index); } // タブのスクロール位置の設定 $scope.tabPoint = { left: '0px' }; ons.ready(function() { // カルーセルに変更があったとき tab.on('postchange', function(e) { // タブ部分の移動可能な範囲 var difference = document.getElementsByClassName('tab-switch_inner')[0].clientWidth - document.getElementsByClassName('tab-switch')[0].clientWidth; // タブのスクロール位置 var scrollPoint = (difference / ($scope.belongData['belongs'].length - 1) * e.activeIndex); $timeout(function() { // activeの解除と設定 $scope.belongData['belongs'][e.lastActiveIndex]['isActive'] = false; $scope.belongData['belongs'][e.activeIndex]['isActive'] = true; // タブのスクロール位置の設定 $scope.tabPoint = { left: -scrollPoint + 'px' }; // タブの高さ変更 $scope.tabHeight = { height: document.getElementsByTagName('ons-carousel-item')[e.activeIndex].clientHeight + 'px' }; }); }); }); });
タブとコンテンツ部分の内容はjsonから取得するようにしています。
belongData.json
{ "belongs": [ { "name": "81プロデュース", "isActive": false }, ~ 略 ~ { "name": "大沢事務所", "isActive": false } ] }
actorData.json
{ "actors": [ { "name": "高橋 李依", "kana_en": "takahashi rie", "kana_jp": "たかはし りえ", "birthday": "1994.2.27", "belong": "81プロデュース" }, ~ 略 ~ { "name": "早見 沙織", "kana_en": "hayami saori", "kana_jp": "はやみ さおり", "birthday": "1991.5.29", "belong": "アイムエンタープライズ" } ] }
コメントが承認されるまで時間がかかります。