UNPKG

lazysizes

Version:

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

256 lines (200 loc) 6.41 kB
(function(window, factory) { if(!window) {return;} 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); } }(typeof window != 'undefined' ? window : 0, function(window, document, lazySizes) { /*jshint eqnull:true */ 'use strict'; if(!window.addEventListener){return;} var config; var regPicture = /^picture$/i; var docElem = document.documentElement; var parseWsrcset = (function(){ var candidates; var reg = /(([^,\s].[^\s]+)\s+(\d+)(w|h)(\s+(\d+)(w|h))?)/g; var addCandidate = function(match, candidate, url, descNumber1, descType1, fullDesc, descNumber2, descType2){ candidates.push({ c: candidate, u: url, w: (descType2 == 'w' ? descNumber2 : descNumber1) * 1 }); }; return function(input){ candidates = []; input.replace(reg, addCandidate); return candidates; }; })(); var parseImg = (function(){ var ascendingSort = function ( a, b ) { return a.w - b.w; }; var parseSets = function (elem, dataName){ var lazyData = {srcset: elem.getAttribute(lazySizes.cfg.srcsetAttr) || ''}; var cands = parseWsrcset(lazyData.srcset); Object.defineProperty(elem, dataName, { value: lazyData, writable: true }); lazyData.cands = cands; lazyData.index = 0; lazyData.dirty = false; if(cands[0] && cands[0].w){ cands.sort( ascendingSort ); lazyData.cSrcset = [cands[ lazyData.index ].c]; } else { lazyData.cSrcset = lazyData.srcset ? [lazyData.srcset] : []; lazyData.cands = []; } return lazyData; }; return function parseImg(elem, dataName){ var sources, i, len, parent; if(!elem[dataName]){ parent = elem.parentNode || {}; elem[dataName] = parseSets(elem, dataName); elem[dataName].isImg = true; if(regPicture.test(parent.nodeName || '')){ elem[dataName].picture = true; sources = parent.getElementsByTagName('source'); for(i = 0, len = sources.length; i < len; i++){ parseSets(sources[i], dataName).isImg = false; } } } return elem[dataName]; }; })(); var constraintFns = { _lazyOptimumx: (function(){ var takeHighRes = function (lowerCandidate, higherCandidateResolution, optimumx){ var low, bonusFactor, substract; if(!lowerCandidate || !lowerCandidate.d){ return true; } substract = optimumx > 0.7 ? 0.6 : 0.4; if(lowerCandidate.d >= optimumx){return false;} bonusFactor = Math.pow(lowerCandidate.d - substract, 1.6) || 0.1; if(bonusFactor < 0.1){ bonusFactor = 0.1; } else if(bonusFactor > 3){ bonusFactor = 3; } low = lowerCandidate.d + ((higherCandidateResolution - optimumx) * bonusFactor); return low < optimumx; }; return function (data, width, optimumx){ var i, can; for(i = 0; i < data.cands.length; i++){ can = data.cands[i]; can.d = (can.w || 1) / width; if(data.index >= i){continue;} if(can.d <= optimumx || takeHighRes(data.cands[i - 1], can.d, optimumx)){ data.cSrcset.push(can.c); data.index = i; } else { break; } } }; })() }; var constrainSets = (function(){ var constrainSet = function(elem, displayWidth, optimumx, attr, dataName){ var curIndex; var lazyData = elem[dataName]; if(!lazyData){return;} curIndex = lazyData.index; constraintFns[dataName](lazyData, displayWidth, optimumx); if(!lazyData.dirty || curIndex != lazyData.index){ lazyData.cSrcset.join(', '); elem.setAttribute(attr, lazyData.cSrcset.join(', ')); lazyData.dirty = true; } }; return function(image, displayWidth, optimumx, attr, dataName){ var sources, parent, len, i; var lazyData = image[dataName]; lazyData.width = displayWidth; if(lazyData.picture && (parent = image.parentNode)){ sources = parent.getElementsByTagName('source'); for(i = 0, len = sources.length; i < len; i++){ constrainSet(sources[i], displayWidth, optimumx, attr, dataName); } } constrainSet(image, displayWidth, optimumx, attr, dataName); }; })(); var getOptimumX = function(element){ var optimumx = element.getAttribute('data-optimumx') || element.getAttribute('data-maxdpr'); if(!optimumx && config.constrainPixelDensity){ optimumx = 'auto'; } if(optimumx){ if(optimumx == 'auto'){ optimumx = config.getOptimumX(element); } else { optimumx = parseFloat(optimumx, 10); } } return optimumx; }; var extentLazySizes = function(){ if(lazySizes && !lazySizes.getOptimumX){ lazySizes.getX = getOptimumX; lazySizes.pWS = parseWsrcset; docElem.removeEventListener('lazybeforeunveil', extentLazySizes); } }; docElem.addEventListener('lazybeforeunveil', extentLazySizes); setTimeout(extentLazySizes); config = lazySizes && lazySizes.cfg; if(typeof config.getOptimumX != 'function'){ config.getOptimumX = function(/*element*/){ var dpr = window.devicePixelRatio || 1; if(dpr > 2.6){ dpr *= 0.6; // returns 1.8 for 3 } else if(dpr > 1.9){ dpr *= 0.8; // returns 1.6 for 2 } else { dpr -= 0.01; // returns 0.99 for 1 } return Math.min(Math.round(dpr * 100) / 100, 2); }; } if(!window.devicePixelRatio){return;} addEventListener('lazybeforesizes', function(e){ if(e.detail.instance != lazySizes){return;} var optimumx, lazyData, width, attr; var elem = e.target; var detail = e.detail; var dataAttr = detail.dataAttr; if(e.defaultPrevented || !(optimumx = getOptimumX(elem)) || optimumx >= devicePixelRatio){return;} if(dataAttr && elem._lazyOptimumx && !detail.reloaded && (!config.unloadedClass || !lazySizes.hC(elem, config.unloadedClass))){ elem._lazyOptimumx = null; } lazyData = parseImg(elem, '_lazyOptimumx'); width = detail.width; if(width && (lazyData.width || 0) < width){ attr = dataAttr ? lazySizes.cfg.srcsetAttr : 'srcset'; lazySizes.rAF(function(){ constrainSets(elem, width, optimumx, attr, '_lazyOptimumx'); }); } }); }));