緊接着上一篇隨筆iframe的內容增高或縮減時設置其iframe的高度的處理方案
如果采用iframe來切換顯示內容的方式來展現辦公Web。那么需要解決幾個問題
1.tab標簽需要和顯示的iframe一一對應,當點擊到某個tab頁簽的時候需要切換到對應的iframe。
2.需要有新增、刪除頁簽的tab功能。
3.在tab頁簽之間切換的時候需要有一個記錄點擊的頁簽的歷史記錄的功能。何用?當你刪除某個頁簽的時候,需要回溯到上一個頁簽。
4.不斷添加頁簽,需要計算頁簽的寬度做適配。
本實例是這樣做的
<div class="tabbable" id="tabs"> <!-- Tab標簽列表 --> <ul class="nav nav-tabs" id="myTab"></ul> <!-- 顯示內容列表,和Tab標簽列表一一對應 --> <div class="tab-content"></div> </div>
如上,#myTab是用來保存Tab標簽頁的,.tab-content用來保存iframe頁面列表。下面舉例說明里面的內容,例子中有兩個Tab頁,效果圖如下
主要style樣式表如下

<style type="text/css"> html,body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, p, blockquote, th, td{ margin: 0; padding:0; } *{ -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } ul, ol { margin-top: 0; margin-bottom: 10px; } a { color: #428bca; text-decoration: none; } .fa { display: inline-block; font-family: FontAwesome; font-style: normal; font-weight: normal; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } :before, :after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } /*這是一個字體,可以自定義一個x圖片*/ .fa-times:before { content: "\f00d"; } .tabbable { border: none; margin-bottom: 10px; } .nav { padding-left: 0; margin-bottom: 0; list-style: none; } .nav>li { position: relative; display: block; } .nav-tabs { margin-bottom: 0; margin-left: 0; border: 0; top: 2px; background-color: #f3f3f3; -webkit-box-shadow: 0 0 4px rgba(0,0,0,.3); -moz-box-shadow: 0 0 4px rgba(0,0,0,.3); box-shadow: 0 0 4px rgba(0,0,0,.3); border-bottom: 1px solid #ddd; } .nav-tabs>li { float: left; margin-bottom: 0px; margin-left: 5px; } .nav-tabs li i { position: relative; margin-left: 10px; cursor: pointer; } .nav-tabs li [class*=" fa-"], .nav-tabs li [class^="fa-"] { width: 1.25em; display: inline-block; text-align: center; } #myTab { height: 40px; overflow: hidden; } #myTab > li { height: 35px; overflow: hidden; margin-top: 5px; background: #dedede; background: rgba(0,0,0,0.05); color: #777; } #myTab > li.active, #myTab>li:hover, #myTab>li:focus { background-color: #fff; border-bottom-color: transparent; box-shadow: 0 -2px 3px 0 rgba(0,0,0,.15); } #myTab > li > a { position: relative; display: inline-block; white-space: nowrap; overflow: hidden; padding: 8px 0px 8px 10px; margin: 0 20px 0 0; border-top: 0px; box-shadow: none; background: transparent; line-height: 17px; border: 0; max-width: 108px; color: #777; } #myTab > li.active { border-top: 2px solid #2dc3e8; } #myTab li [class*=" fa-"], #myTab li [class^="fa-"] { vertical-align: middle; margin-left: 0px; position: absolute; right: 2px; margin-top: 10px; } .tab-content { background: none; padding: 0; padding-top: 5px; position: relative; } .tab-content>div{ display: none; } .tab-content>.active { display: block; } </style>
標簽內容如下
<div class="tabbable" id="tabs"> <!-- 頁面標簽列表 --> <ul class="nav nav-tabs" id="myTab">
<li id="tab-0" class="">
<a data-toggle="tab" href="#tab-content-0" style="width: 518px; padding-left: 10px;"> 首頁 </a>
<i class="fa fa-times" onclick="deleteTab(0)"></i>
</li>
<li id="tab-10301" class="active">
<a data-toggle="tab" href="#tab-content-10301" style="width: 518px; padding-left: 10px;">動向匯報</a>
<i class="fa fa-times" onclick="deleteTab(10301)"></i>
</li>
</ul> <!-- 頁面內容列表,和頁面標簽列表對應 -->
<div class="tab-content">
<div class=" " id="tab-content-0">
<iframe id="iframepage0" name="iframepage1" width="100%" frameborder="0" scrolling="no" src="/business/system/manage/welcome/list/page" height="311"></iframe>
</div>
<div id="tab-content-10301" class="active">
<iframe id="iframepage4" name="iframepage5" width="100%" frameborder="0" scrolling="no" src="/business/workReport/manage/list/myPage" height="311"></iframe>
</div>
</div> </div>
看上面黑色粗體字,tab標簽列表中的a元素的href屬性即是對應的頁面內容DIV標簽的id。tab標簽li和內容標簽div默認都是隱藏的,通過添加class active來使之顯示出來。
實現點擊切換顯示tab顯示的代碼為
//切換tab頁的顯示 $(document).on('click','#myTab > li',function(e){ //清除原來顯示的tab頁 var oldTab = $("#myTab li.active").removeClass("active").find("a[data-toggle='tab']"); $(oldTab.attr("href")).removeClass("active"); //設置新的顯示tab頁 var newTab = $(this).addClass("active").find("a[data-toggle='tab']"); $(newTab.attr("href")).addClass("active"); refreshTabHistory(false/*isDelete*/,$(this).attr('id').substring(4)); }) //手動調用切換到要顯示的tab頁,當前的action只支持show //eg:$("#tab-0 a[data-toggle='tab']").tab("show"); $.fn.tab = function(action){ if(action == "show"){ $(this).parent().click(); } }
新增和刪除tab頁
var currentTabId = '';//當前焦點Tab //在非左側菜單欄彈出的tab頁也會用到該數據,如common.js中的pageForward函數 var pageCounter = 0; /* id: tab頁簽的html標簽ID屬性格式為"tab-"+id,內容容器的html標簽ID格式為"tab-content-"+id text: tab頁簽的顯示文本 url: 打開的iframe的url innerTab: 是否是內部彈出頁(打開的tab頁觸發添加新的tab頁),默認為undefined/false */ function addTab(id,text,url,innerTab) { //如果某個頁面已經打開,則切換到該頁顯示即可,不會新添加tab頁 if($('#myTab #tab-'+id).length > 0){ $('#myTab #tab-' + id + ' a').tab('show'); }else{ var tab_id = "tab-" + id, tab_content_id = "tab-content-"+id; //添加tab頁簽 $("#myTab > li").removeClass("active"); $("#myTab").append("<li id='" + tab_id + "' class='active'><a data-toggle='tab' href='#" + tab_content_id + "'>" + text + "</a>" + ("<i class='fa fa-times' onclick='deleteTab(\"" + id + "\")'></i>") + "</li>"); //添加新的內容顯示 $(".tab-content > div").removeClass("active"); $(".tab-content").append("<div id='"+ tab_content_id +"' class='active'>" + "<iframe id='iframepage" + (pageCounter++) + "' name='iframepage" + (pageCounter++) + "' width='100%' frameborder='0' scrolling='no' src='" + url + "'></iframe></div>"); } //刷新切換tab的歷史記錄 refreshTabHistory(false/*isDelete*/,id); //重新設置tab頁簽的寬度 refreshWidth(); } //參數id為tab的標志,但是並不是tab頁的id屬性,真正的id屬性值是"tab-"+id function deleteTab(id){ var tabJQ = $("#tab-"+id), tabContentJQ = $("#tab-content-" + id); if(!tabJQ.hasClass("active")){ tabJQ.remove(); tabContentJQ.remove(); refreshTabHistory(true/*isDelete*/,id); }else{ tabJQ.remove(); tabContentJQ.remove(); refreshTabHistory(true/*isDelete*/,id); $('#tab-' + currentTabId + ' > a').tab('show').click(); } refreshWidth(); } //關閉當前tab頁的快速方法 function closeCurrentTab(){ deleteTab(currentTabId); }
新增、修改、切換tab的歷史記錄刷新函數
/* 刷新頁簽切換歷史 isdelete: 是否是刪除tab頁簽,true:是,false:否 curTabId:要處理的tab頁簽的id,tab頁簽html標簽元素的ID屬性格式為"tab-"+curTabId */ function refreshTabHistory(isdelete,curTabId){ if(!refreshTabHistory.histoty){ //用來記錄用戶點擊tab的歷史 refreshTabHistory.histoty = []; } var index = 0, leng = refreshTabHistory.histoty.length; //查找傳入的tab頁簽在歷史記錄中的位置 for(; index < leng; index++){ if(refreshTabHistory.histoty[index] == curTabId){ break; } } //如果是刪除頁簽,直接在歷史記錄中刪除即可,歷史記錄的其他頁簽的順序不變 if(isdelete){ refreshTabHistory.histoty.splice(index,1); //如果是新增頁簽,先保證歷史記錄中沒有改頁簽(有就刪掉),然后將新增的頁簽放在歷史記錄的最后面(即該頁簽為最新) }else{ if(index < leng) { refreshTabHistory.histoty.splice(index,1); } refreshTabHistory.histoty.push(curTabId); } currentTabId = refreshTabHistory.histoty[refreshTabHistory.histoty.length - 1]; }
每一個頁簽的構成如下
可以看到tab頁簽的margin-left和關閉按鈕是必須要有的,所以tab頁簽的最小寬度為25px。唯一可以設置寬度的是tab頁簽的名稱顯示部分(也就是css選擇器#myTab > li > a對應的DOM元素),我們必須保證每個tab頁簽的寬度相同。
本實例處理為:默認tab頁簽名稱元素a標簽的最大寬度是108px。隨着頁簽的增多,寬度不夠用的時候先a標簽的內容部分的寬度,當a標簽的內容部分的寬度為0后開始縮減a標簽的padding-left,直到padding-left為0為止。當頁簽過多的時候(每個頁簽至少25px,那么寬度總會到不夠用的時候),我們沒有考慮這種情況的處理,試想誰會打開這么多頁簽,這會讓瀏覽器都卡住了。源碼如下
//刷新重置tab頁簽的寬度 function refreshWidth(){ var panelWidth = $('#myTab').width() - 20/*可能存在的滾動條寬度*/, tabs = $('#myTab > li'), tabContentAverageWidth = 0/*tab > a標簽的寬度*/, minTabAverageWidth = 25/*margin-left:5,X按鈕寬度為20*/, zeroContentTabWidth = 35/*當tab > a標簽寬度為0時tab標簽對應的寬度是30px,外加上margin-left:5*/, aPaddingLeft = 10/*tab > a標簽的padding-left默認是10,當averageWidth< 35需要調整*/; averageWidth = parseInt(panelWidth/(tabs.length),10);// if(averageWidth >= zeroContentTabWidth){ tabContentAverageWidth = averageWidth - zeroContentTabWidth; /*35 > averageWidth >= 25*/ }else if(averageWidth >= minTabAverageWidth){ tabContentAverageWidth = 0; aPaddingLeft = averageWidth - minTabAverageWidth; //averageWidth < 25 }else{ tabContentAverageWidth = 0; aPaddingLeft = 0; } //tab頁簽名稱元素a標簽的寬度和padding-left。這個是在box-sizing:border-box。的情況下 tabs.find('>a').css({'width':(tabContentAverageWidth + aPaddingLeft),'padding-left':aPaddingLeft}); }
完整源碼,里面有一個測試例子

<!DOCTYPE html> <html lang="ch-cn"> <head> <meta charset="utf-8"> <script type="text/javascript" src='jquery-1.9.1.js'></script> <style type="text/css"> html,body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, p, blockquote, th, td{ margin: 0; padding:0; } *{ -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } ul, ol { margin-top: 0; margin-bottom: 10px; } a { color: #428bca; text-decoration: none; } .fa { display: inline-block; font-family: FontAwesome; font-style: normal; font-weight: normal; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } :before, :after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } /*這是一個字體,可以自定義一個x圖片*/ .fa-times:before { content: "\f00d"; } .tabbable { border: none; margin-bottom: 10px; } .nav { padding-left: 0; margin-bottom: 0; list-style: none; } .nav>li { position: relative; display: block; } .nav-tabs { margin-bottom: 0; margin-left: 0; border: 0; top: 2px; background-color: #f3f3f3; -webkit-box-shadow: 0 0 4px rgba(0,0,0,.3); -moz-box-shadow: 0 0 4px rgba(0,0,0,.3); box-shadow: 0 0 4px rgba(0,0,0,.3); border-bottom: 1px solid #ddd; } .nav-tabs>li { float: left; margin-bottom: 0px; margin-left: 5px; } .nav-tabs li i { position: relative; margin-left: 10px; cursor: pointer; } .nav-tabs li [class*=" fa-"], .nav-tabs li [class^="fa-"] { width: 1.25em; display: inline-block; text-align: center; } #myTab { height: 40px; overflow: hidden; } #myTab > li { height: 35px; overflow: hidden; margin-top: 5px; background: #dedede; background: rgba(0,0,0,0.05); color: #777; } #myTab > li.active, #myTab>li:hover, #myTab>li:focus { background-color: #fff; border-bottom-color: transparent; box-shadow: 0 -2px 3px 0 rgba(0,0,0,.15); } #myTab > li > a { position: relative; display: inline-block; white-space: nowrap; overflow: hidden; padding: 8px 0px 8px 10px; margin: 0 20px 0 0; border-top: 0px; box-shadow: none; background: transparent; line-height: 17px; border: 0; max-width: 108px; color: #777; } #myTab > li.active { border-top: 2px solid #2dc3e8; } #myTab li [class*=" fa-"], #myTab li [class^="fa-"] { vertical-align: middle; margin-left: 0px; position: absolute; right: 2px; margin-top: 10px; } .tab-content { background: none; padding: 0; padding-top: 5px; position: relative; } .tab-content > div{ display: none; } .tab-content > div.active{ display: block; } </style> </head> <body> <div class="tabbable" id="tabs" style="border:none;"> <!-- 頁面標簽列表 --> <ul class="nav nav-tabs" id="myTab"> </ul> <!-- 頁面內容列表,和頁面標簽列表對應 --> <div class="tab-content"> </div> </div> </body> <script type="text/javascript"> //切換tab頁的顯示 $(document).on('click','#myTab > li',function(e){ //清除原來顯示的tab頁 var oldTab = $("#myTab li.active").removeClass("active").find("a[data-toggle='tab']"); $(oldTab.attr("href")).removeClass("active"); //設置新的顯示tab頁 var newTab = $(this).addClass("active").find("a[data-toggle='tab']"); $(newTab.attr("href")).addClass("active"); refreshTabHistory(false/*isDelete*/,$(this).attr('id').substring(4)); }) //手動調用切換到要顯示的tab頁,當前的action只支持show //eg:$("#tab-0 a[data-toggle='tab']").tab("show"); $.fn.tab = function(action){ if(action == "show"){ $(this).parent().click(); } } var currentTabId = '';//當前焦點Tab //在非左側菜單欄彈出的tab頁也會用到該數據,如common.js中的pageForward函數 var pageCounter = 0; /* id: tab頁簽的html標簽ID屬性格式為"tab-"+id,內容容器的html標簽ID格式為"tab-content-"+id text: tab頁簽的顯示文本 url: 打開的iframe的url innerTab: 是否是內部彈出頁(打開的tab頁觸發添加新的tab頁),默認為undefined/false */ function addTab(id,text,url,innerTab) { //如果某個頁面已經打開,則切換到該頁顯示即可,不會新添加tab頁 if($('#myTab #tab-'+id).length > 0){ $('#myTab #tab-' + id + ' a').tab('show'); }else{ var tab_id = "tab-" + id, tab_content_id = "tab-content-"+id; //添加tab頁簽 $("#myTab > li").removeClass("active"); $("#myTab").append("<li id='" + tab_id + "' class='active'><a data-toggle='tab' href='#" + tab_content_id + "'>" + text + "</a>" + ("<i class='fa fa-times' onclick='deleteTab(\"" + id + "\")'></i>") + "</li>"); //添加新的內容顯示 $(".tab-content > div").removeClass("active"); $(".tab-content").append("<div id='"+ tab_content_id +"' class='active'>" + "<iframe id='iframepage" + (pageCounter++) + "' name='iframepage" + (pageCounter++) + "' width='100%' frameborder='0' scrolling='no' src='" + url + "'></iframe></div>"); } //刷新切換tab的歷史記錄 refreshTabHistory(false/*isDelete*/,id); //重新設置tab頁簽的寬度 refreshWidth(); } //參數id為tab的標志,但是並不是tab頁的id屬性,真正的id屬性值是"tab-"+id function deleteTab(id){ var tabJQ = $("#tab-"+id), tabContentJQ = $("#tab-content-" + id); if(!tabJQ.hasClass("active")){ tabJQ.remove(); tabContentJQ.remove(); refreshTabHistory(true/*isDelete*/,id); }else{ tabJQ.remove(); tabContentJQ.remove(); refreshTabHistory(true/*isDelete*/,id); $('#tab-' + currentTabId + ' > a').tab('show').click(); } refreshWidth(); } //關閉當前tab頁的快速方法 function closeCurrentTab(){ deleteTab(currentTabId); } /* 刷新頁簽切換歷史 isdelete: 是否是刪除tab頁簽,true:是,false:否 curTabId:要處理的tab頁簽的id,tab頁簽html標簽元素的ID屬性格式為"tab-"+curTabId */ function refreshTabHistory(isdelete,curTabId){ if(!refreshTabHistory.histoty){ //用來記錄用戶點擊tab的歷史 refreshTabHistory.histoty = []; } var index = 0, leng = refreshTabHistory.histoty.length; //查找傳入的tab頁簽在歷史記錄中的位置 for(; index < leng; index++){ if(refreshTabHistory.histoty[index] == curTabId){ break; } } //如果是刪除頁簽,直接在歷史記錄中刪除即可,歷史記錄的其他頁簽的順序不變 if(isdelete){ refreshTabHistory.histoty.splice(index,1); //如果是新增頁簽,先保證歷史記錄中沒有改頁簽(有就刪掉),然后將新增的頁簽放在歷史記錄的最后面(即該頁簽為最新) }else{ if(index < leng) { refreshTabHistory.histoty.splice(index,1); } refreshTabHistory.histoty.push(curTabId); } currentTabId = refreshTabHistory.histoty[refreshTabHistory.histoty.length - 1]; } //刷新重置tab頁簽的寬度 function refreshWidth(){ var panelWidth = $('#myTab').width() - 20/*可能存在的滾動條寬度*/, tabs = $('#myTab > li'), tabContentAverageWidth = 0/*tab > a標簽的寬度*/, minTabAverageWidth = 25/*margin-left:5,X按鈕寬度為20*/, zeroContentTabWidth = 35/*當tab > a標簽寬度為0時tab標簽對應的寬度是30px,外加上margin-left:5*/, aPaddingLeft = 10/*tab > a標簽的padding-left默認是10,當averageWidth< 35需要調整*/; averageWidth = parseInt(panelWidth/(tabs.length),10);// if(averageWidth >= zeroContentTabWidth){ tabContentAverageWidth = averageWidth - zeroContentTabWidth; /*35 > averageWidth >= 25*/ }else if(averageWidth >= minTabAverageWidth){ tabContentAverageWidth = 0; aPaddingLeft = averageWidth - minTabAverageWidth; //averageWidth < 25 }else{ tabContentAverageWidth = 0; aPaddingLeft = 0; } //tab頁簽名稱元素a標簽的寬度和padding-left。這個是在box-sizing:border-box。的情況下 tabs.find('>a').css({'width':(tabContentAverageWidth + aPaddingLeft),'padding-left':aPaddingLeft}); } //測試代碼 for(var i = 0; i < 11; i++){ addTab(i,"test" + i,"http://www.baidu.com"); } </script> </html>