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": "アイムエンタープライズ"
}
]
}
コメントが承認されるまで時間がかかります。