先看bootstrap.carousel.js的结构
var Carousel = function (element, options){} //构造器
Carousel.prototype = {} // 构造器原型
$.fn.carousel = function ( option ) {} //jQuery原型上自定义的方法
$.fn.carousel.defaults ={} //默认参数
$.fn.carousel.Constructor = Carousel // 重写jQuery原型上自定义方法的构造器名
$(function (){}) // 初始化
HTML结构
<div id="myCarousel" class="carousel slide">
<div class="carousel-inner">
<div class="item">
<img alt="" src=/2013/0903/20130903115651384.jpg">
<div class="carousel-caption">
<h4>即使杀光所有报晓的公鸡,天,还是会亮的</h4>
<p> @shifeike: 昨天是李尚平被枪杀10周年,我发的那条纪念微博,成为我的新浪微博账号最后一条微博。这个2010年1月为反对红中抢笔而注册的微博,两年多时间里发了14538条微博,加上被删除的差不多近200万字,积累了96269条粉丝,自此灰飞烟灭。 </p>
</div>
</div>
<div class="item">
<img alt="" src=/2013/0903/20130903115651426.jpg">
<div class="carousel-caption">
<h4>如果人民不欢迎我们,就该我们下台了</h4>
<p> 【胡耀邦语录】①历史是混不过去的。②民主、自由、平等、博爱等观念是人类精神的一大解放。③如果人民不欢迎我们,就该我们下台了。④不懂的不要装懂,不通的不要装通,不服的不要装服。⑤中国的出路是民主和科学。⑥一个精神上、组织上被禁锢被压制的不自由民族怎么可能与其他国家进行自由竞争呢? </p>
</div>
</div>
<div class="item active">
<img alt="" src=/2013/0903/20130903115651718.jpg">
<div class="carousel-caption">
<h4>国家像需要空气一样需要变革</h4>
<p> 据戈尔巴乔夫基金会新闻处通报,俄总统梅德韦杰夫今天向前苏联总统戈尔巴乔夫颁发圣徒安德烈·佩尔沃兹万内勋章。戈尔巴乔夫在受勋时表示感谢,并称很激动。他坦言,对自己做过的事情问心无愧。他强调,他进行改革不是为了赢得敬重和荣誉,而是因为认识到,“国家像需要空气一样需要变革”。他承认犯过错误,并至今还在为这些错误而烦恼。但他认为:“短短几年所走过的路,使专制的过去永远成为了历史。” </p>
</div>
</div>
</div>
<a class="left carousel-control" data-slide="prev" href="#myCarousel">‹</a>
<a class="right carousel-control" data-slide="next" href="#myCarousel">›</a>
</div>
先从初始化开始
$(function () {
$('body').on('click.carousel.data-api', '[data-slide]', function ( e ) {
var $this = $(this), href
//获得整个控件的jQuery对象
, $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
, options = !$target.data('modal') && $.extend({}, $target.data(), $this.data())//{slide:prev}或是{slide:next}
$target.carousel(options)//整个控件对象调用carousel方法
e.preventDefault()//阻止冒泡
})
})
根据HTML结构,为拥有data-slide属性的标签绑定click事件,如果我们点击向左按钮,代码会获取该标签的href,并获取整个控件的对象。接着让整个控件调用jQuery原型上的carousel方法。另外这个方法中,是阻止冒泡的。
/*
* jQuery原型上自定义的方法
* */
$.fn.carousel = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('carousel')
, options = typeof option == 'object' && option
if (!data) $this.data('carousel', (data = new Carousel(this, options)))//实例化构造器
if (typeof option == 'number') data.to(option)
else if (typeof option == 'string' || (option = options.slide)) data[option]()
else data.cycle()
})
}
初次调用carousel方法时,因为$(this).data('carousel')为未定义,实例化构造器,最后进过一些判断,我们执行data的cycle方法,实际上就是实例的方法cycle方法,先看构造器。
/*
* 构造器
* */
var Carousel = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, $.fn.carousel.defaults, options)
this.options.slide && this.slide(this.options.slide)
this.options.pause == 'hover' && this.$element//为整个控件绑定事件
.on('mouseenter', $.proxy(this.pause, this))
.on('mouseleave', $.proxy(this.cycle, this))
}
这里实例化的时候,this是实例对象,这个注意一下,合并参数之后,执行原型上的slide方法,接着为整个控件绑定mouseenter和mouseleave事件,处理方法分别是原型上的pause和cycle方法。先看slide方法
slide: function (type, next) {
var $active = this.$element.find('.active')//找到当前显示的对象
, $next = next || $active[type]()//获取当前显示对象的前一个同级对象
, isCycling = this.interval
, direction = type == 'next' ? 'left' : 'right'//我们点击左边按钮时,direction = right
, fallback = type == 'next' ? 'first' : 'last'//同上,fallback = last
, that = this
this.sliding = true//设置参数
isCycling && this.pause()
$next = $next.length ? $next : this.$element.find('.item')[fallback]()//手动查找