可正确处理溢出的可滚动选项卡



我有如下代码片段。在较小的移动屏幕上,它将无法一次显示所有7个选项卡。因此,它将显示为两行不整洁的选项卡。

我希望当将页面滚动到右侧或左侧的末尾时,它可以处理溢出的选项卡,以便用户会注意到那里有选项卡。

示例是 java 中 android 的 scroollable 选项卡。但是,我在离子 1 中需要它。让我们说手机中的屏幕能够显示 3 个选项卡中的 7 个选项卡。当我向右滚动选项卡(第三个选项卡(时,第 4 个选项卡将显示在右侧,第三个选项卡现在将位于中间选项卡上,而第二个选项卡将在右侧。

请在片段中显示代码,以便我们可以直观地知道它正在工作。

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, maximum-scale=1, user-scalable=no, 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", '$timeout', 
            function($rootScope, $scope, $stateParams, $q, $location, $window, $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,0);
}
.tabbed-slidebox .tsb-icons a {
    display: inline-block;
    width: 54px;
    font-size: 2.5em;
    color: rgba(0, 0, 0, 0.3);
    -webkit-transform:translate3d(0,8px,0);
}
.tabbed-slidebox .tsb-icons a.active {
    color: rgba(0, 0, 0, 1);
    font-size: 3.5em;
    -webkit-transform:translate3d(0,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', '$window', '$ionicSlideBoxDelegate', '$ionicScrollDelegate',
    function($timeout, $window, $ionicSlideBoxDelegate, $ionicScrollDelegate) {
        'use strict';
        return {
            restrict : 'A, E, C',
            link : function(scope, element, 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")), icons = iconsDiv.find("a"), wrap = iconsDiv[0].querySelector(".tsb-ic-wrp"), 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,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), 0, 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});
                });
            }
        };
    } 
]);

另请查看此示例链接以获取更多想法

工作压倒器

最新更新