slideTo.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import { animateCSSModeScroll } from '../../shared/utils.js';
  2. export default function slideTo(index = 0, speed = this.params.speed, runCallbacks = true, internal, initial) {
  3. if (typeof index !== 'number' && typeof index !== 'string') {
  4. throw new Error(`The 'index' argument cannot have type other than 'number' or 'string'. [${typeof index}] given.`);
  5. }
  6. if (typeof index === 'string') {
  7. /**
  8. * The `index` argument converted from `string` to `number`.
  9. * @type {number}
  10. */
  11. const indexAsNumber = parseInt(index, 10);
  12. /**
  13. * Determines whether the `index` argument is a valid `number`
  14. * after being converted from the `string` type.
  15. * @type {boolean}
  16. */
  17. const isValidNumber = isFinite(indexAsNumber);
  18. if (!isValidNumber) {
  19. throw new Error(`The passed-in 'index' (string) couldn't be converted to 'number'. [${index}] given.`);
  20. } // Knowing that the converted `index` is a valid number,
  21. // we can update the original argument's value.
  22. index = indexAsNumber;
  23. }
  24. const swiper = this;
  25. let slideIndex = index;
  26. if (slideIndex < 0) slideIndex = 0;
  27. const {
  28. params,
  29. snapGrid,
  30. slidesGrid,
  31. previousIndex,
  32. activeIndex,
  33. rtlTranslate: rtl,
  34. wrapperEl,
  35. enabled
  36. } = swiper;
  37. if (swiper.animating && params.preventInteractionOnTransition || !enabled && !internal && !initial) {
  38. return false;
  39. }
  40. const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
  41. let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
  42. if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
  43. if ((activeIndex || params.initialSlide || 0) === (previousIndex || 0) && runCallbacks) {
  44. swiper.emit('beforeSlideChangeStart');
  45. }
  46. const translate = -snapGrid[snapIndex]; // Update progress
  47. swiper.updateProgress(translate); // Normalize slideIndex
  48. if (params.normalizeSlideIndex) {
  49. for (let i = 0; i < slidesGrid.length; i += 1) {
  50. const normalizedTranslate = -Math.floor(translate * 100);
  51. const normalizedGrid = Math.floor(slidesGrid[i] * 100);
  52. const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
  53. if (typeof slidesGrid[i + 1] !== 'undefined') {
  54. if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) {
  55. slideIndex = i;
  56. } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
  57. slideIndex = i + 1;
  58. }
  59. } else if (normalizedTranslate >= normalizedGrid) {
  60. slideIndex = i;
  61. }
  62. }
  63. } // Directions locks
  64. if (swiper.initialized && slideIndex !== activeIndex) {
  65. if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) {
  66. return false;
  67. }
  68. if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
  69. if ((activeIndex || 0) !== slideIndex) return false;
  70. }
  71. }
  72. let direction;
  73. if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset'; // Update Index
  74. if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {
  75. swiper.updateActiveIndex(slideIndex); // Update Height
  76. if (params.autoHeight) {
  77. swiper.updateAutoHeight();
  78. }
  79. swiper.updateSlidesClasses();
  80. if (params.effect !== 'slide') {
  81. swiper.setTranslate(translate);
  82. }
  83. if (direction !== 'reset') {
  84. swiper.transitionStart(runCallbacks, direction);
  85. swiper.transitionEnd(runCallbacks, direction);
  86. }
  87. return false;
  88. }
  89. if (params.cssMode) {
  90. const isH = swiper.isHorizontal();
  91. const t = rtl ? translate : -translate;
  92. if (speed === 0) {
  93. const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
  94. if (isVirtual) {
  95. swiper.wrapperEl.style.scrollSnapType = 'none';
  96. swiper._immediateVirtual = true;
  97. }
  98. wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
  99. if (isVirtual) {
  100. requestAnimationFrame(() => {
  101. swiper.wrapperEl.style.scrollSnapType = '';
  102. swiper._swiperImmediateVirtual = false;
  103. });
  104. }
  105. } else {
  106. if (!swiper.support.smoothScroll) {
  107. animateCSSModeScroll({
  108. swiper,
  109. targetPosition: t,
  110. side: isH ? 'left' : 'top'
  111. });
  112. return true;
  113. }
  114. wrapperEl.scrollTo({
  115. [isH ? 'left' : 'top']: t,
  116. behavior: 'smooth'
  117. });
  118. }
  119. return true;
  120. }
  121. if (speed === 0) {
  122. swiper.setTransition(0);
  123. swiper.setTranslate(translate);
  124. swiper.updateActiveIndex(slideIndex);
  125. swiper.updateSlidesClasses();
  126. swiper.emit('beforeTransitionStart', speed, internal);
  127. swiper.transitionStart(runCallbacks, direction);
  128. swiper.transitionEnd(runCallbacks, direction);
  129. } else {
  130. swiper.setTransition(speed);
  131. swiper.setTranslate(translate);
  132. swiper.updateActiveIndex(slideIndex);
  133. swiper.updateSlidesClasses();
  134. swiper.emit('beforeTransitionStart', speed, internal);
  135. swiper.transitionStart(runCallbacks, direction);
  136. if (!swiper.animating) {
  137. swiper.animating = true;
  138. if (!swiper.onSlideToWrapperTransitionEnd) {
  139. swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
  140. if (!swiper || swiper.destroyed) return;
  141. if (e.target !== this) return;
  142. swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
  143. swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);
  144. swiper.onSlideToWrapperTransitionEnd = null;
  145. delete swiper.onSlideToWrapperTransitionEnd;
  146. swiper.transitionEnd(runCallbacks, direction);
  147. };
  148. }
  149. swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
  150. swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);
  151. }
  152. }
  153. return true;
  154. }