import $ from '../../utils/dom';
|
import Utils from '../../utils/utils';
|
|
const Lazy = {
|
loadInSlide(index, loadInDuplicate = true) {
|
const swiper = this;
|
const params = swiper.params.lazy;
|
if (typeof index === 'undefined') return;
|
if (swiper.slides.length === 0) return;
|
const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
|
|
const $slideEl = isVirtual
|
? swiper.$wrapperEl.children(`.${swiper.params.slideClass}[data-swiper-slide-index="${index}"]`)
|
: swiper.slides.eq(index);
|
|
let $images = $slideEl.find(`.${params.elementClass}:not(.${params.loadedClass}):not(.${params.loadingClass})`);
|
if ($slideEl.hasClass(params.elementClass) && !$slideEl.hasClass(params.loadedClass) && !$slideEl.hasClass(params.loadingClass)) {
|
$images = $images.add($slideEl[0]);
|
}
|
if ($images.length === 0) return;
|
|
$images.each((imageIndex, imageEl) => {
|
const $imageEl = $(imageEl);
|
$imageEl.addClass(params.loadingClass);
|
|
const background = $imageEl.attr('data-background');
|
const src = $imageEl.attr('data-src');
|
const srcset = $imageEl.attr('data-srcset');
|
const sizes = $imageEl.attr('data-sizes');
|
const $pictureEl = $imageEl.parent('picture');
|
|
swiper.loadImage($imageEl[0], (src || background), srcset, sizes, false, () => {
|
if (typeof swiper === 'undefined' || swiper === null || !swiper || (swiper && !swiper.params) || swiper.destroyed) return;
|
if (background) {
|
$imageEl.css('background-image', `url("${background}")`);
|
$imageEl.removeAttr('data-background');
|
} else {
|
if (srcset) {
|
$imageEl.attr('srcset', srcset);
|
$imageEl.removeAttr('data-srcset');
|
}
|
if (sizes) {
|
$imageEl.attr('sizes', sizes);
|
$imageEl.removeAttr('data-sizes');
|
}
|
if ($pictureEl.length) {
|
$pictureEl.children('source').each((sourceIndex, sourceEl) => {
|
const $source = $(sourceEl);
|
|
if ($source.attr('data-srcset')) {
|
$source.attr('srcset', $source.attr('data-srcset'));
|
$source.removeAttr('data-srcset');
|
}
|
});
|
}
|
if (src) {
|
$imageEl.attr('src', src);
|
$imageEl.removeAttr('data-src');
|
}
|
}
|
|
$imageEl.addClass(params.loadedClass).removeClass(params.loadingClass);
|
$slideEl.find(`.${params.preloaderClass}`).remove();
|
if (swiper.params.loop && loadInDuplicate) {
|
const slideOriginalIndex = $slideEl.attr('data-swiper-slide-index');
|
if ($slideEl.hasClass(swiper.params.slideDuplicateClass)) {
|
const originalSlide = swiper.$wrapperEl.children(`[data-swiper-slide-index="${slideOriginalIndex}"]:not(.${swiper.params.slideDuplicateClass})`);
|
swiper.lazy.loadInSlide(originalSlide.index(), false);
|
} else {
|
const duplicatedSlide = swiper.$wrapperEl.children(`.${swiper.params.slideDuplicateClass}[data-swiper-slide-index="${slideOriginalIndex}"]`);
|
swiper.lazy.loadInSlide(duplicatedSlide.index(), false);
|
}
|
}
|
swiper.emit('lazyImageReady', $slideEl[0], $imageEl[0]);
|
if (swiper.params.autoHeight) {
|
swiper.updateAutoHeight();
|
}
|
});
|
|
swiper.emit('lazyImageLoad', $slideEl[0], $imageEl[0]);
|
});
|
},
|
load() {
|
const swiper = this;
|
const {
|
$wrapperEl, params: swiperParams, slides, activeIndex,
|
} = swiper;
|
const isVirtual = swiper.virtual && swiperParams.virtual.enabled;
|
const params = swiperParams.lazy;
|
|
let slidesPerView = swiperParams.slidesPerView;
|
if (slidesPerView === 'auto') {
|
slidesPerView = 0;
|
}
|
|
function slideExist(index) {
|
if (isVirtual) {
|
if ($wrapperEl.children(`.${swiperParams.slideClass}[data-swiper-slide-index="${index}"]`).length) {
|
return true;
|
}
|
} else if (slides[index]) return true;
|
return false;
|
}
|
|
function slideIndex(slideEl) {
|
if (isVirtual) {
|
return $(slideEl).attr('data-swiper-slide-index');
|
}
|
return $(slideEl).index();
|
}
|
|
if (!swiper.lazy.initialImageLoaded) swiper.lazy.initialImageLoaded = true;
|
if (swiper.params.watchSlidesVisibility) {
|
$wrapperEl.children(`.${swiperParams.slideVisibleClass}`).each((elIndex, slideEl) => {
|
const index = isVirtual ? $(slideEl).attr('data-swiper-slide-index') : $(slideEl).index();
|
swiper.lazy.loadInSlide(index);
|
});
|
} else if (slidesPerView > 1) {
|
for (let i = activeIndex; i < activeIndex + slidesPerView; i += 1) {
|
if (slideExist(i)) swiper.lazy.loadInSlide(i);
|
}
|
} else {
|
swiper.lazy.loadInSlide(activeIndex);
|
}
|
if (params.loadPrevNext) {
|
if (slidesPerView > 1 || (params.loadPrevNextAmount && params.loadPrevNextAmount > 1)) {
|
const amount = params.loadPrevNextAmount;
|
const spv = slidesPerView;
|
const maxIndex = Math.min(activeIndex + spv + Math.max(amount, spv), slides.length);
|
const minIndex = Math.max(activeIndex - Math.max(spv, amount), 0);
|
// Next Slides
|
for (let i = activeIndex + slidesPerView; i < maxIndex; i += 1) {
|
if (slideExist(i)) swiper.lazy.loadInSlide(i);
|
}
|
// Prev Slides
|
for (let i = minIndex; i < activeIndex; i += 1) {
|
if (slideExist(i)) swiper.lazy.loadInSlide(i);
|
}
|
} else {
|
const nextSlide = $wrapperEl.children(`.${swiperParams.slideNextClass}`);
|
if (nextSlide.length > 0) swiper.lazy.loadInSlide(slideIndex(nextSlide));
|
|
const prevSlide = $wrapperEl.children(`.${swiperParams.slidePrevClass}`);
|
if (prevSlide.length > 0) swiper.lazy.loadInSlide(slideIndex(prevSlide));
|
}
|
}
|
},
|
};
|
|
export default {
|
name: 'lazy',
|
params: {
|
lazy: {
|
enabled: false,
|
loadPrevNext: false,
|
loadPrevNextAmount: 1,
|
loadOnTransitionStart: false,
|
|
elementClass: 'swiper-lazy',
|
loadingClass: 'swiper-lazy-loading',
|
loadedClass: 'swiper-lazy-loaded',
|
preloaderClass: 'swiper-lazy-preloader',
|
},
|
},
|
create() {
|
const swiper = this;
|
Utils.extend(swiper, {
|
lazy: {
|
initialImageLoaded: false,
|
load: Lazy.load.bind(swiper),
|
loadInSlide: Lazy.loadInSlide.bind(swiper),
|
},
|
});
|
},
|
on: {
|
beforeInit() {
|
const swiper = this;
|
if (swiper.params.lazy.enabled && swiper.params.preloadImages) {
|
swiper.params.preloadImages = false;
|
}
|
},
|
init() {
|
const swiper = this;
|
if (swiper.params.lazy.enabled && !swiper.params.loop && swiper.params.initialSlide === 0) {
|
swiper.lazy.load();
|
}
|
},
|
scroll() {
|
const swiper = this;
|
if (swiper.params.freeMode && !swiper.params.freeModeSticky) {
|
swiper.lazy.load();
|
}
|
},
|
resize() {
|
const swiper = this;
|
if (swiper.params.lazy.enabled) {
|
swiper.lazy.load();
|
}
|
},
|
scrollbarDragMove() {
|
const swiper = this;
|
if (swiper.params.lazy.enabled) {
|
swiper.lazy.load();
|
}
|
},
|
transitionStart() {
|
const swiper = this;
|
if (swiper.params.lazy.enabled) {
|
if (swiper.params.lazy.loadOnTransitionStart || (!swiper.params.lazy.loadOnTransitionStart && !swiper.lazy.initialImageLoaded)) {
|
swiper.lazy.load();
|
}
|
}
|
},
|
transitionEnd() {
|
const swiper = this;
|
if (swiper.params.lazy.enabled && !swiper.params.lazy.loadOnTransitionStart) {
|
swiper.lazy.load();
|
}
|
},
|
slideChange() {
|
const swiper = this;
|
if (swiper.params.lazy.enabled && swiper.params.cssMode) {
|
swiper.lazy.load();
|
}
|
},
|
},
|
};
|