bootstrap插件学习-bootstrap.tab.js(读码)


先看bootstrap-tab.js的结构

var Tab = function ( element ) {} //构造器 Tab.prototype ={} //构造器的原型 $.fn.tab = function ( option ){} //jQuery原型上自定义的方法 $.fn.tab.Constructor = Tab //重写jQuery原型上的自定义方法的构造器名 $(function () {}) //初始化

HTML结构

<ul class="nav nav-tabs"> <li class="active"><a href="#home" data-toggle="tab" >首页</a></li> <li><a href="#profile" data-toggle="tab">介绍</a></li> <li><a href="#messages" data-toggle="tab">消息</a></li> <li><a href="#settings" data-toggle="tab">设置</a></li> </ul> <div class="tab-content"> <div class="tab-pane active" id="home">1</div> <div class="tab-pane" id="profile">2</div> <div class="tab-pane" id="messages">3</div> <div class="tab-pane" id="settings">4</div> </div>

先从初始化开始

/* * 初始化 * 给拥有data-toggle='tab'属性的标签绑定click事件 * */ $(function () { $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { e.preventDefault() $(this).tab('show')//向jQuery原型方法tab传入参数show,应该执行show方法。this为拥有data-toggle属性的a标签对象  }) })

让body监听a标签的click事件,并且阻止其冒泡,调用了jQuery的原型方法tab。

/* * jQuery原型上自定义的方法 * */ $.fn.tab = function ( option ) { return this.each(function () { var $this = $(this) , data = $this.data('tab') if (!data) $this.data('tab', (data = new Tab(this)))//实例化构造器 if (typeof option == 'string') data[option]()//执行option的方法  }) }

这个结构跟之前的几个插件差不多,不过最后它是执行了show方法的,进入构造器

var Tab = function ( element ) { this.element = $(element) }

将对象封装成构造器实例的一个属性。接下来我们执行show方法

show: function () { var $this = this.element , $ul = $this.closest('ul:not(.dropdown-menu)')//找到最近的不是dropdown类的ul元素 , selector = $this.attr('data-target') , previous , $target //获取与a标签对应的内容id if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7  } //如果一直点击自己,这句之后的代码将不执行 if ( $this.parent('li').hasClass('active') ) return previous = $ul.find('.active a').last()[0]//获得拥有active类的原生a标签对象,即上一次高亮的节点  $this.trigger({ type: 'show' , relatedTarget: previous }) $target = $(selector)//获得内容节点的jQueryDOM对象 this.activate($this.parent('li'), $ul)//tab页切换 this.activate($target, $target.parent(), function () { $this.trigger({ type: 'shown' , relatedTarget: previous }) })

根据标签a的data-target属性或是其href找到对应的id的dom节点。最后我们执行了两次activate方法,其实大概猜的出来,一个方法控制a标签的高亮显示,另一个控制dom节点的显示与隐藏

/* * 控制显示与隐藏 * 参数主要形式是这样的,一个是可以拥有active类的元素,另一个是其父类。 * 先找到父类下来所有拥有active类的节点,删除它们的active,并将当前节点,也就是第一个参数加上active类。 * * */ , activate: function ( element, container, callback) { var $active = container.find('> .active') , transition = callback && $.support.transition//需要引入其他js文件,这里没有引入。 && $active.hasClass('fade') console.log($active[0]) function next() { $active .removeClass('active') .find('> .dropdown-menu > .active') .removeClass('active') element.addClass('active') if (transition) { element[0].offsetWidth // reflow for transition element.addClass('in') } else { element.removeClass('fade') } if ( element.parent('.dropdown-menu') ) { element.closest('li.dropdown').addClass('active') } callback && callback() } transition ? $active.one($.support.transition.end, next) : next() $active.removeClass('in') }

逻辑比较简单,一般遇到一个显示其他同类不显示的情况,基本都是这一套方法,增删class来达到要求。但对于jQuery操作css完成class切换与javascript原生方法相比,哪个效率会更好一点呢?也希望有经验的园友给予解答。

另外是部分css,表现了两块active类的作用

/*tab页切换时的active作用*/ .nav-tabs > .active > a, .nav-tabs > .active > a:hover, .nav-tabs > .active > a:focus { color: #555555; cursor: default; background-color: #ffffff; border: 1px solid #ddd; border-bottom-color: transparent;//将底部边框变透明 } /*dom*/ .tab-content > .tab-pane, .pill-content > .pill-pane { display: none; //原来为隐藏 } .tab-content > .active, .pill-content > .active { display: block; //加入active ,变为显示 }

 

 

文实例为大家介绍实现tab选项卡的应用,此插件相对比较简单,具体内容如下
源码文件:
tab.js

实现原理:
1、单击一个元素时,首先将原来高亮的元素取消
2、然后给被单击元素进行高亮
3、如果单击元素是下拉框中某个选项,则选中本身,还要选中下拉框
5、如果定义了动画,先执行动画,然后回调

源码分析:
1、Show方法,是在单击一个元素的时候触发,会触发如下四个事件
  1.1、Hiden.bs.tab:隐藏上一个元素
  1.2、Show.bs.tab:显示当前元素
  1.3、Hideen.bs.tab:隐藏上一个元素完成
  1.4、Shown.bs.tab:显示当前元素完成
  1.5、Hiden/show事件源码:

?
1
2
3
4
5
6
7
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]
})

2、Active:激活当前对象
  2.1、对导航元素增加aria-expanded属性,标记此元素是否处于展开状态
  2.2、利用reflow机制,用获取offsetWidth属性来实现部分重绘


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM