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