Carousel jumps over the second item until it's initialized. IE9
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))
}