溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何以BootStrap Tab為例寫一個前端組件

發(fā)布時間:2021-08-13 12:20:14 來源:億速云 閱讀:235 作者:小新 欄目:web開發(fā)

這篇文章將為大家詳細講解有關(guān)如何以BootStrap Tab為例寫一個前端組件,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

實現(xiàn)效果:

如何以BootStrap Tab為例寫一個前端組件

原生的Bootstrap-tab組件主要有html,css組成,開發(fā)者使用時,需要寫很多代碼,不易于使用,對bootstrap-tab封裝后,可以更方便地使用,同時提供關(guān)閉、增加tab頁、指定當(dāng)前選中頁、即使加載等功能,這樣組件可以適配更多的場景。

其中官網(wǎng)一段實例代碼是:

<ul id="myTab" class="nav nav-tabs">
  <li class="active"><a href="#home" rel="external nofollow" data-toggle="tab">
      菜鳥教程</a>
  </li>
  <li><a href="#ios" rel="external nofollow" data-toggle="tab">iOS</a></li>
  <li class="dropdown">
    <a href="#" rel="external nofollow" id="myTabDrop1" class="dropdown-toggle"
      data-toggle="dropdown">Java <b class="caret"></b>
    </a>
    <ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop1">
      <li><a href="#jmeter" rel="external nofollow" tabindex="-1" data-toggle="tab">
          jmeter</a>
      </li>
      <li><a href="#ejb" rel="external nofollow" tabindex="-1" data-toggle="tab">
          ejb</a>
      </li>
    </ul>
  </li>
</ul>
<div id="myTabContent" class="tab-content">
  <div class="tab-pane fade in active" id="home">
    <p>菜鳥教程是一個提供最新的web技術(shù)站點,本站免費提供了建站相關(guān)的技術(shù)文檔,幫助廣大web技術(shù)愛好者快速入門并建立自己的網(wǎng)站。菜鳥先飛早入行——學(xué)的不僅是技術(shù),更是夢想。</p>
  </div>
  <div class="tab-pane fade" id="ios">
    <p>iOS 是一個由蘋果公司開發(fā)和發(fā)布的手機操作系統(tǒng)。最初是于 2007 年首次發(fā)布 iPhone、iPod Touch 和 Apple
      TV。iOS 派生自 OS X,它們共享 Darwin 基礎(chǔ)。OS X 操作系統(tǒng)是用在蘋果電腦上,iOS 是蘋果的移動版本。</p>
  </div>
  <div class="tab-pane fade" id="jmeter">
    <p>jMeter 是一款開源的測試軟件。它是 100% 純 Java 應(yīng)用程序,用于負載和性能測試。</p>
  </div>
  <div class="tab-pane fade" id="ejb">
    <p>Enterprise Java Beans(EJB)是一個創(chuàng)建高度可擴展性和強大企業(yè)級應(yīng)用程序的開發(fā)架構(gòu),部署在兼容應(yīng)用程序服務(wù)器(比如 JBOSS、Web Logic 等)的 J2EE 上。
    </p>
  </div>
</div>
<script>
  $(function () {
    $('#myTab li:eq(1) a').tab('show');
  });
</script>

那么如何封裝或者開發(fā)一個組件呢?

組件開發(fā)步驟

Step1:結(jié)構(gòu)化靜態(tài)代碼,梳理核心的問題

在組件開發(fā)流程中,可能拿到前端設(shè)計的靜態(tài)代碼(html+css的組合),這時候要拆解代碼結(jié)構(gòu),使得結(jié)構(gòu)能夠模板化。其次梳理核心問題,bootstrap-tab組件化之后,應(yīng)該能夠動態(tài)加載tab內(nèi)容,這個可以通過jquery.load方法解決,這樣可以做到主頁面和子頁面解耦。

讀懂了靜態(tài)代碼,理解了結(jié)構(gòu)和核心問題就可以寫代碼了,首先搭建組件的架子。

Step2:組件骨架

/**
 * Bootstrap tab組件封裝
 * @author billjiang qq:475572229
 * @created 2017/7/24
 *
 */
(function ($, window, document, undefined) {
  'use strict';
  var pluginName = 'tabs';
  //入口方法
  $.fn[pluginName] = function (options) {
    var self = $(this);
    if (this == null)
      return null;
    var data = this.data(pluginName);
    if (!data) {
      data = new BaseTab(this, options);
      self.data(pluginName, data);
    }
    return data;
  };
  var BaseTab = function (element, options) {
    this.$element = $(element);
    this.options = $.extend(true, {}, this.default, options);
    this.init();
  }
  //默認(rèn)配置
  BaseTab.prototype.default = {
  }
  //結(jié)構(gòu)模板
  BaseTab.prototype.template = {
  }
  //初始化
  BaseTab.prototype.init = function () {
  } 
})(jQuery, window, document)

搭建了以上組件的骨架,并對組件命名為tabs,這樣就可以通過$("#tab-container").data("tabs")獲取組價的方法和屬性。在入口方法中,會將初始化后的對象緩存到頁面html中,這樣可以避免重復(fù)創(chuàng)建對象。一些經(jīng)典的開源前端組件都是這樣寫法,比如Bootstrap-treeview,大家有時間可以看看它的源碼。

以上的寫法使用原型鏈的寫法。定義了默認(rèn)配置,結(jié)構(gòu)模板,初始化入口。

編寫代碼

在組件的代碼骨架里,填充模板代碼,這里使用占位符{0},{1}等表示外部傳入的變量,然后在init方法中校驗外部傳入數(shù)據(jù)的合法性,然后構(gòu)建組件,并且綁定關(guān)閉事件、點擊事件。

在開發(fā)前端組件的時候,往往不知道默認(rèn)參數(shù)應(yīng)該有什么,可以在開發(fā)的時候,用到就加上去,這里加了兩個默認(rèn)參數(shù),一個showIndex是默認(rèn)顯示的tab頁索引,一個loadAlltab是否一次性把所有的頁面數(shù)據(jù)加載完。

具體的邏輯請看下面的代碼: 

//默認(rèn)配置
  BaseTab.prototype.default = {
    showIndex: 0, //默認(rèn)顯示頁索引
    loadAll: true,//true=一次全部加在頁面,false=只加在showIndex指定的頁面,其他點擊時加載,提高響應(yīng)速度
  }
  //結(jié)構(gòu)模板
  BaseTab.prototype.template = {
    ul_nav: '<ul class="nav nav-tabs"></ul>',
    ul_li: '<li><a href="#{0}" rel="external nofollow" data-toggle="tab"><span>{1}</span></a></li>',
    ul_li_close: '<i class="fa fa-remove closeable" title="關(guān)閉"></i>',
    div_content: '<div class="tab-content"></div>',
    div_content_panel: '<div class="tab-pane fade" id="{0}"></div>'
  }
  //初始化
  BaseTab.prototype.init = function () {
    if (!this.options.data || this.options.data.length == 0) {
      console.error("請指定tab頁數(shù)據(jù)");
      return;
    }
    //當(dāng)前顯示的顯示的頁面是否超出索引
    if (this.options.showIndex < 0 || this.options.showIndex > this.options.data.length - 1) {
      console.error("showIndex超出了范圍");
      //指定為默認(rèn)值
      this.options.showIndex = this.default.showIndex;
    }
    //清除原來的tab頁
    this.$element.html("");
    this.builder(this.options.data);
  }
  //使用模板搭建頁面結(jié)構(gòu)
  BaseTab.prototype.builder = function (data) {
    var ul_nav = $(this.template.ul_nav);
    var div_content = $(this.template.div_content);
    for (var i = 0; i < data.length; i++) {
      //nav-tab
      var ul_li = $(this.template.ul_li.format(data[i].id, data[i].text));
      //如果可關(guān)閉,插入關(guān)閉圖標(biāo),并綁定關(guān)閉事件
      if (data[i].closeable) {
        var ul_li_close = $(this.template.ul_li_close);
        ul_li.find("a").append(ul_li_close);
        ul_li.find("a").append("&nbsp;");
      }
      ul_nav.append(ul_li);
      //div-content
      var div_content_panel = $(this.template.div_content_panel.format(data[i].id));
      div_content.append(div_content_panel);
    }
    this.$element.append(ul_nav);
    this.$element.append(div_content);
    this.loadData();
    this.$element.find(".nav-tabs li:eq(" + this.options.showIndex + ") a").tab("show");
  }
  BaseTab.prototype.loadData = function () {
    var self = this;
    //tab點擊即加載事件
    //設(shè)置一個值,記錄每個tab頁是否加載過
    this.stateObj = {};
    var data = this.options.data;
    //如果是當(dāng)前頁或者配置了一次性全部加載,否則點擊tab頁時加載
    for (var i = 0; i < data.length; i++) {
      if (this.options.loadAll || this.options.showIndex == i) {
        if (data[i].url) {
          $("#" + data[i].id).load(data[i].url);
          this.stateObj[data[i].id] = true;
        } else {
          console.error("id=" + data[i].id + "的tab頁未指定url");
          this.stateObj[data[i].id] = false;
        }
      } else {
        this.stateObj[data[i].id] = false;
        (function (id, url) {
          self.$element.find(".nav-tabs a[href='#" + id + "']").on('show.bs.tab', function () {
            if (!self.stateObj[id]) {
              $("#" + id).load(url);
              self.stateObj[id] = true;
            }
          });
        }(data[i].id, data[i].url))
      }
    }
    //關(guān)閉tab事件
    this.$element.find(".nav-tabs li a i.closeable").each(function (index, item) {
      $(item).click(function () {
        var href = $(this).parents("a").attr("href").substr(1);
        $(this).parents("li").remove();
        $("#" + href).parent().remove();
      })
    });
  }

測試

編寫一個前端界面,測試組件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Tab組件</title>
</head>
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" rel="external nofollow" >
<link rel="stylesheet" href="font-awesome/css/font-awesome.min.css" rel="external nofollow" >
<link rel="stylesheet" href="../css/bootstrap-tab.css" rel="external nofollow" >
<body>
<div id="tabContainer"></div>
</body>
<script src="jquery/jquery-1.8.3.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
<script src="../js/bootstrap-tab.js"></script>
<script>
  $("#tabContainer").tabs({
    data: [{
      id: 'home',
      text: '百度一下',
      url: "tab_first.html",
      closeable:true
    }, {
      id: 'admineap',
      text: 'AdminEAP',
      url: "tab_second.html"
    }, {
      id: 'edit',
      text: '編輯人員',
      url: "tab_content.html",
      closeable:true
    }],
    showIndex:1,
    loadAll:false
  })
</script>
</html>

通過配置各種參數(shù),看看組件是否滿足了預(yù)期的要求。

如何以BootStrap Tab為例寫一個前端組件

擴展



組件在使用的過程中還會遇到各種問題,或者各種需求,比如新增一個tab頁面,比如獲取當(dāng)前tab的ID或index,這是可以在代碼中按需擴展。

//新增一個tab頁
  BaseTab.prototype.addTab=function (obj) {
    //nav-tab
    var ul_li = $(this.template.ul_li.format(obj.id, obj.text));
    //如果可關(guān)閉,插入關(guān)閉圖標(biāo),并綁定關(guān)閉事件
    if (obj.closeable) {
      var ul_li_close = $(this.template.ul_li_close);
      ul_li.find("a").append(ul_li_close);
      ul_li.find("a").append("&nbsp;");
    }
    this.$element.find(".nav-tabs").append(ul_li);
    //div-content
    var div_content_panel = $(this.template.div_content_panel.format(obj.id));
    this.$element.find(".tab-content").append(div_content_panel);
    $("#" + obj.id).load(obj.url);
    this.stateObj[obj.id] = true;
    if(obj.closeable){
      this.$element.find(".nav-tabs li a[href='#" + obj.id + "'] i.closeable").click(function () {
        var href = $(this).parents("a").attr("href").substr(1);
        $(this).parents("li").remove();
        $("#" + href).parent().remove();
      })
    }
    this.$element.find(".nav-tabs a[href='#" + obj.id + "']").tab("show");
  }
  //根據(jù)id設(shè)置活動tab頁
  BaseTab.prototype.showTab=function (tabId) {
    this.$element.find(".nav-tabs li a[href='#" + tabId + "']").tab("show");
  }
  //獲取當(dāng)前活動tab頁的ID
  BaseTab.prototype.getCurrentTabId=function () {
    var href=this.$element.find(".nav-tabs li.active a").attr("href");
    href=href.substring(1);
    return href;
  }

關(guān)于“如何以BootStrap Tab為例寫一個前端組件”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI