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:感谢给位园友的支持和厚爱,源码已经贴出来了,有须要的能够自行下载。欢迎关注!

相关文章
相关标签/搜索