"angular tab directive"
Bootstrap 3.0.0 Snippet by evarevirus

<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>

Related: See More


Questions / Comments: