slideTo.js 5.2 KB

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