zoukankan      html  css  js  c++  java
  • Bootstrap tabs 源码分析

    前言:

    阅读建议:去github下载一个完整dom然后把,本篇代码复制进去然后运行就好了以地址

    tab组件是非常简单的一种组件,因为这是一个系列,所以就顺便看了,其实它写的这个还算不错的,很有条例,也算是插件的规范写法,研究一下也不错

    /* ========================================================================
     * Bootstrap: tab.js v3.3.7
     * http://getbootstrap.com/javascript/#tabs
     * ========================================================================
     * Copyright 2011-2016 Twitter, Inc.
     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
     * ======================================================================== */
    
    
    +function ($) {
      'use strict';
    
      // TAB CLASS DEFINITION
      // ====================
    
      var Tab = function (element) {//传入一个选择器
        // jscs:disable requireDollarBeforejQueryAssignment
        this.element = $(element)
        // jscs:enable requireDollarBeforejQueryAssignment
      }
    
      Tab.VERSION = '3.3.7'
    
      Tab.TRANSITION_DURATION = 150
    
      Tab.prototype.show = function () {
        var $this    = this.element//把a标签赋值给$this
        var $ul      = $this.closest('ul:not(.dropdown-menu)')//closest 仅供插件开发者使用的方法,jquery1.7后就不建议使用了                冲a标签处向上寻找ul包裹元素
        var selector = $this.data('target')//取出target
    
        if (!selector) {//没有target的话,
          selector = $this.attr('href')//把当前触发的a标签的某点,付给他
          selector = selector && selector.replace(/.*(?=#[^s]*$)/, '') // strip for ie7
        }
    
        if ($this.parent('li').hasClass('active')) return//发现已经时active了,则返回,没有泽继续向下执行
    
        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]
        })
    
        $previous.trigger(hideEvent)
        $this.trigger(showEvent)
    
        if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
    
        var $target = $(selector)
    
        this.activate($this.closest('li'), $ul)
        this.activate($target, $target.parent(), function () {
          $previous.trigger({
            type: 'hidden.bs.tab',
            relatedTarget: $this[0]
          })
          $this.trigger({
            type: 'shown.bs.tab',
            relatedTarget: $previous[0]
          })
        })
      }
    
      Tab.prototype.activate = function (element, container, callback) {
        var $active    = container.find('> .active')//得到先前li.active 
        var transition = callback
          && $.support.transition
          && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
    
        function next() {
          $active
            .removeClass('active')//把原来的active去除
            .find('> .dropdown-menu > .active')
              .removeClass('active')//在把menu下拉菜单下的active去掉
            .end()//退到上一层
            .find('[data-toggle="tab"]')//寻找他下面的a标签,
              .attr('aria-expanded', false)//aria-expanded 属性赋值为false
    
          element
            .addClass('active')//给当前触发的li负上active
            .find('[data-toggle="tab"]')//找到地下a标签
              .attr('aria-expanded', true)//赋值为true
    
          if (transition) {//有毁掉函数的时候
            element[0].offsetWidth // reflow for transition
            element.addClass('in')
          } else {
            element.removeClass('fade')
          }
    
          if (element.parent('.dropdown-menu').length) {//父元素时.dropdown-menu时执行
            element
              .closest('li.dropdown')
                .addClass('active')
              .end()
              .find('[data-toggle="tab"]')
                .attr('aria-expanded', true)
          }
    
          callback && callback()
        }
    
        $active.length && transition ?
          $active
            .one('bsTransitionEnd', next)
            .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
          next()
    
        $active.removeClass('in')
      }
    
    
      // TAB PLUGIN DEFINITION
      // =====================
    
      function Plugin(option) {
        return this.each(function () {//加each是jquery插件的标配,意为选中多个dom时挨个处理
          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   自动给你初始化了,这样就可以不用写js代码了
      // ============
    
      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)//pill这个是给胶囊导航用的,其实tab和pill原理都一样,只是名字不一样而已
    
    }(jQuery);
  • 相关阅读:
    Realtime crowdsourcing
    maven 常用插件汇总
    fctix
    sencha extjs4 command tools sdk
    首次吃了一颗带奶糖味的消炎药,不知道管用不
    spring mvc3 example
    ubuntu ati driver DO NOT INSTALL recommand driver
    yet another js editor on windows support extjs
    how to use springsource tools suite maven3 on command
    ocr service
  • 原文地址:https://www.cnblogs.com/xiaobie123/p/5997621.html
Copyright © 2011-2022 走看看