前言:

阅读建议:去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);

Bootstrap tabs 源码分析的更多相关文章

  1. Bootstrap Tooltip源码分析

    /* ======================================================================== * Bootstrap: tooltip.js ...

  2. Bootstrap popover源码分析

    /* ======================================================================== * Bootstrap: popover.js ...

  3. Bootstrap Dropdown 源码分析

    /* ======================================================================== * Bootstrap: dropdown.js ...

  4. Bootstrap button源码分析

    /* ======================================================================== * Bootstrap: button.js v ...

  5. BOOtstrap源码分析之 tooltip、popover

    一.tooltip(提示框) 源码文件: Tooltip.jsTooltip.scss 实现原理: 1.获取当前要显示tooltip的元素的定位信息(top.left.bottom.right.wid ...

  6. Bootstrap源码分析之dropdown

    源码分析: Dropdowns.scss:下拉框模块 Javascripts/bootstrap/dropdown.js:实现下拉框响应 实现功能及原理: 下拉选项卡,默认不能实现显示选中项的功能 原 ...

  7. Appium Server源码分析之作为Bootstrap客户端

    Appium Server拥有两个主要的功能: 它是个http服务器,它专门接收从客户端通过基于http的REST协议发送过来的命令 他是bootstrap客户端:它接收到客户端的命令后,需要想办法把 ...

  8. Appium Android Bootstrap源码分析之启动运行

    通过前面的两篇文章<Appium Android Bootstrap源码分析之控件AndroidElement>和<Appium Android Bootstrap源码分析之命令解析 ...

  9. Appium Android Bootstrap源码分析之命令解析执行

    通过上一篇文章<Appium Android Bootstrap源码分析之控件AndroidElement>我们知道了Appium从pc端发送过来的命令如果是控件相关的话,最终目标控件在b ...

随机推荐

  1. 解决 python No migrations to apply 无法生成表

    第一步: 删除该app名字下的migrations文件. 第二步: 进入数据库,找到django_migrations的表,删除该app名字的所有记录. delete from django_migr ...

  2. 看完这篇 你就能完全操作git 远程分支的增、删、改、查了

    最近项目中又用到了git所以在此总结一番,这篇主要针对的是怎么创建远程分支,如何删除远程分支. 首先,如何创建远程分支.将一系列前期准备工作准备完成后(创建\添加ssh): 在终端键入 git bra ...

  3. PHP:Mysqli 基础类

    文章来源:http://www.cnblogs.com/hello-tl/p/7592594.html <?php /** * __construct($Mysql_config) 构造函数 $ ...

  4. Python随笔day01

    环境变量的配置: 配置Python的安装目录到path变量中,例如C:\Python37 标识符的命名规则: 变量名只能以数字,字母,下划线组成. 不能以数字开头,保留字不能被使用. 建议使用下划线分 ...

  5. 对Spring框架的理解(转)

    ①  spring框架是一个开源而轻量级的框架,是一个IOC和AOP容器 ② spring的核心就是控制反转(IOC)和面向切面编程(AOP) ③  控制反转(IOC):是面向对象编程中的一种设计原则 ...

  6. 九度oj 题目1075:斐波那契数列

    题目1075:斐波那契数列 时间限制:5 秒 内存限制:32 兆 特殊判题:否 提交:3641 解决:2100 题目描述: 编写一个求斐波那契数列的递归函数,输入n值,使用该递归函数,输出如样例输出的 ...

  7. 详解js变量声明提升

    之前一直觉会认为javascript代码执行是由上到下一行行执行的.自从看了<你不知道的JS>后发现这个观点并不完全正确.先来给大家举一个书本上的的例子: var a='hello wor ...

  8. 使用mysql-proxy 快速实现mysql 集群 读写分离

    目前较为常见的mysql读写分离分为两种: 1. 基于程序代码内部实现:在代码中对select操作分发到从库:其它操作由主库执行:这类方法也是目前生产环境应用最广泛,知名的如DISCUZ X2.优点是 ...

  9. [TyvjP1050] 最长公共子序列(DP)

    传送门 f[i][j] 表示第 1 个串匹配到第 i 位,第 2 个串匹配到第 j 位的答案. f[i][j] = max(f[i - 1][j], f[i][j - 1])    (a[i] != ...

  10. MT6753/MT6755 呼吸灯功能添加

    利用mtk pmic自带的呼吸灯模式: 主要修改代码: kernel-3.10/drivers/misc/mediatek/leds/mt6755/leds.c   int mt_brightness ...