slideTo.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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 === 'string') {
  4. index = parseInt(index, 10);
  5. }
  6. const swiper = this;
  7. let slideIndex = index;
  8. if (slideIndex < 0) slideIndex = 0;
  9. const {
  10. params,
  11. snapGrid,
  12. slidesGrid,
  13. previousIndex,
  14. activeIndex,
  15. rtlTranslate: rtl,
  16. wrapperEl,
  17. enabled
  18. } = swiper;
  19. if (swiper.animating && params.preventInteractionOnTransition || !enabled && !internal && !initial) {
  20. return false;
  21. }
  22. const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
  23. let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
  24. if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
  25. const translate = -snapGrid[snapIndex];
  26. // Normalize slideIndex
  27. if (params.normalizeSlideIndex) {
  28. for (let i = 0; i < slidesGrid.length; i += 1) {
  29. const normalizedTranslate = -Math.floor(translate * 100);
  30. const normalizedGrid = Math.floor(slidesGrid[i] * 100);
  31. const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
  32. if (typeof slidesGrid[i + 1] !== 'undefined') {
  33. if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) {
  34. slideIndex = i;
  35. } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
  36. slideIndex = i + 1;
  37. }
  38. } else if (normalizedTranslate >= normalizedGrid) {
  39. slideIndex = i;
  40. }
  41. }
  42. }
  43. // Directions locks
  44. if (swiper.initialized && slideIndex !== activeIndex) {
  45. if (!swiper.allowSlideNext && (rtl ? translate > swiper.translate && translate > swiper.minTranslate() : translate < swiper.translate && translate < swiper.minTranslate())) {
  46. return false;
  47. }
  48. if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
  49. if ((activeIndex || 0) !== slideIndex) {
  50. return false;
  51. }
  52. }
  53. }
  54. if (slideIndex !== (previousIndex || 0) && runCallbacks) {
  55. swiper.emit('beforeSlideChangeStart');
  56. }
  57. // Update progress
  58. swiper.updateProgress(translate);
  59. let direction;
  60. if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset';
  61. // Update Index
  62. if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {
  63. swiper.updateActiveIndex(slideIndex);
  64. // Update Height
  65. if (params.autoHeight) {
  66. swiper.updateAutoHeight();
  67. }
  68. swiper.updateSlidesClasses();
  69. if (params.effect !== 'slide') {
  70. swiper.setTranslate(translate);
  71. }
  72. if (direction !== 'reset') {
  73. swiper.transitionStart(runCallbacks, direction);
  74. swiper.transitionEnd(runCallbacks, direction);
  75. }
  76. return false;
  77. }
  78. if (params.cssMode) {
  79. const isH = swiper.isHorizontal();
  80. const t = rtl ? translate : -translate;
  81. if (speed === 0) {
  82. const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
  83. if (isVirtual) {
  84. swiper.wrapperEl.style.scrollSnapType = 'none';
  85. swiper._immediateVirtual = true;
  86. }
  87. if (isVirtual && !swiper._cssModeVirtualInitialSet && swiper.params.initialSlide > 0) {
  88. swiper._cssModeVirtualInitialSet = true;
  89. requestAnimationFrame(() => {
  90. wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
  91. });
  92. } else {
  93. wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
  94. }
  95. if (isVirtual) {
  96. requestAnimationFrame(() => {
  97. swiper.wrapperEl.style.scrollSnapType = '';
  98. swiper._immediateVirtual = false;
  99. });
  100. }
  101. } else {
  102. if (!swiper.support.smoothScroll) {
  103. animateCSSModeScroll({
  104. swiper,
  105. targetPosition: t,
  106. side: isH ? 'left' : 'top'
  107. });
  108. return true;
  109. }
  110. wrapperEl.scrollTo({
  111. [isH ? 'left' : 'top']: t,
  112. behavior: 'smooth'
  113. });
  114. }
  115. return true;
  116. }
  117. swiper.setTransition(speed);
  118. swiper.setTranslate(translate);
  119. swiper.updateActiveIndex(slideIndex);
  120. swiper.updateSlidesClasses();
  121. swiper.emit('beforeTransitionStart', speed, internal);
  122. swiper.transitionStart(runCallbacks, direction);
  123. if (speed === 0) {
  124. swiper.transitionEnd(runCallbacks, direction);
  125. } else if (!swiper.animating) {
  126. swiper.animating = true;
  127. if (!swiper.onSlideToWrapperTransitionEnd) {
  128. swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
  129. if (!swiper || swiper.destroyed) return;
  130. if (e.target !== this) return;
  131. swiper.wrapperEl.removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
  132. swiper.onSlideToWrapperTransitionEnd = null;
  133. delete swiper.onSlideToWrapperTransitionEnd;
  134. swiper.transitionEnd(runCallbacks, direction);
  135. };
  136. }
  137. swiper.wrapperEl.addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
  138. }
  139. return true;
  140. }