thumbs.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. import { isObject } from '../../shared/utils.js';
  2. import $ from '../../shared/dom.js';
  3. export default function Thumb({
  4. swiper,
  5. extendParams,
  6. on
  7. }) {
  8. extendParams({
  9. thumbs: {
  10. swiper: null,
  11. multipleActiveThumbs: true,
  12. autoScrollOffset: 0,
  13. slideThumbActiveClass: 'swiper-slide-thumb-active',
  14. thumbsContainerClass: 'swiper-thumbs'
  15. }
  16. });
  17. let initialized = false;
  18. let swiperCreated = false;
  19. swiper.thumbs = {
  20. swiper: null
  21. };
  22. function onThumbClick() {
  23. const thumbsSwiper = swiper.thumbs.swiper;
  24. if (!thumbsSwiper) return;
  25. const clickedIndex = thumbsSwiper.clickedIndex;
  26. const clickedSlide = thumbsSwiper.clickedSlide;
  27. if (clickedSlide && $(clickedSlide).hasClass(swiper.params.thumbs.slideThumbActiveClass)) return;
  28. if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;
  29. let slideToIndex;
  30. if (thumbsSwiper.params.loop) {
  31. slideToIndex = parseInt($(thumbsSwiper.clickedSlide).attr('data-swiper-slide-index'), 10);
  32. } else {
  33. slideToIndex = clickedIndex;
  34. }
  35. if (swiper.params.loop) {
  36. let currentIndex = swiper.activeIndex;
  37. if (swiper.slides.eq(currentIndex).hasClass(swiper.params.slideDuplicateClass)) {
  38. swiper.loopFix(); // eslint-disable-next-line
  39. swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
  40. currentIndex = swiper.activeIndex;
  41. }
  42. const prevIndex = swiper.slides.eq(currentIndex).prevAll(`[data-swiper-slide-index="${slideToIndex}"]`).eq(0).index();
  43. const nextIndex = swiper.slides.eq(currentIndex).nextAll(`[data-swiper-slide-index="${slideToIndex}"]`).eq(0).index();
  44. if (typeof prevIndex === 'undefined') slideToIndex = nextIndex;else if (typeof nextIndex === 'undefined') slideToIndex = prevIndex;else if (nextIndex - currentIndex < currentIndex - prevIndex) slideToIndex = nextIndex;else slideToIndex = prevIndex;
  45. }
  46. swiper.slideTo(slideToIndex);
  47. }
  48. function init() {
  49. const {
  50. thumbs: thumbsParams
  51. } = swiper.params;
  52. if (initialized) return false;
  53. initialized = true;
  54. const SwiperClass = swiper.constructor;
  55. if (thumbsParams.swiper instanceof SwiperClass) {
  56. swiper.thumbs.swiper = thumbsParams.swiper;
  57. Object.assign(swiper.thumbs.swiper.originalParams, {
  58. watchSlidesProgress: true,
  59. slideToClickedSlide: false
  60. });
  61. Object.assign(swiper.thumbs.swiper.params, {
  62. watchSlidesProgress: true,
  63. slideToClickedSlide: false
  64. });
  65. } else if (isObject(thumbsParams.swiper)) {
  66. const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper);
  67. Object.assign(thumbsSwiperParams, {
  68. watchSlidesProgress: true,
  69. slideToClickedSlide: false
  70. });
  71. swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams);
  72. swiperCreated = true;
  73. }
  74. swiper.thumbs.swiper.$el.addClass(swiper.params.thumbs.thumbsContainerClass);
  75. swiper.thumbs.swiper.on('tap', onThumbClick);
  76. return true;
  77. }
  78. function update(initial) {
  79. const thumbsSwiper = swiper.thumbs.swiper;
  80. if (!thumbsSwiper) return;
  81. const slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' ? thumbsSwiper.slidesPerViewDynamic() : thumbsSwiper.params.slidesPerView;
  82. const autoScrollOffset = swiper.params.thumbs.autoScrollOffset;
  83. const useOffset = autoScrollOffset && !thumbsSwiper.params.loop;
  84. if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {
  85. let currentThumbsIndex = thumbsSwiper.activeIndex;
  86. let newThumbsIndex;
  87. let direction;
  88. if (thumbsSwiper.params.loop) {
  89. if (thumbsSwiper.slides.eq(currentThumbsIndex).hasClass(thumbsSwiper.params.slideDuplicateClass)) {
  90. thumbsSwiper.loopFix(); // eslint-disable-next-line
  91. thumbsSwiper._clientLeft = thumbsSwiper.$wrapperEl[0].clientLeft;
  92. currentThumbsIndex = thumbsSwiper.activeIndex;
  93. } // Find actual thumbs index to slide to
  94. const prevThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).prevAll(`[data-swiper-slide-index="${swiper.realIndex}"]`).eq(0).index();
  95. const nextThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).nextAll(`[data-swiper-slide-index="${swiper.realIndex}"]`).eq(0).index();
  96. if (typeof prevThumbsIndex === 'undefined') {
  97. newThumbsIndex = nextThumbsIndex;
  98. } else if (typeof nextThumbsIndex === 'undefined') {
  99. newThumbsIndex = prevThumbsIndex;
  100. } else if (nextThumbsIndex - currentThumbsIndex === currentThumbsIndex - prevThumbsIndex) {
  101. newThumbsIndex = thumbsSwiper.params.slidesPerGroup > 1 ? nextThumbsIndex : currentThumbsIndex;
  102. } else if (nextThumbsIndex - currentThumbsIndex < currentThumbsIndex - prevThumbsIndex) {
  103. newThumbsIndex = nextThumbsIndex;
  104. } else {
  105. newThumbsIndex = prevThumbsIndex;
  106. }
  107. direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';
  108. } else {
  109. newThumbsIndex = swiper.realIndex;
  110. direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';
  111. }
  112. if (useOffset) {
  113. newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;
  114. }
  115. if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) {
  116. if (thumbsSwiper.params.centeredSlides) {
  117. if (newThumbsIndex > currentThumbsIndex) {
  118. newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;
  119. } else {
  120. newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;
  121. }
  122. } else if (newThumbsIndex > currentThumbsIndex && thumbsSwiper.params.slidesPerGroup === 1) {// newThumbsIndex = newThumbsIndex - slidesPerView + 1;
  123. }
  124. thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);
  125. }
  126. } // Activate thumbs
  127. let thumbsToActivate = 1;
  128. const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;
  129. if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {
  130. thumbsToActivate = swiper.params.slidesPerView;
  131. }
  132. if (!swiper.params.thumbs.multipleActiveThumbs) {
  133. thumbsToActivate = 1;
  134. }
  135. thumbsToActivate = Math.floor(thumbsToActivate);
  136. thumbsSwiper.slides.removeClass(thumbActiveClass);
  137. if (thumbsSwiper.params.loop || thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled) {
  138. for (let i = 0; i < thumbsToActivate; i += 1) {
  139. thumbsSwiper.$wrapperEl.children(`[data-swiper-slide-index="${swiper.realIndex + i}"]`).addClass(thumbActiveClass);
  140. }
  141. } else {
  142. for (let i = 0; i < thumbsToActivate; i += 1) {
  143. thumbsSwiper.slides.eq(swiper.realIndex + i).addClass(thumbActiveClass);
  144. }
  145. }
  146. }
  147. on('beforeInit', () => {
  148. const {
  149. thumbs
  150. } = swiper.params;
  151. if (!thumbs || !thumbs.swiper) return;
  152. init();
  153. update(true);
  154. });
  155. on('slideChange update resize observerUpdate', () => {
  156. if (!swiper.thumbs.swiper) return;
  157. update();
  158. });
  159. on('setTransition', (_s, duration) => {
  160. const thumbsSwiper = swiper.thumbs.swiper;
  161. if (!thumbsSwiper) return;
  162. thumbsSwiper.setTransition(duration);
  163. });
  164. on('beforeDestroy', () => {
  165. const thumbsSwiper = swiper.thumbs.swiper;
  166. if (!thumbsSwiper) return;
  167. if (swiperCreated && thumbsSwiper) {
  168. thumbsSwiper.destroy();
  169. }
  170. });
  171. Object.assign(swiper.thumbs, {
  172. init,
  173. update
  174. });
  175. }