bootstrap插件學習-bootstrap.tab.js


先看bootstrap-tab.js的結構

var Tab = function ( element ) {} //構造器
Tab.prototype ={} //構造器的原型
$.fn.tab = function ( option ){} //jQuery原型上自定義的方法
$.fn.tab.Constructor = Tab //重寫jQuery原型上的自定義方法的構造器名
$(function () {}) //初始化

HTML結構

<ul class="nav nav-tabs">
    <li class="active"><a href="#home" data-toggle="tab" >首頁</a></li>
      <li><a href="#profile" data-toggle="tab">介紹</a></li>
      <li><a href="#messages" data-toggle="tab">消息</a></li>
      <li><a href="#settings" data-toggle="tab">設置</a></li>

</ul>

<div class="tab-content">
  <div class="tab-pane active" id="home">1</div>
  <div class="tab-pane" id="profile">2</div>
  <div class="tab-pane" id="messages">3</div>
  <div class="tab-pane" id="settings">4</div>
</div>

先從初始化開始

/*
  * 初始化
  * 給擁有data-toggle='tab'屬性的標簽綁定click事件
  * */
  $(function () {
    $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
      e.preventDefault()
      $(this).tab('show')//向jQuery原型方法tab傳入參數show,應該執行show方法。this為擁有data-toggle屬性的a標簽對象
    })
  })

讓body監聽a標簽的click事件,並且阻止其冒泡,調用了jQuery的原型方法tab。

 /*
  * jQuery原型上自定義的方法
  * */
  $.fn.tab = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('tab')
      if (!data) $this.data('tab', (data = new Tab(this)))//實例化構造器
      if (typeof option == 'string') data[option]()//執行option的方法
    })
  }

這個結構跟之前的幾個插件差不多,不過最后它是執行了show方法的,進入構造器

var Tab = function ( element ) {
    this.element = $(element)
  }

將對象封裝成構造器實例的一個屬性。接下來我們執行show方法

show: function () {
      var $this = this.element
        , $ul = $this.closest('ul:not(.dropdown-menu)')//找到最近的不是dropdown類的ul元素
        , selector = $this.attr('data-target')
        , previous
        , $target
      //獲取與a標簽對應的內容id
      if (!selector) {
        selector = $this.attr('href')
        selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
      }
      //如果一直點擊自己,這句之后的代碼將不執行
      if ( $this.parent('li').hasClass('active') ) return

      previous = $ul.find('.active a').last()[0]//獲得擁有active類的原生a標簽對象,即上一次高亮的節點

      $this.trigger({
        type: 'show'
      , relatedTarget: previous
      })

      $target = $(selector)//獲得內容節點的jQueryDOM對象

      this.activate($this.parent('li'), $ul)//tab頁切換


      this.activate($target, $target.parent(), function () {
        $this.trigger({
          type: 'shown'
        , relatedTarget: previous
        })

      })

根據標簽a的data-target屬性或是其href找到對應的id的dom節點。最后我們執行了兩次activate方法,其實大概猜的出來,一個方法控制a標簽的高亮顯示,另一個控制dom節點的顯示與隱藏

/*
    * 控制顯示與隱藏
    * 參數主要形式是這樣的,一個是可以擁有active類的元素,另一個是其父類。
    * 先找到父類下來所有擁有active類的節點,刪除它們的active,並將當前節點,也就是第一個參數加上active類。
    *
    * */
  , activate: function ( element, container, callback) {

      var $active = container.find('> .active')
        , transition = callback
            && $.support.transition//需要引入其他js文件,這里沒有引入。
            && $active.hasClass('fade')
      console.log($active[0])
      function next() {
        $active
          .removeClass('active')
          .find('> .dropdown-menu > .active')
          .removeClass('active')

        element.addClass('active')

        if (transition) {
          element[0].offsetWidth // reflow for transition
          element.addClass('in')
        } else {
          element.removeClass('fade')
        }

        if ( element.parent('.dropdown-menu') ) {
          element.closest('li.dropdown').addClass('active')
        }

        callback && callback()
      }

      transition ?
        $active.one($.support.transition.end, next) :
        next()

      $active.removeClass('in')
    }

邏輯比較簡單,一般遇到一個顯示其他同類不顯示的情況,基本都是這一套方法,增刪class來達到要求。但對於jQuery操作css完成class切換與javascript原生方法相比,哪個效率會更好一點呢?也希望有經驗的園友給予解答。

另外是部分css,表現了兩塊active類的作用

/*tab頁切換時的active作用*/
.nav-tabs > .active > a,
.nav-tabs > .active > a:hover,
.nav-tabs > .active > a:focus {
  color: #555555;
  cursor: default;
  background-color: #ffffff;
  border: 1px solid #ddd;
  border-bottom-color: transparent;//將底部邊框變透明
}

/*dom*/

.tab-content > .tab-pane,
.pill-content > .pill-pane {
  display: none; //原來為隱藏
}

.tab-content > .active,
.pill-content > .active {
  display: block; //加入active ,變為顯示
}

 內容不多,時間剛好,以上是我的一點讀碼體會,如有錯誤,請指出,大家共通學習。 

 

 

 

 

 

 


免責聲明!

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



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