123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- /**
- * b.tabs.js
- * base on Bootstrap Tab
- *
- * 导航功能扩展,可动态添加,可关闭
- * 使用后可将系统改造为以标签页来打开页面的模式
- *
- * @author Terry
- * created : 2016.03.17
- *
- * changelog:
- * 2017.07.21 - 重构代码
- * 解决IE下关闭标签页后切换其它标签页不能获得焦点问题
- * 2017.08.03 - 增加内部高度修正功能
- * 增加标签拖拽功能(依赖jquery-ui功能库,需要引入脚本)
- * 修复部分Bug
- */
- !function ($) {
- "use strict";
-
- var defaults = {
- /**
- * 载入标签页内容,登录超时后跳转的链接
- */
- 'loginUrl' : '/',
- /**
- * 自定义样式
- */
- 'className' : undefined,
- /**
- * 是否允许标签被拖拽排序,默认允许
- * 拖拽功能依赖jquery-ui脚本库,请在使用之前引入功能库
- * 设置“noSort”样式可以让标签不被排序
- */
- 'sortable' : true,
- /**
- * 浏览窗口尺寸发生变化时执行的回调
- */
- 'resize' : undefined
- };
-
- /**
- * 常量
- */
- var constants = {
- closeBtnTemplate : '<button type="button" class="navTabsCloseBtn" title="关闭" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>',
- //设置该样式的tab不会被关闭
- noCloseClass : 'noclose',
- //设置该样式不会被拖拽修改位置
- noSortClass : 'noSort',
- prefixKey : 'bTabs_'
- };
-
- var bTabs = function(box,p){
- this.$container = box;
- this.openTabs = new Array();
- this.p = p;
- };
- /**
- * 版本
- */
- bTabs.version = '1.0';
- /**
- * 初始化
- */
- bTabs.prototype.init = function(){
- var self = this,c = constants, $tabs = this.$container, openTabs = this.openTabs, p = this.p;
-
- $($tabs).addClass('bTabs');
- if(p.className) $($tabs).addClass(p.className);
-
- $('ul.nav-tabs a',$($tabs)).each(function(i,row){
- var li = $(this).closest('li');
- if(li && !$(li).hasClass(c.noCloseClass)) $(row).append(c.closeBtnTemplate);
- });
- $('div.tab-content div.tab-pane',$tabs).each(function(i,row){
- openTabs.push($(this).attr('id'));
- });
- //为关闭图标绑定事件,并适用于动态新增的
- $('ul.nav-tabs',$tabs).on('click','button',function(e){
- var id = $(this).parent().attr('href').replace('#', '');
- self.closeTab(id);
- });
- //处理窗口拖拽排序功能
- if(p.sortable && $.fn.sortable){
- $('ul.nav-tabs',$tabs).sortable({
- items : "li:not(."+c.noSortClass+")",
- cancel : "li:not(.active)",
- axis : "x",
- placeholder : 'bTabsPlaceHolder',
- forcePlaceholderSize : true,
- stop : function(e,ui){}
- }).disableSelection();
- }
- if(p && p.resize && $.isFunction(p.resize)){
- p.resize();
- self.innerResize();
- $(window).off('resize.bTabs').on('resize.bTabs',function(e){
- p.resize();
- self.innerResize();
- });
- }
- };
- /**
- * 内部高度调整
- */
- bTabs.prototype.innerResize = function(){
- var $tabs = this.$container;
- //高度计算
- var mainHeight = $($tabs).innerHeight();
- var tabBarHeight = $('ul.nav-tabs',$tabs).outerHeight(true);
- $('div.tab-content',$tabs).height(mainHeight - tabBarHeight);
- };
- /**
- * 新增一个tab,但如果是已存在的tab则只是激活它,而不再新增
- *
- * @param id {string} 模块ID
- * @param title {string} 标题
- * @param url {string} 目标链接地址
- * @param loginCheck {function}可选参数,不传则直接使用iframe打开界面
- */
- bTabs.prototype.addTab = function(id,title,url,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();
- $('ul.nav-tabs',$tabs).append('<li><a href="#'+tabId+'" title="'+title+'" data-toggle="tab">'+title+c.closeBtnTemplate+'</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%;min-width:1150px;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();
- };
- /**
- * 关闭tab
- * @param id
- */
- bTabs.prototype.closeTab = function(id,toId){
- 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(toId != "" && toId !=undefined) {
- toId = c.prefixKey + toId;
- $('ul.nav-tabs a[href="#' + toId + '"]', $tabs).tab('show');
- $("#"+toId).find("iframe")[0].contentWindow.location.reload();
- }else {
- if (prevLi.size() > 0) $('a', $(prevLi)).tab('show');
- }
- };
-
- /**
- * 插件初始化入口
- */
- function Plugin(p){
- return this.each(function(){
- //参数合并时允许读取在html元素上定义的'data-'系列的参数
- var $this = $(this),
- data = $this.data('bTabs'),
- params = $.extend({}, defaults, $this.data(), typeof p == 'object' && p);
- if(!data) $this.data('bTabs', (data = new bTabs(this,params)));
- data.init();
- });
- }
- /**
- * 新增标签页
- * @param id
- * @param title
- * @param url
- * @param loginCheck
- * @returns {*}
- */
- function bTabsAdd(id,title,url,loginCheck){
- return this.each(function(){
- if(!id || !title || !url) return;
- var $this = $(this),data = $this.data('bTabs');
- if(data) data.addTab(id,title,url,loginCheck);
- });
- }
- /**
- * 关闭标签页
- * @param id
- * @returns {*}
- */
- function bTabsClose(id){
- return this.each(function(){
- if(!id || !title || !url) return;
- var $this = $(this),data = $this.data('bTabs');
- if(data) data.closeTab(id);
- });
- }
- /**
- * 关闭标签页,用于外部调用
- * @param id
- * @returns {*}
- */
- function CloseTabs(id,toId){
- var c = constants;
- id = c.prefixKey+id;
- return this.each(function(){
- if(!id) return;
- var $this = $(this),data = $this.data('bTabs');
- if(data) data.closeTab(id,toId);
- });
- }
-
- var old = $.fn.bTabs;
- $.fn.bTabs = Plugin;
- $.fn.bTabs.Constructor = bTabs;
- $.fn.bTabsAdd = bTabsAdd;
- $.fn.bTabsClose = bTabsClose;
- $.fn.CloseTabs = CloseTabs;
- // 处理新旧版本冲突
- // =================
- $.fn.bTabs.noConflict = function () {
- $.fn.bTabs = old;
- return this;
- };
- }(window.jQuery);
|