123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- export default function Virtual({
- swiper,
- extendParams,
- on
- }) {
- extendParams({
- virtual: {
- enabled: false,
- slides: [],
- cache: true,
- renderSlide: null,
- renderExternal: null,
- renderExternalUpdate: true,
- addSlidesBefore: 0,
- addSlidesAfter: 0,
- },
- });
- let cssModeTimeout;
- swiper.virtual = {
- cache: {},
- from: undefined,
- to: undefined,
- slides: [],
- offset: 0,
- slidesGrid: [],
- };
- function renderSlide(slide, index) {
- const params = swiper.params.virtual;
- if (params.cache && swiper.virtual.cache[index]) {
- return swiper.virtual.cache[index];
- }
- // const $slideEl = params.renderSlide ?
- // $(params.renderSlide.call(swiper, slide, index)) :
- // $(
- // `<div class="${swiper.params.slideClass}" data-swiper-slide-index="${index}">${slide}</div>`,
- // );
- // if (!$slideEl.attr('data-swiper-slide-index')) $slideEl.attr('data-swiper-slide-index', index);
- // if (params.cache) swiper.virtual.cache[index] = $slideEl;
- // return $slideEl;
- }
- function onRendered() {
- swiper.updateSlides();
- swiper.updateProgress();
- swiper.updateSlidesClasses();
- if (swiper.lazy && swiper.params.lazy.enabled) {
- swiper.lazy.load();
- }
- }
- async function update(force) {
- const {
- slidesPerView,
- slidesPerGroup,
- centeredSlides
- } = swiper.params;
- 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 = slidesPerGroup + addSlidesBefore;
- }
- const from = Math.max((activeIndex || 0) - slidesBefore, 0);
- const to = Math.min((activeIndex || 0) + slidesAfter, slides.length - 1);
- const offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
- Object.assign(swiper.virtual, {
- from,
- to,
- offset,
- slidesGrid: swiper.slidesGrid,
- });
- function onRendered() {
- swiper.updateSlides();
- swiper.updateProgress();
- swiper.updateSlidesClasses();
- if (swiper.lazy && swiper.params.lazy.enabled) {
- swiper.lazy.load();
- }
- }
- if (previousFrom === from && previousTo === to && !force) {
- if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
- swiper.slides.css(offsetProp, `${offset}px`);
- }
- swiper.updateProgress();
- return;
- }
- if (swiper.params.virtual.renderExternal) {
- swiper.params.virtual.renderExternal.call(swiper, {
- offset,
- from,
- to,
- slides: (function getSlides() {
- const slidesToRender = [];
- if (swiper.params.virtual.type == 'keep') {
- for (let i = 0; i < from; i += 1) {
- slidesToRender.push("");
- }
- }
- for (let i = from; i <= to; i += 1) {
- slidesToRender.push(slides[i]);
- }
- return slidesToRender;
- })(),
- });
- if (swiper.params.virtual.renderExternalUpdate) {
- onRendered();
- }
- return;
- }
- const prependIndexes = [];
- const appendIndexes = [];
- if (force) {
- swiper.$wrapperEl.find(`.${swiper.params.slideClass}`).remove();
- } else {
- for (let i = previousFrom; i <= previousTo; i += 1) {
- if (i < from || i > to) {
- swiper.virtualList.splice(swiper.virtualList.findIndex((item) => {
- return item == slides[i]
- }), 1)
- swiper.virtualIndexList.splice(swiper.virtualIndexList.findIndex((item) => {
- return item == i
- }), 1)
- // swiper.slides[i].virtualShow = false;
- }
- }
- }
- for (let i = 0; i < slides.length; i += 1) {
- if (i >= from && i <= to) {
- if (typeof previousTo === 'undefined' || force) {
- appendIndexes.push(i);
- } else {
- if (i > previousTo) appendIndexes.push(i);
- if (i < previousFrom) prependIndexes.push(i);
- }
- }
- }
- // let list = [];
- appendIndexes.forEach((index) => {
- // if (swiper.slides[index]) {
- // swiper.slides[index].virtualShow = true;
- // } else {
- swiper.virtualList.push(slides[index]);
- swiper.virtualIndexList.push(index)
- // }
- // renderSlide(slides[index], index)
- // renderSlide(slides[index], index)
- // swiper.$wrapperEl.append(renderSlide(slides[index], index));
- });
- prependIndexes
- .sort((a, b) => b - a)
- .forEach((index) => {
- // swiper.slides[index].virtualShow = true;
- swiper.virtualList.unshift(slides[index]);
- swiper.virtualIndexList.unshift(index)
- // swiper.$wrapperEl.prepend(renderSlide(slides[index], index));
- });
- swiper.native.emit("input", [swiper.virtualList])
- 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.attr('data-swiper-slide-index');
- if (cachedElIndex) {
- $cachedEl.attr(
- '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) {
- swiper.virtual.slides.splice(slidesIndexes[i], 1);
- if (swiper.params.virtual.cache) {
- delete swiper.virtual.cache[slidesIndexes[i]];
- }
- if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
- activeIndex = Math.max(activeIndex, 0);
- }
- } else {
- swiper.virtual.slides.splice(slidesIndexes, 1);
- if (swiper.params.virtual.cache) {
- delete swiper.virtual.cache[slidesIndexes];
- }
- 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;
- swiper.virtual.slides = swiper.params.virtual.slides;
- swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);
- swiper.params.watchSlidesProgress = true;
- swiper.originalParams.watchSlidesProgress = true;
- if (!swiper.params.initialSlide) {
- update();
- }
- });
- // on('beforeUpdate', () => {
- // if (!swiper.params.virtual.enabled) return;
- // let offsetProp;
- // if (swiper.rtlTranslate) offsetProp = 'right';
- // else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
- // swiper.slides.forEach((item, index) => {
- // item.dataSwiperSlideIndex = swiper.virtualIndexList[index];
- // item.css({
- // [offsetProp]: `${swiper.virtual.offset}px`
- // })
- // })
- // })
- on('setTranslate', async () => {
- if (!swiper.params.virtual.enabled) return;
- if (swiper.params.cssMode && !swiper._immediateVirtual) {
- clearTimeout(cssModeTimeout);
- cssModeTimeout = setTimeout(() => {
- update();
- }, 100);
- } else {
- console.log("update==========")
- clearTimeout(cssModeTimeout);
- cssModeTimeout = setTimeout(() => {
- update();
- }, 100);
- // update();
- }
- });
- Object.assign(swiper.virtual, {
- appendSlide,
- prependSlide,
- removeSlide,
- removeAllSlides,
- update,
- });
- }
|