1var Swiper = function (selector, params) { 2 'use strict'; 3 4 /*========================= 5 A little bit dirty but required part for IE8 and old FF support 6 ===========================*/ 7 if (!document.body.outerHTML && document.body.__defineGetter__) { 8 if (HTMLElement) { 9 var element = HTMLElement.prototype; 10 if (element.__defineGetter__) { 11 element.__defineGetter__('outerHTML', function () { return new XMLSerializer().serializeToString(this); }); 12 } 13 } 14 } 15 16 if (!window.getComputedStyle) { 17 window.getComputedStyle = function (el, pseudo) { 18 this.el = el; 19 this.getPropertyValue = function (prop) { 20 var re = /(\-([a-z]){1})/g; 21 if (prop === 'float') prop = 'styleFloat'; 22 if (re.test(prop)) { 23 prop = prop.replace(re, function () { 24 return arguments[2].toUpperCase(); 25 }); 26 } 27 return el.currentStyle[prop] ? el.currentStyle[prop] : null; 28 }; 29 return this; 30 }; 31 } 32 if (!Array.prototype.indexOf) { 33 Array.prototype.indexOf = function (obj, start) { 34 for (var i = (start || 0), j = this.length; i < j; i++) { 35 if (this[i] === obj) { return i; } 36 } 37 return -1; 38 }; 39 } 40 if (!document.querySelectorAll) { 41 if (!window.jQuery) return; 42 } 43 function $$(selector, context) { 44 if (document.querySelectorAll) 45 return (context || document).querySelectorAll(selector); 46 else 47 return jQuery(selector, context); 48 } 49 50 /*========================= 51 Check for correct selector 52 ===========================*/ 53 if (typeof selector === 'undefined') return; 54 55 if (!(selector.nodeType)) { 56 if ($$(selector).length === 0) return; 57 } 58 59 /*========================= 60 _this 61 ===========================*/ 62 var _this = this; 63 64 /*========================= 65 Default Flags and vars 66 ===========================*/ 67 _this.touches = { 68 start: 0, 69 startX: 0, 70 startY: 0, 71 current: 0, 72 currentX: 0, 73 currentY: 0, 74 diff: 0, 75 abs: 0 76 }; 77 _this.positions = { 78 start: 0, 79 abs: 0, 80 diff: 0, 81 current: 0 82 }; 83 _this.times = { 84 start: 0, 85 end: 0 86 }; 87 88 _this.id = (new Date()).getTime(); 89 _this.container = (selector.nodeType) ? selector : $$(selector)[0]; 90 _this.isTouched = false; 91 _this.isMoved = false; 92 _this.activeIndex = 0; 93 _this.centerIndex = 0; 94 _this.activeLoaderIndex = 0; 95 _this.activeLoopIndex = 0; 96 _this.previousIndex = null; 97 _this.velocity = 0; 98 _this.snapGrid = []; 99 _this.slidesGrid = []; 100 _this.imagesToLoad = []; 101 _this.imagesLoaded = 0; 102 _this.wrapperLeft = 0; 103 _this.wrapperRight = 0; 104 _this.wrapperTop = 0; 105 _this.wrapperBottom = 0; 106 _this.isAndroid = navigator.userAgent.toLowerCase().indexOf('android') >= 0; 107 var wrapper, slideSize, wrapperSize, direction, isScrolling, containerSize; 108 109 /*========================= 110 Default Parameters 111 ===========================*/ 112 var defaults = { 113 eventTarget: 'wrapper', // or 'container' 114 mode : 'horizontal', // or 'vertical' 115 touchRatio : 1, 116 speed : 300, 117 freeMode : false, 118 freeModeFluid : false, 119 momentumRatio: 1, 120 momentumBounce: true, 121 momentumBounceRatio: 1, 122 slidesPerView : 1, 123 slidesPerGroup : 1, 124 slidesPerViewFit: true, //Fit to slide when spv "auto" and slides larger than container 125 simulateTouch : true, 126 followFinger : true, 127 shortSwipes : true, 128 longSwipesRatio: 0.5, 129 moveStartThreshold: false, 130 onlyExternal : false, 131 createPagination : true, 132 pagination : false, 133 paginationElement: 'span', 134 paginationClickable: false, 135 paginationAsRange: true, 136 resistance : true, // or false or 100% 137 scrollContainer : false, 138 preventLinks : true, 139 preventLinksPropagation: false, 140 noSwiping : false, // or class 141 noSwipingClass : 'swiper-no-swiping', //:) 142 initialSlide: 0, 143 keyboardControl: false, 144 mousewheelControl : false, 145 mousewheelControlForceToAxis : false, 146 useCSS3Transforms : true, 147 // Autoplay 148 autoplay: false, 149 autoplayDisableOnInteraction: true, 150 autoplayStopOnLast: false, 151 //Loop mode 152 loop: false, 153 loopAdditionalSlides: 0, 154 // Round length values 155 roundLengths: false, 156 //Auto Height 157 calculateHeight: false, 158 //Apply CSS for width and/or height 159 cssWidthAndHeight: false, // or true or 'width' or 'height' 160 //Images Preloader 161 updateOnImagesReady : true, 162 //Form elements 163 releaseFormElements : true, 164 //Watch for active slide, useful when use effects on different slide states
165 watchActiveIndex: false, 166 //Slides Visibility Fit 167 visibilityFullFit : false, 168 //Slides Offset 169 offsetPxBefore : 0, 170 offsetPxAfter : 0, 171 offsetSlidesBefore : 0, 172 offsetSlidesAfter : 0, 173 centeredSlides: false, 174 //Queue callbacks 175 queueStartCallbacks : false, 176 queueEndCallbacks : false, 177 //Auto Resize 178 autoResize : true, 179 resizeReInit : false, 180 //DOMAnimation 181 DOMAnimation : true, 182 //Slides Loader 183 loader: { 184 slides: [], //array with slides 185 slidesHTMLType: 'inner', // or 'outer' 186 surroundGroups: 1, //keep preloaded slides groups around view 187 logic: 'reload', //or 'change' 188 loadAllSlides: false 189 }, 190 // One way swipes 191 swipeToPrev: true, 192 swipeToNext: true, 193 //Namespace 194 slideElement: 'div', 195 slideClass: 'swiper-slide', 196 slideActiveClass: 'swiper-slide-active', 197 slideVisibleClass: 'swiper-slide-visible', 198 slideDuplicateClass: 'swiper-slide-duplicate', 199 wrapperClass: 'swiper-wrapper', 200 paginationElementClass: 'swiper-pagination-switch', 201 paginationActiveClass: 'swiper-active-switch', 202 paginationVisibleClass: 'swiper-visible-switch' 203 }; 204 params = params || {}; 205 for (var prop in defaults) { 206 if (prop in params && typeof params[prop] === 'object') { 207 for (var subProp in defaults[prop]) { 208 if (! (subProp in params[prop])) { 209 params[prop][subProp] = defaults[prop][subProp]; 210 } 211 } 212 } 213 else if (! (prop in params)) { 214 params[prop] = defaults[prop]; 215 } 216 } 217 _this.params = params; 218 if (params.scrollContainer) { 219 params.freeMode = true; 220 params.freeModeFluid = true; 221 } 222 if (params.loop) { 223 params.resistance = '100%'; 224 } 225 var isH = params.mode === 'horizontal'; 226 227 /*========================= 228 Define Touch Events 229 ===========================*/ 230 var desktopEvents = ['mousedown', 'mousemove', 'mouseup']; 231 if (_this.browser.ie10) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp']; 232 if (_this.browser.ie11) desktopEvents = ['pointerdown', 'pointermove', 'pointerup']; 233 234 _this.touchEvents = { 235 touchStart : _this.support.touch || !params.simulateTouch ? 'touchstart' : desktopEvents[0], 236 touchMove : _this.support.touch || !params.simulateTouch ? 'touchmove' : desktopEvents[1], 237 touchEnd : _this.support.touch || !params.simulateTouch ? 'touchend' : desktopEvents[2] 238 }; 239 240 /*========================= 241 Wrapper 242 ===========================*/ 243 for (var i = _this.container.childNodes.length - 1; i >= 0; i--) { 244 if (_this.container.childNodes[i].className) { 245 var _wrapperClasses = _this.container.childNodes[i].className.split(/\s+/); 246 for (var j = 0; j < _wrapperClasses.length; j++) { 247 if (_wrapperClasses[j] === params.wrapperClass) { 248 wrapper = _this.container.childNodes[i]; 249 } 250 } 251 } 252 } 253 254 _this.wrapper = wrapper; 255 /*========================= 256 Slide API 257 ===========================*/ 258 _this._extendSwiperSlide = function (el) { 259 el.append = function () { 260 if (params.loop) { 261 el.insertAfter(_this.slides.length - _this.loopedSlides); 262 } 263 else { 264 _this.wrapper.appendChild(el); 265 _this.reInit(); 266 } 267 268 return el; 269 }; 270 el.prepend = function () { 271 if (params.loop) { 272 _this.wrapper.insertBefore(el, _this.slides[_this.loopedSlides]); 273 _this.removeLoopedSlides(); 274 _this.calcSlides(); 275 _this.createLoop(); 276 } 277 else { 278 _this.wrapper.insertBefore(el, _this.wrapper.firstChild); 279 } 280 _this.reInit(); 281 return el; 282 }; 283 el.insertAfter = function (index) { 284 if (typeof index === 'undefined') return false;
285 var beforeSlide; 286 287 if (params.loop) { 288 beforeSlide = _this.slides[index + 1 + _this.loopedSlides]; 289 if (beforeSlide) { 290 _this.wrapper.insertBefore(el, beforeSlide); 291 } 292 else { 293 _this.wrapper.appendChild(el); 294 } 295 _this.removeLoopedSlides(); 296 _this.calcSlides(); 297 _this.createLoop(); 298 } 299 else { 300 beforeSlide = _this.slides[index + 1]; 301 _this.wrapper.insertBefore(el, beforeSlide); 302 } 303 _this.reInit(); 304 return el; 305 }; 306 el.clone = function () { 307 return _this._extendSwiperSlide(el.cloneNode(true)); 308 }; 309 el.remove = function () { 310 _this.wrapper.removeChild(el); 311 _this.reInit(); 312 }; 313 el.html = function (html) { 314 if (typeof html === 'undefined') { 315 return el.innerHTML; 316 } 317 else { 318 el.innerHTML = html; 319 return el; 320 } 321 }; 322 el.index = function () { 323 var index; 324 for (var i = _this.slides.length - 1; i >= 0; i--) { 325 if (el === _this.slides[i]) index = i; 326 } 327 return index; 328 }; 329 el.isActive = function () { 330 if (el.index() === _this.activeIndex) return true; 331 else return false; 332 }; 333 if (!el.swiperSlideDataStorage) el.swiperSlideDataStorage = {}; 334 el.getData = function (name) { 335 return el.swiperSlideDataStorage[name]; 336 }; 337 el.setData = function (name, value) { 338 el.swiperSlideDataStorage[name] = value; 339 return el; 340 }; 341 el.data = function (name, value) { 342 if (typeof value === 'undefined') { 343 return el.getAttribute('data-' + name); 344 } 345 else { 346 el.setAttribute('data-' + name, value); 347 return el; 348 } 349 }; 350 el.getWidth = function (outer, round) { 351 return _this.h.getWidth(el, outer, round); 352 }; 353 el.getHeight = function (outer, round) { 354 return _this.h.getHeight(el, outer, round); 355 }; 356 el.getOffset = function () { 357 return _this.h.getOffset(el); 358 }; 359 return el; 360 }; 361 362 //Calculate information about number of slides 363 _this.calcSlides = function (forceCalcSlides) { 364 var oldNumber = _this.slides ? _this.slides.length : false; 365 _this.slides = []; 366 _this.displaySlides = []; 367 for (var i = 0; i < _this.wrapper.childNodes.length; i++) { 368 if (_this.wrapper.childNodes[i].className) { 369 var _className = _this.wrapper.childNodes[i].className; 370 var _slideClasses = _className.split(/\s+/); 371 for (var j = 0; j < _slideClasses.length; j++) { 372 if (_slideClasses[j] === params.slideClass) { 373 _this.slides.push(_this.wrapper.childNodes[i]); 374 } 375 } 376 } 377 } 378 for (i = _this.slides.length - 1; i >= 0; i--) { 379 _this._extendSwiperSlide(_this.slides[i]); 380 } 381 if (oldNumber === false) return; 382 if (oldNumber !== _this.slides.length || forceCalcSlides) { 383 384 // Number of slides has been changed 385 removeSlideEvents(); 386 addSlideEvents(); 387 _this.updateActiveSlide(); 388 if (_this.params.pagination) _this.createPagination(); 389 _this.callPlugins('numberOfSlidesChanged'); 390 } 391 }; 392 393 //Create Slide 394 _this.createSlide = function (html, slideClassList, el) { 395 slideClassList = slideClassList || _this.params.slideClass; 396 el = el || params.slideElement; 397 var newSlide = document.createElement(el); 398 newSlide.innerHTML = html || ''; 399 newSlide.className = slideClassList; 400 return _this._extendSwiperSlide(newSlide); 401 }; 402 403 //Append Slide 404 _this.appendSlide = function (html, slideClassList, el) { 405 if (!html) return; 406 if (html.nodeType) { 407 return _this._extendSwiperSlide(html).append(); 408 } 409 else { 410 return _this.createSlide(html, slideClassList, el).append(); 411 } 412 }; 413 _this.prependSlide = function (html, slideClassList, el) { 414 if (!html) return; 415 if (html.nodeType) { 416 return _this._extendSwiperSlide(html).prepend(); 417 } 418 else { 419 return _this.createSlide(html, slideClassList, el).prepend(); 420 } 421 }; 422 _this.insertSlideAfter = function (index, html, slideClassList, el) { 423 if (typeof index === 'undefined') return false;
424 if (html.nodeType) { 425 return _this._extendSwiperSlide(html).insertAfter(index); 426 } 427 else { 428 return _this.createSlide(html, slideClassList, el).insertAfter(index); 429 } 430 }; 431 _this.removeSlide = function (index) { 432 if (_this.slides[index]) { 433 if (params.loop) { 434 if (!_this.slides[index + _this.loopedSlides]) return false; 435 _this.slides[index + _this.loopedSlides].remove(); 436 _this.removeLoopedSlides(); 437 _this.calcSlides(); 438 _this.createLoop(); 439 } 440 else _this.slides[index].remove(); 441 return true; 442 } 443 else return false; 444 }; 445 _this.removeLastSlide = function () { 446 if (_this.slides.length > 0) { 447 if (params.loop) { 448 _this.slides[_this.slides.length - 1 - _this.loopedSlides].remove(); 449 _this.removeLoopedSlides(); 450 _this.calcSlides(); 451 _this.createLoop(); 452 } 453 else _this.slides[_this.slides.length - 1].remove(); 454 return true; 455 } 456 else { 457 return false; 458 } 459 }; 460 _this.removeAllSlides = function () { 461 var num = _this.slides.length; 462 for (var i = _this.slides.length - 1; i >= 0; i--) { 463 _this.slides[i].remove(); 464 if (i === num - 1) { 465 _this.setWrapperTranslate(0); 466 } 467 } 468 };
469 _this.getSlide = function (index) { 470 return _this.slides[index]; 471 }; 472 _this.getLastSlide = function () { 473 return _this.slides[_this.slides.length - 1]; 474 }; 475 _this.getFirstSlide = function () { 476 return _this.slides[0]; 477 }; 478 479 //Currently Active Slide 480 _this.activeSlide = function () { 481 return _this.slides[_this.activeIndex]; 482 }; 483 484 /*========================= 485 Wrapper for Callbacks : Allows additive callbacks via function arrays 486 ===========================*/ 487 _this.fireCallback = function () { 488 var callback = arguments[0]; 489 if (Object.prototype.toString.call(callback) === '[object Array]') { 490 for (var i = 0; i < callback.length; i++) { 491 if (typeof callback[i] === 'function') { 492 callback[i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]); 493 } 494 } 495 } else if (Object.prototype.toString.call(callback) === '[object String]') { 496 if (params['on' + callback]) _this.fireCallback(params['on' + callback], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]); 497 } else { 498 callback(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]); 499 } 500 }; 501 function isArray(obj) { 502 if (Object.prototype.toString.apply(obj) === '[object Array]') return true; 503 return false; 504 } 505 506 /** 507 * Allows user to add callbacks, rather than replace them 508 * @param callback 509 * @param func 510 * @return {*} 511 */ 512 _this.addCallback = function (callback, func) { 513 var _this = this, tempFunc; 514 if (_this.params['on' + callback]) { 515 if (isArray(this.params['on' + callback])) { 516 return this.params['on' + callback].push(func); 517 } else if (typeof this.params['on' + callback] === 'function') { 518 tempFunc = this.params['on' + callback]; 519 this.params['on' + callback] = []; 520 this.params['on' + callback].push(tempFunc); 521 return this.params['on' + callback].push(func); 522 } 523 } else { 524 this.params['on' + callback] = []; 525 return this.params['on' + callback].push(func); 526 } 527 }; 528 _this.removeCallbacks = function (callback) { 529 if (_this.params['on' + callback]) { 530 _this.params['on' + callback] = null; 531 } 532 }; 533 534 /*========================= 535 Plugins API 536 ===========================*/ 537 var _plugins = []; 538 for (var plugin in _this.plugins) { 539 if (params[plugin]) { 540 var p = _this.plugins[plugin](_this, params[plugin]); 541 if (p) _plugins.push(p); 542 } 543 } 544 _this.callPlugins = function (method, args) { 545 if (!args) args = {}; 546 for (var i = 0; i < _plugins.length; i++) { 547 if (method in _plugins[i]) { 548 _plugins[i][method](args); 549 } 550 } 551 }; 552 553 /*========================= 554 Windows Phone 8 Fix 555 ===========================*/ 556 if ((_this.browser.ie10 || _this.browser.ie11) && !params.onlyExternal) { 557 _this.wrapper.classList.add('swiper-wp8-' + (isH ? 'horizontal' : 'vertical')); 558 } 559 560 /*========================= 561 Free Mode Class 562 ===========================*/ 563 if (params.freeMode) { 564 _this.container.className += ' swiper-free-mode'; 565 } 566 567 /*================================================== 568 Init/Re-init/Resize Fix 569 ====================================================*/ 570 _this.initialized = false; 571 _this.init = function (force, forceCalcSlides) { 572 var _width = _this.h.getWidth(_this.container, false, params.roundLengths); 573 var _height = _this.h.getHeight(_this.container, false, params.roundLengths); 574 if (_width === _this.width && _height === _this.height && !force) return; 575 576 _this.width = _width; 577 _this.height = _height; 578 579 var slideWidth, slideHeight, slideMaxHeight, wrapperWidth, wrapperHeight, slideLeft; 580 var i; // loop index variable to avoid JSHint W004 / W038 581 containerSize = isH ? _width : _height; 582 var wrapper = _this.wrapper; 583 584 if (force) { 585 _this.calcSlides(forceCalcSlides); 586 } 587 588 if (params.slidesPerView === 'auto') { 589 //Auto mode 590 var slidesWidth = 0; 591 var slidesHeight = 0; 592 593 //Unset Styles 594 if (params.slidesOffset > 0) { 595 wrapper.style.paddingLeft = ''; 596 wrapper.style.paddingRight = ''; 597 wrapper.style.paddingTop = ''; 598 wrapper.style.paddingBottom = ''; 599 } 600 wrapper.style.width = ''; 601 wrapper.style.height = ''; 602 if (params.offsetPxBefore > 0) { 603 if (isH) _this.wrapperLeft = params.offsetPxBefore; 604 else _this.wrapperTop = params.offsetPxBefore; 605 } 606 if (params.offsetPxAfter > 0) { 607 if (isH) _this.wrapperRight = params.offsetPxAfter; 608 else _this.wrapperBottom = params.offsetPxAfter; 609 } 610 611 if (params.centeredSlides) { 612 if (isH) { 613 _this.wrapperLeft = (containerSize - this.slides[0].getWidth(true, params.roundLengths)) / 2; 614 _this.wrapperRight = (containerSize - _this.slides[_this.slides.length - 1].getWidth(true, params.roundLengths)) / 2; 615 } 616 else { 617 _this.wrapperTop = (containerSize - _this.slides[0].getHeight(true, params.roundLengths)) / 2; 618 _this.wrapperBottom = (containerSize - _this.slides[_this.slides.length - 1].getHeight(true, params.roundLengths)) / 2; 619 } 620 } 621 622 if (isH) { 623 if (_this.wrapperLeft >= 0) wrapper.style.paddingLeft = _this.wrapperLeft + 'px'; 624 if (_this.wrapperRight >= 0) wrapper.style.paddingRight = _this.wrapperRight + 'px'; 625 } 626 else { 627 if (_this.wrapperTop >= 0) wrapper.style.paddingTop = _this.wrapperTop + 'px'; 628 if (_this.wrapperBottom >= 0) wrapper.style.paddingBottom = _this.wrapperBottom + 'px'; 629 } 630 slideLeft = 0; 631 var centeredSlideLeft = 0; 632 _this.snapGrid = []; 633 _this.slidesGrid = []; 634 635 slideMaxHeight = 0; 636 for (i = 0; i < _this.slides.length; i++) { 637 slideWidth = _this.slides[i].getWidth(true, params.roundLengths); 638 slideHeight = _this.slides[i].getHeight(true, params.roundLengths); 639 if (params.calculateHeight) { 640 slideMaxHeight = Math.max(slideMaxHeight, slideHeight); 641 } 642 var _slideSize = isH ? slideWidth : slideHeight; 643 if (params.centeredSlides) { 644 var nextSlideWidth = i === _this.slides.length - 1 ? 0 : _this.slides[i + 1].getWidth(true, params.roundLengths); 645 var nextSlideHeight = i === _this.slides.length - 1 ? 0 : _this.slides[i + 1].getHeight(true, params.roundLengths); 646 var nextSlideSize = isH ? nextSlideWidth : nextSlideHeight; 647 if (_slideSize > containerSize) { 648 if (params.slidesPerViewFit) { 649 _this.snapGrid.push(slideLeft + _this.wrapperLeft); 650 _this.snapGrid.push(slideLeft + _slideSize - containerSize + _this.wrapperLeft); 651 } 652 else { 653 for (var j = 0; j <= Math.floor(_slideSize / (containerSize + _this.wrapperLeft)); j++) { 654 if (j === 0) _this.snapGrid.push(slideLeft + _this.wrapperLeft); 655 else _this.snapGrid.push(slideLeft + _this.wrapperLeft + containerSize * j); 656 } 657 } 658 _this.slidesGrid.push(slideLeft + _this.wrapperLeft); 659 } 660 else { 661 _this.snapGrid.push(centeredSlideLeft); 662 _this.slidesGrid.push(centeredSlideLeft); 663 } 664 centeredSlideLeft += _slideSize / 2 + nextSlideSize / 2; 665 } 666 else { 667 if (_slideSize > containerSize) { 668 if (params.slidesPerViewFit) { 669 _this.snapGrid.push(slideLeft); 670 _this.snapGrid.push(slideLeft + _slideSize - containerSize); 671 } 672 else { 673 if (containerSize !== 0) { 674 for (var k = 0; k <= Math.floor(_slideSize / containerSize); k++) { 675 _this.snapGrid.push(slideLeft + containerSize * k); 676 } 677 } 678 else { 679 _this.snapGrid.push(slideLeft); 680 } 681 } 682 683 } 684 else { 685 _this.snapGrid.push(slideLeft); 686 } 687 _this.slidesGrid.push(slideLeft); 688 } 689 690 slideLeft += _slideSize; 691 692 slidesWidth += slideWidth; 693 slidesHeight += slideHeight; 694 } 695 if (params.calculateHeight) _this.height = slideMaxHeight; 696 if (isH) { 697 wrapperSize = slidesWidth + _this.wrapperRight + _this.wrapperLeft; 698 if (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'height') { 699 wrapper.style.width = (slidesWidth) + 'px'; 700 } 701 if (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'width') { 702 wrapper.style.height = (_this.height) + 'px'; 703 } 704 } 705 else { 706 if (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'height') { 707 wrapper.style.width = (_this.width) + 'px'; 708 } 709 if (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'width') { 710 wrapper.style.height = (slidesHeight) + 'px'; 711 } 712 wrapperSize = slidesHeight + _this.wrapperTop + _this.wrapperBottom; 713 } 714 715 } 716 else if (params.scrollContainer) { 717 //Scroll Container 718 wrapper.style.width = ''; 719 wrapper.style.height = '';
720 wrapperWidth = _this.slides[0].getWidth(true, params.roundLengths); 721 wrapperHeight = _this.slides[0].getHeight(true, params.roundLengths); 722 wrapperSize = isH ? wrapperWidth : wrapperHeight; 723 wrapper.style.width = wrapperWidth + 'px'; 724 wrapper.style.height = wrapperHeight + 'px'; 725 slideSize = isH ? wrapperWidth : wrapperHeight; 726 727 } 728 else { 729 //For usual slides 730 if (params.calculateHeight) { 731 slideMaxHeight = 0; 732 wrapperHeight = 0; 733 //ResetWrapperSize 734 if (!isH) _this.container.style.height = ''; 735 wrapper.style.height = ''; 736 737 for (i = 0; i < _this.slides.length; i++) { 738 //ResetSlideSize 739 _this.slides[i].style.height = ''; 740 slideMaxHeight = Math.max(_this.slides[i].getHeight(true), slideMaxHeight); 741 if (!isH) wrapperHeight += _this.slides[i].getHeight(true); 742 } 743 slideHeight = slideMaxHeight; 744 _this.height = slideHeight; 745 746 if (isH) wrapperHeight = slideHeight; 747 else { 748 containerSize = slideHeight; 749 _this.container.style.height = containerSize + 'px'; 750 } 751 } 752 else { 753 slideHeight = isH ? _this.height : _this.height / params.slidesPerView; 754 if (params.roundLengths) slideHeight = Math.ceil(slideHeight); 755 wrapperHeight = isH ? _this.height : _this.slides.length * slideHeight; 756 } 757 slideWidth = isH ? _this.width / params.slidesPerView : _this.width; 758 if (params.roundLengths) slideWidth = Math.ceil(slideWidth); 759 wrapperWidth = isH ? _this.slides.length * slideWidth : _this.width; 760 slideSize = isH ? slideWidth : slideHeight; 761 762 if (params.offsetSlidesBefore > 0) { 763 if (isH) _this.wrapperLeft = slideSize * params.offsetSlidesBefore; 764 else _this.wrapperTop = slideSize * params.offsetSlidesBefore; 765 } 766 if (params.offsetSlidesAfter > 0) { 767 if (isH) _this.wrapperRight = slideSize * params.offsetSlidesAfter; 768 else _this.wrapperBottom = slideSize * params.offsetSlidesAfter; 769 } 770 if (params.offsetPxBefore > 0) { 771 if (isH) _this.wrapperLeft = params.offsetPxBefore; 772 else _this.wrapperTop = params.offsetPxBefore; 773 } 774 if (params.offsetPxAfter > 0) { 775 if (isH) _this.wrapperRight = params.offsetPxAfter; 776 else _this.wrapperBottom = params.offsetPxAfter; 777 } 778 if (params.centeredSlides) { 779 if (isH) { 780 _this.wrapperLeft = (containerSize - slideSize) / 2; 781 _this.wrapperRight = (containerSize - slideSize) / 2; 782 } 783 else { 784 _this.wrapperTop = (containerSize - slideSize) / 2; 785 _this.wrapperBottom = (containerSize - slideSize) / 2; 786 } 787 } 788 if (isH) { 789 if (_this.wrapperLeft > 0) wrapper.style.paddingLeft = _this.wrapperLeft + 'px'; 790 if (_this.wrapperRight > 0) wrapper.style.paddingRight = _this.wrapperRight + 'px'; 791 } 792 else { 793 if (_this.wrapperTop > 0) wrapper.style.paddingTop = _this.wrapperTop + 'px'; 794 if (_this.wrapperBottom > 0) wrapper.style.paddingBottom = _this.wrapperBottom + 'px'; 795 } 796 797 wrapperSize = isH ? wrapperWidth + _this.wrapperRight + _this.wrapperLeft : wrapperHeight + _this.wrapperTop + _this.wrapperBottom; 798 if (parseFloat(wrapperWidth) > 0 && (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'height')) { 799 wrapper.style.width = wrapperWidth + 'px'; 800 } 801 if (parseFloat(wrapperHeight) > 0 && (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'width')) { 802 wrapper.style.height = wrapperHeight + 'px'; 803 } 804 slideLeft = 0; 805 _this.snapGrid = []; 806 _this.slidesGrid = []; 807 for (i = 0; i < _this.slides.length; i++) { 808 _this.snapGrid.push(slideLeft); 809 _this.slidesGrid.push(slideLeft); 810 slideLeft += slideSize; 811 if (parseFloat(slideWidth) > 0 && (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'height')) { 812 _this.slides[i].style.width = slideWidth + 'px'; 813 } 814 if (parseFloat(slideHeight) > 0 && (!params.cssWidthAndHeight || params.cssWidthAndHeight === 'width')) { 815 _this.slides[i].style.height = slideHeight + 'px'; 816 } 817 } 818 819 } 820 821 if (!_this.initialized) { 822 _this.callPlugins('onFirstInit'); 823 if (params.onFirstInit) _this.fireCallback(params.onFirstInit, _this); 824 } 825 else { 826 _this.callPlugins('onInit'); 827 if (params.onInit) _this.fireCallback(params.onInit, _this); 828 } 829 _this.initialized = true; 830 }; 831 832 _this.reInit = function (forceCalcSlides) { 833 _this.init(true, forceCalcSlides); 834 }; 835 836 _this.resizeFix = function (reInit) { 837 _this.callPlugins('beforeResizeFix'); 838 839 _this.init(params.resizeReInit || reInit); 840 841 // swipe to active slide in fixed mode 842 if (!params.freeMode) { 843 _this.swipeTo((params.loop ? _this.activeLoopIndex : _this.activeIndex), 0, false); 844 // Fix autoplay 845 if (params.autoplay) { 846 if (_this.support.transitions && typeof autoplayTimeoutId !== 'undefined') { 847 if (typeof autoplayTimeoutId !== 'undefined') { 848 clearTimeout(autoplayTimeoutId); 849 autoplayTimeoutId = undefined; 850 _this.startAutoplay(); 851 } 852 } 853 else { 854 if (typeof autoplayIntervalId !== 'undefined') { 855 clearInterval(autoplayIntervalId); 856 autoplayIntervalId = undefined; 857 _this.startAutoplay(); 858 } 859 } 860 } 861 } 862 // move wrapper to the beginning in free mode 863 else if (_this.getWrapperTranslate() < -maxWrapperPosition()) { 864 _this.setWrapperTransition(0);
865 _this.setWrapperTranslate(-maxWrapperPosition()); 866 } 867 868 _this.callPlugins('afterResizeFix'); 869 }; 870 871 /*========================================== 872 Max and Min Positions 873 ============================================*/ 874 function maxWrapperPosition() { 875 var a = (wrapperSize - containerSize); 876 if (params.freeMode) { 877 a = wrapperSize - containerSize; 878 } 879 // if (params.loop) a -= containerSize; 880 if (params.slidesPerView > _this.slides.length && !params.centeredSlides) { 881 a = 0; 882 } 883 if (a < 0) a = 0; 884 return a; 885 } 886 887 /*========================================== 888 Event Listeners 889 ============================================*/ 890 function initEvents() { 891 var bind = _this.h.addEventListener; 892 var eventTarget = params.eventTarget === 'wrapper' ? _this.wrapper : _this.container; 893 //Touch Events 894 if (! (_this.browser.ie10 || _this.browser.ie11)) { 895 if (_this.support.touch) { 896 bind(eventTarget, 'touchstart', onTouchStart); 897 bind(eventTarget, 'touchmove', onTouchMove); 898 bind(eventTarget, 'touchend', onTouchEnd); 899 } 900 if (params.simulateTouch) { 901 bind(eventTarget, 'mousedown', onTouchStart); 902 bind(document, 'mousemove', onTouchMove); 903 bind(document, 'mouseup', onTouchEnd); 904 } 905 } 906 else { 907 bind(eventTarget, _this.touchEvents.touchStart, onTouchStart); 908 bind(document, _this.touchEvents.touchMove, onTouchMove); 909 bind(document, _this.touchEvents.touchEnd, onTouchEnd); 910 } 911 912 //Resize Event 913 if (params.autoResize) { 914 bind(window, 'resize', _this.resizeFix); 915 } 916 //Slide Events 917 addSlideEvents(); 918 //Mousewheel 919 _this._wheelEvent = false; 920 if (params.mousewheelControl) { 921 if (document.onmousewheel !== undefined) { 922 _this._wheelEvent = 'mousewheel'; 923 } 924 if (!_this._wheelEvent) { 925 try { 926 new WheelEvent('wheel'); 927 _this._wheelEvent = 'wheel'; 928 } catch (e) {} 929 } 930 if (!_this._wheelEvent) { 931 _this._wheelEvent = 'DOMMouseScroll'; 932 } 933 if (_this._wheelEvent) { 934 bind(_this.container, _this._wheelEvent, handleMousewheel); 935 } 936 } 937 938 //Keyboard 939 function _loadImage(img) { 940 var image, src; 941 var onReady = function () { 942 if (typeof _this === 'undefined' || _this === null) return; 943 if (_this.imagesLoaded !== undefined) _this.imagesLoaded++; 944 if (_this.imagesLoaded === _this.imagesToLoad.length) { 945 _this.reInit(); 946 if (params.onImagesReady) _this.fireCallback(params.onImagesReady, _this); 947 } 948 }; 949 950 if (!img.complete) { 951 src = (img.currentSrc || img.getAttribute('src')); 952 if (src) { 953 image = new Image(); 954 image.onload = onReady; 955 image.onerror = onReady; 956 image.src = src; 957 } else { 958 onReady(); 959 } 960 961 } else {//image already loaded... 962 onReady(); 963 } 964 } 965 966 if (params.keyboardControl) { 967 bind(document, 'keydown', handleKeyboardKeys); 968 } 969 if (params.updateOnImagesReady) { 970 _this.imagesToLoad = $$('img', _this.container); 971 972 for (var i = 0; i < _this.imagesToLoad.length; i++) { 973 _loadImage(_this.imagesToLoad[i]); 974 } 975 } 976 } 977 978 //Remove Event Listeners 979 _this.destroy = function (removeStyles) { 980 var unbind = _this.h.removeEventListener; 981 var eventTarget = params.eventTarget === 'wrapper' ? _this.wrapper : _this.container; 982 //Touch Events 983 if (! (_this.browser.ie10 || _this.browser.ie11)) { 984 if (_this.support.touch) { 985 unbind(eventTarget, 'touchstart', onTouchStart); 986 unbind(eventTarget, 'touchmove', onTouchMove); 987 unbind(eventTarget, 'touchend', onTouchEnd); 988 } 989 if (params.simulateTouch) { 990 unbind(eventTarget, 'mousedown', onTouchStart); 991 unbind(document, 'mousemove', onTouchMove); 992 unbind(document, 'mouseup', onTouchEnd); 993 } 994 } 995 else { 996 unbind(eventTarget, _this.touchEvents.touchStart, onTouchStart); 997 unbind(document, _this.touchEvents.touchMove, onTouchMove); 998 unbind(document, _this.touchEvents.touchEnd, onTouchEnd); 999 } 1000 1001 //Resize Event 1002 if (params.autoResize) { 1003 unbind(window, 'resize', _this.resizeFix); 1004 } 1005 1006 //Init Slide Events 1007 removeSlideEvents(); 1008 1009 //Pagination 1010 if (params.paginationClickable) { 1011 removePaginationEvents(); 1012 } 1013 1014 //Mousewheel 1015 if (params.mousewheelControl && _this._wheelEvent) { 1016 unbind(_this.container, _this._wheelEvent, handleMousewheel); 1017 } 1018 1019 //Keyboard 1020 if (params.keyboardControl) { 1021 unbind(document, 'keydown', handleKeyboardKeys); 1022 } 1023 1024 //Stop autoplay 1025 if (params.autoplay) { 1026 _this.stopAutoplay(); 1027 } 1028 // Remove styles 1029 if (removeStyles) { 1030 _this.wrapper.removeAttribute('style'); 1031 for (var i = 0; i < _this.slides.length; i++) { 1032 _this.slides[i].removeAttribute('style'); 1033 } 1034 } 1035 // Plugins 1036 _this.callPlugins('onDestroy'); 1037 1038 // Check jQuery/Zepto data 1039 if (window.jQuery && window.jQuery(_this.container).data('swiper')) { 1040 window.jQuery(_this.container).removeData('swiper'); 1041 } 1042 if (window.Zepto && window.Zepto(_this.container).data('swiper')) { 1043 window.Zepto(_this.container).removeData('swiper'); 1044 } 1045 1046 //Destroy variable 1047 _this = null; 1048 }; 1049 1050 function addSlideEvents() { 1051 var bind = _this.h.addEventListener, 1052 i; 1053 1054 //Prevent Links Events 1055 if (params.preventLinks) { 1056 var links = $$('a', _this.container); 1057 for (i = 0; i < links.length; i++) { 1058 bind(links[i], 'click', preventClick); 1059 } 1060 } 1061 //Release Form Elements 1062 if (params.releaseFormElements) { 1063 var formElements = $$('input, textarea, select', _this.container); 1064 for (i = 0; i < formElements.length; i++) { 1065 bind(formElements[i], _this.touchEvents.touchStart, releaseForms, true); 1066 if (_this.support.touch && params.simulateTouch) { 1067 bind(formElements[i], 'mousedown', releaseForms, true); 1068 } 1069 } 1070 } 1071 1072 //Slide Clicks & Touches 1073 if (params.onSlideClick) { 1074 for (i = 0; i < _this.slides.length; i++) { 1075 bind(_this.slides[i], 'click', slideClick); 1076 } 1077 } 1078 if (params.onSlideTouch) { 1079 for (i = 0; i < _this.slides.length; i++) { 1080 bind(_this.slides[i], _this.touchEvents.touchStart, slideTouch); 1081 } 1082 } 1083 } 1084 function removeSlideEvents() { 1085 var unbind = _this.h.removeEventListener, 1086 i; 1087 1088 //Slide Clicks & Touches 1089 if (params.onSlideClick) { 1090 for (i = 0; i < _this.slides.length; i++) { 1091 unbind(_this.slides[i], 'click', slideClick); 1092 } 1093 } 1094 if (params.onSlideTouch) { 1095 for (i = 0; i < _this.slides.length; i++) { 1096 unbind(_this.slides[i], _this.touchEvents.touchStart, slideTouch); 1097 } 1098 } 1099 //Release Form Elements 1100 if (params.releaseFormElements) { 1101 var formElements = $$('input, textarea, select', _this.container); 1102 for (i = 0; i < formElements.length; i++) { 1103 unbind(formElements[i], _this.touchEvents.touchStart, releaseForms, true); 1104 if (_this.support.touch && params.simulateTouch) { 1105 unbind(formElements[i], 'mousedown', releaseForms, true); 1106 } 1107 } 1108 } 1109 //Prevent Links Events 1110 if (params.preventLinks) { 1111 var links = $$('a', _this.container); 1112 for (i = 0; i < links.length; i++) { 1113 unbind(links[i], 'click', preventClick); 1114 } 1115 } 1116 } 1117 /*========================================== 1118 Keyboard Control 1119 ============================================*/ 1120 function handleKeyboardKeys(e) { 1121 var kc = e.keyCode || e.charCode; 1122 if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) return; 1123 if (kc === 37 || kc === 39 || kc === 38 || kc === 40) { 1124 var inView = false;
1125 //Check that swiper should be inside of visible area of window 1126 var swiperOffset = _this.h.getOffset(_this.container); 1127 var scrollLeft = _this.h.windowScroll().left; 1128 var scrollTop = _this.h.windowScroll().top; 1129 var windowWidth = _this.h.windowWidth(); 1130 var windowHeight = _this.h.windowHeight(); 1131 var swiperCoord = [ 1132 [swiperOffset.left, swiperOffset.top], 1133 [swiperOffset.left + _this.width, swiperOffset.top], 1134 [swiperOffset.left, swiperOffset.top + _this.height], 1135 [swiperOffset.left + _this.width, swiperOffset.top + _this.height] 1136 ]; 1137 for (var i = 0; i < swiperCoord.length; i++) { 1138 var point = swiperCoord[i]; 1139 if ( 1140 point[0] >= scrollLeft && point[0] <= scrollLeft + windowWidth && 1141 point[1] >= scrollTop && point[1] <= scrollTop + windowHeight 1142 ) { 1143 inView = true; 1144 } 1145 1146 } 1147 if (!inView) return; 1148 } 1149 if (isH) { 1150 if (kc === 37 || kc === 39) { 1151 if (e.preventDefault) e.preventDefault(); 1152 else e.returnValue = false; 1153 } 1154 if (kc === 39) _this.swipeNext(); 1155 if (kc === 37) _this.swipePrev(); 1156 } 1157 else { 1158 if (kc === 38 || kc === 40) { 1159 if (e.preventDefault) e.preventDefault(); 1160 else e.returnValue = false; 1161 } 1162 if (kc === 40) _this.swipeNext(); 1163 if (kc === 38) _this.swipePrev(); 1164 } 1165 } 1166 1167 _this.disableKeyboardControl = function () { 1168 params.keyboardControl = false; 1169 _this.h.removeEventListener(document, 'keydown', handleKeyboardKeys); 1170 }; 1171 1172 _this.enableKeyboardControl = function () { 1173 params.keyboardControl = true; 1174 _this.h.addEventListener(document, 'keydown', handleKeyboardKeys); 1175 }; 1176 1177 /*========================================== 1178 Mousewheel Control 1179 ============================================*/ 1180 var lastScrollTime = (new Date()).getTime(); 1181 function handleMousewheel(e) { 1182 var we = _this._wheelEvent; 1183 var delta = 0; 1184 1185 //Opera & IE 1186 if (e.detail) delta = -e.detail; 1187 //WebKits 1188 else if (we === 'mousewheel') { 1189 if (params.mousewheelControlForceToAxis) { 1190 if (isH) { 1191 if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX; 1192 else return; 1193 } 1194 else { 1195 if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY; 1196 else return; 1197 } 1198 } 1199 else { 1200 delta = e.wheelDelta; 1201 } 1202 } 1203 //Old FireFox 1204 else if (we === 'DOMMouseScroll') delta = -e.detail; 1205 //New FireFox 1206 else if (we === 'wheel') { 1207 if (params.mousewheelControlForceToAxis) { 1208 if (isH) { 1209 if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX; 1210 else return; 1211 } 1212 else { 1213 if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY; 1214 else return; 1215 } 1216 } 1217 else { 1218 delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX : - e.deltaY; 1219 } 1220 } 1221 1222 if (!params.freeMode) { 1223 if ((new Date()).getTime() - lastScrollTime > 60) { 1224 if (delta < 0) _this.swipeNext(); 1225 else _this.swipePrev(); 1226 } 1227 lastScrollTime = (new Date()).getTime(); 1228 1229 } 1230 else { 1231 //Freemode or scrollContainer: 1232 var position = _this.getWrapperTranslate() + delta; 1233 1234 if (position > 0) position = 0; 1235 if (position < -maxWrapperPosition()) position = -maxWrapperPosition(); 1236 1237 _this.setWrapperTransition(0); 1238 _this.setWrapperTranslate(position); 1239 _this.updateActiveSlide(position); 1240 1241 // Return page scroll on edge positions 1242 if (position === 0 || position === -maxWrapperPosition()) return; 1243 } 1244 if (params.autoplay) _this.stopAutoplay(true); 1245 1246 if (e.preventDefault) e.preventDefault(); 1247 else e.returnValue = false;
1248 return false; 1249 } 1250 _this.disableMousewheelControl = function () { 1251 if (!_this._wheelEvent) return false; 1252 params.mousewheelControl = false; 1253 _this.h.removeEventListener(_this.container, _this._wheelEvent, handleMousewheel); 1254 return true; 1255 }; 1256 1257 _this.enableMousewheelControl = function () { 1258 if (!_this._wheelEvent) return false; 1259 params.mousewheelControl = true; 1260 _this.h.addEventListener(_this.container, _this._wheelEvent, handleMousewheel); 1261 return true; 1262 }; 1263 1264 /*========================= 1265 Grab Cursor 1266 ===========================*/ 1267 if (params.grabCursor) { 1268 var containerStyle = _this.container.style; 1269 containerStyle.cursor = 'move'; 1270 containerStyle.cursor = 'grab'; 1271 containerStyle.cursor = '-moz-grab'; 1272 containerStyle.cursor = '-webkit-grab'; 1273 } 1274 1275 /*========================= 1276 Slides Events Handlers 1277 ===========================*/ 1278 1279 _this.allowSlideClick = true; 1280 function slideClick(event) { 1281 if (_this.allowSlideClick) { 1282 setClickedSlide(event); 1283 _this.fireCallback(params.onSlideClick, _this, event); 1284 } 1285 } 1286 1287 function slideTouch(event) { 1288 setClickedSlide(event); 1289 _this.fireCallback(params.onSlideTouch, _this, event); 1290 } 1291 1292 function setClickedSlide(event) { 1293 1294 // IE 6-8 support 1295 if (!event.currentTarget) { 1296 var element = event.srcElement; 1297 do { 1298 if (element.className.indexOf(params.slideClass) > -1) { 1299 break; 1300 } 1301 element = element.parentNode; 1302 } while (element); 1303 _this.clickedSlide = element; 1304 } 1305 else { 1306 _this.clickedSlide = event.currentTarget; 1307 } 1308 1309 _this.clickedSlideIndex = _this.slides.indexOf(_this.clickedSlide); 1310 _this.clickedSlideLoopIndex = _this.clickedSlideIndex - (_this.loopedSlides || 0); 1311 } 1312 1313 _this.allowLinks = true; 1314 function preventClick(e) { 1315 if (!_this.allowLinks) { 1316 if (e.preventDefault) e.preventDefault(); 1317 else e.returnValue = false; 1318 if (params.preventLinksPropagation && 'stopPropagation' in e) { 1319 e.stopPropagation(); 1320 } 1321 return false; 1322 } 1323 } 1324 function releaseForms(e) { 1325 if (e.stopPropagation) e.stopPropagation(); 1326 else e.returnValue = false; 1327 return false; 1328 1329 } 1330 1331 /*================================================== 1332 Event Handlers 1333 ====================================================*/ 1334 var isTouchEvent = false; 1335 var allowThresholdMove; 1336 var allowMomentumBounce = true; 1337 function onTouchStart(event) { 1338 if (params.preventLinks) _this.allowLinks = true; 1339 //Exit if slider is already was touched 1340 if (_this.isTouched || params.onlyExternal) { 1341 return false; 1342 } 1343 1344 // Blur active elements 1345 var eventTarget = event.target || event.srcElement; 1346 if (document.activeElement && document.activeElement !== document.body) { 1347 if (document.activeElement !== eventTarget) document.activeElement.blur(); 1348 } 1349 1350 // Form tag names 1351 var formTagNames = ('input select textarea').split(' '); 1352 1353 // Check for no swiping 1354 if (params.noSwiping && (eventTarget) && noSwipingSlide(eventTarget)) return false; 1355 allowMomentumBounce = false; 1356 //Check For Nested Swipers 1357 _this.isTouched = true; 1358 isTouchEvent = event.type === 'touchstart'; 1359 1360 // prevent user enter with right and the swiper move (needs isTouchEvent) 1361 if (!isTouchEvent && 'which' in event && event.which === 3) { 1362 _this.isTouched = false; 1363 return false; 1364 } 1365 1366 if (!isTouchEvent || event.targetTouches.length === 1) { 1367 _this.callPlugins('onTouchStartBegin'); 1368 if (!isTouchEvent && !_this.isAndroid && formTagNames.indexOf(eventTarget.tagName.toLowerCase()) < 0) { 1369 1370 if (event.preventDefault) event.preventDefault(); 1371 else event.returnValue = false;
1372 } 1373 1374 var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX); 1375 var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY); 1376 1377 //Start Touches to check the scrolling 1378 _this.touches.startX = _this.touches.currentX = pageX; 1379 _this.touches.startY = _this.touches.currentY = pageY; 1380 1381 _this.touches.start = _this.touches.current = isH ? pageX : pageY; 1382 1383 //Set Transition Time to 0 1384 _this.setWrapperTransition(0); 1385 1386 //Get Start Translate Position 1387 _this.positions.start = _this.positions.current = _this.getWrapperTranslate(); 1388 1389 //Set Transform 1390 _this.setWrapperTranslate(_this.positions.start); 1391 1392 //TouchStartTime 1393 _this.times.start = (new Date()).getTime(); 1394 1395 //Unset Scrolling 1396 isScrolling = undefined; 1397 1398 //Set Treshold 1399 if (params.moveStartThreshold > 0) { 1400 allowThresholdMove = false; 1401 } 1402 1403 //CallBack 1404 if (params.onTouchStart) _this.fireCallback(params.onTouchStart, _this, event); 1405 _this.callPlugins('onTouchStartEnd'); 1406 1407 } 1408 } 1409 var velocityPrevPosition, velocityPrevTime; 1410 function onTouchMove(event) { 1411 // If slider is not touched - exit 1412 if (!_this.isTouched || params.onlyExternal) return; 1413 if (isTouchEvent && event.type === 'mousemove') return; 1414 1415 var pageX = isTouchEvent ? event.targetTouches[0].pageX : (event.pageX || event.clientX); 1416 var pageY = isTouchEvent ? event.targetTouches[0].pageY : (event.pageY || event.clientY); 1417 1418 //check for scrolling 1419 if (typeof isScrolling === 'undefined' && isH) { 1420 isScrolling = !!(isScrolling || Math.abs(pageY - _this.touches.startY) > Math.abs(pageX - _this.touches.startX)); 1421 } 1422 if (typeof isScrolling === 'undefined' && !isH) { 1423 isScrolling = !!(isScrolling || Math.abs(pageY - _this.touches.startY) < Math.abs(pageX - _this.touches.startX)); 1424 } 1425 if (isScrolling) { 1426 _this.isTouched = false; 1427 return; 1428 } 1429 1430 // One way swipes 1431 if (isH) { 1432 if ((!params.swipeToNext && pageX < _this.touches.startX) || ((!params.swipeToPrev && pageX > _this.touches.startX))) { 1433 return; 1434 } 1435 } 1436 else { 1437 if ((!params.swipeToNext && pageY < _this.touches.startY) || ((!params.swipeToPrev && pageY > _this.touches.startY))) { 1438 return; 1439 } 1440 } 1441 1442 //Check For Nested Swipers 1443 if (event.assignedToSwiper) { 1444 _this.isTouched = false; 1445 return; 1446 } 1447 event.assignedToSwiper = true; 1448 1449 //Block inner links 1450 if (params.preventLinks) { 1451 _this.allowLinks = false; 1452 } 1453 if (params.onSlideClick) { 1454 _this.allowSlideClick = false; 1455 } 1456 1457 //Stop AutoPlay if exist 1458 if (params.autoplay) { 1459 _this.stopAutoplay(true); 1460 } 1461 if (!isTouchEvent || event.touches.length === 1) { 1462 1463 //Moved Flag 1464 if (!_this.isMoved) { 1465 _this.callPlugins('onTouchMoveStart'); 1466 1467 if (params.loop) { 1468 _this.fixLoop(); 1469 _this.positions.start = _this.getWrapperTranslate(); 1470 } 1471 if (params.onTouchMoveStart) _this.fireCallback(params.onTouchMoveStart, _this); 1472 } 1473 _this.isMoved = true; 1474 1475 // cancel event 1476 if (event.preventDefault) event.preventDefault(); 1477 else event.returnValue = false; 1478 1479 _this.touches.current = isH ? pageX : pageY; 1480 1481 _this.positions.current = (_this.touches.current - _this.touches.start) * params.touchRatio + _this.positions.start; 1482 1483 //Resistance Callbacks 1484 if (_this.positions.current > 0 && params.onResistanceBefore) { 1485 _this.fireCallback(params.onResistanceBefore, _this, _this.positions.current); 1486 } 1487 if (_this.positions.current < -maxWrapperPosition() && params.onResistanceAfter) { 1488 _this.fireCallback(params.onResistanceAfter, _this, Math.abs(_this.positions.current + maxWrapperPosition())); 1489 } 1490 //Resistance 1491 if (params.resistance && params.resistance !== '100%') { 1492 var resistance; 1493 //Resistance for Negative-Back sliding 1494 if (_this.positions.current > 0) { 1495 resistance = 1 - _this.positions.current / containerSize / 2; 1496 if (resistance < 0.5) 1497 _this.positions.current = (containerSize / 2); 1498 else 1499 _this.positions.current = _this.positions.current * resistance; 1500 } 1501 //Resistance for After-End Sliding 1502 if (_this.positions.current < -maxWrapperPosition()) { 1503 1504 var diff = (_this.touches.current - _this.touches.start) * params.touchRatio + (maxWrapperPosition() + _this.positions.start); 1505 resistance = (containerSize + diff) / (containerSize); 1506 var newPos = _this.positions.current - diff * (1 - resistance) / 2; 1507 var stopPos = -maxWrapperPosition() - containerSize / 2; 1508 1509 if (newPos < stopPos || resistance <= 0) 1510 _this.positions.current = stopPos; 1511 else 1512 _this.positions.current = newPos; 1513 } 1514 } 1515 if (params.resistance && params.resistance === '100%') { 1516 //Resistance for Negative-Back sliding 1517 if (_this.positions.current > 0 && !(params.freeMode && !params.freeModeFluid)) { 1518 _this.positions.current = 0; 1519 } 1520 //Resistance for After-End Sliding 1521 if (_this.positions.current < -maxWrapperPosition() && !(params.freeMode && !params.freeModeFluid)) { 1522 _this.positions.current = -maxWrapperPosition(); 1523 } 1524 } 1525 //Move Slides 1526 if (!params.followFinger) return; 1527 1528 if (!params.moveStartThreshold) { 1529 _this.setWrapperTranslate(_this.positions.current); 1530 } 1531 else { 1532 if (Math.abs(_this.touches.current - _this.touches.start) > params.moveStartThreshold || allowThresholdMove) { 1533 if (!allowThresholdMove) { 1534 allowThresholdMove = true; 1535 _this.touches.start = _this.touches.current; 1536 return; 1537 } 1538 _this.setWrapperTranslate(_this.positions.current); 1539 } 1540 else { 1541 _this.positions.current = _this.positions.start; 1542 } 1543 } 1544 1545 if (params.freeMode || params.watchActiveIndex) { 1546 _this.updateActiveSlide(_this.positions.current); 1547 } 1548 1549 //Grab Cursor 1550 if (params.grabCursor) { 1551 _this.container.style.cursor = 'move'; 1552 _this.container.style.cursor = 'grabbing'; 1553 _this.container.style.cursor = '-moz-grabbin'; 1554 _this.container.style.cursor = '-webkit-grabbing'; 1555 } 1556 //Velocity 1557 if (!velocityPrevPosition) velocityPrevPosition = _this.touches.current; 1558 if (!velocityPrevTime) velocityPrevTime = (new Date()).getTime(); 1559 _this.velocity = (_this.touches.current - velocityPrevPosition) / ((new Date()).getTime() - velocityPrevTime) / 2; 1560 if (Math.abs(_this.touches.current - velocityPrevPosition) < 2) _this.velocity = 0; 1561 velocityPrevPosition = _this.touches.current; 1562 velocityPrevTime = (new Date()).getTime(); 1563 //Callbacks 1564 _this.callPlugins('onTouchMoveEnd'); 1565 if (params.onTouchMove) _this.fireCallback(params.onTouchMove, _this, event); 1566 1567 return false;
1568 } 1569 } 1570 function onTouchEnd(event) { 1571 //Check For scrolling 1572 if (isScrolling) { 1573 _this.swipeReset(); 1574 } 1575 // If slider is not touched exit 1576 if (params.onlyExternal || !_this.isTouched) return; 1577 _this.isTouched = false; 1578 1579 //Return Grab Cursor 1580 if (params.grabCursor) { 1581 _this.container.style.cursor = 'move'; 1582 _this.container.style.cursor = 'grab'; 1583 _this.container.style.cursor = '-moz-grab'; 1584 _this.container.style.cursor = '-webkit-grab'; 1585 } 1586 1587 //Check for Current Position 1588 if (!_this.positions.current && _this.positions.current !== 0) { 1589 _this.positions.current = _this.positions.start; 1590 } 1591 1592 //For case if slider touched but not moved 1593 if (params.followFinger) { 1594 _this.setWrapperTranslate(_this.positions.current); 1595 } 1596 1597 // TouchEndTime 1598 _this.times.end = (new Date()).getTime(); 1599 1600 //Difference 1601 _this.touches.diff = _this.touches.current - _this.touches.start; 1602 _this.touches.abs = Math.abs(_this.touches.diff); 1603 1604 _this.positions.diff = _this.positions.current - _this.positions.start; 1605 _this.positions.abs = Math.abs(_this.positions.diff); 1606 1607 var diff = _this.positions.diff; 1608 var diffAbs = _this.positions.abs; 1609 var timeDiff = _this.times.end - _this.times.start; 1610 1611 if (diffAbs < 5 && (timeDiff) < 300 && _this.allowLinks === false) { 1612 if (!params.freeMode && diffAbs !== 0) _this.swipeReset(); 1613 //Release inner links 1614 if (params.preventLinks) { 1615 _this.allowLinks = true; 1616 } 1617 if (params.onSlideClick) { 1618 _this.allowSlideClick = true; 1619 } 1620 } 1621 1622 setTimeout(function () { 1623 //Release inner links 1624 if (typeof _this === 'undefined' || _this === null) return; 1625 if (params.preventLinks) { 1626 _this.allowLinks = true; 1627 } 1628 if (params.onSlideClick) { 1629 _this.allowSlideClick = true; 1630 } 1631 }, 100); 1632 1633 var maxPosition = maxWrapperPosition(); 1634 1635 //Not moved or Prevent Negative Back Sliding/After-End Sliding 1636 if (!_this.isMoved && params.freeMode) { 1637 _this.isMoved = false; 1638 if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this, event); 1639 _this.callPlugins('onTouchEnd'); 1640 return; 1641 } 1642 if (!_this.isMoved || _this.positions.current > 0 || _this.positions.current < -maxPosition) { 1643 _this.swipeReset(); 1644 if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this, event); 1645 _this.callPlugins('onTouchEnd'); 1646 return; 1647 } 1648 1649 _this.isMoved = false; 1650 1651 //Free Mode 1652 if (params.freeMode) { 1653 if (params.freeModeFluid) { 1654 var momentumDuration = 1000 * params.momentumRatio; 1655 var momentumDistance = _this.velocity * momentumDuration; 1656 var newPosition = _this.positions.current + momentumDistance; 1657 var doBounce = false; 1658 var afterBouncePosition; 1659 var bounceAmount = Math.abs(_this.velocity) * 20 * params.momentumBounceRatio; 1660 if (newPosition < -maxPosition) { 1661 if (params.momentumBounce && _this.support.transitions) { 1662 if (newPosition + maxPosition < -bounceAmount) newPosition = -maxPosition - bounceAmount; 1663 afterBouncePosition = -maxPosition; 1664 doBounce = true; 1665 allowMomentumBounce = true; 1666 } 1667 else newPosition = -maxPosition; 1668 } 1669 if (newPosition > 0) { 1670 if (params.momentumBounce && _this.support.transitions) { 1671 if (newPosition > bounceAmount) newPosition = bounceAmount; 1672 afterBouncePosition = 0; 1673 doBounce = true; 1674 allowMomentumBounce = true; 1675 } 1676 else newPosition = 0; 1677 } 1678 //Fix duration 1679 if (_this.velocity !== 0) momentumDuration = Math.abs((newPosition - _this.positions.current) / _this.velocity); 1680 1681 _this.setWrapperTranslate(newPosition); 1682 1683 _this.setWrapperTransition(momentumDuration); 1684 1685 if (params.momentumBounce && doBounce) { 1686 _this.wrapperTransitionEnd(function () { 1687 if (!allowMomentumBounce) return; 1688 if (params.onMomentumBounce) _this.fireCallback(params.onMomentumBounce, _this); 1689 _this.callPlugins('onMomentumBounce'); 1690 1691 _this.setWrapperTranslate(afterBouncePosition); 1692 _this.setWrapperTransition(300); 1693 }); 1694 } 1695 1696 _this.updateActiveSlide(newPosition); 1697 } 1698 if (!params.freeModeFluid || timeDiff >= 300) _this.updateActiveSlide(_this.positions.current); 1699 1700 if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this, event); 1701 _this.callPlugins('onTouchEnd'); 1702 return; 1703 } 1704 1705 //Direction 1706 direction = diff < 0 ? 'toNext' : 'toPrev'; 1707 1708 //Short Touches 1709 if (direction === 'toNext' && (timeDiff <= 300)) { 1710 if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset(); 1711 else _this.swipeNext(true, true); 1712 } 1713 1714 if (direction === 'toPrev' && (timeDiff <= 300)) { 1715 if (diffAbs < 30 || !params.shortSwipes) _this.swipeReset(); 1716 else _this.swipePrev(true, true); 1717 } 1718 1719 //Long Touches 1720 var targetSlideSize = 0; 1721 if (params.slidesPerView === 'auto') { 1722 //Define current slide's width 1723 var currentPosition = Math.abs(_this.getWrapperTranslate()); 1724 var slidesOffset = 0; 1725 var _slideSize; 1726 for (var i = 0; i < _this.slides.length; i++) { 1727 _slideSize = isH ? _this.slides[i].getWidth(true, params.roundLengths) : _this.slides[i].getHeight(true, params.roundLengths); 1728 slidesOffset += _slideSize; 1729 if (slidesOffset > currentPosition) { 1730 targetSlideSize = _slideSize; 1731 break; 1732 } 1733 }
1734 if (targetSlideSize > containerSize) targetSlideSize = containerSize; 1735 } 1736 else { 1737 targetSlideSize = slideSize * params.slidesPerView; 1738 } 1739 if (direction === 'toNext' && (timeDiff > 300)) { 1740 if (diffAbs >= targetSlideSize * params.longSwipesRatio) { 1741 _this.swipeNext(true, true); 1742 } 1743 else { 1744 _this.swipeReset(); 1745 } 1746 } 1747 if (direction === 'toPrev' && (timeDiff > 300)) { 1748 if (diffAbs >= targetSlideSize * params.longSwipesRatio) { 1749 _this.swipePrev(true, true); 1750 } 1751 else { 1752 _this.swipeReset(); 1753 } 1754 } 1755 if (params.onTouchEnd) _this.fireCallback(params.onTouchEnd, _this, event); 1756 _this.callPlugins('onTouchEnd'); 1757 } 1758 1759 1760 /*================================================== 1761 noSwiping Bubble Check by Isaac Strack 1762 ====================================================*/ 1763 function hasClass(el, classname) { 1764 return el && el.getAttribute('class') && el.getAttribute('class').indexOf(classname) > -1; 1765 } 1766 function noSwipingSlide(el) { 1767 /*This function is specifically designed to check the parent elements for the noSwiping class, up to the wrapper. 1768 We need to check parents because while onTouchStart bubbles, _this.isTouched is checked in onTouchStart, which stops the bubbling. 1769 So, if a text box, for example, is the initial target, and the parent slide container has the noSwiping class, the _this.isTouched 1770 check will never find it, and what was supposed to be noSwiping is able to be swiped. 1771 This function will iterate up and check for the noSwiping class in parents, up through the wrapperClass.*/ 1772 1773 // First we create a truthy variable, which is that swiping is allowd (noSwiping = false) 1774 var noSwiping = false; 1775 1776 // Now we iterate up (parentElements) until we reach the node with the wrapperClass. 1777 do { 1778 1779 // Each time, we check to see if there's a 'swiper-no-swiping' class (noSwipingClass). 1780 if (hasClass(el, params.noSwipingClass)) 1781 { 1782 noSwiping = true; // If there is, we set noSwiping = true; 1783 } 1784 1785 el = el.parentElement; // now we iterate up (parent node) 1786 1787 } while (!noSwiping && el.parentElement && !hasClass(el, params.wrapperClass)); // also include el.parentElement truthy, just in case. 1788 1789 // because we didn't check the wrapper itself, we do so now, if noSwiping is false: 1790 if (!noSwiping && hasClass(el, params.wrapperClass) && hasClass(el, params.noSwipingClass)) 1791 noSwiping = true; // if the wrapper has the noSwipingClass, we set noSwiping = true; 1792 1793 return noSwiping; 1794 } 1795 1796 function addClassToHtmlString(klass, outerHtml) { 1797 var par = document.createElement('div'); 1798 var child; 1799 1800 par.innerHTML = outerHtml; 1801 child = par.firstChild; 1802 child.className += ' ' + klass; 1803 1804 return child.outerHTML; 1805 } 1806 1807 1808 /*================================================== 1809 Swipe Functions 1810 ====================================================*/ 1811 _this.swipeNext = function (runCallbacks, internal) { 1812 if (typeof runCallbacks === 'undefined') runCallbacks = true; 1813 if (!internal && params.loop) _this.fixLoop(); 1814 if (!internal && params.autoplay) _this.stopAutoplay(true); 1815 _this.callPlugins('onSwipeNext'); 1816 var currentPosition = _this.getWrapperTranslate().toFixed(2); 1817 var newPosition = currentPosition; 1818 if (params.slidesPerView === 'auto') { 1819 for (var i = 0; i < _this.snapGrid.length; i++) { 1820 if (-currentPosition >= _this.snapGrid[i].toFixed(2) && -currentPosition < _this.snapGrid[i + 1].toFixed(2)) { 1821 newPosition = -_this.snapGrid[i + 1]; 1822 break; 1823 } 1824 } 1825 } 1826 else { 1827 var groupSize = slideSize * params.slidesPerGroup; 1828 newPosition = -(Math.floor(Math.abs(currentPosition) / Math.floor(groupSize)) * groupSize + groupSize); 1829 } 1830 if (newPosition < -maxWrapperPosition()) { 1831 newPosition = -maxWrapperPosition(); 1832 } 1833 if (newPosition === currentPosition) return false;
1834 swipeToPosition(newPosition, 'next', {runCallbacks: runCallbacks}); 1835 return true; 1836 }; 1837 _this.swipePrev = function (runCallbacks, internal) { 1838 if (typeof runCallbacks === 'undefined') runCallbacks = true; 1839 if (!internal && params.loop) _this.fixLoop(); 1840 if (!internal && params.autoplay) _this.stopAutoplay(true); 1841 _this.callPlugins('onSwipePrev'); 1842 1843 var currentPosition = Math.ceil(_this.getWrapperTranslate()); 1844 var newPosition; 1845 if (params.slidesPerView === 'auto') { 1846 newPosition = 0; 1847 for (var i = 1; i < _this.snapGrid.length; i++) { 1848 if (-currentPosition === _this.snapGrid[i]) { 1849 newPosition = -_this.snapGrid[i - 1]; 1850 break; 1851 } 1852 if (-currentPosition > _this.snapGrid[i] && -currentPosition < _this.snapGrid[i + 1]) { 1853 newPosition = -_this.snapGrid[i]; 1854 break; 1855 } 1856 } 1857 } 1858 else { 1859 var groupSize = slideSize * params.slidesPerGroup; 1860 newPosition = -(Math.ceil(-currentPosition / groupSize) - 1) * groupSize; 1861 } 1862 1863 if (newPosition > 0) newPosition = 0; 1864 1865 if (newPosition === currentPosition) return false; 1866 swipeToPosition(newPosition, 'prev', {runCallbacks: runCallbacks}); 1867 return true; 1868 1869 }; 1870 _this.swipeReset = function (runCallbacks) { 1871 if (typeof runCallbacks === 'undefined') runCallbacks = true; 1872 _this.callPlugins('onSwipeReset'); 1873 var currentPosition = _this.getWrapperTranslate(); 1874 var groupSize = slideSize * params.slidesPerGroup; 1875 var newPosition; 1876 var maxPosition = -maxWrapperPosition(); 1877 if (params.slidesPerView === 'auto') { 1878 newPosition = 0; 1879 for (var i = 0; i < _this.snapGrid.length; i++) { 1880 if (-currentPosition === _this.snapGrid[i]) return; 1881 if (-currentPosition >= _this.snapGrid[i] && -currentPosition < _this.snapGrid[i + 1]) { 1882 if (_this.positions.diff > 0) newPosition = -_this.snapGrid[i + 1]; 1883 else newPosition = -_this.snapGrid[i]; 1884 break; 1885 } 1886 } 1887 if (-currentPosition >= _this.snapGrid[_this.snapGrid.length - 1]) newPosition = -_this.snapGrid[_this.snapGrid.length - 1]; 1888 if (currentPosition <= -maxWrapperPosition()) newPosition = -maxWrapperPosition(); 1889 } 1890 else { 1891 newPosition = currentPosition < 0 ? Math.round(currentPosition / groupSize) * groupSize : 0; 1892 if (currentPosition <= -maxWrapperPosition()) newPosition = -maxWrapperPosition(); 1893 } 1894 if (params.scrollContainer) { 1895 newPosition = currentPosition < 0 ? currentPosition : 0; 1896 } 1897 if (newPosition < -maxWrapperPosition()) { 1898 newPosition = -maxWrapperPosition(); 1899 } 1900 if (params.scrollContainer && (containerSize > slideSize)) { 1901 newPosition = 0; 1902 } 1903 1904 if (newPosition === currentPosition) return false; 1905 1906 swipeToPosition(newPosition, 'reset', {runCallbacks: runCallbacks}); 1907 return true; 1908 }; 1909 1910 _this.swipeTo = function (index, speed, runCallbacks) { 1911 index = parseInt(index, 10); 1912 _this.callPlugins('onSwipeTo', {index: index, speed: speed}); 1913 if (params.loop) index = index + _this.loopedSlides; 1914 var currentPosition = _this.getWrapperTranslate(); 1915 if (!isFinite(index) || index > (_this.slides.length - 1) || index < 0) return; 1916 var newPosition; 1917 if (params.slidesPerView === 'auto') { 1918 newPosition = -_this.slidesGrid[index]; 1919 } 1920 else { 1921 newPosition = -index * slideSize; 1922 } 1923 if (newPosition < - maxWrapperPosition()) { 1924 newPosition = - maxWrapperPosition(); 1925 } 1926 1927 if (newPosition === currentPosition) return false; 1928 1929 if (typeof runCallbacks === 'undefined') runCallbacks = true; 1930 swipeToPosition(newPosition, 'to', {index: index, speed: speed, runCallbacks: runCallbacks}); 1931 return true; 1932 }; 1933 1934 function swipeToPosition(newPosition, action, toOptions) { 1935 var speed = (action === 'to' && toOptions.speed >= 0) ? toOptions.speed : params.speed; 1936 var timeOld = + new Date(); 1937 1938 function anim() { 1939 var timeNew = + new Date(); 1940 var time = timeNew - timeOld; 1941 currentPosition += animationStep * time / (1000 / 60); 1942 condition = direction === 'toNext' ? currentPosition > newPosition : currentPosition < newPosition; 1943 if (condition) { 1944 _this.setWrapperTranslate(Math.ceil(currentPosition)); 1945 _this._DOMAnimating = true; 1946 window.setTimeout(function () { 1947 anim(); 1948 }, 1000 / 60); 1949 } 1950 else { 1951 if (params.onSlideChangeEnd) { 1952 if (action === 'to') { 1953 if (toOptions.runCallbacks === true) _this.fireCallback(params.onSlideChangeEnd, _this, direction); 1954 } 1955 else { 1956 _this.fireCallback(params.onSlideChangeEnd, _this, direction); 1957 } 1958 1959 } 1960 _this.setWrapperTranslate(newPosition); 1961 _this._DOMAnimating = false;
1962 } 1963 } 1964 1965 if (_this.support.transitions || !params.DOMAnimation) { 1966 _this.setWrapperTransition(speed); 1967 _this.setWrapperTranslate(newPosition); 1968 } 1969 else { 1970 //Try the DOM animation 1971 var currentPosition = _this.getWrapperTranslate(); 1972 var animationStep = Math.ceil((newPosition - currentPosition) / speed * (1000 / 60)); 1973 var direction = currentPosition > newPosition ? 'toNext' : 'toPrev'; 1974 var condition = direction === 'toNext' ? currentPosition > newPosition : currentPosition < newPosition; 1975 if (_this._DOMAnimating) return; 1976 1977 anim(); 1978 } 1979 1980 //Update Active Slide Index 1981 _this.updateActiveSlide(newPosition); 1982 1983 //Callbacks 1984 if (params.onSlideNext && action === 'next' && toOptions.runCallbacks === true) { 1985 _this.fireCallback(params.onSlideNext, _this, newPosition); 1986 } 1987 if (params.onSlidePrev && action === 'prev' && toOptions.runCallbacks === true) { 1988 _this.fireCallback(params.onSlidePrev, _this, newPosition); 1989 } 1990 //'Reset' Callback 1991 if (params.onSlideReset && action === 'reset' && toOptions.runCallbacks === true) { 1992 _this.fireCallback(params.onSlideReset, _this, newPosition); 1993 } 1994 1995 //'Next', 'Prev' and 'To' Callbacks 1996 if ((action === 'next' || action === 'prev' || action === 'to') && toOptions.runCallbacks === true) 1997 slideChangeCallbacks(action); 1998 } 1999 /*================================================== 2000 Transition Callbacks 2001 ====================================================*/ 2002 //Prevent Multiple Callbacks 2003 _this._queueStartCallbacks = false; 2004 _this._queueEndCallbacks = false; 2005 function slideChangeCallbacks(direction) { 2006 //Transition Start Callback 2007 _this.callPlugins('onSlideChangeStart'); 2008 if (params.onSlideChangeStart) { 2009 if (params.queueStartCallbacks && _this.support.transitions) { 2010 if (_this._queueStartCallbacks) return; 2011 _this._queueStartCallbacks = true; 2012 _this.fireCallback(params.onSlideChangeStart, _this, direction); 2013 _this.wrapperTransitionEnd(function () { 2014 _this._queueStartCallbacks = false; 2015 }); 2016 } 2017 else _this.fireCallback(params.onSlideChangeStart, _this, direction); 2018 } 2019 //Transition End Callback 2020 if (params.onSlideChangeEnd) { 2021 if (_this.support.transitions) { 2022 if (params.queueEndCallbacks) { 2023 if (_this._queueEndCallbacks) return; 2024 _this._queueEndCallbacks = true; 2025 _this.wrapperTransitionEnd(function (swiper) { 2026 _this.fireCallback(params.onSlideChangeEnd, swiper, direction); 2027 }); 2028 } 2029 else { 2030 _this.wrapperTransitionEnd(function (swiper) { 2031 _this.fireCallback(params.onSlideChangeEnd, swiper, direction); 2032 }); 2033 } 2034 } 2035 else { 2036 if (!params.DOMAnimation) { 2037 setTimeout(function () { 2038 _this.fireCallback(params.onSlideChangeEnd, _this, direction); 2039 }, 10); 2040 } 2041 } 2042 } 2043 } 2044 2045 /*================================================== 2046 Update Active Slide Index 2047 ====================================================*/ 2048 _this.updateActiveSlide = function (position) { 2049 if (!_this.initialized) return; 2050 if (_this.slides.length === 0) return; 2051 _this.previousIndex = _this.activeIndex; 2052 if (typeof position === 'undefined') position = _this.getWrapperTranslate(); 2053 if (position > 0) position = 0; 2054 var i; 2055 if (params.slidesPerView === 'auto') { 2056 var slidesOffset = 0; 2057 _this.activeIndex = _this.slidesGrid.indexOf(-position); 2058 if (_this.activeIndex < 0) { 2059 for (i = 0; i < _this.slidesGrid.length - 1; i++) { 2060 if (-position > _this.slidesGrid[i] && -position < _this.slidesGrid[i + 1]) { 2061 break; 2062 } 2063 } 2064 var leftDistance = Math.abs(_this.slidesGrid[i] + position); 2065 var rightDistance = Math.abs(_this.slidesGrid[i + 1] + position); 2066 if (leftDistance <= rightDistance) _this.activeIndex = i; 2067 else _this.activeIndex = i + 1; 2068 } 2069 } 2070 else { 2071 _this.activeIndex = Math[params.visibilityFullFit ? 'ceil' : 'round'](-position / slideSize); 2072 } 2073 2074 if (_this.activeIndex === _this.slides.length) _this.activeIndex = _this.slides.length - 1; 2075 if (_this.activeIndex < 0) _this.activeIndex = 0; 2076 2077 // Check for slide 2078 if (!_this.slides[_this.activeIndex]) return; 2079 2080 // Calc Visible slides 2081 _this.calcVisibleSlides(position); 2082 2083 // Mark visible and active slides with additonal classes 2084 if (_this.support.classList) { 2085 var slide; 2086 for (i = 0; i < _this.slides.length; i++) { 2087 slide = _this.slides[i]; 2088 slide.classList.remove(params.slideActiveClass); 2089 if (_this.visibleSlides.indexOf(slide) >= 0) { 2090 slide.classList.add(params.slideVisibleClass); 2091 } else { 2092 slide.classList.remove(params.slideVisibleClass); 2093 } 2094 } 2095 _this.slides[_this.activeIndex].classList.add(params.slideActiveClass); 2096 } else { 2097 var activeClassRegexp = new RegExp('\\s*' + params.slideActiveClass); 2098 var inViewClassRegexp = new RegExp('\\s*' + params.slideVisibleClass); 2099 2100 for (i = 0; i < _this.slides.length; i++) { 2101 _this.slides[i].className = _this.slides[i].className.replace(activeClassRegexp, '').replace(inViewClassRegexp, ''); 2102 if (_this.visibleSlides.indexOf(_this.slides[i]) >= 0) { 2103 _this.slides[i].className += ' ' + params.slideVisibleClass; 2104 } 2105 } 2106 _this.slides[_this.activeIndex].className += ' ' + params.slideActiveClass; 2107 } 2108 2109 //Update loop index 2110 if (params.loop) { 2111 var ls = _this.loopedSlides; 2112 _this.activeLoopIndex = _this.activeIndex - ls; 2113 if (_this.activeLoopIndex >= _this.slides.length - ls * 2) { 2114 _this.activeLoopIndex = _this.slides.length - ls * 2 - _this.activeLoopIndex; 2115 } 2116 if (_this.activeLoopIndex < 0) { 2117 _this.activeLoopIndex = _this.slides.length - ls * 2 + _this.activeLoopIndex; 2118 } 2119 if (_this.activeLoopIndex < 0) _this.activeLoopIndex = 0; 2120 } 2121 else { 2122 _this.activeLoopIndex = _this.activeIndex; 2123 } 2124 //Update Pagination 2125 if (params.pagination) { 2126 _this.updatePagination(position); 2127 } 2128 }; 2129 /*================================================== 2130 Pagination 2131 ====================================================*/ 2132 _this.createPagination = function (firstInit) { 2133 if (params.paginationClickable && _this.paginationButtons) { 2134 removePaginationEvents(); 2135 } 2136 _this.paginationContainer = params.pagination.nodeType ? params.pagination : $$(params.pagination)[0]; 2137 if (params.createPagination) { 2138 var paginationHTML = ''; 2139 var numOfSlides = _this.slides.length; 2140 var numOfButtons = numOfSlides; 2141 if (params.loop) numOfButtons -= _this.loopedSlides * 2; 2142 for (var i = 0; i < numOfButtons; i++) { 2143 paginationHTML += '<' + params.paginationElement + ' class="' + params.paginationElementClass + '"></' + params.paginationElement + '>'; 2144 } 2145 _this.paginationContainer.innerHTML = paginationHTML; 2146 } 2147 _this.paginationButtons = $$('.' + params.paginationElementClass, _this.paginationContainer); 2148 if (!firstInit) _this.updatePagination(); 2149 _this.callPlugins('onCreatePagination'); 2150 if (params.paginationClickable) { 2151 addPaginationEvents(); 2152 } 2153 }; 2154 function removePaginationEvents() { 2155 var pagers = _this.paginationButtons; 2156 if (pagers) { 2157 for (var i = 0; i < pagers.length; i++) {
2158 _this.h.removeEventListener(pagers[i], 'click', paginationClick); 2159 } 2160 } 2161 } 2162 function addPaginationEvents() { 2163 var pagers = _this.paginationButtons; 2164 if (pagers) { 2165 for (var i = 0; i < pagers.length; i++) { 2166 _this.h.addEventListener(pagers[i], 'click', paginationClick); 2167 } 2168 } 2169 } 2170 function paginationClick(e) { 2171 var index; 2172 var target = e.target || e.srcElement; 2173 var pagers = _this.paginationButtons; 2174 for (var i = 0; i < pagers.length; i++) { 2175 if (target === pagers[i]) index = i; 2176 } 2177 if (params.autoplay) _this.stopAutoplay(true); 2178 _this.swipeTo(index); 2179 } 2180 _this.updatePagination = function (position) { 2181 if (!params.pagination) return; 2182 if (_this.slides.length < 1) return; 2183 var activePagers = $$('.' + params.paginationActiveClass, _this.paginationContainer); 2184 if (!activePagers) return; 2185 2186 //Reset all Buttons' class to not active 2187 var pagers = _this.paginationButtons; 2188 if (pagers.length === 0) return; 2189 for (var i = 0; i < pagers.length; i++) { 2190 pagers[i].className = params.paginationElementClass; 2191 } 2192 2193 var indexOffset = params.loop ? _this.loopedSlides : 0; 2194 if (params.paginationAsRange) { 2195 if (!_this.visibleSlides) _this.calcVisibleSlides(position); 2196 //Get Visible Indexes 2197 var visibleIndexes = []; 2198 var j; // lopp index - avoid JSHint W004 / W038 2199 for (j = 0; j < _this.visibleSlides.length; j++) { 2200 var visIndex = _this.slides.indexOf(_this.visibleSlides[j]) - indexOffset; 2201 2202 if (params.loop && visIndex < 0) { 2203 visIndex = _this.slides.length - _this.loopedSlides * 2 + visIndex; 2204 } 2205 if (params.loop && visIndex >= _this.slides.length - _this.loopedSlides * 2) { 2206 visIndex = _this.slides.length - _this.loopedSlides * 2 - visIndex; 2207 visIndex = Math.abs(visIndex); 2208 } 2209 visibleIndexes.push(visIndex); 2210 } 2211 2212 for (j = 0; j < visibleIndexes.length; j++) { 2213 if (pagers[visibleIndexes[j]]) pagers[visibleIndexes[j]].className += ' ' + params.paginationVisibleClass; 2214 } 2215 2216 if (params.loop) { 2217 if (pagers[_this.activeLoopIndex] !== undefined) { 2218 pagers[_this.activeLoopIndex].className += ' ' + params.paginationActiveClass; 2219 } 2220 } 2221 else { 2222 if (pagers[_this.activeIndex]) pagers[_this.activeIndex].className += ' ' + params.paginationActiveClass; 2223 } 2224 } 2225 else { 2226 if (params.loop) { 2227 if (pagers[_this.activeLoopIndex]) pagers[_this.activeLoopIndex].className += ' ' + params.paginationActiveClass + ' ' + params.paginationVisibleClass; 2228 } 2229 else { 2230 if (pagers[_this.activeIndex]) pagers[_this.activeIndex].className += ' ' + params.paginationActiveClass + ' ' + params.paginationVisibleClass; 2231 } 2232 } 2233 }; 2234 _this.calcVisibleSlides = function (position) { 2235 var visibleSlides = []; 2236 var _slideLeft = 0, _slideSize = 0, _slideRight = 0; 2237 if (isH && _this.wrapperLeft > 0) position = position + _this.wrapperLeft; 2238 if (!isH && _this.wrapperTop > 0) position = position + _this.wrapperTop; 2239 2240 for (var i = 0; i < _this.slides.length; i++) { 2241 _slideLeft += _slideSize; 2242 if (params.slidesPerView === 'auto') 2243 _slideSize = isH ? _this.h.getWidth(_this.slides[i], true, params.roundLengths) : _this.h.getHeight(_this.slides[i], true, params.roundLengths); 2244 else _slideSize = slideSize; 2245 2246 _slideRight = _slideLeft + _slideSize; 2247 var isVisibile = false; 2248 if (params.visibilityFullFit) { 2249 if (_slideLeft >= -position && _slideRight <= -position + containerSize) isVisibile = true; 2250 if (_slideLeft <= -position && _slideRight >= -position + containerSize) isVisibile = true; 2251 } 2252 else { 2253 if (_slideRight > -position && _slideRight <= ((-position + containerSize))) isVisibile = true; 2254 if (_slideLeft >= -position && _slideLeft < ((-position + containerSize))) isVisibile = true; 2255 if (_slideLeft < -position && _slideRight > ((-position + containerSize))) isVisibile = true; 2256 } 2257 2258 if (isVisibile) visibleSlides.push(_this.slides[i]); 2259 2260 } 2261 if (visibleSlides.length === 0) visibleSlides = [_this.slides[_this.activeIndex]]; 2262 2263 _this.visibleSlides = visibleSlides; 2264 }; 2265 2266 /*========================================== 2267 Autoplay 2268 ============================================*/ 2269 var autoplayTimeoutId, autoplayIntervalId; 2270 _this.startAutoplay = function () { 2271 if (_this.support.transitions) { 2272 if (typeof autoplayTimeoutId !== 'undefined') return false;
2273 if (!params.autoplay) return; 2274 _this.callPlugins('onAutoplayStart'); 2275 if (params.onAutoplayStart) _this.fireCallback(params.onAutoplayStart, _this); 2276 autoplay(); 2277 } 2278 else { 2279 if (typeof autoplayIntervalId !== 'undefined') return false; 2280 if (!params.autoplay) return; 2281 _this.callPlugins('onAutoplayStart'); 2282 if (params.onAutoplayStart) _this.fireCallback(params.onAutoplayStart, _this); 2283 autoplayIntervalId = setInterval(function () { 2284 if (params.loop) { 2285 _this.fixLoop(); 2286 _this.swipeNext(true, true); 2287 } 2288 else if (!_this.swipeNext(true, true)) { 2289 if (!params.autoplayStopOnLast) _this.swipeTo(0); 2290 else { 2291 clearInterval(autoplayIntervalId); 2292 autoplayIntervalId = undefined; 2293 } 2294 } 2295 }, params.autoplay); 2296 } 2297 }; 2298 _this.stopAutoplay = function (internal) { 2299 if (_this.support.transitions) { 2300 if (!autoplayTimeoutId) return; 2301 if (autoplayTimeoutId) clearTimeout(autoplayTimeoutId); 2302 autoplayTimeoutId = undefined; 2303 if (internal && !params.autoplayDisableOnInteraction) { 2304 _this.wrapperTransitionEnd(function () { 2305 autoplay(); 2306 }); 2307 } 2308 _this.callPlugins('onAutoplayStop'); 2309 if (params.onAutoplayStop) _this.fireCallback(params.onAutoplayStop, _this); 2310 } 2311 else { 2312 if (autoplayIntervalId) clearInterval(autoplayIntervalId); 2313 autoplayIntervalId = undefined; 2314 _this.callPlugins('onAutoplayStop'); 2315 if (params.onAutoplayStop) _this.fireCallback(params.onAutoplayStop, _this); 2316 } 2317 }; 2318 function autoplay() { 2319 autoplayTimeoutId = setTimeout(function () { 2320 if (params.loop) { 2321 _this.fixLoop(); 2322 _this.swipeNext(true, true); 2323 } 2324 else if (!_this.swipeNext(true, true)) { 2325 if (!params.autoplayStopOnLast) _this.swipeTo(0); 2326 else { 2327 clearTimeout(autoplayTimeoutId); 2328 autoplayTimeoutId = undefined; 2329 } 2330 } 2331 _this.wrapperTransitionEnd(function () { 2332 if (typeof autoplayTimeoutId !== 'undefined') autoplay(); 2333 }); 2334 }, params.autoplay); 2335 } 2336 /*================================================== 2337 Loop 2338 ====================================================*/ 2339 _this.loopCreated = false; 2340 _this.removeLoopedSlides = function () { 2341 if (_this.loopCreated) { 2342 for (var i = 0; i < _this.slides.length; i++) { 2343 if (_this.slides[i].getData('looped') === true) _this.wrapper.removeChild(_this.slides[i]); 2344 } 2345 } 2346 }; 2347 2348 _this.createLoop = function () { 2349 if (_this.slides.length === 0) return; 2350 if (params.slidesPerView === 'auto') { 2351 _this.loopedSlides = params.loopedSlides || 1; 2352 } 2353 else { 2354 _this.loopedSlides = Math.floor(params.slidesPerView) + params.loopAdditionalSlides; 2355 } 2356 2357 if (_this.loopedSlides > _this.slides.length) { 2358 _this.loopedSlides = _this.slides.length; 2359 } 2360 2361 var slideFirstHTML = '', 2362 slideLastHTML = '', 2363 i; 2364 var slidesSetFullHTML = ''; 2365 /** 2366 loopedSlides is too large if loopAdditionalSlides are set. 2367 Need to divide the slides by maximum number of slides existing. 2368 2369 @author Tomaz Lovrec <[email protected]> 2370 */ 2371 var numSlides = _this.slides.length; 2372 var fullSlideSets = Math.floor(_this.loopedSlides / numSlides); 2373 var remainderSlides = _this.loopedSlides % numSlides; 2374 // assemble full sets of slides 2375 for (i = 0; i < (fullSlideSets * numSlides); i++) { 2376 var j = i; 2377 if (i >= numSlides) { 2378 var over = Math.floor(i / numSlides);
2379 j = i - (numSlides * over); 2380 } 2381 slidesSetFullHTML += _this.slides[j].outerHTML; 2382 } 2383 // assemble remainder slides 2384 // assemble remainder appended to existing slides 2385 for (i = 0; i < remainderSlides;i++) { 2386 slideLastHTML += addClassToHtmlString(params.slideDuplicateClass, _this.slides[i].outerHTML); 2387 } 2388 // assemble slides that get preppended to existing slides 2389 for (i = numSlides - remainderSlides; i < numSlides;i++) { 2390 slideFirstHTML += addClassToHtmlString(params.slideDuplicateClass, _this.slides[i].outerHTML); 2391 } 2392 // assemble all slides 2393 var slides = slideFirstHTML + slidesSetFullHTML + wrapper.innerHTML + slidesSetFullHTML + slideLastHTML; 2394 // set the slides 2395 wrapper.innerHTML = slides; 2396 2397 _this.loopCreated = true; 2398 _this.calcSlides(); 2399 2400 //Update Looped Slides with special class 2401 for (i = 0; i < _this.slides.length; i++) { 2402 if (i < _this.loopedSlides || i >= _this.slides.length - _this.loopedSlides) _this.slides[i].setData('looped', true); 2403 } 2404 _this.callPlugins('onCreateLoop'); 2405 2406 }; 2407 2408 _this.fixLoop = function () { 2409 var newIndex; 2410 //Fix For Negative Oversliding 2411 if (_this.activeIndex < _this.loopedSlides) { 2412 newIndex = _this.slides.length - _this.loopedSlides * 3 + _this.activeIndex; 2413 _this.swipeTo(newIndex, 0, false); 2414 } 2415 //Fix For Positive Oversliding 2416 else if ((params.slidesPerView === 'auto' && _this.activeIndex >= _this.loopedSlides * 2) || (_this.activeIndex > _this.slides.length - params.slidesPerView * 2)) { 2417 newIndex = -_this.slides.length + _this.activeIndex + _this.loopedSlides; 2418 _this.swipeTo(newIndex, 0, false); 2419 } 2420 }; 2421 2422 /*================================================== 2423 Slides Loader 2424 ====================================================*/ 2425 _this.loadSlides = function () { 2426 var slidesHTML = ''; 2427 _this.activeLoaderIndex = 0; 2428 var slides = params.loader.slides; 2429 var slidesToLoad = params.loader.loadAllSlides ? slides.length : params.slidesPerView * (1 + params.loader.surroundGroups); 2430 for (var i = 0; i < slidesToLoad; i++) { 2431 if (params.loader.slidesHTMLType === 'outer') slidesHTML += slides[i]; 2432 else { 2433 slidesHTML += '<' + params.slideElement + ' class="' + params.slideClass + '" data-swiperindex="' + i + '">' + slides[i] + '</' + params.slideElement + '>'; 2434 } 2435 } 2436 _this.wrapper.innerHTML = slidesHTML; 2437 _this.calcSlides(true); 2438 //Add permanent transitionEnd callback 2439 if (!params.loader.loadAllSlides) { 2440 _this.wrapperTransitionEnd(_this.reloadSlides, true); 2441 } 2442 }; 2443 2444 _this.reloadSlides = function () { 2445 var slides = params.loader.slides; 2446 var newActiveIndex = parseInt(_this.activeSlide().data('swiperindex'), 10); 2447 if (newActiveIndex < 0 || newActiveIndex > slides.length - 1) return; //<-- Exit 2448 _this.activeLoaderIndex = newActiveIndex; 2449 var firstIndex = Math.max(0, newActiveIndex - params.slidesPerView * params.loader.surroundGroups); 2450 var lastIndex = Math.min(newActiveIndex + params.slidesPerView * (1 + params.loader.surroundGroups) - 1, slides.length - 1); 2451 //Update Transforms 2452 if (newActiveIndex > 0) { 2453 var newTransform = -slideSize * (newActiveIndex - firstIndex); 2454 _this.setWrapperTranslate(newTransform); 2455 _this.setWrapperTransition(0); 2456 } 2457 var i; // loop index 2458 //New Slides 2459 if (params.loader.logic === 'reload') { 2460 _this.wrapper.innerHTML = ''; 2461 var slidesHTML = ''; 2462 for (i = firstIndex; i <= lastIndex; i++) { 2463 slidesHTML += params.loader.slidesHTMLType === 'outer' ? slides[i] : '<' + params.slideElement + ' class="' + params.slideClass + '" data-swiperindex="' + i + '">' + slides[i] + '</' + params.slideElement + '>'; 2464 } 2465 _this.wrapper.innerHTML = slidesHTML; 2466 } 2467 else { 2468 var minExistIndex = 1000; 2469 var maxExistIndex = 0; 2470 2471 for (i = 0; i < _this.slides.length; i++) { 2472 var index = _this.slides[i].data('swiperindex'); 2473 if (index < firstIndex || index > lastIndex) { 2474 _this.wrapper.removeChild(_this.slides[i]); 2475 } 2476 else { 2477 minExistIndex = Math.min(index, minExistIndex); 2478 maxExistIndex = Math.max(index, maxExistIndex); 2479 } 2480 } 2481 for (i = firstIndex; i <= lastIndex; i++) { 2482 var newSlide; 2483 if (i < minExistIndex) { 2484 newSlide = document.createElement(params.slideElement); 2485 newSlide.className = params.slideClass; 2486 newSlide.setAttribute('data-swiperindex', i); 2487 newSlide.innerHTML = slides[i]; 2488 _this.wrapper.insertBefore(newSlide, _this.wrapper.firstChild); 2489 } 2490 if (i > maxExistIndex) { 2491 newSlide = document.createElement(params.slideElement); 2492 newSlide.className = params.slideClass; 2493 newSlide.setAttribute('data-swiperindex', i); 2494 newSlide.innerHTML = slides[i]; 2495 _this.wrapper.appendChild(newSlide); 2496 } 2497 } 2498 } 2499 //reInit 2500 _this.reInit(true); 2501 }; 2502 2503 /*================================================== 2504 Make Swiper 2505 ====================================================*/ 2506 function makeSwiper() { 2507 _this.calcSlides(); 2508 if (params.loader.slides.length > 0 && _this.slides.length === 0) { 2509 _this.loadSlides(); 2510 } 2511 if (params.loop) { 2512 _this.createLoop(); 2513 } 2514 _this.init(); 2515 initEvents(); 2516 if (params.pagination) { 2517 _this.createPagination(true); 2518 } 2519 2520 if (params.loop || params.initialSlide > 0) { 2521 _this.swipeTo(params.initialSlide, 0, false); 2522 } 2523 else { 2524 _this.updateActiveSlide(0); 2525 } 2526 if (params.autoplay) { 2527 _this.startAutoplay(); 2528 } 2529 /** 2530 * Set center slide index. 2531 * 2532 * @author Tomaz Lovrec <[email protected]> 2533 */ 2534 _this.centerIndex = _this.activeIndex; 2535 2536 // Callbacks 2537 if (params.onSwiperCreated) _this.fireCallback(params.onSwiperCreated, _this); 2538 _this.callPlugins('onSwiperCreated'); 2539 } 2540 2541 makeSwiper(); 2542}; 2543 2544Swiper.prototype = { 2545 plugins : {}, 2546 2547 /*================================================== 2548 Wrapper Operations 2549 ====================================================*/ 2550 wrapperTransitionEnd : function (callback, permanent) { 2551 'use strict'; 2552 var a = this, 2553 el = a.wrapper,
2554 events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'], 2555 i; 2556 2557 function fireCallBack(e) { 2558 if (e.target !== el) return; 2559 callback(a); 2560 if (a.params.queueEndCallbacks) a._queueEndCallbacks = false; 2561 if (!permanent) { 2562 for (i = 0; i < events.length; i++) { 2563 a.h.removeEventListener(el, events[i], fireCallBack); 2564 } 2565 } 2566 } 2567 2568 if (callback) { 2569 for (i = 0; i < events.length; i++) { 2570 a.h.addEventListener(el, events[i], fireCallBack); 2571 } 2572 } 2573 }, 2574 2575 getWrapperTranslate : function (axis) { 2576 'use strict'; 2577 var el = this.wrapper, 2578 matrix, curTransform, curStyle, transformMatrix; 2579 2580 // automatic axis detection 2581 if (typeof axis === 'undefined') { 2582 axis = this.params.mode === 'horizontal' ? 'x' : 'y'; 2583 } 2584 2585 if (this.support.transforms && this.params.useCSS3Transforms) { 2586 curStyle = window.getComputedStyle(el, null); 2587 if (window.WebKitCSSMatrix) { 2588 // Some old versions of Webkit choke when 'none' is passed; pass 2589 // empty string instead in this case 2590 transformMatrix = new WebKitCSSMatrix(curStyle.webkitTransform === 'none' ? '' : curStyle.webkitTransform); 2591 } 2592 else { 2593 transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,'); 2594 matrix = transformMatrix.toString().split(','); 2595 } 2596 2597 if (axis === 'x') { 2598 //Latest Chrome and webkits Fix 2599 if (window.WebKitCSSMatrix) 2600 curTransform = transformMatrix.m41; 2601 //Crazy IE10 Matrix 2602 else if (matrix.length === 16) 2603 curTransform = parseFloat(matrix[12]); 2604 //Normal Browsers 2605 else 2606 curTransform = parseFloat(matrix[4]); 2607 } 2608 if (axis === 'y') { 2609 //Latest Chrome and webkits Fix 2610 if (window.WebKitCSSMatrix) 2611 curTransform = transformMatrix.m42; 2612 //Crazy IE10 Matrix 2613 else if (matrix.length === 16) 2614 curTransform = parseFloat(matrix[13]); 2615 //Normal Browsers 2616 else 2617 curTransform = parseFloat(matrix[5]); 2618 } 2619 } 2620 else { 2621 if (axis === 'x') curTransform = parseFloat(el.style.left, 10) || 0; 2622 if (axis === 'y') curTransform = parseFloat(el.style.top, 10) || 0; 2623 } 2624 return curTransform || 0; 2625 }, 2626 2627 setWrapperTranslate : function (x, y, z) { 2628 'use strict'; 2629 var es = this.wrapper.style, 2630 coords = {x: 0, y: 0, z: 0}, 2631 translate; 2632 2633 // passed all coordinates 2634 if (arguments.length === 3) { 2635 coords.x = x; 2636 coords.y = y; 2637 coords.z = z; 2638 } 2639 2640 // passed one coordinate and optional axis 2641 else { 2642 if (typeof y === 'undefined') { 2643 y = this.params.mode === 'horizontal' ? 'x' : 'y'; 2644 } 2645 coords[y] = x; 2646 } 2647 2648 if (this.support.transforms && this.params.useCSS3Transforms) { 2649 translate = this.support.transforms3d ? 'translate3d(' + coords.x + 'px, ' + coords.y + 'px, ' + coords.z + 'px)' : 'translate(' + coords.x + 'px, ' + coords.y + 'px)'; 2650 es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = translate; 2651 } 2652 else { 2653 es.left = coords.x + 'px'; 2654 es.top = coords.y + 'px'; 2655 } 2656 this.callPlugins('onSetWrapperTransform', coords); 2657 if (this.params.onSetWrapperTransform) this.fireCallback(this.params.onSetWrapperTransform, this, coords); 2658 }, 2659 2660 setWrapperTransition : function (duration) { 2661 'use strict'; 2662 var es = this.wrapper.style; 2663 es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = (duration / 1000) + 's'; 2664 this.callPlugins('onSetWrapperTransition', {duration: duration}); 2665 if (this.params.onSetWrapperTransition) this.fireCallback(this.params.onSetWrapperTransition, this, duration); 2666 2667 }, 2668 2669 /*================================================== 2670 Helpers 2671 ====================================================*/ 2672 h : { 2673 getWidth: function (el, outer, round) { 2674 'use strict'; 2675 var width = window.getComputedStyle(el, null).getPropertyValue('width'); 2676 var returnWidth = parseFloat(width); 2677 //IE Fixes 2678 if (isNaN(returnWidth) || width.indexOf('%') > 0 || returnWidth < 0) { 2679 returnWidth = el.offsetWidth - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-left')) - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-right')); 2680 } 2681 if (outer) returnWidth += parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-left')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-right')); 2682 if (round) return Math.ceil(returnWidth); 2683 else return returnWidth; 2684 }, 2685 getHeight: function (el, outer, round) { 2686 'use strict'; 2687 if (outer) return el.offsetHeight; 2688 2689 var height = window.getComputedStyle(el, null).getPropertyValue('height'); 2690 var returnHeight = parseFloat(height); 2691 //IE Fixes 2692 if (isNaN(returnHeight) || height.indexOf('%') > 0 || returnHeight < 0) { 2693 returnHeight = el.offsetHeight - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-top')) - parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-bottom')); 2694 } 2695 if (outer) returnHeight += parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue('padding-bottom')); 2696 if (round) return Math.ceil(returnHeight); 2697 else return returnHeight; 2698 }, 2699 getOffset: function (el) { 2700 'use strict'; 2701 var box = el.getBoundingClientRect(); 2702 var body = document.body; 2703 var clientTop = el.clientTop || body.clientTop || 0; 2704 var clientLeft = el.clientLeft || body.clientLeft || 0; 2705 var scrollTop = window.pageYOffset || el.scrollTop; 2706 var scrollLeft = window.pageXOffset || el.scrollLeft; 2707 if (document.documentElement && !window.pageYOffset) { 2708 //IE7-8 2709 scrollTop = document.documentElement.scrollTop; 2710 scrollLeft = document.documentElement.scrollLeft; 2711 } 2712 return { 2713 top: box.top + scrollTop - clientTop, 2714 left: box.left + scrollLeft - clientLeft 2715 }; 2716 }, 2717 windowWidth : function () { 2718 'use strict'; 2719 if (window.innerWidth) return window.innerWidth; 2720 else if (document.documentElement && document.documentElement.clientWidth) return document.documentElement.clientWidth; 2721 }, 2722 windowHeight : function () { 2723 'use strict'; 2724 if (window.innerHeight) return window.innerHeight; 2725 else if (document.documentElement && document.documentElement.clientHeight) return document.documentElement.clientHeight; 2726 }, 2727 windowScroll : function () { 2728 'use strict'; 2729 if (typeof pageYOffset !== 'undefined') { 2730 return { 2731 left: window.pageXOffset, 2732 top: window.pageYOffset 2733 }; 2734 } 2735 else if (document.documentElement) { 2736 return { 2737 left: document.documentElement.scrollLeft, 2738 top: document.documentElement.scrollTop 2739 }; 2740 } 2741 }, 2742 2743 addEventListener : function (el, event, listener, useCapture) { 2744 'use strict'; 2745 if (typeof useCapture === 'undefined') { 2746 useCapture = false;
2747 } 2748 2749 if (el.addEventListener) { 2750 el.addEventListener(event, listener, useCapture); 2751 } 2752 else if (el.attachEvent) { 2753 el.attachEvent('on' + event, listener); 2754 } 2755 }, 2756 2757 removeEventListener : function (el, event, listener, useCapture) { 2758 'use strict'; 2759 if (typeof useCapture === 'undefined') { 2760 useCapture = false; 2761 } 2762 2763 if (el.removeEventListener) { 2764 el.removeEventListener(event, listener, useCapture); 2765 } 2766 else if (el.detachEvent) { 2767 el.detachEvent('on' + event, listener); 2768 } 2769 } 2770 }, 2771 setTransform : function (el, transform) { 2772 'use strict'; 2773 var es = el.style; 2774 es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transform; 2775 }, 2776 setTranslate : function (el, translate) { 2777 'use strict'; 2778 var es = el.style; 2779 var pos = { 2780 x : translate.x || 0, 2781 y : translate.y || 0, 2782 z : translate.z || 0 2783 }; 2784 var transformString = this.support.transforms3d ? 'translate3d(' + (pos.x) + 'px,' + (pos.y) + 'px,' + (pos.z) + 'px)' : 'translate(' + (pos.x) + 'px,' + (pos.y) + 'px)'; 2785 es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = transformString; 2786 if (!this.support.transforms) { 2787 es.left = pos.x + 'px'; 2788 es.top = pos.y + 'px'; 2789 } 2790 }, 2791 setTransition : function (el, duration) { 2792 'use strict'; 2793 var es = el.style; 2794 es.webkitTransitionDuration = es.MsTransitionDuration = es.msTransitionDuration = es.MozTransitionDuration = es.OTransitionDuration = es.transitionDuration = duration + 'ms'; 2795 }, 2796 /*================================================== 2797 Feature Detection 2798 ====================================================*/ 2799 support: { 2800 2801 touch : (window.Modernizr && Modernizr.touch === true) || (function () { 2802 'use strict'; 2803 return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch); 2804 })(), 2805 2806 transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () { 2807 'use strict'; 2808 var div = document.createElement('div').style; 2809 return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div); 2810 })(), 2811 2812 transforms : (window.Modernizr && Modernizr.csstransforms === true) || (function () { 2813 'use strict'; 2814 var div = document.createElement('div').style; 2815 return ('transform' in div || 'WebkitTransform' in div || 'MozTransform' in div || 'msTransform' in div || 'MsTransform' in div || 'OTransform' in div); 2816 })(), 2817 2818 transitions : (window.Modernizr && Modernizr.csstransitions === true) || (function () { 2819 'use strict'; 2820 var div = document.createElement('div').style; 2821 return ('transition' in div || 'WebkitTransition' in div || 'MozTransition' in div || 'msTransition' in div || 'MsTransition' in div || 'OTransition' in div); 2822 })(), 2823 2824 classList : (function () { 2825 'use strict'; 2826 var div = document.createElement('div'); 2827 return 'classList' in div; 2828 })() 2829 }, 2830 2831 browser : { 2832 2833 ie8 : (function () { 2834 'use strict'; 2835 var rv = -1; // Return value assumes failure. 2836 if (navigator.appName === 'Microsoft Internet Explorer') { 2837 var ua = navigator.userAgent; 2838 var re = new RegExp(/MSIE ([0-9]{1,}[\.0-9]{0,})/); 2839 if (re.exec(ua) !== null) 2840 rv = parseFloat(RegExp.$1); 2841 } 2842 return rv !== -1 && rv < 9; 2843 })(), 2844 2845 ie10 : window.navigator.msPointerEnabled, 2846 ie11 : window.navigator.pointerEnabled 2847 } 2848}; 2849 2850/*========================= 2851 jQuery & Zepto Plugins 2852 ===========================*/ 2853if (window.jQuery || window.Zepto) { 2854 (function ($) { 2855 'use strict'; 2856 $.fn.swiper = function (params) { 2857 var firstInstance; 2858 this.each(function (i) { 2859 var that = $(this); 2860 var s = new Swiper(that[0], params); 2861 if (!i) firstInstance = s; 2862 that.data('swiper', s); 2863 }); 2864 return firstInstance; 2865 }; 2866 })(window.jQuery || window.Zepto); 2867} 2868 2869// CommonJS support 2870if (typeof(module) !== 'undefined') { 2871 module.exports = Swiper; 2872 2873// requirejs support 2874} else if (typeof define === 'function' && define.amd) { 2875 define([], function () { 2876 'use strict'; 2877 return Swiper; 2878 }); 2879}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.