thumbs.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import { getDocument } from 'ssr-window';
  2. import { elementChildren, isObject } from '../../shared/utils.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 || thumbsSwiper.destroyed) return;
  25. const clickedIndex = thumbsSwiper.clickedIndex;
  26. const clickedSlide = thumbsSwiper.clickedSlide;
  27. if (clickedSlide && clickedSlide.classList.contains(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.getAttribute('data-swiper-slide-index'), 10);
  32. } else {
  33. slideToIndex = clickedIndex;
  34. }
  35. if (swiper.params.loop) {
  36. swiper.slideToLoop(slideToIndex);
  37. } else {
  38. swiper.slideTo(slideToIndex);
  39. }
  40. }
  41. function init() {
  42. const {
  43. thumbs: thumbsParams
  44. } = swiper.params;
  45. if (initialized) return false;
  46. initialized = true;
  47. const SwiperClass = swiper.constructor;
  48. if (thumbsParams.swiper instanceof SwiperClass) {
  49. swiper.thumbs.swiper = thumbsParams.swiper;
  50. Object.assign(swiper.thumbs.swiper.originalParams, {
  51. watchSlidesProgress: true,
  52. slideToClickedSlide: false
  53. });
  54. Object.assign(swiper.thumbs.swiper.params, {
  55. watchSlidesProgress: true,
  56. slideToClickedSlide: false
  57. });
  58. swiper.thumbs.swiper.update();
  59. } else if (isObject(thumbsParams.swiper)) {
  60. const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper);
  61. Object.assign(thumbsSwiperParams, {
  62. watchSlidesProgress: true,
  63. slideToClickedSlide: false
  64. });
  65. swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams);
  66. swiperCreated = true;
  67. }
  68. swiper.thumbs.swiper.el.classList.add(swiper.params.thumbs.thumbsContainerClass);
  69. swiper.thumbs.swiper.on('tap', onThumbClick);
  70. return true;
  71. }
  72. function update(initial) {
  73. const thumbsSwiper = swiper.thumbs.swiper;
  74. if (!thumbsSwiper || thumbsSwiper.destroyed) return;
  75. const slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' ? thumbsSwiper.slidesPerViewDynamic() : thumbsSwiper.params.slidesPerView;
  76. // Activate thumbs
  77. let thumbsToActivate = 1;
  78. const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;
  79. if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {
  80. thumbsToActivate = swiper.params.slidesPerView;
  81. }
  82. if (!swiper.params.thumbs.multipleActiveThumbs) {
  83. thumbsToActivate = 1;
  84. }
  85. thumbsToActivate = Math.floor(thumbsToActivate);
  86. thumbsSwiper.slides.forEach(slideEl => slideEl.classList.remove(thumbActiveClass));
  87. if (thumbsSwiper.params.loop || thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled) {
  88. for (let i = 0; i < thumbsToActivate; i += 1) {
  89. elementChildren(thumbsSwiper.slidesEl, `[data-swiper-slide-index="${swiper.realIndex + i}"]`).forEach(slideEl => {
  90. slideEl.classList.add(thumbActiveClass);
  91. });
  92. }
  93. } else {
  94. for (let i = 0; i < thumbsToActivate; i += 1) {
  95. if (thumbsSwiper.slides[swiper.realIndex + i]) {
  96. thumbsSwiper.slides[swiper.realIndex + i].classList.add(thumbActiveClass);
  97. }
  98. }
  99. }
  100. const autoScrollOffset = swiper.params.thumbs.autoScrollOffset;
  101. const useOffset = autoScrollOffset && !thumbsSwiper.params.loop;
  102. if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {
  103. const currentThumbsIndex = thumbsSwiper.activeIndex;
  104. let newThumbsIndex;
  105. let direction;
  106. if (thumbsSwiper.params.loop) {
  107. const newThumbsSlide = thumbsSwiper.slides.filter(slideEl => slideEl.getAttribute('data-swiper-slide-index') === `${swiper.realIndex}`)[0];
  108. newThumbsIndex = thumbsSwiper.slides.indexOf(newThumbsSlide);
  109. direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';
  110. } else {
  111. newThumbsIndex = swiper.realIndex;
  112. direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';
  113. }
  114. if (useOffset) {
  115. newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;
  116. }
  117. if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) {
  118. if (thumbsSwiper.params.centeredSlides) {
  119. if (newThumbsIndex > currentThumbsIndex) {
  120. newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;
  121. } else {
  122. newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;
  123. }
  124. } else if (newThumbsIndex > currentThumbsIndex && thumbsSwiper.params.slidesPerGroup === 1) {
  125. // newThumbsIndex = newThumbsIndex - slidesPerView + 1;
  126. }
  127. thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);
  128. }
  129. }
  130. }
  131. on('beforeInit', () => {
  132. const {
  133. thumbs
  134. } = swiper.params;
  135. if (!thumbs || !thumbs.swiper) return;
  136. if (typeof thumbs.swiper === 'string' || thumbs.swiper instanceof HTMLElement) {
  137. const document = getDocument();
  138. const getThumbsElementAndInit = () => {
  139. const thumbsElement = typeof thumbs.swiper === 'string' ? document.querySelector(thumbs.swiper) : thumbs.swiper;
  140. if (thumbsElement && thumbsElement.swiper) {
  141. thumbs.swiper = thumbsElement.swiper;
  142. init();
  143. update(true);
  144. } else if (thumbsElement) {
  145. const onThumbsSwiper = e => {
  146. thumbs.swiper = e.detail[0];
  147. thumbsElement.removeEventListener('init', onThumbsSwiper);
  148. init();
  149. update(true);
  150. thumbs.swiper.update();
  151. swiper.update();
  152. };
  153. thumbsElement.addEventListener('init', onThumbsSwiper);
  154. }
  155. return thumbsElement;
  156. };
  157. const watchForThumbsToAppear = () => {
  158. if (swiper.destroyed) return;
  159. const thumbsElement = getThumbsElementAndInit();
  160. if (!thumbsElement) {
  161. requestAnimationFrame(watchForThumbsToAppear);
  162. }
  163. };
  164. requestAnimationFrame(watchForThumbsToAppear);
  165. } else {
  166. init();
  167. update(true);
  168. }
  169. });
  170. on('slideChange update resize observerUpdate', () => {
  171. update();
  172. });
  173. on('setTransition', (_s, duration) => {
  174. const thumbsSwiper = swiper.thumbs.swiper;
  175. if (!thumbsSwiper || thumbsSwiper.destroyed) return;
  176. thumbsSwiper.setTransition(duration);
  177. });
  178. on('beforeDestroy', () => {
  179. const thumbsSwiper = swiper.thumbs.swiper;
  180. if (!thumbsSwiper || thumbsSwiper.destroyed) return;
  181. if (swiperCreated) {
  182. thumbsSwiper.destroy();
  183. }
  184. });
  185. Object.assign(swiper.thumbs, {
  186. init,
  187. update
  188. });
  189. }