/* jQuery iFrame Tabs Plugin * Version: 0.5.01 * Author: think8848 * Contact: QQ: 166156888 Blog: http://think8848.cnblogs.com * Company: http://www.cleversoft.com */ ; $.fn.cleverTabs = function (options) { var self = this; var options = $.extend({ setupContextMenu: true }, options || {}); var tabs = new CleverTabs(self, options); if (options.setupContextMenu) { tabs.setupContextMenu(); } return tabs; }; //定义CleverTabs对象 function CleverTabs(self, options) { var self = self; this.hashtable = new Array(); this.options = $.extend({ //锁定Tab,不允许关闭 lock: false, //禁止选中Tab disable: false, //每个Tab是否生成关闭按钮 close: true, //当只有一个Tab页面时是否锁定该Tab lockOnlyOne: true, //Tab用于显示Panel的容器 panelContainer: (function () { var tick = new Date().getTime(); var panelElement = $('
'); self.append(panelElement); return panelElement; })(), //Tab用于控制的头模板 tabHeaderTemplate: '
  • #{label}
  • ', //Tab用于显示的Panel模板 tabPanelTemplate: '
    ', //Tab唯一id生成器 uidGenerator: function () { return new Date().getTime(); } }, options || {}); self.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"); this.wrapper = self; var el = self.find('ol,ul').eq(0); this.element = el; this.element.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"); var pc = this.options.panelContainer; this.panelContainer = pc; if (!this.panelContainer.hasClass('ui-tabs')) { this.panelContainer.addClass('ui-tabs'); } this.panelContainer.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"); this.lockOnlyOne = this.options.lockOnlyOne; if (this instanceof CleverTabs) { CleverTabs.prototype.resizePanelContainer = function () { if (pc.attr('id').indexOf('cleverTabsPanelContainer') === 0) { var height = self.height() - el.height()-10; pc.css('height', Math.floor(height / self.height() * 100) + '%'); } } } }; //添加Tab CleverTabs.prototype.add = function (options) { var self = this; var uid = self.options.uidGenerator(self); var options = $.extend({ id: uid, url: '#', label: 'New Tab', closeRefresh: null, closeActivate: null, callback: function () { } }, options || {}); //验证指定Url的Tab是否已经开启,如果开启则激活它 var exsitsTab = self.getTabByUrl(options.url); if (exsitsTab) { if (!exsitsTab.activate()) { return false; } } //生成Tab头 var tabHeader = $(self.options.tabHeaderTemplate .replace(/#\{id\}/g, options.id) .replace(/#\{liclass\}/g, 'ui-state-default ui-corner-top') .replace(/#\{title\}/g, options.label) .replace(/#\{label\}/g, function () { //如果Tab的Label大于7个字符,则强制使其为前7个字符加'...' if (options.label.length > 7) { return options.label.substring(0, 7) + '...'; } return options.label; } ())); //Tab头绑定click事件 tabHeader.bind("click", function () { if (!$(this).hasClass('ui-state-disabled')) { tab.activate(); } }); //Tab头绑定mouseover事件 tabHeader.bind('mouseover', function () { if (!$(this).hasClass('ui-state-disabled')) { $(this).addClass('ui-state-hover'); } }); //Tab头绑定mouseout事件 tabHeader.bind('mouseout', function () { if (!$(this).hasClass('ui-state-disabled')) { $(this).removeClass('ui-state-hover'); } }); //生成Tab显示面板 var panel = $(self.options.tabPanelTemplate .replace(/#\{id\}/g, options.id) .replace(/#\{src\}/g, options.url.toLowerCase())); self.element.append(tabHeader); //没有办法的办法,因为无法使iframe自动"撑大"外面的div,所在只能在这里计算生成的Tab页面容器的高度, //注意,如果style属性还设置了除height之外的样式,则需要修改这里的代码,自求多福吧 //ps: 可以使用https://github.com/aaronmanela外的jQuery.iframe.auto.height插件做到“撑大”外层的div //但是不能支持跨域访问,虽然这不是大问题,但是我没有采用这个方法 if (self.panelContainer.attr('id').indexOf('cleverTabsPanelContainer') === 0) { var height = self.wrapper.height() - self.element.height()-10; self.panelContainer.css('height', Math.floor(height / self.wrapper.height() * 100) + '%'); } self.panelContainer.append(panel); self.hashtable[options.id] = { 'callback': options.callback, 'closerefresh': options.closeRefresh, 'closeactivate': options.closeActivate, 'orgLock': options.lock }; var tab = new CleverTab(self, options.id); tab.setLock(options.locked); tab.activate(); return tab; }; //为Tab安装右键菜单 CleverTabs.prototype.setupContextMenu = function () { var self = this; var contextMenu; if (!self.options.contextMenu) { contextMenu = { element: $(''), handler: function (action, el, pos) { var tab = self.getCurrentTab(); switch (action) { case 'enabled': tab.setDisable(false); break; case 'disable': tab.setDisable(true); break; case 'lock': tab.setLock(true); break; case 'unlock': tab.setLock(false); break; case 'refresh': tab.refresh(); break; case 'clear': tabs.clear(); break; } } }; } var menu = contextMenu.element; self.wrapper.parent().append(menu); self.element.contextMenu( { menu: menu.attr('id') }, contextMenu.handler); } //获取当前选中的Tab的唯一Id CleverTabs.prototype.getCurrentUniqueId = function () { var self = this; if (self.element.find(' > li').size() > 0) { var current = self.element.find('li.ui-tabs-selected'); return current.size() > 0 ? CleverTab.getUniqueByHeaderId(current.attr('id')) : null; } else { return null; } } //获取当前选中的Tab CleverTabs.prototype.getCurrentTab = function () { var self = this; var uid = self.getCurrentUniqueId(); return uid ? new CleverTab(self, self.getCurrentUniqueId()) : null; } //获取指定Url的Tab CleverTabs.prototype.getTabByUrl = function (url) { if (!url) { return null; } var self = this; var frames = self.panelContainer.find('div[id^="cleverTabPanelItem-"]>iframe'); var tab; for (i = 0; i < frames.size(); i++) { var frame = $(frames[i]); var src = frame.attr('src'); if (src.indexOf('clever_tabs_time_stamp=') > 0) { src = src.substring(0, src.indexOf('clever_tabs_time_stamp=') - 1); } if (src == url.toLowerCase()) { tab = new CleverTab(self, CleverTab.getUniqueByPanelId(frame.parent('div:first').attr('id'))); } } return tab; } //清除所有Tab页面 CleverTabs.prototype.clear = function () { var self = this; var lis = self.element.find('>li'); var hasLock = self.element.find('span.ui-icon-locked').size() > 0; for (i = self.lockOnlyOne && !hasLock ? 1 : 0; i < lis.size(); i++) { var id = CleverTab.getUniqueByHeaderId(lis.eq(i).attr('id')); var tab = new CleverTab(self, id); tab.kill(); } } //定义Tab页面类 function CleverTab(tabs, id) { //Tab控件 this.tabs = tabs; //Tab页面Id this.id = id //Tab页面头 this.header = this.tabs.element.find('li#' + CleverTab.getFullHeaderId(id)); this.headerId = this.header.attr('id'); //Tab页面是否可激活 this.disable = this.header.hasClass('ui-state-disabled'); //Tab页面是否锁定(不允许关闭) this.lock = this.header.find('span.ui-icon-locked').size() != 0; //Tab页面有于显示内容的面板 this.panel = tabs.panelContainer.find('div#' + CleverTab.getFullPanelId(id)); //Tab页面id this.panelId = this.panel.attr('id'); //Tab标题 this.label = (this.header ? this.header.find('a:first').attr('title') : null); //Tab中iframe的url this.url = (this.panel ? this.panel.find(' > iframe:first').attr('src') : null); //Tab关闭时的回调函数 this.callback = this.tabs.hashtable[id].callback; //当关闭Tab时需要刷新的Tab的url this.closeRefresh = this.tabs.hashtable[id].closeRefresh; //当关闭当前Tab时需要激活的Tab的url this.closeActivate = this.tabs.hashtable[id].closeActivate; //该属性和CleverTabs.lockOnlyOne有关 this.orgLock = this.tabs.hashtable[id].orgLock; }; //使Tab页面处于未激活状态,不建议在代码中使用 CleverTab.prototype.deactivate = function () { var self = this; self.header.removeClass('ui-tabs-selected ui-state-active'); self.panel.addClass('ui-tabs-hide'); if (self.tabs.lockOnlyOne && !self.tabs.hashtable[self.id].orgLock && self.tabs.element.find('>li').size() > 1) { self.setLock(false); } } //使Tab页面处于激活状态 CleverTab.prototype.activate = function () { var self = this; if ($.browser.msie) { self.header.find('a').trigger('blur'); } if (self.disable) { return false; } var currentTab = self.tabs.getCurrentTab(); if (currentTab) { if (currentTab.id == self.id) { return false; } currentTab.deactivate(); } self.header.addClass('ui-tabs-selected ui-state-active'); self.panel.removeClass('ui-tabs-hide'); if (self.tabs.lockOnlyOne && self.tabs.element.find('>li').size() == 1) { self.setLock(true, false); } } //获取该Tab之前的Tab CleverTab.prototype.prevTab = function () { var self = this; var prev = self.header.prev(); if (prev.size() > 0) { var headerId = prev.attr('id'); return new CleverTab(tabs, CleverTab.getUniqueByHeaderId(headerId)); } else { return null; } } //获取该Tab之后的Tab CleverTab.prototype.nextTab = function () { var self = this; var next = self.header.next(); if (next.size() > 0) { var headerId = next.attr('id'); return new CleverTab(tabs, CleverTab.getUniqueByHeaderId(headerId)); } else { return null; } } //移移该Tab CleverTab.prototype.kill = function () { var self = this; if (self.lock) { return; } var nextTab = self.nextTab(); if (!nextTab) { nextTab = self.prevTab(); } var callback = self.callback; var refresh = self.closeRefresh; var activate = self.closeActivate; self.header.remove(); self.panel.remove(); delete self.tabs.hashtable[self.id]; if (self.tabs.panelContainer.attr('id').indexOf('cleverTabsPanelContainer') === 0) { var height = self.tabs.wrapper.height() - self.tabs.element.height()-10; self.tabs.panelContainer.css('height', Math.floor(height / self.tabs.wrapper.height() * 100) + '%'); } var refreshTab = self.tabs.getTabByUrl(refresh); if (refreshTab) { refreshTab.refresh(); } var activateTab = self.tabs.getTabByUrl(activate); if (activateTab) { activateTab.activate(); } else { if (nextTab) { nextTab.activate(); } } callback(); } //刷新该Tab的iframe中的内容 CleverTab.prototype.refresh = function () { var self = this; if (self.url.indexOf('clever_tabs_time_stamp=') > 0) { self.url = self.url.substring(0, self.url.indexOf('clever_tabs_time_stamp=') - 1); } var newUrl = self.url.concat(self.url.indexOf('?') < 0 ? '?' : '&').concat('clever_tabs_time_stamp=').concat(new Date().getTime()); self.panel.find(' > iframe:first').attr('src', newUrl); } //设置该Tab的disabled属性 CleverTab.prototype.setDisable = function (disable) { var self = this; if (disable) { self.header.addClass('ui-state-disabled'); var overlay = $('
    '); self.panel.append(overlay); this.setLock(true); } else { self.header.removeClass('ui-state-disabled'); var overlay = self.panel.find('div.ui-widget-overlay:first'); overlay.remove(); if (self.tabs.lockOnlyOne && self.tabs.element.find('>li').size() == 1) { return; } this.setLock(); } } //设置该Tab的locked属性 CleverTab.prototype.setLock = function (lock, changeOrgLock) { var self = this; var changeOrgLock = changeOrgLock == undefined || changeOrgLock; if (changeOrgLock) { self.tabs.hashtable[self.id].orgLock = lock; } if (self.lock == lock) { return; } if (!lock && self.tabs.lockOnlyOne && self.tabs.element.find('>li').size() == 1) { return; } if (!lock) { var btnLock = this.header.find('span.ui-icon-locked'); if (btnLock.size() > 0) { btnLock.remove(); } var btnClose = $(''); this.header.append(btnClose); btnClose.bind('mouseover', function () { $(this).addClass('ui-state-active'); }); btnClose.bind('mouseout', function () { $(this).removeClass('ui-state-active'); }); btnClose.bind('click', function () { new CleverTab(self.tabs, self.id).kill(); }); } else { var btnClose = this.header.find('span.ui-icon-close').parent('a:first'); if (btnClose.size() > 0) { btnClose.remove(); } this.header.append($('')); } } //获取指定Tab头完全id的唯一id CleverTab.getUniqueByHeaderId = function (id) { return id.replace('cleverTabHeaderItem-', ''); } //获取指定Tab页面完全id的唯一id CleverTab.getUniqueByPanelId = function (id) { return id.replace('cleverTabPanelItem-', ''); } //获取指定Tab头唯一id的完全id CleverTab.getFullHeaderId = function (uid) { return 'cleverTabHeaderItem-'.concat(uid); } //获取指定Tab页面唯一id的完全id CleverTab.getFullPanelId = function (uid) { return 'cleverTabPanelItem-'.concat(uid); }