多iframe使用tab標簽方式添加、刪除、切換的處理實例


  緊接着上一篇隨筆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>
View Code

  標簽內容如下  


<
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>
View Code

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM