bootstrap之tab.js源码解读

# tab.js所须要的html结构以下html

<!-- Nav tabs -->
<ul class="nav nav-tabs" id="myTabs">
  <li class="active">
    <a href="#home">Home</a>
  </li>
  <li>
    <a href="#profile">Profile</a>
  </li>
  <li>
    <a href="#messages">Messages</a>
  </li>
  <li>
    <a href="#settings">Settings</a>
  </li>
</ul>

<!-- Tab panes -->
<div class="tab-content">
  <div class="tab-pane active" id="home">home</div>
  <div class="tab-pane" id="profile">profile</div>
  <div class="tab-pane" id="messages">messages</div>
  <div class="tab-pane" id="settings">settings</div>
</div>

# 核心代码说明api

10.jpg

# html结构须要注意缓存

1.a标签上的href的值要和tab-pane的id值同样,或者给a标签添加data-tagert属性而且和tab-pane的id值同样闭包

2.若是a标签上没有data-toggle="tab",就须要以下代码来实现tab切换功能ide

$('#myTabs a').click(function (e) {
  e.preventDefault()
  $(this).tab('show') // 
})
// 若是a标签上有data-toggle="tab"属性,就不须要任何的js代码,只须要引入tab.js便可

# js代码以下函数

;+(function ($) {
  'use strict'

  // TAB CLASS DEFINITION
  // ====================

  var Tab = function (element) {
    // 添加实例属性element
    this.element = $(element)
  }
  // 添加静态属性
  Tab.VERSION = '3.3.7'

  //tab原型show函数
  Tab.prototype.show = function () {
    // 获取当前点击的元素 该元素为li下面的a元素
    var $this = this.element
    var $ul = $this.closest('ul:not(.dropdown-menu)')
    var selector = $this.data('target')
    // 若是经过target属性,没有获取到值,就获取href值
    if (!selector) {
      selector = $this.attr('href') // 获取href属性,后面须要经过href值来获取tab-pane元素
      //正则替换部分:任意个.不对#号记录,以任意非空白字符结束。使用空字符串替换.#号前面字符
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
    }
    //若是当前li已经触发,返回
    if ($this.parent('li').hasClass('active')) return

    var $previous = $ul.find('.active:last a') //选择最后active的后代元素 a

    // 获取目标tab-pane元素
    var $target = $(selector)
    // tab的显示和隐藏
    this.activate($this.closest('li'), $ul)
    // tab-pane的显示和隐藏
    this.activate($target, $target.parent())
  }

  Tab.prototype.activate = function (element, container, callback) {
    // 这个$active是li标签(不是里面的a标签)
    var $active = container.find('> .active') //container后代active元素
    //下一个
    function next() {
      $active.removeClass('active') //移除active类

      element.addClass('active') //在传入元素上增长active类

      callback && callback() //若callback为true,则把callback当作函数执行;相似于if(callback){callback()}
    }
    $active.length && next()
  }

  // TAB PLUGIN DEFINITION
  // =====================

  function Plugin(option) {
    // 闭包  将option值提早植入进来
    return this.each(function () {
      var $this = $(this)
      var data = $this.data('bs.tab') //先取一下bs.tab   这一步是为了缓存Tab对象的,这是必须的,不可能点击一下tab就new Tab(this),
      if (!data) {
        $this.data('bs.tab', (data = new Tab(this))) //若是没有data,那么将点击的a标签传入tab,而后把Tab对象赋值给data
      }
      if (typeof option == 'string') data[option]() //若是传入的是字符串,则执行相应的方法
    })
  }

  var old = $.fn.tab

  $.fn.tab = Plugin
  $.fn.tab.Constructor = Tab

  // TAB NO CONFLICT
  // ===============
  //防冲突代码,为了规范,应该加上
  $.fn.tab.noConflict = function () {
    $.fn.tab = old
    return this
  }

  // TAB DATA-API
  // ============
  var clickHandler = function (e) {
    e.preventDefault() //阻止事件冒泡
    Plugin.call($(this), 'show')
  }

  /* $(document)
    .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
    .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) */

  // 使用了属性选择器
  $(document).on('click', '[data-toggle="tab"]', clickHandler)
})(jQuery)

# 核心代码说明this

11.jpg

这就是为何若是a标签上有data-toggle="tab"属性,就不须要任何js代码,若是没有,就须要本身来调用spa


12.jpg

tab切换的原理就是,让以前active的li元素变成非active便可,让当前点击的元素变成active便可,tab-pane跟随tab一块儿变化prototype

# 手动调用htm

<script>
  $('#myTabs a').click(function (e) {
    e.preventDefault()
    $(this).tab('show')
  })
</script>
相关文章
相关标签/搜索