loopFix.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. export default function loopFix({
  2. slideRealIndex,
  3. slideTo = true,
  4. direction,
  5. setTranslate,
  6. activeSlideIndex,
  7. byController,
  8. byMousewheel
  9. } = {}) {
  10. const swiper = this;
  11. if (!swiper.params.loop) return;
  12. swiper.emit('beforeLoopFix');
  13. const {
  14. slides,
  15. allowSlidePrev,
  16. allowSlideNext,
  17. slidesEl,
  18. params
  19. } = swiper;
  20. swiper.allowSlidePrev = true;
  21. swiper.allowSlideNext = true;
  22. if (swiper.virtual && params.virtual.enabled) {
  23. if (slideTo) {
  24. if (!params.centeredSlides && swiper.snapIndex === 0) {
  25. swiper.slideTo(swiper.virtual.slides.length, 0, false, true);
  26. } else if (params.centeredSlides && swiper.snapIndex < params.slidesPerView) {
  27. swiper.slideTo(swiper.virtual.slides.length + swiper.snapIndex, 0, false, true);
  28. } else if (swiper.snapIndex === swiper.snapGrid.length - 1) {
  29. swiper.slideTo(swiper.virtual.slidesBefore, 0, false, true);
  30. }
  31. }
  32. swiper.allowSlidePrev = allowSlidePrev;
  33. swiper.allowSlideNext = allowSlideNext;
  34. swiper.emit('loopFix');
  35. return;
  36. }
  37. const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10));
  38. let loopedSlides = params.loopedSlides || slidesPerView;
  39. if (loopedSlides % params.slidesPerGroup !== 0) {
  40. loopedSlides += params.slidesPerGroup - loopedSlides % params.slidesPerGroup;
  41. }
  42. swiper.loopedSlides = loopedSlides;
  43. const prependSlidesIndexes = [];
  44. const appendSlidesIndexes = [];
  45. let activeIndex = swiper.activeIndex;
  46. if (typeof activeSlideIndex === 'undefined') {
  47. activeSlideIndex = swiper.getSlideIndex(swiper.slides.filter(el => el.classList.contains(params.slideActiveClass))[0]);
  48. } else {
  49. activeIndex = activeSlideIndex;
  50. }
  51. const isNext = direction === 'next' || !direction;
  52. const isPrev = direction === 'prev' || !direction;
  53. let slidesPrepended = 0;
  54. let slidesAppended = 0;
  55. // prepend last slides before start
  56. if (activeSlideIndex < loopedSlides) {
  57. slidesPrepended = Math.max(loopedSlides - activeSlideIndex, params.slidesPerGroup);
  58. for (let i = 0; i < loopedSlides - activeSlideIndex; i += 1) {
  59. const index = i - Math.floor(i / slides.length) * slides.length;
  60. prependSlidesIndexes.push(slides.length - index - 1);
  61. }
  62. } else if (activeSlideIndex /* + slidesPerView */ > swiper.slides.length - loopedSlides * 2) {
  63. slidesAppended = Math.max(activeSlideIndex - (swiper.slides.length - loopedSlides * 2), params.slidesPerGroup);
  64. for (let i = 0; i < slidesAppended; i += 1) {
  65. const index = i - Math.floor(i / slides.length) * slides.length;
  66. appendSlidesIndexes.push(index);
  67. }
  68. }
  69. if (isPrev) {
  70. prependSlidesIndexes.forEach(index => {
  71. swiper.slides[index].swiperLoopMoveDOM = true;
  72. slidesEl.prepend(swiper.slides[index]);
  73. swiper.slides[index].swiperLoopMoveDOM = false;
  74. });
  75. }
  76. if (isNext) {
  77. appendSlidesIndexes.forEach(index => {
  78. swiper.slides[index].swiperLoopMoveDOM = true;
  79. slidesEl.append(swiper.slides[index]);
  80. swiper.slides[index].swiperLoopMoveDOM = false;
  81. });
  82. }
  83. swiper.recalcSlides();
  84. if (params.slidesPerView === 'auto') {
  85. swiper.updateSlides();
  86. }
  87. if (params.watchSlidesProgress) {
  88. swiper.updateSlidesOffset();
  89. }
  90. if (slideTo) {
  91. if (prependSlidesIndexes.length > 0 && isPrev) {
  92. if (typeof slideRealIndex === 'undefined') {
  93. const currentSlideTranslate = swiper.slidesGrid[activeIndex];
  94. const newSlideTranslate = swiper.slidesGrid[activeIndex + slidesPrepended];
  95. const diff = newSlideTranslate - currentSlideTranslate;
  96. if (byMousewheel) {
  97. swiper.setTranslate(swiper.translate - diff);
  98. } else {
  99. swiper.slideTo(activeIndex + slidesPrepended, 0, false, true);
  100. if (setTranslate) {
  101. swiper.touches[swiper.isHorizontal() ? 'startX' : 'startY'] += diff;
  102. }
  103. }
  104. } else {
  105. if (setTranslate) {
  106. swiper.slideToLoop(slideRealIndex, 0, false, true);
  107. }
  108. }
  109. } else if (appendSlidesIndexes.length > 0 && isNext) {
  110. if (typeof slideRealIndex === 'undefined') {
  111. const currentSlideTranslate = swiper.slidesGrid[activeIndex];
  112. const newSlideTranslate = swiper.slidesGrid[activeIndex - slidesAppended];
  113. const diff = newSlideTranslate - currentSlideTranslate;
  114. if (byMousewheel) {
  115. swiper.setTranslate(swiper.translate - diff);
  116. } else {
  117. swiper.slideTo(activeIndex - slidesAppended, 0, false, true);
  118. if (setTranslate) {
  119. swiper.touches[swiper.isHorizontal() ? 'startX' : 'startY'] += diff;
  120. }
  121. }
  122. } else {
  123. swiper.slideToLoop(slideRealIndex, 0, false, true);
  124. }
  125. }
  126. }
  127. swiper.allowSlidePrev = allowSlidePrev;
  128. swiper.allowSlideNext = allowSlideNext;
  129. if (swiper.controller && swiper.controller.control && !byController) {
  130. const loopParams = {
  131. slideRealIndex,
  132. slideTo: false,
  133. direction,
  134. setTranslate,
  135. activeSlideIndex,
  136. byController: true
  137. };
  138. if (Array.isArray(swiper.controller.control)) {
  139. swiper.controller.control.forEach(c => {
  140. if (!c.destroyed && c.params.loop) c.loopFix(loopParams);
  141. });
  142. } else if (swiper.controller.control instanceof swiper.constructor && swiper.controller.control.params.loop) {
  143. swiper.controller.control.loopFix(loopParams);
  144. }
  145. }
  146. swiper.emit('loopFix');
  147. }