Files

482 lines
22 KiB
JavaScript
Raw Permalink Normal View History

2026-01-16 14:13:44 +08:00
/**
* nth-tabs
* author:nethuige
* version:2.0
*/
var App = function() {
return {
// To get the correct viewport width based on http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
getViewPort: function() {
var e = window,
a = 'inner';
if (!('innerWidth' in window)) {
a = 'client';
e = document.documentElement || document.body;
}
return {
width: e[a + 'Width'],
height: e[a + 'Height']
};
}
}
}();
(function ($) {
$.fn.nthTabs = function (options) {
// 插件中的40为默认左边距
var nthTabs = this;
var nthTabsContent = $('.tab-content');
/*var content = $('.nth-tabs');
var available_width = $('.main-header').outerWidth(true) - $('.logo').outerWidth(true)
- $('.sidebar-toggle').outerWidth(true) - $('.navbar-custom-menu').outerWidth(true);
content.css('min-width', available_width);
$(window).resize(function() {
available_width = $('.main-header').outerWidth(true) - $('.logo').outerWidth(true)
- $('.sidebar-toggle').outerWidth(true) - $('.navbar-custom-menu').outerWidth(true);
content.css('min-width', available_width);
});*/
var defaults = {
allowClose: true, // 新建选项卡,是否允许关闭,默认启用
allowRefresh: true, // 新建选项卡,是否允许刷新,默认启用
active: true, // 新建选项卡,是否为活动状态,默认启用
location: true, //新建选项卡,是否自动定位,默认启用
fadeIn: true, // 新建选项卡,淡入效果,默认启用
rollWidth: nthTabs.width() - 135 // 可滚动的区域宽度减去3个操作按钮的宽度
};
var settings = $.extend({}, defaults, options);
var handler = [];
var frameName = 0;
var template =
'<div class="page-tabs">' +
'<a href="javascript:;" class="roll-nav roll-nav-left" title="菜单左滑"><span class="iconfont iconbackward"></span></a>' +
'<div class="content-tabs">' +
'<div class="content-tabs-container">' +
'<ul class="nav nav-tabs"></ul>' +
'</div>' +
'</div>' +
'<a href="javascript:;" class="roll-nav roll-nav-right" title="菜单右滑"><span class="iconfont iconforward"></span></a>' +
'<a href="javascript:;" class="roll-nav roll-nav-allclose tab-close-all" title="关闭全部"><span class="iconfont iconallclose"></span></a>' +
/*'<div class="dropdown roll-nav right-nav-list">' +
'<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown" title="功能菜单">' +
'<span class="tab-down iconfont iconxiala"></span></a>' +
'<ul class="dropdown-menu">' +
'<li><a href="javascript:;" class="tab-location">定位当前选项卡</a></li>' +
'<li><a href="javascript:;" class="tab-close-current">关闭当前选项卡</a></li>' +
'<li role="separator" class="divider"></li>' +
'<li><a href="javascript:;" class="tab-close-other">关闭其他选项卡</a></li>' +
'<li><a href="javascript:;" class="tab-close-all">关闭全部选项卡</a></li>' +
'<li class="divider"></li>' +
'<li class="scrollbar-outer tab-list-scrollbar">' +
'<div class="tab-list-container"><ul class="tab-list"></ul></div>' +
'</li>' +
'</ul>' +
'</div>' +*/
'</div>' ;
// 启用插件
var run = function(){
nthTabs.html(template);
event.onWindowsResize().onTabRefresh().onTabClose().onTabRollLeft().onTabRollRight().onTabList()
.onTabCloseOpt().onTabCloseAll().onTabCloseOther().onLocationTab().onTabToggle();
return methods;
};
// 方法列表
var methods = {
// 获取所有tab宽度
getAllTabWidth: function () {
var sum_width = 0;
nthTabs.find('.nav-tabs li').each(function () {
sum_width += parseFloat($(this).width());
});
return sum_width;
},
// 获取左右滑动步值
getMarginStep: function () {
return settings.rollWidth / 2;
},
// 获取当前活动状态选项卡ID
getActiveId: function () {
return nthTabs.find('.active').find("a").attr("href").replace('#', '');
},
// 获取所有选项卡
getTabList: function () {
var tabList = [];
nthTabs.find('.nav-tabs li a').each(function () {
tabList.push({id: $(this).attr('href'), title: $(this).children('span').html()});
});
return tabList;
},
// 新建单个选项卡
addTab: function (options) {
console.log("into "+options.id+","+options.title+","+options.url+"addTab");
// 调用模块点击日志
$.post(ext.contextPath + "/fwk/Menunumber/dosave.do", {menuitemid:options.id}, function(data) {
if (data == 1) {
console.log(options.id+"模块点击日志保存成功!");
}else if(data == 0){
console.log("模块点击日志保存失败!");
}else{
console.log("模块点击日志保存失败!");
}
},'json');
if(this.isExistsTab(options.id)){this.setActTab(options.id);return;}
// nav-tab
var tab = [];
var active = options.active == undefined ? settings.active : options.active;
var allowClose = options.allowClose == undefined ? settings.allowClose : options.allowClose;
var allowRefresh = options.allowRefresh == undefined ? settings.allowRefresh : options.allowRefresh;
var location = options.location == undefined ? settings.location : options.location;
var fadeIn = options.fadeIn == undefined ? settings.fadeIn : options.fadeIn;
var url = options.url == undefined ? "" : options.url;
var windowHeight = $(window).height();
var minheight = windowHeight-90;
tab.push('<li title="' + options.title + '" '+(allowClose ? '' : 'not-allow-close')+'>');
tab.push('<a href="#' + options.id + '" data-url="' + options.url + '" data-toggle="tab">');
tab.push('<i class="fa fa-circle tab-icon"></i>');
tab.push('<span>' + options.title + '</span>');
allowRefresh ? tab.push('<i class="fa fa-refresh tab-refresh"></i>') : '';
allowClose ? tab.push('<i class="fa fa-close tab-close"></i>') : '';
tab.push('</a>');
tab.push('</li>');
nthTabs.find(".nav-tabs").append(tab.join(''));
//tab-content
var tabContent = [];
tabContent.push('<div class="tab-pane '+(fadeIn ? 'animation-fade' : '')+'" id="' + options.id +'" '+(allowClose ? '' : 'not-allow-close')+'>');
if(url.length>0){
tabContent.push('<iframe frameborder="0" name="iframe-'+frameName+'" class="nth-tabs-frame" style="min-height:'+minheight+'px;"></iframe>');
frameName++;
}else{
tabContent.push('<div class="nth-tabs-content">'+options.content+"</div>");
}
tabContent.push('</div>');
/*//nthTabs.find(".tab-content").append(tabContent.join(''));*/
nthTabsContent.append(tabContent.join(''));
active && this.setActTab(options.id);
location && this.locationTab(options.id);
//解决iframe初始设置src导致页面刷新两次问题
$("#"+options.id).find("iframe").attr('src',options.url);
return this;
},
//新建多个选项卡
addTabs: function (tabsOptions) {
for(var index in tabsOptions){
this.addTab(tabsOptions[index]);
}
return this;
},
// 定位选项卡
locationTab: function (tabId) {
tabId = tabId == undefined ? methods.getActiveId() : tabId;
tabId = tabId.indexOf('#') > -1 ? tabId : '#' + tabId;
var navTabOpt = nthTabs.find("[href='" + tabId + "']"); // 当前所操作选项卡对象
// 计算存在于当前活动选项卡之前的所有同级选项卡的宽度之和
var beforeTabsWidth = navTabOpt.parent().width();
navTabOpt.parent().prevAll().each(function () {
beforeTabsWidth += $(this).width();
});
// 得到选项卡容器对象
var contentTab = navTabOpt.parent().parent().parent();
// 情况1前面同级选项卡宽度之和小于选项卡可视区域的则默认5
if (beforeTabsWidth <= settings.rollWidth) {
margin_left_total = 1;
}
// 情况2前面同级选项卡宽度之和大于选项卡可视区域的则margin为向左偏移整数倍的距离
else{
margin_left_total = 1 - Math.floor(beforeTabsWidth / settings.rollWidth) * settings.rollWidth;
}
contentTab.css("margin-left", margin_left_total);
return this;
},
// 删除单个选项卡
delTab: function (tabId) {
tabId = tabId == undefined ? methods.getActiveId() : tabId;
tabId = tabId.indexOf('#') > -1 ? tabId : '#' + tabId;
var navTabA = nthTabs.find("[href='" + tabId + "']");
if(navTabA.parent().attr('not-allow-close')!=undefined) return false;
// 如果关闭的是激活状态的选项卡
if (navTabA.parent().hasClass('active')) {
// 激活选项卡,如果后面存在激活后面,否则激活前面
var activeNavTab = navTabA.parent().next();
var activeTabContent = $(tabId).next();
if (activeNavTab.length < 1) {
activeNavTab = navTabA.parent().prev();
activeTabContent = $(tabId).prev();
}
activeNavTab.addClass('active');
activeTabContent.addClass('active');
}
// 移除旧选项卡
navTabA.parent().remove();
$(tabId).remove();
return this;
},
// 删除其他选项卡
delOtherTab: function () {
nthTabs.find(".nav-tabs li").not('[class="active"]').not('[not-allow-close]').remove();
$(".tab-content div.tab-pane").not('[not-allow-close]').not('[class$="active"]').remove();
nthTabs.find('.content-tabs-container').css("margin-left", 1); //重置位置
return this;
},
// 删除全部选项卡
delAllTab: function () {
this.delOtherTab();
this.delTab();
return this;
},
// 设置活动选项卡
setActTab: function (tabId) {
tabId = tabId == undefined ? methods.getActiveId() : tabId;
tabId = tabId.indexOf('#') > -1 ? tabId : '#' + tabId;
nthTabs.find('.active').removeClass('active');
nthTabsContent.find('.active').removeClass('active');
nthTabs.find("[href='" + tabId + "']").parent().addClass('active');
$(tabId).addClass('active');
return this;
},
// 切换选项卡
toggleTab: function (tabId) {
this.setActTab(tabId).locationTab(tabId);
return this;
},
// 切换并刷新选项卡
toggleTabAndRef: function (tabId,url) {
this.setActTab(tabId).locationTab(tabId);
tabId = tabId == undefined ? methods.getActiveId() : tabId;
tabId = tabId.indexOf('#') > -1 ? tabId : '#' + tabId;
$(tabId).find("iframe").attr('src',url);
return this;
},
// just刷新选项卡
refTab: function (tabId,url) {
tabId = tabId == undefined ? methods.getActiveId() : tabId;
tabId = tabId.indexOf('#') > -1 ? tabId : '#' + tabId;
$(tabId).find("iframe").attr('src',url);
if(nthTabs.find("[href='" + tabId + "']").length>0){
nthTabs.find("[href='" + tabId + "']").attr("data-url",url);
console.log(nthTabs.find("[href='" + tabId + "']").attr("data-url"));
}
return this;
},
// 指定选项卡是否存在
isExistsTab: function (tabId) {
tabId = tabId.indexOf('#') > -1 ? tabId : '#' + tabId;
return nthTabs.find("[href='" + tabId + "']").length>0;
},
// 选项卡切换事件处理器
tabToggleHandler: function(func){
handler["tabToggleHandler"] = func;
},
// 选项卡只变更刷新状态
tabChangeRefSt: function(tabId){
tabId = tabId == undefined ? methods.getActiveId() : tabId;
tabId = tabId.indexOf('#') > -1 ? tabId : '#' + tabId;
//增加Company发生变更状态变化为true不变化为false
var changeCompany = $(tabId).find("iframe").attr('data-changeCompany');
console.log(changeCompany);
if(changeCompany==true){
//Company发生变更状态刷新tab
$(tabId).find("iframe").attr('data-changeCompany', false);
}
},
// 选项卡变更刷新状态,并刷新
tabChangeRefStAndRef: function(tabId){
tabId = tabId == undefined ? methods.getActiveId() : tabId;
tabId = tabId.indexOf('#') > -1 ? tabId : '#' + tabId;
//增加Company发生变更状态变化为true不变化为false
var changeCompany = $(tabId).find("iframe").attr('data-changeCompany');
if(changeCompany=="true"){
//Company发生变更状态刷新tab
$(tabId).find("iframe").attr('data-changeCompany', false);
var url = $(tabId).find("iframe").attr("src");
$(tabId).find("iframe").attr('src',url);
}
}
};
// 事件处理
var event = {
// 窗口变化
onWindowsResize: function () {
$(window).resize(function () {
settings.rollWidth = nthTabs.width() - 120;
});
return this;
},
// 定位选项卡
onLocationTab: function () {
nthTabs.on("click", '.tab-location', function () {
methods.locationTab();
});
return this;
},
// 刷新选项卡按钮
onTabRefresh: function () {
nthTabs.on("click", '.tab-refresh', function () {
var tabId = $(this).parent().parent().find("a").attr('href');
var url = $(this).parent().parent().find("a").attr('data-url');
methods.toggleTabAndRef(tabId,url);
methods.tabChangeRefSt(tabId);
});
return this;
},
// 关闭选项卡按钮
onTabClose: function () {
nthTabs.on("click", '.tab-close', function () {
var tabId = $(this).parent().parent().find("a").attr('href');
//当前操作的标签宽度
var navTabOpt = nthTabs.find("[href='" + tabId + "']"); // 当前操作选项卡对象
// 当前选项卡后有选项卡则不处理,如果无,则整体向左偏移一个选项卡
if(navTabOpt.parent().next().length == 0){
// 计算存在于当前操作选项卡之前的所有同级选项卡的宽度之和
var beforeTabsWidth = 0;
navTabOpt.parent().prevAll().each(function () {
beforeTabsWidth += $(this).width();
});
//当前操作选项卡的宽度
var optTabWidth = navTabOpt.parent().width();
var margin_left_total = 1; // 默认偏移(总宽度未超过滚动区域)
// 得到选项卡容器对象
var contentTab = navTabOpt.parent().parent().parent();
// 满足此情况才需要做整体左偏移处理
if (beforeTabsWidth > settings.rollWidth) {
var margin_left_origin = contentTab.css('marginLeft').replace('px', '');
margin_left_total = parseFloat(margin_left_origin) + optTabWidth + 1;
}
contentTab.css("margin-left", margin_left_total);
}
methods.delTab(tabId);
});
return this;
},
// 关闭当前选项卡操作
onTabCloseOpt: function () {
nthTabs.on("click", '.tab-close-current', function () {
methods.delTab();
});
return this;
},
// 关闭其他选项卡
onTabCloseOther: function () {
nthTabs.on("click", '.tab-close-other', function () {
methods.delOtherTab();
});
return this;
},
// 关闭全部选项卡
onTabCloseAll: function () {
nthTabs.on("click", '.tab-close-all', function () {
methods.delAllTab();
});
return this;
},
// 左滑选项卡
onTabRollLeft: function () {
nthTabs.on("click", '.roll-nav-left', function () {
var contentTab = $(this).parent().find('.content-tabs-container');
var margin_left_total;
if (methods.getAllTabWidth() <= settings.rollWidth) {
//未超出可视区域宽度,不可滑动
margin_left_total = 40;
}else{
var margin_left_origin = contentTab.css('marginLeft').replace('px', '');
margin_left_total = parseFloat(margin_left_origin) + methods.getMarginStep() + 40;
}
contentTab.css("margin-left", margin_left_total > 1 ? 1 : margin_left_total);
});
return this;
},
// 右滑选项卡
onTabRollRight: function () {
nthTabs.on("click", '.roll-nav-right', function () {
if (methods.getAllTabWidth() <= settings.rollWidth) return false; //未超出可视区域宽度,不可滑动
var contentTab = $(this).parent().find('.content-tabs-container');
var margin_left_origin = contentTab.css('marginLeft').replace('px', '');
var margin_left_total = parseFloat(margin_left_origin) - methods.getMarginStep();
if (methods.getAllTabWidth() - Math.abs(margin_left_origin) <= settings.rollWidth) return false; //已无隐藏无需滚动
contentTab.css("margin-left", margin_left_total);
});
return this;
},
// 选项卡清单
onTabList: function () {
nthTabs.on("click", '.right-nav-list', function () {
var tabList = methods.getTabList();
var html = [];
$.each(tabList, function (key, val) {
html.push('<li class="toggle-tab" data-id="' + val.id + '">' + val.title + '</li>');
});
nthTabs.find(".tab-list").html(html.join(''));
});
nthTabs.find(".tab-list-scrollbar").scrollbar();
this.onTabListToggle();
return this;
},
// 清单下切换选项卡
onTabListToggle: function () {
nthTabs.on("click", '.toggle-tab', function () {
var tabId = $(this).data("id");
methods.setActTab(tabId).locationTab(tabId);
methods.tabChangeRefStAndRef(tabId);
});
// 选项卡清单滚动条点击不关闭
nthTabs.on('click','.scroll-element',function (e) {
e.stopPropagation();
});
return this;
},
// 选项卡切换事件
onTabToggle: function(){
nthTabs.on("click", '.nav-tabs li', function () {
var lastTabText = nthTabs.find(".nav-tabs li a[href='#"+methods.getActiveId()+"'] span").text();
handler.hasOwnProperty("tabToggleHandler") && handler["tabToggleHandler"]({
last:{
tabId:methods.getActiveId(),
tabText:lastTabText
},
active:{
tabId:$(this).find("a").attr("href").replace('#',''),
tabText:$(this).find("a span").text()
}
});
var tabId = $(this).find("a").attr("href");
methods.tabChangeRefStAndRef(tabId);
});
}
};
return run();
}
})(jQuery);