123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- /**
- * Created by duhuan on 2017/9/14.
- */
- ;(function($) { "use strict";
- // CAROUSEL CLASS DEFINITION
- // =========================
- var Carousel = function (element, options) {
- this.$element = $(element)
- this.$indicators = this.$element.find('.vc_carousel-indicators')
- this.options = options
- this.paused =
- this.sliding =
- this.interval =
- this.$active =
- this.$items = null
- this.options.pause == 'hover' && this.$element
- .on('mouseenter', $.proxy(this.pause, this))
- .on('mouseleave', $.proxy(this.cycle, this))
- this._build() // new
- }
- Carousel.DEFAULTS = {
- mode: 'horizontal'
- , partial: false
- , interval: 5000
- , pause: 'hover'
- , wrap: false
- , autoHeight: false
- , perView: 1
- }
- Carousel.prototype.cycle = function (e) {
- e || (this.paused = false)
- this.interval && clearInterval(this.interval)
- this.options.interval
- && !this.paused
- && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
- this.touch_start_position = 0;
- return this
- }
- Carousel.prototype.getActiveIndex = function () {
- this.$active = this.$element.find('.vc_item.vc_active')
- if(!this.$active.length) this.$active = this.$element.find('.vc_item:first').addClass('vc_active')
- this.$items = this.$active.parent().children()
- return this.$items.index(this.$active)
- }
- Carousel.prototype.showHideControl = function(index) {
- if(typeof index === 'undefined') var index = this.getActiveIndex()
- this.$left_control[index===0 ? 'hide' : 'show']()
- this.$right_control[index===this.items_count-1 ? 'hide' : 'show']()
- }
- Carousel.prototype.to = function (pos) {
- var that = this
- var activeIndex = this.getActiveIndex()
- if (pos > (this.$items.length - 1) || pos < 0) return
- if (this.sliding) return this.$element.one('slid', function () { that.to(pos) })
- if (activeIndex == pos) return this.pause().cycle()
- return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
- }
- Carousel.prototype.pause = function (e) {
- e || (this.paused = true)
- if (this.$element.find('.vc_right.vc_carousel-control, .vc_left.vc_carousel-control').length && $.support.transition.end) {
- this.$element.trigger($.support.transition.end)
- this.cycle(true)
- }
- this.interval = clearInterval(this.interval)
- return this
- }
- Carousel.prototype.next = function () {
- if (this.sliding) return
- return this.slide('next')
- }
- Carousel.prototype.prev = function () {
- if (this.sliding) return
- return this.slide('prev')
- }
- Carousel.prototype.slide = function (type, next) {
- var $active = this.$element.find('.vc_item.vc_active')
- var $next = next || $active[type]()
- var isCycling = this.interval
- var direction = type == 'next' ? 'vc_left' : 'vc_right'
- var fallback = type == 'next' ? 'first' : 'last'
- var that = this
- if (!$next.length) {
- if (!this.options.wrap) {
- this.returnSwipedSlide()
- return
- }
- $next = this.$element.find('.vc_item')[fallback]()
- }
- this.sliding = true
- isCycling && this.pause()
- var e = $.Event('slide.vc.carousel', { relatedTarget: $next[0], direction: direction })
- if ($next.hasClass('vc_active')) return
- if (this.$indicators.length) {
- this.$indicators.find('.vc_active').removeClass('vc_active')
- this.$indicators.find('.vc_partial').removeClass('vc_partial')
- this.$element.one('slid', function () {
- var index = that.getActiveIndex(),
- $nextIndicator = $(that.$indicators.children().slice(index, that.getActiveIndex() + that.options.perView))
- $nextIndicator && $nextIndicator.addClass('vc_active')
- that.options.partial && $nextIndicator && (index+1 < that.items_count ? $nextIndicator.last().next().addClass('vc_partial') : $nextIndicator.first().prev().addClass('vc_partial'))
- !that.options.wrap && that.showHideControl(index)
- })
- }
- this.current_index = $next.index()
- if(this.current_index > this.items_count) {
- this.current_index = 0
- } else if(this.current_index < 0) {
- this.current_index = this.items_count -1
- }
- if(this.options.autoHeight) {
- this.current_pos_value = -1 * this._step * this.current_index
- } else {
- this.current_pos_value = -1 * $next.position()[this.animation_position]
- }
- if(this.options.partial && this.current_index >= this.items_count-1) {
- this.current_pos_value += this._step*(1-this.partial_part)
- }
- if ($.support.transition && this.$element.hasClass('vc_slide')) {
- this.$element.trigger(e)
- if (e.isDefaultPrevented()) return
- this.$slideline_inner
- .addClass('vc_transition')
- .css(this.animation_position, this.current_pos_value + that.pos_units)
- if(!this.options.autoHeight) this.recalculateSlidelineHeight($next.height(), true)
- this.$slideline_inner.one($.support.transition.end, function(){
- $next.addClass('vc_active')
- $active.removeClass('vc_active')
- that.$slideline_inner.removeClass([type, 'vc_transition'].join(' '))
- that.sliding = false
- that.removeSwipeAnimationSpeed()
- setTimeout(function () { that.$element.trigger('slid') }, 0)
- }).emulateTransitionEnd(this.transition_speed)
- } else {
- this.$element.trigger(e)
- if (e.isDefaultPrevented()) return
- $active.removeClass('vc_active')
- $next.addClass('vc_active')
- this.sliding = false
- this.$slideline_inner.css(this.animation_position, this.current_pos_value + that.pos_units)
- }
- isCycling && this.cycle()
- return this
- }
- Carousel.prototype.setSwipeAnimationSpeed = function() {
- this.$slideline_inner.addClass('vc_swipe-transition')
- }
- Carousel.prototype.removeSwipeAnimationSpeed = function() {
- this.$slideline_inner.removeClass('vc_swipe-transition')
- }
- Carousel.prototype.velocity = function(time, x) {
- return {
- x: Math.abs(x / time) || 0
- }
- }
- Carousel.prototype.recalculateSlidelineHeight = function(height, animate) {
- if(animate === true) {
- this.$slideline.animate({height: height})
- } else {
- this.$slideline.height(height)
- }
- }
- /**
- * Change layout size after resizing of window.
- */
- Carousel.prototype.resizeAction = function() {
- var max_height = 0,
- new_slideline_height = 0
- if(this.options.mode === 'horizontal') {
- this.el_effect_size = this.$element.width() * ( this.options.partial ? this.partial_part : 1 )
- this.$slideline.width(this.items_count*this.el_effect_size)
- }
- if (this.options.autoHeight) {
- this.$items.height('auto')
- this.$items.each(function(){
- var item_height = $(this).height()
- if(item_height > max_height) max_height = item_height
- })
- this.$items.height(max_height)
- } else {
- this.recalculateSlidelineHeight(this.$active.height())
- }
- if(this.options.mode === 'vertical') {
- this._step = this.$active.height()
- new_slideline_height = this.$active.height() * this.options.perView * (this.options.partial ? (1 + 1-this.partial_part) : 1)
- this.recalculateSlidelineHeight(new_slideline_height, false)
- this.$slideline_inner.css({top: -1 * this.$active.position().top})
- this.el_effect_size = this._step
- }
- }
- Carousel.prototype.returnSwipedSlide = function() {
- var params = {}
- params[this.animation_position] = this.current_pos_value + this.pos_units
- this.$slideline_inner.animate(params)
- }
- Carousel.prototype._build = function() {
- var el = this.$element.get(0),
- _touch_start_position = false,
- _touch_start_time = 0,
- _pos_before_touch = 0,
- _diff = 0,
- _moved = false,
- that = this,
- mode = this.options.mode
- this.getActiveIndex()
- this.el_width = 0
- this.items_count = this.$items.length
- this.$slideline = this.$element.find('.vc_carousel-slideline')
- this.$slideline_inner = this.$slideline.find('> div')
- this.slideline_inner = this.$slideline_inner.get(0)
- this.partial_part = 0.8
- this._slide_width = 0
- this.swipe_velocity = 0.7
- this.current_pos_value = 0
- this.current_index = 0 // TODO: default start position by options
- this.el_effect_size = 0
- this.transition_speed = 600
- this.$left_control = this.$element.find('.vc_left.vc_carousel-control')
- this.$right_control = this.$element.find('.vc_right.vc_carousel-control')
- // Enable autoHeight if partial
- if(this.options.partial) this.options.autoHeight = true
- // Add Css classes for perView > 1
- if(this.options.perView > 1) this.$element.addClass('vc_per-view-more vc_per-view-' + this.options.perView)
- if( mode === 'horizontal') {
- this.pos_units = '%'
- this._step = 100.00/this.items_count/this.options.perView
- this.animation_position = 'left'
- this.$items.width(this._step + this.pos_units)
- this.touch_direction = 'pageX'
- } else {
- this.pos_units = 'px'
- this.animation_position = 'top'
- this.touch_direction = 'pageY'
- this.$element.addClass('vc_carousel_vertical')
- }
- // Hide first control if this.current_index === 0
- !that.options.wrap && this.showHideControl()
- // Add partial css class if partial
- if(this.options.partial) this.$element.addClass('vc_partial')
- // Set indicator
- if(this.$indicators.length) {
- var $active_indecators = that.$indicators.children()
- .slice(this.current_index, this.current_index + this.options.perView)
- .addClass('vc_active')
- this.options.partial && $active_indecators.last().next().addClass('vc_partial')
- }
- $(window).resize(this.resizeAction.bind(this)); this.resizeAction()
- el.addEventListener("touchstart", function(e){
- _touch_start_position = parseFloat(e[that.touch_direction])
- _touch_start_time = e.timeStamp
- _pos_before_touch = that.$slideline_inner.position()[that.animation_position]
- }.bind(this), false)
- el.addEventListener('touchmove', function(e){
- _diff = parseFloat(e[that.touch_direction]) - _touch_start_position
- _moved = Math.abs(_diff) > 0
- if(!_moved) return true
- e.preventDefault()
- that.slideline_inner.style[that.animation_position] = (_pos_before_touch + _diff) + 'px'
- }, false)
- el.addEventListener('touchend', function(e){
- var time,part,velocity
- if(_moved) {
- time= (e.timeStamp-_touch_start_time)/1000
- part = _diff/ that.el_effect_size
- velocity = that.velocity(time, part)
- if((velocity.x > that.swipe_velocity && part < 0) || part <= -0.7) {
- that.setSwipeAnimationSpeed()
- that.next()
- } else if(velocity.x > that.swipe_velocity || part >= 0.7) {
- that.setSwipeAnimationSpeed()
- that.prev()
- } else {
- that.returnSwipedSlide()
- }
- _moved = false
- }
- }, false)
- this.$element.addClass('vc_build')
- return this
- }
- // CAROUSEL PLUGIN DEFINITION
- // ==========================
- var old = $.fn.carousel
- $.fn.carousel = function (option, value) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('vc.carousel')
- var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
- var action = typeof option == 'string' ? option : options.slide
- if (!data) $this.data('vc.carousel', (data = new Carousel(this, options)))
- if (typeof option == 'number') data.to(option)
- else if (action) data[action](value)
- else if (options.interval) data.pause().cycle()
- })
- }
- $.fn.carousel.Constructor = Carousel
- // CAROUSEL NO CONFLICT
- // ====================
- $.fn.carousel.noConflict = function () {
- $.fn.carousel = old
- return this
- }
- // CAROUSEL DATA-API
- // =================
- $(document).off('click.vc.carousel.data-api').on('click.vc.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
- var $this = $(this), href
- var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
- var options = $.extend({}, $target.data(), $this.data())
- var slideIndex = $this.attr('data-slide-to')
- if (slideIndex) options.interval = false
- $target.carousel(options)
- if (slideIndex = $this.attr('data-slide-to')) {
- $target.data('vc.carousel').to(slideIndex)
- }
- e.preventDefault()
- })
- $(window).on('load', function () {
- $('[data-ride="vc_carousel"]').each(function () {
- var $carousel = $(this)
- $carousel.carousel($carousel.data())
- })
- })
- })(window.jQuery);
|