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

时间:2023-03-08 21:45:24

前言:之前发表过一篇  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页效果优化

解决iframe高度自适应问题

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

增加上边框

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

美化删除图标

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

标签页上面显示菜单图标

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

标签增加边框

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

方角边框

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

标签颜色搭配

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

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

标签过多时左右移动

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

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

菜单选中效果

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

菜单独立滚动条

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

二、代码示例

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 = '<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里面更改即可。

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

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

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页效果优化

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

3、美化删除图标

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

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

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

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

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

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

效果如下

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

4、标签页带图标

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

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

然后其他每一个动态打开的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;
}

最终得到效果如下:

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

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

5、标签页增加边框

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

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

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

然后增加

.nav-tabs{
background: #fafafa;
}

这样看到的效果:

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

当然,有人喜欢将边框的圆角去掉,你也可以在.nav-tabs li a里面增加 border-radius:0; 得到的效果
JS组件系列——基于Bootstrap Ace模板的菜单Tab页效果优化

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

6、标签页颜色搭配

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

.nav-tabs{
background: #fafafa;
border-bottom: 3px #3498db solid;
} .nav-tabs li a{
line-height:;
border:1px #ddd solid;
margin-right: -1px;
color: #999;
border-radius:;
}
.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页效果优化

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

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

7、标签页宽度超限处理

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

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

JS组件系列——基于Bootstrap Ace模板的菜单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:;
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的配置使用。

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

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

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

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

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

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

得到效果

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

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

增加如下样式

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

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

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

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

效果如下

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

三、总结

源码下载地址:https://download.csdn.net/download/landeanfen/12323940

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

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

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