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

我有以下代码段.在移动屏幕较小的情况下,它无法一次显示所有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

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...