zoukankan      html  css  js  c++  java
  • 多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=" 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=" 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

      

  • 相关阅读:
    查看内置命令和非内置命令帮助的几种方法(man、help、info)
    手写js的insertAfter
    Java 单链表简单实现
    StudentMain控屏后如何关闭
    python3 twisted问题
    python3 you-get
    数据库方言(这是啥玩意儿?)
    vi/vim用法
    sublime text3
    数据库命令大全(也不是很全哈)
  • 原文地址:https://www.cnblogs.com/chuaWeb/p/5052053.html
Copyright © 2011-2022 走看看