2706 lines
103 KiB
JavaScript
Executable File
2706 lines
103 KiB
JavaScript
Executable File
var Swiper = function (selector, params) {
|
|
'use strict';
|
|
|
|
/*=========================
|
|
A little bit dirty but required part for IE8 and old FF support
|
|
===========================*/
|
|
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;
|
|
};
|
|
}
|
|
if (!Array.prototype.indexOf) {
|
|
Array.prototype.indexOf = function (obj, start) {
|
|
for (var i = (start || 0), j = this.length; i < j; i++) {
|
|
if (this[i] === obj) { return i; }
|
|
}
|
|
return -1;
|
|
};
|
|
}
|
|
if (!document.querySelectorAll) {
|
|
if (!window.jQuery) return;
|
|
}
|
|
function $$(selector, context) {
|
|
if (document.querySelectorAll)
|
|
return (context || document).querySelectorAll(selector);
|
|
else
|
|
return jQuery(selector, context);
|
|
}
|
|
|
|
/*=========================
|
|
Check for correct selector
|
|
===========================*/
|
|
if (typeof selector === 'undefined') return;
|
|
|
|
if (!(selector.nodeType)) {
|
|
if ($$(selector).length === 0) return;
|
|
}
|
|
|
|
/*=========================
|
|
_this
|
|
===========================*/
|
|
var _this = this;
|
|
|
|
/*=========================
|
|
Default Flags and vars
|
|
===========================*/
|
|
_this.touches = {
|
|
start: 0,
|
|
startX: 0,
|
|
startY: 0,
|
|
current: 0,
|
|
currentX: 0,
|
|
currentY: 0,
|
|
diff: 0,
|
|
abs: 0
|
|
};
|
|
_this.positions = {
|
|
start: 0,
|
|
abs: 0,
|
|
diff: 0,
|
|
current: 0
|
|
};
|
|
_this.times = {
|
|
start: 0,
|
|
end: 0
|
|
};
|
|
|
|
_this.id = (new Date()).getTime();
|
|
_this.container = (selector.nodeType) ? selector : $$(selector)[0];
|
|
_this.isTouched = false;
|
|
_this.isMoved = false;
|
|
_this.activeIndex = 0;
|
|
_this.centerIndex = 0;
|
|
_this.activeLoaderIndex = 0;
|
|
_this.activeLoopIndex = 0;
|
|
_this.previousIndex = null;
|
|
_this.velocity = 0;
|
|
_this.snapGrid = [];
|
|
_this.slidesGrid = [];
|
|
_this.imagesToLoad = [];
|
|
_this.imagesLoaded = 0;
|
|
_this.wrapperLeft = 0;
|
|
_this.wrapperRight = 0;
|
|
_this.wrapperTop = 0;
|
|
_this.wrapperBottom = 0;
|
|
_this.isAndroid = navigator.userAgent.toLowerCase().indexOf('android') >= 0;
|
|
var wrapper, slideSize, wrapperSize, direction, isScrolling, containerSize;
|
|
|
|
/*=========================
|
|
Default Parameters
|
|
===========================*/
|
|
var defaults = {
|
|
eventTarget: 'wrapper', // or 'container'
|
|
mode : 'horizontal', // or 'vertical'
|
|
touchRatio : 1,
|
|
speed : 300,
|
|
freeMode : false,
|
|
freeModeFluid : false,
|
|
momentumRatio: 1,
|
|
momentumBounce: true,
|
|
momentumBounceRatio: 1,
|
|
slidesPerView : 1,
|
|
slidesPerGroup : 1,
|
|
simulateTouch : true,
|
|
followFinger : true,
|
|
shortSwipes : true,
|
|
longSwipesRatio: 0.5,
|
|
moveStartThreshold: false,
|
|
onlyExternal : false,
|
|
createPagination : true,
|
|
pagination : false,
|
|
paginationElement: 'span',
|
|
paginationClickable: false,
|
|
paginationAsRange: true,
|
|
resistance : true, // or false or 100%
|
|
scrollContainer : false,
|
|
preventLinks : true,
|
|
preventLinksPropagation: false,
|
|
noSwiping : false, // or class
|
|
noSwipingClass : 'swiper-no-swiping', //:)
|
|
initialSlide: 0,
|
|
keyboardControl: false,
|
|
mousewheelControl : false,
|
|
mousewheelControlForceToAxis : false,
|
|
useCSS3Transforms : true,
|
|
// Autoplay
|
|
autoplay: false,
|
|
autoplayDisableOnInteraction: true,
|
|
autoplayStopOnLast: false,
|
|
//Loop mode
|
|
loop: false,
|
|
loopAdditionalSlides: 0,
|
|
//Auto Height
|
|
calculateHeight: false,
|
|
cssWidthAndHeight: false,
|
|
//Images Preloader
|
|
updateOnImagesReady : true,
|
|
//Form elements
|
|
releaseFormElements : true,
|
|
//Watch for active slide, useful when use effects on different slide states
|
|
watchActiveIndex: false,
|
|
//Slides Visibility Fit
|
|
visibilityFullFit : false,
|
|
//Slides Offset
|
|
offsetPxBefore : 0,
|
|
offsetPxAfter : 0,
|
|
offsetSlidesBefore : 0,
|
|
offsetSlidesAfter : 0,
|
|
centeredSlides: false,
|
|
//Queue callbacks
|
|
queueStartCallbacks : false,
|
|
queueEndCallbacks : false,
|
|
//Auto Resize
|
|
autoResize : true,
|
|
resizeReInit : false,
|
|
//DOMAnimation
|
|
DOMAnimation : true,
|
|
//Slides Loader
|
|
loader: {
|
|
slides: [], //array with slides
|
|
slidesHTMLType: 'inner', // or 'outer'
|
|
surroundGroups: 1, //keep preloaded slides groups around view
|
|
logic: 'reload', //or 'change'
|
|
loadAllSlides: false
|
|
},
|
|
//Namespace
|
|
slideElement: 'div',
|
|
slideClass: 'swiper-slide',
|
|
slideActiveClass: 'swiper-slide-active',
|
|
slideVisibleClass: 'swiper-slide-visible',
|
|
slideDuplicateClass: 'swiper-slide-duplicate',
|
|
wrapperClass: 'swiper-wrapper',
|
|
paginationElementClass: 'swiper-pagination-switch',
|
|
paginationActiveClass: 'swiper-active-switch',
|
|
paginationVisibleClass: 'swiper-visible-switch'
|
|
};
|
|
params = params || {};
|
|
for (var prop in defaults) {
|
|
if (prop in params && typeof params[prop] === 'object') {
|
|
for (var subProp in defaults[prop]) {
|
|
if (! (subProp in params[prop])) {
|
|
params[prop][subProp] = defaults[prop][subProp];
|
|
}
|
|
}
|
|
}
|
|
else if (! (prop in params)) {
|
|
params[prop] = defaults[prop];
|
|
}
|
|
}
|
|
_this.params = params;
|
|
if (params.scrollContainer) {
|
|
params.freeMode = true;
|
|
params.freeModeFluid = true;
|
|
}
|
|
if (params.loop) {
|
|
params.resistance = '100%';
|
|
}
|
|
var isH = params.mode === 'horizontal';
|
|
|
|
/*=========================
|
|
Define Touch Events
|
|
===========================*/
|
|
var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];
|
|
if (_this.browser.ie10) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];
|
|
if (_this.browser.ie11) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];
|
|
|
|
_this.touchEvents = {
|
|
touchStart : _this.support.touch || !params.simulateTouch ? 'touchstart' : desktopEvents[0],
|
|
touchMove : _this.support.touch || !params.simulateTouch ? 'touchmove' : desktopEvents[1],
|
|
touchEnd : _this.support.touch || !params.simulateTouch ? 'touchend' : desktopEvents[2]
|
|
};
|
|
|
|
/*=========================
|
|
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(/\s+/);
|
|
for (var j = 0; j < _wrapperClasses.length; j++) {
|
|
if (_wrapperClasses[j] === params.wrapperClass) {
|
|
wrapper = _this.container.childNodes[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
_this.wrapper = wrapper;
|
|
/*=========================
|
|
Slide API
|
|
===========================*/
|
|
_this._extendSwiperSlide = function (el) {
|
|
el.append = function () {
|
|
if (params.loop) {
|
|
el.insertAfter(_this.slides.length - _this.loopedSlides);
|
|
}
|
|
else {
|
|
_this.wrapper.appendChild(el);
|
|
_this.reInit();
|
|
}
|
|
|
|
return el;
|
|
};
|
|
el.prepend = function () {
|
|
if (params.loop) {
|
|
_this.wrapper.insertBefore(el, _this.slides[_this.loopedSlides]);
|
|
_this.removeLoopedSlides();
|
|
_this.calcSlides();
|
|
_this.createLoop();
|
|
}
|
|
else {
|
|
_this.wrapper.insertBefore(el, _this.wrapper.firstChild);
|
|
}
|
|
_this.reInit();
|
|
return el;
|
|
};
|
|
el.insertAfter = function (index) {
|
|
if (typeof index === 'undefined') return false;
|
|
var beforeSlide;
|
|
|
|
if (params.loop) {
|
|
beforeSlide = _this.slides[index + 1 + _this.loopedSlides];
|
|
if (beforeSlide) {
|
|
_this.wrapper.insertBefore(el, beforeSlide);
|
|
}
|
|
else {
|
|
_this.wrapper.appendChild(el);
|
|
}
|
|
_this.removeLoopedSlides();
|
|
_this.calcSlides();
|
|
_this.createLoop();
|
|
}
|
|
else {
|
|
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 (typeof value === 'undefined') {
|
|
return el.getAttribute('data-' + name);
|
|
}
|
|
else {
|
|
el.setAttribute('data-' + name, value);
|
|
return el;
|
|
}
|
|
};
|
|
el.getWidth = function (outer) {
|
|
return _this.h.getWidth(el, outer);
|
|
};
|
|
el.getHeight = function (outer) {
|
|
return _this.h.getHeight(el, outer);
|
|
};
|
|
el.getOffset = function () {
|
|
return _this.h.getOffset(el);
|
|
};
|
|
return el;
|
|
};
|
|
|
|
//Calculate information about number of slides
|
|
_this.calcSlides = function (forceCalcSlides) {
|
|
var oldNumber = _this.slides ? _this.slides.length : false;
|
|
_this.slides = [];
|
|
_this.displaySlides = [];
|
|
for (var i = 0; i < _this.wrapper.childNodes.length; i++) {
|
|
if (_this.wrapper.childNodes[i].className) {
|
|
var _className = _this.wrapper.childNodes[i].className;
|
|
var _slideClasses = _className.split(/\s+/);
|
|
for (var j = 0; j < _slideClasses.length; j++) {
|
|
if (_slideClasses[j] === params.slideClass) {
|
|
_this.slides.push(_this.wrapper.childNodes[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (i = _this.slides.length - 1; i >= 0; i--) {
|
|
_this._extendSwiperSlide(_this.slides[i]);
|
|
}
|
|
if (oldNumber === false) return;
|
|
if (oldNumber !== _this.slides.length || forceCalcSlides) {
|
|
|
|
// Number of slides has been changed
|
|
removeSlideEvents();
|
|
addSlideEvents();
|
|
_this.updateActiveSlide();
|
|
if (_this.params.pagination) _this.createPagination();
|
|
_this.callPlugins('numberOfSlidesChanged');
|
|
}
|
|
};
|
|
|
|
//Create Slide
|
|
_this.createSlide = function (html, slideClassList, el) {
|
|
slideClassList = slideClassList || _this.params.slideClass;
|
|
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 (typeof index === 'undefined') 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]) {
|
|
if (params.loop) {
|
|
if (!_this.slides[index + _this.loopedSlides]) return false;
|
|
_this.slides[index + _this.loopedSlides].remove();
|
|
_this.removeLoopedSlides();
|
|
_this.calcSlides();
|
|
_this.createLoop();
|
|
}
|
|
else _this.slides[index].remove();
|
|
return true;
|
|
}
|
|
else return false;
|
|
};
|
|
_this.removeLastSlide = function () {
|
|
if (_this.slides.length > 0) {
|
|
if (params.loop) {
|
|
_this.slides[_this.slides.length - 1 - _this.loopedSlides].remove();
|
|
_this.removeLoopedSlides();
|
|
_this.calcSlides();
|
|
_this.createLoop();
|
|
}
|
|
else _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.activeSlide = function () {
|
|
return _this.slides[_this.activeIndex];
|
|
};
|
|
|
|
/*=========================
|
|
Wrapper for Callbacks : Allows additive callbacks via function arrays
|
|
===========================*/
|
|
_this.fireCallback = function () {
|
|
var callback = arguments[0];
|
|
if (Object.prototype.toString.call(callback) === '[object Array]') {
|
|
for (var i = 0; i < callback.length; i++) {
|
|
if (typeof callback[i] === 'function') {
|
|
callback[i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
|
|
}
|
|
}
|
|
} else if (Object.prototype.toString.call(callback) === '[object String]') {
|
|
if (params['on' + callback]) _this.fireCallback(params['on' + callback]);
|
|
} else {
|
|
callback(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
|
|
}
|
|
};
|
|
function isArray(obj) {
|
|
if (Object.prototype.toString.apply(obj) === '[object Array]') return true;
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Allows user to add callbacks, rather than replace them
|
|
* @param callback
|
|
* @param func
|
|
* @return {*}
|
|
*/
|
|
_this.addCallback = function (callback, func) {
|
|
var _this = this, tempFunc;
|
|
if (_this.params['on' + callback]) {
|
|
if (isArray(this.params['on' + callback])) {
|
|
return this.params['on' + callback].push(func);
|
|
} else if (typeof this.params['on' + callback] === 'function') {
|
|
tempFunc = this.params['on' + callback];
|
|
this.params['on' + callback] = [];
|
|
this.params['on' + callback].push(tempFunc);
|
|
return this.params['on' + callback].push(func);
|
|
}
|
|
} else {
|
|
this.params['on' + callback] = [];
|
|
return this.params['on' + callback].push(func);
|
|
}
|
|
};
|
|
_this.removeCallbacks = function (callback) {
|
|
if (_this.params['on' + callback]) {
|
|
_this.params['on' + callback] = null;
|
|
}
|
|
};
|
|
|
|
/*=========================
|
|
Plugins API
|
|
===========================*/
|
|
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);
|
|
}
|
|
}
|
|
};
|
|
|
|
/*=========================
|
|
Windows Phone 8 Fix
|
|
===========================*/
|
|
if ((_this.browser.ie10 || _this.browser.ie11) && !params.onlyExternal) {
|
|
_this.wrapper.classList.add('swiper-wp8-' + (isH ? 'horizontal' : 'vertical'));
|
|
}
|
|
|
|
/*=========================
|
|
Free Mode Class
|
|
===========================*/
|
|
if (params.freeMode) {
|
|
_this.container.className += ' swiper-free-mode';
|
|
}
|
|
|
|
/*==================================================
|
|
Init/Re-init/Resize Fix
|
|
====================================================*/
|
|
_this.initialized = false;
|
|
_this.init = function (force, forceCalcSlides) {
|
|
var _width = _this.h.getWidth(_this.container);
|
|
var _height = _this.h.getHeight(_this.container);
|
|
if (_width === _this.width && _height === _this.height && !force) return;
|
|
_this.width = _width;
|
|
_this.height = _height;
|
|
|
|
var slideWidth, slideHeight, slideMaxHeight, wrapperWidth, wrapperHeight, slideLeft;
|
|
var i; // loop index variable to avoid JSHint W004 / W038
|
|
containerSize = isH ? _width : _height;
|
|
var wrapper = _this.wrapper;
|
|
|
|
if (force) {
|
|
_this.calcSlides(forceCalcSlides);
|
|
}
|
|
|
|
if (params.slidesPerView === 'auto') {
|
|
//Auto mode
|
|
var slidesWidth = 0;
|
|
var slidesHeight = 0;
|
|
|
|
//Unset Styles
|
|
if (params.slidesOffset > 0) {
|
|
wrapper.style.paddingLeft = '';
|
|
wrapper.style.paddingRight = '';
|
|
wrapper.style.paddingTop = '';
|
|
wrapper.style.paddingBottom = '';
|
|
}
|
|
wrapper.style.width = '';
|
|
wrapper.style.height = '';
|
|
if (params.offsetPxBefore > 0) {
|
|
if (isH) _this.wrapperLeft = params.offsetPxBefore;
|
|
else _this.wrapperTop = params.offsetPxBefore;
|
|
}
|
|
if (params.offsetPxAfter > 0) {
|
|
if (isH) _this.wrapperRight = params.offsetPxAfter;
|
|
else _this.wrapperBottom = params.offsetPxAfter;
|
|
}
|
|
|
|
if (params.centeredSlides) {
|
|
if (isH) {
|
|
_this.wrapperLeft = (containerSize - this.slides[0].getWidth(true)) / 2;
|
|
_this.wrapperRight = (containerSize - _this.slides[_this.slides.length - 1].getWidth(true)) / 2;
|
|
}
|
|
else {
|
|
_this.wrapperTop = (containerSize - _this.slides[0].getHeight(true)) / 2;
|
|
_this.wrapperBottom = (containerSize - _this.slides[_this.slides.length - 1].getHeight(true)) / 2;
|
|
}
|
|
}
|
|
|
|
if (isH) {
|
|
if (_this.wrapperLeft >= 0) wrapper.style.paddingLeft = _this.wrapperLeft + 'px';
|
|
if (_this.wrapperRight >= 0) wrapper.style.paddingRight = _this.wrapperRight + 'px';
|
|
}
|
|
else {
|
|
if (_this.wrapperTop >= 0) wrapper.style.paddingTop = _this.wrapperTop + 'px';
|
|
if (_this.wrapperBottom >= 0) wrapper.style.paddingBottom = _this.wrapperBottom + 'px';
|
|
}
|
|
slideLeft = 0;
|
|
var centeredSlideLeft = 0;
|
|
_this.snapGrid = [];
|
|
_this.slidesGrid = [];
|
|
|
|
slideMaxHeight = 0;
|
|
for (i = 0; i < _this.slides.length; i++) {
|
|
slideWidth = _this.slides[i].getWidth(true);
|
|
slideHeight = _this.slides[i].getHeight(true);
|
|
if (params.calculateHeight) {
|
|
slideMaxHeight = Math.max(slideMaxHeight, slideHeight);
|
|
}
|
|
var _slideSize = isH ? slideWidth : slideHeight;
|
|
if (params.centeredSlides) {
|
|
var nextSlideWidth = i === _this.slides.length - 1 ? 0 : _this.slides[i + 1].getWidth(true);
|
|
var nextSlideHeight = i === _this.slides.length - 1 ? 0 : _this.slides[i + 1].getHeight(true);
|
|
var nextSlideSize = isH ? nextSlideWidth : nextSlideHeight;
|
|
if (_slideSize > containerSize) {
|
|
for (var j = 0; j <= Math.floor(_slideSize / (containerSize + _this.wrapperLeft)); j++) {
|
|
if (j === 0) _this.snapGrid.push(slideLeft + _this.wrapperLeft);
|
|
else _this.snapGrid.push(slideLeft + _this.wrapperLeft + containerSize * j);
|
|
}
|
|
_this.slidesGrid.push(slideLeft + _this.wrapperLeft);
|
|
}
|
|
else {
|
|
_this.snapGrid.push(centeredSlideLeft);
|
|
_this.slidesGrid.push(centeredSlideLeft);
|
|
}
|
|
|
|
centeredSlideLeft += _slideSize / 2 + nextSlideSize / 2;
|
|
|
|
}
|
|
else {
|
|
if (_slideSize > containerSize) {
|
|
for (var k = 0; k <= Math.floor(_slideSize / containerSize); k++) {
|
|
_this.snapGrid.push(slideLeft + containerSize * k);
|
|
}
|
|
}
|
|
else {
|
|
_this.snapGrid.push(slideLeft);
|
|
}
|
|
_this.slidesGrid.push(slideLeft);
|
|
}
|
|
|
|
slideLeft += _slideSize;
|
|
|
|
slidesWidth += slideWidth;
|
|
slidesHeight += slideHeight;
|
|
}
|
|
if (params.calculateHeight) _this.height = slideMaxHeight;
|
|
if (isH) {
|
|
wrapperSize = slidesWidth + _this.wrapperRight + _this.wrapperLeft;
|
|
wrapper.style.width = (slidesWidth) + 'px';
|
|
wrapper.style.height = (_this.height) + 'px';
|
|
}
|
|
else {
|
|
wrapperSize = slidesHeight + _this.wrapperTop + _this.wrapperBottom;
|
|
wrapper.style.width = (_this.width) + 'px';
|
|
wrapper.style.height = (slidesHeight) + 'px';
|
|
}
|
|
|
|
}
|
|
else if (params.scrollContainer) {
|
|
//Scroll Container
|
|
wrapper.style.width = '';
|
|
wrapper.style.height = '';
|
|
wrapperWidth = _this.slides[0].getWidth(true);
|
|
wrapperHeight = _this.slides[0].getHeight(true);
|
|
wrapperSize = isH ? wrapperWidth : wrapperHeight;
|
|
wrapper.style.width = wrapperWidth + 'px';
|
|
wrapper.style.height = wrapperHeight + 'px';
|
|
slideSize = isH ? wrapperWidth : wrapperHeight;
|
|
|
|
}
|
|
else {
|
|
//For usual slides
|
|
if (params.calculateHeight) {
|
|
slideMaxHeight = 0;
|
|
wrapperHeight = 0;
|
|
//ResetWrapperSize
|
|
if (!isH) _this.container.style.height = '';
|
|
wrapper.style.height = '';
|
|
|
|
for (i = 0; i < _this.slides.length; i++) {
|
|
//ResetSlideSize
|
|
_this.slides[i].style.height = '';
|
|
slideMaxHeight = Math.max(_this.slides[i].getHeight(true), slideMaxHeight);
|
|
if (!isH) wrapperHeight += _this.slides[i].getHeight(true);
|
|
}
|
|
slideHeight = slideMaxHeight;
|
|
_this.height = slideHeight;
|
|
|
|
if (isH) wrapperHeight = slideHeight;
|
|
else {
|
|
containerSize = slideHeight;
|
|
_this.container.style.height = containerSize + 'px';
|
|
}
|
|
}
|
|
else {
|
|
slideHeight = isH ? _this.height : _this.height / params.slidesPerView;
|
|
wrapperHeight = isH ? _this.height : _this.slides.length * slideHeight;
|
|
}
|
|
slideWidth = isH ? _this.width / params.slidesPerView : _this.width;
|
|
wrapperWidth = isH ? _this.slides.length * slideWidth : _this.width;
|
|
slideSize = isH ? slideWidth : slideHeight;
|
|
|
|
if (params.offsetSlidesBefore > 0) {
|
|
if (isH) _this.wrapperLeft = slideSize * params.offsetSlidesBefore;
|
|
else _this.wrapperTop = slideSize * params.offsetSlidesBefore;
|
|
}
|
|
if (params.offsetSlidesAfter > 0) {
|
|
if (isH) _this.wrapperRight = slideSize * params.offsetSlidesAfter;
|
|
else _this.wrapperBottom = slideSize * params.offsetSlidesAfter;
|
|
}
|
|
if (params.offsetPxBefore > 0) {
|
|
if (isH) _this.wrapperLeft = params.offsetPxBefore;
|
|
else _this.wrapperTop = params.offsetPxBefore;
|
|
}
|
|
if (params.offsetPxAfter > 0) {
|
|
if (isH) _this.wrapperRight = params.offsetPxAfter;
|
|
else _this.wrapperBottom = params.offsetPxAfter;
|
|
}
|
|
if (params.centeredSlides) {
|
|
if (isH) {
|
|
_this.wrapperLeft = (containerSize - slideSize) / 2;
|
|
_this.wrapperRight = (containerSize - slideSize) / 2;
|
|
}
|
|
else {
|
|
_this.wrapperTop = (containerSize - slideSize) / 2;
|
|
_this.wrapperBottom = (containerSize - slideSize) / 2;
|
|
}
|
|
}
|
|
if (isH) {
|
|
if (_this.wrapperLeft > 0) wrapper.style.paddingLeft = _this.wrapperLeft + 'px';
|
|
if (_this.wrapperRight > 0) wrapper.style.paddingRight = _this.wrapperRight + 'px';
|
|
}
|
|
else {
|
|
if (_this.wrapperTop > 0) wrapper.style.paddingTop = _this.wrapperTop + 'px';
|
|
if (_this.wrapperBottom > 0) wrapper.style.paddingBottom = _this.wrapperBottom + 'px';
|
|
}
|
|
|
|
wrapperSize = isH ? wrapperWidth + _this.wrapperRight + _this.wrapperLeft : wrapperHeight + _this.wrapperTop + _this.wrapperBottom;
|
|
if (!params.cssWidthAndHeight) {
|
|
if (parseFloat(wrapperWidth) > 0) {
|
|
wrapper.style.width = wrapperWidth + 'px';
|
|
}
|
|
if (parseFloat(wrapperHeight) > 0) {
|
|
wrapper.style.height = wrapperHeight + 'px';
|
|
}
|
|
}
|
|
slideLeft = 0;
|
|
_this.snapGrid = [];
|
|
_this.slidesGrid = [];
|
|
for (i = 0; i < _this.slides.length; i++) {
|
|
_this.snapGrid.push(slideLeft);
|
|
_this.slidesGrid.push(slideLeft);
|
|
slideLeft += slideSize;
|
|
if (!params.cssWidthAndHeight) {
|
|
if (parseFloat(slideWidth) > 0) {
|
|
_this.slides[i].style.width = slideWidth + 'px';
|
|
}
|
|
if (parseFloat(slideHeight) > 0) {
|
|
_this.slides[i].style.height = slideHeight + 'px';
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (!_this.initialized) {
|
|
_this.callPlugins('onFirstInit');
|
|
if (params.onFirstInit) _this.fireCallback(params.onFirstInit, _this);
|
|
}
|
|
else {
|
|
_this.callPlugins('onInit');
|
|
if (params.onInit) _this.fireCallback(params.onInit, _this);
|
|
}
|
|
_this.initialized = true;
|
|
};
|
|
|
|
_this.reInit = function (forceCalcSlides) {
|
|
_this.init(true, forceCalcSlides);
|
|
};
|
|
|
|
_this.resizeFix = function (reInit) {
|
|
_this.callPlugins('beforeResizeFix');
|
|
|
|
_this.init(params.resizeReInit || reInit);
|
|
|
|
// swipe to active slide in fixed mode
|
|
if (!params.freeMode) {
|
|
_this.swipeTo((params.loop ? _this.activeLoopIndex : _this.activeIndex), 0, false);
|
|
// Fix autoplay
|
|
if (params.autoplay) {
|
|
if (_this.support.transitions && typeof autoplayTimeoutId !== 'undefined') {
|
|
if (typeof autoplayTimeoutId !== 'undefined') {
|
|
clearTimeout(autoplayTimeoutId);
|
|
autoplayTimeoutId = undefined;
|
|
_this.startAutoplay();
|
|
}
|
|
}
|
|
else {
|
|
if (typeof autoplayIntervalId !== 'undefined') {
|
|
clearInterval(autoplayIntervalId);
|
|
autoplayIntervalId = undefined;
|
|
_this.startAutoplay();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// move wrapper to the beginning in free mode
|
|
else if (_this.getWrapperTranslate() < -maxWrapperPosition()) {
|
|
_this.setWrapperTransition(0);
|
|
_this.setWrapperTranslate(-maxWrapperPosition());
|
|
}
|
|
|
|
_this.callPlugins('afterResizeFix');
|
|
};
|
|
|
|
/*==========================================
|
|
Max and Min Positions
|
|
============================================*/
|
|
function maxWrapperPosition() {
|
|
var a = (wrapperSize - containerSize);
|
|
if (params.freeMode) {
|
|
a = wrapperSize - containerSize;
|
|
}
|
|
// if (params.loop) a -= containerSize;
|
|
if (params.slidesPerView > _this.slides.length) a = 0;
|
|
if (a < 0) a = 0;
|
|
return a;
|
|
}
|
|
function minWrapperPosition() {
|
|
var a = 0;
|
|
// if (params.loop) a = containerSize;
|
|
return a;
|
|
}
|
|
|
|
/*==========================================
|
|
Event Listeners
|
|
============================================*/
|
|
function initEvents() {
|
|
var bind = _this.h.addEventListener;
|
|
var eventTarget = params.eventTarget === 'wrapper' ? _this.wrapper : _this.container;
|
|
//Touch Events
|
|
if (! (_this.browser.ie10 || _this.browser.ie11)) {
|
|
if (_this.support.touch) {
|
|
bind(eventTarget, 'touchstart', onTouchStart);
|
|
bind(eventTarget, 'touchmove', onTouchMove);
|
|
bind(eventTarget, 'touchend', onTouchEnd);
|
|
}
|
|
if (params.simulateTouch) {
|
|
bind(eventTarget, 'mousedown', onTouchStart);
|
|
bind(document, 'mousemove', onTouchMove);
|
|
bind(document, 'mouseup', onTouchEnd);
|
|
}
|
|
}
|
|
else {
|
|
bind(eventTarget, _this.touchEvents.touchStart, onTouchStart);
|
|
bind(document, _this.touchEvents.touchMove, onTouchMove);
|
|
bind(document, _this.touchEvents.touchEnd, onTouchEnd);
|
|
}
|
|
|
|
//Resize Event
|
|
if (params.autoResize) {
|
|
bind(window, 'resize', _this.resizeFix);
|
|
}
|
|
//Slide Events
|
|
addSlideEvents();
|
|
//Mousewheel
|
|
_this._wheelEvent = false;
|
|
if (params.mousewheelControl) {
|
|
if (document.onmousewheel !== undefined) {
|
|
_this._wheelEvent = 'mousewheel';
|
|
}
|
|
try {
|
|
new WheelEvent('wheel');
|
|
_this._wheelEvent = 'wheel';
|
|
} catch (e) {}
|
|
if (!_this._wheelEvent) {
|
|
_this._wheelEvent = 'DOMMouseScroll';
|
|
}
|
|
|
|
if (_this._wheelEvent) {
|
|
bind(_this.container, _this._wheelEvent, handleMousewheel);
|
|
}
|
|
}
|
|
|
|
//Keyboard
|
|
function _loadImage(src) {
|
|
var image = new Image();
|
|
image.onload = function () {
|
|
_this.imagesLoaded++;
|
|
if (_this.imagesLoaded === _this.imagesToLoad.length) {
|
|
_this.reInit();
|
|
if (params.onImagesReady) _this.fireCallback(params.onImagesReady, _this);
|
|
}
|
|
};
|
|
image.src = src;
|
|
}
|
|
|
|
if (params.keyboardControl) {
|
|
bind(document, 'keydown', handleKeyboardKeys);
|
|
}
|
|
if (params.updateOnImagesReady) {
|
|
_this.imagesToLoad = $$('img', _this.container);
|
|
|
|
for (var i = 0; i < _this.imagesToLoad.length; i++) {
|
|
_loadImage(_this.imagesToLoad[i].getAttribute('src'));
|
|
}
|
|
}
|
|
}
|
|
|
|
//Remove Event Listeners
|
|
_this.destroy = function () {
|
|
var unbind = _this.h.removeEventListener;
|
|
var eventTarget = params.eventTarget === 'wrapper' ? _this.wrapper : _this.container;
|
|
//Touch Events
|
|
if (! (_this.browser.ie10 || _this.browser.ie11)) {
|
|
if (_this.support.touch) {
|
|
unbind(eventTarget, 'touchstart', onTouchStart);
|
|
unbind(eventTarget, 'touchmove', onTouchMove);
|
|
unbind(eventTarget, 'touchend', onTouchEnd);
|
|
}
|
|
if (params.simulateTouch) {
|
|
unbind(eventTarget, 'mousedown', onTouchStart);
|
|
unbind(document, 'mousemove', onTouchMove);
|
|
unbind(document, 'mouseup', onTouchEnd);
|
|
}
|
|
}
|
|
else {
|
|
unbind(eventTarget, _this.touchEvents.touchStart, onTouchStart);
|
|
unbind(document, _this.touchEvents.touchMove, onTouchMove);
|
|
unbind(document, _this.touchEvents.touchEnd, onTouchEnd);
|
|
}
|
|
|
|
//Resize Event
|
|
if (params.autoResize) {
|
|
unbind(window, 'resize', _this.resizeFix);
|
|
}
|
|
|
|
//Init Slide Events
|
|
removeSlideEvents();
|
|
|
|
//Pagination
|
|
if (params.paginationClickable) {
|
|
removePaginationEvents();
|
|
}
|
|
|
|
//Mousewheel
|
|
if (params.mousewheelControl && _this._wheelEvent) {
|
|
unbind(_this.container, _this._wheelEvent, handleMousewheel);
|
|
}
|
|
|
|
//Keyboard
|
|
if (params.keyboardControl) {
|
|
unbind(document, 'keydown', handleKeyboardKeys);
|
|
}
|
|
|
|
//Stop autoplay
|
|
if (params.autoplay) {
|
|
_this.stopAutoplay();
|
|
}
|
|
_this.callPlugins('onDestroy');
|
|
|
|
//Destroy variable
|
|
_this = null;
|
|
};
|
|
|
|
function addSlideEvents() {
|
|
var bind = _this.h.addEventListener,
|
|
i;
|
|
|
|
//Prevent Links Events
|
|
if (params.preventLinks) {
|
|
var links = $$('a', _this.container);
|
|
for (i = 0; i < links.length; i++) {
|
|
bind(links[i], 'click', preventClick);
|
|
}
|
|
}
|
|
//Release Form Elements
|
|
if (params.releaseFormElements) {
|
|
var formElements = $$('input, textarea, select', _this.container);
|
|
for (i = 0; i < formElements.length; i++) {
|
|
bind(formElements[i], _this.touchEvents.touchStart, releaseForms, true);
|
|
}
|
|
}
|
|
|
|
//Slide Clicks & Touches
|
|
if (params.onSlideClick) {
|
|
for (i = 0; i < _this.slides.length; i++) {
|
|
bind(_this.slides[i], 'click', slideClick);
|
|
}
|
|
}
|
|
if (params.onSlideTouch) {
|
|
for (i = 0; i < _this.slides.length; i++) {
|
|
bind(_this.slides[i], _this.touchEvents.touchStart, slideTouch);
|
|
}
|
|
}
|
|
}
|
|
function removeSlideEvents() {
|
|
var unbind = _this.h.removeEventListener,
|
|
i;
|
|
|
|
//Slide Clicks & Touches
|
|
if (params.onSlideClick) {
|
|
for (i = 0; i < _this.slides.length; i++) {
|
|
unbind(_this.slides[i], 'click', slideClick);
|
|
}
|
|
}
|
|
if (params.onSlideTouch) {
|
|
for (i = 0; i < _this.slides.length; i++) {
|
|
unbind(_this.slides[i], _this.touchEvents.touchStart, slideTouch);
|
|
}
|
|
}
|
|
//Release Form Elements
|
|
if (params.releaseFormElements) {
|
|
var formElements = $$('input, textarea, select', _this.container);
|
|
for (i = 0; i < formElements.length; i++) {
|
|
unbind(formElements[i], _this.touchEvents.touchStart, releaseForms, true);
|
|
}
|
|
}
|
|
//Prevent Links Events
|
|
if (params.preventLinks) {
|
|
var links = $$('a', _this.container);
|
|
for (i = 0; i < links.length; i++) {
|
|
unbind(links[i], 'click', preventClick);
|
|
}
|
|
}
|
|
}
|
|
/*==========================================
|
|
Keyboard Control
|
|
============================================*/
|
|
function handleKeyboardKeys(e) {
|
|
var kc = e.keyCode || e.charCode;
|
|
if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) return;
|
|
if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {
|
|
var inView = false;
|
|
//Check that swiper should be inside of visible area of window
|
|
var swiperOffset = _this.h.getOffset(_this.container);
|
|
var scrollLeft = _this.h.windowScroll().left;
|
|
var scrollTop = _this.h.windowScroll().top;
|
|
var windowWidth = _this.h.windowWidth();
|
|
var windowHeight = _this.h.windowHeight();
|
|
var swiperCoord = [
|
|
[swiperOffset.left, swiperOffset.top],
|
|
[swiperOffset.left + _this.width, swiperOffset.top],
|
|
[swiperOffset.left, swiperOffset.top + _this.height],
|
|
[swiperOffset.left + _this.width, swiperOffset.top + _this.height]
|
|
];
|
|
for (var i = 0; i < swiperCoord.length; i++) {
|
|
var point = swiperCoord[i];
|
|
if (
|
|
point[0] >= scrollLeft && point[0] <= scrollLeft + windowWidth &&
|
|
point[1] >= scrollTop && point[1] <= scrollTop + windowHeight
|
|
) {
|
|
inView = true;
|
|
}
|
|
|
|
}
|
|
if (!inView) return;
|
|
}
|
|
if (isH) {
|
|
if (kc === 37 || kc === 39) {
|
|
if (e.preventDefault) e.preventDefault();
|
|
else e.returnValue = false;
|
|
}
|
|
if (kc === 39) _this.swipeNext();
|
|
if (kc === 37) _this.swipePrev();
|
|
}
|
|
else {
|
|
if (kc === 38 || kc === 40) {
|
|
if (e.preventDefault) e.preventDefault();
|
|
else e.returnValue = false;
|
|
}
|
|
if (kc === 40) _this.swipeNext();
|
|
if (kc === 38) _this.swipePrev();
|
|
}
|
|
}
|
|
|
|
/*==========================================
|
|
Mousewheel Control
|
|
============================================*/
|
|
var lastScrollTime = (new Date()).getTime();
|
|
function handleMousewheel(e) {
|
|
var we = _this._wheelEvent;
|
|
var delta = 0;
|
|
|
|
//Opera & IE
|
|
if (e.detail) delta = -e.detail;
|
|
//WebKits
|
|
else if (we === 'mousewheel') {
|
|
if (params.mousewheelControlForceToAxis) {
|
|
if (isH) {
|
|
if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX;
|
|
else return;
|
|
}
|
|
else {
|
|
if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;
|
|
else return;
|
|
}
|
|
}
|
|
else {
|
|
delta = e.wheelDelta;
|
|
}
|
|
}
|
|
//Old FireFox
|
|
else if (we === 'DOMMouseScroll') delta = -e.detail;
|
|
//New FireFox
|
|
else if (we === 'wheel') {
|
|
if (params.mousewheelControlForceToAxis) {
|
|
if (isH) {
|
|
if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX;
|
|
else return;
|
|
}
|
|
else {
|
|
if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;
|
|
else return;
|
|
}
|
|
}
|
|
else {
|
|
delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX : - e.deltaY;
|
|
}
|
|
}
|
|
|
|
if (!params.freeMode) {
|
|
if ((new Date()).getTime() - lastScrollTime > 60) {
|
|
if (delta < 0) _this.swipeNext();
|
|
else _this.swipePrev();
|
|
}
|
|
lastScrollTime = (new Date()).getTime();
|
|
|
|
}
|
|
else {
|
|
//Freemode or scrollContainer:
|
|
var position = _this.getWrapperTranslate() + delta;
|
|
|
|
if (position > 0) position = 0;
|
|
if (position < -maxWrapperPosition()) position = -maxWrapperPosition();
|
|
|
|
_this.setWrapperTransition(0);
|
|
_this.setWrapperTranslate(position);
|
|
_this.updateActiveSlide(position);
|
|
|
|
// Return page scroll on edge positions
|
|
if (position === 0 || position === -maxWrapperPosition()) return;
|
|
}
|
|
if (params.autoplay) _this.stopAutoplay(true);
|
|
|
|
if (e.preventDefault) e.preventDefault();
|
|
else e.returnValue = false;
|
|
return false;
|
|
}
|
|
|
|
/*=========================
|
|
Grab Cursor
|
|
===========================*/
|
|
if (params.grabCursor) {
|
|
var containerStyle = _this.container.style;
|
|
containerStyle.cursor = 'move';
|
|
containerStyle.cursor = 'grab';
|
|
containerStyle.cursor = '-moz-grab';
|
|
containerStyle.cursor = '-webkit-grab';
|
|
}
|
|
|
|
/*=========================
|
|
Slides Events Handlers
|
|
===========================*/
|
|
|
|
_this.allowSlideClick = true;
|
|
function slideClick(event) {
|
|
if (_this.allowSlideClick) {
|
|
setClickedSlide(event);
|
|
_this.fireCallback(params.onSlideClick, _this, event);
|
|
}
|
|
}
|
|
|
|
function slideTouch(event) {
|
|
setClickedSlide(event);
|
|
_this.fireCallback(params.onSlideTouch, _this, event);
|
|
}
|
|
|
|
function setClickedSlide(event) {
|
|
|
|
// IE 6-8 support
|
|
if (!event.currentTarget) {
|
|
var element = event.srcElement;
|
|
do {
|
|
if (element.className.indexOf(params.slideClass) > -1) {
|
|
break;
|
|
}
|
|
element = element.parentNode;
|
|
} while (element);
|
|
_this.clickedSlide = element;
|
|
}
|
|
else {
|
|
_this.clickedSlide = event.currentTarget;
|
|
}
|
|
|
|
_this.clickedSlideIndex = _this.slides.indexOf(_this.clickedSlide);
|
|
_this.clickedSlideLoopIndex = _this.clickedSlideIndex - (_this.loopedSlides || 0);
|
|
}
|
|
|
|
_this.allowLinks = true;
|
|
function preventClick(e) {
|
|
if (!_this.allowLinks) {
|
|
if (e.preventDefault) e.preventDefault();
|
|
else e.returnValue = false;
|
|
if (params.preventLinksPropagation && 'stopPropagation' in e) {
|
|
e.stopPropagation();
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
function releaseForms(e) {
|
|
if (e.stopPropagation) e.stopPropagation();
|
|
else e.returnValue = false;
|
|
return false;
|
|
|
|
}
|
|
|
|
/*==================================================
|
|
Event Handlers
|
|
====================================================*/
|
|
var isTouchEvent = false;
|
|
var allowThresholdMove;
|
|
var allowMomentumBounce = true;
|
|
function onTouchStart(event) {
|
|
if (params.preventLinks) _this.allowLinks = true;
|
|
//Exit if slider is already was touched
|
|
if (_this.isTouched || params.onlyExternal) {
|
|
return false;
|
|
}
|
|
|
|
if (params.noSwiping && (event.target || event.srcElement) && noSwipingSlide(event.target || event.srcElement)) return false;
|
|
allowMomentumBounce = false;
|
|
//Check For Nested Swipers
|
|
_this.isTouched = true;
|
|
isTouchEvent = event.type === 'touchstart';
|
|
|
|
if (!isTouchEvent || event.targetTouches.length === 1) {
|
|
_this.callPlugins('onTouchStartBegin');
|
|
|
|
if (!isTouchEvent && !_this.isAndroid) {
|
|
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 = isH ? pageX : pageY;
|
|
|
|
//Set Transition Time to 0
|
|
_this.setWrapperTransition(0);
|
|
|
|
//Get Start Translate Position
|
|
_this.positions.start = _this.positions.current = _this.getWrapperTranslate();
|
|
|
|
//Set Transform
|
|
_this.setWrapperTranslate(_this.positions.start);
|
|
|
|
//TouchStartTime
|
|
_this.times.start = (new Date()).getTime();
|
|
|
|
//Unset Scrolling
|
|
isScrolling = undefined;
|
|
|
|
//Set Treshold
|
|
if (params.moveStartThreshold > 0) {
|
|
allowThresholdMove = false;
|
|
}
|
|
|
|
//CallBack
|
|
if (params.onTouchStart) _this.fireCallback(params.onTouchStart, _this);
|
|
_this.callPlugins('onTouchStartEnd');
|
|
|
|
}
|
|
}
|
|
var velocityPrevPosition, velocityPrevTime;
|
|
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' && isH) {
|
|
isScrolling = !!(isScrolling || Math.abs(pageY - _this.touches.startY) > Math.abs(pageX - _this.touches.startX));
|
|
}
|
|
if (typeof isScrolling === 'undefined' && !isH) {
|
|
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;
|
|
}
|
|
if (params.onSlideClick) {
|
|
_this.allowSlideClick = false;
|
|
}
|
|
|
|
//Stop AutoPlay if exist
|
|
if (params.autoplay) {
|
|
_this.stopAutoplay(true);
|
|
}
|
|
if (!isTouchEvent || event.touches.length === 1) {
|
|
|
|
//Moved Flag
|
|
if (!_this.isMoved) {
|
|
_this.callPlugins('onTouchMoveStart');
|
|
|
|
if (params.loop) {
|
|
_this.fixLoop();
|
|
_this.positions.start = _this.getWrapperTranslate();
|
|
}
|
|
if (params.onTouchMoveStart) _this.fireCallback(params.onTouchMoveStart, _this);
|
|
}
|
|
_this.isMoved = true;
|
|
|
|
// cancel event
|
|
if (event.preventDefault) event.preventDefault();
|
|
else event.returnValue = false;
|
|
|
|
_this.touches.current = isH ? pageX : pageY;
|
|
|
|
_this.positions.current = (_this.touches.current - _this.touches.start) * params.touchRatio + _this.positions.start;
|
|
|
|
//Resistance Callbacks
|
|
if (_this.positions.current > 0 && params.onResistanceBefore) {
|
|
_this.fireCallback(params.onResistanceBefore, _this, _this.positions.current);
|
|
}
|
|
if (_this.positions.current < -maxWrapperPosition() && params.onResistanceAfter) {
|
|
_this.fireCallback(params.onResistanceAfter, _this, Math.abs(_this.positions.current + maxWrapperPosition()));
|
|
}
|
|
//Resistance
|
|
if (params.resistance && params.resistance !== '100%') {
|
|
var resistance;
|
|
//Resistance for Negative-Back sliding
|
|
if (_this.positions.current > 0) {
|
|
resistance = 1 - _this.positions.current / containerSize / 2;
|
|
if (resistance < 0.5)
|
|
_this.positions.current = (containerSize / 2);
|
|
else
|
|
_this.positions.current = _this.positions.current * resistance;
|
|
}
|
|
//Resistance for After-End Sliding
|
|
if (_this.positions.current < -maxWrapperPosition()) {
|
|
|
|
var diff = (_this.touches.current - _this.touches.start) * params.touchRatio + (maxWrapperPosition() + _this.positions.start);
|
|
resistance = (containerSize + diff) / (containerSize);
|
|
var newPos = _this.positions.current - diff * (1 - resistance) / 2;
|
|
var stopPos = -maxWrapperPosition() - containerSize / 2;
|
|
|
|
if (newPos < stopPos || resistance <= 0)
|
|
_this.positions.current = stopPos;
|
|
else
|
|
_this.positions.current = newPos;
|
|
}
|
|
}
|
|
if (params.resistance && params.resistance === '100%') {
|
|
//Resistance for Negative-Back sliding
|
|
if (_this.positions.current > 0 && !(params.freeMode && !params.freeModeFluid)) {
|
|
_this.positions.current = 0;
|
|
}
|
|
//Resistance for After-End Sliding
|
|
if (_this.positions.current < -maxWrapperPosition() && !(params.freeMode && !params.freeModeFluid)) {
|
|
_this.positions.current = -maxWrapperPosition();
|
|
}
|
|
}
|
|
//Move Slides
|
|
if (!params.followFinger) return;
|
|
|
|
if (!params.moveStartThreshold) {
|
|
_this.setWrapperTranslate(_this.positions.current);
|
|
}
|
|
else {
|
|
if (Math.abs(_this.touches.current - _this.touches.start) > params.moveStartThreshold || allowThresholdMove) {
|
|
if (!allowThresholdMove) {
|
|
allowThresholdMove = true;
|
|
_this.touches.start = _this.touches.current;
|
|
return;
|
|
}
|
|
_this.setWrapperTranslate(_this.positions.current);
|
|
}
|
|
else {
|
|
_this.positions.current = _this.positions.start;
|
|
}
|
|
}
|
|
|
|
if (params.freeMode || params.watchActiveIndex) {
|
|
_this.updateActiveSlide(_this.positions.current);
|
|
}
|
|
|
|
//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';
|
|
}
|
|
//Velocity
|
|
if (!velocityPrevPosition) velocityPrevPosition = _this.touches.current;
|
|
if (!velocityPrevTime) velocityPrevTime = (new Date()).getTime();
|
|
_this.velocity = (_this.touches.current - velocityPrevPosition) / ((new Date()).getTime() - velocityPrevTime) / 2;
|
|
if (Math.abs(_this.touches.current - velocityPrevPosition) < 2) _this.velocity = 0;
|
|
velocityPrevPosition = _this.touches.current;
|
|
velocityPrevTime = (new Date()).getTime();
|
|
//Callbacks
|
|
_this.callPlugins('onTouchMoveEnd');
|
|
if (params.onTouchMove) _this.fireCallback(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';
|
|
}
|
|
|
|
//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) {
|
|
_this.setWrapperTranslate(_this.positions.current);
|
|
}
|
|
|
|
// TouchEndTime
|
|
_this.times.end = (new Date()).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;
|
|
var timeDiff = _this.times.end - _this.times.start;
|
|
|
|
if (diffAbs < 5 && (timeDiff) < 300 && _this.allowLinks === false) {
|
|
if (!params.freeMode && diffAbs !== 0) _this.swipeReset();
|
|
//Release inner links
|
|
if (params.preventLinks) {
|
|
_this.allowLinks = true;
|
|
}
|
|
if (params.onSlideClick) {
|
|
_this.allowSlideClick = true;
|
|
}
|
|
}
|
|
|
|
setTimeout(function () {
|
|
//Release inner links
|
|
if (params.preventLinks) {
|
|
_this.allowLinks = true;
|
|
}
|
|
if (params.onSlideClick) {
|
|
_this.allowSlideClick = true;
|
|
}
|
|
}, 100);
|
|
|
|
var maxPosition = maxWrapperPosition();
|
|
|
|
//Not moved or Prevent Negative Back Sliding/After-End Sliding
|
|
if (!_this.isMoved && params.freeMode) {
|
|
_this.isMoved = false;
|
|
if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this);
|
|
_this.callPlugins('onTouchEnd');
|
|
return;
|
|
}
|
|
if (!_this.isMoved || _this.positions.current > 0 || _this.positions.current < -maxPosition) {
|
|
_this.swipeReset();
|
|
if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this);
|
|
_this.callPlugins('onTouchEnd');
|
|
return;
|
|
}
|
|
|
|
_this.isMoved = false;
|
|
|
|
//Free Mode
|
|
if (params.freeMode) {
|
|
if (params.freeModeFluid) {
|
|
var momentumDuration = 1000 * params.momentumRatio;
|
|
var momentumDistance = _this.velocity * momentumDuration;
|
|
var newPosition = _this.positions.current + momentumDistance;
|
|
var doBounce = false;
|
|
var afterBouncePosition;
|
|
var bounceAmount = Math.abs(_this.velocity) * 20 * params.momentumBounceRatio;
|
|
if (newPosition < -maxPosition) {
|
|
if (params.momentumBounce && _this.support.transitions) {
|
|
if (newPosition + maxPosition < -bounceAmount) newPosition = -maxPosition - bounceAmount;
|
|
afterBouncePosition = -maxPosition;
|
|
doBounce = true;
|
|
allowMomentumBounce = true;
|
|
}
|
|
else newPosition = -maxPosition;
|
|
}
|
|
if (newPosition > 0) {
|
|
if (params.momentumBounce && _this.support.transitions) {
|
|
if (newPosition > bounceAmount) newPosition = bounceAmount;
|
|
afterBouncePosition = 0;
|
|
doBounce = true;
|
|
allowMomentumBounce = true;
|
|
}
|
|
else newPosition = 0;
|
|
}
|
|
//Fix duration
|
|
if (_this.velocity !== 0) momentumDuration = Math.abs((newPosition - _this.positions.current) / _this.velocity);
|
|
|
|
_this.setWrapperTranslate(newPosition);
|
|
|
|
_this.setWrapperTransition(momentumDuration);
|
|
|
|
if (params.momentumBounce && doBounce) {
|
|
_this.wrapperTransitionEnd(function () {
|
|
if (!allowMomentumBounce) return;
|
|
if (params.onMomentumBounce) _this.fireCallback(params.onMomentumBounce, _this);
|
|
_this.callPlugins('onMomentumBounce');
|
|
|
|
_this.setWrapperTranslate(afterBouncePosition);
|
|
_this.setWrapperTransition(300);
|
|
});
|
|
}
|
|
|
|
_this.updateActiveSlide(newPosition);
|
|
}
|
|
if (!params.freeModeFluid || timeDiff >= 300) _this.updateActiveSlide(_this.positions.current);
|
|
|
|
if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this);
|
|
_this.callPlugins('onTouchEnd');
|
|
return;
|
|
}
|
|
|
|
//Direction
|
|
direction = diff < 0 ? 'toNext' : 'toPrev';
|
|
|
|
//Short Touches
|
|
if (direction === 'toNext' && (timeDiff <= 300)) {
|
|
if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset();
|
|
else _this.swipeNext(true);
|
|
}
|
|
|
|
if (direction === 'toPrev' && (timeDiff <= 300)) {
|
|
if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset();
|
|
else _this.swipePrev(true);
|
|
}
|
|
|
|
//Long Touches
|
|
var targetSlideSize = 0;
|
|
if (params.slidesPerView === 'auto') {
|
|
//Define current slide's width
|
|
var currentPosition = Math.abs(_this.getWrapperTranslate());
|
|
var slidesOffset = 0;
|
|
var _slideSize;
|
|
for (var i = 0; i < _this.slides.length; i++) {
|
|
_slideSize = isH ? _this.slides[i].getWidth(true) : _this.slides[i].getHeight(true);
|
|
slidesOffset += _slideSize;
|
|
if (slidesOffset > currentPosition) {
|
|
targetSlideSize = _slideSize;
|
|
break;
|
|
}
|
|
}
|
|
if (targetSlideSize > containerSize) targetSlideSize = containerSize;
|
|
}
|
|
else {
|
|
targetSlideSize = slideSize * params.slidesPerView;
|
|
}
|
|
if (direction === 'toNext' && (timeDiff > 300)) {
|
|
if (diffAbs >= targetSlideSize * params.longSwipesRatio) {
|
|
_this.swipeNext(true);
|
|
}
|
|
else {
|
|
_this.swipeReset();
|
|
}
|
|
}
|
|
if (direction === 'toPrev' && (timeDiff > 300)) {
|
|
if (diffAbs >= targetSlideSize * params.longSwipesRatio) {
|
|
_this.swipePrev(true);
|
|
}
|
|
else {
|
|
_this.swipeReset();
|
|
}
|
|
}
|
|
if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this);
|
|
_this.callPlugins('onTouchEnd');
|
|
}
|
|
|
|
|
|
/*==================================================
|
|
noSwiping Bubble Check by Isaac Strack
|
|
====================================================*/
|
|
function noSwipingSlide(el) {
|
|
/*This function is specifically designed to check the parent elements for the noSwiping class, up to the wrapper.
|
|
We need to check parents because while onTouchStart bubbles, _this.isTouched is checked in onTouchStart, which stops the bubbling.
|
|
So, if a text box, for example, is the initial target, and the parent slide container has the noSwiping class, the _this.isTouched
|
|
check will never find it, and what was supposed to be noSwiping is able to be swiped.
|
|
This function will iterate up and check for the noSwiping class in parents, up through the wrapperClass.*/
|
|
|
|
// First we create a truthy variable, which is that swiping is allowd (noSwiping = false)
|
|
var noSwiping = false;
|
|
|
|
// Now we iterate up (parentElements) until we reach the node with the wrapperClass.
|
|
do {
|
|
|
|
// Each time, we check to see if there's a 'swiper-no-swiping' class (noSwipingClass).
|
|
if (el.className.indexOf(params.noSwipingClass) > -1)
|
|
{
|
|
noSwiping = true; // If there is, we set noSwiping = true;
|
|
}
|
|
|
|
el = el.parentElement; // now we iterate up (parent node)
|
|
|
|
} while (!noSwiping && el.parentElement && el.className.indexOf(params.wrapperClass) === -1); // also include el.parentElement truthy, just in case.
|
|
|
|
// because we didn't check the wrapper itself, we do so now, if noSwiping is false:
|
|
if (!noSwiping && el.className.indexOf(params.wrapperClass) > -1 && el.className.indexOf(params.noSwipingClass) > -1)
|
|
noSwiping = true; // if the wrapper has the noSwipingClass, we set noSwiping = true;
|
|
|
|
return noSwiping;
|
|
}
|
|
|
|
function addClassToHtmlString(klass, outerHtml) {
|
|
var par = document.createElement('div');
|
|
var child;
|
|
|
|
par.innerHTML = outerHtml;
|
|
child = par.firstChild;
|
|
child.className += ' ' + klass;
|
|
|
|
return child.outerHTML;
|
|
}
|
|
|
|
|
|
/*==================================================
|
|
Swipe Functions
|
|
====================================================*/
|
|
_this.swipeNext = function (internal) {
|
|
if (!internal && params.loop) _this.fixLoop();
|
|
if (!internal && params.autoplay) _this.stopAutoplay(true);
|
|
_this.callPlugins('onSwipeNext');
|
|
var currentPosition = _this.getWrapperTranslate();
|
|
var newPosition = currentPosition;
|
|
if (params.slidesPerView === 'auto') {
|
|
for (var i = 0; i < _this.snapGrid.length; i++) {
|
|
if (-currentPosition >= _this.snapGrid[i] && -currentPosition < _this.snapGrid[i + 1]) {
|
|
newPosition = -_this.snapGrid[i + 1];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
var groupSize = slideSize * params.slidesPerGroup;
|
|
newPosition = -(Math.floor(Math.abs(currentPosition) / Math.floor(groupSize)) * groupSize + groupSize);
|
|
}
|
|
if (newPosition < -maxWrapperPosition()) {
|
|
newPosition = -maxWrapperPosition();
|
|
}
|
|
if (newPosition === currentPosition) return false;
|
|
swipeToPosition(newPosition, 'next');
|
|
return true;
|
|
};
|
|
_this.swipePrev = function (internal) {
|
|
if (!internal && params.loop) _this.fixLoop();
|
|
if (!internal && params.autoplay) _this.stopAutoplay(true);
|
|
_this.callPlugins('onSwipePrev');
|
|
|
|
var currentPosition = Math.ceil(_this.getWrapperTranslate());
|
|
var newPosition;
|
|
if (params.slidesPerView === 'auto') {
|
|
newPosition = 0;
|
|
for (var i = 1; i < _this.snapGrid.length; i++) {
|
|
if (-currentPosition === _this.snapGrid[i]) {
|
|
newPosition = -_this.snapGrid[i - 1];
|
|
break;
|
|
}
|
|
if (-currentPosition > _this.snapGrid[i] && -currentPosition < _this.snapGrid[i + 1]) {
|
|
newPosition = -_this.snapGrid[i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
var groupSize = slideSize * params.slidesPerGroup;
|
|
newPosition = -(Math.ceil(-currentPosition / groupSize) - 1) * groupSize;
|
|
}
|
|
|
|
if (newPosition > 0) newPosition = 0;
|
|
|
|
if (newPosition === currentPosition) return false;
|
|
swipeToPosition(newPosition, 'prev');
|
|
return true;
|
|
|
|
};
|
|
_this.swipeReset = function () {
|
|
_this.callPlugins('onSwipeReset');
|
|
var currentPosition = _this.getWrapperTranslate();
|
|
var groupSize = slideSize * params.slidesPerGroup;
|
|
var newPosition;
|
|
var maxPosition = -maxWrapperPosition();
|
|
if (params.slidesPerView === 'auto') {
|
|
newPosition = 0;
|
|
for (var i = 0; i < _this.snapGrid.length; i++) {
|
|
if (-currentPosition === _this.snapGrid[i]) return;
|
|
if (-currentPosition >= _this.snapGrid[i] && -currentPosition < _this.snapGrid[i + 1]) {
|
|
if (_this.positions.diff > 0) newPosition = -_this.snapGrid[i + 1];
|
|
else newPosition = -_this.snapGrid[i];
|
|
break;
|
|
}
|
|
}
|
|
if (-currentPosition >= _this.snapGrid[_this.snapGrid.length - 1]) newPosition = -_this.snapGrid[_this.snapGrid.length - 1];
|
|
if (currentPosition <= -maxWrapperPosition()) newPosition = -maxWrapperPosition();
|
|
}
|
|
else {
|
|
newPosition = currentPosition < 0 ? Math.round(currentPosition / groupSize) * groupSize : 0;
|
|
}
|
|
if (params.scrollContainer) {
|
|
newPosition = currentPosition < 0 ? currentPosition : 0;
|
|
}
|
|
if (newPosition < -maxWrapperPosition()) {
|
|
newPosition = -maxWrapperPosition();
|
|
}
|
|
if (params.scrollContainer && (containerSize > slideSize)) {
|
|
newPosition = 0;
|
|
}
|
|
|
|
if (newPosition === currentPosition) return false;
|
|
|
|
swipeToPosition(newPosition, 'reset');
|
|
return true;
|
|
};
|
|
|
|
_this.swipeTo = function (index, speed, runCallbacks) {
|
|
index = parseInt(index, 10);
|
|
_this.callPlugins('onSwipeTo', {index: index, speed: speed});
|
|
if (params.loop) index = index + _this.loopedSlides;
|
|
var currentPosition = _this.getWrapperTranslate();
|
|
if (index > (_this.slides.length - 1) || index < 0) return;
|
|
var newPosition;
|
|
if (params.slidesPerView === 'auto') {
|
|
newPosition = -_this.slidesGrid[index];
|
|
}
|
|
else {
|
|
newPosition = -index * slideSize;
|
|
}
|
|
if (newPosition < - maxWrapperPosition()) {
|
|
newPosition = - maxWrapperPosition();
|
|
}
|
|
|
|
if (newPosition === currentPosition) return false;
|
|
|
|
runCallbacks = runCallbacks === false ? false : true;
|
|
swipeToPosition(newPosition, 'to', {index: index, speed: speed, runCallbacks: runCallbacks});
|
|
return true;
|
|
};
|
|
|
|
function swipeToPosition(newPosition, action, toOptions) {
|
|
var speed = (action === 'to' && toOptions.speed >= 0) ? toOptions.speed : params.speed;
|
|
var timeOld = + new Date();
|
|
|
|
function anim() {
|
|
var timeNew = + new Date();
|
|
var time = timeNew - timeOld;
|
|
currentPosition += animationStep * time / (1000 / 60);
|
|
condition = direction === 'toNext' ? currentPosition > newPosition : currentPosition < newPosition;
|
|
if (condition) {
|
|
_this.setWrapperTranslate(Math.round(currentPosition));
|
|
_this._DOMAnimating = true;
|
|
window.setTimeout(function () {
|
|
anim();
|
|
}, 1000 / 60);
|
|
}
|
|
else {
|
|
if (params.onSlideChangeEnd) _this.fireCallback(params.onSlideChangeEnd, _this);
|
|
_this.setWrapperTranslate(newPosition);
|
|
_this._DOMAnimating = false;
|
|
}
|
|
}
|
|
|
|
if (_this.support.transitions || !params.DOMAnimation) {
|
|
_this.setWrapperTranslate(newPosition);
|
|
_this.setWrapperTransition(speed);
|
|
}
|
|
else {
|
|
//Try the DOM animation
|
|
var currentPosition = _this.getWrapperTranslate();
|
|
var animationStep = Math.ceil((newPosition - currentPosition) / speed * (1000 / 60));
|
|
var direction = currentPosition > newPosition ? 'toNext' : 'toPrev';
|
|
var condition = direction === 'toNext' ? currentPosition > newPosition : currentPosition < newPosition;
|
|
if (_this._DOMAnimating) return;
|
|
|
|
anim();
|
|
}
|
|
|
|
//Update Active Slide Index
|
|
_this.updateActiveSlide(newPosition);
|
|
|
|
//Callbacks
|
|
if (params.onSlideNext && action === 'next') {
|
|
_this.fireCallback(params.onSlideNext, _this, newPosition);
|
|
}
|
|
if (params.onSlidePrev && action === 'prev') {
|
|
_this.fireCallback(params.onSlidePrev, _this, newPosition);
|
|
}
|
|
//'Reset' Callback
|
|
if (params.onSlideReset && action === 'reset') {
|
|
_this.fireCallback(params.onSlideReset, _this, newPosition);
|
|
}
|
|
|
|
//'Next', 'Prev' and 'To' Callbacks
|
|
if (action === 'next' || action === 'prev' || (action === 'to' && toOptions.runCallbacks === true))
|
|
slideChangeCallbacks(action);
|
|
}
|
|
/*==================================================
|
|
Transition Callbacks
|
|
====================================================*/
|
|
//Prevent Multiple Callbacks
|
|
_this._queueStartCallbacks = false;
|
|
_this._queueEndCallbacks = false;
|
|
function slideChangeCallbacks(direction) {
|
|
//Transition Start Callback
|
|
_this.callPlugins('onSlideChangeStart');
|
|
if (params.onSlideChangeStart) {
|
|
if (params.queueStartCallbacks && _this.support.transitions) {
|
|
if (_this._queueStartCallbacks) return;
|
|
_this._queueStartCallbacks = true;
|
|
_this.fireCallback(params.onSlideChangeStart, _this, direction);
|
|
_this.wrapperTransitionEnd(function () {
|
|
_this._queueStartCallbacks = false;
|
|
});
|
|
}
|
|
else _this.fireCallback(params.onSlideChangeStart, _this, direction);
|
|
}
|
|
//Transition End Callback
|
|
if (params.onSlideChangeEnd) {
|
|
if (_this.support.transitions) {
|
|
if (params.queueEndCallbacks) {
|
|
if (_this._queueEndCallbacks) return;
|
|
_this._queueEndCallbacks = true;
|
|
_this.wrapperTransitionEnd(function (swiper) {
|
|
_this.fireCallback(params.onSlideChangeEnd, swiper, direction);
|
|
});
|
|
}
|
|
else {
|
|
_this.wrapperTransitionEnd(function (swiper) {
|
|
_this.fireCallback(params.onSlideChangeEnd, swiper, direction);
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
if (!params.DOMAnimation) {
|
|
setTimeout(function () {
|
|
_this.fireCallback(params.onSlideChangeEnd, _this, direction);
|
|
}, 10);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*==================================================
|
|
Update Active Slide Index
|
|
====================================================*/
|
|
_this.updateActiveSlide = function (position) {
|
|
if (!_this.initialized) return;
|
|
if (_this.slides.length === 0) return;
|
|
_this.previousIndex = _this.activeIndex;
|
|
if (typeof position === 'undefined') position = _this.getWrapperTranslate();
|
|
if (position > 0) position = 0;
|
|
|
|
if (params.slidesPerView === 'auto') {
|
|
var slidesOffset = 0;
|
|
_this.activeIndex = _this.slidesGrid.indexOf(-position);
|
|
if (_this.activeIndex < 0) {
|
|
for (var i = 0; i < _this.slidesGrid.length - 1; i++) {
|
|
if (-position > _this.slidesGrid[i] && -position < _this.slidesGrid[i + 1]) {
|
|
break;
|
|
}
|
|
}
|
|
var leftDistance = Math.abs(_this.slidesGrid[i] + position);
|
|
var rightDistance = Math.abs(_this.slidesGrid[i + 1] + position);
|
|
if (leftDistance <= rightDistance) _this.activeIndex = i;
|
|
else _this.activeIndex = i + 1;
|
|
}
|
|
}
|
|
else {
|
|
_this.activeIndex = Math[params.visibilityFullFit ? 'ceil' : 'round'](-position / slideSize);
|
|
}
|
|
|
|
if (_this.activeIndex === _this.slides.length) _this.activeIndex = _this.slides.length - 1;
|
|
if (_this.activeIndex < 0) _this.activeIndex = 0;
|
|
|
|
// Check for slide
|
|
if (!_this.slides[_this.activeIndex]) return;
|
|
|
|
// Calc Visible slides
|
|
_this.calcVisibleSlides(position);
|
|
|
|
// Mark visible and active slides with additonal classes
|
|
var activeClassRegexp = new RegExp('\\s*' + params.slideActiveClass);
|
|
var inViewClassRegexp = new RegExp('\\s*' + params.slideVisibleClass);
|
|
|
|
for (var j = 0; j < _this.slides.length; j++) {
|
|
_this.slides[j].className = _this.slides[j].className.replace(activeClassRegexp, '').replace(inViewClassRegexp, '');
|
|
if (_this.visibleSlides.indexOf(_this.slides[j]) >= 0) {
|
|
_this.slides[j].className += ' ' + params.slideVisibleClass;
|
|
}
|
|
|
|
}
|
|
_this.slides[_this.activeIndex].className += ' ' + params.slideActiveClass;
|
|
|
|
//Update loop index
|
|
if (params.loop) {
|
|
var ls = _this.loopedSlides;
|
|
_this.activeLoopIndex = _this.activeIndex - ls;
|
|
if (_this.activeLoopIndex >= _this.slides.length - ls * 2) {
|
|
_this.activeLoopIndex = _this.slides.length - ls * 2 - _this.activeLoopIndex;
|
|
}
|
|
if (_this.activeLoopIndex < 0) {
|
|
_this.activeLoopIndex = _this.slides.length - ls * 2 + _this.activeLoopIndex;
|
|
}
|
|
if (_this.activeLoopIndex < 0) _this.activeLoopIndex = 0;
|
|
}
|
|
else {
|
|
_this.activeLoopIndex = _this.activeIndex;
|
|
}
|
|
//Update Pagination
|
|
if (params.pagination) {
|
|
_this.updatePagination(position);
|
|
}
|
|
};
|
|
/*==================================================
|
|
Pagination
|
|
====================================================*/
|
|
_this.createPagination = function (firstInit) {
|
|
if (params.paginationClickable && _this.paginationButtons) {
|
|
removePaginationEvents();
|
|
}
|
|
_this.paginationContainer = params.pagination.nodeType ? params.pagination : $$(params.pagination)[0];
|
|
if (params.createPagination) {
|
|
var paginationHTML = '';
|
|
var numOfSlides = _this.slides.length;
|
|
var numOfButtons = numOfSlides;
|
|
if (params.loop) numOfButtons -= _this.loopedSlides * 2;
|
|
for (var i = 0; i < numOfButtons; i++) {
|
|
paginationHTML += '<' + params.paginationElement + ' class="' + params.paginationElementClass + '"></' + params.paginationElement + '>';
|
|
}
|
|
_this.paginationContainer.innerHTML = paginationHTML;
|
|
}
|
|
_this.paginationButtons = $$('.' + params.paginationElementClass, _this.paginationContainer);
|
|
if (!firstInit) _this.updatePagination();
|
|
_this.callPlugins('onCreatePagination');
|
|
if (params.paginationClickable) {
|
|
addPaginationEvents();
|
|
}
|
|
};
|
|
function removePaginationEvents() {
|
|
var pagers = _this.paginationButtons;
|
|
if (pagers) {
|
|
for (var i = 0; i < pagers.length; i++) {
|
|
_this.h.removeEventListener(pagers[i], 'click', paginationClick);
|
|
}
|
|
}
|
|
}
|
|
function addPaginationEvents() {
|
|
var pagers = _this.paginationButtons;
|
|
if (pagers) {
|
|
for (var i = 0; i < pagers.length; i++) {
|
|
_this.h.addEventListener(pagers[i], 'click', paginationClick);
|
|
}
|
|
}
|
|
}
|
|
function paginationClick(e) {
|
|
var index;
|
|
var target = e.target || e.srcElement;
|
|
var pagers = _this.paginationButtons;
|
|
for (var i = 0; i < pagers.length; i++) {
|
|
if (target === pagers[i]) index = i;
|
|
}
|
|
_this.swipeTo(index);
|
|
}
|
|
_this.updatePagination = function (position) {
|
|
if (!params.pagination) return;
|
|
if (_this.slides.length < 1) return;
|
|
var activePagers = $$('.' + params.paginationActiveClass, _this.paginationContainer);
|
|
if (!activePagers) return;
|
|
|
|
//Reset all Buttons' class to not active
|
|
var pagers = _this.paginationButtons;
|
|
if (pagers.length === 0) return;
|
|
for (var i = 0; i < pagers.length; i++) {
|
|
pagers[i].className = params.paginationElementClass;
|
|
}
|
|
|
|
var indexOffset = params.loop ? _this.loopedSlides : 0;
|
|
if (params.paginationAsRange) {
|
|
if (!_this.visibleSlides) _this.calcVisibleSlides(position);
|
|
//Get Visible Indexes
|
|
var visibleIndexes = [];
|
|
var j; // lopp index - avoid JSHint W004 / W038
|
|
for (j = 0; j < _this.visibleSlides.length; j++) {
|
|
var visIndex = _this.slides.indexOf(_this.visibleSlides[j]) - indexOffset;
|
|
|
|
if (params.loop && visIndex < 0) {
|
|
visIndex = _this.slides.length - _this.loopedSlides * 2 + visIndex;
|
|
}
|
|
if (params.loop && visIndex >= _this.slides.length - _this.loopedSlides * 2) {
|
|
visIndex = _this.slides.length - _this.loopedSlides * 2 - visIndex;
|
|
visIndex = Math.abs(visIndex);
|
|
}
|
|
visibleIndexes.push(visIndex);
|
|
}
|
|
|
|
for (j = 0; j < visibleIndexes.length; j++) {
|
|
if (pagers[visibleIndexes[j]]) pagers[visibleIndexes[j]].className += ' ' + params.paginationVisibleClass;
|
|
}
|
|
|
|
if (params.loop) {
|
|
if (pagers[_this.activeLoopIndex] !== undefined) {
|
|
pagers[_this.activeLoopIndex].className += ' ' + params.paginationActiveClass;
|
|
}
|
|
}
|
|
else {
|
|
pagers[_this.activeIndex].className += ' ' + params.paginationActiveClass;
|
|
}
|
|
}
|
|
else {
|
|
if (params.loop) {
|
|
if (pagers[_this.activeLoopIndex]) pagers[_this.activeLoopIndex].className += ' ' + params.paginationActiveClass + ' ' + params.paginationVisibleClass;
|
|
}
|
|
else {
|
|
pagers[_this.activeIndex].className += ' ' + params.paginationActiveClass + ' ' + params.paginationVisibleClass;
|
|
}
|
|
}
|
|
};
|
|
_this.calcVisibleSlides = function (position) {
|
|
var visibleSlides = [];
|
|
var _slideLeft = 0, _slideSize = 0, _slideRight = 0;
|
|
if (isH && _this.wrapperLeft > 0) position = position + _this.wrapperLeft;
|
|
if (!isH && _this.wrapperTop > 0) position = position + _this.wrapperTop;
|
|
|
|
for (var i = 0; i < _this.slides.length; i++) {
|
|
_slideLeft += _slideSize;
|
|
if (params.slidesPerView === 'auto')
|
|
_slideSize = isH ? _this.h.getWidth(_this.slides[i], true) : _this.h.getHeight(_this.slides[i], true);
|
|
else _slideSize = slideSize;
|
|
|
|
_slideRight = _slideLeft + _slideSize;
|
|
var isVisibile = false;
|
|
if (params.visibilityFullFit) {
|
|
if (_slideLeft >= -position && _slideRight <= -position + containerSize) isVisibile = true;
|
|
if (_slideLeft <= -position && _slideRight >= -position + containerSize) isVisibile = true;
|
|
}
|
|
else {
|
|
if (_slideRight > -position && _slideRight <= ((-position + containerSize))) isVisibile = true;
|
|
if (_slideLeft >= -position && _slideLeft < ((-position + containerSize))) isVisibile = true;
|
|
if (_slideLeft < -position && _slideRight > ((-position + containerSize))) isVisibile = true;
|
|
}
|
|
|
|
if (isVisibile) visibleSlides.push(_this.slides[i]);
|
|
|
|
}
|
|
if (visibleSlides.length === 0) visibleSlides = [_this.slides[_this.activeIndex]];
|
|
|
|
_this.visibleSlides = visibleSlides;
|
|
};
|
|
|
|
/*==========================================
|
|
Autoplay
|
|
============================================*/
|
|
var autoplayTimeoutId, autoplayIntervalId;
|
|
_this.startAutoplay = function () {
|
|
if (_this.support.transitions) {
|
|
if (typeof autoplayTimeoutId !== 'undefined') return false;
|
|
if (!params.autoplay) return;
|
|
_this.callPlugins('onAutoplayStart');
|
|
autoplay();
|
|
}
|
|
else {
|
|
if (typeof autoplayIntervalId !== 'undefined') return false;
|
|
if (!params.autoplay) return;
|
|
_this.callPlugins('onAutoplayStart');
|
|
autoplayIntervalId = setInterval(function () {
|
|
if (params.loop) {
|
|
_this.fixLoop();
|
|
_this.swipeNext(true);
|
|
}
|
|
else if (!_this.swipeNext(true)) {
|
|
if (!params.autoplayStopOnLast) _this.swipeTo(0);
|
|
else {
|
|
clearInterval(autoplayIntervalId);
|
|
autoplayIntervalId = undefined;
|
|
}
|
|
}
|
|
}, params.autoplay);
|
|
}
|
|
};
|
|
_this.stopAutoplay = function (internal) {
|
|
if (_this.support.transitions) {
|
|
if (!autoplayTimeoutId) return;
|
|
if (autoplayTimeoutId) clearTimeout(autoplayTimeoutId);
|
|
autoplayTimeoutId = undefined;
|
|
if (internal && !params.autoplayDisableOnInteraction) {
|
|
_this.wrapperTransitionEnd(function () {
|
|
autoplay();
|
|
});
|
|
}
|
|
_this.callPlugins('onAutoplayStop');
|
|
}
|
|
else {
|
|
if (autoplayIntervalId) clearInterval(autoplayIntervalId);
|
|
autoplayIntervalId = undefined;
|
|
_this.callPlugins('onAutoplayStop');
|
|
}
|
|
};
|
|
function autoplay() {
|
|
autoplayTimeoutId = setTimeout(function () {
|
|
if (params.loop) {
|
|
_this.fixLoop();
|
|
_this.swipeNext(true);
|
|
}
|
|
else if (!_this.swipeNext(true)) {
|
|
if (!params.autoplayStopOnLast) _this.swipeTo(0);
|
|
else {
|
|
clearTimeout(autoplayTimeoutId);
|
|
autoplayTimeoutId = undefined;
|
|
}
|
|
}
|
|
_this.wrapperTransitionEnd(function () {
|
|
if (typeof autoplayTimeoutId !== 'undefined') autoplay();
|
|
});
|
|
}, params.autoplay);
|
|
}
|
|
/*==================================================
|
|
Loop
|
|
====================================================*/
|
|
_this.loopCreated = false;
|
|
_this.removeLoopedSlides = function () {
|
|
if (_this.loopCreated) {
|
|
for (var i = 0; i < _this.slides.length; i++) {
|
|
if (_this.slides[i].getData('looped') === true) _this.wrapper.removeChild(_this.slides[i]);
|
|
}
|
|
}
|
|
};
|
|
|
|
_this.createLoop = function () {
|
|
if (_this.slides.length === 0) return;
|
|
if (params.slidesPerView === 'auto') {
|
|
_this.loopedSlides = params.loopedSlides || 1;
|
|
}
|
|
else {
|
|
_this.loopedSlides = params.slidesPerView + params.loopAdditionalSlides;
|
|
}
|
|
|
|
if (_this.loopedSlides > _this.slides.length) {
|
|
_this.loopedSlides = _this.slides.length;
|
|
}
|
|
|
|
var slideFirstHTML = '',
|
|
slideLastHTML = '',
|
|
i;
|
|
var slidesSetFullHTML = '';
|
|
/**
|
|
loopedSlides is too large if loopAdditionalSlides are set.
|
|
Need to divide the slides by maximum number of slides existing.
|
|
|
|
@author Tomaz Lovrec <tomaz.lovrec@blanc-noir.at>
|
|
*/
|
|
var numSlides = _this.slides.length;
|
|
var fullSlideSets = Math.floor(_this.loopedSlides / numSlides);
|
|
var remainderSlides = _this.loopedSlides % numSlides;
|
|
// assemble full sets of slides
|
|
for (i = 0; i < (fullSlideSets * numSlides); i++) {
|
|
var j = i;
|
|
if (i >= numSlides) {
|
|
var over = Math.floor(i / numSlides);
|
|
j = i - (numSlides * over);
|
|
}
|
|
slidesSetFullHTML += _this.slides[j].outerHTML;
|
|
}
|
|
// assemble remainder slides
|
|
// assemble remainder appended to existing slides
|
|
for (i = 0; i < remainderSlides;i++) {
|
|
slideLastHTML += addClassToHtmlString(params.slideDuplicateClass, _this.slides[i].outerHTML);
|
|
}
|
|
// assemble slides that get preppended to existing slides
|
|
for (i = numSlides - remainderSlides; i < numSlides;i++) {
|
|
slideFirstHTML += addClassToHtmlString(params.slideDuplicateClass, _this.slides[i].outerHTML);
|
|
}
|
|
// assemble all slides
|
|
var slides = slideFirstHTML + slidesSetFullHTML + wrapper.innerHTML + slidesSetFullHTML + slideLastHTML;
|
|
// set the slides
|
|
wrapper.innerHTML = slides;
|
|
|
|
_this.loopCreated = true;
|
|
_this.calcSlides();
|
|
|
|
//Update Looped Slides with special class
|
|
for (i = 0; i < _this.slides.length; i++) {
|
|
if (i < _this.loopedSlides || i >= _this.slides.length - _this.loopedSlides) _this.slides[i].setData('looped', true);
|
|
}
|
|
_this.callPlugins('onCreateLoop');
|
|
|
|
};
|
|
|
|
_this.fixLoop = function () {
|
|
var newIndex;
|
|
//Fix For Negative Oversliding
|
|
if (_this.activeIndex < _this.loopedSlides) {
|
|
newIndex = _this.slides.length - _this.loopedSlides * 3 + _this.activeIndex;
|
|
_this.swipeTo(newIndex, 0, false);
|
|
}
|
|
//Fix For Positive Oversliding
|
|
else if ((params.slidesPerView === 'auto' && _this.activeIndex >= _this.loopedSlides * 2) || (_this.activeIndex > _this.slides.length - params.slidesPerView * 2)) {
|
|
newIndex = -_this.slides.length + _this.activeIndex + _this.loopedSlides;
|
|
_this.swipeTo(newIndex, 0, false);
|
|
}
|
|
};
|
|
|
|
/*==================================================
|
|
Slides Loader
|
|
====================================================*/
|
|
_this.loadSlides = function () {
|
|
var slidesHTML = '';
|
|
_this.activeLoaderIndex = 0;
|
|
var slides = params.loader.slides;
|
|
var slidesToLoad = params.loader.loadAllSlides ? slides.length : params.slidesPerView * (1 + params.loader.surroundGroups);
|
|
for (var i = 0; i < slidesToLoad; i++) {
|
|
if (params.loader.slidesHTMLType === 'outer') slidesHTML += slides[i];
|
|
else {
|
|
slidesHTML += '<' + params.slideElement + ' class="' + params.slideClass + '" data-swiperindex="' + i + '">' + slides[i] + '</' + params.slideElement + '>';
|
|
}
|
|
}
|
|
_this.wrapper.innerHTML = slidesHTML;
|
|
_this.calcSlides(true);
|
|
//Add permanent transitionEnd callback
|
|
if (!params.loader.loadAllSlides) {
|
|
_this.wrapperTransitionEnd(_this.reloadSlides, true);
|
|
}
|
|
};
|
|
|
|
_this.reloadSlides = function () {
|
|
var slides = params.loader.slides;
|
|
var newActiveIndex = parseInt(_this.activeSlide().data('swiperindex'), 10);
|
|
if (newActiveIndex < 0 || newActiveIndex > slides.length - 1) return; //<-- Exit
|
|
_this.activeLoaderIndex = newActiveIndex;
|
|
var firstIndex = Math.max(0, newActiveIndex - params.slidesPerView * params.loader.surroundGroups);
|
|
var lastIndex = Math.min(newActiveIndex + params.slidesPerView * (1 + params.loader.surroundGroups) - 1, slides.length - 1);
|
|
//Update Transforms
|
|
if (newActiveIndex > 0) {
|
|
var newTransform = -slideSize * (newActiveIndex - firstIndex);
|
|
_this.setWrapperTranslate(newTransform);
|
|
_this.setWrapperTransition(0);
|
|
}
|
|
var i; // loop index
|
|
//New Slides
|
|
if (params.loader.logic === 'reload') {
|
|
_this.wrapper.innerHTML = '';
|
|
var slidesHTML = '';
|
|
for (i = firstIndex; i <= lastIndex; i++) {
|
|
slidesHTML += params.loader.slidesHTMLType === 'outer' ? slides[i] : '<' + params.slideElement + ' class="' + params.slideClass + '" data-swiperindex="' + i + '">' + slides[i] + '</' + params.slideElement + '>';
|
|
}
|
|
_this.wrapper.innerHTML = slidesHTML;
|
|
}
|
|
else {
|
|
var minExistIndex = 1000;
|
|
var maxExistIndex = 0;
|
|
|
|
for (i = 0; i < _this.slides.length; i++) {
|
|
var index = _this.slides[i].data('swiperindex');
|
|
if (index < firstIndex || index > lastIndex) {
|
|
_this.wrapper.removeChild(_this.slides[i]);
|
|
}
|
|
else {
|
|
minExistIndex = Math.min(index, minExistIndex);
|
|
maxExistIndex = Math.max(index, maxExistIndex);
|
|
}
|
|
}
|
|
for (i = firstIndex; i <= lastIndex; i++) {
|
|
var newSlide;
|
|
if (i < minExistIndex) {
|
|
newSlide = document.createElement(params.slideElement);
|
|
newSlide.className = params.slideClass;
|
|
newSlide.setAttribute('data-swiperindex', i);
|
|
newSlide.innerHTML = slides[i];
|
|
_this.wrapper.insertBefore(newSlide, _this.wrapper.firstChild);
|
|
}
|
|
if (i > maxExistIndex) {
|
|
newSlide = document.createElement(params.slideElement);
|
|
newSlide.className = params.slideClass;
|
|
newSlide.setAttribute('data-swiperindex', i);
|
|
newSlide.innerHTML = slides[i];
|
|
_this.wrapper.appendChild(newSlide);
|
|
}
|
|
}
|
|
}
|
|
//reInit
|
|
_this.reInit(true);
|
|
};
|
|
|
|
/*==================================================
|
|
Make Swiper
|
|
====================================================*/
|
|
function makeSwiper() {
|
|
_this.calcSlides();
|
|
if (params.loader.slides.length > 0 && _this.slides.length === 0) {
|
|
_this.loadSlides();
|
|
}
|
|
if (params.loop) {
|
|
_this.createLoop();
|
|
}
|
|
_this.init();
|
|
initEvents();
|
|
if (params.pagination) {
|
|
_this.createPagination(true);
|
|
}
|
|
|
|
if (params.loop || params.initialSlide > 0) {
|
|
_this.swipeTo(params.initialSlide, 0, false);
|
|
}
|
|
else {
|
|
_this.updateActiveSlide(0);
|
|
}
|
|
if (params.autoplay) {
|
|
_this.startAutoplay();
|
|
}
|
|
/**
|
|
* Set center slide index.
|
|
*
|
|
* @author Tomaz Lovrec <tomaz.lovrec@gmail.com>
|
|
*/
|
|
_this.centerIndex = _this.activeIndex;
|
|
|
|
// Callbacks
|
|
if (params.onSwiperCreated) _this.fireCallback(params.onSwiperCreated, _this);
|
|
_this.callPlugins('onSwiperCreated');
|
|
}
|
|
|
|
makeSwiper();
|
|
};
|
|
|
|
Swiper.prototype = {
|
|
plugins : {},
|
|
|
|
/*==================================================
|
|
Wrapper Operations
|
|
====================================================*/
|
|
wrapperTransitionEnd : function (callback, permanent) {
|
|
'use strict';
|
|
var a = this,
|
|
el = a.wrapper,
|
|
events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],
|
|
i;
|
|
|
|
function fireCallBack() {
|
|
callback(a);
|
|
if (a.params.queueEndCallbacks) a._queueEndCallbacks = false;
|
|
if (!permanent) {
|
|
for (i = 0; i < events.length; i++) {
|
|
a.h.removeEventListener(el, events[i], fireCallBack);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (callback) {
|
|
for (i = 0; i < events.length; i++) {
|
|
a.h.addEventListener(el, events[i], fireCallBack);
|
|
}
|
|
}
|
|
},
|
|
|
|
getWrapperTranslate : function (axis) {
|
|
'use strict';
|
|
var el = this.wrapper,
|
|
matrix, curTransform, curStyle, transformMatrix;
|
|
|
|
// automatic axis detection
|
|
if (typeof axis === 'undefined') {
|
|
axis = this.params.mode === 'horizontal' ? 'x' : 'y';
|
|
}
|
|
|
|
if (this.support.transforms && this.params.useCSS3Transforms) {
|
|
curStyle = window.getComputedStyle(el, null);
|
|
if (window.WebKitCSSMatrix) {
|
|
transformMatrix = new WebKitCSSMatrix(curStyle.webkitTransform);
|
|
}
|
|
else {
|
|
transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
|
|
matrix = transformMatrix.toString().split(',');
|
|
}
|
|
|
|
if (axis === 'x') {
|
|
//Latest Chrome and webkits Fix
|
|
if (window.WebKitCSSMatrix)
|
|
curTransform = transformMatrix.m41;
|
|
//Crazy IE10 Matrix
|
|
else if (matrix.length === 16)
|
|
curTransform = parseFloat(matrix[12]);
|
|
//Normal Browsers
|
|
else
|
|
curTransform = parseFloat(matrix[4]);
|
|
}
|
|
if (axis === 'y') {
|
|
//Latest Chrome and webkits Fix
|
|
if (window.WebKitCSSMatrix)
|
|
curTransform = transformMatrix.m42;
|
|
//Crazy IE10 Matrix
|
|
else if (matrix.length === 16)
|
|
curTransform = parseFloat(matrix[13]);
|
|
//Normal Browsers
|
|
else
|
|
curTransform = parseFloat(matrix[5]);
|
|
}
|
|
}
|
|
else {
|
|
if (axis === 'x') curTransform = parseFloat(el.style.left, 10) || 0;
|
|
if (axis === 'y') curTransform = parseFloat(el.style.top, 10) || 0;
|
|
}
|
|
return curTransform || 0;
|
|
},
|
|
|
|
setWrapperTranslate : function (x, y, z) {
|
|
'use strict';
|
|
var es = this.wrapper.style,
|
|
coords = {x: 0, y: 0, z: 0},
|
|
translate;
|
|
|
|
// passed all coordinates
|
|
if (arguments.length === 3) {
|
|
coords.x = x;
|
|
coords.y = y;
|
|
coords.z = z;
|
|
}
|
|
|
|
// passed one coordinate and optional axis
|
|
else {
|
|
if (typeof y === 'undefined') {
|
|
y = this.params.mode === 'horizontal' ? 'x' : 'y';
|
|
}
|
|
coords[y] = x;
|
|
}
|
|
|
|
if (this.support.transforms && this.params.useCSS3Transforms) {
|
|
translate = this.support.transforms3d ? 'translate3d(' + coords.x + 'px, ' + coords.y + 'px, ' + coords.z + 'px)' : 'translate(' + coords.x + 'px, ' + coords.y + 'px)';
|
|
es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = translate;
|
|
}
|
|
else {
|
|
es.left = coords.x + 'px';
|
|
es.top = coords.y + 'px';
|
|
}
|
|
this.callPlugins('onSetWrapperTransform', coords);
|
|
if (this.params.onSetWrapperTransform) this.fireCallback(this.params.onSetWrapperTransform, this, coords);
|
|
},
|
|
|
|
setWrapperTransition : function (duration) {
|
|
'use strict';
|
|
var es = this.wrapper.style;
|
|
es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = (duration / 1000) + 's';
|
|
this.callPlugins('onSetWrapperTransition', {duration: duration});
|
|
if (this.params.onSetWrapperTransition) this.fireCallback(this.params.onSetWrapperTransition, this, duration);
|
|
|
|
},
|
|
|
|
/*==================================================
|
|
Helpers
|
|
====================================================*/
|
|
h : {
|
|
getWidth: function (el, outer) {
|
|
'use strict';
|
|
var width = window.getComputedStyle(el, null).getPropertyValue('width');
|
|
var returnWidth = parseFloat(width);
|
|
//IE Fixes
|
|
if (isNaN(returnWidth) || width.indexOf('%') > 0) {
|
|
returnWidth = el.offsetWidth - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-left')) - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-right'));
|
|
}
|
|
if (outer) returnWidth += parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-left')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-right'));
|
|
|
|
return returnWidth;
|
|
},
|
|
getHeight: function (el, outer) {
|
|
'use strict';
|
|
if (outer) return el.offsetHeight;
|
|
|
|
var height = window.getComputedStyle(el, null).getPropertyValue('height');
|
|
var returnHeight = parseFloat(height);
|
|
//IE Fixes
|
|
if (isNaN(returnHeight) || height.indexOf('%') > 0) {
|
|
returnHeight = el.offsetHeight - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-top')) - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-bottom'));
|
|
}
|
|
if (outer) returnHeight += parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-bottom'));
|
|
return returnHeight;
|
|
},
|
|
getOffset: function (el) {
|
|
'use strict';
|
|
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;
|
|
if (document.documentElement && !window.pageYOffset) {
|
|
//IE7-8
|
|
scrollTop = document.documentElement.scrollTop;
|
|
scrollLeft = document.documentElement.scrollLeft;
|
|
}
|
|
return {
|
|
top: box.top + scrollTop - clientTop,
|
|
left: box.left + scrollLeft - clientLeft
|
|
};
|
|
},
|
|
windowWidth : function () {
|
|
'use strict';
|
|
if (window.innerWidth) return window.innerWidth;
|
|
else if (document.documentElement && document.documentElement.clientWidth) return document.documentElement.clientWidth;
|
|
},
|
|
windowHeight : function () {
|
|
'use strict';
|
|
if (window.innerHeight) return window.innerHeight;
|
|
else if (document.documentElement && document.documentElement.clientHeight) return document.documentElement.clientHeight;
|
|
},
|
|
windowScroll : function () {
|
|
'use strict';
|
|
var left = 0, top = 0;
|
|
if (typeof pageYOffset !== 'undefined') {
|
|
return {
|
|
left: window.pageXOffset,
|
|
top: window.pageYOffset
|
|
};
|
|
}
|
|
else if (document.documentElement) {
|
|
return {
|
|
left: document.documentElement.scrollLeft,
|
|
top: document.documentElement.scrollTop
|
|
};
|
|
}
|
|
},
|
|
|
|
addEventListener : function (el, event, listener, useCapture) {
|
|
'use strict';
|
|
if (typeof useCapture === 'undefined') {
|
|
useCapture = false;
|
|
}
|
|
|
|
if (el.addEventListener) {
|
|
el.addEventListener(event, listener, useCapture);
|
|
}
|
|
else if (el.attachEvent) {
|
|
el.attachEvent('on' + event, listener);
|
|
}
|
|
},
|
|
|
|
removeEventListener : function (el, event, listener, useCapture) {
|
|
'use strict';
|
|
if (typeof useCapture === 'undefined') {
|
|
useCapture = false;
|
|
}
|
|
|
|
if (el.removeEventListener) {
|
|
el.removeEventListener(event, listener, useCapture);
|
|
}
|
|
else if (el.detachEvent) {
|
|
el.detachEvent('on' + event, listener);
|
|
}
|
|
}
|
|
},
|
|
setTransform : function (el, transform) {
|
|
'use strict';
|
|
var es = el.style;
|
|
es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transform;
|
|
},
|
|
setTranslate : function (el, translate) {
|
|
'use strict';
|
|
var es = el.style;
|
|
var pos = {
|
|
x : translate.x || 0,
|
|
y : translate.y || 0,
|
|
z : translate.z || 0
|
|
};
|
|
var transformString = this.support.transforms3d ? 'translate3d(' + (pos.x) + 'px,' + (pos.y) + 'px,' + (pos.z) + 'px)' : 'translate(' + (pos.x) + 'px,' + (pos.y) + 'px)';
|
|
es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transformString;
|
|
if (!this.support.transforms) {
|
|
es.left = pos.x + 'px';
|
|
es.top = pos.y + 'px';
|
|
}
|
|
},
|
|
setTransition : function (el, duration) {
|
|
'use strict';
|
|
var es = el.style;
|
|
es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = duration + 'ms';
|
|
},
|
|
/*==================================================
|
|
Feature Detection
|
|
====================================================*/
|
|
support: {
|
|
|
|
touch : (window.Modernizr && Modernizr.touch === true) || (function () {
|
|
'use strict';
|
|
return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
|
|
})(),
|
|
|
|
transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {
|
|
'use strict';
|
|
var div = document.createElement('div').style;
|
|
return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);
|
|
})(),
|
|
|
|
transforms : (window.Modernizr && Modernizr.csstransforms === true) || (function () {
|
|
'use strict';
|
|
var div = document.createElement('div').style;
|
|
return ('transform' in div || 'WebkitTransform' in div || 'MozTransform' in div || 'msTransform' in div || 'MsTransform' in div || 'OTransform' in div);
|
|
})(),
|
|
|
|
transitions : (window.Modernizr && Modernizr.csstransitions === true) || (function () {
|
|
'use strict';
|
|
var div = document.createElement('div').style;
|
|
return ('transition' in div || 'WebkitTransition' in div || 'MozTransition' in div || 'msTransition' in div || 'MsTransition' in div || 'OTransition' in div);
|
|
})()
|
|
},
|
|
|
|
browser : {
|
|
|
|
ie8 : (function () {
|
|
'use strict';
|
|
var rv = -1; // Return value assumes failure.
|
|
if (navigator.appName === 'Microsoft Internet Explorer') {
|
|
var ua = navigator.userAgent;
|
|
var re = new RegExp(/MSIE ([0-9]{1,}[\.0-9]{0,})/);
|
|
if (re.exec(ua) != null)
|
|
rv = parseFloat(RegExp.$1);
|
|
}
|
|
return rv !== -1 && rv < 9;
|
|
})(),
|
|
|
|
ie10 : window.navigator.msPointerEnabled,
|
|
ie11 : window.navigator.pointerEnabled
|
|
}
|
|
};
|
|
|
|
/*=========================
|
|
jQuery & Zepto Plugins
|
|
===========================*/
|
|
if (window.jQuery || window.Zepto) {
|
|
(function ($) {
|
|
'use strict';
|
|
$.fn.swiper = function (params) {
|
|
var s = new Swiper($(this)[0], params);
|
|
$(this).data('swiper', s);
|
|
return s;
|
|
};
|
|
})(window.jQuery || window.Zepto);
|
|
}
|
|
|
|
// component
|
|
if (typeof(module) !== 'undefined')
|
|
{
|
|
module.exports = Swiper;
|
|
}
|