UNPKG

flickity

Version:

Touch, responsive, flickable carousels

125 lines (102 loc) 3.55 kB
// lazyload ( function( window, factory ) { // universal module definition if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( require('./core'), require('fizzy-ui-utils'), ); } else { // browser global factory( window.Flickity, window.fizzyUIUtils, ); } }( typeof window != 'undefined' ? window : this, function factory( Flickity, utils ) { const lazyAttr = 'data-flickity-lazyload'; const lazySrcAttr = `${lazyAttr}-src`; const lazySrcsetAttr = `${lazyAttr}-srcset`; const imgSelector = `img[${lazyAttr}], img[${lazySrcAttr}], ` + `img[${lazySrcsetAttr}], source[${lazySrcsetAttr}]`; Flickity.create.lazyLoad = function() { this.on( 'select', this.lazyLoad ); this.handleLazyLoadComplete = this.onLazyLoadComplete.bind( this ); }; let proto = Flickity.prototype; proto.lazyLoad = function() { let { lazyLoad } = this.options; if ( !lazyLoad ) return; // get adjacent cells, use lazyLoad option for adjacent count let adjCount = typeof lazyLoad == 'number' ? lazyLoad : 0; // lazy load images this.getAdjacentCellElements( adjCount ) .map( getCellLazyImages ) .flat() .forEach( ( img ) => new LazyLoader( img, this.handleLazyLoadComplete ) ); }; function getCellLazyImages( cellElem ) { // check if cell element is lazy image if ( cellElem.matches('img') ) { let cellAttr = cellElem.getAttribute( lazyAttr ); let cellSrcAttr = cellElem.getAttribute( lazySrcAttr ); let cellSrcsetAttr = cellElem.getAttribute( lazySrcsetAttr ); if ( cellAttr || cellSrcAttr || cellSrcsetAttr ) { return cellElem; } } // select lazy images in cell return [ ...cellElem.querySelectorAll( imgSelector ) ]; } proto.onLazyLoadComplete = function( img, event ) { let cell = this.getParentCell( img ); let cellElem = cell && cell.element; this.cellSizeChange( cellElem ); this.dispatchEvent( 'lazyLoad', event, cellElem ); }; // -------------------------- LazyLoader -------------------------- // /** * class to handle loading images * @param {Image} img - Image element * @param {Function} onComplete - callback function */ function LazyLoader( img, onComplete ) { this.img = img; this.onComplete = onComplete; this.load(); } LazyLoader.prototype.handleEvent = utils.handleEvent; LazyLoader.prototype.load = function() { this.img.addEventListener( 'load', this ); this.img.addEventListener( 'error', this ); // get src & srcset let src = this.img.getAttribute( lazyAttr ) || this.img.getAttribute( lazySrcAttr ); let srcset = this.img.getAttribute( lazySrcsetAttr ); // set src & serset this.img.src = src; if ( srcset ) this.img.setAttribute( 'srcset', srcset ); // remove attr this.img.removeAttribute( lazyAttr ); this.img.removeAttribute( lazySrcAttr ); this.img.removeAttribute( lazySrcsetAttr ); }; LazyLoader.prototype.onload = function( event ) { this.complete( event, 'flickity-lazyloaded' ); }; LazyLoader.prototype.onerror = function( event ) { this.complete( event, 'flickity-lazyerror' ); }; LazyLoader.prototype.complete = function( event, className ) { // unbind events this.img.removeEventListener( 'load', this ); this.img.removeEventListener( 'error', this ); let mediaElem = this.img.parentNode.matches('picture') ? this.img.parentNode : this.img; mediaElem.classList.add( className ); this.onComplete( this.img, event ); }; // ----- ----- // Flickity.LazyLoader = LazyLoader; return Flickity; } ) );