Skip to content

Commit

Permalink
feat(core): all new loop mode without slides duplication
Browse files Browse the repository at this point in the history
The following parameters have been removed:

  loopAdditionalSlides
  loopedSlides
  loopedSlidesLimit
  loopFillGroupWithBlank
  loopPreventsSlide
  slideBlankClass
  • Loading branch information
nolimits4web committed Nov 21, 2022
1 parent 329c956 commit f57aa3b
Show file tree
Hide file tree
Showing 33 changed files with 242 additions and 431 deletions.
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const rules = {
'no-lonely-if': 'off',
'no-param-reassign': 'off',
'no-underscore-dangle': 'off',
'prefer-object-spread': 'off',
Expand Down
6 changes: 0 additions & 6 deletions src/components-shared/params-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ const paramsList = [
'preventClicksPropagation',
'_slideToClickedSlide',
'_loop',
'_loopAdditionalSlides',
'_loopedSlides',
'_loopedSlidesLimit',
'_loopFillGroupWithBlank',
'loopPreventsSlide',
'_rewind',
'_allowSlidePrev',
'_allowSlideNext',
Expand All @@ -78,7 +73,6 @@ const paramsList = [
'passiveListeners',
'containerModifierClass',
'slideClass',
'slideBlankClass',
'slideActiveClass',
'slideDuplicateActiveClass',
'slideVisibleClass',
Expand Down
3 changes: 3 additions & 0 deletions src/components-shared/update-swiper.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ function updateSwiper({
virtual.slides = slides;
virtual.update(true);
}
if (changedParams.includes('children') && slides && currentParams.loop) {
loopNeedReloop = true;
}

if (needThumbsInit) {
const initialized = thumbs.init();
Expand Down
5 changes: 2 additions & 3 deletions src/core/breakpoints/setBreakpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const isGridEnabled = (swiper, params) => {

export default function setBreakpoint() {
const swiper = this;
const { activeIndex, initialized, loopedSlides = 0, params, $el } = swiper;
const { realIndex, initialized, params, $el } = swiper;
const breakpoints = params.breakpoints;
if (!breakpoints || (breakpoints && Object.keys(breakpoints).length === 0)) return;

Expand Down Expand Up @@ -80,9 +80,8 @@ export default function setBreakpoint() {

if (needsReLoop && initialized) {
swiper.loopDestroy();
swiper.loopCreate();
swiper.loopCreate(realIndex);
swiper.updateSlides();
swiper.slideTo(activeIndex - loopedSlides + swiper.loopedSlides, 0, false);
}

swiper.emit('breakpoint', breakpointParams);
Expand Down
25 changes: 11 additions & 14 deletions src/core/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,12 @@ class Swiper {
return swiper;
}

recalcSlides() {
const swiper = this;
const { $slidesEl, params } = swiper;
swiper.slides = $slidesEl.children(`.${params.slideClass}, swiper-slide`);
}

enable() {
const swiper = this;
if (swiper.enabled) return;
Expand Down Expand Up @@ -476,6 +482,7 @@ class Swiper {
el,
$wrapperEl,
wrapperEl: $wrapperEl[0],
$slidesEl: swiper.isElement ? $el : $wrapperEl,
mounted: true,

// RTL
Expand Down Expand Up @@ -506,11 +513,6 @@ class Swiper {
// Add Classes
swiper.addClasses();

// Create loop
if (swiper.params.loop) {
swiper.loopCreate();
}

// Update size
swiper.updateSize();

Expand All @@ -527,16 +529,11 @@ class Swiper {
}

// Slide To Initial Slide
swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);

// Create loop
if (swiper.params.loop) {
swiper.slideTo(
swiper.params.initialSlide + swiper.loopedSlides,
0,
swiper.params.runCallbacksOnInit,
false,
true,
);
} else {
swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
swiper.loopCreate();
}

// Attach events
Expand Down
6 changes: 0 additions & 6 deletions src/core/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,6 @@ export default {

// loop
loop: false,
loopAdditionalSlides: 0,
loopedSlides: null,
loopedSlidesLimit: true,
loopFillGroupWithBlank: false,
loopPreventsSlide: true,

// rewind
rewind: false,
Expand All @@ -123,7 +118,6 @@ export default {
// NS
containerModifierClass: 'swiper-', // NEW
slideClass: 'swiper-slide',
slideBlankClass: 'swiper-slide-invisible-blank',
slideActiveClass: 'swiper-slide-active',
slideDuplicateActiveClass: 'swiper-slide-duplicate-active',
slideVisibleClass: 'swiper-slide-visible',
Expand Down
6 changes: 5 additions & 1 deletion src/core/events/onResize.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ export default function onResize() {
) {
swiper.slideTo(swiper.slides.length - 1, 0, false, true);
} else {
swiper.slideTo(swiper.activeIndex, 0, false, true);
if (swiper.params.loop) {
swiper.slideToLoop(swiper.realIndex, 0, false, true);
} else {
swiper.slideTo(swiper.activeIndex, 0, false, true);
}
}

if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
Expand Down
61 changes: 5 additions & 56 deletions src/core/loop/loopCreate.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,16 @@
import { getDocument } from 'ssr-window';
import $ from '../../shared/dom.js';

export default function loopCreate() {
export default function loopCreate(slideRealIndex) {
const swiper = this;
const document = getDocument();
const { params, $wrapperEl } = swiper;
// Remove duplicated slides
const $selector =
$wrapperEl.children().length > 0 ? $($wrapperEl.children()[0].parentNode) : $wrapperEl;
$selector
.children(
`.${params.slideClass}.${params.slideDuplicateClass}, swiper-slide.${params.slideDuplicateClass}`,
)
.remove();
const { params, $slidesEl } = swiper;
if (!params.loop || (swiper.virtual && swiper.params.virtual.enabled)) return;

let slides = $selector.children(`.${params.slideClass}, swiper-slide`);

if (params.loopFillGroupWithBlank) {
const blankSlidesNum = params.slidesPerGroup - (slides.length % params.slidesPerGroup);
if (blankSlidesNum !== params.slidesPerGroup) {
for (let i = 0; i < blankSlidesNum; i += 1) {
let blankNode;
if (swiper.isElement) {
blankNode = $(document.createElement('swiper-slide')).addClass(
`${params.slideBlankClass}`,
);
} else {
blankNode = $(document.createElement('div')).addClass(
`${params.slideClass} ${params.slideBlankClass}`,
);
}
$selector.append(blankNode);
}
slides = $selector.children(`.${params.slideClass}, swiper-slide`);
}
}

if (params.slidesPerView === 'auto' && !params.loopedSlides) params.loopedSlides = slides.length;

swiper.loopedSlides = Math.ceil(parseFloat(params.loopedSlides || params.slidesPerView, 10));
swiper.loopedSlides += params.loopAdditionalSlides;
if (swiper.loopedSlides > slides.length && swiper.params.loopedSlidesLimit) {
swiper.loopedSlides = slides.length;
}

const prependSlides = [];
const appendSlides = [];
const slides = $slidesEl.children(`.${params.slideClass}, swiper-slide`);

slides.each((el, index) => {
const slide = $(el);
slide.attr('data-swiper-slide-index', index);
});

for (let i = 0; i < swiper.loopedSlides; i += 1) {
const index = i - Math.floor(i / slides.length) * slides.length;
appendSlides.push(slides.eq(index)[0]);
prependSlides.unshift(slides.eq(slides.length - index - 1)[0]);
}

for (let i = 0; i < appendSlides.length; i += 1) {
$selector.append($(appendSlides[i].cloneNode(true)).addClass(params.slideDuplicateClass));
}
for (let i = prependSlides.length - 1; i >= 0; i -= 1) {
$selector.prepend($(prependSlides[i].cloneNode(true)).addClass(params.slideDuplicateClass));
}
swiper.loopFix(slideRealIndex);
}
23 changes: 17 additions & 6 deletions src/core/loop/loopDestroy.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
export default function loopDestroy() {
const swiper = this;
const { $wrapperEl, params, slides } = swiper;
$wrapperEl
.children(
`.${params.slideClass}.${params.slideDuplicateClass},.${params.slideClass}.${params.slideBlankClass},swiper-slide.${params.slideDuplicateClass},swiper-slide.${params.slideBlankClass}`,
)
.remove();
const { slides, params, $slidesEl } = swiper;
if (!params.loop || (swiper.virtual && swiper.params.virtual.enabled)) return;
swiper.recalcSlides();

const newSlidesOrder = [];
slides.forEach((slideEl) => {
const index =
typeof slideEl.swiperSlideIndex === 'undefined'
? slideEl.getAttribute('data-swiper-slide-index') * 1
: slideEl.swiperSlideIndex;
newSlidesOrder[index] = slideEl;
});
slides.removeAttr('data-swiper-slide-index');
newSlidesOrder.forEach((slideEl) => {
$slidesEl.append(slideEl);
});
swiper.recalcSlides();
swiper.slideTo(swiper.realIndex, 0);
}
86 changes: 59 additions & 27 deletions src/core/loop/loopFix.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,73 @@
export default function loopFix() {
export default function loopFix(slideRealIndex, slideTo = true) {
const swiper = this;

if (!swiper.params.loop || (swiper.virtual && swiper.params.virtual.enabled)) return;

swiper.emit('beforeLoopFix');

const {
activeIndex,
slides,
loopedSlides,
allowSlidePrev,
allowSlideNext,
snapGrid,
rtlTranslate: rtl,
} = swiper;
let newIndex;
const { slides, allowSlidePrev, allowSlideNext, $slidesEl } = swiper;

swiper.allowSlidePrev = true;
swiper.allowSlideNext = true;

const snapTranslate = -snapGrid[activeIndex];
const diff = snapTranslate - swiper.getTranslate();
const slidesPerView =
swiper.params.slidesPerView === 'auto'
? swiper.slidesPerViewDynamic()
: Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
let loopedSlides = slidesPerView;
if (loopedSlides % swiper.params.slidesPerGroup !== 0) {
loopedSlides += swiper.params.slidesPerGroup - (loopedSlides % swiper.params.slidesPerGroup);
}
swiper.loopedSlides = loopedSlides;

const prependSlidesIndexes = [];
const appendSlidesIndexes = [];

const activeSlideIndex = swiper.slides
.filter((el) => el.classList.contains('swiper-slide-active'))
.index();

// Fix For Negative Oversliding
if (activeIndex < loopedSlides) {
newIndex = slides.length - loopedSlides * 3 + activeIndex;
newIndex += loopedSlides;
const slideChanged = swiper.slideTo(newIndex, 0, false, true);
if (slideChanged && diff !== 0) {
swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);
let slidesPrepended = 0;
let slidesAppended = 0;
// prepend last slides before start
if (activeSlideIndex < loopedSlides) {
slidesPrepended = loopedSlides - activeSlideIndex;
for (let i = 0; i < loopedSlides - activeSlideIndex; i += 1) {
const index = i - Math.floor(i / slides.length) * slides.length;
prependSlidesIndexes.push(slides.length - index - 1);
}
} else if (activeIndex >= slides.length - loopedSlides) {
// Fix For Positive Oversliding
newIndex = -slides.length + activeIndex + loopedSlides;
newIndex += loopedSlides;
const slideChanged = swiper.slideTo(newIndex, 0, false, true);
if (slideChanged && diff !== 0) {
swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);
} else if (activeSlideIndex /* + slidesPerView */ > swiper.slides.length - loopedSlides * 2) {
slidesAppended = activeSlideIndex - (swiper.slides.length - loopedSlides * 2);
for (let i = 0; i < slidesAppended; i += 1) {
const index = i - Math.floor(i / slides.length) * slides.length;
appendSlidesIndexes.push(index);
}
}

prependSlidesIndexes.forEach((index) => {
$slidesEl.prepend(swiper.slides.eq(index));
});
appendSlidesIndexes.forEach((index) => {
$slidesEl.append(swiper.slides.eq(index));
});
swiper.recalcSlides();

if (slideTo) {
if (prependSlidesIndexes.length > 0) {
if (typeof slideRealIndex === 'undefined') {
swiper.slideTo(swiper.activeIndex + slidesPrepended, 0, false, true);
} else {
swiper.slideToLoop(slideRealIndex, 0, false, true);
}
} else if (appendSlidesIndexes.length > 0) {
if (typeof slideRealIndex === 'undefined') {
swiper.slideTo(swiper.activeIndex - slidesAppended, 0, false, true);
} else {
swiper.slideToLoop(slideRealIndex, 0, false, true);
}
}
}

swiper.allowSlidePrev = allowSlidePrev;
swiper.allowSlideNext = allowSlideNext;

Expand Down
2 changes: 1 addition & 1 deletion src/core/slide/slideNext.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default function slideNext(speed = this.params.speed, runCallbacks = true
}
const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
if (params.loop) {
if (animating && params.loopPreventsSlide) return false;
if (animating) return false;
swiper.loopFix();
// eslint-disable-next-line
swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
Expand Down
2 changes: 1 addition & 1 deletion src/core/slide/slidePrev.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default function slidePrev(speed = this.params.speed, runCallbacks = true
if (!enabled) return swiper;

if (params.loop) {
if (animating && params.loopPreventsSlide) return false;
if (animating) return false;
swiper.loopFix();
// eslint-disable-next-line
swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
Expand Down
Loading

0 comments on commit f57aa3b

Please sign in to comment.