<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<!DOCTYPE html><html lang='en' class=''>
<head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/cungen/pen/LVWwVq?limit=all&page=24&q=terminal" />
<link rel='stylesheet prefetch' href='//cdn.bootcss.com/angular-material/0.10.1-rc1/angular-material.min.css'><link rel='stylesheet prefetch' href='//cdn.bootcss.com/font-awesome/4.3.0/css/font-awesome.min.css'>
<style class="cp-pen-styles">[ng\:cloak], [ng-cloak], .ng-cloak {
display: none !important;
}
fpm-tabs, fpm-tabs-wrapper,
fpm-prev-button, fpm-next-button,
fpm-tabs-canvas, fpm-pagination-wrapper, fpm-tabs-content-wrapper,
fpm-tab-item, fpm-tab-content {
display: block;
}
fpm-tab-data {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
opacity: 0;
overflow: hidden;
}
fpm-tabs {
border: 1px solid lightgrey;
}
fpm-tabs-wrapper {
position: relative;
border-bottom: 1px solid lightgrey;
}
fpm-tabs-wrapper fpm-tabs-canvas:after, fpm-tabs-wrapper fpm-pagination-wrapper:after {
content: "";
display: table;
clear: both;
}
fpm-tabs-wrapper fpm-tabs-canvas {
position: relative;
overflow: hidden;
}
fpm-tabs-wrapper fpm-tabs-canvas.fpm-paginated {
margin: 0 32px;
}
fpm-tabs-wrapper fpm-pagination-wrapper {
position: relative;
width: 999999px;
left: 0;
top: 0;
-webkit-transition: left 0.3s cubic-bezier(0.35, 0, 0.25, 1);
-moz-transition: left 0.3s cubic-bezier(0.35, 0, 0.25, 1);
-ms-transition: left 0.3s cubic-bezier(0.35, 0, 0.25, 1);
-o-transition: left 0.3s cubic-bezier(0.35, 0, 0.25, 1);
transition: left 0.3s cubic-bezier(0.35, 0, 0.25, 1);
}
fpm-tabs-wrapper fpm-pagination-wrapper fpm-tab-item {
font-size: 14px;
padding: 12px 24px;
white-space: nowrap;
cursor: pointer;
float: left;
outline: 0;
}
fpm-tabs-wrapper fpm-pagination-wrapper fpm-tab-item.fpm-active {
color: deepskyblue;
}
fpm-tabs-wrapper fpm-prev-button, fpm-tabs-wrapper fpm-next-button {
cursor: pointer;
font-size: 14px;
padding: 12px 12px;
outline: 0;
}
fpm-tabs-wrapper fpm-prev-button.fpm-disabled, fpm-tabs-wrapper fpm-next-button.fpm-disabled {
opacity: 0.25;
cursor: default;
}
fpm-tabs-wrapper fpm-prev-button {
float: left;
}
fpm-tabs-wrapper fpm-next-button {
float: right;
}
fpm-tabs-content-wrapper {
position: relative;
overflow: hidden;
}
fpm-tabs-content-wrapper fpm-tab-content {
position: absolute;
top: 0;
right: 0;
left: 0;
height: auto;
overflow: auto;
}
fpm-tabs-content-wrapper .fpm-active {
position: relative;
}
fpm-tabs-content-wrapper .fpm-left {
-webkit-transform: translateX(-100%);
-moz-transform: translateX(-100%);
-ms-transform: translateX(-100%);
-o-transform: translateX(-100%);
transform: translateX(-100%);
}
fpm-tabs-content-wrapper .fpm-right {
-webkit-transform: translateX(100%);
-moz-transform: translateX(100%);
-ms-transform: translateX(100%);
-o-transform: translateX(100%);
transform: translateX(100%);
}
fpm-tabs[fpm-align="left"], fpm-tabs[fpm-align="right"] {
display: table;
}
fpm-tabs[fpm-align="left"] fpm-tabs-wrapper, fpm-tabs[fpm-align="right"] fpm-tabs-wrapper {
display: table-cell;
vertical-align: top;
border-bottom: 0;
border-top: 0;
border-right: 1px solid lightgrey;
}
fpm-tabs[fpm-align="left"] fpm-tabs-canvas, fpm-tabs[fpm-align="right"] fpm-tabs-canvas {
margin: 0;
overflow: hidden;
}
fpm-tabs[fpm-align="left"] fpm-pagination-wrapper, fpm-tabs[fpm-align="right"] fpm-pagination-wrapper {
width: auto;
height: auto;
max-height: 999999px;
-webkit-transition: top 0.3s cubic-bezier(0.35, 0, 0.25, 1);
-moz-transition: top 0.3s cubic-bezier(0.35, 0, 0.25, 1);
-ms-transition: top 0.3s cubic-bezier(0.35, 0, 0.25, 1);
-o-transition: top 0.3s cubic-bezier(0.35, 0, 0.25, 1);
transition: top 0.3s cubic-bezier(0.35, 0, 0.25, 1);
}
fpm-tabs[fpm-align="left"] fpm-tabs-content-wrapper, fpm-tabs[fpm-align="right"] fpm-tabs-content-wrapper {
display: table-cell;
vertical-align: top;
}
fpm-tabs[fpm-align="left"] fpm-tab-item, fpm-tabs[fpm-align="right"] fpm-tab-item {
display: block;
float: none;
}
fpm-tabs[fpm-align="left"] fpm-prev-button, fpm-tabs[fpm-align="left"] fpm-next-button, fpm-tabs[fpm-align="right"] fpm-prev-button, fpm-tabs[fpm-align="right"] fpm-next-button {
position: absolute;
left: 0;
right: 0;
text-align: center;
}
fpm-tabs[fpm-align="left"] fpm-prev-button, fpm-tabs[fpm-align="right"] fpm-prev-button {
top: 0;
}
fpm-tabs[fpm-align="left"] fpm-next-button, fpm-tabs[fpm-align="right"] fpm-next-button {
bottom: 0;
}
fpm-tabs[fpm-align="right"] fpm-tabs-wrapper {
border-right: 0;
border-left: 1px solid lightgrey;
}
fpm-tabs[fpm-align="bottom"] fpm-tabs-wrapper {
border-bottom: 0;
border-top: 1px solid lightgrey;
}
</style></head><body>
<div ng-controller="TabsController" layout="column">
<md-toolbar>
<div class="md-toolbar-tools">
<h2><span>Fpm-tabs</span></h2>
</div>
</md-toolbar>
<md-content layout="row" layout-wrap="layout-wrap">
<div class="md-padding" flex="60" offset="20">
<h3>试试在导航条上用鼠标的滚轮</h3>
</div>
<div class="md-padding" flex="60" offset="20">
<fpm-tabs fpm-align="top">
<fpm-prev-button><i class="fa fa-angle-left"></i></fpm-prev-button>
<fpm-next-button><i class="fa fa-angle-right"></i></fpm-next-button>
<fpm-tab ng-repeat="tab in tabs" ng-disabled="tab.disabled" label="{{tab.title}}" fpm-on-select="selectTab()">
<div style="padding: 25px; text-align: center">
<div ng-bind="tab.content"></div><br/>
<md-button class="md-primary md-raised" ng-click="removeTab( tab )" ng-disabled="tabs.length <= 1">Remove Tab</md-button>
</div>
</fpm-tab>
</fpm-tabs>
</div>
</md-content>
<md-content layout="row" layout-wrap="layout-wrap">
<div class="md-padding" flex="30" offset="20">
<fpm-tabs fpm-align="top">
<fpm-prev-button><i class="fa fa-angle-left"></i></fpm-prev-button>
<fpm-next-button><i class="fa fa-angle-right"></i></fpm-next-button>
<fpm-tab ng-repeat="tab in tabs" ng-disabled="tab.disabled" label="{{tab.title}}" fpm-on-select="selectTab()">
<div style="padding: 25px; text-align: center">
<div ng-bind="tab.content"></div><br/>
<md-button class="md-primary md-raised" ng-click="removeTab( tab )" ng-disabled="tabs.length <= 1">Remove Tab</md-button>
</div>
</fpm-tab>
</fpm-tabs>
</div>
<div class="md-padding" flex="30">
<fpm-tabs fpm-align="bottom">
<fpm-prev-button><i class="fa fa-angle-left"></i></fpm-prev-button>
<fpm-next-button><i class="fa fa-angle-right"></i></fpm-next-button>
<fpm-tab ng-repeat="tab in tabs" ng-disabled="tab.disabled" label="{{tab.title}}" fpm-on-select="selectTab()">
<div style="padding: 25px; text-align: center">
<div ng-bind="tab.content"></div><br/>
<md-button class="md-primary md-raised" ng-click="removeTab( tab )" ng-disabled="tabs.length <= 1">Remove Tab</md-button>
</div>
</fpm-tab>
</fpm-tabs>
</div>
</md-content>
<md-content layout="row" layout-wrap="layout-wrap">
<div class="md-padding" flex="30" offset="20">
<fpm-tabs fpm-align="left" fpm-height="250px">
<fpm-prev-button><i class="fa fa-angle-up"></i></fpm-prev-button>
<fpm-next-button><i class="fa fa-angle-down"></i></fpm-next-button>
<fpm-tab ng-repeat="tab in tabs" ng-disabled="tab.disabled" label="{{tab.title}}" fpm-on-select="selectTab()">
<div style="padding: 25px; text-align: center">
<div ng-bind="tab.content"></div><br/>
<md-button class="md-primary md-raised" ng-click="removeTab( tab )" ng-disabled="tabs.length <= 1">Remove Tab</md-button>
</div>
</fpm-tab>
</fpm-tabs>
</div>
<div class="md-padding" flex="30">
<fpm-tabs fpm-align="right" fpm-height="250px">
<fpm-prev-button><i class="fa fa-angle-up"></i></fpm-prev-button>
<fpm-next-button><i class="fa fa-angle-down"></i></fpm-next-button>
<fpm-tab ng-repeat="tab in tabs" ng-disabled="tab.disabled" label="{{tab.title}}" fpm-on-select="selectTab()">
<div style="padding: 25px; text-align: center">
<div ng-bind="tab.content"></div><br/>
<md-button class="md-primary md-raised" ng-click="removeTab( tab )" ng-disabled="tabs.length <= 1">Remove Tab</md-button>
</div>
</fpm-tab>
</fpm-tabs>
</div>
</md-content>
</div>
<script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script><script src='//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js'></script><script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js'></script><script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js'></script><script src='//cdn.bootcss.com/angular-material/0.10.1-rc1/angular-material.min.js'></script>
<script >angular.module('fpm:directives', []);
angular.module('fpm:controllers', []);
angular.module('fpm:services', []);
angular.module('fpm:filters', []);
(function(window, angular) {
angular
.module('fpm:directives')
.directive('fpmTab', FpmTab)
.directive('fpmTabs', FpmTabs)
.directive('fpmTemplate', FpmTemplate)
.directive('fpmTabScroll', FpmTabScroll)
.controller('FpmTabsController', FpmTabsController);
/**
* fpm-tab-data中的tab directive
*/
function FpmTab() {
return {
require: '^?fpmTabs',
terminal: true,
template: function(element, attr) {
var label = getLabel(),
body = getTemplate();
return '' +
'<fpm-tab-label>' + label + '</fpm-tab-label>' +
'<fpm-tab-body>' + body + '</fpm-tab-body>';
function getLabel() {
return getLabelElement() || getLabelAttribute() || getElementContents();
function getLabelAttribute () { return attr.label; }
function getLabelElement () {
var label = element.find('fpm-tab-label').eq(0);
if (label.length) return label.remove().html();
}
function getElementContents () {
var html = element.html();
element.empty();
return html;
}
}
function getTemplate() {
var content = element.find('fpm-tab-body').eq(0),
template = content.length ? content.html() : attr.label ? element.html() : '';
if (content.length) {
content.remove();
} else if (attr.label) {
element.empty();
}
return template;
}
},
scope: {
active: '=?fpmActive',
disabled: '=?ngDisabled',
select: '&?fpmOnSelect',
deselect: '&?fpmOnDeselect'
},
link: postLink
};
function postLink(scope, element, attr, tabsCtrl) {
if (!tabsCtrl) return;
var ctrl = tabsCtrl.scope,
body = element.find('fpm-tab-body').eq(0).remove(),
label = element.find('fpm-tab-label').eq(0).remove(),
data = ctrl.insertTab({
scope: scope,
parent: scope.$parent,
element: element,
template: body.html(),
label: label.html()
});
scope.select = scope.select || angular.noop;
scope.deselect = scope.deselect || angular.noop;
scope.$on('$destroy', function () {
ctrl.remove(data);
})
}
}
function FpmTabsController($scope, $element, $attrs, $compile, $timeout, $window) {
var _this = this,
elements = getElements();
_this.scope = $scope;
// variables
$scope.tabs = [];
$scope.offsetValue = 0;
$scope.isVerticalPager = $scope.align && ($scope.align == 'left' || $scope.align == 'right') ? true : false;
$scope.verticalHeight = parseFloat($scope.height);
$scope.defaultOptions = {
selectedIndex: 0,
noPagination: false,
centerTabs: false,
height: 0
};
// public functions
init();
function init() {
initOptionalProperties($scope, $attrs, $scope.defaultOptions);
compileTemplate();
configureWatchers();
bindEvents();
}
/**
* 编译data模板
*/
function compileTemplate() {
var template = $attrs.$fpmTabsTemplate,
element = angular.element(elements.data);
element.html(template);
$compile(element.contents())($scope.$parent);
delete $attrs.$fpmTabsTemplate;
}
function configureWatchers() {
$scope.$watch('selectedIndex', function(newValue, oldValue) {
if (newValue === oldValue) return;
$scope.selectedIndex = getNearestSafeIndex(newValue);
adjustOffset($scope.selectedIndex);
$scope.tabs[oldValue] && $scope.tabs[oldValue].scope.deselect();
$scope.tabs[newValue] && $scope.tabs[newValue].scope.select();
});
$scope.$watch('offsetValue', function(newValue, oldValue) {
if (newValue === oldValue) return;
if ($scope.isVerticalPager) {
angular.element(elements.paging).css('top', '-' + newValue + 'px');
} else {
angular.element(elements.paging).css('left', '-' + newValue + 'px');
}
});
$scope.$on('$destroy', function() {
angular.element($window).off('resize', handleWindowResize);
angular.element(elements.paging).off('DOMSubtreeModified', updatePagination);
});
}
function bindEvents() {
angular.element($window).on('resize', handleWindowResize);
// Fired when paging wrapper's child elements finish modified.
angular.element(elements.paging).on('DOMSubtreeModified', updatePagination);
}
function handleWindowResize() {
updatePagination();
}
function updatePagination() {
var canvasSize;
if ($scope.isVerticalPager) {
canvasSize = $element.prop('clientHeight');
angular.forEach(elements.tabs, function(tab) {
canvasSize -= tab.offsetHeight;
});
if (canvasSize < 0) {
var btnHeight = $element.find('fpm-prev-button')[0].clientHeight;
angular.element(elements.canvas).css({
height: $scope.verticalHeight - $element.find('fpm-prev-button')[0].clientHeight * 2 + 'px',
marginTop: btnHeight + 'px',
marginBottom: btnHeight + 'px'
});
} else {
angular.element(elements.canvas).css({
height: $scope.verticalHeight + 'px',
marginTop: 0,
marginBottom: 0
});
}
} else {
canvasSize = $element.prop('clientWidth');
angular.forEach(elements.tabs, function(tab) {
canvasSize -= tab.offsetWidth;
});
}
$scope.shouldPaginate = canvasSize < 0;
$timeout(function () {
adjustOffset($scope.selectedIndex);
});
}
//-- Tab control methods
function getElements() {
elements = {};
elements.wrapper = $element[0].getElementsByTagName('fpm-tabs-wrapper')[0];
elements.data = $element[0].getElementsByTagName('fpm-tab-data')[0];
elements.canvas = elements.wrapper.getElementsByTagName('fpm-tabs-canvas')[0];
elements.paging = elements.wrapper.getElementsByTagName('fpm-pagination-wrapper')[0];
elements.tabs = elements.paging.getElementsByTagName('fpm-tab-item');
return elements;
}
/**
* Insert a tab with a extend tab data.
* @param tabData {Object} the data of the tab that you want to insert.
* @param index {Number} Optional, the index of the tab you want to insert.
* @returns {Object} the whole tab data.
*/
$scope.insertTab = function(tabData, index) {
var proto = {
getIndex: function() { return $scope.tabs.indexOf(tab); },
isActive: function() { return this.getIndex() === $scope.selectedIndex; },
isLeft: function() { return this.getIndex() < $scope.selectedIndex; },
isRight: function() { return this.getIndex() > $scope.selectedIndex; }
},
tab = angular.extend(proto, tabData);
if (angular.isDefined(index)) {
$scope.tabs.splice(index, 0, tab);
} else {
$scope.tabs.push(tab);
}
return tab;
};
$scope.scroll = function(event) {
if (!$scope.shouldPaginate) return;
event.preventDefault();
$scope.offsetValue = fixOffset($scope.offsetValue - event.wheelDelta);
};
$scope.remove = function(tab) {
var selectedIndex = $scope.selectedIndex;
tab = $scope.tabs.splice(tab.getIndex(), 1)[0];
refreshIndex();
};
$scope.select = function(index) {
$scope.selectedIndex = index;
};
$scope.canPageBack = function() {
return $scope.offsetValue > 0;
};
$scope.canPageForward = function() {
var lastTab = elements.tabs[elements.tabs.length - 1];
if ($scope.isVerticalPager) {
return lastTab && lastTab.offsetTop + lastTab.offsetHeight > elements.canvas.clientHeight +
$scope.offsetValue;
}
return lastTab && lastTab.offsetLeft + lastTab.offsetWidth > elements.canvas.clientWidth +
$scope.offsetValue;
};
$scope.previousPage = function() {
var i, tab;
if ($scope.isVerticalPager) {
for (i = 0; i < elements.tabs.length; i++) {if (window.CP.shouldStopExecution(1)){break;}
tab = elements.tabs[i];
if (tab.offsetTop + tab.offsetHeight >= $scope.offsetValue) break;
}
window.CP.exitedLoop(1);
$scope.offsetValue = fixOffset(tab.offsetTop + tab.offsetHeight - elements.canvas.clientHeight);
} else {
for (i = 0; i < elements.tabs.length; i++) {if (window.CP.shouldStopExecution(2)){break;}
tab = elements.tabs[i];
if (tab.offsetLeft + tab.offsetWidth >= $scope.offsetValue) break;
}
window.CP.exitedLoop(2);
$scope.offsetValue = fixOffset(tab.offsetLeft + tab.offsetWidth - elements.canvas.clientWidth);
}
};
$scope.nextPage = function() {
var viewportValue = $scope.isVerticalPager ? elements.canvas.clientHeight : elements.canvas.clientWidth,
total = $scope.isVerticalPager ? viewportValue + $scope.offsetValue : viewportValue + $scope.offsetValue,
i, tab;
if ($scope.isVerticalPager) {
for (i = 0; i < elements.tabs.length; i++) {if (window.CP.shouldStopExecution(3)){break;}
tab = elements.tabs[i];
if (tab.offsetTop + tab.offsetHeight > total) break;
}
window.CP.exitedLoop(3);
$scope.offsetValue = fixOffset(tab.offsetTop);
} else {
for (i = 0; i < elements.tabs.length; i++) {if (window.CP.shouldStopExecution(4)){break;}
tab = elements.tabs[i];
if (tab.offsetLeft + tab.offsetWidth > total) break;
}
window.CP.exitedLoop(4);
$scope.offsetValue = fixOffset(tab.offsetLeft);
}
};
//-- Utilities Methods
/**
* Refresh selectedIndex
*/
function refreshIndex() {
$scope.selectedIndex = getNearestSafeIndex($scope.selectedIndex);
}
function getNearestSafeIndex(newIndex) {
var tabs = $scope.tabs,
maxOffset = Math.max(tabs.length - newIndex, newIndex),
i, tab;
for (i = 0; i <= maxOffset; i++) {if (window.CP.shouldStopExecution(5)){break;}
tab = tabs[newIndex + i];
if (tab && (tab.scope.disabled !== true)) {
return tab.getIndex();
}
tab = tabs[newIndex - i];
if (tab && (tab.scope.disabled !== true)) {
return tab.getIndex();
}
}
window.CP.exitedLoop(5);
return newIndex;
}
function fixOffset(value) {
if (!elements.tabs.length || !$scope.shouldPaginate) return 0;
var lastTab = elements.tabs[elements.tabs.length - 1], totalOffset;
if ($scope.isVerticalPager) {
totalOffset = lastTab.offsetTop + lastTab.offsetHeight - elements.canvas.clientHeight;
} else {
totalOffset = lastTab.offsetLeft + lastTab.offsetWidth - elements.canvas.clientWidth;
}
value = Math.max(0, value);
value = Math.min(totalOffset, value);
return value;
}
function adjustOffset(index) {
if (index == null) {
index = $scope.selectedIndex;
}
var tab = elements.tabs[index],
left = tab.offsetLeft,
top = tab.offsetTop,
right = tab.offsetWidth + left,
bottom = tab.offsetHeight + top;
if ($scope.isVerticalPager) {
$scope.offsetValue = Math.max($scope.offsetValue, fixOffset(bottom - elements.canvas.clientHeight));
$scope.offsetValue = Math.min($scope.offsetValue, fixOffset(top));
} else {
$scope.offsetValue = Math.max($scope.offsetValue, fixOffset(right - elements.canvas.clientWidth));
$scope.offsetValue = Math.min($scope.offsetValue, fixOffset(left));
}
}
}
FpmTabsController.$inject = ['$scope', '$element', '$attrs', '$compile', '$timeout', '$window'];
function FpmTabs() {
return {
scope: {
noPagination: '=?fpmNoPagination',
centerTabs: '=?fpmCenterTabs',
selectedIndex: '=?fpmSelected',
align: '@?fpmAlign',
height: '@?fpmHeight'
},
template: function(element, attr) {
var prevButton, nextButton, tabContent;
attr["$fpmTabsTemplate"] = element.html();
prevButton = getPrevButton();
nextButton = getNextButton();
tabContent = '\
<fpm-tab-content\
ng-repeat="(index, tab) in tabs"\
fpm-template="tab.template"\
fpm-scope="tab.parent"\
ng-class="{\
\'fpm-active\': tab.isActive(),\
\'fpm-left\': tab.isLeft(),\
\'fpm-right\': tab.isRight()\
}"\
ng-style="{ height: height || \'\' }">\
</fpm-tab-content>'.replace(/[\s]+/g, ' ');
return '\
<fpm-tabs-content-wrapper ng-if=\'align == "bottom" || align == "right"\'>' + tabContent + '</fpm-tabs-content-wrapper>\
<fpm-tabs-wrapper>\
<fpm-tab-data></fpm-tab-data>\
<fpm-prev-button\
ng-click="previousPage()"\
ng-show="shouldPaginate"\
ng-class="{ \'fpm-disabled\': !canPageBack() }">' + prevButton + '</fpm-prev-button>\
<fpm-next-button\
ng-click="nextPage()"\
ng-show="shouldPaginate"\
ng-class="{ \'fpm-disabled\': !canPageForward() }">' + nextButton + '</fpm-next-button>\
<fpm-tabs-canvas\
ng-class="{ \'fpm-paginated\': shouldPaginate }">\
<fpm-pagination-wrapper\
fpm-tab-scroll="scroll($event)">\
<fpm-tab-item\
class="fpm-tab"\
ng-repeat="tab in tabs"\
fpm-template="tab.label"\
fpm-scope="tab.parent"\
ng-click="select(tab.getIndex())"\
ng-disabled="tab.scope.disabled"\
ng-class="{ \'fpm-active\': tab.isActive() }"></fpm-tab-item>\
</fpm-pagination-wrapper>\
</fpm-tabs-canvas>\
</fpm-tabs-wrapper>\
<fpm-tabs-content-wrapper ng-if=\'!align || align=="top" || align=="left"\'>' + tabContent + '</fpm-tabs-content-wrapper>\
'.replace(/[\s]+/g, ' ');
function getPrevButton() {
var ele = element.find('fpm-prev-button').eq(0);
if (ele.length) {
return ele.remove().html();
}
return '<';
}
function getNextButton() {
var ele = element.find('fpm-next-button').eq(0);
if (ele.length) {
return ele.remove().html();
}
return '>'
}
},
controller: 'FpmTabsController',
controllerAs: '$fpmTabsCtrl'
}
}
function FpmTemplate($compile, $timeout) {
return {
restrict: 'A',
link: link,
scope: {
template: '=fpmTemplate',
compileScope: '=fpmScope',
connected: '=?fpmConnectedIf'
},
require: '^?fpmTabs'
};
function link(scope, element, attr, ctrl) {
if (!ctrl) return;
var compileScope = scope.compileScope.$new();
element.html(scope.template);
$compile(element.contents())(compileScope);
}
}
FpmTemplate.$inject = ['$compile', '$timeout'];
function FpmTabScroll($parse) {
return {
restrict: 'A',
compile: function ($element, attr) {
var fn = $parse(attr.fpmTabScroll, null, true);
return function ngEventHandler (scope, element) {
element.on('mousewheel', function (event) {
scope.$apply(function () { fn(scope, { $event: event }); });
});
};
}
}
}
FpmTabScroll.$inject = ['$parse'];
// -- Util Methods 以下是工具类
function initOptionalProperties(scope, attr, defaults) {
defaults = defaults || {};
angular.forEach(scope.$$isolateBindings, function (binding, key) {
if (binding.optional && angular.isUndefined(scope[key])) {
var hasKey = attr.hasOwnProperty(attr.$normalize(binding.attrName));
scope[key] = angular.isDefined(defaults[key]) ? defaults[key] : hasKey;
}
})
}
})(window, angular);
angular
.module('fpm:controllers')
.controller('TabsController', [
'$scope',
'$log',
'$timeout',
function($scope, $log, $timeout){
var tabs = [{
title: 'One',
content: 'Tabs will become paginated if there isn\'t enough room for them.'
}, {
title: 'Two',
content: 'You can swipe left and right on a mobile device to change tabs.'
}, {
title: 'Three',
content: 'You can bind the selected tab via the selected attribute on the md-tabs element.'
}, {
title: 'Four',
content: 'If you set the selected tab binding to -1, it will leave no tab selected.'
}, {
title: 'Five',
content: 'If you remove a tab, it will try to select a new one. If you remove a tab, it will try to select a new one.' +
'If you remove a tab, it will try to select a new one.If you remove a tab, it will try to select a new one.' +
'If you remove a tab, it will try to select a new one. If you remove a tab, it will try to select a new one.' +
'If you remove a tab, it will try to select a new one.If you remove a tab, it will try to select a new one.'
}, {
title: 'Six',
content: 'If you remove a tab, it will try to select a new one. If you remove a tab, it will try to select a new one.' +
'If you remove a tab, it will try to select a new one.If you remove a tab, it will try to select a new one.'
}, {
title: 'Seven',
content: 'If you remove a tab, it will try to select a new one. If you remove a tab, it will try to select a new one.' +
'If you remove a tab, it will try to select a new one.If you remove a tab, it will try to select a new one.' +
'If you remove a tab, it will try to select a new one. If you remove a tab, it will try to select a new one.'
}, {
title: 'Eight',
content: 'If you remove a tab, it will try to select a new one. If you remove a tab, it will try to select a new one.'
}, {
title: 'Nine',
content: 'If you remove a tab, it will try to select a new one. If you remove a tab, it will try to select a new one.' +
'If you remove a tab, it will try to select a new one.If you remove a tab, it will try to select a new one.' +
'If you remove a tab, it will try to select a new one. If you remove a tab, it will try to select a new one.' +
'If you remove a tab, it will try to select a new one.If you remove a tab, it will try to select a new one.'
}],
previous = null,
selected = null;
$scope.tabs = tabs;
$scope.selectedIndex = 2;
$scope.$watch('selectedIndex', function(current, old){
previous = selected;
selected = tabs[current];
//if ( old + 1 && (old != current)) $log.debug('Goodbye ' + previous.title + '!');
//if ( current + 1 ) $log.debug('Hello ' + selected.title + '!');
});
$scope.addTab = function(title, view) {
view = view || title + " Content View";
tabs.push({
title: title,
content: view,
disabled: false
})
};
$scope.removeTab = function(tab) {
var index = tabs.indexOf(tab);
tabs.splice(index, 1);
};
$scope.selectTab = function(index) {
};
$scope.changeContent = function () {
$scope.tabs[0].content = 'aaaa';
};
}
]);
angular
.module('fpm-demo', ['fpm:directives', 'fpm:controllers', 'fpm:services', 'fpm:filters', 'ngMaterial'])
.config(function($mdThemingProvider) {
$mdThemingProvider.theme('default')
.primaryPalette('light-blue')
.accentPalette('orange');
})
.constant('APIServiceConfig', { endpoint: '/api/' });
angular.bootstrap(document.body, ['fpm-demo']);
//# sourceURL=pen.js
</script>
</body></html>