在大型的bs系统开发中,界面通常组织成MDI的形式,fineui、jquery miniui等框架都完美的实现了,如果不想引入这些大的类库,需要自己实现或下载特定的插件。网上可以下载到一个clevertabs jquery插件库,但只支持jquery1.6和jquery ui1.8,对高版本jquery支持的不好。网上搜索了一下,有基于bootstrap的实现,而且兼容高版本jquery。下载后改进一下,满足基本需求。
下面分析一下实现原理。首先看看bootstrap tab页签的实现方式:
<ul id="myTab" class="nav nav-tabs">
<li class="active">
<a href="#home" data-toggle="tab">菜鸟教程</a>
</li>
<li><a href="#ios" data-toggle="tab">iOS</a></li>
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade in active" id="home">
<p>菜鸟教程是一个提供最新的web技术站点,本站免费提供了建站相关的技术文档,帮助广大web技术爱好者快速入门并建立自己的网站。菜鸟先飞早入行——学的不仅是技术,更是梦想。</p>
</div>
<div class="tab-pane fade" id="ios">
<p>iOS 是一个由苹果公司开发和发布的手机操作系统。最初是于 2007 年首次发布 iPhone、iPod Touch 和 Apple
TV。iOS 派生自 OS X,它们共享 Darwin 基础。OS X 操作系统是用在苹果电脑上,iOS 是苹果的移动版本。</p>
</div>
</div>
在具体项目中,页签下面要显示具体的子页面,这里把ios的页签内容替换为iframe,并在其中显示一个具体的页面:
<ul id="myTab" class="nav nav-tabs">
<li class="active">
<a href="#home" data-toggle="tab">菜鸟教程</a>
</li>
<li><a href="#ios" data-toggle="tab">iOS</a></li>
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade in active" id="home">
<p>菜鸟教程是一个提供最新的web技术站点,本站免费提供了建站相关的技术文档,帮助广大web技术爱好者快速入门并建立自己的网站。菜鸟先飞早入行——学的不仅是技术,更是梦想。</p>
</div>
<div class="tab-pane fade in" id="ios">
<iframe style="height:500px;width:500px" src="www.baidu.com"></iframe>
</div>
</div>
测试通过,那么现在只需要能够动态生成页签和相关页面,并根据需要生成页签上的关闭按钮。
/**
* 新增一个tab,但如果是已存在的tab则只是激活它,而不再新增
*
* @param id {string} 模块ID
* @param title {string} 标题
* @param url {string} 目标链接地址
* @param canClose {boolean} 是否生成关闭按钮
* @param loginCheck {function}可选参数,不传则直接使用iframe打开界面
*/
bTabs.prototype.addTab = function(id,title,url,canClose,loginCheck){
if(!id || !title || !url) console.error('新增tab时,id,title,url参数为必须传递参数!');
var c = constants, $tabs = this.$container, openTabs = this.openTabs, p = this.p;
var tabId = c.prefixKey + id;
if(openTabs && $.isArray(openTabs) && openTabs.length>0){
var exist = false;//是否已存在
$.each(openTabs,function(i,row){
if(row == tabId){
exist = true;
return false;
}
});
//若功能已存在,则直接切换
if(exist){
$('ul.nav-tabs a[href="#'+tabId+'"]',$tabs).tab('show');
return;
}
}else openTabs = new Array();
if(canClose)
$('ul.nav-tabs',$tabs).append('<li><a href="#'+tabId+'" data-toggle="tab">'+title+c.closeBtnTemplate+'</a></li>');
else
{
$('ul.nav-tabs',$tabs).append('<li role="presentation" class="noclose"><a href="#'+tabId+'" data-toggle="tab">'+title+'</a></li>');
}
var content = $('<div class="tab-pane" id="'+tabId+'"></div>');
$('div.tab-content',$tabs).append(content);
//切换到新增加的tab上
$('ul.nav-tabs li:last a',$tabs).tab('show');
openTabs.push(tabId);
var openIframe = function(){
$(content).append('<iframe frameborder="0" scrolling="yes" style="width:100%;height:100%;border:0px;" src="'+url+'"></iframe>');
};
//进行登录验证
if(loginCheck && $.isFunction(loginCheck)){
if(loginCheck()) openIframe();
else if(p && p.loginUrl) window.top.location.replace(p.loginUrl);
}else openIframe();
};
动态生成页签和相关内容的实现方式,就是拼html,在append到指定元素上,原理比较简单。这里只要分析清楚bootstrap的实现方式即可。页签上的关闭按钮也是拼了一个button(closeBtnTemplate : '<button type="button" class="navTabsCloseBtn" title="关闭" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>',),并用css改变其 显示风格。总体上,灵活运用jquery的css选择器和bootstrap tab的接口,即可实现相关功能。
关闭页签的时候,过程相反,删除掉tab页签和相关页面内容
/**
* 关闭tab
* @param id
*/
bTabs.prototype.closeTab = function(id){
var c = constants, $tabs = this.$container, openTabs = this.openTabs;
var thisTab = $('#' + id);
//在移除标签页之前,先把iframe移除,解决在IE下,窗口上的输入控件获得不了焦点的问题
if($('iframe',$(thisTab)).size() > 0) $('iframe',$(thisTab)).remove();
//移除内容区
$(thisTab).remove();
var a = $('ul.nav-tabs a[href="#'+id+'"]',$tabs);
var li = $(a).closest('li');
//获得当前tab的前一个tab
var prevLi = $(li).prev();
//移除Tab
li.remove();
if(openTabs && $.isArray(openTabs) && openTabs.length>0){
var index = -1;
$.each(openTabs,function(i,d){
if(d == id){
index = i;
return false;
}
});
if(index != -1) openTabs.splice(index,1);
}
//激活被关闭Tab邻的Tab,若没有则不处理
if(prevLi.size() > 0 ) $('a',$(prevLi)).tab('show');
};
bootstrap提供了一些基本的功能,把这些功能做成动态的,就可以实现非常绚丽的效果。现在web前端技术非常灵活,一些特效在cs端开发很困难,在bs端可以轻松实现。