JS組件系列——基於Bootstrap Ace模板的菜單Tab頁效果優化

前言:以前發表過一篇  JS組件系列——基於Bootstrap Ace模板的菜單和Tab頁效果分享(你值得擁有) ,收到不少園友的反饋,固然也包括不少詬病,由於上篇只是將功能實現了,不少細節都沒有處理,這篇博主將帶領你們一塊兒來優化這裏的效果,使之成爲一個能夠在項目裏面使用的成品。javascript

說點題外話,原本,在互聯網模式下,Tab頁+iframe的組合是不能被大多數平臺接受的,從這些年推出的一些好的產品能夠看出,幾乎你們都不這麼玩,即便是一些後臺的管理模板,好比常見的AdminLTE、Ace、INSPINIA+等也都擯棄了iframe,由於iframe的壞處博主均可以說出一千條。可爲何這裏博主還要寫這篇文章?用一句老套的話說:需求產生市場!在一些傳統的企業,系統的使用人員的使用習慣還停留在10年前,他們但願頁面上面展現的東西越多越好,而且但願頁面切換方便,他們喜歡tab頁+iframe的效果,無論你信不信,這點確實是客觀存在的!就拿博主所在的公司來講,要不要tab+iframe基本上持兩種意見,一半一半,但是客戶更加傾向使用iframe的這種操做習慣,你有何解!前段時間用Abp作了一個Erp的項目,原本Abp原始的頁面就是沒有iframe的,上線以後客戶以爲這種操做很不方便,最後硬生生的把Abp的界面改頭換面。究其緣由,在互聯網+時代,你們都在大力推各類不使用iframe的效果,但願改變人們的思惟模式和操做方式,但這個改變並不能一蹴而就,還須要一些時間。好了,廢話到此爲止,進入正題!css

本文原創地址:http://www.cnblogs.com/landeanfen/p/7601880.htmlhtml

系列文章java

1、效果展現

原始效果bootstrap

解決iframe高度自適應問題瀏覽器

增長上邊框session

美化刪除圖標app

標籤頁上面顯示菜單圖標dom

標籤增長邊框ide

方角邊框

標籤顏色搭配

標籤過多時左右移動

菜單選中效果

菜單獨立滾動條

2、代碼示例

一、解決高度自適應的問題

這個並不屬於Tab頁的優化範疇,而是常常有羣友討論這個高度不能跟着頁面的內容自適應,博主花了點時間作的優化而已,主要的思路就是動態計算頁面內容的高度,而後給iframe的高度賦值。

首先在bootstrap-tab.js裏面定義一個方法去作高度計算和賦值

var changeFrameHeight = function (that) {
    $(that).height(document.documentElement.clientHeight - 115);
    $(that).parent(".tab-pane").height(document.documentElement.clientHeight - 130);
}

而後建立iframe的時候調用這個方法

content = '<div role="tabpanel" class="tab-pane" id="' + id + '"><iframe id="iframe_'+id+'" src="' + options.url + 
                '" width="100%" height="100%" onload="changeFrameHeight(this)" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling="yes" allowtransparency="yes"></iframe></div>';

爲了在瀏覽器的寬高變化時頁面的寬高也跟着變化,還須要註冊頁面的onresize事件

    window.onresize = function () {
        var target = $(".tab-content .active iframe");
        changeFrameHeight(target);
    }

這三個地方都在bootstrap-tab.js裏面更改便可。

改完以後來看看測試效果:

二、新建文件bootstrap-tab.css,調整高度和上邊框

其實美化boostrap的tab頁面原始效果並不難,我看到羣友都本身改造了,難度不大,這裏博主就給出改造思路,供你們參考。

新建文件,而後在index.html頁面引用該樣式文件

    <link href="Content/bootstrap/css/bootstrap-tab.css" rel="stylesheet"/>

 咱們增長兩個樣式

.nav-tabs li a{
    line-height:2
}
.nav-tabs .active a{
    border-top: solid 2px #3498db !important;
}

查看效果

是否是看上去趕忙好好看一些~~

三、美化刪除圖標

上圖中標籤頁加上上邊框以後看上去要好看一些了,但是還不夠美觀,看來看去總以爲哪一個關閉的小圖標怪怪的,咱們來美化一下。好比咱們在boostrap-tab.js裏面將關閉按鈕換成帶圓形邊框的

將圖標i標籤的的class由原來的 glyphicon glyphicon-remove 換成 glyphicon glyphicon-remove-sign 便可,咱們來看看效果:

爲了更加符合使用習慣,咱們增長一個鼠標移動到圖標上面顯示紅色的效果,咱們在boostrap-tab.css裏面增長以下樣式:

.nav-tabs li a .glyphicon-remove-sign:hover{
  color:red;
  cursor: pointer;
}

效果以下

四、標籤頁帶圖標

標籤頁裏面僅僅顯示文字和關閉的圖標給人感受太空洞,咱們增長頁面的圖標。首先首頁的標籤頁咱們增長一個home圖標,在index.html增長以下i標籤:

而後其餘每個動態打開的tab頁前面的圖標就是對應的點擊左邊菜單對應的圖標。首先咱們在初始化菜單的那個作以下更改,在sidebar-menu.js文件改爲這樣

(function ($) {
    $.fn.sidebarMenu = function (options) {
        options = $.extend({}, $.fn.sidebarMenu.defaults, options || {});
        var target = $(this);
        target.addClass('nav');
        target.addClass('nav-list');
        if (options.data) {
            init(target, options.data);
        }
        else {
            if (!options.url) return;
            $.getJSON(options.url, options.param, function (data) {
                init(target, data);
            });
        }
        var url = window.location.pathname;
        //menu = target.find("[href='" + url + "']");
        //menu.parent().addClass('active');
        //menu.parent().parentsUntil('.nav-list', 'li').addClass('active').addClass('open');
        function init(target, data) {
            $.each(data, function (i, item) {
                var li = $('<li></li>');
                var a = $('<a></a>');
                var icon = $('<i></i>');
                //icon.addClass('glyphicon');
                icon.addClass(item.icon);
                var text = $('<span></span>');
                text.addClass('menu-text').text(item.text);
                a.append(icon);
                a.append(text);
                if (item.menus&&item.menus.length>0) {
                    a.attr('href', '#');
                    a.addClass('dropdown-toggle');
                    var arrow = $('<b></b>');
                    arrow.addClass('arrow').addClass('icon-angle-down');
                    a.append(arrow);
                    li.append(a);
                    var menus = $('<ul></ul>');
                    menus.addClass('submenu');
                    init(menus, item.menus);
                    li.append(menus);
                }
                else {
                    var href = 'javascript:addTabs({id:\'' + item.id + '\',title: \'' + item.text + '\',close: true,url: \'' + item.url + '\',icon:\''+ item.icon +'\'});';
                    a.attr('href', href);
                    //if (item.istab)
                    //    a.attr('href', href);
                    //else {
                    //    a.attr('href', item.url);
                    //    a.attr('title', item.text);
                    //    a.attr('target', '_blank')
                    //}
                    li.append(a);
                }
                target.append(li);
            });
        }
    }

    $.fn.sidebarMenu.defaults = {
        url: null,
        param: null,
        data: null
    };
})(jQuery);
sidebar-menu.js

其中有一句

var href = 'javascript:addTabs({id:\'' + item.id + '\',title: \'' + item.text + '\',close: true,url: \'' + item.url + '\',icon:\''+ item.icon +'\'});';

這裏將當前菜單的圖標傳到addTabs()方法裏面,而後在addTabs()方法裏面接收這個參數。

var addTabs = function (options) {
    //能夠在此處驗證session
    //var rand = Math.random().toString();
    //var id = rand.substring(rand.indexOf('.') + 1);
    debugger;
    var url = window.location.protocol + '//' + window.location.host;
    options.url = url + options.url;
    id = "tab_" + options.id;
    var active_flag = false;
    if($("#" + id)){
        active_flag = $("#" + id).hasClass('active');
    }
    $(".active").removeClass("active");
    //若是TAB不存在,建立一個新的TAB
    if (!$("#" + id)[0]) {
        //固定TAB中IFRAME高度
        mainHeight = $(document.body).height();
        //建立新TAB的title
        title = '<li role="presentation" id="tab_' + id + '"><a href="#' + id + '" aria-controls="' + id + '" role="tab" data-toggle="tab"><i class="'+options.icon+'"></i>' + options.title;
        //是否容許關閉
        if (options.close) {
            title += ' <i class="glyphicon glyphicon-remove-sign" tabclose="' + id + '"></i>';
        }
        title += '</a></li>';
        //是否指定TAB內容
        if (options.content) {
            content = '<div role="tabpanel" class="tab-pane" id="' + id + '">' + options.content + '</div>';
        } else {//沒有內容,使用IFRAME打開連接
            content = '<div role="tabpanel" class="tab-pane" id="' + id + '"><iframe id="iframe_'+id+'" src="' + options.url + 
                '" width="100%" height="100%" onload="changeFrameHeight(this)" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling="yes" allowtransparency="yes"></iframe></div>';
        }
        //加入TABS
        $(".nav-tabs").append(title);
        $(".tab-content").append(content);
    }else{
        if(active_flag){
            $("#iframe_" + id).attr('src', $("#iframe_" + id).attr('src'));
        }
    }
    //激活TAB
    $("#tab_" + id).addClass('active');
    $("#" + id).addClass("active");
};
var changeFrameHeight = function (that) {
    $(that).height(document.documentElement.clientHeight - 115);
    $(that).parent(".tab-pane").height(document.documentElement.clientHeight - 130);
}
var closeTab = function (id) {
    //若是關閉的是當前激活的TAB,激活他的前一個TAB
    if ($("li.active").attr('id') == "tab_" + id) {
        $("#tab_" + id).prev().addClass('active');
        $("#" + id).prev().addClass('active');
    }
    //關閉TAB
    $("#tab_" + id).remove();
    $("#" + id).remove();
};
$(function () {
    $("[addtabs]").click(function () {
        addTabs({ id: $(this).attr("id"), title: $(this).attr('title'), close: true });
    });

    $(".nav-tabs").on("click", "[tabclose]", function (e) {
        id = $(this).attr("tabclose");
        closeTab(id);
    });

    window.onresize = function () {
        var target = $(".tab-content .active iframe");
        changeFrameHeight(target);
    }
});
bootstrap-tab.js

其中有一句

title = '<li role="presentation" id="tab_' + id + '"><a href="#' + id + '" aria-controls="' + id + '" role="tab" data-toggle="tab"><i class="'+options.icon+'"></i>' + options.title;

而後寫一個樣式調整標籤頁圖標和標題的距離,咱們在bootstrap-tab.css裏面增長以下樣式:

.nav-tabs li a i:first-child{
    margin-right: 3px;
}

最終獲得效果以下:

固然,有可能你以爲加上這個以後tab頁顯得很擁擠,你也能夠不加,根據本身的喜愛來進行美化 

五、標籤頁增長邊框

通過上面三步驟的美化,咱們的標籤頁已經好看了許多。若是你對界面要求不高,其實也夠了,可是博主以爲還能夠繼續美化呢~

好比咱們給標籤也增長一個邊框,使每個標籤頁看上去更加像一個獨立的總體。咱們調整.nav-tabs li a這個樣式爲

.nav-tabs li a{
    line-height:2;
    border:1px #ddd solid;
    margin-right: -1px;
    color: #999;
}

而後增長

.nav-tabs{
    background: #fafafa;
}

這樣看到的效果:

固然,有人喜歡將邊框的圓角去掉,你也能夠在.nav-tabs li a裏面增長 border-radius:0; 獲得的效果

博主以爲使用圓角也不錯啊,反正這個取決於我的喜愛!

六、標籤頁顏色搭配

以上效果基本夠用,在項目裏面使用起來沒有太大的問題,但博主還想將其優化下。好比咱們作以下樣式調整:

.nav-tabs{
    background: #fafafa;
    border-bottom: 3px #3498db solid;
}

.nav-tabs li a{
    line-height:2;
    border:1px #ddd solid;
    margin-right: -1px;
    color: #999;
    border-radius: 0;
}
.nav-tabs li a .glyphicon-remove-sign:hover{
    color:red;
    cursor: pointer;
}
.nav-tabs li a i:first-child{
    margin-right: 3px;
}
.nav-tabs .active a{
    border-top: solid 2px #3498db !important;
    background: #3498db !important;
    color:#fff !important;
}
bootstrap-tab.css

可能這裏的顏色搭配並不協調,但至少看上去更加perfect一點吧。

 七、標籤頁寬度超限處理

到上面爲止Tab頁的樣式已經能夠了,但是還有一個最大的問題沒有解決,就是當全部tab頁的寬度的和超過瀏覽器的寬度限制時,就會出現tab的換行,看上去很是「噁心」。不信你多打開一些tab頁試試。這裏博主花了兩天時間寫了一套可行的樣式方案,來一睹風采吧:

 

 實現思路其實不難,主要就是界面樣式的調整確實很是話時間。下面來看一看實現步驟

首先界面上面在標籤頁的兩邊增長向左移、向右移的圖標

                <ul class="nav-my-tab">
                                <li class="leftbackward"><a href="#" >
                                    <i class="icon-backward"></i></a>
                                </li>
                                <li class="middletab">
                                    <ul class="nav nav-tabs" role="tablist">
                                        <li class="active"><a href="#Index" role="tab" data-toggle="tab">
                                            <i class="icon-home"></i>系統首頁</a>
                                        </li>
                                    </ul>
                                </li>
                                <li class="rightforward"><a href="#">
                                        <i class="icon-forward"></i></a>
                                 </li>
                            </ul>

而後就是這兩個圖標以及中間tab頁的樣式

.nav-my-tab{
    padding-left: 0px;
    margin-bottom: 0px;
}
.nav-my-tab .middletab{
    height: 36px;
    overflow: hidden;
    border-bottom: 3px #3498db solid;
    position: relative;
    background: #fafafa;
}
.nav-my-tab li{
    list-style-type: none;
}
.nav-my-tab li a{
    padding:5px 10px;
}
.nav-my-tab .leftbackward{
    float: left;
    background: #fff;
    padding-top: 7px;
    border-top: 1px #ddd solid;
    height:36px;
    border-bottom: 3px #3498db solid;
}
.nav-my-tab .leftbackward a{
    border-left-width: 0px;
    color: #999;
    padding-top: 9px;
    padding-bottom: 8px;
    margin-right: -1px;
}
.nav-my-tab .leftbackward a:hover,.nav-my-tab .leftbackward a:focus{
    text-decoration: none;
    background: #ddd;
}

.nav-my-tab .rightforward{
    float:right;
    position: relative;
    line-height: 2.6;
    background: #fff;
    border-top: 1px #ddd solid;
    border-bottom: 3px #3498db solid;
    
}
.nav-my-tab .rightforward a{
    width: 35.5px;
    line-height: 2;
    color: #999;
    height: 35px;
    padding: 8px 10px;
    padding-left: 13px;
    border-left: 1px #ddd solid;
}
.nav-my-tab .rightforward a:hover,.nav-my-tab .rightforward a:focus{
    text-decoration: none;
    background: #ddd;
}

最後就是左移、右移的按鈕事件

$(function () {
    $("[addtabs]").click(function () {
        addTabs({ id: $(this).attr("id"), title: $(this).attr('title'), close: true });
    });

    $(".nav-tabs").on("click", "[tabclose]", function (e) {
        id = $(this).attr("tabclose");
        closeTab(id);
    });

    $('.nav-my-tab .middletab').width($('.nav-my-tab .middletab').width()-37);
    //固定左邊菜單的高度
    $('#sidebar').height($(window).height() - 80);
    window.onresize = function () {
        var target = $(".tab-content .active iframe");
        changeFrameHeight(target);
    }

    //tab頁向左向右移動
    $('.nav-my-tab .leftbackward').click(function(){
        var strLeft=$('.nav-my-tab .middletab .nav-tabs').css('left');
        var iLeft = parseInt(strLeft.replace('px', ''));
        if(iLeft>=0){
            return;
        }
        else{
            debugger;
            var totalWidth=0;
            var lis = $(".nav-tabs li");
            for(var i=0;i<lis.length;i++){
                var item = lis[i];
                totalWidth-= $(item).width();
                if(iLeft>totalWidth){
                    iLeft+=$(item).width();
                    break;
                }
            };
            if(iLeft>0){
                iLeft=0;
            }
            $(".nav-my-tab .middletab .nav-tabs").animate({left:iLeft + 'px'});
        }
    });
    $('.nav-my-tab .rightforward').click(function(){
            var strLeft=$('.nav-my-tab .middletab .nav-tabs').css('left');
            var iLeft = parseInt(strLeft.replace('px', ''));
            var totalWidth=0;
            $.each($(".nav-tabs li"),function(key, item){
                   totalWidth+= $(item).width();
            });
            var tabsWidth = $(".nav-my-tab .middletab").width();
            if(totalWidth>tabsWidth){
                debugger;
                if(totalWidth-tabsWidth<=Math.abs(iLeft)){
                    return;
                }
                var lis = $(".nav-tabs li");
                totalWidth=0;
                for(var i=0;i<lis.length;i++){
                    var item = lis[i];
                    totalWidth-= $(item).width();
                    if(iLeft>totalWidth){
                        iLeft-=$(item).width();
                        break;
                    }
                };
                $(".nav-my-tab .middletab .nav-tabs").animate({left:iLeft + 'px'});
            }            
        });
});

主要原理就是經過計算全部tab頁的寬度的和已經ul當前的左移量來判斷是否須要移動,以及每次移動多少。這裏的移動是經過css樣式的left屬性去控制的。若是你理解了這個原理,其實實現起來並不算太複雜,關鍵的問題仍是頁面的樣式和js的配置使用。

八、左邊菜單的選中效果和固定高度效果

 這部分其實不屬於Tab頁的優化範疇,但既然要把這個作好,順帶也把這個優化了下。

首先在sidebar-menu.js裏面增長以下id

而後在addTabs()方法的最下面加這兩句便可

    //激活左邊菜單
    $('#menu li').removeClass('active');
    $('#li_'+options.id).addClass('active');

獲得效果

還有一個就是左邊菜單的滾動條,當左邊菜單的數量多了之後,每次展開都會致使整個頁面出現滾動條,界面很是不友好,博主打算給左邊菜單部分單獨加上滾動條,用來控制菜單的滾動。

增長以下樣式

#sidebar{
    overflow-x: hidden;
    overflow-y: auto;
}

這裏的sidebar是左邊菜單的div容器。

而後在頁面初始化完成的時候給這個div固定一個動態高度。

$(function () {
    //固定左邊菜單的高度
    $('#sidebar').height($(window).height() - 80);
});

效果以下

3、總結

源碼下載地址:https://pan.baidu.com/s/1knn42rY34YgQCm3Ax2d1Yw   提取碼:rjuz

本文原創出處:http://www.cnblogs.com/landeanfen/

歡迎各位轉載,可是未經做者本人贊成,轉載文章以後必須在文章頁面明顯位置給出做者和原文鏈接,不然保留追究法律責任的權利

PS:感謝給位園友的支持和厚愛,源碼已經貼出來了,有須要的能夠自行下載。歡迎關注!

相關文章
相關標籤/搜索