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);
  • 相关阅读:
    运动检测技术在数字化监控中的实现和应用(作者:何峻峰)
    EF BB BF的问题
    理解HTTP幂等性
    FusionCharts 分类以及各个属性 参数列表
    SQL语言包含的四个部分
    Inno Setup (安装程序制作)
    PowerDesigner 参照完整性约束(级联删除)
    java默认语法、EL、JSTL表达式,JSTL和struts Tag标签的使用总结
    修改PowerDesigner中create index的bug
    神奇的java Object ( Object和数组关系) Object数据互转
  • 原文地址:https://www.cnblogs.com/xiaobie123/p/5997621.html
Copyright © 2011-2022 走看看