123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- import { getWindow } from 'ssr-window';
- import $ from '../../shared/dom.js';
- export default function Lazy(_ref) {
- let {
- swiper,
- extendParams,
- on,
- emit
- } = _ref;
- extendParams({
- lazy: {
- checkInView: false,
- enabled: false,
- loadPrevNext: false,
- loadPrevNextAmount: 1,
- loadOnTransitionStart: false,
- scrollingElement: '',
- elementClass: 'swiper-lazy',
- loadingClass: 'swiper-lazy-loading',
- loadedClass: 'swiper-lazy-loaded',
- preloaderClass: 'swiper-lazy-preloader'
- }
- });
- swiper.lazy = {};
- let scrollHandlerAttached = false;
- let initialImageLoaded = false;
- function loadInSlide(index, loadInDuplicate) {
- if (loadInDuplicate === void 0) {
- loadInDuplicate = true;
- }
- 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);
- const $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.push($slideEl[0]);
- }
- if ($images.length === 0) return;
- $images.each(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(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})`);
- loadInSlide(originalSlide.index(), false);
- } else {
- const duplicatedSlide = swiper.$wrapperEl.children(`.${swiper.params.slideDuplicateClass}[data-swiper-slide-index="${slideOriginalIndex}"]`);
- loadInSlide(duplicatedSlide.index(), false);
- }
- }
- emit('lazyImageReady', $slideEl[0], $imageEl[0]);
- if (swiper.params.autoHeight) {
- swiper.updateAutoHeight();
- }
- });
- emit('lazyImageLoad', $slideEl[0], $imageEl[0]);
- });
- }
- function load() {
- 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 (!initialImageLoaded) initialImageLoaded = true;
- if (swiper.params.watchSlidesProgress) {
- $wrapperEl.children(`.${swiperParams.slideVisibleClass}`).each(slideEl => {
- const index = isVirtual ? $(slideEl).attr('data-swiper-slide-index') : $(slideEl).index();
- loadInSlide(index);
- });
- } else if (slidesPerView > 1) {
- for (let i = activeIndex; i < activeIndex + slidesPerView; i += 1) {
- if (slideExist(i)) loadInSlide(i);
- }
- } else {
- 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)) loadInSlide(i);
- } // Prev Slides
- for (let i = minIndex; i < activeIndex; i += 1) {
- if (slideExist(i)) loadInSlide(i);
- }
- } else {
- const nextSlide = $wrapperEl.children(`.${swiperParams.slideNextClass}`);
- if (nextSlide.length > 0) loadInSlide(slideIndex(nextSlide));
- const prevSlide = $wrapperEl.children(`.${swiperParams.slidePrevClass}`);
- if (prevSlide.length > 0) loadInSlide(slideIndex(prevSlide));
- }
- }
- }
- function checkInViewOnLoad() {
- const window = getWindow();
- if (!swiper || swiper.destroyed) return;
- const $scrollElement = swiper.params.lazy.scrollingElement ? $(swiper.params.lazy.scrollingElement) : $(window);
- const isWindow = $scrollElement[0] === window;
- const scrollElementWidth = isWindow ? window.innerWidth : $scrollElement[0].offsetWidth;
- const scrollElementHeight = isWindow ? window.innerHeight : $scrollElement[0].offsetHeight;
- const swiperOffset = swiper.$el.offset();
- const {
- rtlTranslate: rtl
- } = swiper;
- let inView = false;
- if (rtl) swiperOffset.left -= swiper.$el[0].scrollLeft;
- const swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiper.width, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiper.height], [swiperOffset.left + swiper.width, swiperOffset.top + swiper.height]];
- for (let i = 0; i < swiperCoord.length; i += 1) {
- const point = swiperCoord[i];
- if (point[0] >= 0 && point[0] <= scrollElementWidth && point[1] >= 0 && point[1] <= scrollElementHeight) {
- if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line
- inView = true;
- }
- }
- const passiveListener = swiper.touchEvents.start === 'touchstart' && swiper.support.passiveListener && swiper.params.passiveListeners ? {
- passive: true,
- capture: false
- } : false;
- if (inView) {
- load();
- $scrollElement.off('scroll', checkInViewOnLoad, passiveListener);
- } else if (!scrollHandlerAttached) {
- scrollHandlerAttached = true;
- $scrollElement.on('scroll', checkInViewOnLoad, passiveListener);
- }
- }
- on('beforeInit', () => {
- if (swiper.params.lazy.enabled && swiper.params.preloadImages) {
- swiper.params.preloadImages = false;
- }
- });
- on('init', () => {
- if (swiper.params.lazy.enabled) {
- if (swiper.params.lazy.checkInView) {
- checkInViewOnLoad();
- } else {
- load();
- }
- }
- });
- on('scroll', () => {
- if (swiper.params.freeMode && swiper.params.freeMode.enabled && !swiper.params.freeMode.sticky) {
- load();
- }
- });
- on('scrollbarDragMove resize _freeModeNoMomentumRelease', () => {
- if (swiper.params.lazy.enabled) {
- if (swiper.params.lazy.checkInView) {
- checkInViewOnLoad();
- } else {
- load();
- }
- }
- });
- on('transitionStart', () => {
- if (swiper.params.lazy.enabled) {
- if (swiper.params.lazy.loadOnTransitionStart || !swiper.params.lazy.loadOnTransitionStart && !initialImageLoaded) {
- if (swiper.params.lazy.checkInView) {
- checkInViewOnLoad();
- } else {
- load();
- }
- }
- }
- });
- on('transitionEnd', () => {
- if (swiper.params.lazy.enabled && !swiper.params.lazy.loadOnTransitionStart) {
- if (swiper.params.lazy.checkInView) {
- checkInViewOnLoad();
- } else {
- load();
- }
- }
- });
- on('slideChange', () => {
- const {
- lazy,
- cssMode,
- watchSlidesProgress,
- touchReleaseOnEdges,
- resistanceRatio
- } = swiper.params;
- if (lazy.enabled && (cssMode || watchSlidesProgress && (touchReleaseOnEdges || resistanceRatio === 0))) {
- load();
- }
- });
- Object.assign(swiper.lazy, {
- load,
- loadInSlide
- });
- }
|