swiper-rails 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Swiper 1.9.3 - Mobile Touch Slider
2
+ * Swiper 2.1 - Mobile Touch Slider
3
3
  * http://www.idangero.us/sliders/swiper/
4
4
  *
5
5
  * Copyright 2012-2013, Vladimir Kharlampidi
@@ -8,34 +8,27 @@
8
8
  *
9
9
  * Licensed under GPL & MIT
10
10
  *
11
- * Updated on: April 30, 2013
11
+ * Updated on: August 22, 2013
12
12
  */
13
- var Swiper = function (selector, params, callback) {
13
+ var Swiper = function (selector, params) {
14
14
  /*=========================
15
15
  A little bit dirty but required part for IE8 and old FF support
16
16
  ===========================*/
17
- if (!window.addEventListener) {
18
- if (!window.Element)
19
- Element = function () { };
20
-
21
- Element.prototype.addEventListener = HTMLDocument.prototype.addEventListener = addEventListener = function (type, listener, useCapture) { this.attachEvent('on' + type, listener); }
22
- Element.prototype.removeEventListener = HTMLDocument.prototype.removeEventListener = removeEventListener = function (type, listener, useCapture) { this.detachEvent('on' + type, listener); }
23
- }
24
-
25
17
  if (document.body.__defineGetter__) {
26
18
  if (HTMLElement) {
27
19
  var element = HTMLElement.prototype;
28
- if (element.__defineGetter__)
20
+ if (element.__defineGetter__) {
29
21
  element.__defineGetter__("outerHTML", function () { return new XMLSerializer().serializeToString(this); } );
22
+ }
30
23
  }
31
24
  }
32
-
25
+
33
26
  if (!window.getComputedStyle) {
34
27
  window.getComputedStyle = function (el, pseudo) {
35
28
  this.el = el;
36
29
  this.getPropertyValue = function (prop) {
37
30
  var re = /(\-([a-z]){1})/g;
38
- if (prop == 'float') prop = 'styleFloat';
31
+ if (prop === 'float') prop = 'styleFloat';
39
32
  if (re.test(prop)) {
40
33
  prop = prop.replace(re, function () {
41
34
  return arguments[2].toUpperCase();
@@ -46,142 +39,255 @@ var Swiper = function (selector, params, callback) {
46
39
  return this;
47
40
  }
48
41
  }
49
-
50
- /* End Of Polyfills*/
51
- if(!(selector.nodeType))
52
- if (!document.querySelectorAll||document.querySelectorAll(selector).length==0) return;
53
-
54
- function dQ(s) {
55
- return document.querySelectorAll(s)
42
+ if (!Array.prototype.indexOf) {
43
+ Array.prototype.indexOf = function(obj, start) {
44
+ for (var i = (start || 0), j = this.length; i < j; i++) {
45
+ if (this[i] === obj) { return i; }
46
+ }
47
+ return -1;
48
+ }
49
+ }
50
+ if (!document.querySelectorAll) {
51
+ if (!window.jQuery) return;
52
+ }
53
+ function $$(s) {
54
+ if (document.querySelectorAll)
55
+ return document.querySelectorAll(s);
56
+ else
57
+ return jQuery(s);
58
+ }
59
+
60
+ /*=========================
61
+ Check for correct selector
62
+ ===========================*/
63
+ if(typeof selector === 'undefined') return;
64
+
65
+ if(!(selector.nodeType)){
66
+ if ($$(selector).length === 0) return;
56
67
  }
57
- var _this = this
58
- _this.touches = {};
68
+
69
+ /*=========================
70
+ _this
71
+ ===========================*/
72
+ var _this = this;
73
+
74
+ /*=========================
75
+ Default Flags and vars
76
+ ===========================*/
77
+ _this.touches = {
78
+ start:0,
79
+ startX:0,
80
+ startY:0,
81
+ current:0,
82
+ currentX:0,
83
+ currentY:0,
84
+ diff:0,
85
+ abs:0
86
+ };
59
87
  _this.positions = {
60
- current : 0
88
+ start:0,
89
+ abs:0,
90
+ diff:0,
91
+ current:0
92
+ };
93
+ _this.times = {
94
+ start:0,
95
+ end:0
61
96
  };
97
+
62
98
  _this.id = (new Date()).getTime();
63
- _this.container = (selector.nodeType) ? selector : dQ(selector)[0];
64
- _this.times = {};
99
+ _this.container = (selector.nodeType) ? selector : $$(selector)[0];
65
100
  _this.isTouched = false;
66
- _this.realIndex = 0;
67
- _this.activeSlide = 0;
101
+ _this.isMoved = false;
68
102
  _this.activeIndex = 0;
69
- _this.previousSlide = null;
103
+ _this.activeLoaderIndex = 0;
104
+ _this.activeLoopIndex = 0;
70
105
  _this.previousIndex = null;
71
- _this.langDirection = window.getComputedStyle(_this.container, null).getPropertyValue('direction')
72
- /*=========================
73
- New Support Object
74
- ===========================*/
75
- _this.support = {
76
- touch : _this.isSupportTouch(),
77
- threeD : _this.isSupport3D(),
78
- transitions : _this.isSupportTransitions()
79
- }
80
- //For fallback with older versions
81
- _this.use3D = _this.support.threeD;
82
-
83
-
106
+ _this.velocity = 0;
107
+ _this.snapGrid = [];
108
+ _this.slidesGrid = [];
109
+ _this.imagesToLoad = [];
110
+ _this.imagesLoaded = 0;
111
+ _this.wrapperLeft=0;
112
+ _this.wrapperRight=0;
113
+ _this.wrapperTop=0;
114
+ _this.wrapperBottom=0;
115
+ var wrapper, slideSize, wrapperSize, direction, isScrolling, containerSize;
116
+
84
117
  /*=========================
85
118
  Default Parameters
86
119
  ===========================*/
87
120
  var defaults = {
88
- mode : 'horizontal',
89
- ratio : 1,
121
+ mode : 'horizontal', // or 'vertical'
122
+ touchRatio : 1,
90
123
  speed : 300,
91
124
  freeMode : false,
92
125
  freeModeFluid : false,
93
- slidesPerSlide : 1,
126
+ momentumRatio: 1,
127
+ momentumBounce: true,
128
+ momentumBounceRatio: 1,
129
+ slidesPerView : 1,
94
130
  slidesPerGroup : 1,
95
131
  simulateTouch : true,
96
132
  followFinger : true,
97
133
  shortSwipes : true,
98
134
  moveStartThreshold:false,
99
- autoPlay:false,
135
+ autoplay: false,
100
136
  onlyExternal : false,
101
137
  createPagination : true,
102
138
  pagination : false,
103
- resistance : true,
104
- nopeek : false,
139
+ paginationElement: 'span',
140
+ paginationClickable: false,
141
+ paginationAsRange: true,
142
+ resistance : true, // or false or 100%
105
143
  scrollContainer : false,
106
144
  preventLinks : true,
107
- preventClassNoSwiping : true,
145
+ noSwiping : false, // or class
146
+ noSwipingClass : 'swiper-no-swiping', //:)
108
147
  initialSlide: 0,
109
- keyboardControl: false,
148
+ keyboardControl: false,
110
149
  mousewheelControl : false,
111
- resizeEvent : 'auto', //or 'resize' or 'orientationchange'
150
+ mousewheelDebounce: 600,
112
151
  useCSS3Transforms : true,
152
+ //Loop mode
153
+ loop:false,
154
+ loopAdditionalSlides:0,
155
+ //Auto Height
156
+ calculateHeight: false,
157
+ //Images Preloader
158
+ updateOnImagesReady : true,
159
+ //Form elements
160
+ releaseFormElements : true,
161
+ //Watch for active slide, useful when use effects on different slide states
162
+ watchActiveIndex: false,
163
+ //Slides Visibility Fit
164
+ visibilityFullFit : false,
165
+ //Slides Offset
166
+ offsetPxBefore : 0,
167
+ offsetPxAfter : 0,
168
+ offsetSlidesBefore : 0,
169
+ offsetSlidesAfter : 0,
170
+ centeredSlides: false,
171
+ //Queue callbacks
172
+ queueStartCallbacks : false,
173
+ queueEndCallbacks : false,
174
+ //Auto Resize
175
+ autoResize : true,
176
+ resizeReInit : false,
177
+ //DOMAnimation
178
+ DOMAnimation : true,
179
+ //Slides Loader
180
+ loader: {
181
+ slides:[], //array with slides
182
+ slidesHTMLType:'inner', // or 'outer'
183
+ surroundGroups: 1, //keep preloaded slides groups around view
184
+ logic: 'reload', //or 'change'
185
+ loadAllSlides: false
186
+ },
113
187
  //Namespace
114
188
  slideElement : 'div',
115
189
  slideClass : 'swiper-slide',
190
+ slideActiveClass : 'swiper-slide-active',
191
+ slideVisibleClass : 'swiper-slide-visible',
116
192
  wrapperClass : 'swiper-wrapper',
117
- paginationClass: 'swiper-pagination-switch' ,
118
- paginationActiveClass : 'swiper-active-switch'
193
+ paginationElementClass: 'swiper-pagination-switch',
194
+ paginationActiveClass : 'swiper-active-switch',
195
+ paginationVisibleClass : 'swiper-visible-switch'
119
196
  }
120
- params = params || {};
197
+ params = params || {};
121
198
  for (var prop in defaults) {
122
- if (! (prop in params)) {
123
- params[prop] = defaults[prop]
199
+ if (prop in params && typeof params[prop]==='object') {
200
+ for (var subProp in defaults[prop]) {
201
+ if (! (subProp in params[prop])) {
202
+ params[prop][subProp] = defaults[prop][subProp];
203
+ }
204
+ }
205
+ }
206
+ else if (! (prop in params)) {
207
+ params[prop] = defaults[prop]
124
208
  }
125
209
  }
126
210
  _this.params = params;
127
211
  if (params.scrollContainer) {
128
212
  params.freeMode = true;
129
- params.freeModeFluid = true;
213
+ params.freeModeFluid = true;
130
214
  }
131
- var _widthFromCSS = false
132
- if (params.slidesPerSlide=='auto') {
133
- _widthFromCSS = true;
134
- params.slidesPerSlide = 1;
215
+ if (params.loop) {
216
+ params.resistance = '100%';
135
217
  }
136
-
137
- //Default Vars
138
- var wrapper, isHorizontal,
139
- slideSize, numOfSlides, wrapperSize, direction, isScrolling, containerSize;
140
-
141
- //Define wrapper
218
+ var isH = params.mode==='horizontal';
219
+
220
+ /*=========================
221
+ Define Touch Events
222
+ ===========================*/
223
+
224
+ _this.touchEvents = {
225
+ touchStart : _this.support.touch || !params.simulateTouch ? 'touchstart' : (_this.browser.ie10 ? 'MSPointerDown' : 'mousedown'),
226
+ touchMove : _this.support.touch || !params.simulateTouch ? 'touchmove' : (_this.browser.ie10 ? 'MSPointerMove' : 'mousemove'),
227
+ touchEnd : _this.support.touch || !params.simulateTouch ? 'touchend' : (_this.browser.ie10 ? 'MSPointerUp' : 'mouseup')
228
+ };
229
+
230
+ /*=========================
231
+ Wrapper
232
+ ===========================*/
142
233
  for (var i = _this.container.childNodes.length - 1; i >= 0; i--) {
143
-
144
234
  if (_this.container.childNodes[i].className) {
145
-
146
235
  var _wrapperClasses = _this.container.childNodes[i].className.split(' ')
147
-
148
236
  for (var j = 0; j < _wrapperClasses.length; j++) {
149
237
  if (_wrapperClasses[j]===params.wrapperClass) {
150
- wrapper = _this.container.childNodes[i]
238
+ wrapper = _this.container.childNodes[i];
151
239
  }
152
- };
240
+ };
153
241
  }
154
242
  };
155
243
 
156
244
  _this.wrapper = wrapper;
157
- //Mode
158
- isHorizontal = params.mode == 'horizontal';
159
-
160
- //Define Touch Events
161
- _this.touchEvents = {
162
- touchStart : _this.support.touch || !params.simulateTouch ? 'touchstart' : (_this.ie10 ? 'MSPointerDown' : 'mousedown'),
163
- touchMove : _this.support.touch || !params.simulateTouch ? 'touchmove' : (_this.ie10 ? 'MSPointerMove' : 'mousemove'),
164
- touchEnd : _this.support.touch || !params.simulateTouch ? 'touchend' : (_this.ie10 ? 'MSPointerUp' : 'mouseup')
165
- };
166
-
167
245
  /*=========================
168
246
  Slide API
169
247
  ===========================*/
170
248
  _this._extendSwiperSlide = function (el) {
171
249
  el.append = function () {
172
- _this.wrapper.appendChild(el);
250
+ if (params.loop) {
251
+ el.insertAfter(_this.slides.length-_this.loopedSlides);
252
+ _this.removeLoopedSlides();
253
+ _this.calcSlides();
254
+ _this.createLoop();
255
+ }
256
+ else {
257
+ _this.wrapper.appendChild(el);
258
+ }
259
+
173
260
  _this.reInit();
174
261
  return el;
175
262
  }
176
263
  el.prepend = function () {
177
- _this.wrapper.insertBefore(el, _this.wrapper.firstChild)
264
+ if (params.loop) {
265
+ _this.wrapper.insertBefore(el, _this.slides[_this.loopedSlides]);
266
+ _this.removeLoopedSlides();
267
+ _this.calcSlides();
268
+ _this.createLoop();
269
+ }
270
+ else {
271
+ _this.wrapper.insertBefore(el, _this.wrapper.firstChild);
272
+ }
178
273
  _this.reInit();
179
274
  return el;
180
275
  }
181
276
  el.insertAfter = function (index) {
182
277
  if(typeof index === 'undefined') return false;
183
- var beforeSlide = _this.slides[index+1]
184
- _this.wrapper.insertBefore(el, beforeSlide)
278
+ var beforeSlide;
279
+
280
+ if (params.loop) {
281
+ beforeSlide = _this.slides[index + 1 + _this.loopedSlides];
282
+ _this.wrapper.insertBefore(el, beforeSlide);
283
+ _this.removeLoopedSlides();
284
+ _this.calcSlides();
285
+ _this.createLoop();
286
+ }
287
+ else {
288
+ beforeSlide = _this.slides[index + 1];
289
+ _this.wrapper.insertBefore(el, beforeSlide)
290
+ }
185
291
  _this.reInit();
186
292
  return el;
187
293
  }
@@ -190,11 +296,11 @@ var Swiper = function (selector, params, callback) {
190
296
  }
191
297
  el.remove = function () {
192
298
  _this.wrapper.removeChild(el);
193
- _this.reInit()
299
+ _this.reInit();
194
300
  }
195
301
  el.html = function (html) {
196
302
  if (typeof html === 'undefined') {
197
- return el.innerHTML
303
+ return el.innerHTML;
198
304
  }
199
305
  else {
200
306
  el.innerHTML = html;
@@ -202,19 +308,19 @@ var Swiper = function (selector, params, callback) {
202
308
  }
203
309
  }
204
310
  el.index = function () {
205
- var index
311
+ var index;
206
312
  for (var i = _this.slides.length - 1; i >= 0; i--) {
207
- if(el==_this.slides[i]) index = i
208
- };
313
+ if(el === _this.slides[i]) index = i;
314
+ }
209
315
  return index;
210
316
  }
211
317
  el.isActive = function () {
212
- if (el.index() == _this.activeIndex) return true;
318
+ if (el.index() === _this.activeIndex) return true;
213
319
  else return false;
214
320
  }
215
321
  if (!el.swiperSlideDataStorage) el.swiperSlideDataStorage={};
216
322
  el.getData = function (name) {
217
- return el.swiperSlideDataStorage[name]
323
+ return el.swiperSlideDataStorage[name];
218
324
  }
219
325
  el.setData = function (name, value) {
220
326
  el.swiperSlideDataStorage[name] = value;
@@ -229,51 +335,59 @@ var Swiper = function (selector, params, callback) {
229
335
  return el;
230
336
  }
231
337
  }
338
+ el.getWidth = function (outer) {
339
+ return _this.h.getWidth(el, outer);
340
+ }
341
+ el.getHeight = function (outer) {
342
+ return _this.h.getHeight(el, outer);
343
+ }
344
+ el.getOffset = function() {
345
+ return _this.h.getOffset(el);
346
+ }
232
347
  return el;
233
348
  }
234
349
 
235
- //Calculate information about slides
236
- _this._calcSlides = function () {
350
+ //Calculate information about number of slides
351
+ _this.calcSlides = function (forceCalcSlides) {
237
352
  var oldNumber = _this.slides ? _this.slides.length : false;
238
- _this.slides = []
353
+ _this.slides = [];
354
+ _this.displaySlides = [];
239
355
  for (var i = 0; i < _this.wrapper.childNodes.length; i++) {
240
356
  if (_this.wrapper.childNodes[i].className) {
241
- var _slideClasses = _this.wrapper.childNodes[i].className.split(' ')
357
+ var _className = _this.wrapper.childNodes[i].className;
358
+ var _slideClasses = _className.split(' ');
242
359
  for (var j = 0; j < _slideClasses.length; j++) {
243
- if(_slideClasses[j]===params.slideClass) _this.slides.push(_this.wrapper.childNodes[i])
244
- };
245
- }
246
- };
247
- for (var i = _this.slides.length - 1; i >= 0; i--) {
360
+ if(_slideClasses[j]===params.slideClass) {
361
+ _this.slides.push(_this.wrapper.childNodes[i]);
362
+ }
363
+ }
364
+ }
365
+ }
366
+ for (i = _this.slides.length - 1; i >= 0; i--) {
248
367
  _this._extendSwiperSlide(_this.slides[i]);
249
- };
368
+ }
250
369
  if (!oldNumber) return;
251
- if(oldNumber!=_this.slides.length && _this.createPagination) {
370
+ if(oldNumber!==_this.slides.length || forceCalcSlides) {
252
371
  // Number of slides has been changed
253
- _this.createPagination();
254
- _this.callPlugins('numberOfSlidesChanged')
255
- }
256
- /*
257
- if (_this.langDirection=='rtl') {
258
- for (var i = 0; i < _this.slides.length; i++) {
259
- _this.slides[i].style.float="right"
260
- };
372
+ removeSlideEvents();
373
+ addSlideEvents();
374
+ _this.updateActiveSlide();
375
+ if (params.createPagination && _this.params.pagination) _this.createPagination();
376
+ _this.callPlugins('numberOfSlidesChanged');
261
377
  }
262
- */
263
378
  }
264
- _this._calcSlides();
265
379
 
266
380
  //Create Slide
267
381
  _this.createSlide = function (html, slideClassList, el) {
268
382
  var slideClassList = slideClassList || _this.params.slideClass;
269
383
  var el = el||params.slideElement;
270
- var newSlide = document.createElement(el)
384
+ var newSlide = document.createElement(el);
271
385
  newSlide.innerHTML = html||'';
272
386
  newSlide.className = slideClassList;
273
387
  return _this._extendSwiperSlide(newSlide);
274
388
  }
275
389
 
276
- //Append Slide
390
+ //Append Slide
277
391
  _this.appendSlide = function (html, slideClassList, el) {
278
392
  if (!html) return;
279
393
  if (html.nodeType) {
@@ -293,34 +407,47 @@ var Swiper = function (selector, params, callback) {
293
407
  }
294
408
  }
295
409
  _this.insertSlideAfter = function (index, html, slideClassList, el) {
296
- if (!index) return false;
410
+ if (typeof index === 'undefined') return false;
297
411
  if (html.nodeType) {
298
- return _this._extendSwiperSlide(html).insertAfter(index)
412
+ return _this._extendSwiperSlide(html).insertAfter(index);
299
413
  }
300
414
  else {
301
- return _this.createSlide(html, slideClassList, el).insertAfter(index)
415
+ return _this.createSlide(html, slideClassList, el).insertAfter(index);
302
416
  }
303
417
  }
304
418
  _this.removeSlide = function (index) {
305
419
  if (_this.slides[index]) {
306
- _this.slides[index].remove()
420
+ if (params.loop) {
421
+ if (!_this.slides[index+_this.loopedSlides]) return false;
422
+ _this.slides[index+_this.loopedSlides].remove();
423
+ _this.removeLoopedSlides();
424
+ _this.calcSlides();
425
+ _this.createLoop();
426
+ }
427
+ else _this.slides[index].remove();
307
428
  return true;
308
429
  }
309
430
  else return false;
310
431
  }
311
432
  _this.removeLastSlide = function () {
312
433
  if (_this.slides.length>0) {
313
- _this.slides[ (_this.slides.length-1) ].remove();
314
- return true
434
+ if (params.loop) {
435
+ _this.slides[_this.slides.length - 1 - _this.loopedSlides].remove();
436
+ _this.removeLoopedSlides();
437
+ _this.calcSlides();
438
+ _this.createLoop();
439
+ }
440
+ else _this.slides[ (_this.slides.length-1) ].remove();
441
+ return true;
315
442
  }
316
443
  else {
317
- return false
444
+ return false;
318
445
  }
319
446
  }
320
447
  _this.removeAllSlides = function () {
321
448
  for (var i = _this.slides.length - 1; i >= 0; i--) {
322
449
  _this.slides[i].remove()
323
- };
450
+ }
324
451
  }
325
452
  _this.getSlide = function (index) {
326
453
  return _this.slides[index]
@@ -333,449 +460,599 @@ var Swiper = function (selector, params, callback) {
333
460
  }
334
461
 
335
462
  //Currently Active Slide
336
- _this.currentSlide = function () {
463
+ _this.activeSlide = function () {
337
464
  return _this.slides[_this.activeIndex]
338
465
  }
339
-
466
+
340
467
  /*=========================
341
- Find All Plugins
342
- !!! Plugins API is in beta !!!
468
+ Plugins API
343
469
  ===========================*/
344
470
  var _plugins = [];
345
471
  for (var plugin in _this.plugins) {
346
472
  if (params[plugin]) {
347
- var p = _this.plugins[plugin](_this, params[plugin])
348
- if (p)
349
- _plugins.push( p )
473
+ var p = _this.plugins[plugin](_this, params[plugin]);
474
+ if (p) _plugins.push( p );
350
475
  }
351
476
  }
352
-
353
477
  _this.callPlugins = function(method, args) {
354
478
  if (!args) args = {}
355
479
  for (var i=0; i<_plugins.length; i++) {
356
480
  if (method in _plugins[i]) {
357
481
  _plugins[i][method](args);
358
482
  }
359
-
360
483
  }
361
-
362
484
  }
363
485
 
364
486
  /*=========================
365
487
  WP8 Fix
366
488
  ===========================*/
367
- if (_this.ie10 && !params.onlyExternal) {
368
- if (isHorizontal) _this.wrapper.classList.add('swiper-wp8-horizontal')
369
- else _this.wrapper.classList.add('swiper-wp8-vertical')
489
+ if (_this.browser.ie10 && !params.onlyExternal) {
490
+ if (isH) _this.wrapper.classList.add('swiper-wp8-horizontal');
491
+ else _this.wrapper.classList.add('swiper-wp8-vertical');
370
492
  }
371
-
493
+
372
494
  /*=========================
373
- Loop
495
+ Free Mode Class
374
496
  ===========================*/
375
- if (params.loop) {
376
- (function(){
377
- numOfSlides = _this.slides.length;
378
- if (_this.slides.length==0) return;
379
- var slideFirstHTML = '';
380
- var slideLastHTML = '';
381
- //Grab First Slides
382
- for (var i=0; i<params.slidesPerSlide; i++) {
383
- slideFirstHTML+=_this.slides[i].outerHTML
384
- }
385
- //Grab Last Slides
386
- for (var i=numOfSlides-params.slidesPerSlide; i<numOfSlides; i++) {
387
- slideLastHTML+=_this.slides[i].outerHTML
388
- }
389
- wrapper.innerHTML = slideLastHTML + wrapper.innerHTML + slideFirstHTML;
390
- _this._calcSlides()
391
- _this.callPlugins('onCreateLoop');
392
- })();
497
+ if (params.freeMode) {
498
+ _this.container.className+=' swiper-free-mode';
393
499
  }
394
-
395
- //Init Function
396
- var firstInit = false;
397
- //ReInitizize function. Good to use after dynamically changes of Swiper, like after add/remove slides
398
- _this.reInit = function () {
399
- _this.init(true)
400
- }
401
- _this.init = function(reInit) {
402
- var _width = window.getComputedStyle(_this.container, null).getPropertyValue('width')
403
- var _height = window.getComputedStyle(_this.container, null).getPropertyValue('height')
404
- var newWidth = parseInt(_width,10);
405
- var newHeight = parseInt(_height,10);
406
-
407
- //IE8 Fixes
408
- if(isNaN(newWidth) || _width.indexOf('%')>0) {
409
- newWidth = _this.container.offsetWidth - parseInt(window.getComputedStyle(_this.container, null).getPropertyValue('padding-left'),10) - parseInt(window.getComputedStyle(_this.container, null).getPropertyValue('padding-right'),10)
410
- }
411
- if(isNaN(newHeight) || _height.indexOf('%')>0) {
412
- newHeight = _this.container.offsetHeight - parseInt(window.getComputedStyle(_this.container, null).getPropertyValue('padding-top'),10) - parseInt(window.getComputedStyle(_this.container, null).getPropertyValue('padding-bottom'),10)
413
- }
414
- if (!reInit) {
415
- if (_this.width==newWidth && _this.height==newHeight) return
416
- }
417
- if (reInit || firstInit) {
418
- _this._calcSlides();
419
- if (params.pagination) {
420
- _this.updatePagination()
421
- }
422
- }
423
- _this.width = newWidth;
424
- _this.height = newHeight;
425
-
426
- var dividerVertical = isHorizontal ? 1 : params.slidesPerSlide,
427
- dividerHorizontal = isHorizontal ? params.slidesPerSlide : 1,
428
- slideWidth, slideHeight, wrapperWidth, wrapperHeight;
429
-
430
- numOfSlides = _this.slides.length
431
- if (!params.scrollContainer) {
432
- if (!_widthFromCSS) {
433
- slideWidth = _this.width/dividerHorizontal;
434
- slideHeight = _this.height/dividerVertical;
500
+
501
+ /*==================================================
502
+ Init/Re-init/Resize Fix
503
+ ====================================================*/
504
+ _this.initialized = false;
505
+ _this.init = function(force, forceCalcSlides) {
506
+ var _width = _this.h.getWidth(_this.container);
507
+ var _height = _this.h.getHeight(_this.container);
508
+ if (_width===_this.width && _height===_this.height && !force) return;
509
+ _this.width = _width;
510
+ _this.height = _height;
511
+
512
+ containerSize = isH ? _width : _height;
513
+ var wrapper = _this.wrapper;
514
+
515
+ if (force) {
516
+ _this.calcSlides(forceCalcSlides);
517
+ }
518
+
519
+ if (params.slidesPerView==='auto') {
520
+ //Auto mode
521
+ var slidesWidth = 0;
522
+ var slidesHeight = 0;
523
+
524
+ //Unset Styles
525
+ if (params.slidesOffset>0) {
526
+ wrapper.style.paddingLeft = '';
527
+ wrapper.style.paddingRight = '';
528
+ wrapper.style.paddingTop = '';
529
+ wrapper.style.paddingBottom = '';
530
+ }
531
+ wrapper.style.width = '';
532
+ wrapper.style.height = '';
533
+ if (params.offsetPxBefore>0) {
534
+ if (isH) _this.wrapperLeft = params.offsetPxBefore;
535
+ else _this.wrapperTop = params.offsetPxBefore;
536
+ }
537
+ if (params.offsetPxAfter>0) {
538
+ if (isH) _this.wrapperRight = params.offsetPxAfter;
539
+ else _this.wrapperBottom = params.offsetPxAfter;
540
+ }
541
+
542
+ if (params.centeredSlides) {
543
+ if (isH) {
544
+ _this.wrapperLeft = (containerSize - this.slides[0].getWidth(true) )/2;
545
+ _this.wrapperRight = (containerSize - _this.slides[ _this.slides.length-1 ].getWidth(true))/2;
546
+ }
547
+ else {
548
+ _this.wrapperTop = (containerSize - _this.slides[0].getHeight(true))/2;
549
+ _this.wrapperBottom = (containerSize - _this.slides[ _this.slides.length-1 ].getHeight(true))/2;
550
+ }
551
+ }
552
+
553
+ if (isH) {
554
+ if (_this.wrapperLeft>=0) wrapper.style.paddingLeft = _this.wrapperLeft+'px';
555
+ if (_this.wrapperRight>=0) wrapper.style.paddingRight = _this.wrapperRight+'px';
435
556
  }
436
557
  else {
437
- slideWidth = _this.slides[0].offsetWidth;
438
- slideHeight = _this.slides[0].offsetHeight;
558
+ if (_this.wrapperTop>=0) wrapper.style.paddingTop = _this.wrapperTop+'px';
559
+ if (_this.wrapperBottom>=0) wrapper.style.paddingBottom = _this.wrapperBottom+'px';
560
+ }
561
+ var slideLeft = 0;
562
+ var centeredSlideLeft=0;
563
+ _this.snapGrid = [];
564
+ _this.slidesGrid = [];
565
+
566
+ var slideMaxHeight = 0;
567
+ for(var i = 0; i<_this.slides.length; i++) {
568
+ var slideWidth = _this.slides[i].getWidth(true);
569
+ var slideHeight = _this.slides[i].getHeight(true);
570
+ if (params.calculateHeight) {
571
+ slideMaxHeight = Math.max(slideMaxHeight, slideHeight)
572
+ }
573
+ var _slideSize = isH ? slideWidth : slideHeight;
574
+ if (params.centeredSlides) {
575
+ var nextSlideWidth = i === _this.slides.length-1 ? 0 : _this.slides[i+1].getWidth(true);
576
+ var nextSlideHeight = i === _this.slides.length-1 ? 0 : _this.slides[i+1].getHeight(true);
577
+ var nextSlideSize = isH ? nextSlideWidth : nextSlideHeight;
578
+ if (_slideSize>containerSize) {
579
+ for (var j=0; j<=Math.floor(_slideSize/(containerSize+_this.wrapperLeft)); j++) {
580
+ if (j === 0) _this.snapGrid.push(slideLeft+_this.wrapperLeft);
581
+ else _this.snapGrid.push(slideLeft+_this.wrapperLeft+containerSize*j);
582
+ }
583
+ _this.slidesGrid.push(slideLeft+_this.wrapperLeft);
584
+ }
585
+ else {
586
+ _this.snapGrid.push(centeredSlideLeft);
587
+ _this.slidesGrid.push(centeredSlideLeft);
588
+ }
589
+
590
+ centeredSlideLeft += _slideSize/2 + nextSlideSize/2;
591
+
592
+ }
593
+ else {
594
+ if (_slideSize>containerSize) {
595
+ for (var j=0; j<=Math.floor(_slideSize/containerSize); j++) {
596
+ _this.snapGrid.push(slideLeft+containerSize*j);
597
+ }
598
+ }
599
+ else {
600
+ _this.snapGrid.push(slideLeft);
601
+ }
602
+ _this.slidesGrid.push(slideLeft);
603
+ }
604
+
605
+ slideLeft += _slideSize;
606
+
607
+ slidesWidth += slideWidth;
608
+ slidesHeight += slideHeight;
609
+ }
610
+ if (params.calculateHeight) _this.height = slideMaxHeight;
611
+ if(isH) {
612
+ wrapperSize = slidesWidth + _this.wrapperRight + _this.wrapperLeft;
613
+ wrapper.style.width = (slidesWidth)+'px';
614
+ wrapper.style.height = (_this.height)+'px';
439
615
  }
440
- containerSize = isHorizontal ? _this.width : _this.height;
441
- slideSize = isHorizontal ? slideWidth : slideHeight;
442
- wrapperWidth = isHorizontal ? numOfSlides * slideWidth : _this.width;
443
- wrapperHeight = isHorizontal ? _this.height : numOfSlides*slideHeight;
444
- if (_widthFromCSS) {
445
- //Re-Calc sps for pagination
446
- params.slidesPerSlide = Math.round(containerSize/slideSize)
616
+ else {
617
+ wrapperSize = slidesHeight + _this.wrapperTop + _this.wrapperBottom;
618
+ wrapper.style.width = (_this.width)+'px';
619
+ wrapper.style.height = (slidesHeight)+'px';
447
620
  }
621
+
622
+ }
623
+ else if (params.scrollContainer) {
624
+ //Scroll Container
625
+ wrapper.style.width = '';
626
+ wrapper.style.height = '';
627
+ var wrapperWidth = _this.slides[0].getWidth(true);
628
+ var wrapperHeight = _this.slides[0].getHeight(true);
629
+ wrapperSize = isH ? wrapperWidth : wrapperHeight;
630
+ wrapper.style.width = wrapperWidth+'px';
631
+ wrapper.style.height = wrapperHeight+'px';
632
+ slideSize = isH ? wrapperWidth : wrapperHeight;
633
+
448
634
  }
449
635
  else {
450
- //Unset dimensions in vertical scroll container mode to recalculate slides
451
- if (!isHorizontal) {
452
- wrapper.style.width='';
636
+ //For usual slides
637
+ if (params.calculateHeight) {
638
+ var slideMaxHeight = 0;
639
+ var wrapperHeight = 0;
640
+ //ResetWrapperSize
641
+ if (!isH) _this.container.style.height= '';
453
642
  wrapper.style.height='';
454
- _this.slides[0].style.width='';
455
- _this.slides[0].style.height='';
643
+
644
+ for (var i=0; i<_this.slides.length; i++) {
645
+ //ResetSlideSize
646
+ _this.slides[i].style.height='';
647
+ slideMaxHeight = Math.max( _this.slides[i].getHeight(true), slideMaxHeight );
648
+ if (!isH) wrapperHeight+=_this.slides[i].getHeight(true);
649
+ }
650
+ var slideHeight = slideMaxHeight;
651
+ _this.height = slideHeight;
652
+
653
+ if (isH) wrapperHeight = slideHeight;
654
+ else containerSize = slideHeight, _this.container.style.height= containerSize+'px';
456
655
  }
457
-
458
- slideWidth = _this.slides[0].offsetWidth;
459
- slideHeight = _this.slides[0].offsetHeight;
460
- containerSize = isHorizontal ? _this.width : _this.height;
461
-
462
- slideSize = isHorizontal ? slideWidth : slideHeight;
463
- wrapperWidth = slideWidth;
464
- wrapperHeight = slideHeight;
465
- }
656
+ else {
657
+ var slideHeight = isH ? _this.height : _this.height/params.slidesPerView ;
658
+ var wrapperHeight = isH ? _this.height : _this.slides.length*slideHeight;
659
+ }
660
+ var slideWidth = isH ? _this.width/params.slidesPerView : _this.width;
661
+ var wrapperWidth = isH ? _this.slides.length*slideWidth : _this.width;
662
+ slideSize = isH ? slideWidth : slideHeight;
466
663
 
467
- wrapperSize = isHorizontal ? wrapperWidth : wrapperHeight;
468
-
469
- for (var i=0; i<_this.slides.length; i++ ) {
470
- var el = _this.slides[i];
471
- if (!_widthFromCSS) {
472
- el.style.width=slideWidth+"px"
473
- el.style.height=slideHeight+"px"
474
- }
475
- if (params.onSlideInitialize) {
476
- params.onSlideInitialize(_this, el);
477
- }
478
- }
479
- wrapper.style.width = wrapperWidth+"px";
480
- wrapper.style.height = wrapperHeight+"px";
481
-
482
- // Set Initial Slide Position
483
- if(params.initialSlide > 0 && params.initialSlide < numOfSlides && !firstInit) {
484
- _this.realIndex = _this.activeIndex = params.initialSlide;
485
-
486
- if (params.loop) {
487
- _this.activeIndex = _this.realIndex-params.slidesPerSlide;
664
+ if (params.offsetSlidesBefore>0) {
665
+ if (isH) _this.wrapperLeft = slideSize*params.offsetSlidesBefore;
666
+ else _this.wrapperTop = slideSize*params.offsetSlidesBefore;
488
667
  }
489
- //Legacy
490
- _this.activeSlide = _this.activeIndex;
491
- //--
492
- if (isHorizontal) {
493
- _this.positions.current = -params.initialSlide * slideWidth;
494
- _this.setTransform( _this.positions.current, 0, 0);
668
+ if (params.offsetSlidesAfter>0) {
669
+ if (isH) _this.wrapperRight = slideSize*params.offsetSlidesAfter;
670
+ else _this.wrapperBottom = slideSize*params.offsetSlidesAfter;
495
671
  }
496
- else {
497
- _this.positions.current = -params.initialSlide * slideHeight;
498
- _this.setTransform( 0, _this.positions.current, 0);
672
+ if (params.offsetPxBefore>0) {
673
+ if (isH) _this.wrapperLeft = params.offsetPxBefore;
674
+ else _this.wrapperTop = params.offsetPxBefore;
675
+ }
676
+ if (params.offsetPxAfter>0) {
677
+ if (isH) _this.wrapperRight = params.offsetPxAfter;
678
+ else _this.wrapperBottom = params.offsetPxAfter;
679
+ }
680
+ if (params.centeredSlides) {
681
+ if (isH) {
682
+ _this.wrapperLeft = (containerSize - slideSize)/2;
683
+ _this.wrapperRight = (containerSize - slideSize)/2;
684
+ }
685
+ else {
686
+ _this.wrapperTop = (containerSize - slideSize)/2;
687
+ _this.wrapperBottom = (containerSize - slideSize)/2;
688
+ }
689
+ }
690
+ if (isH) {
691
+ if (_this.wrapperLeft>0) wrapper.style.paddingLeft = _this.wrapperLeft+'px';
692
+ if (_this.wrapperRight>0) wrapper.style.paddingRight = _this.wrapperRight+'px';
693
+ }
694
+ else {
695
+ if (_this.wrapperTop>0) wrapper.style.paddingTop = _this.wrapperTop+'px';
696
+ if (_this.wrapperBottom>0) wrapper.style.paddingBottom = _this.wrapperBottom+'px';
499
697
  }
500
- }
501
-
502
- if (!firstInit) _this.callPlugins('onFirstInit');
503
- else _this.callPlugins('onInit');
504
- firstInit = true;
505
- }
506
698
 
507
- _this.init()
699
+ wrapperSize = isH ? wrapperWidth + _this.wrapperRight + _this.wrapperLeft : wrapperHeight + _this.wrapperTop + _this.wrapperBottom;
700
+ wrapper.style.width = wrapperWidth+'px';
701
+ wrapper.style.height = wrapperHeight+'px';
702
+ var slideLeft = 0;
703
+ _this.snapGrid = [];
704
+ _this.slidesGrid = [];
705
+ for (var i=0; i<_this.slides.length; i++) {
706
+ _this.snapGrid.push(slideLeft);
707
+ _this.slidesGrid.push(slideLeft);
708
+ slideLeft+=slideSize;
709
+ _this.slides[i].style.width = slideWidth+'px';
710
+ _this.slides[i].style.height = slideHeight+'px';
711
+ }
508
712
 
509
-
510
-
511
- //Get Max And Min Positions
512
- function maxPos() {
513
- var a = (wrapperSize - containerSize);
514
- if (params.loop) a = a - containerSize;
515
- if (params.scrollContainer) {
516
- a = slideSize - containerSize;
517
- if (a<0) a = 0;
518
713
  }
519
- if (params.slidesPerSlide > _this.slides.length) a = 0;
520
- return a;
521
- }
522
- function minPos() {
523
- var a = 0;
524
- if (params.loop) a = containerSize;
525
- return a;
714
+
715
+ if (!_this.initialized) {
716
+ _this.callPlugins('onFirstInit');
717
+ if (params.onFirstInit) params.onFirstInit(_this);
718
+ }
719
+ else {
720
+ _this.callPlugins('onInit');
721
+ if (params.onInit) params.onInit(_this);
722
+ }
723
+ _this.initialized = true;
526
724
  }
527
-
528
- /*=========================
529
- Pagination
530
- ===========================*/
531
- _this.updatePagination = function() {
532
- if (_this.slides.length<2) return;
533
- var activeSwitch = dQ(params.pagination+' .'+params.paginationActiveClass)
534
- if(!activeSwitch) return
535
- for (var i=0; i < activeSwitch.length; i++) {
536
- activeSwitch.item(i).className = params.paginationClass
537
- }
538
- var pagers = dQ(params.pagination+' .'+params.paginationClass).length;
539
- var minPagerIndex = params.loop ? _this.realIndex-params.slidesPerSlide : _this.realIndex;
540
- var maxPagerIndex = minPagerIndex + (params.slidesPerSlide-1);
541
- for (var i = minPagerIndex; i <= maxPagerIndex; i++ ) {
542
- var j = i;
543
- if (j>=pagers) j=j-pagers;
544
- if (j<0) j = pagers + j;
545
- if (j<numOfSlides) {
546
- dQ(params.pagination+' .'+params.paginationClass).item( j ).className = params.paginationClass+' '+params.paginationActiveClass
547
- }
548
- if (i==minPagerIndex) dQ(params.pagination+' .'+params.paginationClass).item( j ).className+=' swiper-activeslide-switch'
549
- }
550
- }
551
- _this.createPagination = function () {
552
- if (params.pagination && params.createPagination) {
553
- var paginationHTML = "";
554
- var numOfSlides = _this.slides.length;
555
- var numOfButtons = params.loop ? numOfSlides - params.slidesPerSlide*2 : numOfSlides;
556
- for (var i = 0; i < numOfButtons; i++) {
557
- paginationHTML += '<span class="'+params.paginationClass+'"></span>'
558
- }
559
- dQ(params.pagination)[0].innerHTML = paginationHTML
560
- _this.updatePagination()
561
-
562
- _this.callPlugins('onCreatePagination');
563
- }
725
+ _this.reInit = function (forceCalcSlides) {
726
+ _this.init(true, forceCalcSlides);
564
727
  }
565
- _this.createPagination();
566
-
567
-
568
- //Window Resize Re-init
569
- _this.resizeEvent = params.resizeEvent==='auto'
570
- ? ('onorientationchange' in window) ? 'orientationchange' : 'resize'
571
- : params.resizeEvent
572
-
573
- _this.resizeFix = function(){
728
+ _this.resizeFix = function(reInit){
574
729
  _this.callPlugins('beforeResizeFix');
575
- _this.init()
576
- //To fix translate value
577
- if (!params.scrollContainer)
578
- _this.swipeTo(_this.activeIndex, 0, false)
730
+ _this.init(params.resizeReInit||reInit);
731
+ if (!params.freeMode) {
732
+ if (params.loop) _this.swipeTo(_this.activeLoopIndex, 0, false);
733
+ else _this.swipeTo(_this.activeIndex, 0, false);
734
+ }
579
735
  else {
580
- var pos = isHorizontal ? _this.getTranslate('x') : _this.getTranslate('y')
581
- if (pos < -maxPos()) {
582
- var x = isHorizontal ? -maxPos() : 0;
583
- var y = isHorizontal ? 0 : -maxPos();
584
- _this.setTransition(0)
585
- _this.setTransform(x,y,0)
736
+ var pos = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
737
+ if (pos < -maxWrapperPosition()) {
738
+ var x = isH ? -maxWrapperPosition() : 0;
739
+ var y = isH ? 0 : -maxWrapperPosition();
740
+ _this.setWrapperTransition(0);
741
+ _this.setWrapperTranslate(x,y,0);
586
742
  }
587
743
  }
588
744
  _this.callPlugins('afterResizeFix');
589
745
  }
590
- if (!params.disableAutoResize) {
591
- //Check for resize event
592
- window.addEventListener(_this.resizeEvent, _this.resizeFix, false)
593
- }
594
746
 
595
- /*==========================================
596
- Autoplay
747
+ /*==========================================
748
+ Max and Min Positions
597
749
  ============================================*/
598
-
599
- var autoPlay
600
- _this.startAutoPlay = function() {
601
- if (params.autoPlay && !params.loop) {
602
- autoPlay = setInterval(function(){
603
- var newSlide = _this.realIndex + 1
604
- if ( newSlide == numOfSlides) newSlide = 0
605
- _this.swipeTo(newSlide)
606
- }, params.autoPlay)
607
- }
608
- else if (params.autoPlay && params.loop) {
609
- autoPlay = setInterval(function(){
610
- _this.fixLoop();
611
- _this.swipeNext(true)
612
- }, params.autoPlay)
750
+ function maxWrapperPosition() {
751
+ var a = (wrapperSize - containerSize);
752
+ if (params.freeMode) {
753
+ a = wrapperSize - containerSize;
613
754
  }
614
- _this.callPlugins('onAutoPlayStart');
615
- }
616
- _this.stopAutoPlay = function() {
617
- if (autoPlay)
618
- clearInterval(autoPlay)
619
- _this.callPlugins('onAutoPlayStop');
755
+ // if (params.loop) a -= containerSize;
756
+ if (params.slidesPerView > _this.slides.length) a = 0;
757
+ if (a<0) a = 0;
758
+ return a;
620
759
  }
621
- if (params.autoPlay) {
622
- _this.startAutoPlay()
760
+ function minWrapperPosition() {
761
+ var a = 0;
762
+ // if (params.loop) a = containerSize;
763
+ return a;
623
764
  }
624
-
625
- /*==========================================
626
- Event Listeners
765
+
766
+ /*==========================================
767
+ Event Listeners
627
768
  ============================================*/
628
-
629
- if (!_this.ie10) {
630
- if (_this.support.touch) {
631
- wrapper.addEventListener('touchstart', onTouchStart, false);
632
- wrapper.addEventListener('touchmove', onTouchMove, false);
633
- wrapper.addEventListener('touchend', onTouchEnd, false);
769
+ function initEvents() {
770
+ //Touch Events
771
+ if (!_this.browser.ie10) {
772
+ if (_this.support.touch) {
773
+ _this.h.addEventListener(_this.wrapper, 'touchstart', onTouchStart, false);
774
+ _this.h.addEventListener(_this.wrapper, 'touchmove', onTouchMove, false);
775
+ _this.h.addEventListener(_this.wrapper, 'touchend', onTouchEnd, false);
776
+ }
777
+ if (params.simulateTouch) {
778
+ _this.h.addEventListener(_this.wrapper, 'mousedown', onTouchStart, false);
779
+ _this.h.addEventListener(document, 'mousemove', onTouchMove, false);
780
+ _this.h.addEventListener(document, 'mouseup', onTouchEnd, false);
781
+ }
634
782
  }
635
- if (params.simulateTouch) {
636
- wrapper.addEventListener('mousedown', onTouchStart, false);
637
- document.addEventListener('mousemove', onTouchMove, false);
638
- document.addEventListener('mouseup', onTouchEnd, false);
783
+ else {
784
+ _this.h.addEventListener(_this.wrapper, _this.touchEvents.touchStart, onTouchStart, false);
785
+ _this.h.addEventListener(document, _this.touchEvents.touchMove, onTouchMove, false);
786
+ _this.h.addEventListener(document, _this.touchEvents.touchEnd, onTouchEnd, false);
787
+ }
788
+ //Resize Event
789
+ if (params.autoResize) {
790
+ _this.h.addEventListener(window, 'resize', _this.resizeFix, false);
791
+ }
792
+ //Slide Events
793
+ addSlideEvents();
794
+ //Mousewheel
795
+ _this._wheelEvent = false;
796
+ if (params.mousewheelControl) {
797
+ if ( document.onmousewheel !== undefined ) {
798
+ _this._wheelEvent = "mousewheel";
799
+ }
800
+ try {
801
+ WheelEvent("wheel");
802
+ _this._wheelEvent = "wheel";
803
+ } catch (e) {}
804
+ if ( !_this._wheelEvent ) {
805
+ _this._wheelEvent = "DOMMouseScroll";
806
+ }
807
+
808
+ if (_this._wheelEvent) {
809
+ _this.h.addEventListener(_this.container, _this._wheelEvent, handleMousewheel, false);
810
+ }
639
811
  }
640
- }
641
- else {
642
- wrapper.addEventListener(_this.touchEvents.touchStart, onTouchStart, false);
643
- document.addEventListener(_this.touchEvents.touchMove, onTouchMove, false);
644
- document.addEventListener(_this.touchEvents.touchEnd, onTouchEnd, false);
645
- }
646
-
647
- //Remove Events
648
- _this.destroy = function(removeResizeFix){
649
- removeResizeFix = removeResizeFix===false ? removeResizeFix : removeResizeFix || true
650
- if (removeResizeFix) {
651
- window.removeEventListener(_this.resizeEvent, _this.resizeFix, false);
812
+
813
+ //Keyboard
814
+ if (params.keyboardControl) {
815
+ _this.h.addEventListener(document, 'keydown', handleKeyboardKeys, false);
652
816
  }
817
+ if (params.updateOnImagesReady) {
818
+ if (document.querySelectorAll) _this.imagesToLoad = _this.container.querySelectorAll('img');
819
+ else if (window.jQuery) _this.imagesToLoad = $$(_this.container).find('img');
653
820
 
654
- if (_this.ie10) {
655
- wrapper.removeEventListener(_this.touchEvents.touchStart, onTouchStart, false);
656
- document.removeEventListener(_this.touchEvents.touchMove, onTouchMove, false);
657
- document.removeEventListener(_this.touchEvents.touchEnd, onTouchEnd, false);
821
+ for (var i=0; i<_this.imagesToLoad.length; i++) {
822
+ _loadImage(_this.imagesToLoad[i].getAttribute('src'))
823
+ }
658
824
  }
659
- else {
825
+ function _loadImage(src) {
826
+ var image = new Image();
827
+ image.onload = function(){
828
+ _this.imagesLoaded++;
829
+ if (_this.imagesLoaded==_this.imagesToLoad.length) {
830
+ _this.reInit();
831
+ if (params.onImagesReady) params.onImagesReady(_this);
832
+ }
833
+ }
834
+ image.src = src;
835
+ }
836
+ }
837
+
838
+
839
+
840
+ //Remove Event Listeners
841
+ _this.destroy = function(removeResizeFix){
842
+ //Touch Events
843
+ if (!_this.browser.ie10) {
660
844
  if (_this.support.touch) {
661
- wrapper.removeEventListener('touchstart', onTouchStart, false);
662
- wrapper.removeEventListener('touchmove', onTouchMove, false);
663
- wrapper.removeEventListener('touchend', onTouchEnd, false);
845
+ _this.h.removeEventListener(_this.wrapper, 'touchstart', onTouchStart, false);
846
+ _this.h.removeEventListener(_this.wrapper, 'touchmove', onTouchMove, false);
847
+ _this.h.removeEventListener(_this.wrapper, 'touchend', onTouchEnd, false);
848
+ }
849
+ if (params.simulateTouch) {
850
+ _this.h.removeEventListener(_this.wrapper, 'mousedown', onTouchStart, false);
851
+ _this.h.removeEventListener(document, 'mousemove', onTouchMove, false);
852
+ _this.h.removeEventListener(document, 'mouseup', onTouchEnd, false);
664
853
  }
665
- wrapper.removeEventListener('mousedown', onTouchStart, false);
666
- document.removeEventListener('mousemove', onTouchMove, false);
667
- document.removeEventListener('mouseup', onTouchEnd, false);
668
854
  }
855
+ else {
856
+ _this.h.removeEventListener(_this.wrapper, _this.touchEvents.touchStart, onTouchStart, false);
857
+ _this.h.removeEventListener(document, _this.touchEvents.touchMove, onTouchMove, false);
858
+ _this.h.removeEventListener(document, _this.touchEvents.touchEnd, onTouchEnd, false);
859
+ }
860
+ //Resize Event
861
+ if (params.autoResize) {
862
+ _this.h.removeEventListener(window, 'resize', _this.resizeFix, false);
863
+ }
864
+ //Init Slide Events
865
+ removeSlideEvents();
669
866
 
670
- if (params.keyboardControl) {
671
- document.removeEventListener('keydown', handleKeyboardKeys, false);
867
+ //Pagination
868
+ if (params.paginationClickable) {
869
+ removePaginationEvents();
672
870
  }
871
+
872
+ //Mousewheel
673
873
  if (params.mousewheelControl && _this._wheelEvent) {
674
- _this.container.removeEventListener(_this._wheelEvent, handleMousewheel, false);
874
+ _this.h.removeEventListener(_this.container, _this._wheelEvent, handleMousewheel, false);
875
+ }
876
+
877
+ //Keyboard
878
+ if (params.keyboardControl) {
879
+ _this.h.removeEventListener(document, 'keydown', handleKeyboardKeys, false);
675
880
  }
676
- if (params.autoPlay) {
677
- _this.stopAutoPlay()
881
+
882
+ //Stop autoplay
883
+ if (params.autoplay) {
884
+ _this.stopAutoplay();
678
885
  }
679
886
  _this.callPlugins('onDestroy');
680
- }
681
- /*=========================
682
- Prevent Links
683
- ===========================*/
684
887
 
685
- _this.allowLinks = true;
686
- if (params.preventLinks) {
687
- var links = _this.container.querySelectorAll('a')
688
- for (var i=0; i<links.length; i++) {
689
- links[i].addEventListener('click', preventClick, false)
690
- }
691
- }
692
- function preventClick(e) {
693
- if (!_this.allowLinks) e.preventDefault();
888
+ //Destroy variable
889
+ _this = null;
694
890
  }
891
+ function addSlideEvents() {
892
+ //Prevent Links Events
893
+ if (params.preventLinks) {
894
+ var links = [];
895
+ if (document.querySelectorAll) {
896
+ links = _this.container.querySelectorAll('a');
897
+ }
898
+ else if (window.jQuery) {
899
+ links = $$(_this.container).find('a');
900
+ }
901
+ for (var i=0; i<links.length; i++) {
902
+ _this.h.addEventListener(links[i], 'click', preventClick, false);
903
+ }
904
+ }
905
+ //Release Form Elements
906
+ if (params.releaseFormElements) {
907
+ var formElements = document.querySelectorAll ? _this.container.querySelectorAll('input, textarea, select') : $$(_this.container).find('input, textarea, select');
908
+ for (var i=0; i<formElements.length; i++) {
909
+ _this.h.addEventListener(formElements[i], _this.touchEvents.touchStart, releaseForms, true);
910
+ }
911
+ }
695
912
 
696
- /*==========================================
697
- Keyboard Control
698
- ============================================*/
699
- if (params.keyboardControl) {
700
- function handleKeyboardKeys (e) {
701
- var kc = e.keyCode || e.charCode;
702
- if (isHorizontal) {
703
- if (kc==37 || kc==39) e.preventDefault();
704
- if (kc == 39) _this.swipeNext()
705
- if (kc == 37) _this.swipePrev()
913
+ //Slide Clicks & Touches
914
+ if (params.onSlideClick) {
915
+ for (var i=0; i<_this.slides.length; i++) {
916
+ _this.h.addEventListener(_this.slides[i], 'click', slideClick, false);
706
917
  }
707
- else {
708
- if (kc==38 || kc==40) e.preventDefault();
709
- if (kc == 40) _this.swipeNext()
710
- if (kc == 38) _this.swipePrev()
918
+ }
919
+ if (params.onSlideTouch) {
920
+ for (var i=0; i<_this.slides.length; i++) {
921
+ _this.h.addEventListener(_this.slides[i], _this.touchEvents.touchStart, slideTouch, false);
711
922
  }
712
923
  }
713
- document.addEventListener('keydown',handleKeyboardKeys, false);
714
924
  }
715
-
716
- /*==========================================
717
- Mousewheel Control. Beta!
718
- ============================================*/
719
- // detect available wheel event
720
- _this._wheelEvent = false;
721
-
722
- if (params.mousewheelControl) {
723
- if ( document.onmousewheel !== undefined ) {
724
- _this._wheelEvent = "mousewheel"
925
+ function removeSlideEvents() {
926
+ //Slide Clicks & Touches
927
+ if (params.onSlideClick) {
928
+ for (var i=0; i<_this.slides.length; i++) {
929
+ _this.h.removeEventListener(_this.slides[i], 'click', slideClick, false);
930
+ }
725
931
  }
726
- try {
727
- WheelEvent("wheel");
728
- _this._wheelEvent = "wheel";
729
- } catch (e) {}
730
- if ( !_this._wheelEvent ) {
731
- _this._wheelEvent = "DOMMouseScroll";
932
+ if (params.onSlideTouch) {
933
+ for (var i=0; i<_this.slides.length; i++) {
934
+ _this.h.removeEventListener(_this.slides[i], _this.touchEvents.touchStart, slideTouch, false);
732
935
  }
733
- function handleMousewheel (e) {
734
- if(e.preventDefault) e.preventDefault();
735
- var we = _this._wheelEvent;
736
- var delta;
737
- //Opera & IE
738
- if (e.detail) delta = -e.detail;
739
- //WebKits
740
- else if (we == 'mousewheel') delta = e.wheelDelta;
741
- //Old FireFox
742
- else if (we == 'DOMMouseScroll') delta = -e.detail;
743
- //New FireFox
744
- else if (we == 'wheel') {
745
- delta = Math.abs(e.deltaX)>Math.abs(e.deltaY) ? - e.deltaX : - e.deltaY;
746
- }
747
- if (!params.freeMode) {
748
- if(delta<0) _this.swipeNext()
749
- else _this.swipePrev()
936
+ }
937
+ //Release Form Elements
938
+ if (params.releaseFormElements) {
939
+ var formElements = document.querySelectorAll ? _this.container.querySelectorAll('input, textarea, select') : $$(_this.container).find('input, textarea, select');
940
+ for (var i=0; i<formElements.length; i++) {
941
+ _this.h.removeEventListener(formElements[i], _this.touchEvents.touchStart, releaseForms, true);
750
942
  }
751
- else {
752
- //Freemode or scrollContainer:
753
- var currentTransform =isHorizontal ? _this.getTranslate('x') : _this.getTranslate('y')
754
- var x,y;
755
- if (isHorizontal) {
756
- x = _this.getTranslate('x') + delta;
757
- y = _this.getTranslate('y');
758
- if (x>0) x = 0;
759
- if (x<-maxPos()) x = -maxPos();
760
- }
761
- else {
762
- x = _this.getTranslate('x');
763
- y = _this.getTranslate('y')+delta;
764
- if (y>0) y = 0;
765
- if (y<-maxPos()) y = -maxPos();
943
+ }
944
+ //Prevent Links Events
945
+ if (params.preventLinks) {
946
+ var links = [];
947
+ if (document.querySelectorAll) {
948
+ links = _this.container.querySelectorAll('a');
949
+ }
950
+ else if (window.jQuery) {
951
+ links = $$(_this.container).find('a');
952
+ }
953
+ for (var i=0; i<links.length; i++) {
954
+ _this.h.removeEventListener(links[i], 'click', preventClick, false);
955
+ }
956
+ }
957
+ }
958
+ /*==========================================
959
+ Keyboard Control
960
+ ============================================*/
961
+ function handleKeyboardKeys (e) {
962
+ var kc = e.keyCode || e.charCode;
963
+ if (kc==37 || kc==39 || kc==38 || kc==40) {
964
+ var inView = false;
965
+ //Check that swiper should be inside of visible area of window
966
+ var swiperOffset = _this.h.getOffset( _this.container );
967
+ var scrollLeft = _this.h.windowScroll().left;
968
+ var scrollTop = _this.h.windowScroll().top;
969
+ var windowWidth = _this.h.windowWidth();
970
+ var windowHeight = _this.h.windowHeight();
971
+ var swiperCoord = [
972
+ [swiperOffset.left, swiperOffset.top],
973
+ [swiperOffset.left + _this.width, swiperOffset.top],
974
+ [swiperOffset.left, swiperOffset.top + _this.height],
975
+ [swiperOffset.left + _this.width, swiperOffset.top + _this.height]
976
+ ]
977
+ for (var i=0; i<swiperCoord.length; i++) {
978
+ var point = swiperCoord[i];
979
+ if (
980
+ point[0]>=scrollLeft && point[0]<=scrollLeft+windowWidth &&
981
+ point[1]>=scrollTop && point[1]<=scrollTop+windowHeight
982
+ ) {
983
+ inView = true;
766
984
  }
767
- _this.setTransition(0)
768
- _this.setTransform(x,y,0)
985
+
986
+ }
987
+ if (!inView) return;
988
+ }
989
+ if (isH) {
990
+ if (kc==37 || kc==39) {
991
+ if (e.preventDefault) e.preventDefault();
992
+ else e.returnValue = false;
993
+ }
994
+ if (kc == 39) _this.swipeNext();
995
+ if (kc == 37) _this.swipePrev();
996
+ }
997
+ else {
998
+ if (kc==38 || kc==40) {
999
+ if (e.preventDefault) e.preventDefault();
1000
+ else e.returnValue = false;
769
1001
  }
1002
+ if (kc == 40) _this.swipeNext();
1003
+ if (kc == 38) _this.swipePrev();
1004
+ }
1005
+ }
770
1006
 
771
- if(event.preventDefault) event.preventDefault();
772
- else event.returnValue = false;
773
- return false;
1007
+ /*==========================================
1008
+ Mousewheel Control
1009
+ ============================================*/
1010
+ var allowScrollChange = true;
1011
+ function handleMousewheel (e) {
1012
+ var we = _this._wheelEvent;
1013
+ var delta;
1014
+ //Opera & IE
1015
+ if (e.detail) delta = -e.detail;
1016
+ //WebKits
1017
+ else if (we == 'mousewheel') delta = e.wheelDelta;
1018
+ //Old FireFox
1019
+ else if (we == 'DOMMouseScroll') delta = -e.detail;
1020
+ //New FireFox
1021
+ else if (we == 'wheel') {
1022
+ delta = Math.abs(e.deltaX)>Math.abs(e.deltaY) ? - e.deltaX : - e.deltaY;
1023
+ }
1024
+ if (!params.freeMode) {
1025
+ if(delta<0) _this.swipeNext();
1026
+ else _this.swipePrev();
774
1027
  }
775
- if (_this._wheelEvent) {
776
- _this.container.addEventListener(_this._wheelEvent, handleMousewheel, false);
1028
+ else {
1029
+ //Freemode or scrollContainer:
1030
+ var currentTransform =isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
1031
+ var x,y;
1032
+ if (isH) {
1033
+ x = _this.getWrapperTranslate('x') + delta;
1034
+ y = _this.getWrapperTranslate('y');
1035
+ if (x>0) x = 0;
1036
+ if (x<-maxWrapperPosition()) x = -maxWrapperPosition();
1037
+ }
1038
+ else {
1039
+ x = _this.getWrapperTranslate('x');
1040
+ y = _this.getWrapperTranslate('y')+delta;
1041
+ if (y>0) y = 0;
1042
+ if (y<-maxWrapperPosition()) y = -maxWrapperPosition();
1043
+ }
1044
+ _this.setWrapperTransition(0);
1045
+ _this.setWrapperTranslate(x,y,0);
1046
+ if (isH) _this.updateActiveSlide(x);
1047
+ else _this.updateActiveSlide(y);
777
1048
  }
1049
+ if (params.autoplay) _this.stopAutoplay();
1050
+
1051
+ if(e.preventDefault) e.preventDefault();
1052
+ else e.returnValue = false;
1053
+ return false;
778
1054
  }
1055
+
779
1056
  /*=========================
780
1057
  Grab Cursor
781
1058
  ===========================*/
@@ -784,220 +1061,237 @@ var Swiper = function (selector, params, callback) {
784
1061
  _this.container.style.cursor = 'grab';
785
1062
  _this.container.style.cursor = '-moz-grab';
786
1063
  _this.container.style.cursor = '-webkit-grab';
787
- }
1064
+ }
1065
+
788
1066
  /*=========================
789
- Handle Touches
1067
+ Slides Events Handlers
790
1068
  ===========================*/
791
- //Detect event type for devices with both touch and mouse support
792
- var isTouchEvent = false;
793
- var allowThresholdMove;
1069
+ function findSlide(el) {
1070
+ var found = false;
1071
+ while(!found) {
1072
+ if (el.className.indexOf(params.slideClass)>-1)
1073
+ {
1074
+ found = el;
1075
+ }
1076
+ el = el.parentElement;
1077
+ }
1078
+ return found;
1079
+ }
1080
+ _this.allowSlideClick = true;
1081
+ function slideClick(e) {
1082
+ if(_this.allowSlideClick) {
1083
+ if (!e.target) {
1084
+ _this.clickedSlide = findSlide(e.srcElement);
1085
+ _this.clickedSlideIndex = _this.slides.indexOf(_this.clickedSlide);
1086
+ }
1087
+ else {
1088
+ _this.clickedSlide = this;
1089
+ _this.clickedSlideIndex = _this.slides.indexOf(this);
1090
+ }
1091
+ params.onSlideClick(_this);
1092
+ }
1093
+ }
1094
+ function slideTouch(e) {
1095
+ if (!e.target) _this.clickedSlide = findSlide(e.srcElement);
1096
+ else _this.clickedSlide = this;
1097
+ _this.clickedSlideIndex = _this.slides.indexOf(_this.clickedSlide);
1098
+ params.onSlideTouch(_this);
1099
+ }
1100
+ _this.allowLinks = true;
1101
+ function preventClick(e) {
1102
+ if (!_this.allowLinks) {
1103
+ if(e.preventDefault) e.preventDefault();
1104
+ else e.returnValue = false;
1105
+ return false;
1106
+ }
1107
+ }
1108
+ function releaseForms(e) {
1109
+ if (e.stopPropagation) e.stopPropagation();
1110
+ else e.returnValue = false;
1111
+ return false;
1112
+ }
1113
+
1114
+ /*==================================================
1115
+ Event Handlers
1116
+ ====================================================*/
1117
+ var isTouchEvent = false;
1118
+ var allowThresholdMove;
1119
+ var allowMomentumBounce = true;
794
1120
  function onTouchStart(event) {
1121
+ if (params.preventLinks) _this.allowLinks = true;
795
1122
  //Exit if slider is already was touched
796
1123
  if (_this.isTouched || params.onlyExternal) {
797
- return false
1124
+ return false;
798
1125
  }
799
- if (params.preventClassNoSwiping && event.target && event.target.className.indexOf('NoSwiping') > -1) return false;
800
-
1126
+
1127
+ if (params.noSwiping && (event.target || event.srcElement) && noSwipingSlide(event.target || event.srcElement)) return false;
1128
+ allowMomentumBounce = false;
1129
+
801
1130
  //Check For Nested Swipers
802
1131
  _this.isTouched = true;
803
1132
  isTouchEvent = event.type=='touchstart';
1133
+
804
1134
  if (!isTouchEvent || event.targetTouches.length == 1 ) {
805
- _this.callPlugins('onTouchStartBegin');
806
-
807
1135
  if (params.loop) _this.fixLoop();
1136
+ _this.callPlugins('onTouchStartBegin');
1137
+
808
1138
  if(!isTouchEvent) {
809
1139
  if(event.preventDefault) event.preventDefault();
810
1140
  else event.returnValue = false;
811
1141
  }
812
- var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX)
813
- var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY)
814
-
1142
+
1143
+ var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX);
1144
+ var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY);
1145
+
815
1146
  //Start Touches to check the scrolling
816
1147
  _this.touches.startX = _this.touches.currentX = pageX;
817
1148
  _this.touches.startY = _this.touches.currentY = pageY;
818
-
819
- _this.touches.start = _this.touches.current = isHorizontal ? _this.touches.startX : _this.touches.startY ;
820
-
1149
+
1150
+ _this.touches.start = _this.touches.current = isH ? pageX : pageY ;
1151
+
821
1152
  //Set Transition Time to 0
822
- _this.setTransition(0)
823
-
1153
+ _this.setWrapperTransition(0);
1154
+
824
1155
  //Get Start Translate Position
825
- _this.positions.start = _this.positions.current = isHorizontal ? _this.getTranslate('x') : _this.getTranslate('y');
1156
+ _this.positions.start = _this.positions.current = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
826
1157
 
827
1158
  //Set Transform
828
- if (isHorizontal) {
829
- _this.setTransform( _this.positions.start, 0, 0)
1159
+ if (isH) {
1160
+ _this.setWrapperTranslate( _this.positions.start, 0, 0);
830
1161
  }
831
1162
  else {
832
- _this.setTransform( 0, _this.positions.start, 0)
1163
+ _this.setWrapperTranslate( 0, _this.positions.start, 0);
833
1164
  }
834
-
1165
+
835
1166
  //TouchStartTime
836
- var tst = new Date()
837
- _this.times.start = tst.getTime()
838
-
1167
+ _this.times.start = (new Date()).getTime();
1168
+
839
1169
  //Unset Scrolling
840
1170
  isScrolling = undefined;
841
-
842
- //Define Clicked Slide without additional event listeners
843
- if (params.onSlideClick || params.onSlideTouch) {
844
- ;(function () {
845
- var el = _this.container;
846
- var box = el.getBoundingClientRect();
847
- var body = document.body;
848
- var clientTop = el.clientTop || body.clientTop || 0;
849
- var clientLeft = el.clientLeft || body.clientLeft || 0;
850
- var scrollTop = window.pageYOffset || el.scrollTop;
851
- var scrollLeft = window.pageXOffset || el.scrollLeft;
852
- var x = pageX - box.left + clientLeft - scrollLeft;
853
- var y = pageY - box.top - clientTop - scrollTop;
854
- var touchOffset = isHorizontal ? x : y;
855
- var beforeSlides = -Math.round(_this.positions.current/slideSize)
856
- var realClickedIndex = Math.floor(touchOffset/slideSize) + beforeSlides
857
- var clickedIndex = realClickedIndex;
858
- if (params.loop) {
859
- var clickedIndex = realClickedIndex - params.slidesPerSlide;
860
- if (clickedIndex<0) {
861
- clickedIndex = _this.slides.length+clickedIndex-(params.slidesPerSlide*2);
862
- }
863
1171
 
864
- }
865
- _this.clickedSlideIndex = clickedIndex
866
- _this.clickedSlide = _this.getSlide(realClickedIndex);
867
- if (params.onSlideTouch) {
868
- params.onSlideTouch(_this);
869
- _this.callPlugins('onSlideTouch');
870
- }
871
- })();
872
- }
873
1172
  //Set Treshold
874
1173
  if (params.moveStartThreshold>0) allowThresholdMove = false;
1174
+
875
1175
  //CallBack
876
- if (params.onTouchStart) params.onTouchStart(_this)
1176
+ if (params.onTouchStart) params.onTouchStart(_this);
877
1177
  _this.callPlugins('onTouchStartEnd');
878
-
1178
+
879
1179
  }
880
1180
  }
1181
+ var velocityPrevPosition, velocityPrevTime;
881
1182
  function onTouchMove(event) {
882
1183
  // If slider is not touched - exit
883
1184
  if (!_this.isTouched || params.onlyExternal) return;
884
1185
  if (isTouchEvent && event.type=='mousemove') return;
885
- var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX)
886
- var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY)
1186
+
1187
+ var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX);
1188
+ var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY);
1189
+
887
1190
  //check for scrolling
888
- if ( typeof isScrolling === 'undefined' && isHorizontal) {
889
- isScrolling = !!( isScrolling || Math.abs(pageY - _this.touches.startY) > Math.abs( pageX - _this.touches.startX ) )
1191
+ if ( typeof isScrolling === 'undefined' && isH) {
1192
+ isScrolling = !!( isScrolling || Math.abs(pageY - _this.touches.startY) > Math.abs( pageX - _this.touches.startX ) );
890
1193
  }
891
- if ( typeof isScrolling === 'undefined' && !isHorizontal) {
892
- isScrolling = !!( isScrolling || Math.abs(pageY - _this.touches.startY) < Math.abs( pageX - _this.touches.startX ) )
1194
+ if ( typeof isScrolling === 'undefined' && !isH) {
1195
+ isScrolling = !!( isScrolling || Math.abs(pageY - _this.touches.startY) < Math.abs( pageX - _this.touches.startX ) );
893
1196
  }
894
-
895
1197
  if (isScrolling ) {
896
1198
  _this.isTouched = false;
897
1199
  return
898
1200
  }
899
-
1201
+
900
1202
  //Check For Nested Swipers
901
1203
  if (event.assignedToSwiper) {
902
1204
  _this.isTouched = false;
903
1205
  return
904
1206
  }
905
- event.assignedToSwiper = true;
906
-
1207
+ event.assignedToSwiper = true;
1208
+
1209
+ //Moved Flag
1210
+ _this.isMoved = true;
1211
+
907
1212
  //Block inner links
908
1213
  if (params.preventLinks) {
909
- _this.allowLinks = false;
1214
+ _this.allowLinks = false;
910
1215
  }
911
-
1216
+ if (params.onSlideClick) {
1217
+ _this.allowSlideClick = false;
1218
+ }
1219
+
912
1220
  //Stop AutoPlay if exist
913
- if (params.autoPlay) {
914
- _this.stopAutoPlay()
1221
+ if (params.autoplay) {
1222
+ _this.stopAutoplay();
915
1223
  }
916
1224
  if (!isTouchEvent || event.touches.length == 1) {
917
-
918
- _this.callPlugins('onTouchMoveStart');
919
1225
 
1226
+ _this.callPlugins('onTouchMoveStart');
920
1227
  if(event.preventDefault) event.preventDefault();
921
1228
  else event.returnValue = false;
922
-
923
- _this.touches.current = isHorizontal ? pageX : pageY ;
924
-
925
- _this.positions.current = (_this.touches.current - _this.touches.start)*params.ratio + _this.positions.start
926
-
927
- if (params.resistance) {
1229
+
1230
+ _this.touches.current = isH ? pageX : pageY ;
1231
+
1232
+ _this.positions.current = (_this.touches.current - _this.touches.start) * params.touchRatio + _this.positions.start;
1233
+
1234
+ //Resistance Callbacks
1235
+ if(_this.positions.current > 0 && params.onResistanceBefore) {
1236
+ params.onResistanceBefore(_this, _this.positions.current);
1237
+ }
1238
+ if(_this.positions.current < -maxWrapperPosition() && params.onResistanceAfter) {
1239
+ params.onResistanceAfter(_this, Math.abs(_this.positions.current + maxWrapperPosition()));
1240
+ }
1241
+ //Resistance
1242
+ if (params.resistance && params.resistance!='100%') {
928
1243
  //Resistance for Negative-Back sliding
929
- if(_this.positions.current > 0 && !(params.freeMode&&!params.freeModeFluid)) {
930
-
931
- if (params.loop) {
932
- var resistance = 1;
933
- if (_this.positions.current>0) _this.positions.current = 0;
934
- }
935
- else {
936
- var resistance = (containerSize*2-_this.positions.current)/containerSize/2;
937
- }
938
- if (resistance < 0.5)
939
- _this.positions.current = (containerSize/2)
940
- else
941
- _this.positions.current = _this.positions.current * resistance
942
-
943
- if (params.nopeek)
944
- _this.positions.current = 0;
945
-
1244
+ if(_this.positions.current > 0) {
1245
+ var resistance = 1 - _this.positions.current/containerSize/2;
1246
+ if (resistance < 0.5)
1247
+ _this.positions.current = (containerSize/2);
1248
+ else
1249
+ _this.positions.current = _this.positions.current * resistance;
946
1250
  }
947
1251
  //Resistance for After-End Sliding
948
- if ( (_this.positions.current) < -maxPos() && !(params.freeMode&&!params.freeModeFluid)) {
949
-
950
- if (params.loop) {
951
- var resistance = 1;
952
- var newPos = _this.positions.current
953
- var stopPos = -maxPos() - containerSize
954
- }
955
- else {
956
-
957
- var diff = (_this.touches.current - _this.touches.start)*params.ratio + (maxPos()+_this.positions.start)
958
- var resistance = (containerSize+diff)/(containerSize);
959
- var newPos = _this.positions.current-diff*(1-resistance)/2
960
- var stopPos = -maxPos() - containerSize/2;
961
- }
962
-
963
- if (params.nopeek) {
964
- newPos = _this.positions.current-diff;
965
- stopPos = -maxPos();
966
- }
967
-
1252
+ if ( _this.positions.current < -maxWrapperPosition() ) {
1253
+
1254
+ var diff = (_this.touches.current - _this.touches.start)*params.touchRatio + (maxWrapperPosition()+_this.positions.start);
1255
+ var resistance = (containerSize+diff)/(containerSize);
1256
+ var newPos = _this.positions.current-diff*(1-resistance)/2;
1257
+ var stopPos = -maxWrapperPosition() - containerSize/2;
1258
+
968
1259
  if (newPos < stopPos || resistance<=0)
969
1260
  _this.positions.current = stopPos;
970
- else
971
- _this.positions.current = newPos
1261
+ else
1262
+ _this.positions.current = newPos;
1263
+ }
1264
+ }
1265
+ if (params.resistance && params.resistance=='100%') {
1266
+ //Resistance for Negative-Back sliding
1267
+ if(_this.positions.current > 0 && !(params.freeMode&&!params.freeModeFluid)) {
1268
+ _this.positions.current = 0;
1269
+ }
1270
+ //Resistance for After-End Sliding
1271
+ if ( (_this.positions.current) < -maxWrapperPosition() && !(params.freeMode&&!params.freeModeFluid)) {
1272
+ _this.positions.current = -maxWrapperPosition();
972
1273
  }
973
1274
  }
974
-
975
1275
  //Move Slides
976
1276
  if (!params.followFinger) return
977
1277
 
978
1278
  if (!params.moveStartThreshold) {
979
- if (isHorizontal) _this.setTransform( _this.positions.current, 0, 0)
980
- else _this.setTransform( 0, _this.positions.current, 0)
1279
+ if (isH) _this.setWrapperTranslate( _this.positions.current, 0, 0);
1280
+ else _this.setWrapperTranslate( 0, _this.positions.current, 0);
981
1281
  }
982
1282
  else {
983
1283
  if ( Math.abs(_this.touches.current - _this.touches.start)>params.moveStartThreshold || allowThresholdMove) {
984
1284
  allowThresholdMove = true;
985
- if (isHorizontal) _this.setTransform( _this.positions.current, 0, 0)
986
- else _this.setTransform( 0, _this.positions.current, 0)
1285
+ if (isH) _this.setWrapperTranslate( _this.positions.current, 0, 0);
1286
+ else _this.setWrapperTranslate( 0, _this.positions.current, 0);
987
1287
  }
988
1288
  else {
989
- _this.positions.current = _this.positions.start
1289
+ _this.positions.current = _this.positions.start;
990
1290
  }
991
- }
992
-
993
-
994
- if (params.freeMode) {
995
- _this.updateActiveSlide(_this.positions.current)
996
1291
  }
997
1292
 
998
- //Prevent onSlideClick Fallback if slide is moved
999
- if (params.onSlideClick && _this.clickedSlide) {
1000
- _this.clickedSlide = false
1293
+ if (params.freeMode || params.watchActiveIndex) {
1294
+ _this.updateActiveSlide(_this.positions.current);
1001
1295
  }
1002
1296
 
1003
1297
  //Grab Cursor
@@ -1006,20 +1300,28 @@ var Swiper = function (selector, params, callback) {
1006
1300
  _this.container.style.cursor = 'grabbing';
1007
1301
  _this.container.style.cursor = '-moz-grabbin';
1008
1302
  _this.container.style.cursor = '-webkit-grabbing';
1009
- }
1010
-
1303
+ }
1304
+ //Velocity
1305
+ if (!velocityPrevPosition) velocityPrevPosition = _this.touches.current;
1306
+ if (!velocityPrevTime) velocityPrevTime = (new Date).getTime();
1307
+ _this.velocity = (_this.touches.current - velocityPrevPosition)/((new Date).getTime() - velocityPrevTime)/2;
1308
+ if (Math.abs(_this.touches.current - velocityPrevPosition)<2) _this.velocity=0;
1309
+ velocityPrevPosition = _this.touches.current;
1310
+ velocityPrevTime = (new Date).getTime();
1011
1311
  //Callbacks
1012
1312
  _this.callPlugins('onTouchMoveEnd');
1013
- if (params.onTouchMove) params.onTouchMove(_this)
1313
+ if (params.onTouchMove) params.onTouchMove(_this);
1014
1314
 
1015
- return false
1315
+ return false;
1016
1316
  }
1017
1317
  }
1018
1318
  function onTouchEnd(event) {
1019
1319
  //Check For scrolling
1020
- if (isScrolling) _this.swipeReset();
1320
+ if (isScrolling) {
1321
+ _this.swipeReset();
1322
+ }
1021
1323
  // If slider is not touched exit
1022
- if ( params.onlyExternal || !_this.isTouched ) return
1324
+ if ( params.onlyExternal || !_this.isTouched ) return;
1023
1325
  _this.isTouched = false
1024
1326
 
1025
1327
  //Return Grab Cursor
@@ -1028,114 +1330,179 @@ var Swiper = function (selector, params, callback) {
1028
1330
  _this.container.style.cursor = 'grab';
1029
1331
  _this.container.style.cursor = '-moz-grab';
1030
1332
  _this.container.style.cursor = '-webkit-grab';
1031
- }
1032
-
1033
- //onSlideClick
1034
- if (params.onSlideClick && _this.clickedSlide) {
1035
- params.onSlideClick(_this);
1036
- _this.callPlugins('onSlideClick')
1037
1333
  }
1038
1334
 
1039
1335
  //Check for Current Position
1040
1336
  if (!_this.positions.current && _this.positions.current!==0) {
1041
- _this.positions.current = _this.positions.start
1337
+ _this.positions.current = _this.positions.start
1042
1338
  }
1043
-
1339
+
1044
1340
  //For case if slider touched but not moved
1045
1341
  if (params.followFinger) {
1046
- if (isHorizontal) _this.setTransform( _this.positions.current, 0, 0)
1047
- else _this.setTransform( 0, _this.positions.current, 0)
1342
+ if (isH) _this.setWrapperTranslate( _this.positions.current, 0, 0)
1343
+ else _this.setWrapperTranslate( 0, _this.positions.current, 0)
1048
1344
  }
1049
1345
  //--
1050
-
1346
+
1051
1347
  // TouchEndTime
1052
- var tet = new Date()
1053
- _this.times.end = tet.getTime();
1054
-
1348
+ _this.times.end = (new Date()).getTime();
1349
+
1055
1350
  //Difference
1056
- _this.touches.diff = _this.touches.current - _this.touches.start
1351
+ _this.touches.diff = _this.touches.current - _this.touches.start
1057
1352
  _this.touches.abs = Math.abs(_this.touches.diff)
1058
-
1353
+
1059
1354
  _this.positions.diff = _this.positions.current - _this.positions.start
1060
1355
  _this.positions.abs = Math.abs(_this.positions.diff)
1061
-
1356
+
1062
1357
  var diff = _this.positions.diff ;
1063
1358
  var diffAbs =_this.positions.abs ;
1359
+ var timeDiff = _this.times.end - _this.times.start
1064
1360
 
1065
- if(diffAbs < 5 && (_this.times.end - _this.times.start) < 300 && _this.allowLinks == false) {
1066
- _this.swipeReset()
1361
+ if(diffAbs < 5 && (timeDiff) < 300 && _this.allowLinks == false) {
1362
+ if (!params.freeMode && diffAbs!=0) _this.swipeReset()
1067
1363
  //Release inner links
1068
1364
  if (params.preventLinks) {
1069
1365
  _this.allowLinks = true;
1070
1366
  }
1367
+ if (params.onSlideClick) {
1368
+ _this.allowSlideClick = true;
1369
+ }
1071
1370
  }
1072
-
1073
- var maxPosition = wrapperSize - containerSize;
1074
- if (params.scrollContainer) {
1075
- maxPosition = slideSize - containerSize
1371
+ setTimeout(function(){
1372
+ //Release inner links
1373
+ if (params.preventLinks) {
1374
+ _this.allowLinks = true;
1375
+ }
1376
+ if (params.onSlideClick) {
1377
+ _this.allowSlideClick = true;
1378
+ }
1379
+ },100)
1380
+
1381
+ //Exit if not moved
1382
+ if (!_this.isMoved) {
1383
+ _this.isMoved = false;
1384
+ if (params.onTouchEnd) params.onTouchEnd(_this)
1385
+ _this.callPlugins('onTouchEnd');
1386
+ _this.swipeReset();
1387
+ return;
1076
1388
  }
1077
-
1389
+ _this.isMoved = false;
1390
+
1391
+ var maxPosition = maxWrapperPosition();
1392
+
1078
1393
  //Prevent Negative Back Sliding
1079
1394
  if (_this.positions.current > 0) {
1080
1395
  _this.swipeReset()
1081
1396
  if (params.onTouchEnd) params.onTouchEnd(_this)
1082
1397
  _this.callPlugins('onTouchEnd');
1083
- return
1398
+ return;
1084
1399
  }
1085
1400
  //Prevent After-End Sliding
1086
1401
  if (_this.positions.current < -maxPosition) {
1087
1402
  _this.swipeReset()
1088
1403
  if (params.onTouchEnd) params.onTouchEnd(_this)
1089
1404
  _this.callPlugins('onTouchEnd');
1090
- return
1405
+ return;
1091
1406
  }
1092
-
1407
+
1093
1408
  //Free Mode
1094
1409
  if (params.freeMode) {
1095
- if ( (_this.times.end - _this.times.start) < 300 && params.freeModeFluid ) {
1096
- var newPosition = _this.positions.current + _this.touches.diff * 2 ;
1097
- if (newPosition < maxPosition*(-1)) newPosition = -maxPosition;
1098
- if (newPosition > 0) newPosition = 0;
1099
- if (isHorizontal)
1100
- _this.setTransform( newPosition, 0, 0)
1101
- else
1102
- _this.setTransform( 0, newPosition, 0)
1103
-
1104
- _this.setTransition( (_this.times.end - _this.times.start)*2 )
1410
+ if ( params.freeModeFluid ) {
1411
+ var momentumDuration = 1000*params.momentumRatio;
1412
+ var momentumDistance = _this.velocity*momentumDuration;
1413
+ var newPosition = _this.positions.current + momentumDistance
1414
+ var doBounce = false;
1415
+ var afterBouncePosition;
1416
+ var bounceAmount = Math.abs( _this.velocity )*20*params.momentumBounceRatio;
1417
+ if (newPosition < -maxPosition) {
1418
+ if (params.momentumBounce && _this.support.transitions) {
1419
+ if (newPosition + maxPosition < -bounceAmount) newPosition = -maxPosition-bounceAmount;
1420
+ afterBouncePosition = -maxPosition;
1421
+ doBounce=true;
1422
+ allowMomentumBounce = true;
1423
+ }
1424
+ else newPosition = -maxPosition;
1425
+ }
1426
+ if (newPosition > 0) {
1427
+ if (params.momentumBounce && _this.support.transitions) {
1428
+ if (newPosition>bounceAmount) newPosition = bounceAmount;
1429
+ afterBouncePosition = 0
1430
+ doBounce = true;
1431
+ allowMomentumBounce = true;
1432
+ }
1433
+ else newPosition = 0;
1434
+ }
1435
+ //Fix duration
1436
+ if (_this.velocity!=0) momentumDuration = Math.abs((newPosition - _this.positions.current)/_this.velocity)
1437
+
1438
+ if (isH) _this.setWrapperTranslate( newPosition, 0, 0);
1439
+ else _this.setWrapperTranslate( 0, newPosition, 0);
1440
+
1441
+ _this.setWrapperTransition( momentumDuration );
1442
+
1443
+ if (params.momentumBounce && doBounce) {
1444
+ _this.wrapperTransitionEnd(function(){
1445
+ if (!allowMomentumBounce) return;
1446
+ if (params.onMomentumBounce) params.onMomentumBounce(_this);
1447
+ if (isH) _this.setWrapperTranslate(afterBouncePosition, 0, 0);
1448
+ else _this.setWrapperTranslate(0, afterBouncePosition, 0);
1449
+ _this.setWrapperTransition(300);
1450
+ })
1451
+ }
1452
+
1105
1453
  _this.updateActiveSlide(newPosition)
1106
1454
  }
1107
- if (!params.freeModeFluid || (_this.times.end - _this.times.start) >= 300) _this.updateActiveSlide(_this.positions.current)
1455
+ if (!params.freeModeFluid || timeDiff >= 300) _this.updateActiveSlide(_this.positions.current)
1456
+
1108
1457
  if (params.onTouchEnd) params.onTouchEnd(_this)
1109
1458
  _this.callPlugins('onTouchEnd');
1110
- return
1459
+ return;
1111
1460
  }
1112
-
1461
+
1113
1462
  //Direction
1114
1463
  direction = diff < 0 ? "toNext" : "toPrev"
1115
-
1464
+
1116
1465
  //Short Touches
1117
- if (direction=="toNext" && ( _this.times.end - _this.times.start <= 300 ) ) {
1466
+ if (direction=="toNext" && ( timeDiff <= 300 ) ) {
1118
1467
  if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset()
1119
1468
  else _this.swipeNext(true);
1120
1469
  }
1121
-
1122
- if (direction=="toPrev" && ( _this.times.end - _this.times.start <= 300 ) ) {
1123
-
1470
+
1471
+ if (direction=="toPrev" && ( timeDiff <= 300 ) ) {
1124
1472
  if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset()
1125
1473
  else _this.swipePrev(true);
1126
1474
  }
1475
+
1127
1476
  //Long Touches
1128
- var groupSize = slideSize * params.slidesPerGroup
1129
- if (direction=="toNext" && ( _this.times.end - _this.times.start > 300 ) ) {
1130
- if (diffAbs >= groupSize*0.5) {
1477
+ var targetSlideSize = 0;
1478
+ if(params.slidesPerView == 'auto') {
1479
+ //Define current slide's width
1480
+ var currentPosition = Math.abs( isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y') );
1481
+ var slidesOffset = 0;
1482
+ var _slideSize;
1483
+ for (var i=0; i<_this.slides.length; i++) {
1484
+ _slideSize = isH ? _this.slides[i].getWidth(true) : _this.slides[i].getHeight(true);
1485
+ slidesOffset+= _slideSize;
1486
+ if (slidesOffset>currentPosition) {
1487
+ targetSlideSize = _slideSize;
1488
+ break;
1489
+ }
1490
+ }
1491
+ if (targetSlideSize>containerSize) targetSlideSize = containerSize;
1492
+ }
1493
+ else {
1494
+ targetSlideSize = slideSize * params.slidesPerView;
1495
+ }
1496
+ if (direction=="toNext" && ( timeDiff > 300 ) ) {
1497
+ if (diffAbs >= targetSlideSize*0.5) {
1131
1498
  _this.swipeNext(true)
1132
1499
  }
1133
1500
  else {
1134
1501
  _this.swipeReset()
1135
1502
  }
1136
1503
  }
1137
- if (direction=="toPrev" && ( _this.times.end - _this.times.start > 300 ) ) {
1138
- if (diffAbs >= groupSize*0.5) {
1504
+ if (direction=="toPrev" && ( timeDiff > 300 ) ) {
1505
+ if (diffAbs >= targetSlideSize*0.5) {
1139
1506
  _this.swipePrev(true);
1140
1507
  }
1141
1508
  else {
@@ -1145,289 +1512,671 @@ var Swiper = function (selector, params, callback) {
1145
1512
  if (params.onTouchEnd) params.onTouchEnd(_this)
1146
1513
  _this.callPlugins('onTouchEnd');
1147
1514
  }
1515
+
1516
+
1517
+ /*==================================================
1518
+ noSwiping Bubble Check by Isaac Strack
1519
+ ====================================================*/
1520
+ function noSwipingSlide(el){
1521
+ /*This function is specifically designed to check the parent elements for the noSwiping class, up to the wrapper.
1522
+ We need to check parents because while onTouchStart bubbles, _this.isTouched is checked in onTouchStart, which stops the bubbling.
1523
+ So, if a text box, for example, is the initial target, and the parent slide container has the noSwiping class, the _this.isTouched
1524
+ check will never find it, and what was supposed to be noSwiping is able to be swiped.
1525
+ This function will iterate up and check for the noSwiping class in parents, up through the wrapperClass.*/
1526
+
1527
+ // First we create a truthy variable, which is that swiping is allowd (noSwiping = false)
1528
+ var noSwiping = false;
1148
1529
 
1149
- /*=========================
1150
- Swipe Functions
1151
- ===========================*/
1152
- _this.swipeNext = function(internal) {
1153
- if (!internal && params.loop) _this.fixLoop();
1154
- if (!internal && params.autoPlay) _this.stopAutoPlay();
1530
+ // Now we iterate up (parentElements) until we reach the node with the wrapperClass.
1531
+ do{
1155
1532
 
1156
- _this.callPlugins('onSwipeNext');
1533
+ // Each time, we check to see if there's a 'swiper-no-swiping' class (noSwipingClass).
1534
+ if (el.className.indexOf(params.noSwipingClass)>-1)
1535
+ {
1536
+ noSwiping = true; // If there is, we set noSwiping = true;
1537
+ }
1157
1538
 
1158
- var getTranslate = isHorizontal ? _this.getTranslate('x') : _this.getTranslate('y');
1159
- var groupSize = slideSize * params.slidesPerGroup;
1160
- var newPosition = Math.floor(Math.abs(getTranslate)/Math.floor(groupSize))*groupSize + groupSize;
1161
- var curPos = Math.abs(getTranslate)
1162
- if (newPosition==wrapperSize) return;
1163
- if (curPos >= maxPos() && !params.loop) return;
1164
- if (newPosition > maxPos() && !params.loop) {
1165
- newPosition = maxPos()
1166
- };
1167
- if (params.loop) {
1168
- if (newPosition >= (maxPos()+containerSize)) newPosition = maxPos()+containerSize
1169
- }
1170
- if (isHorizontal) {
1171
- _this.setTransform(-newPosition,0,0)
1539
+ el = el.parentElement; // now we iterate up (parent node)
1540
+
1541
+ } while(!noSwiping && el.parentElement && el.className.indexOf(params.wrapperClass)==-1); // also include el.parentElement truthy, just in case.
1542
+
1543
+ // because we didn't check the wrapper itself, we do so now, if noSwiping is false:
1544
+ if (!noSwiping && el.className.indexOf(params.wrapperClass)>-1 && el.className.indexOf(params.noSwipingClass)>-1)
1545
+ noSwiping = true; // if the wrapper has the noSwipingClass, we set noSwiping = true;
1546
+
1547
+ return noSwiping;
1548
+ }
1549
+
1550
+ /*==================================================
1551
+ Swipe Functions
1552
+ ====================================================*/
1553
+ _this.swipeNext = function(internal){
1554
+ if (!internal && params.loop) _this.fixLoop();
1555
+ _this.callPlugins('onSwipeNext');
1556
+ var currentPosition = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
1557
+ var newPosition = currentPosition;
1558
+ if (params.slidesPerView=='auto') {
1559
+ for (var i=0; i<_this.snapGrid.length; i++) {
1560
+ if (-currentPosition >= _this.snapGrid[i] && -currentPosition<_this.snapGrid[i+1]) {
1561
+ newPosition = -_this.snapGrid[i+1]
1562
+ break;
1563
+ }
1564
+ }
1172
1565
  }
1173
1566
  else {
1174
- _this.setTransform(0,-newPosition,0)
1175
- }
1176
-
1177
- _this.setTransition( params.speed)
1178
-
1179
- //Update Active Slide
1180
- _this.updateActiveSlide(-newPosition)
1181
-
1182
- //Run Callbacks
1183
- slideChangeCallbacks()
1184
-
1567
+ var groupSize = slideSize * params.slidesPerGroup;
1568
+ newPosition = -(Math.floor(Math.abs(currentPosition)/Math.floor(groupSize))*groupSize + groupSize);
1569
+ }
1570
+ if (newPosition < - maxWrapperPosition()) {
1571
+ newPosition = - maxWrapperPosition()
1572
+ };
1573
+
1574
+ if (newPosition == currentPosition) return false;
1575
+
1576
+ swipeToPosition(newPosition, 'next');
1185
1577
  return true
1186
1578
  }
1187
-
1188
- _this.swipePrev = function(internal) {
1189
- if (!internal&&params.loop) _this.fixLoop();
1190
- if (!internal && params.autoPlay) _this.stopAutoPlay();
1191
-
1579
+ _this.swipePrev = function(internal){
1580
+ if (!internal && params.loop) _this.fixLoop();
1581
+ if (!internal && params.autoplay) _this.stopAutoplay();
1192
1582
  _this.callPlugins('onSwipePrev');
1193
1583
 
1194
- var getTranslate = Math.ceil( isHorizontal ? _this.getTranslate('x') : _this.getTranslate('y') );
1195
-
1196
- var groupSize = slideSize * params.slidesPerGroup;
1197
- var newPosition = (Math.ceil(-getTranslate/groupSize)-1)*groupSize;
1198
-
1199
- if (newPosition < 0) newPosition = 0;
1200
-
1201
- if (isHorizontal) {
1202
- _this.setTransform(-newPosition,0,0)
1203
- }
1204
- else {
1205
- _this.setTransform(0,-newPosition,0)
1206
- }
1207
- _this.setTransition(params.speed)
1208
-
1209
- //Update Active Slide
1210
- _this.updateActiveSlide(-newPosition)
1211
-
1212
- //Run Callbacks
1213
- slideChangeCallbacks()
1214
-
1215
- return true
1584
+ var currentPosition = Math.ceil( isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y') );
1585
+ var newPosition;
1586
+ if (params.slidesPerView=='auto') {
1587
+ newPosition = 0;
1588
+ for (var i=1; i<_this.snapGrid.length; i++) {
1589
+ if (-currentPosition == _this.snapGrid[i]) {
1590
+ newPosition = -_this.snapGrid[i-1]
1591
+ break;
1592
+ }
1593
+ if (-currentPosition > _this.snapGrid[i] && -currentPosition<_this.snapGrid[i+1]) {
1594
+ newPosition = -_this.snapGrid[i]
1595
+ break;
1596
+ }
1597
+ }
1598
+ }
1599
+ else {
1600
+ var groupSize = slideSize * params.slidesPerGroup;
1601
+ newPosition = -(Math.ceil(-currentPosition/groupSize)-1)*groupSize;
1602
+ }
1603
+
1604
+ if (newPosition > 0) newPosition = 0;
1605
+
1606
+ if (newPosition == currentPosition) return false;
1607
+ swipeToPosition(newPosition, 'prev');
1608
+ return true;
1609
+
1216
1610
  }
1217
-
1218
- _this.swipeReset = function(prevention) {
1611
+ _this.swipeReset = function(){
1219
1612
  _this.callPlugins('onSwipeReset');
1220
- var getTranslate = isHorizontal ? _this.getTranslate('x') : _this.getTranslate('y');
1221
- var groupSize = slideSize * params.slidesPerGroup
1222
- var newPosition = getTranslate<0 ? Math.round(getTranslate/groupSize)*groupSize : 0
1223
- var maxPosition = -maxPos()
1613
+ var currentPosition = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
1614
+ var groupSize = slideSize * params.slidesPerGroup;
1615
+ var newPosition;
1616
+ var maxPosition = -maxWrapperPosition();
1617
+ if (params.slidesPerView=='auto') {
1618
+ newPosition = 0;
1619
+ for (var i=0; i<_this.snapGrid.length; i++) {
1620
+ if (-currentPosition===_this.snapGrid[i]) return;
1621
+ if (-currentPosition >= _this.snapGrid[i] && -currentPosition<_this.snapGrid[i+1]) {
1622
+ if(_this.positions.diff>0) newPosition = -_this.snapGrid[i+1]
1623
+ else newPosition = -_this.snapGrid[i]
1624
+ break;
1625
+ }
1626
+ }
1627
+ if (-currentPosition >= _this.snapGrid[_this.snapGrid.length-1]) newPosition = -_this.snapGrid[_this.snapGrid.length-1];
1628
+ if (currentPosition <= -maxWrapperPosition()) newPosition = -maxWrapperPosition()
1629
+ }
1630
+ else {
1631
+ newPosition = currentPosition<0 ? Math.round(currentPosition/groupSize)*groupSize : 0
1632
+ }
1224
1633
  if (params.scrollContainer) {
1225
- newPosition = getTranslate<0 ? getTranslate : 0;
1226
- maxPosition = containerSize - slideSize;
1634
+ newPosition = currentPosition<0 ? currentPosition : 0;
1227
1635
  }
1228
-
1229
- if (newPosition <= maxPosition) {
1230
- newPosition = maxPosition
1636
+ if (newPosition < -maxWrapperPosition()) {
1637
+ newPosition = -maxWrapperPosition()
1231
1638
  }
1232
1639
  if (params.scrollContainer && (containerSize>slideSize)) {
1233
1640
  newPosition = 0;
1234
1641
  }
1235
-
1236
- if (params.mode=='horizontal') {
1237
- _this.setTransform(newPosition,0,0)
1642
+
1643
+ if (newPosition == currentPosition) return false;
1644
+
1645
+ swipeToPosition(newPosition, 'reset');
1646
+ return true;
1647
+ }
1648
+ _this.swipeTo = function(index, speed, runCallbacks){
1649
+ index = parseInt(index, 10);
1650
+ _this.callPlugins('onSwipeTo', {index:index, speed:speed});
1651
+ if (params.loop) index = index + _this.loopedSlides;
1652
+ var currentPosition = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
1653
+ if (index > (_this.slides.length-1)) return;
1654
+ if (index<0) return;
1655
+ var newPosition
1656
+ if (params.slidesPerView=='auto') {
1657
+ newPosition = -_this.slidesGrid[ index ];
1238
1658
  }
1239
1659
  else {
1240
- _this.setTransform(0,newPosition,0)
1241
- }
1242
-
1243
- _this.setTransition( params.speed)
1244
-
1245
- //Update Active Slide
1246
- _this.updateActiveSlide(newPosition)
1247
-
1248
- //Reset Callback
1249
- if (params.onSlideReset) {
1250
- params.onSlideReset(_this)
1251
- }
1252
-
1253
- return true
1660
+ newPosition = -index*slideSize;
1661
+ }
1662
+ if (newPosition < - maxWrapperPosition()) {
1663
+ newPosition = - maxWrapperPosition();
1664
+ };
1665
+
1666
+ if (newPosition == currentPosition) return false;
1667
+
1668
+ runCallbacks = runCallbacks===false ? false : true;
1669
+ swipeToPosition(newPosition, 'to', {index:index, speed:speed, runCallbacks:runCallbacks});
1670
+ return true;
1254
1671
  }
1255
-
1256
- var firstTimeLoopPositioning = true;
1257
-
1258
- _this.swipeTo = function (index, speed, runCallbacks) {
1259
-
1260
- index = parseInt(index, 10); //type cast to int
1261
- _this.callPlugins('onSwipeTo', {index:index, speed:speed});
1262
-
1263
- if (index > (numOfSlides-1)) return;
1264
- if (index<0 && !params.loop) return;
1265
- runCallbacks = runCallbacks===false ? false : runCallbacks || true
1266
- var speed = speed===0 ? speed : speed || params.speed;
1267
-
1268
- if (params.loop) index = index + params.slidesPerSlide;
1269
-
1270
- if (index > numOfSlides - params.slidesPerSlide) index = numOfSlides - params.slidesPerSlide;
1271
- var newPosition = -index*slideSize ;
1272
-
1273
- if(firstTimeLoopPositioning && params.loop && params.initialSlide > 0 && params.initialSlide < numOfSlides){
1274
- newPosition = newPosition - params.initialSlide * slideSize;
1275
- firstTimeLoopPositioning = false;
1276
- }
1277
-
1278
- if (isHorizontal) {
1279
- _this.setTransform(newPosition,0,0)
1672
+ function swipeToPosition(newPosition, action, toOptions) {
1673
+ if (_this.support.transitions || !params.DOMAnimation) {
1674
+ if (isH) _this.setWrapperTranslate(newPosition,0,0);
1675
+ else _this.setWrapperTranslate(0,newPosition,0);
1676
+ var speed = (action=='to' && toOptions.speed>=0) ? toOptions.speed : params.speed;
1677
+ _this.setWrapperTransition(speed);
1280
1678
  }
1281
1679
  else {
1282
- _this.setTransform(0,newPosition,0)
1680
+ //Try the DOM animation
1681
+ var currentPosition = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
1682
+ var speed = (action=='to' && toOptions.speed>=0) ? toOptions.speed : params.speed;
1683
+ var animationStep = Math.ceil( (newPosition - currentPosition)/speed*(1000/60) );
1684
+ var direction = currentPosition > newPosition ? 'toNext' : 'toPrev';
1685
+ var condition = direction=='toNext' ? currentPosition > newPosition : currentPosition < newPosition;
1686
+ if (_this._DOMAnimating) return;
1687
+
1688
+ anim()
1689
+ }
1690
+ function anim(){
1691
+ currentPosition += animationStep;
1692
+ condition = direction=='toNext' ? currentPosition > newPosition : currentPosition < newPosition;
1693
+ if (condition) {
1694
+ if (isH) _this.setWrapperTranslate(Math.round(currentPosition),0)
1695
+ else _this.setWrapperTranslate(0,Math.round(currentPosition))
1696
+ _this._DOMAnimating = true
1697
+ window.setTimeout(function(){
1698
+ anim()
1699
+ }, 1000 / 60)
1700
+ }
1701
+ else {
1702
+ if (params.onSlideChangeEnd) params.onSlideChangeEnd(_this)
1703
+ if (isH) _this.setWrapperTranslate(newPosition,0);
1704
+ else _this.setWrapperTranslate(0, newPosition);
1705
+ _this._DOMAnimating = false;
1706
+ }
1283
1707
  }
1284
- _this.setTransition( speed )
1285
- _this.updateActiveSlide(newPosition)
1286
1708
 
1287
- //Run Callbacks
1288
- if (runCallbacks)
1709
+ //Update Active Slide Index
1710
+ _this.updateActiveSlide(newPosition);
1711
+
1712
+ //Callbacks
1713
+ if (params.onSlideNext && action=='next') {
1714
+ params.onSlideNext(_this, newPosition)
1715
+ }
1716
+ if (params.onSlidePrev && action=='prev') {
1717
+ params.onSlidePrev(_this, newPosition)
1718
+ }
1719
+ //"Reset" Callback
1720
+ if (params.onSlideReset && action=='reset') {
1721
+ params.onSlideReset(_this, newPosition)
1722
+ }
1723
+
1724
+ //"Next", "Prev" and "To" Callbacks
1725
+ if (action=='next' || action=='prev' || (action=='to' && toOptions.runCallbacks==true))
1289
1726
  slideChangeCallbacks()
1290
-
1291
- return true
1292
1727
  }
1293
-
1294
- //Prevent Multiple Callbacks
1728
+ /*==================================================
1729
+ Transition Callbacks
1730
+ ====================================================*/
1731
+ //Prevent Multiple Callbacks
1295
1732
  _this._queueStartCallbacks = false;
1296
1733
  _this._queueEndCallbacks = false;
1297
1734
  function slideChangeCallbacks() {
1298
1735
  //Transition Start Callback
1299
1736
  _this.callPlugins('onSlideChangeStart');
1300
- if (params.onSlideChangeStart && !_this._queueStartCallbacks) {
1301
- _this._queueStartCallbacks = true;
1302
- params.onSlideChangeStart(_this)
1303
- _this.transitionEnd(function(){
1304
- _this._queueStartCallbacks = false;
1305
- })
1306
- }
1307
-
1737
+ if (params.onSlideChangeStart) {
1738
+ if (params.queueStartCallbacks && _this.support.transitions) {
1739
+ if (_this._queueStartCallbacks) return;
1740
+ _this._queueStartCallbacks = true;
1741
+ params.onSlideChangeStart(_this)
1742
+ _this.wrapperTransitionEnd(function(){
1743
+ _this._queueStartCallbacks = false;
1744
+ })
1745
+ }
1746
+ else params.onSlideChangeStart(_this)
1747
+ }
1308
1748
  //Transition End Callback
1309
- if (params.onSlideChangeEnd && !_this._queueEndCallbacks) {
1310
- if(_this.support.transitions) {
1311
- _this._queueEndCallbacks = true;
1312
- _this.transitionEnd(params.onSlideChangeEnd)
1749
+ if (params.onSlideChangeEnd) {
1750
+ if (_this.support.transitions) {
1751
+ if (params.queueEndCallbacks) {
1752
+ if (_this._queueEndCallbacks) return;
1753
+ _this._queueEndCallbacks = true;
1754
+ _this.wrapperTransitionEnd(params.onSlideChangeEnd)
1755
+ }
1756
+ else _this.wrapperTransitionEnd(params.onSlideChangeEnd)
1313
1757
  }
1314
1758
  else {
1315
- setTimeout(function(){
1316
- params.onSlideChangeEnd(_this)
1317
- },10)
1759
+ if (!params.DOMAnimation) {
1760
+ setTimeout(function(){
1761
+ params.onSlideChangeEnd(_this)
1762
+ },10)
1763
+ }
1318
1764
  }
1319
1765
  }
1320
1766
  }
1321
-
1767
+ /*==================================================
1768
+ Update Active Slide Index
1769
+ ====================================================*/
1322
1770
  _this.updateActiveSlide = function(position) {
1323
- _this.previousIndex = _this.previousSlide = _this.realIndex
1324
- _this.realIndex = Math.round(-position/slideSize)
1325
- if (!params.loop) _this.activeIndex = _this.realIndex;
1771
+ if (!_this.initialized) return;
1772
+ if (_this.slides.length==0) return;
1773
+ _this.previousIndex = _this.activeIndex;
1774
+ if (position>0) position=0;
1775
+ if (typeof position=='undefined') position = isH ? _this.getWrapperTranslate('x') : _this.getWrapperTranslate('y');
1776
+
1777
+ if (params.slidesPerView == 'auto') {
1778
+ var slidesOffset = 0;
1779
+ _this.activeIndex = _this.slidesGrid.indexOf(-position);
1780
+ if (_this.activeIndex<0) {
1781
+ for (var i=0; i<_this.slidesGrid.length-1; i++) {
1782
+ if (-position>_this.slidesGrid[i] && -position<_this.slidesGrid[i+1]) {
1783
+ break;
1784
+ }
1785
+ }
1786
+ var leftDistance = Math.abs( _this.slidesGrid[i] + position )
1787
+ var rightDistance = Math.abs( _this.slidesGrid[i+1] + position )
1788
+ if (leftDistance<=rightDistance) _this.activeIndex = i;
1789
+ else _this.activeIndex = i+1;
1790
+ }
1791
+ }
1326
1792
  else {
1327
- _this.activeIndex = _this.realIndex-params.slidesPerSlide
1328
- if (_this.activeIndex>=numOfSlides-params.slidesPerSlide*2) {
1329
- _this.activeIndex = numOfSlides - params.slidesPerSlide*2 - _this.activeIndex
1793
+ if (params.visibilityFullFit) _this.activeIndex = Math.ceil( -position/slideSize );
1794
+ else _this.activeIndex = Math.round( -position/slideSize );
1795
+ }
1796
+ if (_this.activeIndex== _this.slides.length ) _this.activeIndex = _this.slides.length-1;
1797
+ if (_this.activeIndex<0) _this.activeIndex = 0;
1798
+ // Check for slide
1799
+ if (!_this.slides[_this.activeIndex]) return;
1800
+ // Calc Visible slides
1801
+ _this.calcVisibleSlides(position);
1802
+
1803
+ // Mark visible and active slides with additonal classes
1804
+ var activeClassRegexp = new RegExp( "\\s*" + params.slideActiveClass );
1805
+ var inViewClassRegexp = new RegExp( "\\s*" + params.slideVisibleClass );
1806
+
1807
+ for (var i = 0; i < _this.slides.length; i++) {
1808
+ _this.slides[ i ].className = _this.slides[ i ].className.replace( activeClassRegexp, '' ).replace( inViewClassRegexp, '' );
1809
+ if ( _this.visibleSlides.indexOf( _this.slides[ i ] )>=0 ) {
1810
+ _this.slides[ i ].className += ' ' + params.slideVisibleClass;
1330
1811
  }
1331
- if (_this.activeIndex<0) {
1332
- _this.activeIndex = numOfSlides - params.slidesPerSlide*2 + _this.activeIndex
1812
+
1813
+ }
1814
+ _this.slides[ _this.activeIndex ].className += ' ' + params.slideActiveClass;
1815
+
1816
+ //Update loop index
1817
+ if (params.loop) {
1818
+ var ls = _this.loopedSlides;
1819
+ _this.activeLoopIndex = _this.activeIndex - ls;
1820
+ if (_this.activeLoopIndex >= _this.slides.length - ls*2 ) {
1821
+ _this.activeLoopIndex = _this.slides.length - ls*2 - _this.activeLoopIndex;
1822
+ }
1823
+ if (_this.activeLoopIndex<0) {
1824
+ _this.activeLoopIndex = _this.slides.length - ls*2 + _this.activeLoopIndex;
1333
1825
  }
1334
1826
  }
1335
- if (_this.realIndex==numOfSlides) _this.realIndex = numOfSlides-1
1336
- if (_this.realIndex<0) _this.realIndex = 0
1337
- //Legacy
1338
- _this.activeSlide = _this.activeIndex;
1827
+ else {
1828
+ _this.activeLoopIndex = _this.activeIndex;
1829
+ }
1339
1830
  //Update Pagination
1340
1831
  if (params.pagination) {
1341
- _this.updatePagination()
1832
+ _this.updatePagination(position);
1342
1833
  }
1343
-
1344
1834
  }
1345
-
1346
-
1347
-
1348
- /*=========================
1349
- Loop Fixes
1350
- ===========================*/
1351
- _this.fixLoop = function(){
1835
+ /*==================================================
1836
+ Pagination
1837
+ ====================================================*/
1838
+ _this.createPagination = function (firstInit) {
1839
+ if (params.paginationClickable && _this.paginationButtons) {
1840
+ removePaginationEvents();
1841
+ }
1842
+ var paginationHTML = "";
1843
+ var numOfSlides = _this.slides.length;
1844
+ var numOfButtons = numOfSlides;
1845
+ if (params.loop) numOfButtons -= _this.loopedSlides*2
1846
+ for (var i = 0; i < numOfButtons; i++) {
1847
+ paginationHTML += '<'+params.paginationElement+' class="'+params.paginationElementClass+'"></'+params.paginationElement+'>'
1848
+ }
1849
+ _this.paginationContainer = params.pagination.nodeType ? params.pagination : $$(params.pagination)[0];
1850
+ _this.paginationContainer.innerHTML = paginationHTML;
1851
+ _this.paginationButtons = []
1852
+ if (document.querySelectorAll)
1853
+ _this.paginationButtons = _this.paginationContainer.querySelectorAll('.'+params.paginationElementClass);
1854
+ else if (window.jQuery)
1855
+ _this.paginationButtons = $$(_this.paginationContainer).find('.'+params.paginationElementClass);
1856
+ if (!firstInit) _this.updatePagination()
1857
+ _this.callPlugins('onCreatePagination');
1858
+ if (params.paginationClickable) {
1859
+ addPaginationEvents();
1860
+ }
1861
+ }
1862
+ function removePaginationEvents() {
1863
+ var pagers = _this.paginationButtons;
1864
+ for (var i=0; i<pagers.length; i++) {
1865
+ _this.h.removeEventListener(pagers[i],'click', paginationClick, false)
1866
+ }
1867
+ }
1868
+ function addPaginationEvents() {
1869
+ var pagers = _this.paginationButtons;
1870
+ for (var i=0; i<pagers.length; i++) {
1871
+ _this.h.addEventListener(pagers[i],'click', paginationClick, false)
1872
+ }
1873
+ }
1874
+ function paginationClick(e){
1875
+ var index;
1876
+ var target = e.target || e.srcElement;
1877
+ var pagers = _this.paginationButtons;
1878
+ for (var i=0; i<pagers.length; i++) {
1879
+ if (target===pagers[i]) index = i;
1880
+ }
1881
+ _this.swipeTo(index)
1882
+ }
1883
+ _this.updatePagination = function(position) {
1884
+ if (!params.pagination) return;
1885
+ if (_this.slides.length<1) return;
1886
+
1887
+ if (document.querySelectorAll)
1888
+ var activePagers = _this.paginationContainer.querySelectorAll('.'+params.paginationActiveClass)
1889
+ else if (window.jQuery)
1890
+ var activePagers = $$(_this.paginationContainer).find('.'+params.paginationActiveClass);
1891
+ if(!activePagers) return;
1892
+
1893
+ //Reset all Buttons' class to not active
1894
+ var pagers = _this.paginationButtons;
1895
+ if (pagers.length==0) return;
1896
+ for (var i=0; i < pagers.length; i++) {
1897
+ pagers[i].className = params.paginationElementClass
1898
+ }
1899
+
1900
+ var indexOffset = params.loop ? _this.loopedSlides : 0;
1901
+ if (params.paginationAsRange) {
1902
+ if (!_this.visibleSlides) _this.calcVisibleSlides(position)
1903
+ //Get Visible Indexes
1904
+ var visibleIndexes = [];
1905
+ for (var i = 0; i < _this.visibleSlides.length; i++) {
1906
+ var visIndex = _this.slides.indexOf( _this.visibleSlides[i] ) - indexOffset
1907
+
1908
+ if (params.loop && visIndex<0) {
1909
+ visIndex = _this.slides.length - _this.loopedSlides*2 + visIndex;
1910
+ }
1911
+ if (params.loop && visIndex>=_this.slides.length-_this.loopedSlides*2) {
1912
+ visIndex = _this.slides.length - _this.loopedSlides*2 - visIndex;
1913
+ visIndex = Math.abs(visIndex)
1914
+ }
1915
+ visibleIndexes.push( visIndex )
1916
+ }
1917
+
1918
+ for (i=0; i<visibleIndexes.length; i++) {
1919
+ if (pagers[ visibleIndexes[i] ]) pagers[ visibleIndexes[i] ].className += ' ' + params.paginationVisibleClass;
1920
+ }
1921
+
1922
+ if (params.loop) {
1923
+ pagers[ _this.activeLoopIndex ].className += ' ' + params.paginationActiveClass;
1924
+ }
1925
+ else {
1926
+ pagers[ _this.activeIndex ].className += ' ' + params.paginationActiveClass;
1927
+ }
1928
+
1929
+ }
1930
+ else {
1931
+ if (params.loop) {
1932
+ pagers[ _this.activeLoopIndex ].className+=' '+params.paginationActiveClass+' '+params.paginationVisibleClass;
1933
+ }
1934
+ else {
1935
+ pagers[ _this.activeIndex ].className+=' '+params.paginationActiveClass+' '+params.paginationVisibleClass;
1936
+ }
1937
+
1938
+ }
1939
+
1940
+ }
1941
+ _this.calcVisibleSlides = function(position){
1942
+ var visibleSlides = [];
1943
+ var _slideLeft = 0, _slideSize = 0, _slideRight = 0;
1944
+ if (isH && _this.wrapperLeft>0) position = position+_this.wrapperLeft;
1945
+ if (!isH && _this.wrapperTop>0) position = position+_this.wrapperTop;
1946
+
1947
+ for (var i=0; i<_this.slides.length; i++) {
1948
+ _slideLeft += _slideSize;
1949
+ if (params.slidesPerView == 'auto')
1950
+ _slideSize = isH ? _this.h.getWidth(_this.slides[i],true) : _this.h.getHeight(_this.slides[i],true);
1951
+ else _slideSize = slideSize;
1952
+
1953
+ _slideRight = _slideLeft + _slideSize;
1954
+ var isVisibile = false;
1955
+ if (params.visibilityFullFit) {
1956
+ if (_slideLeft >= -position && _slideRight <= -position+containerSize) isVisibile = true;
1957
+ if (_slideLeft <= -position && _slideRight >= -position+containerSize) isVisibile = true;
1958
+ }
1959
+ else {
1960
+
1961
+ if (_slideRight > -position && _slideRight <= ((-position+containerSize))) isVisibile = true;
1962
+ if (_slideLeft >= -position && _slideLeft < ((-position+containerSize))) isVisibile = true;
1963
+ if (_slideLeft < -position && _slideRight > ((-position+containerSize))) isVisibile = true;
1964
+ }
1965
+
1966
+ if (isVisibile) visibleSlides.push(_this.slides[i])
1967
+
1968
+ }
1969
+ if (visibleSlides.length==0) visibleSlides = [ _this.slides[ _this.activeIndex ] ]
1970
+
1971
+ _this.visibleSlides = visibleSlides;
1972
+ }
1973
+
1974
+ /*==========================================
1975
+ Autoplay
1976
+ ============================================*/
1977
+ _this.autoPlayIntervalId = undefined;
1978
+ _this.startAutoplay = function () {
1979
+ if (typeof _this.autoPlayIntervalId !== 'undefined') return false;
1980
+ if (params.autoplay && !params.loop) {
1981
+ _this.autoPlayIntervalId = setInterval(function(){
1982
+ if (!_this.swipeNext(true)) _this.swipeTo(0);
1983
+ }, params.autoplay)
1984
+ }
1985
+ if (params.autoplay && params.loop) {
1986
+ _this.autoPlayIntervalId = setInterval(function(){
1987
+ _this.swipeNext();
1988
+ }, params.autoplay)
1989
+ }
1990
+ _this.callPlugins('onAutoplayStart');
1991
+ }
1992
+ _this.stopAutoplay = function () {
1993
+ if (_this.autoPlayIntervalId) clearInterval(_this.autoPlayIntervalId);
1994
+ _this.autoPlayIntervalId = undefined;
1995
+ _this.callPlugins('onAutoplayStop');
1996
+ }
1997
+ /*==================================================
1998
+ Loop
1999
+ ====================================================*/
2000
+ _this.loopCreated = false;
2001
+ _this.removeLoopedSlides = function(){
2002
+ if (_this.loopCreated) {
2003
+ for (var i=0; i<_this.slides.length; i++) {
2004
+ if (_this.slides[i].getData('looped')===true) _this.wrapper.removeChild(_this.slides[i]);
2005
+ }
2006
+ }
2007
+ }
2008
+ _this.createLoop = function(){
2009
+ if (_this.slides.length==0) return;
2010
+ _this.loopedSlides = params.slidesPerView+params.loopAdditionalSlides;
2011
+
2012
+ var slideFirstHTML = '';
2013
+ var slideLastHTML = '';
2014
+
2015
+ //Grab First Slides
2016
+ for (var i=0; i<_this.loopedSlides; i++) {
2017
+ slideFirstHTML+=_this.slides[i].outerHTML
2018
+ }
2019
+ //Grab Last Slides
2020
+ for (i=_this.slides.length-_this.loopedSlides; i<_this.slides.length; i++) {
2021
+ slideLastHTML+=_this.slides[i].outerHTML
2022
+ }
2023
+ wrapper.innerHTML = slideLastHTML + wrapper.innerHTML + slideFirstHTML;
2024
+
2025
+ _this.loopCreated = true;
2026
+ _this.calcSlides();
2027
+
2028
+ //Update Looped Slides with special class
2029
+ for (i=0; i<_this.slides.length; i++) {
2030
+ if (i<_this.loopedSlides || i>=_this.slides.length-_this.loopedSlides) _this.slides[i].setData('looped', true);
2031
+ }
2032
+ _this.callPlugins('onCreateLoop');
2033
+
2034
+ }
2035
+ _this.fixLoop = function(){
1352
2036
  //Fix For Negative Oversliding
1353
- if (_this.realIndex < params.slidesPerSlide) {
1354
- var newIndex = numOfSlides - params.slidesPerSlide*3 + _this.realIndex;
1355
- _this.swipeTo(newIndex,0, false)
2037
+ if (_this.activeIndex < _this.loopedSlides) {
2038
+ var newIndex = _this.slides.length - _this.loopedSlides*3 + _this.activeIndex;
2039
+ _this.swipeTo(newIndex, 0, false)
1356
2040
  }
1357
2041
  //Fix For Positive Oversliding
1358
- if (_this.realIndex > numOfSlides - params.slidesPerSlide*2) {
1359
- var newIndex = -numOfSlides + _this.realIndex + params.slidesPerSlide
2042
+ else if (_this.activeIndex > _this.slides.length - params.slidesPerView*2) {
2043
+ var newIndex = -_this.slides.length + _this.activeIndex + _this.loopedSlides
1360
2044
  _this.swipeTo(newIndex,0, false)
1361
2045
  }
1362
2046
  }
1363
- if (params.loop) {
1364
- _this.swipeTo(0,0, false)
2047
+ /*==================================================
2048
+ Slides Loader
2049
+ ====================================================*/
2050
+ _this.loadSlides = function(){
2051
+ var slidesHTML = '';
2052
+ _this.activeLoaderIndex = 0;
2053
+ var slides = params.loader.slides;
2054
+ var slidesToLoad = params.loader.loadAllSlides ? slides.length : params.slidesPerView*(1+params.loader.surroundGroups);
2055
+ for (var i=0; i< slidesToLoad; i++) {
2056
+ if (params.loader.slidesHTMLType=='outer') slidesHTML+=slides[i];
2057
+ else {
2058
+ slidesHTML+='<'+params.slideElement+' class="'+params.slideClass+'" data-swiperindex="'+i+'">'+slides[i]+'</'+params.slideElement+'>';
2059
+ }
2060
+ }
2061
+ _this.wrapper.innerHTML = slidesHTML;
2062
+ _this.calcSlides(true);
2063
+ //Add permanent transitionEnd callback
2064
+ if (!params.loader.loadAllSlides) {
2065
+ _this.wrapperTransitionEnd(_this.reloadSlides, true);
2066
+ }
1365
2067
  }
2068
+ _this.reloadSlides = function(){
2069
+ var slides = params.loader.slides;
2070
+ var newActiveIndex = parseInt(_this.activeSlide().data('swiperindex'),10)
2071
+ if (newActiveIndex<0 || newActiveIndex>slides.length-1) return //<-- Exit
2072
+ _this.activeLoaderIndex = newActiveIndex;
2073
+ var firstIndex = Math.max(0, newActiveIndex - params.slidesPerView*params.loader.surroundGroups)
2074
+ var lastIndex = Math.min(newActiveIndex+params.slidesPerView*(1+params.loader.surroundGroups)-1, slides.length-1)
2075
+ //Update Transforms
2076
+ if (newActiveIndex>0) {
2077
+ var newTransform = -slideSize*(newActiveIndex-firstIndex)
2078
+ if (isH) _this.setWrapperTranslate(newTransform,0,0)
2079
+ else _this.setWrapperTranslate(0,newTransform,0)
2080
+ _this.setWrapperTransition(0)
2081
+ }
2082
+ //New Slides
2083
+ if (params.loader.logic==='reload') {
2084
+ _this.wrapper.innerHTML = '';
2085
+ var slidesHTML = '';
2086
+ for (var i = firstIndex; i<=lastIndex; i++) {
2087
+ slidesHTML += params.loader.slidesHTMLType == 'outer' ? slides[i] : '<'+params.slideElement+' class="'+params.slideClass+'" data-swiperindex="'+i+'">'+slides[i]+'</'+params.slideElement+'>';
2088
+ }
2089
+ _this.wrapper.innerHTML = slidesHTML;
2090
+ }
2091
+ else {
2092
+ var minExistIndex=1000;
2093
+ var maxExistIndex=0;
2094
+ for (var i=0; i<_this.slides.length; i++) {
2095
+ var index = _this.slides[i].data('swiperindex');
2096
+ if (index<firstIndex || index>lastIndex) {
2097
+ _this.wrapper.removeChild(_this.slides[i]);
2098
+ }
2099
+ else {
2100
+ minExistIndex = Math.min(index, minExistIndex)
2101
+ maxExistIndex = Math.max(index, maxExistIndex)
2102
+ }
2103
+ }
2104
+ for (var i=firstIndex; i<=lastIndex; i++) {
2105
+ if (i<minExistIndex) {
2106
+ var newSlide = document.createElement(params.slideElement);
2107
+ newSlide.className = params.slideClass;
2108
+ newSlide.setAttribute('data-swiperindex',i);
2109
+ newSlide.innerHTML = slides[i];
2110
+ _this.wrapper.insertBefore(newSlide, _this.wrapper.firstChild);
2111
+ }
2112
+ if (i>maxExistIndex) {
2113
+ var newSlide = document.createElement(params.slideElement);
2114
+ newSlide.className = params.slideClass;
2115
+ newSlide.setAttribute('data-swiperindex',i);
2116
+ newSlide.innerHTML = slides[i];
2117
+ _this.wrapper.appendChild(newSlide);
2118
+ }
2119
+ }
2120
+ }
2121
+ //reInit
2122
+ _this.reInit(true);
2123
+ }
2124
+ /*==================================================
2125
+ Make Swiper
2126
+ ====================================================*/
2127
+ function makeSwiper(){
2128
+ _this.calcSlides();
2129
+ if (params.loader.slides.length>0 && _this.slides.length==0) {
2130
+ _this.loadSlides();
2131
+ }
2132
+ if (params.loop) {
2133
+ _this.createLoop();
2134
+ }
2135
+ _this.init();
2136
+ initEvents();
2137
+ if (params.pagination && params.createPagination) {
2138
+ _this.createPagination(true);
2139
+ }
2140
+ if (params.loop || params.initialSlide>0) {
2141
+ _this.swipeTo( params.initialSlide, 0, false );
2142
+ }
2143
+ else {
2144
+ _this.updateActiveSlide(0);
2145
+ }
2146
+ if (params.autoplay) {
2147
+ _this.startAutoplay();
2148
+ }
1366
2149
 
1367
-
1368
-
2150
+ }
2151
+ makeSwiper();
1369
2152
  }
1370
2153
 
1371
2154
  Swiper.prototype = {
1372
2155
  plugins : {},
1373
- //Transition End
1374
- transitionEnd : function(callback, permanent) {
2156
+ /*==================================================
2157
+ Wrapper Operations
2158
+ ====================================================*/
2159
+ wrapperTransitionEnd : function(callback, permanent) {
1375
2160
  var a = this
1376
2161
  var el = a.wrapper
1377
2162
  var events = ['webkitTransitionEnd','transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];
1378
- if (callback) {
1379
- function fireCallBack() {
1380
- callback(a)
1381
- a._queueEndCallbacks = false
1382
- if (!permanent) {
1383
- for (var i=0; i<events.length; i++) {
1384
- el.removeEventListener(events[i], fireCallBack, false)
1385
- }
2163
+ function fireCallBack() {
2164
+ callback(a)
2165
+ if (a.params.queueEndCallbacks) a._queueEndCallbacks = false
2166
+ if (!permanent) {
2167
+ for (var i=0; i<events.length; i++) {
2168
+ a.h.removeEventListener(el,events[i], fireCallBack, false)
1386
2169
  }
1387
2170
  }
2171
+ }
2172
+ if (callback) {
1388
2173
  for (var i=0; i<events.length; i++) {
1389
- el.addEventListener(events[i], fireCallBack, false)
2174
+ a.h.addEventListener(el,events[i], fireCallBack, false)
1390
2175
  }
1391
2176
  }
1392
2177
  },
1393
-
1394
- //Touch Support
1395
- isSupportTouch : function() {
1396
- return ("ontouchstart" in window) || window.DocumentTouch && document instanceof DocumentTouch;
1397
- },
1398
- //Transition Support
1399
- isSupportTransitions : function(){
1400
- var div = document.createElement('div').style
1401
- return ('transition' in div) || ('WebkitTransition' in div) || ('MozTransition' in div) || ('msTransition' in div) || ('MsTransition' in div) || ('OTransition' in div);
1402
- },
1403
- // 3D Transforms Test
1404
- isSupport3D : function() {
1405
- var div = document.createElement('div');
1406
- div.id = 'test3d';
1407
-
1408
- var s3d=false;
1409
- if("webkitPerspective" in div.style) s3d=true;
1410
- if("MozPerspective" in div.style) s3d=true;
1411
- if("OPerspective" in div.style) s3d=true;
1412
- if("MsPerspective" in div.style) s3d=true;
1413
- if("perspective" in div.style) s3d=true;
1414
-
1415
- /* Test with Media query for Webkit to prevent FALSE positive*/
1416
- if(s3d && ("webkitPerspective" in div.style) ) {
1417
- var st = document.createElement('style');
1418
- st.textContent = '@media (-webkit-transform-3d), (transform-3d), (-moz-transform-3d), (-o-transform-3d), (-ms-transform-3d) {#test3d{height:5px}}'
1419
- document.getElementsByTagName('head')[0].appendChild(st);
1420
- document.body.appendChild(div);
1421
- s3d = div.offsetHeight === 5;
1422
- st.parentNode.removeChild(st);
1423
- div.parentNode.removeChild(div);
1424
- }
1425
-
1426
- return s3d;
1427
- },
1428
-
1429
- //GetTranslate
1430
- getTranslate : function(axis){
2178
+
2179
+ getWrapperTranslate : function(axis){
1431
2180
  var el = this.wrapper
1432
2181
  var matrix;
1433
2182
  var curTransform;
@@ -1438,29 +2187,29 @@ Swiper.prototype = {
1438
2187
  else {
1439
2188
  var transformMatrix = window.getComputedStyle(el, null).MozTransform || window.getComputedStyle(el, null).OTransform || window.getComputedStyle(el, null).MsTransform || window.getComputedStyle(el, null).msTransform || window.getComputedStyle(el, null).transform|| window.getComputedStyle(el, null).getPropertyValue("transform").replace("translate(", "matrix(1, 0, 0, 1,");
1440
2189
  matrix = transformMatrix.toString().split(',');
1441
-
2190
+
1442
2191
  }
1443
- if (this.params.useCSS3Transforms) {
2192
+ if (this.params.useCSS3Transforms) {
1444
2193
  if (axis=='x') {
1445
2194
  //Crazy IE10 Matrix
1446
- if (matrix.length==16)
2195
+ if (matrix.length==16)
1447
2196
  curTransform = parseFloat( matrix[12] )
1448
2197
  //Latest Chrome and webkits Fix
1449
2198
  else if (window.WebKitCSSMatrix)
1450
2199
  curTransform = transformMatrix.m41
1451
2200
  //Normal Browsers
1452
- else
2201
+ else
1453
2202
  curTransform = parseFloat( matrix[4] )
1454
2203
  }
1455
2204
  if (axis=='y') {
1456
2205
  //Crazy IE10 Matrix
1457
- if (matrix.length==16)
2206
+ if (matrix.length==16)
1458
2207
  curTransform = parseFloat( matrix[13] )
1459
2208
  //Latest Chrome and webkits Fix
1460
2209
  else if (window.WebKitCSSMatrix)
1461
2210
  curTransform = transformMatrix.m42
1462
2211
  //Normal Browsers
1463
- else
2212
+ else
1464
2213
  curTransform = parseFloat( matrix[5] )
1465
2214
  }
1466
2215
  }
@@ -1468,24 +2217,22 @@ Swiper.prototype = {
1468
2217
  if (axis=='x') curTransform = parseFloat(el.style.left,10) || 0
1469
2218
  if (axis=='y') curTransform = parseFloat(el.style.top,10) || 0
1470
2219
  }
1471
- return curTransform;
2220
+ return curTransform || 0;
1472
2221
  },
1473
-
1474
- //Set Transform
1475
- setTransform : function(x,y,z) {
1476
-
2222
+
2223
+ setWrapperTranslate : function(x,y,z) {
1477
2224
  var es = this.wrapper.style
1478
2225
  x=x||0;
1479
2226
  y=y||0;
1480
2227
  z=z||0;
1481
2228
  if (this.params.useCSS3Transforms) {
1482
- if (this.support.threeD) {
2229
+ if (this.support.transforms3d) {
1483
2230
  es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = 'translate3d('+x+'px, '+y+'px, '+z+'px)'
1484
2231
  }
1485
2232
  else {
1486
-
2233
+
1487
2234
  es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = 'translate('+x+'px, '+y+'px)'
1488
- if (this.ie8) {
2235
+ if (!this.support.transforms) {
1489
2236
  es.left = x+'px'
1490
2237
  es.top = y+'px'
1491
2238
  }
@@ -1495,34 +2242,167 @@ Swiper.prototype = {
1495
2242
  es.left = x+'px';
1496
2243
  es.top = y+'px';
1497
2244
  }
1498
- this.callPlugins('onSetTransform', {x:x, y:y, z:z})
2245
+ this.callPlugins('onSetWrapperTransform', {x:x, y:y, z:z})
1499
2246
  },
1500
-
1501
- //Set Transition
1502
- setTransition : function(duration) {
2247
+
2248
+ setWrapperTransition : function(duration) {
1503
2249
  var es = this.wrapper.style
1504
2250
  es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = duration/1000+'s';
1505
- this.callPlugins('onSetTransition', {duration: duration})
2251
+ this.callPlugins('onSetWrapperTransition', {duration: duration})
1506
2252
  },
1507
-
1508
- //Check for IE8
1509
- ie8: (function(){
1510
- var rv = -1; // Return value assumes failure.
1511
- if (navigator.appName == 'Microsoft Internet Explorer') {
1512
- var ua = navigator.userAgent;
1513
- var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
1514
- if (re.exec(ua) != null)
1515
- rv = parseFloat(RegExp.$1);
1516
- }
1517
- return rv != -1 && rv < 9;
1518
- })(),
1519
-
1520
- ie10 : window.navigator.msPointerEnabled
2253
+
2254
+ /*==================================================
2255
+ Helpers
2256
+ ====================================================*/
2257
+ h : {
2258
+ getWidth: function (el, outer) {
2259
+ var width = window.getComputedStyle(el, null).getPropertyValue('width')
2260
+ var returnWidth = parseFloat(width);
2261
+ //IE Fixes
2262
+ if(isNaN(returnWidth) || width.indexOf('%')>0) {
2263
+ returnWidth = el.offsetWidth - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-left')) - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-right'));
2264
+ }
2265
+ if (outer) returnWidth += parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-left')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-right'))
2266
+
2267
+ return returnWidth;
2268
+ },
2269
+ getHeight: function(el, outer) {
2270
+ if (outer) return el.offsetHeight;
2271
+
2272
+ var height = window.getComputedStyle(el, null).getPropertyValue('height')
2273
+ var returnHeight = parseFloat(height);
2274
+ //IE Fixes
2275
+ if(isNaN(returnHeight) || height.indexOf('%')>0) {
2276
+ returnHeight = el.offsetHeight - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-top')) - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-bottom'));
2277
+ }
2278
+ if (outer) returnHeight += parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-bottom'))
2279
+ return returnHeight;
2280
+ },
2281
+ getOffset: function(el) {
2282
+ var box = el.getBoundingClientRect();
2283
+ var body = document.body;
2284
+ var clientTop = el.clientTop || body.clientTop || 0;
2285
+ var clientLeft = el.clientLeft || body.clientLeft || 0;
2286
+ var scrollTop = window.pageYOffset || el.scrollTop;
2287
+ var scrollLeft = window.pageXOffset || el.scrollLeft;
2288
+ if (document.documentElement && !window.pageYOffset) {
2289
+ //IE7-8
2290
+ scrollTop = document.documentElement.scrollTop;
2291
+ scrollLeft = document.documentElement.scrollLeft;
2292
+ }
2293
+ return {
2294
+ top: box.top + scrollTop - clientTop,
2295
+ left: box.left + scrollLeft - clientLeft
2296
+ };
2297
+ },
2298
+ windowWidth : function() {
2299
+ if (window.innerWidth) return window.innerWidth
2300
+ else if (document.documentElement && document.documentElement.clientWidth) return document.documentElement.clientWidth;
2301
+ },
2302
+ windowHeight : function() {
2303
+ if (window.innerHeight) return window.innerHeight
2304
+ else if (document.documentElement && document.documentElement.clientHeight) return document.documentElement.clientHeight;
2305
+ },
2306
+ windowScroll : function() {
2307
+ var left=0, top=0;
2308
+ if (typeof pageYOffset != 'undefined') {
2309
+ return {
2310
+ left: window.pageXOffset,
2311
+ top: window.pageYOffset
2312
+ }
2313
+ }
2314
+ else if (document.documentElement) {
2315
+ return {
2316
+ left: document.documentElement.scrollLeft,
2317
+ top: document.documentElement.scrollTop
2318
+ }
2319
+ }
2320
+ },
2321
+
2322
+ addEventListener : function (el, event, listener, useCapture) {
2323
+ if (el.addEventListener) {
2324
+ el.addEventListener(event, listener, useCapture)
2325
+ }
2326
+ else if (el.attachEvent) {
2327
+ el.attachEvent('on'+event, listener)
2328
+ }
2329
+ },
2330
+ removeEventListener : function (el, event, listener, useCapture) {
2331
+ if (el.removeEventListener) {
2332
+ el.removeEventListener(event, listener, useCapture)
2333
+ }
2334
+ else if (el.detachEvent) {
2335
+ el.detachEvent('on'+event, listener)
2336
+ }
2337
+ }
2338
+ },
2339
+ setTransform : function (el, transform) {
2340
+ var es = el.style
2341
+ es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transform
2342
+ },
2343
+ setTranslate : function (el, translate) {
2344
+ var es = el.style
2345
+ var pos = {
2346
+ x : translate.x || 0,
2347
+ y : translate.y || 0,
2348
+ z : translate.z || 0
2349
+ };
2350
+ var transformString = this.support.transforms3d ? 'translate3d('+(pos.x)+'px,'+(pos.y)+'px,'+(pos.z)+'px)' : 'translate('+(pos.x)+'px,'+(pos.y)+'px)';
2351
+ es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transformString;
2352
+ if (!this.support.transforms) {
2353
+ es.left = pos.x+'px'
2354
+ es.top = pos.y+'px'
2355
+ }
2356
+ },
2357
+ setTransition : function (el, duration) {
2358
+ var es = el.style
2359
+ es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = duration+'ms';
2360
+ },
2361
+ /*==================================================
2362
+ Feature Detection
2363
+ ====================================================*/
2364
+ support: {
2365
+
2366
+ touch : (window.Modernizr && Modernizr.touch===true) || (function() {
2367
+ return !!(("ontouchstart" in window) || window.DocumentTouch && document instanceof DocumentTouch);
2368
+ })(),
2369
+
2370
+ transforms3d : (window.Modernizr && Modernizr.csstransforms3d===true) || (function() {
2371
+ var div = document.createElement('div');
2372
+ return ( "webkitPerspective" in div.style || "MozPerspective" in div.style || "OPerspective" in div.style || "MsPerspective" in div.style || "perspective" in div.style );
2373
+ })(),
2374
+
2375
+ transforms : (window.Modernizr && Modernizr.csstransforms===true) || (function(){
2376
+ var div = document.createElement('div').style
2377
+ return ('transform' in div) || ('WebkitTransform' in div) || ('MozTransform' in div) || ('msTransform' in div) || ('MsTransform' in div) || ('OTransform' in div);
2378
+ })(),
2379
+
2380
+ transitions : (window.Modernizr && Modernizr.csstransitions===true) || (function(){
2381
+ var div = document.createElement('div').style
2382
+ return ('transition' in div) || ('WebkitTransition' in div) || ('MozTransition' in div) || ('msTransition' in div) || ('MsTransition' in div) || ('OTransition' in div);
2383
+ })()
2384
+ },
2385
+
2386
+ browser : {
2387
+
2388
+ ie8 : (function(){
2389
+ var rv = -1; // Return value assumes failure.
2390
+ if (navigator.appName == 'Microsoft Internet Explorer') {
2391
+ var ua = navigator.userAgent;
2392
+ var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
2393
+ if (re.exec(ua) != null)
2394
+ rv = parseFloat(RegExp.$1);
2395
+ }
2396
+ return rv != -1 && rv < 9;
2397
+ })(),
2398
+
2399
+ ie10 : window.navigator.msPointerEnabled
2400
+ }
1521
2401
  }
1522
2402
 
1523
2403
  /*=========================
1524
2404
  jQuery & Zepto Plugins
1525
- ===========================*/
2405
+ ===========================*/
1526
2406
  if (window.jQuery||window.Zepto) {
1527
2407
  (function($){
1528
2408
  $.fn.swiper = function(params) {
@@ -1532,3 +2412,9 @@ if (window.jQuery||window.Zepto) {
1532
2412
  }
1533
2413
  })(window.jQuery||window.Zepto)
1534
2414
  }
2415
+
2416
+ // component
2417
+ if ( typeof( module ) !== 'undefined' )
2418
+ {
2419
+ module.exports = Swiper;
2420
+ }