JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化

前言:之前发表过一篇  JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果分享(你值得拥有) ,收到很多园友的反馈,当然也包括很多诟病,因为上篇只是将功能实现了,很多细节都没有处理,这篇博主将带领大家一起来优化这里的效果,使之成为一个可以在项目里面使用的成品。

说点题外话,本来,在互联网模式下,Tab页+iframe的组合是不能被大多数平台接受的,从这些年推出的一些好的产品可以看出,几乎大家都不这么玩,即使是一些后台的管理模板,比如常见的AdminLTE、Ace、INSPINIA+等也都摈弃了iframe,因为iframe的坏处博主都可以说出一千条。可为什么这里博主还要写这篇文章?用一句老套的话说:需求产生市场!在一些传统的企业,系统的使用人员的使用习惯还停留在10年前,他们希望页面上面展示的东西越多越好,并且希望页面切换方便,他们喜欢tab页+iframe的效果,不管你信不信,这点确实是客观存在的!就拿博主所在的公司来说,要不要tab+iframe基本上持两种意见,一半一半,可是客户更加倾向使用iframe的这种操作习惯,你有何解!前段时间用Abp做了一个Erp的项目,本来Abp原始的页面就是没有iframe的,上线之后客户觉得这种操作很不方便,最后硬生生的把Abp的界面改头换面。究其原因,在互联网+时代,大家都在大力推各种不使用iframe的效果,希望改变人们的思维模式和操作方式,但这个改变并不能一蹴而就,还需要一些时间。好了,废话到此为止,进入正题!

本文原创地址:http://www.cnblogs.com/landeanfen/p/7601880.html

系列文章

  • JS组件系列——基于Bootstrap Ace模板的菜单和Tab页效果分享(你值得拥有)
  • JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化

一、效果展示

原始效果

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第1张图片

解决iframe高度自适应问题

增加上边框

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第2张图片

美化删除图标

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第3张图片

标签页上面显示菜单图标

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第4张图片

标签增加边框

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第5张图片

方角边框

标签颜色搭配

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第6张图片

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第7张图片

标签过多时左右移动

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第8张图片

菜单选中效果

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第9张图片

菜单独立滚动条

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第10张图片

二、代码示例

1、解决高度自适应的问题

这个并不属于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 = '
';

为了在浏览器的宽高变化时页面的宽高也跟着变化,还需要注册页面的onresize事件

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

这三个地方都在bootstrap-tab.js里面更改即可。

改完之后来看看测试效果:

2、新建文件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;
}

查看效果

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第11张图片

是不是看上去赶紧好好看一些~~

3、美化删除图标

上图中标签页加上上边框之后看上去要好看一些了,可是还不够美观,看来看去总觉得哪个关闭的小图标怪怪的,我们来美化一下。比如我们在boostrap-tab.js里面将关闭按钮换成带圆形边框的

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第12张图片

将图标i标签的的class由原来的 glyphicon glyphicon-remove 换成 glyphicon glyphicon-remove-sign 即可,我们来看看效果:

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第13张图片

为了更加符合使用习惯,我们增加一个鼠标移动到图标上面显示红色的效果,我们在boostrap-tab.css里面增加如下样式:

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

效果如下

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第14张图片

4、标签页带图标

标签页里面仅仅显示文字和关闭的图标给人感觉太空洞,我们增加页面的图标。首先首页的标签页我们增加一个home图标,在index.html增加如下i标签:

JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第15张图片

然后其他每一个动态打开的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 = $('
  • '); var a = $(''); var icon = $(''); //icon.addClass('glyphicon'); icon.addClass(item.icon); var text = $(''); 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 = $(''); arrow.addClass('arrow').addClass('icon-angle-down'); a.append(arrow); li.append(a); var menus = $('
      '); 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 = '';
              //是否指定TAB内容
              if (options.content) {
                  content = '
      ' + options.content + '
      '; } else {//没有内容,使用IFRAME打开链接 content = '
      '; } //加入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

      其中有一句

      然后写一个样式调整标签页图标和标题的距离,我们在bootstrap-tab.css里面增加如下样式:

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

      最终得到效果如下:

      JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第16张图片

      当然,有可能你觉得加上这个之后tab页显得很拥挤,你也可以不加,根据自己的喜好来进行美化 

      5、标签页增加边框

      经过上面三步骤的美化,我们的标签页已经好看了许多。如果你对界面要求不高,其实也够了,但是博主觉得还可以继续美化呢~

      比如我们给标签也增加一个边框,使每一个标签页看上去更加像一个独立的整体。我们调整.nav-tabs li a这个样式为

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

      然后增加

      .nav-tabs{
          background: #fafafa;
      }

      这样看到的效果:

      JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第17张图片

      当然,有人喜欢将边框的圆角去掉,你也可以在.nav-tabs li a里面增加 border-radius:0; 得到的效果

      博主觉得使用圆角也不错啊,反正这个取决于个人喜好!

      6、标签页颜色搭配

      以上效果基本够用,在项目里面使用起来没有太大的问题,但博主还想将其优化下。比如我们做如下样式调整:

      .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

      JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第18张图片

      JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第19张图片

      可能这里的颜色搭配并不协调,但至少看上去更加perfect一点吧。

       7、标签页宽度超限处理

      到上面为止Tab页的样式已经可以了,可是还有一个最大的问题没有解决,就是当所有tab页的宽度的和超过浏览器的宽度限制时,就会出现tab的换行,看上去非常“恶心”。不信你多打开一些tab页试试。这里博主花了两天时间写了一套可行的样式方案,来一睹风采吧:

      JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第20张图片

       

       实现思路其实不难,主要就是界面样式的调整确实非常话时间。下面来看一看实现步骤

      首先界面上面在标签页的两边增加向左移、向右移的图标

                      <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){
                      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){
                          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的配置使用。

      8、左边菜单的选中效果和固定高度效果

       这部分其实不属于Tab页的优化范畴,但既然要把这个做好,顺带也把这个优化了下。

      首先在sidebar-menu.js里面增加如下id

      JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第21张图片

      然后在addTabs()方法的最下面加这两句即可

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

      得到效果

      JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第22张图片

      还有一个就是左边菜单的滚动条,当左边菜单的数量多了以后,每次展开都会导致整个页面出现滚动条,界面非常不友好,博主打算给左边菜单部分单独加上滚动条,用来控制菜单的滚动。

      增加如下样式

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

      这里的sidebar是左边菜单的div容器。

      然后在页面初始化完成的时候给这个div固定一个动态高度。

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

      效果如下

      JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化_第23张图片

      三、总结

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

      本文原创出处:http://www.cnblogs.com/landeanfen/

      欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利

      PS:感谢给位园友的支持和厚爱,源码已经贴出来了,有需要的可以自行下载。欢迎关注!

      你可能感兴趣的:(JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化)