thumbs.js 7.3 KB

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