123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- import { g as getDocument } from '../shared/ssr-window.esm.mjs';
- import { s as setCSSProperty, e as elementChildren, c as createElement } from '../shared/utils.mjs';
- function Virtual(_ref) {
- let {
- swiper,
- extendParams,
- on,
- emit
- } = _ref;
- extendParams({
- virtual: {
- enabled: false,
- slides: [],
- cache: true,
- renderSlide: null,
- renderExternal: null,
- renderExternalUpdate: true,
- addSlidesBefore: 0,
- addSlidesAfter: 0
- }
- });
- let cssModeTimeout;
- const document = getDocument();
- swiper.virtual = {
- cache: {},
- from: undefined,
- to: undefined,
- slides: [],
- offset: 0,
- slidesGrid: []
- };
- const tempDOM = document.createElement('div');
- function renderSlide(slide, index) {
- const params = swiper.params.virtual;
- if (params.cache && swiper.virtual.cache[index]) {
- return swiper.virtual.cache[index];
- }
- // eslint-disable-next-line
- let slideEl;
- if (params.renderSlide) {
- slideEl = params.renderSlide.call(swiper, slide, index);
- if (typeof slideEl === 'string') {
- tempDOM.innerHTML = slideEl;
- slideEl = tempDOM.children[0];
- }
- } else if (swiper.isElement) {
- slideEl = createElement('swiper-slide');
- } else {
- slideEl = createElement('div', swiper.params.slideClass);
- }
- slideEl.setAttribute('data-swiper-slide-index', index);
- if (!params.renderSlide) {
- slideEl.innerHTML = slide;
- }
- if (params.cache) {
- swiper.virtual.cache[index] = slideEl;
- }
- return slideEl;
- }
- function update(force, beforeInit) {
- const {
- slidesPerView,
- slidesPerGroup,
- centeredSlides,
- loop: isLoop,
- initialSlide
- } = swiper.params;
- if (beforeInit && !isLoop && initialSlide > 0) {
- return;
- }
- const {
- addSlidesBefore,
- addSlidesAfter
- } = swiper.params.virtual;
- const {
- from: previousFrom,
- to: previousTo,
- slides,
- slidesGrid: previousSlidesGrid,
- offset: previousOffset
- } = swiper.virtual;
- if (!swiper.params.cssMode) {
- swiper.updateActiveIndex();
- }
- const activeIndex = swiper.activeIndex || 0;
- let offsetProp;
- if (swiper.rtlTranslate) offsetProp = 'right';else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
- let slidesAfter;
- let slidesBefore;
- if (centeredSlides) {
- slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;
- slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;
- } else {
- slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter;
- slidesBefore = (isLoop ? slidesPerView : slidesPerGroup) + addSlidesBefore;
- }
- let from = activeIndex - slidesBefore;
- let to = activeIndex + slidesAfter;
- if (!isLoop) {
- from = Math.max(from, 0);
- to = Math.min(to, slides.length - 1);
- }
- let offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
- if (isLoop && activeIndex >= slidesBefore) {
- from -= slidesBefore;
- if (!centeredSlides) offset += swiper.slidesGrid[0];
- } else if (isLoop && activeIndex < slidesBefore) {
- from = -slidesBefore;
- if (centeredSlides) offset += swiper.slidesGrid[0];
- }
- Object.assign(swiper.virtual, {
- from,
- to,
- offset,
- slidesGrid: swiper.slidesGrid,
- slidesBefore,
- slidesAfter
- });
- function onRendered() {
- swiper.updateSlides();
- swiper.updateProgress();
- swiper.updateSlidesClasses();
- emit('virtualUpdate');
- }
- if (previousFrom === from && previousTo === to && !force) {
- if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
- swiper.slides.forEach(slideEl => {
- slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
- });
- }
- swiper.updateProgress();
- emit('virtualUpdate');
- return;
- }
- if (swiper.params.virtual.renderExternal) {
- swiper.params.virtual.renderExternal.call(swiper, {
- offset,
- from,
- to,
- slides: function getSlides() {
- const slidesToRender = [];
- for (let i = from; i <= to; i += 1) {
- slidesToRender.push(slides[i]);
- }
- return slidesToRender;
- }()
- });
- if (swiper.params.virtual.renderExternalUpdate) {
- onRendered();
- } else {
- emit('virtualUpdate');
- }
- return;
- }
- const prependIndexes = [];
- const appendIndexes = [];
- const getSlideIndex = index => {
- let slideIndex = index;
- if (index < 0) {
- slideIndex = slides.length + index;
- } else if (slideIndex >= slides.length) {
- // eslint-disable-next-line
- slideIndex = slideIndex - slides.length;
- }
- return slideIndex;
- };
- if (force) {
- swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`)).forEach(slideEl => {
- slideEl.remove();
- });
- } else {
- for (let i = previousFrom; i <= previousTo; i += 1) {
- if (i < from || i > to) {
- const slideIndex = getSlideIndex(i);
- swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}[data-swiper-slide-index="${slideIndex}"], swiper-slide[data-swiper-slide-index="${slideIndex}"]`)).forEach(slideEl => {
- slideEl.remove();
- });
- }
- }
- }
- const loopFrom = isLoop ? -slides.length : 0;
- const loopTo = isLoop ? slides.length * 2 : slides.length;
- for (let i = loopFrom; i < loopTo; i += 1) {
- if (i >= from && i <= to) {
- const slideIndex = getSlideIndex(i);
- if (typeof previousTo === 'undefined' || force) {
- appendIndexes.push(slideIndex);
- } else {
- if (i > previousTo) appendIndexes.push(slideIndex);
- if (i < previousFrom) prependIndexes.push(slideIndex);
- }
- }
- }
- appendIndexes.forEach(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.slidesEl.prepend(renderSlide(slides[index], index));
- }
- } else {
- prependIndexes.sort((a, b) => b - a);
- prependIndexes.forEach(index => {
- swiper.slidesEl.prepend(renderSlide(slides[index], index));
- });
- }
- elementChildren(swiper.slidesEl, '.swiper-slide, swiper-slide').forEach(slideEl => {
- slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
- });
- onRendered();
- }
- function appendSlide(slides) {
- if (typeof slides === 'object' && 'length' in slides) {
- for (let i = 0; i < slides.length; i += 1) {
- if (slides[i]) swiper.virtual.slides.push(slides[i]);
- }
- } else {
- swiper.virtual.slides.push(slides);
- }
- update(true);
- }
- function prependSlide(slides) {
- const activeIndex = swiper.activeIndex;
- let newActiveIndex = activeIndex + 1;
- let numberOfNewSlides = 1;
- if (Array.isArray(slides)) {
- for (let i = 0; i < slides.length; i += 1) {
- if (slides[i]) swiper.virtual.slides.unshift(slides[i]);
- }
- newActiveIndex = activeIndex + slides.length;
- numberOfNewSlides = slides.length;
- } else {
- swiper.virtual.slides.unshift(slides);
- }
- if (swiper.params.virtual.cache) {
- const cache = swiper.virtual.cache;
- const newCache = {};
- Object.keys(cache).forEach(cachedIndex => {
- const cachedEl = cache[cachedIndex];
- const cachedElIndex = cachedEl.getAttribute('data-swiper-slide-index');
- if (cachedElIndex) {
- cachedEl.setAttribute('data-swiper-slide-index', parseInt(cachedElIndex, 10) + numberOfNewSlides);
- }
- newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cachedEl;
- });
- swiper.virtual.cache = newCache;
- }
- update(true);
- swiper.slideTo(newActiveIndex, 0);
- }
- function removeSlide(slidesIndexes) {
- if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;
- let activeIndex = swiper.activeIndex;
- if (Array.isArray(slidesIndexes)) {
- for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) {
- if (swiper.params.virtual.cache) {
- delete swiper.virtual.cache[slidesIndexes[i]];
- // shift cache indexes
- Object.keys(swiper.virtual.cache).forEach(key => {
- if (key > slidesIndexes) {
- swiper.virtual.cache[key - 1] = swiper.virtual.cache[key];
- swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1);
- delete swiper.virtual.cache[key];
- }
- });
- }
- swiper.virtual.slides.splice(slidesIndexes[i], 1);
- if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
- activeIndex = Math.max(activeIndex, 0);
- }
- } else {
- if (swiper.params.virtual.cache) {
- delete swiper.virtual.cache[slidesIndexes];
- // shift cache indexes
- Object.keys(swiper.virtual.cache).forEach(key => {
- if (key > slidesIndexes) {
- swiper.virtual.cache[key - 1] = swiper.virtual.cache[key];
- swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1);
- delete swiper.virtual.cache[key];
- }
- });
- }
- swiper.virtual.slides.splice(slidesIndexes, 1);
- if (slidesIndexes < activeIndex) activeIndex -= 1;
- activeIndex = Math.max(activeIndex, 0);
- }
- update(true);
- swiper.slideTo(activeIndex, 0);
- }
- function removeAllSlides() {
- swiper.virtual.slides = [];
- if (swiper.params.virtual.cache) {
- swiper.virtual.cache = {};
- }
- update(true);
- swiper.slideTo(0, 0);
- }
- on('beforeInit', () => {
- if (!swiper.params.virtual.enabled) return;
- let domSlidesAssigned;
- if (typeof swiper.passedParams.virtual.slides === 'undefined') {
- const slides = [...swiper.slidesEl.children].filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`));
- if (slides && slides.length) {
- swiper.virtual.slides = [...slides];
- domSlidesAssigned = true;
- slides.forEach((slideEl, slideIndex) => {
- slideEl.setAttribute('data-swiper-slide-index', slideIndex);
- swiper.virtual.cache[slideIndex] = slideEl;
- slideEl.remove();
- });
- }
- }
- if (!domSlidesAssigned) {
- swiper.virtual.slides = swiper.params.virtual.slides;
- }
- swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);
- swiper.params.watchSlidesProgress = true;
- swiper.originalParams.watchSlidesProgress = true;
- update(false, true);
- });
- on('setTranslate', () => {
- if (!swiper.params.virtual.enabled) return;
- if (swiper.params.cssMode && !swiper._immediateVirtual) {
- clearTimeout(cssModeTimeout);
- cssModeTimeout = setTimeout(() => {
- update();
- }, 100);
- } else {
- update();
- }
- });
- on('init update resize', () => {
- if (!swiper.params.virtual.enabled) return;
- if (swiper.params.cssMode) {
- setCSSProperty(swiper.wrapperEl, '--swiper-virtual-size', `${swiper.virtualSize}px`);
- }
- });
- Object.assign(swiper.virtual, {
- appendSlide,
- prependSlide,
- removeSlide,
- removeAllSlides,
- update
- });
- }
- export { Virtual as default };
|