/* * Swiper 1.9.2+ - Mobile Touch Slider * http://www.idangero.us/sliders/swiper/ * * Copyright 2012-2013, Vladimir Kharlampidi * The iDangero.us * http://www.idangero.us/ * * Licensed under GPL & MIT * * Updated on: April 19, 2013 */ var Swiper = function (selector, params, callback) { /*========================= A little bit dirty but required part for IE8 and old FF support ===========================*/ if (!window.addEventListener) { if (!window.Element) Element = function () { }; Element.prototype.addEventListener = HTMLDocument.prototype.addEventListener = addEventListener = function (type, listener, useCapture) { this.attachEvent('on' + type, listener); } Element.prototype.removeEventListener = HTMLDocument.prototype.removeEventListener = removeEventListener = function (type, listener, useCapture) { this.detachEvent('on' + type, listener); } } if (document.body.__defineGetter__) { if (HTMLElement) { var element = HTMLElement.prototype; if (element.__defineGetter__) element.__defineGetter__("outerHTML", function () { return new XMLSerializer().serializeToString(this); } ); } } if (!window.getComputedStyle) { window.getComputedStyle = function (el, pseudo) { this.el = el; this.getPropertyValue = function (prop) { var re = /(\-([a-z]){1})/g; if (prop == 'float') prop = 'styleFloat'; if (re.test(prop)) { prop = prop.replace(re, function () { return arguments[2].toUpperCase(); }); } return el.currentStyle[prop] ? el.currentStyle[prop] : null; } return this; } } /* End Of Polyfills*/ if(!(selector.nodeType)) if (!document.querySelectorAll||document.querySelectorAll(selector).length==0) return; function dQ(s) { return document.querySelectorAll(s) } var _this = this _this.touches = {}; _this.positions = { current : 0 }; _this.id = (new Date()).getTime(); _this.container = (selector.nodeType) ? selector : dQ(selector)[0]; _this.times = {}; _this.isTouched = false; _this.realIndex = 0; _this.activeSlide = 0; _this.activeIndex = 0; _this.previousSlide = null; _this.previousIndex = null; _this.langDirection = window.getComputedStyle(_this.container, null).getPropertyValue('direction') /*========================= New Support Object ===========================*/ _this.support = { touch : _this.isSupportTouch(), threeD : _this.isSupport3D(), transitions : _this.isSupportTransitions() } //For fallback with older versions _this.use3D = _this.support.threeD; /*========================= Default Parameters ===========================*/ var defaults = { mode : 'horizontal', ratio : 1, speed : 300, freeMode : false, freeModeFluid : false, slidesPerSlide : 1, slidesPerGroup : 1, simulateTouch : true, followFinger : true, shortSwipes : true, moveStartThreshold:false, autoPlay:false, onlyExternal : false, createPagination : true, pagination : false, resistance : true, nopeek : false, scrollContainer : false, preventLinks : true, preventClassNoSwiping : true, initialSlide: 0, keyboardControl: false, mousewheelControl : false, resizeEvent : 'auto', //or 'resize' or 'orientationchange' useCSS3Transforms : true, //Namespace slideElement : 'div', slideClass : 'swiper-slide', slideActiveClass : 'swiper-slide-active', wrapperClass : 'swiper-wrapper', paginationClass: 'swiper-pagination-switch' , paginationActiveClass : 'swiper-active-switch' } params = params || {}; for (var prop in defaults) { if (! (prop in params)) { params[prop] = defaults[prop] } } _this.params = params; if (params.scrollContainer) { params.freeMode = true; params.freeModeFluid = true; } var _widthFromCSS = false if (params.slidesPerSlide=='auto') { _widthFromCSS = true; params.slidesPerSlide = 1; } //Default Vars var wrapper, isHorizontal, slideSize, numOfSlides, wrapperSize, direction, isScrolling, containerSize; //Define wrapper for (var i = _this.container.childNodes.length - 1; i >= 0; i--) { if (_this.container.childNodes[i].className) { var _wrapperClasses = _this.container.childNodes[i].className.split(' ') for (var j = 0; j < _wrapperClasses.length; j++) { if (_wrapperClasses[j]===params.wrapperClass) { wrapper = _this.container.childNodes[i] } }; } }; _this.wrapper = wrapper; //Mode isHorizontal = params.mode == 'horizontal'; //Define Touch Events _this.touchEvents = { touchStart : _this.support.touch || !params.simulateTouch ? 'touchstart' : (_this.ie10 ? 'MSPointerDown' : 'mousedown'), touchMove : _this.support.touch || !params.simulateTouch ? 'touchmove' : (_this.ie10 ? 'MSPointerMove' : 'mousemove'), touchEnd : _this.support.touch || !params.simulateTouch ? 'touchend' : (_this.ie10 ? 'MSPointerUp' : 'mouseup') }; /*========================= Slide API ===========================*/ _this._extendSwiperSlide = function (el) { el.append = function () { _this.wrapper.appendChild(el); _this.reInit(); return el; } el.prepend = function () { _this.wrapper.insertBefore(el, _this.wrapper.firstChild) _this.reInit(); return el; } el.insertAfter = function (index) { if(typeof index === 'undefined') return false; var beforeSlide = _this.slides[index+1] _this.wrapper.insertBefore(el, beforeSlide) _this.reInit(); return el; } el.clone = function () { return _this._extendSwiperSlide(el.cloneNode(true)) } el.remove = function () { _this.wrapper.removeChild(el); _this.reInit() } el.html = function (html) { if (typeof html === 'undefined') { return el.innerHTML } else { el.innerHTML = html; return el; } } el.index = function () { var index for (var i = _this.slides.length - 1; i >= 0; i--) { if(el==_this.slides[i]) index = i }; return index; } el.isActive = function () { if (el.index() == _this.activeIndex) return true; else return false; } if (!el.swiperSlideDataStorage) el.swiperSlideDataStorage={}; el.getData = function (name) { return el.swiperSlideDataStorage[name] } el.setData = function (name, value) { el.swiperSlideDataStorage[name] = value; return el; } el.data = function (name, value) { if (!value) { return el.getAttribute('data-'+name); } else { el.setAttribute('data-'+name,value); return el; } } return el; } //Calculate information about slides _this._calcSlides = function () { var oldNumber = _this.slides ? _this.slides.length : false; _this.slides = [] for (var i = 0; i < _this.wrapper.childNodes.length; i++) { if (_this.wrapper.childNodes[i].className) { var _slideClasses = _this.wrapper.childNodes[i].className.split(' ') for (var j = 0; j < _slideClasses.length; j++) { if(_slideClasses[j]===params.slideClass) _this.slides.push(_this.wrapper.childNodes[i]) }; } }; for (var i = _this.slides.length - 1; i >= 0; i--) { _this._extendSwiperSlide(_this.slides[i]); }; if (!oldNumber) return; if(oldNumber!=_this.slides.length && _this.createPagination) { // Number of slides has been changed _this.createPagination(); _this.callPlugins('numberOfSlidesChanged') } /* if (_this.langDirection=='rtl') { for (var i = 0; i < _this.slides.length; i++) { _this.slides[i].style.float="right" }; } */ } _this._calcSlides(); //Create Slide _this.createSlide = function (html, slideClassList, el) { var slideClassList = slideClassList || _this.params.slideClass; var el = el||params.slideElement; var newSlide = document.createElement(el) newSlide.innerHTML = html||''; newSlide.className = slideClassList; return _this._extendSwiperSlide(newSlide); } //Append Slide _this.appendSlide = function (html, slideClassList, el) { if (!html) return; if (html.nodeType) { return _this._extendSwiperSlide(html).append() } else { return _this.createSlide(html, slideClassList, el).append() } } _this.prependSlide = function (html, slideClassList, el) { if (!html) return; if (html.nodeType) { return _this._extendSwiperSlide(html).prepend() } else { return _this.createSlide(html, slideClassList, el).prepend() } } _this.insertSlideAfter = function (index, html, slideClassList, el) { if (!index) return false; if (html.nodeType) { return _this._extendSwiperSlide(html).insertAfter(index) } else { return _this.createSlide(html, slideClassList, el).insertAfter(index) } } _this.removeSlide = function (index) { if (_this.slides[index]) { _this.slides[index].remove() return true; } else return false; } _this.removeLastSlide = function () { if (_this.slides.length>0) { _this.slides[ (_this.slides.length-1) ].remove(); return true } else { return false } } _this.removeAllSlides = function () { for (var i = _this.slides.length - 1; i >= 0; i--) { _this.slides[i].remove() }; } _this.getSlide = function (index) { return _this.slides[index] } _this.getLastSlide = function () { return _this.slides[ _this.slides.length-1 ] } _this.getFirstSlide = function () { return _this.slides[0] } //Currently Active Slide _this.currentSlide = function () { return _this.slides[_this.activeIndex] } /*========================= Find All Plugins !!! Plugins API is in beta !!! ===========================*/ var _plugins = []; for (var plugin in _this.plugins) { if (params[plugin]) { var p = _this.plugins[plugin](_this, params[plugin]) if (p) _plugins.push( p ) } } _this.callPlugins = function(method, args) { if (!args) args = {} for (var i=0; i<_plugins.length; i++) { if (method in _plugins[i]) { _plugins[i][method](args); } } } /*========================= WP8 Fix ===========================*/ if (_this.ie10 && !params.onlyExternal) { if (isHorizontal) _this.wrapper.classList.add('swiper-wp8-horizontal') else _this.wrapper.classList.add('swiper-wp8-vertical') } /*========================= Loop ===========================*/ if (params.loop) { (function(){ numOfSlides = _this.slides.length; if (_this.slides.length==0) return; var slideFirstHTML = ''; var slideLastHTML = ''; //Grab First Slides for (var i=0; i0) { newWidth = _this.container.offsetWidth - parseInt(window.getComputedStyle(_this.container, null).getPropertyValue('padding-left'),10) - parseInt(window.getComputedStyle(_this.container, null).getPropertyValue('padding-right'),10) } if(isNaN(newHeight) || _height.indexOf('%')>0) { newHeight = _this.container.offsetHeight - parseInt(window.getComputedStyle(_this.container, null).getPropertyValue('padding-top'),10) - parseInt(window.getComputedStyle(_this.container, null).getPropertyValue('padding-bottom'),10) } if (!reInit) { if (_this.width==newWidth && _this.height==newHeight) return } if (reInit || firstInit) { _this._calcSlides(); if (params.pagination) { _this.updatePagination() } } _this.width = newWidth; _this.height = newHeight; var dividerVertical = isHorizontal ? 1 : params.slidesPerSlide, dividerHorizontal = isHorizontal ? params.slidesPerSlide : 1, slideWidth, slideHeight, wrapperWidth, wrapperHeight; numOfSlides = _this.slides.length if (!params.scrollContainer) { if (!_widthFromCSS) { slideWidth = _this.width/dividerHorizontal; slideHeight = _this.height/dividerVertical; } else { slideWidth = _this.slides[0].offsetWidth; slideHeight = _this.slides[0].offsetHeight; } containerSize = isHorizontal ? _this.width : _this.height; slideSize = isHorizontal ? slideWidth : slideHeight; wrapperWidth = isHorizontal ? numOfSlides * slideWidth : _this.width; wrapperHeight = isHorizontal ? _this.height : numOfSlides*slideHeight; if (_widthFromCSS) { //Re-Calc sps for pagination params.slidesPerSlide = Math.round(containerSize/slideSize) } } else { //Unset dimensions in vertical scroll container mode to recalculate slides if (!isHorizontal) { wrapper.style.width=''; wrapper.style.height=''; _this.slides[0].style.width=''; _this.slides[0].style.height=''; } slideWidth = _this.slides[0].offsetWidth; slideHeight = _this.slides[0].offsetHeight; containerSize = isHorizontal ? _this.width : _this.height; slideSize = isHorizontal ? slideWidth : slideHeight; wrapperWidth = slideWidth; wrapperHeight = slideHeight; } wrapperSize = isHorizontal ? wrapperWidth : wrapperHeight; for (var i=0; i<_this.slides.length; i++ ) { var el = _this.slides[i]; if (!_widthFromCSS) { el.style.width=slideWidth+"px" el.style.height=slideHeight+"px" } if (params.onSlideInitialize) { params.onSlideInitialize(_this, el); } } wrapper.style.width = wrapperWidth+"px"; wrapper.style.height = wrapperHeight+"px"; // Set Initial Slide Position if(params.initialSlide > 0 && params.initialSlide < numOfSlides && !firstInit) { _this.realIndex = _this.activeIndex = params.initialSlide; if (params.loop) { _this.activeIndex = _this.realIndex-params.slidesPerSlide; } //Legacy _this.activeSlide = _this.activeIndex; //-- if (isHorizontal) { _this.positions.current = -params.initialSlide * slideWidth; _this.setTransform( _this.positions.current, 0, 0); } else { _this.positions.current = -params.initialSlide * slideHeight; _this.setTransform( 0, _this.positions.current, 0); } } if (!firstInit) _this.callPlugins('onFirstInit'); else _this.callPlugins('onInit'); firstInit = true; } _this.init() //Get Max And Min Positions function maxPos() { var a = (wrapperSize - containerSize); if (params.loop) a = a - containerSize; if (params.scrollContainer) { a = slideSize - containerSize; if (a<0) a = 0; } if (params.slidesPerSlide > _this.slides.length) a = 0; return a; } function minPos() { var a = 0; if (params.loop) a = containerSize; return a; } /*========================= Pagination ===========================*/ _this.updatePagination = function() { if (_this.slides.length<2) return; var activeSwitch = dQ(params.pagination+' .'+params.paginationActiveClass) if(!activeSwitch) return for (var i=0; i < activeSwitch.length; i++) { activeSwitch.item(i).className = params.paginationClass } var pagers = dQ(params.pagination+' .'+params.paginationClass).length; var minPagerIndex = params.loop ? _this.realIndex-params.slidesPerSlide : _this.realIndex; var maxPagerIndex = minPagerIndex + (params.slidesPerSlide-1); for (var i = minPagerIndex; i <= maxPagerIndex; i++ ) { var j = i; if (j>=pagers) j=j-pagers; if (j<0) j = pagers + j; if (j' } dQ(params.pagination)[0].innerHTML = paginationHTML _this.updatePagination() _this.callPlugins('onCreatePagination'); } } _this.createPagination(); //Window Resize Re-init _this.resizeEvent = params.resizeEvent==='auto' ? ('onorientationchange' in window) ? 'orientationchange' : 'resize' : params.resizeEvent _this.resizeFix = function(){ _this.callPlugins('beforeResizeFix'); _this.init() //To fix translate value if (!params.scrollContainer) _this.swipeTo(_this.activeIndex, 0, false) else { var pos = isHorizontal ? _this.getTranslate('x') : _this.getTranslate('y') if (pos < -maxPos()) { var x = isHorizontal ? -maxPos() : 0; var y = isHorizontal ? 0 : -maxPos(); _this.setTransition(0) _this.setTransform(x,y,0) } } _this.callPlugins('afterResizeFix'); } if (!params.disableAutoResize) { //Check for resize event window.addEventListener(_this.resizeEvent, _this.resizeFix, false) } /*========================================== Autoplay ============================================*/ var autoPlay _this.startAutoPlay = function() { if (params.autoPlay && !params.loop) { autoPlay = setInterval(function(){ var newSlide = _this.realIndex + 1 if ( newSlide == numOfSlides) newSlide = 0 _this.swipeTo(newSlide) }, params.autoPlay) } else if (params.autoPlay && params.loop) { autoPlay = setInterval(function(){ _this.fixLoop(); _this.swipeNext(true) }, params.autoPlay) } _this.callPlugins('onAutoPlayStart'); } _this.stopAutoPlay = function() { if (autoPlay) clearInterval(autoPlay) _this.callPlugins('onAutoPlayStop'); } if (params.autoPlay) { _this.startAutoPlay() } /*========================================== Event Listeners ============================================*/ if (!_this.ie10) { if (_this.support.touch) { wrapper.addEventListener('touchstart', onTouchStart, false); wrapper.addEventListener('touchmove', onTouchMove, false); wrapper.addEventListener('touchend', onTouchEnd, false); } if (params.simulateTouch) { wrapper.addEventListener('mousedown', onTouchStart, false); document.addEventListener('mousemove', onTouchMove, false); document.addEventListener('mouseup', onTouchEnd, false); } } else { wrapper.addEventListener(_this.touchEvents.touchStart, onTouchStart, false); document.addEventListener(_this.touchEvents.touchMove, onTouchMove, false); document.addEventListener(_this.touchEvents.touchEnd, onTouchEnd, false); } //Remove Events _this.destroy = function(removeResizeFix){ removeResizeFix = removeResizeFix===false ? removeResizeFix : removeResizeFix || true if (removeResizeFix) { window.removeEventListener(_this.resizeEvent, _this.resizeFix, false); } if (_this.ie10) { wrapper.removeEventListener(_this.touchEvents.touchStart, onTouchStart, false); document.removeEventListener(_this.touchEvents.touchMove, onTouchMove, false); document.removeEventListener(_this.touchEvents.touchEnd, onTouchEnd, false); } else { if (_this.support.touch) { wrapper.removeEventListener('touchstart', onTouchStart, false); wrapper.removeEventListener('touchmove', onTouchMove, false); wrapper.removeEventListener('touchend', onTouchEnd, false); } wrapper.removeEventListener('mousedown', onTouchStart, false); document.removeEventListener('mousemove', onTouchMove, false); document.removeEventListener('mouseup', onTouchEnd, false); } if (params.keyboardControl) { document.removeEventListener('keydown', handleKeyboardKeys, false); } if (params.mousewheelControl && _this._wheelEvent) { _this.container.removeEventListener(_this._wheelEvent, handleMousewheel, false); } if (params.autoPlay) { _this.stopAutoPlay() } _this.callPlugins('onDestroy'); } /*========================= Prevent Links ===========================*/ _this.allowLinks = true; if (params.preventLinks) { var links = _this.container.querySelectorAll('a') for (var i=0; iMath.abs(e.deltaY) ? - e.deltaX : - e.deltaY; } if (!params.freeMode) { if(delta<0) _this.swipeNext() else _this.swipePrev() } else { //Freemode or scrollContainer: var currentTransform =isHorizontal ? _this.getTranslate('x') : _this.getTranslate('y') var x,y; if (isHorizontal) { x = _this.getTranslate('x') + delta; y = _this.getTranslate('y'); if (x>0) x = 0; if (x<-maxPos()) x = -maxPos(); } else { x = _this.getTranslate('x'); y = _this.getTranslate('y')+delta; if (y>0) y = 0; if (y<-maxPos()) y = -maxPos(); } _this.setTransition(0) _this.setTransform(x,y,0) } if(event.preventDefault) event.preventDefault(); else event.returnValue = false; return false; } if (_this._wheelEvent) { _this.container.addEventListener(_this._wheelEvent, handleMousewheel, false); } } /*========================= Grab Cursor ===========================*/ if (params.grabCursor) { _this.container.style.cursor = 'move'; _this.container.style.cursor = 'grab'; _this.container.style.cursor = '-moz-grab'; _this.container.style.cursor = '-webkit-grab'; } /*========================= Handle Touches ===========================*/ //Detect event type for devices with both touch and mouse support var isTouchEvent = false; var allowThresholdMove; function onTouchStart(event) { //Exit if slider is already was touched if (_this.isTouched || params.onlyExternal) { return false } if (params.preventClassNoSwiping && event.target && event.target.className.indexOf('NoSwiping') > -1) return false; //Check For Nested Swipers _this.isTouched = true; isTouchEvent = event.type=='touchstart'; if (!isTouchEvent || event.targetTouches.length == 1 ) { _this.callPlugins('onTouchStartBegin'); if (params.loop) _this.fixLoop(); if(!isTouchEvent) { if(event.preventDefault) event.preventDefault(); else event.returnValue = false; } var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX) var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY) //Start Touches to check the scrolling _this.touches.startX = _this.touches.currentX = pageX; _this.touches.startY = _this.touches.currentY = pageY; _this.touches.start = _this.touches.current = isHorizontal ? _this.touches.startX : _this.touches.startY ; //Set Transition Time to 0 _this.setTransition(0) //Get Start Translate Position _this.positions.start = _this.positions.current = isHorizontal ? _this.getTranslate('x') : _this.getTranslate('y'); //Set Transform if (isHorizontal) { _this.setTransform( _this.positions.start, 0, 0) } else { _this.setTransform( 0, _this.positions.start, 0) } //TouchStartTime var tst = new Date() _this.times.start = tst.getTime() //Unset Scrolling isScrolling = undefined; //Define Clicked Slide without additional event listeners if (params.onSlideClick || params.onSlideTouch) { ;(function () { var el = _this.container; var box = el.getBoundingClientRect(); var body = document.body; var clientTop = el.clientTop || body.clientTop || 0; var clientLeft = el.clientLeft || body.clientLeft || 0; var scrollTop = window.pageYOffset || el.scrollTop; var scrollLeft = window.pageXOffset || el.scrollLeft; var x = pageX - box.left + clientLeft - scrollLeft; var y = pageY - box.top - clientTop - scrollTop; var touchOffset = isHorizontal ? x : y; var beforeSlides = -Math.round(_this.positions.current/slideSize) var realClickedIndex = Math.floor(touchOffset/slideSize) + beforeSlides var clickedIndex = realClickedIndex; if (params.loop) { var clickedIndex = realClickedIndex - params.slidesPerSlide; if (clickedIndex<0) { clickedIndex = _this.slides.length+clickedIndex-(params.slidesPerSlide*2); } } _this.clickedSlideIndex = clickedIndex _this.clickedSlide = _this.getSlide(realClickedIndex); if (params.onSlideTouch) { params.onSlideTouch(_this); _this.callPlugins('onSlideTouch'); } })(); } //Set Treshold if (params.moveStartThreshold>0) allowThresholdMove = false; //CallBack if (params.onTouchStart) params.onTouchStart(_this) _this.callPlugins('onTouchStartEnd'); } } function onTouchMove(event) { // If slider is not touched - exit if (!_this.isTouched || params.onlyExternal) return; if (isTouchEvent && event.type=='mousemove') return; var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX) var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY) //check for scrolling if ( typeof isScrolling === 'undefined' && isHorizontal) { isScrolling = !!( isScrolling || Math.abs(pageY - _this.touches.startY) > Math.abs( pageX - _this.touches.startX ) ) } if ( typeof isScrolling === 'undefined' && !isHorizontal) { isScrolling = !!( isScrolling || Math.abs(pageY - _this.touches.startY) < Math.abs( pageX - _this.touches.startX ) ) } if (isScrolling ) { _this.isTouched = false; return } //Check For Nested Swipers if (event.assignedToSwiper) { _this.isTouched = false; return } event.assignedToSwiper = true; //Block inner links if (params.preventLinks) { _this.allowLinks = false; } //Stop AutoPlay if exist if (params.autoPlay) { _this.stopAutoPlay() } if (!isTouchEvent || event.touches.length == 1) { _this.callPlugins('onTouchMoveStart'); if(event.preventDefault) event.preventDefault(); else event.returnValue = false; _this.touches.current = isHorizontal ? pageX : pageY ; _this.positions.current = (_this.touches.current - _this.touches.start)*params.ratio + _this.positions.start if (params.resistance) { //Resistance for Negative-Back sliding if(_this.positions.current > 0 && !(params.freeMode&&!params.freeModeFluid)) { if (params.loop) { var resistance = 1; if (_this.positions.current>0) _this.positions.current = 0; } else { var resistance = (containerSize*2-_this.positions.current)/containerSize/2; } if (resistance < 0.5) _this.positions.current = (containerSize/2) else _this.positions.current = _this.positions.current * resistance if (params.nopeek) _this.positions.current = 0; } //Resistance for After-End Sliding if ( (_this.positions.current) < -maxPos() && !(params.freeMode&&!params.freeModeFluid)) { if (params.loop) { var resistance = 1; var newPos = _this.positions.current var stopPos = -maxPos() - containerSize } else { var diff = (_this.touches.current - _this.touches.start)*params.ratio + (maxPos()+_this.positions.start) var resistance = (containerSize+diff)/(containerSize); var newPos = _this.positions.current-diff*(1-resistance)/2 var stopPos = -maxPos() - containerSize/2; } if (params.nopeek) { newPos = _this.positions.current-diff; stopPos = -maxPos(); } if (newPos < stopPos || resistance<=0) _this.positions.current = stopPos; else _this.positions.current = newPos } } //Move Slides if (!params.followFinger) return if (!params.moveStartThreshold) { if (isHorizontal) _this.setTransform( _this.positions.current, 0, 0) else _this.setTransform( 0, _this.positions.current, 0) } else { if ( Math.abs(_this.touches.current - _this.touches.start)>params.moveStartThreshold || allowThresholdMove) { allowThresholdMove = true; if (isHorizontal) _this.setTransform( _this.positions.current, 0, 0) else _this.setTransform( 0, _this.positions.current, 0) } else { _this.positions.current = _this.positions.start } } if (params.freeMode) { _this.updateActiveSlide(_this.positions.current) } //Prevent onSlideClick Fallback if slide is moved if (params.onSlideClick && _this.clickedSlide) { _this.clickedSlide = false } //Grab Cursor if (params.grabCursor) { _this.container.style.cursor = 'move'; _this.container.style.cursor = 'grabbing'; _this.container.style.cursor = '-moz-grabbin'; _this.container.style.cursor = '-webkit-grabbing'; } //Callbacks _this.callPlugins('onTouchMoveEnd'); if (params.onTouchMove) params.onTouchMove(_this) return false } } function onTouchEnd(event) { //Check For scrolling if (isScrolling) _this.swipeReset(); // If slider is not touched exit if ( params.onlyExternal || !_this.isTouched ) return _this.isTouched = false //Return Grab Cursor if (params.grabCursor) { _this.container.style.cursor = 'move'; _this.container.style.cursor = 'grab'; _this.container.style.cursor = '-moz-grab'; _this.container.style.cursor = '-webkit-grab'; } //onSlideClick if (params.onSlideClick && _this.clickedSlide) { params.onSlideClick(_this); _this.callPlugins('onSlideClick') } //Check for Current Position if (!_this.positions.current && _this.positions.current!==0) { _this.positions.current = _this.positions.start } //For case if slider touched but not moved if (params.followFinger) { if (isHorizontal) _this.setTransform( _this.positions.current, 0, 0) else _this.setTransform( 0, _this.positions.current, 0) } //-- // TouchEndTime var tet = new Date() _this.times.end = tet.getTime(); //Difference _this.touches.diff = _this.touches.current - _this.touches.start _this.touches.abs = Math.abs(_this.touches.diff) _this.positions.diff = _this.positions.current - _this.positions.start _this.positions.abs = Math.abs(_this.positions.diff) var diff = _this.positions.diff ; var diffAbs =_this.positions.abs ; if(diffAbs < 5 && (_this.times.end - _this.times.start) < 300 && _this.allowLinks == false) { _this.swipeReset() //Release inner links if (params.preventLinks) { _this.allowLinks = true; } } var maxPosition = wrapperSize - containerSize; if (params.scrollContainer) { maxPosition = slideSize - containerSize } //Prevent Negative Back Sliding if (_this.positions.current > 0) { _this.swipeReset() if (params.onTouchEnd) params.onTouchEnd(_this) _this.callPlugins('onTouchEnd'); return } //Prevent After-End Sliding if (_this.positions.current < -maxPosition) { _this.swipeReset() if (params.onTouchEnd) params.onTouchEnd(_this) _this.callPlugins('onTouchEnd'); return } //Free Mode if (params.freeMode) { if ( (_this.times.end - _this.times.start) < 300 && params.freeModeFluid ) { var newPosition = _this.positions.current + _this.touches.diff * 2 ; if (newPosition < maxPosition*(-1)) newPosition = -maxPosition; if (newPosition > 0) newPosition = 0; if (isHorizontal) _this.setTransform( newPosition, 0, 0) else _this.setTransform( 0, newPosition, 0) _this.setTransition( (_this.times.end - _this.times.start)*2 ) _this.updateActiveSlide(newPosition) } if (!params.freeModeFluid || (_this.times.end - _this.times.start) >= 300) _this.updateActiveSlide(_this.positions.current) if (params.onTouchEnd) params.onTouchEnd(_this) _this.callPlugins('onTouchEnd'); return } //Direction direction = diff < 0 ? "toNext" : "toPrev" //Short Touches if (direction=="toNext" && ( _this.times.end - _this.times.start <= 300 ) ) { if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset() else _this.swipeNext(true); } if (direction=="toPrev" && ( _this.times.end - _this.times.start <= 300 ) ) { if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset() else _this.swipePrev(true); } //Long Touches var groupSize = slideSize * params.slidesPerGroup if (direction=="toNext" && ( _this.times.end - _this.times.start > 300 ) ) { if (diffAbs >= groupSize*0.5) { _this.swipeNext(true) } else { _this.swipeReset() } } if (direction=="toPrev" && ( _this.times.end - _this.times.start > 300 ) ) { if (diffAbs >= groupSize*0.5) { _this.swipePrev(true); } else { _this.swipeReset() } } if (params.onTouchEnd) params.onTouchEnd(_this) _this.callPlugins('onTouchEnd'); } /*========================= Swipe Functions ===========================*/ _this.swipeNext = function(internal) { if (!internal && params.loop) _this.fixLoop(); if (!internal && params.autoPlay) _this.stopAutoPlay(); _this.callPlugins('onSwipeNext'); var getTranslate = isHorizontal ? _this.getTranslate('x') : _this.getTranslate('y'); var groupSize = slideSize * params.slidesPerGroup; var newPosition = Math.floor(Math.abs(getTranslate)/Math.floor(groupSize))*groupSize + groupSize; var curPos = Math.abs(getTranslate) if (newPosition==wrapperSize) return; if (curPos >= maxPos() && !params.loop) return; if (newPosition > maxPos() && !params.loop) { newPosition = maxPos() }; if (params.loop) { if (newPosition >= (maxPos()+containerSize)) newPosition = maxPos()+containerSize } if (isHorizontal) { _this.setTransform(-newPosition,0,0) } else { _this.setTransform(0,-newPosition,0) } _this.setTransition( params.speed) //Update Active Slide _this.updateActiveSlide(-newPosition) //Run Callbacks slideChangeCallbacks() return true } _this.swipePrev = function(internal) { if (!internal&¶ms.loop) _this.fixLoop(); if (!internal && params.autoPlay) _this.stopAutoPlay(); _this.callPlugins('onSwipePrev'); var getTranslate = Math.ceil( isHorizontal ? _this.getTranslate('x') : _this.getTranslate('y') ); var groupSize = slideSize * params.slidesPerGroup; var newPosition = (Math.ceil(-getTranslate/groupSize)-1)*groupSize; if (newPosition < 0) newPosition = 0; if (isHorizontal) { _this.setTransform(-newPosition,0,0) } else { _this.setTransform(0,-newPosition,0) } _this.setTransition(params.speed) //Update Active Slide _this.updateActiveSlide(-newPosition) //Run Callbacks slideChangeCallbacks() return true } _this.swipeReset = function(prevention) { _this.callPlugins('onSwipeReset'); var getTranslate = isHorizontal ? _this.getTranslate('x') : _this.getTranslate('y'); var groupSize = slideSize * params.slidesPerGroup var newPosition = getTranslate<0 ? Math.round(getTranslate/groupSize)*groupSize : 0 var maxPosition = -maxPos() if (params.scrollContainer) { newPosition = getTranslate<0 ? getTranslate : 0; maxPosition = containerSize - slideSize; } if (newPosition <= maxPosition) { newPosition = maxPosition } if (params.scrollContainer && (containerSize>slideSize)) { newPosition = 0; } if (params.mode=='horizontal') { _this.setTransform(newPosition,0,0) } else { _this.setTransform(0,newPosition,0) } _this.setTransition( params.speed) //Update Active Slide _this.updateActiveSlide(newPosition) //Reset Callback if (params.onSlideReset) { params.onSlideReset(_this) } return true } var firstTimeLoopPositioning = true; _this.swipeTo = function (index, speed, runCallbacks) { index = parseInt(index, 10); //type cast to int _this.callPlugins('onSwipeTo', {index:index, speed:speed}); if (index > (numOfSlides-1)) return; if (index<0 && !params.loop) return; runCallbacks = runCallbacks===false ? false : runCallbacks || true var speed = speed===0 ? speed : speed || params.speed; if (params.loop) index = index + params.slidesPerSlide; if (index > numOfSlides - params.slidesPerSlide) index = numOfSlides - params.slidesPerSlide; var newPosition = -index*slideSize ; if(firstTimeLoopPositioning && params.loop && params.initialSlide > 0 && params.initialSlide < numOfSlides){ newPosition = newPosition - params.initialSlide * slideSize; firstTimeLoopPositioning = false; } if (isHorizontal) { _this.setTransform(newPosition,0,0) } else { _this.setTransform(0,newPosition,0) } _this.setTransition( speed ) _this.updateActiveSlide(newPosition) //Run Callbacks if (runCallbacks) slideChangeCallbacks() return true } //Prevent Multiple Callbacks _this._queueStartCallbacks = false; _this._queueEndCallbacks = false; function slideChangeCallbacks() { //Transition Start Callback _this.callPlugins('onSlideChangeStart'); if (params.onSlideChangeStart && !_this._queueStartCallbacks) { _this._queueStartCallbacks = true; params.onSlideChangeStart(_this) _this.transitionEnd(function(){ _this._queueStartCallbacks = false; }) } //Transition End Callback if (params.onSlideChangeEnd && !_this._queueEndCallbacks) { if(_this.support.transitions) { _this._queueEndCallbacks = true; _this.transitionEnd(params.onSlideChangeEnd) } else { setTimeout(function(){ params.onSlideChangeEnd(_this) },10) } } } _this.updateActiveSlide = function(position) { _this.previousIndex = _this.previousSlide = _this.realIndex _this.realIndex = Math.round(-position/slideSize) if (!params.loop) _this.activeIndex = _this.realIndex; else { _this.activeIndex = _this.realIndex-params.slidesPerSlide if (_this.activeIndex>=numOfSlides-params.slidesPerSlide*2) { _this.activeIndex = numOfSlides - params.slidesPerSlide*2 - _this.activeIndex } if (_this.activeIndex<0) { _this.activeIndex = numOfSlides - params.slidesPerSlide*2 + _this.activeIndex } } if (_this.realIndex==numOfSlides) _this.realIndex = numOfSlides-1 if (_this.realIndex<0) _this.realIndex = 0 //Legacy _this.activeSlide = _this.activeIndex; // mark active slide var activeClassRegexp = new RegExp( "\\s*" + params.slideActiveClass ); for ( var i = 0; i < numOfSlides; ++i ) { _this.slides[ i ].className = _this.slides[ i ].className.replace( activeClassRegexp, '' ); } _this.slides[ _this.activeIndex ].className += ' ' + params.slideActiveClass; //Update Pagination if (params.pagination) { _this.updatePagination() } } /*========================= Loop Fixes ===========================*/ _this.fixLoop = function(){ //Fix For Negative Oversliding if (_this.realIndex < params.slidesPerSlide) { var newIndex = numOfSlides - params.slidesPerSlide*3 + _this.realIndex; _this.swipeTo(newIndex,0, false) } //Fix For Positive Oversliding if (_this.realIndex > numOfSlides - params.slidesPerSlide*2) { var newIndex = -numOfSlides + _this.realIndex + params.slidesPerSlide _this.swipeTo(newIndex,0, false) } } if (params.loop) { _this.swipeTo(0,0, false) } } Swiper.prototype = { plugins : {}, //Transition End transitionEnd : function(callback, permanent) { var a = this var el = a.wrapper var events = ['webkitTransitionEnd','transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd']; if (callback) { function fireCallBack() { callback(a) a._queueEndCallbacks = false if (!permanent) { for (var i=0; i