1 |
|
2 | import { getDocument } from 'ssr-window';
|
3 | import $ from '../shared/dom.js';
|
4 | import { extend, now, deleteProps } from '../shared/utils.js';
|
5 | import { getSupport } from '../shared/get-support.js';
|
6 | import { getDevice } from '../shared/get-device.js';
|
7 | import { getBrowser } from '../shared/get-browser.js';
|
8 | import Resize from './modules/resize/resize.js';
|
9 | import Observer from './modules/observer/observer.js';
|
10 | import eventsEmitter from './events-emitter.js';
|
11 | import update from './update/index.js';
|
12 | import translate from './translate/index.js';
|
13 | import transition from './transition/index.js';
|
14 | import slide from './slide/index.js';
|
15 | import loop from './loop/index.js';
|
16 | import grabCursor from './grab-cursor/index.js';
|
17 | import events from './events/index.js';
|
18 | import breakpoints from './breakpoints/index.js';
|
19 | import classes from './classes/index.js';
|
20 | import images from './images/index.js';
|
21 | import checkOverflow from './check-overflow/index.js';
|
22 | import defaults from './defaults.js';
|
23 | import moduleExtendParams from './moduleExtendParams.js';
|
24 | const prototypes = {
|
25 | eventsEmitter,
|
26 | update,
|
27 | translate,
|
28 | transition,
|
29 | slide,
|
30 | loop,
|
31 | grabCursor,
|
32 | events,
|
33 | breakpoints,
|
34 | checkOverflow,
|
35 | classes,
|
36 | images
|
37 | };
|
38 | const extendedDefaults = {};
|
39 |
|
40 | class Swiper {
|
41 | constructor(...args) {
|
42 | let el;
|
43 | let params;
|
44 |
|
45 | if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') {
|
46 | params = args[0];
|
47 | } else {
|
48 | [el, params] = args;
|
49 | }
|
50 |
|
51 | if (!params) params = {};
|
52 | params = extend({}, params);
|
53 | if (el && !params.el) params.el = el;
|
54 |
|
55 | if (params.el && $(params.el).length > 1) {
|
56 | const swipers = [];
|
57 | $(params.el).each(containerEl => {
|
58 | const newParams = extend({}, params, {
|
59 | el: containerEl
|
60 | });
|
61 | swipers.push(new Swiper(newParams));
|
62 | });
|
63 | return swipers;
|
64 | }
|
65 |
|
66 |
|
67 | const swiper = this;
|
68 | swiper.__swiper__ = true;
|
69 | swiper.support = getSupport();
|
70 | swiper.device = getDevice({
|
71 | userAgent: params.userAgent
|
72 | });
|
73 | swiper.browser = getBrowser();
|
74 | swiper.eventsListeners = {};
|
75 | swiper.eventsAnyListeners = [];
|
76 | swiper.modules = [...swiper.__modules__];
|
77 |
|
78 | if (params.modules && Array.isArray(params.modules)) {
|
79 | swiper.modules.push(...params.modules);
|
80 | }
|
81 |
|
82 | const allModulesParams = {};
|
83 | swiper.modules.forEach(mod => {
|
84 | mod({
|
85 | swiper,
|
86 | extendParams: moduleExtendParams(params, allModulesParams),
|
87 | on: swiper.on.bind(swiper),
|
88 | once: swiper.once.bind(swiper),
|
89 | off: swiper.off.bind(swiper),
|
90 | emit: swiper.emit.bind(swiper)
|
91 | });
|
92 | });
|
93 |
|
94 | const swiperParams = extend({}, defaults, allModulesParams);
|
95 |
|
96 | swiper.params = extend({}, swiperParams, extendedDefaults, params);
|
97 | swiper.originalParams = extend({}, swiper.params);
|
98 | swiper.passedParams = extend({}, params);
|
99 |
|
100 | if (swiper.params && swiper.params.on) {
|
101 | Object.keys(swiper.params.on).forEach(eventName => {
|
102 | swiper.on(eventName, swiper.params.on[eventName]);
|
103 | });
|
104 | }
|
105 |
|
106 | if (swiper.params && swiper.params.onAny) {
|
107 | swiper.onAny(swiper.params.onAny);
|
108 | }
|
109 |
|
110 |
|
111 | swiper.$ = $;
|
112 |
|
113 | Object.assign(swiper, {
|
114 | enabled: swiper.params.enabled,
|
115 | el,
|
116 |
|
117 | classNames: [],
|
118 |
|
119 | slides: $(),
|
120 | slidesGrid: [],
|
121 | snapGrid: [],
|
122 | slidesSizesGrid: [],
|
123 |
|
124 |
|
125 | isHorizontal() {
|
126 | return swiper.params.direction === 'horizontal';
|
127 | },
|
128 |
|
129 | isVertical() {
|
130 | return swiper.params.direction === 'vertical';
|
131 | },
|
132 |
|
133 |
|
134 | activeIndex: 0,
|
135 | realIndex: 0,
|
136 |
|
137 | isBeginning: true,
|
138 | isEnd: false,
|
139 |
|
140 | translate: 0,
|
141 | previousTranslate: 0,
|
142 | progress: 0,
|
143 | velocity: 0,
|
144 | animating: false,
|
145 |
|
146 | allowSlideNext: swiper.params.allowSlideNext,
|
147 | allowSlidePrev: swiper.params.allowSlidePrev,
|
148 |
|
149 | touchEvents: function touchEvents() {
|
150 | const touch = ['touchstart', 'touchmove', 'touchend', 'touchcancel'];
|
151 | const desktop = ['pointerdown', 'pointermove', 'pointerup'];
|
152 | swiper.touchEventsTouch = {
|
153 | start: touch[0],
|
154 | move: touch[1],
|
155 | end: touch[2],
|
156 | cancel: touch[3]
|
157 | };
|
158 | swiper.touchEventsDesktop = {
|
159 | start: desktop[0],
|
160 | move: desktop[1],
|
161 | end: desktop[2]
|
162 | };
|
163 | return swiper.support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch : swiper.touchEventsDesktop;
|
164 | }(),
|
165 | touchEventsData: {
|
166 | isTouched: undefined,
|
167 | isMoved: undefined,
|
168 | allowTouchCallbacks: undefined,
|
169 | touchStartTime: undefined,
|
170 | isScrolling: undefined,
|
171 | currentTranslate: undefined,
|
172 | startTranslate: undefined,
|
173 | allowThresholdMove: undefined,
|
174 |
|
175 | focusableElements: swiper.params.focusableElements,
|
176 |
|
177 | lastClickTime: now(),
|
178 | clickTimeout: undefined,
|
179 |
|
180 | velocities: [],
|
181 | allowMomentumBounce: undefined,
|
182 | isTouchEvent: undefined,
|
183 | startMoving: undefined
|
184 | },
|
185 |
|
186 | allowClick: true,
|
187 |
|
188 | allowTouchMove: swiper.params.allowTouchMove,
|
189 | touches: {
|
190 | startX: 0,
|
191 | startY: 0,
|
192 | currentX: 0,
|
193 | currentY: 0,
|
194 | diff: 0
|
195 | },
|
196 |
|
197 | imagesToLoad: [],
|
198 | imagesLoaded: 0
|
199 | });
|
200 | swiper.emit('_swiper');
|
201 |
|
202 | if (swiper.params.init) {
|
203 | swiper.init();
|
204 | }
|
205 |
|
206 |
|
207 | return swiper;
|
208 | }
|
209 |
|
210 | enable() {
|
211 | const swiper = this;
|
212 | if (swiper.enabled) return;
|
213 | swiper.enabled = true;
|
214 |
|
215 | if (swiper.params.grabCursor) {
|
216 | swiper.setGrabCursor();
|
217 | }
|
218 |
|
219 | swiper.emit('enable');
|
220 | }
|
221 |
|
222 | disable() {
|
223 | const swiper = this;
|
224 | if (!swiper.enabled) return;
|
225 | swiper.enabled = false;
|
226 |
|
227 | if (swiper.params.grabCursor) {
|
228 | swiper.unsetGrabCursor();
|
229 | }
|
230 |
|
231 | swiper.emit('disable');
|
232 | }
|
233 |
|
234 | setProgress(progress, speed) {
|
235 | const swiper = this;
|
236 | progress = Math.min(Math.max(progress, 0), 1);
|
237 | const min = swiper.minTranslate();
|
238 | const max = swiper.maxTranslate();
|
239 | const current = (max - min) * progress + min;
|
240 | swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);
|
241 | swiper.updateActiveIndex();
|
242 | swiper.updateSlidesClasses();
|
243 | }
|
244 |
|
245 | emitContainerClasses() {
|
246 | const swiper = this;
|
247 | if (!swiper.params._emitClasses || !swiper.el) return;
|
248 | const cls = swiper.el.className.split(' ').filter(className => {
|
249 | return className.indexOf('swiper') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0;
|
250 | });
|
251 | swiper.emit('_containerClasses', cls.join(' '));
|
252 | }
|
253 |
|
254 | getSlideClasses(slideEl) {
|
255 | const swiper = this;
|
256 | return slideEl.className.split(' ').filter(className => {
|
257 | return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0;
|
258 | }).join(' ');
|
259 | }
|
260 |
|
261 | emitSlidesClasses() {
|
262 | const swiper = this;
|
263 | if (!swiper.params._emitClasses || !swiper.el) return;
|
264 | const updates = [];
|
265 | swiper.slides.each(slideEl => {
|
266 | const classNames = swiper.getSlideClasses(slideEl);
|
267 | updates.push({
|
268 | slideEl,
|
269 | classNames
|
270 | });
|
271 | swiper.emit('_slideClass', slideEl, classNames);
|
272 | });
|
273 | swiper.emit('_slideClasses', updates);
|
274 | }
|
275 |
|
276 | slidesPerViewDynamic(view = 'current', exact = false) {
|
277 | const swiper = this;
|
278 | const {
|
279 | params,
|
280 | slides,
|
281 | slidesGrid,
|
282 | slidesSizesGrid,
|
283 | size: swiperSize,
|
284 | activeIndex
|
285 | } = swiper;
|
286 | let spv = 1;
|
287 |
|
288 | if (params.centeredSlides) {
|
289 | let slideSize = slides[activeIndex].swiperSlideSize;
|
290 | let breakLoop;
|
291 |
|
292 | for (let i = activeIndex + 1; i < slides.length; i += 1) {
|
293 | if (slides[i] && !breakLoop) {
|
294 | slideSize += slides[i].swiperSlideSize;
|
295 | spv += 1;
|
296 | if (slideSize > swiperSize) breakLoop = true;
|
297 | }
|
298 | }
|
299 |
|
300 | for (let i = activeIndex - 1; i >= 0; i -= 1) {
|
301 | if (slides[i] && !breakLoop) {
|
302 | slideSize += slides[i].swiperSlideSize;
|
303 | spv += 1;
|
304 | if (slideSize > swiperSize) breakLoop = true;
|
305 | }
|
306 | }
|
307 | } else {
|
308 |
|
309 | if (view === 'current') {
|
310 | for (let i = activeIndex + 1; i < slides.length; i += 1) {
|
311 | const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
|
312 |
|
313 | if (slideInView) {
|
314 | spv += 1;
|
315 | }
|
316 | }
|
317 | } else {
|
318 |
|
319 | for (let i = activeIndex - 1; i >= 0; i -= 1) {
|
320 | const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
|
321 |
|
322 | if (slideInView) {
|
323 | spv += 1;
|
324 | }
|
325 | }
|
326 | }
|
327 | }
|
328 |
|
329 | return spv;
|
330 | }
|
331 |
|
332 | update() {
|
333 | const swiper = this;
|
334 | if (!swiper || swiper.destroyed) return;
|
335 | const {
|
336 | snapGrid,
|
337 | params
|
338 | } = swiper;
|
339 |
|
340 | if (params.breakpoints) {
|
341 | swiper.setBreakpoint();
|
342 | }
|
343 |
|
344 | swiper.updateSize();
|
345 | swiper.updateSlides();
|
346 | swiper.updateProgress();
|
347 | swiper.updateSlidesClasses();
|
348 |
|
349 | function setTranslate() {
|
350 | const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
|
351 | const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
|
352 | swiper.setTranslate(newTranslate);
|
353 | swiper.updateActiveIndex();
|
354 | swiper.updateSlidesClasses();
|
355 | }
|
356 |
|
357 | let translated;
|
358 |
|
359 | if (swiper.params.freeMode && swiper.params.freeMode.enabled) {
|
360 | setTranslate();
|
361 |
|
362 | if (swiper.params.autoHeight) {
|
363 | swiper.updateAutoHeight();
|
364 | }
|
365 | } else {
|
366 | if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) {
|
367 | translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true);
|
368 | } else {
|
369 | translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
|
370 | }
|
371 |
|
372 | if (!translated) {
|
373 | setTranslate();
|
374 | }
|
375 | }
|
376 |
|
377 | if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
|
378 | swiper.checkOverflow();
|
379 | }
|
380 |
|
381 | swiper.emit('update');
|
382 | }
|
383 |
|
384 | changeDirection(newDirection, needUpdate = true) {
|
385 | const swiper = this;
|
386 | const currentDirection = swiper.params.direction;
|
387 |
|
388 | if (!newDirection) {
|
389 |
|
390 | newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
|
391 | }
|
392 |
|
393 | if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
|
394 | return swiper;
|
395 | }
|
396 |
|
397 | swiper.$el.removeClass(`${swiper.params.containerModifierClass}${currentDirection}`).addClass(`${swiper.params.containerModifierClass}${newDirection}`);
|
398 | swiper.emitContainerClasses();
|
399 | swiper.params.direction = newDirection;
|
400 | swiper.slides.each(slideEl => {
|
401 | if (newDirection === 'vertical') {
|
402 | slideEl.style.width = '';
|
403 | } else {
|
404 | slideEl.style.height = '';
|
405 | }
|
406 | });
|
407 | swiper.emit('changeDirection');
|
408 | if (needUpdate) swiper.update();
|
409 | return swiper;
|
410 | }
|
411 |
|
412 | mount(el) {
|
413 | const swiper = this;
|
414 | if (swiper.mounted) return true;
|
415 |
|
416 | const $el = $(el || swiper.params.el);
|
417 | el = $el[0];
|
418 |
|
419 | if (!el) {
|
420 | return false;
|
421 | }
|
422 |
|
423 | el.swiper = swiper;
|
424 |
|
425 | const getWrapperSelector = () => {
|
426 | return `.${(swiper.params.wrapperClass || '').trim().split(' ').join('.')}`;
|
427 | };
|
428 |
|
429 | const getWrapper = () => {
|
430 | if (el && el.shadowRoot && el.shadowRoot.querySelector) {
|
431 | const res = $(el.shadowRoot.querySelector(getWrapperSelector()));
|
432 |
|
433 | res.children = options => $el.children(options);
|
434 |
|
435 | return res;
|
436 | }
|
437 |
|
438 | return $el.children(getWrapperSelector());
|
439 | };
|
440 |
|
441 |
|
442 | let $wrapperEl = getWrapper();
|
443 |
|
444 | if ($wrapperEl.length === 0 && swiper.params.createElements) {
|
445 | const document = getDocument();
|
446 | const wrapper = document.createElement('div');
|
447 | $wrapperEl = $(wrapper);
|
448 | wrapper.className = swiper.params.wrapperClass;
|
449 | $el.append(wrapper);
|
450 | $el.children(`.${swiper.params.slideClass}`).each(slideEl => {
|
451 | $wrapperEl.append(slideEl);
|
452 | });
|
453 | }
|
454 |
|
455 | Object.assign(swiper, {
|
456 | $el,
|
457 | el,
|
458 | $wrapperEl,
|
459 | wrapperEl: $wrapperEl[0],
|
460 | mounted: true,
|
461 |
|
462 | rtl: el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl',
|
463 | rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'),
|
464 | wrongRTL: $wrapperEl.css('display') === '-webkit-box'
|
465 | });
|
466 | return true;
|
467 | }
|
468 |
|
469 | init(el) {
|
470 | const swiper = this;
|
471 | if (swiper.initialized) return swiper;
|
472 | const mounted = swiper.mount(el);
|
473 | if (mounted === false) return swiper;
|
474 | swiper.emit('beforeInit');
|
475 |
|
476 | if (swiper.params.breakpoints) {
|
477 | swiper.setBreakpoint();
|
478 | }
|
479 |
|
480 |
|
481 | swiper.addClasses();
|
482 |
|
483 | if (swiper.params.loop) {
|
484 | swiper.loopCreate();
|
485 | }
|
486 |
|
487 |
|
488 | swiper.updateSize();
|
489 |
|
490 | swiper.updateSlides();
|
491 |
|
492 | if (swiper.params.watchOverflow) {
|
493 | swiper.checkOverflow();
|
494 | }
|
495 |
|
496 |
|
497 | if (swiper.params.grabCursor && swiper.enabled) {
|
498 | swiper.setGrabCursor();
|
499 | }
|
500 |
|
501 | if (swiper.params.preloadImages) {
|
502 | swiper.preloadImages();
|
503 | }
|
504 |
|
505 |
|
506 | if (swiper.params.loop) {
|
507 | swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params.runCallbacksOnInit, false, true);
|
508 | } else {
|
509 | swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
|
510 | }
|
511 |
|
512 |
|
513 | swiper.attachEvents();
|
514 |
|
515 | swiper.initialized = true;
|
516 |
|
517 | swiper.emit('init');
|
518 | swiper.emit('afterInit');
|
519 | return swiper;
|
520 | }
|
521 |
|
522 | destroy(deleteInstance = true, cleanStyles = true) {
|
523 | const swiper = this;
|
524 | const {
|
525 | params,
|
526 | $el,
|
527 | $wrapperEl,
|
528 | slides
|
529 | } = swiper;
|
530 |
|
531 | if (typeof swiper.params === 'undefined' || swiper.destroyed) {
|
532 | return null;
|
533 | }
|
534 |
|
535 | swiper.emit('beforeDestroy');
|
536 |
|
537 | swiper.initialized = false;
|
538 |
|
539 | swiper.detachEvents();
|
540 |
|
541 | if (params.loop) {
|
542 | swiper.loopDestroy();
|
543 | }
|
544 |
|
545 |
|
546 | if (cleanStyles) {
|
547 | swiper.removeClasses();
|
548 | $el.removeAttr('style');
|
549 | $wrapperEl.removeAttr('style');
|
550 |
|
551 | if (slides && slides.length) {
|
552 | slides.removeClass([params.slideVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass].join(' ')).removeAttr('style').removeAttr('data-swiper-slide-index');
|
553 | }
|
554 | }
|
555 |
|
556 | swiper.emit('destroy');
|
557 |
|
558 | Object.keys(swiper.eventsListeners).forEach(eventName => {
|
559 | swiper.off(eventName);
|
560 | });
|
561 |
|
562 | if (deleteInstance !== false) {
|
563 | swiper.$el[0].swiper = null;
|
564 | deleteProps(swiper);
|
565 | }
|
566 |
|
567 | swiper.destroyed = true;
|
568 | return null;
|
569 | }
|
570 |
|
571 | static extendDefaults(newDefaults) {
|
572 | extend(extendedDefaults, newDefaults);
|
573 | }
|
574 |
|
575 | static get extendedDefaults() {
|
576 | return extendedDefaults;
|
577 | }
|
578 |
|
579 | static get defaults() {
|
580 | return defaults;
|
581 | }
|
582 |
|
583 | static installModule(mod) {
|
584 | if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = [];
|
585 | const modules = Swiper.prototype.__modules__;
|
586 |
|
587 | if (typeof mod === 'function' && modules.indexOf(mod) < 0) {
|
588 | modules.push(mod);
|
589 | }
|
590 | }
|
591 |
|
592 | static use(module) {
|
593 | if (Array.isArray(module)) {
|
594 | module.forEach(m => Swiper.installModule(m));
|
595 | return Swiper;
|
596 | }
|
597 |
|
598 | Swiper.installModule(module);
|
599 | return Swiper;
|
600 | }
|
601 |
|
602 | }
|
603 |
|
604 | Object.keys(prototypes).forEach(prototypeGroup => {
|
605 | Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => {
|
606 | Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
|
607 | });
|
608 | });
|
609 | Swiper.use([Resize, Observer]);
|
610 | export default Swiper; |
\ | No newline at end of file |