UNPKG

lazysizes

Version:

High performance (jankfree) lazy loader for images (including responsive images), iframes and scripts (widgets).

204 lines (163 loc) 5.28 kB
(function(window, factory) { var globalInstall = function(){ factory(window.lazySizes); window.removeEventListener('lazyunveilread', globalInstall, true); }; factory = factory.bind(null, window, window.document); if(typeof module == 'object' && module.exports){ factory(require('lazysizes')); } else if (typeof define == 'function' && define.amd) { define(['lazysizes'], factory); } else if(window.lazySizes) { globalInstall(); } else { window.addEventListener('lazyunveilread', globalInstall, true); } }(window, function(window, document, lazySizes) { 'use strict'; if(!window.addEventListener){return;} var lazySizesCfg = lazySizes.cfg; var regWhite = /\s+/g; var regSplitSet = /\s*\|\s+|\s+\|\s*/g; var regSource = /^(.+?)(?:\s+\[\s*(.+?)\s*\])(?:\s+\[\s*(.+?)\s*\])?$/; var regType = /^\s*\(*\s*type\s*:\s*(.+?)\s*\)*\s*$/; var regBgUrlEscape = /\(|\)|'/; var allowedBackgroundSize = {contain: 1, cover: 1}; var proxyWidth = function(elem){ var width = lazySizes.gW(elem, elem.parentNode); if(!elem._lazysizesWidth || width > elem._lazysizesWidth){ elem._lazysizesWidth = width; } return elem._lazysizesWidth; }; var getBgSize = function(elem){ var bgSize; bgSize = (getComputedStyle(elem) || {getPropertyValue: function(){}}).getPropertyValue('background-size'); if(!allowedBackgroundSize[bgSize] && allowedBackgroundSize[elem.style.backgroundSize]){ bgSize = elem.style.backgroundSize; } return bgSize; }; var setTypeOrMedia = function(source, match){ if(match){ var typeMatch = match.match(regType); if(typeMatch && typeMatch[1]){ source.setAttribute('type', typeMatch[1]); } else { source.setAttribute('media', lazySizesCfg.customMedia[match] || match); } } }; var createPicture = function(sets, elem, img){ var picture = document.createElement('picture'); var sizes = elem.getAttribute(lazySizesCfg.sizesAttr); var ratio = elem.getAttribute('data-ratio'); var optimumx = elem.getAttribute('data-optimumx'); if(elem._lazybgset && elem._lazybgset.parentNode == elem){ elem.removeChild(elem._lazybgset); } Object.defineProperty(img, '_lazybgset', { value: elem, writable: true }); Object.defineProperty(elem, '_lazybgset', { value: picture, writable: true }); sets = sets.replace(regWhite, ' ').split(regSplitSet); picture.style.display = 'none'; img.className = lazySizesCfg.lazyClass; if(sets.length == 1 && !sizes){ sizes = 'auto'; } sets.forEach(function(set){ var match; var source = document.createElement('source'); if(sizes && sizes != 'auto'){ source.setAttribute('sizes', sizes); } if((match = set.match(regSource))){ source.setAttribute(lazySizesCfg.srcsetAttr, match[1]); setTypeOrMedia(source, match[2]); setTypeOrMedia(source, match[3]); } else { source.setAttribute(lazySizesCfg.srcsetAttr, set); } picture.appendChild(source); }); if(sizes){ img.setAttribute(lazySizesCfg.sizesAttr, sizes); elem.removeAttribute(lazySizesCfg.sizesAttr); elem.removeAttribute('sizes'); } if(optimumx){ img.setAttribute('data-optimumx', optimumx); } if(ratio) { img.setAttribute('data-ratio', ratio); } picture.appendChild(img); elem.appendChild(picture); }; var proxyLoad = function(e){ if(!e.target._lazybgset){return;} var image = e.target; var elem = image._lazybgset; var bg = image.currentSrc || image.src; if(bg){ var useSrc = regBgUrlEscape.test(bg) ? JSON.stringify(bg) : bg; var event = lazySizes.fire(elem, 'bgsetproxy', { src: bg, useSrc: useSrc, fullSrc: null, }); if(!event.defaultPrevented){ elem.style.backgroundImage = event.detail.fullSrc || 'url(' + event.detail.useSrc + ')'; } } if(image._lazybgsetLoading){ lazySizes.fire(elem, '_lazyloaded', {}, false, true); delete image._lazybgsetLoading; } }; addEventListener('lazybeforeunveil', function(e){ var set, image, elem; if(e.defaultPrevented || !(set = e.target.getAttribute('data-bgset'))){return;} elem = e.target; image = document.createElement('img'); image.alt = ''; image._lazybgsetLoading = true; e.detail.firesLoad = true; createPicture(set, elem, image); setTimeout(function(){ lazySizes.loader.unveil(image); lazySizes.rAF(function(){ lazySizes.fire(image, '_lazyloaded', {}, true, true); if(image.complete) { proxyLoad({target: image}); } }); }); }); document.addEventListener('load', proxyLoad, true); window.addEventListener('lazybeforesizes', function(e){ if(e.detail.instance != lazySizes){return;} if(e.target._lazybgset && e.detail.dataAttr){ var elem = e.target._lazybgset; var bgSize = getBgSize(elem); if(allowedBackgroundSize[bgSize]){ e.target._lazysizesParentFit = bgSize; lazySizes.rAF(function(){ e.target.setAttribute('data-parent-fit', bgSize); if(e.target._lazysizesParentFit){ delete e.target._lazysizesParentFit; } }); } } }, true); document.documentElement.addEventListener('lazybeforesizes', function(e){ if(e.defaultPrevented || !e.target._lazybgset || e.detail.instance != lazySizes){return;} e.detail.width = proxyWidth(e.target._lazybgset); }); }));