Carousel jumps over the second item until it's initialized. IE9
Created by: petalvlad
You can try here: http://jsfiddle.net/vm9vX/6/
Explored
When you clicked on the next (prev) element, the following callback is invoked:
$('body').on('click.carousel.data-api', '[data-slide]', function ( e ) {
var $this = $(this), href
, $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
, options = !$target.data('modal') && $.extend({}, $target.data(), $this.data())
$target.carousel(options)
e.preventDefault()
})
Then you'll go to the carousel prototype method:
$.fn.carousel = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('carousel')
, options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
, action = typeof option == 'string' ? option : options.slide
if (!data) $this.data('carousel', (data = new Carousel(this, options)))
if (typeof option == 'number') data.to(option)
else if (action) data[action]()
else if (options.interval) data.cycle()
})
}
Because this $this.data('carousel') is undefined you'll go to the Carousel constructor:
var Carousel = function (element, options) {
this.$element = $(element)
this.options = 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))
}
Because the options object has not empty slide property, corresponding method will be called.
After successful sliding and other Carousel initialization you will come back to carousel prototype method.
$.fn.carousel = function (option) {
return this.each(function () {
var $this = $(this)
, data = $this.data('carousel')
, options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
, action = typeof option == 'string' ? option : options.slide
if (!data) $this.data('carousel', (data = new Carousel(this, options)))
if (typeof option == 'number') data.to(option)
else if (action) data[action]()
else if (options.interval) data.cycle()
})
}
The sliding operation action was also defined here. After this data[action]() invoke, the slide method will be called amiss again.
Next time there will no duplication, because the $this.data('carousel') has already been initialized and the Carousel constructor will not be called.
Why only in browsers which don't support transition
If the browser supports transition, at the next or prev method calling, this.sliding will be true.
next: function () {
if (this.sliding) return
return this.slide('next')
}
But if the browser don't support transition, this is false.
Workaround
It seems like no need to cause the slide method in constructor, because later in the carousel prototype method the next or prev method will be called for sure.
var Carousel = function (element, options) {
this.$element = $(element)
this.options = 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))
}