前言:

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

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

  1. /* ========================================================================
  2. * Bootstrap: tab.js v3.3.7
  3. * http://getbootstrap.com/javascript/#tabs
  4. * ========================================================================
  5. * Copyright 2011-2016 Twitter, Inc.
  6. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  7. * ======================================================================== */
  8.  
  9. +function ($) {
  10. 'use strict';
  11.  
  12. // TAB CLASS DEFINITION
  13. // ====================
  14.  
  15. var Tab = function (element) {//传入一个选择器
  16. // jscs:disable requireDollarBeforejQueryAssignment
  17. this.element = $(element)
  18. // jscs:enable requireDollarBeforejQueryAssignment
  19. }
  20.  
  21. Tab.VERSION = '3.3.7'
  22.  
  23. Tab.TRANSITION_DURATION = 150
  24.  
  25. Tab.prototype.show = function () {
  26. var $this = this.element//把a标签赋值给$this
  27. var $ul = $this.closest('ul:not(.dropdown-menu)')//closest 仅供插件开发者使用的方法,jquery1.7后就不建议使用了 冲a标签处向上寻找ul包裹元素
  28. var selector = $this.data('target')//取出target
  29.  
  30. if (!selector) {//没有target的话,
  31. selector = $this.attr('href')//把当前触发的a标签的某点,付给他
  32. selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
  33. }
  34.  
  35. if ($this.parent('li').hasClass('active')) return//发现已经时active了,则返回,没有泽继续向下执行
  36.  
  37. var $previous = $ul.find('.active:last a')
  38. var hideEvent = $.Event('hide.bs.tab', {
  39. relatedTarget: $this[0]
  40. })
  41. var showEvent = $.Event('show.bs.tab', {
  42. relatedTarget: $previous[0]
  43. })
  44.  
  45. $previous.trigger(hideEvent)
  46. $this.trigger(showEvent)
  47.  
  48. if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
  49.  
  50. var $target = $(selector)
  51.  
  52. this.activate($this.closest('li'), $ul)
  53. this.activate($target, $target.parent(), function () {
  54. $previous.trigger({
  55. type: 'hidden.bs.tab',
  56. relatedTarget: $this[0]
  57. })
  58. $this.trigger({
  59. type: 'shown.bs.tab',
  60. relatedTarget: $previous[0]
  61. })
  62. })
  63. }
  64.  
  65. Tab.prototype.activate = function (element, container, callback) {
  66. var $active = container.find('> .active')//得到先前li.active
  67. var transition = callback
  68. && $.support.transition
  69. && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
  70.  
  71. function next() {
  72. $active
  73. .removeClass('active')//把原来的active去除
  74. .find('> .dropdown-menu > .active')
  75. .removeClass('active')//在把menu下拉菜单下的active去掉
  76. .end()//退到上一层
  77. .find('[data-toggle="tab"]')//寻找他下面的a标签,
  78. .attr('aria-expanded', false)//aria-expanded 属性赋值为false
  79.  
  80. element
  81. .addClass('active')//给当前触发的li负上active
  82. .find('[data-toggle="tab"]')//找到地下a标签
  83. .attr('aria-expanded', true)//赋值为true
  84.  
  85. if (transition) {//有毁掉函数的时候
  86. element[0].offsetWidth // reflow for transition
  87. element.addClass('in')
  88. } else {
  89. element.removeClass('fade')
  90. }
  91.  
  92. if (element.parent('.dropdown-menu').length) {//父元素时.dropdown-menu时执行
  93. element
  94. .closest('li.dropdown')
  95. .addClass('active')
  96. .end()
  97. .find('[data-toggle="tab"]')
  98. .attr('aria-expanded', true)
  99. }
  100.  
  101. callback && callback()
  102. }
  103.  
  104. $active.length && transition ?
  105. $active
  106. .one('bsTransitionEnd', next)
  107. .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
  108. next()
  109.  
  110. $active.removeClass('in')
  111. }
  112.  
  113. // TAB PLUGIN DEFINITION
  114. // =====================
  115.  
  116. function Plugin(option) {
  117. return this.each(function () {//加each是jquery插件的标配,意为选中多个dom时挨个处理
  118. var $this = $(this)
  119. var data = $this.data('bs.tab')//先取一下bs.tab 这一步是为了缓存Tab对象的,这是必须的,不可能点击一下tab就new Tab(this),
  120.  
  121. if (!data) $this.data('bs.tab', (data = new Tab(this)))//如果没有data,那么吧点击的a标签传入tab,然后把Tab对象赋值给data
  122. if (typeof option == 'string') data[option]()//如果传入的是字符串,则执行相应的方法
  123. })
  124. }
  125.  
  126. var old = $.fn.tab
  127.  
  128. $.fn.tab = Plugin
  129. $.fn.tab.Constructor = Tab
  130.  
  131. // TAB NO CONFLICT
  132. // ===============
  133.  
  134. $.fn.tab.noConflict = function () {//这个防冲突的代码,为了规范,应该加上
  135. $.fn.tab = old
  136. return this
  137. }
  138.  
  139. // TAB DATA-API 自动给你初始化了,这样就可以不用写js代码了
  140. // ============
  141.  
  142. var clickHandler = function (e) {
  143. e.preventDefault()
  144. Plugin.call($(this), 'show')
  145. }
  146.  
  147. $(document)
  148. .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
  149. .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)//pill这个是给胶囊导航用的,其实tab和pill原理都一样,只是名字不一样而已
  150.  
  151. }(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. 负对数似然(negative log-likelihood)

    negative log likelihood文章目录negative log likelihood似然函数(likelihood function)OverviewDefinition离散型概率分布 ...

  2. C++如何显式调用常成员函数

    C++的常成员函数与同名成员函数重载时,该如何显式调用常成员函数? 具体的一个小例子: #include <iostream> using namespace std; class C1 ...

  3. nohup 忽略所有挂断信号

    1.nohup 用途:不挂断地运行命令. 语法:nohup Command [ Arg … ] [ & ] 无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup ...

  4. 第一节:python提取PDF文档中的图片

    由于项目需要将PDF文档当中的图片转换成图片,所以参考了这篇文章https://blog.csdn.net/qq_15969343/article/details/81673302后项目得以解决. 1 ...

  5. Django-rest_framework中利用jwt登录验证时,自定义返回凭证和登录校验支持手机号

    安装 pip install djangorestframework-jwt 在Django.settings中配置 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATIO ...

  6. 分数拆分(刘汝佳紫书P183)

    枚举,由已知条件推得y大于k,小于等于2K AC代码: #include"iostream"#include"cstring"using namespace s ...

  7. Python基础之列表、元组、字典、集合的使用

    一.列表 1.列表定义 names=["Jhon","Lucy","Michel","Tom","Wiliam ...

  8. C51 keil 注意事项

    下载程序需要生成hex文件 仿真 蜂鸣器 音调:频率 音量:高低电平占空比 有源:上面没有加号,只需高低电平即可发声 无源:上面有加号,不仅要电平,还要, 的频率

  9. Fiddler基本用法:手机抓包

    from:https://blog.csdn.net/gld824125233/article/details/52588275 电脑最好是笔记本,这样能和手机保持统一局域网内:其他不多说,直接说步骤 ...

  10. Linux清除arp缓存

    arp缓存就是IP地址和MAC地址关系缓存列表.在Windows下 arp -d [$ip] 不指定IP地址时清除所有arp缓存.在Linux下 arp -d $ip 必须指定IP地址才能执行这条命令 ...