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