我有以下代码段.在移动屏幕较小的情况下,它无法一次显示所有7个标签.因此,它将显示为两行选项卡,这些选项卡不够整洁.
我想要的选项卡,当滚动页面到右边或左边的末尾时,它可以处理溢出,以便用户会注意到那里有标签.
例如java中的android为scroollable tabs.但是,我需要它在离子1中.让我们说移动屏幕能够显示7个标签中的3个标签.当我向右滚动选项卡(第3个选项卡)时,第4个选项卡将显示在右侧,第3个选项卡现在将位于中间选项卡上,而第3个选项卡将显示在右侧.
angular.module('ionicApp',['ionic']) .controller('MyCtrl',function($scope,$ionicSlideBoxDelegate) { $scope.slideIndex = 0; // Called each time the slide changes $scope.slideChanged = function(index) { $scope.slideIndex = index; }; $scope.activeSlide = function (index) { $ionicSlideBoxDelegate.slide(index); }; });
body { cursor: url('https://ionicframework.com/img/finger.png'),auto; } .slide-tab{ display: table; overflow: hidden; margin: 0; width: 100%; background-color: #eff0f2; border-bottom: 2px solid #00897B; } .slide-tab li{ float: left; line-height: 38px; overflow: hidden; padding: 0; } .slide-tab a{ background-color: #eff0f2; border-bottom: 1px solid #fff; color: #888; font-weight: 500; display: block; letter-spacing: 0; outline: none; padding: 0 20px; text-decoration: none; -webkit-transition: all 0.2s ease-in-out; -moz-transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out; border-bottom: 2px solid #00897B; } .current a{ color: #fff; background: #00897B; }
<html ng-app="ionicApp"> <head> <Meta charset="utf-8"> <Meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width"> <title>Ionic Slide Tab</title> <link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet"> <script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script> </head> <body ng-controller="MyCtrl"> <ion-header-bar class="bar-positive"> <h1 class="title">Ionic Slide Tab</h1> </ion-header-bar> <ion-content> <div class="row"> <ul class="slide-tab"> <li ng-class="slideIndex == 0 ? 'current':''"><a href="#" ng-click="activeSlide(0)">Tab01</a></li> <li ng-class="slideIndex == 1 ? 'current':''"><a href="#" ng-click="activeSlide(1)">Tab02</a></li> <li ng-class="slideIndex == 2 ? 'current':''"><a href="#" ng-click="activeSlide(2)">Tab03</a></li> <li ng-class="slideIndex == 3 ? 'current':''"><a href="#" ng-click="activeSlide(3)">Tab04</a> </li> <li ng-class="slideIndex == 4 ? 'current':''"><a href="#" ng-click="activeSlide(4)">Tab05</a></li> <li ng-class="slideIndex == 5 ? 'current':''"><a href="#" ng-click="activeSlide(5)">Tab06</a></li> <li ng-class="slideIndex == 6 ? 'current':''"><a href="#" ng-click="activeSlide(6)">Tab07</a></li> </ul> </div> <ion-slide-Box on-slide-changed="slideChanged(index)" active-slide="slideIndex" class="padding"> <ion-slide> <h3>Tab 1</h3> <p>Page 1</p> </ion-slide> <ion-slide> <h3>Tab 2</h3> <p>Page 2</p> </ion-slide> <ion-slide> <h3>Tab 3</h3> <p>Page 3</p> </ion-slide> <ion-slide> <h3>Tab 4</h3> <p>page 4</p> </ion-slide> <ion-slide> <h3>Tab 5</h3> <p>page 5</p> </ion-slide> <ion-slide> <h3>Tab 6</h3> <p>page 6</p> </ion-slide> <ion-slide> <h3>Tab 7</h3> <p>page 7</p> </ion-slide> </ion-slide-Box> </ion-content> </body> </html>
解决方法
尝试这个例子我认为它会帮助你..
slidingTabs.html
<html> <head> <Meta charset="utf-8" /> <Meta name="format-detection" content="telephone=no" /> <Meta name="viewport" content="initial-scale=1,width=device-width"> <title>Tabbed Slide Box</title> <!-- ionic css --> <link href="http://code.ionicframework.com/1.0.0-rc.4/css/ionic.css" rel="stylesheet"> <!-- your app's css --> <link href="tabSlideBox.css" rel="stylesheet"> <!-- ionic/angularjs scripts --> <script src="http://code.ionicframework.com/1.0.0-rc.4/js/ionic.bundle.min.js"></script> <script src="tabSlideBox.js"></script> <!-- your app's script --> <script> var app = angular.module('slideBox',['ionic','tabSlideBox']) .run(['$q','$http','$rootScope','$location','$window','$timeout',function($q,$http,$rootScope,$location,$window,$timeout){ $rootScope.$on("$locationChangeStart",function(event,next,current){ $rootScope.error = null; console.log("Route change!!!",$location.path()); var path = $location.path(); console.log("App Loaded!!!"); }); } ]); app.config(function($stateProvider,$urlRouterProvider) { $stateProvider.state('index',{ url : '/',templateUrl : 'index.html',controller : 'IndexCtrl' }); $urlRouterProvider.otherwise("/"); }); app.controller("IndexCtrl",['$rootScope',"$scope","$stateParams","$q","$location","$window",function($rootScope,$scope,$stateParams,$q,$timeout){ $scope.onSlideMove = function(data){ alert("You have selected " + data.index + " tab"); }; } ]); </script> <style> .slider-slide h3{ color:#fff; margin-top:10px; } .scroll{ height:100%; } .tabbed-slideBox .tsb-icons:after{ display:none; } </style> </head> <body ng-app="slideBox" animation="slide-left-right-ios7"> <ion-nav-bar class="nav-title-slide-ios7 bar-positive"> <ion-nav-back-button class="button-icon ion-arrow-left-c"> </ion-nav-back-button> </ion-nav-bar> <ion-nav-view ng-controller="IndexCtrl"></ion-nav-view> <script id="index.html" type="text/ng-template"> <ion-view title="Scrollable Tabbed Slide Box"> <ion-content scroll="false"> <tab-slide-Box> <div class="tsb-icons"> <div class="tsb-ic-wrp"> <ion-scroll direction="x" class="tsb-hscroll"> <a href="javascript:;" class="ion-home1">Home</a> <a href="javascript:;" class="ion-ios-game-controller-b1">Games</a> <a href="javascript:;" class="ion-email1">Email</a> <a href="javascript:;" class="ion-model-s1">Car</a> <a href="javascript:;" class="ion-person1">Profile</a> <a href="javascript:;" class="ion-heart1">Favourites</a> <a href="javascript:;" class="ion-chatbubbles1">Chats</a> <a href="javascript:;" class="ion-gear-b1">Settings</a> <a href="javascript:;" class="ion-camera1">Photos</a> <a href="javascript:;" class="ion-ios-paw1">Pets</a> </ion-scroll> </div> </div> <ion-slide-Box show-pager="false" on-slide-changed="slideHasChanged($index)"> <ion-slide> <h3>Home content</h3> </ion-slide> <ion-slide> <h3>Games content</h3> </ion-slide> <ion-slide> <h3>Mail content</h3> </ion-slide> <ion-slide> <h3>Car content</h3> </ion-slide> <ion-slide> <h3>Profile content</h3> </ion-slide> <ion-slide> <h3>Favourites content</h3> </ion-slide> <ion-slide> <h3>Chats content</h3> </ion-slide> <ion-slide> <h3>Settings content</h3> </ion-slide> <ion-slide> <h3>Photos content</h3> </ion-slide> <ion-slide> <h3>Pets content</h3> </ion-slide> </ion-slide-Box> </tab-slide-Box> </ion-content> </ion-view> </script> </body> </html>
tabSlideBox.css
.tabbed-slideBox .slider { height: 100%; } .tabbed-slideBox.btm .slider { margin-bottom: -50px; } .tabbed-slideBox .slider-slides { width: 100%; } .tabbed-slideBox .slider-slide { padding-top: 0px; color: #000; background-color: #fff; text-align: center; font-weight: 300; background-color: #0398dc; } .tabbed-slideBox .tsb-icons { text-align: center; margin: 10px 0; position: relative; background-color:#fff; } .tabbed-slideBox .tsb-ic-wrp { display: flex; position: relative; -webkit-transition: -webkit-transform 0.3s; /* For Safari 3.1 to 6.0 */ -webkit-transform:translate3d(0,0); } .tabbed-slideBox .tsb-icons a { display: inline-block; width: 54px; font-size: 2.5em; color: rgba(0,0.3); -webkit-transform:translate3d(0,8px,0); } .tabbed-slideBox .tsb-icons a.active { color: rgba(0,1); font-size: 3.5em; -webkit-transform:translate3d(0,0); } .tabbed-slideBox .tabbed-slideBox { position: relative; height: 100%; overflow: hidden; } .tabbed-slideBox .tsb-icons:after { width: 0; height: 0; border-style: solid; border-width: 0 1.4em 1.4em 1.4em; border-color: transparent transparent #0398dc transparent; position: absolute; content: ""; display: block; bottom: -12px; left: 50%; margin-left: -14px; } .tsb-hscroll.scroll-view{ white-space: nowrap; margin:0 auto; } .tsb-hscroll.scroll-view .scroll-bar{ visibility:hidden; } .tsb-hscroll.scroll-view .scroll.onscroll{ -webkit-transition: -webkit-transform 0.3s; /* For Safari 3.1 to 6.0 */ } .tabbed-slideBox .tsb-icons .scroll a{ width:auto; font-size: 1.5em; line-height: 1.5em; text-decoration: none; margin: 0 15px; border-bottom: 3px solid transparent; } .tabbed-slideBox .tsb-icons .scroll a.active { font-size: 1.8em; border-bottom: 3px solid #ccc; }
tabSlideBox.js
'use strict'; function SimplePubSub() { var events = {}; return { on: function(names,handler) { names.split(' ').forEach(function(name) { if (!events[name]) { events[name] = []; } events[name].push(handler); }); return this; },trigger: function(name,args) { angular.forEach(events[name],function(handler) { handler.call(null,args); }); return this; } }; }; angular.module('tabSlideBox',[]) .directive('onFinishRender',function ($timeout) { return { restrict: 'A',link: function (scope,element,attr) { if (scope.$last === true) { $timeout(function () { scope.$emit('ngRepeatFinished'); }); } } } }) .directive('tabSlideBox',[ '$timeout','$ionicSlideBoxDelegate','$ionicScrollDelegate',function($timeout,$ionicSlideBoxDelegate,$ionicScrollDelegate) { 'use strict'; return { restrict : 'A,E,C',link : function(scope,attrs,ngModel) { var ta = element[0],$ta = element; $ta.addClass("tabbed-slideBox"); if(attrs.tabsPosition === "bottom"){ $ta.addClass("btm"); } //Handle multiple slide/scroll Boxes var handle = ta.querySelector('.slider').getAttribute('delegate-handle'); var ionicSlideBoxDelegate = $ionicSlideBoxDelegate; if(handle){ ionicSlideBoxDelegate = ionicSlideBoxDelegate.$getByHandle(handle); } var ionicScrollDelegate = $ionicScrollDelegate; if(handle){ ionicScrollDelegate = ionicScrollDelegate.$getByHandle(handle); } function renderScrollableTabs(){ var iconsDiv = angular.element(ta.querySelector(".tsb-icons")),icons = iconsDiv.find("a"),wrap = iconsDiv[0].querySelector(".tsb-ic-wrp"),totalTabs = icons.length; var scrollDiv = wrap.querySelector(".scroll"); angular.forEach(icons,function(value,key){ var a = angular.element(value); a.on('click',function(){ ionicSlideBoxDelegate.slide(key); }); if(a.attr('icon-off')) { a.attr("class",a.attr('icon-off')); } }); var initialIndex = attrs.tab; //Initializing the middle tab if(typeof attrs.tab === 'undefined' || (totalTabs <= initialIndex) || initialIndex < 0){ initialIndex = Math.floor(icons.length/2); } //If initial element is 0,set position of the tab to 0th tab if(initialIndex == 0){ setPosition(0); } $timeout(function() { ionicSlideBoxDelegate.slide(initialIndex); },0); } function setPosition(index){ var iconsDiv = angular.element(ta.querySelector(".tsb-icons")),totalTabs = icons.length; var scrollDiv = wrap.querySelector(".scroll"); var middle = iconsDiv[0].offsetWidth/2; var curEl = angular.element(icons[index]); var prvEl = angular.element(iconsDiv[0].querySelector(".active")); if(curEl && curEl.length){ var curElWidth = curEl[0].offsetWidth,curElLeft = curEl[0].offsetLeft; if(prvEl.attr('icon-off')) { prvEl.attr("class",prvEl.attr('icon-off')); }else{ prvEl.removeClass("active"); } if(curEl.attr('icon-on')) { curEl.attr("class",curEl.attr('icon-on')); } curEl.addClass("active"); var leftStr = (middle - (curElLeft) - curElWidth/2 + 5); //If tabs are not scrollable if(!scrollDiv){ var leftStr = (middle - (curElLeft) - curElWidth/2 + 5) + "px"; wrap.style.webkitTransform = "translate3d("+leftStr+",0)" ; }else{ //If scrollable tabs var wrapWidth = wrap.offsetWidth; var currentX = Math.abs(getX(scrollDiv.style.webkitTransform)); var leftOffset = 100; var elementOffset = 40; //If tabs are reaching right end or left end if(((currentX + wrapWidth) < (curElLeft + curElWidth + elementOffset)) || (currentX > (curElLeft - leftOffset))){ if(leftStr > 0){ leftStr = 0; } //Use this scrollTo,so when scrolling tab manually will not flicker ionicScrollDelegate.scrollTo(Math.abs(leftStr),true); } } } }; function getX(matrix) { matrix = matrix.replace("translate3d(",""); matrix = matrix.replace("translate(",""); return (parseInt(matrix)); } var events = scope.events; events.on('slideChange',function(data){ setPosition(data.index); }); events.on('ngRepeatFinished',function(ngRepeatFinishedEvent) { renderScrollableTabs(); }); renderScrollableTabs(); },controller : function($scope,$attrs,$element) { $scope.events = new SimplePubSub(); $scope.slideHasChanged = function(index){ $scope.events.trigger("slideChange",{"index" : index}); $timeout(function(){if($scope.onSlideMove) $scope.onSlideMove({"index" : eval(index)});},100); }; $scope.$on('ngRepeatFinished',function(ngRepeatFinishedEvent) { $scope.events.trigger("ngRepeatFinished",{"event" : ngRepeatFinishedEvent}); }); } }; } ]);
另请查看此示例link以获得更多想法
工作plunker