slideTo.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. const translate = -snapGrid[snapIndex]; // Normalize slideIndex
  44. if (params.normalizeSlideIndex) {
  45. for (let i = 0; i < slidesGrid.length; i += 1) {
  46. const normalizedTranslate = -Math.floor(translate * 100);
  47. const normalizedGrid = Math.floor(slidesGrid[i] * 100);
  48. const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
  49. if (typeof slidesGrid[i + 1] !== 'undefined') {
  50. if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) {
  51. slideIndex = i;
  52. } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
  53. slideIndex = i + 1;
  54. }
  55. } else if (normalizedTranslate >= normalizedGrid) {
  56. slideIndex = i;
  57. }
  58. }
  59. } // Directions locks
  60. if (swiper.initialized && slideIndex !== activeIndex) {
  61. if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) {
  62. return false;
  63. }
  64. if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
  65. if ((activeIndex || 0) !== slideIndex) return false;
  66. }
  67. }
  68. if (slideIndex !== (previousIndex || 0) && runCallbacks) {
  69. swiper.emit('beforeSlideChangeStart');
  70. } // Update progress
  71. swiper.updateProgress(translate);
  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. swiper.setTransition(speed);
  122. swiper.setTranslate(translate);
  123. swiper.updateActiveIndex(slideIndex);
  124. swiper.updateSlidesClasses();
  125. swiper.emit('beforeTransitionStart', speed, internal);
  126. swiper.transitionStart(runCallbacks, direction);
  127. if (speed === 0) {
  128. swiper.transitionEnd(runCallbacks, direction);
  129. } else if (!swiper.animating) {
  130. swiper.animating = true;
  131. if (!swiper.onSlideToWrapperTransitionEnd) {
  132. swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
  133. if (!swiper || swiper.destroyed) return;
  134. if (e.target !== this) return;
  135. swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
  136. swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);
  137. swiper.onSlideToWrapperTransitionEnd = null;
  138. delete swiper.onSlideToWrapperTransitionEnd;
  139. swiper.transitionEnd(runCallbacks, direction);
  140. };
  141. }
  142. swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
  143. swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);
  144. }
  145. return true;
  146. }