Skip to content

Commit

Permalink
feat(virtual): support for DOM virtual slides
Browse files Browse the repository at this point in the history
  • Loading branch information
nolimits4web committed Dec 7, 2022
1 parent ce1cb3b commit 59da65c
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 13 deletions.
3 changes: 2 additions & 1 deletion src/core/slide/slideNext.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ export default function slideNext(speed = this.params.speed, runCallbacks = true
perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
}
const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
if (params.loop) {
if (animating) return false;
if (animating && !isVirtual) return false;
swiper.loopFix();
// eslint-disable-next-line
swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
Expand Down
3 changes: 2 additions & 1 deletion src/core/slide/slidePrev.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ export default function slidePrev(speed = this.params.speed, runCallbacks = true
const swiper = this;
const { params, animating, snapGrid, slidesGrid, rtlTranslate, enabled } = swiper;
if (!enabled) return swiper;
const isVirtual = swiper.virtual && swiper.params.virtual.enabled;

if (params.loop) {
if (animating) return false;
if (animating && !isVirtual) return false;
swiper.loopFix();
// eslint-disable-next-line
swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
Expand Down
6 changes: 4 additions & 2 deletions src/core/update/updateSlides.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,12 @@ export default function updateSlides() {

for (let i = 0; i < slidesLength; i += 1) {
slideSize = 0;
const slide = slides.eq(i);
let slide;
if (slides[i]) slide = slides.eq(i);
if (gridEnabled) {
swiper.grid.updateSlide(i, slide, slidesLength, getDirectionLabel);
}
if (slide.css('display') === 'none') continue; // eslint-disable-line
if (slides[i] && slide.css('display') === 'none') continue; // eslint-disable-line

if (params.slidesPerView === 'auto') {
if (shouldResetSlideSize) {
Expand Down Expand Up @@ -175,6 +176,7 @@ export default function updateSlides() {

index += 1;
}

swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;

if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
Expand Down
2 changes: 1 addition & 1 deletion src/element/swiper-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class SwiperContainer extends ClassToExtend {
this.swiper = new Swiper(this, {
...swiperParams,
touchEventsTarget: 'container',
observer: true,
...(swiperParams.virtual ? {} : { observer: true }),
onAny: (name, ...args) => {
const event = new CustomEvent(name.toLowerCase(), {
detail: args,
Expand Down
35 changes: 27 additions & 8 deletions src/modules/virtual/virtual.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,20 @@ export default function Virtual({ swiper, extendParams, on, emit }) {
};

if (force) {
swiper.$wrapperEl.find(`.${swiper.params.slideClass}`).remove();
swiper.$slidesEl.find(`.${swiper.params.slideClass}, swiper-slide`).remove();
} else {
for (let i = previousFrom; i <= previousTo; i += 1) {
if (i < from || i > to) {
const slideIndex = getSlideIndex(i);
swiper.$wrapperEl
.find(`.${swiper.params.slideClass}[data-swiper-slide-index="${slideIndex}"]`)
swiper.$slidesEl
.find(
`.${swiper.params.slideClass}[data-swiper-slide-index="${slideIndex}"], swiper-slide[data-swiper-slide-index="${slideIndex}"]`,
)
.remove();
}
}
}

const loopFrom = isLoop ? -slides.length : 0;
const loopTo = isLoop ? slides.length * 2 : slides.length;
for (let i = loopFrom; i < loopTo; i += 1) {
Expand All @@ -172,21 +175,21 @@ export default function Virtual({ swiper, extendParams, on, emit }) {
}
}
appendIndexes.forEach((index) => {
swiper.$wrapperEl.append(renderSlide(slides[index], index));
swiper.$slidesEl.append(renderSlide(slides[index], index));
});
if (isLoop) {
for (let i = prependIndexes.length - 1; i >= 0; i -= 1) {
const index = prependIndexes[i];
swiper.$wrapperEl.prepend(renderSlide(slides[index], index));
swiper.$slidesEl.prepend(renderSlide(slides[index], index));
}
} else {
prependIndexes.sort((a, b) => b - a);
prependIndexes.forEach((index) => {
swiper.$wrapperEl.prepend(renderSlide(slides[index], index));
swiper.$slidesEl.prepend(renderSlide(slides[index], index));
});
}

swiper.$wrapperEl.children('.swiper-slide').css(offsetProp, `${offset}px`);
swiper.$slidesEl.children('.swiper-slide, swiper-slide').css(offsetProp, `${offset}px`);
onRendered();
}

Expand Down Expand Up @@ -267,7 +270,23 @@ export default function Virtual({ swiper, extendParams, on, emit }) {

on('beforeInit', () => {
if (!swiper.params.virtual.enabled) return;
swiper.virtual.slides = swiper.params.virtual.slides;
let domSlidesAssigned;
if (typeof swiper.passedParams.virtual.slides === 'undefined') {
const $slides = swiper.$slidesEl.children(`.${swiper.params.slideClass}, swiper-slide`);
if ($slides && $slides.length) {
swiper.virtual.slides = [...$slides];
domSlidesAssigned = true;
$slides.forEach((slideEl, slideIndex) => {
$(slideEl).attr('data-swiper-slide-index', slideIndex);
swiper.virtual.cache[slideIndex] = $(slideEl);
});
$slides.remove();
}
}
if (!domSlidesAssigned) {
swiper.virtual.slides = swiper.params.virtual.slides;
}

swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);

swiper.params.watchSlidesProgress = true;
Expand Down

0 comments on commit 59da65c

Please sign in to comment.