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 ,變為顯示 }

 

 

文實例為大家介紹實現tab選項卡的應用,此插件相對比較簡單,具體內容如下
源碼文件:
tab.js

實現原理:
1、單擊一個元素時,首先將原來高亮的元素取消
2、然后給被單擊元素進行高亮
3、如果單擊元素是下拉框中某個選項,則選中本身,還要選中下拉框
5、如果定義了動畫,先執行動畫,然后回調

源碼分析:
1、Show方法,是在單擊一個元素的時候觸發,會觸發如下四個事件
  1.1、Hiden.bs.tab:隱藏上一個元素
  1.2、Show.bs.tab:顯示當前元素
  1.3、Hideen.bs.tab:隱藏上一個元素完成
  1.4、Shown.bs.tab:顯示當前元素完成
  1.5、Hiden/show事件源碼:

?
1
2
3
4
5
6
7
var $previous = $ul.find( '.active:last a' )
  var hideEvent = $.Event( 'hide.bs.tab' , {
  relatedTarget: $ this [0]
  })
  var showEvent = $.Event( 'show.bs.tab' , {
  relatedTarget: $previous[0]
})

2、Active:激活當前對象
  2.1、對導航元素增加aria-expanded屬性,標記此元素是否處於展開狀態
  2.2、利用reflow機制,用獲取offsetWidth屬性來實現部分重繪


免責聲明!

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



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