lazysizes
Advanced tools
Comparing version 0.9.0 to 1.0.0-RC3
195
lazysizes.js
@@ -26,3 +26,3 @@ (function (window, factory) { | ||
if (!hasClass(ele, cls)){ | ||
ele.className += " "+cls; | ||
ele.className += ' '+cls; | ||
} | ||
@@ -48,6 +48,6 @@ }; | ||
var triggerEvent = function(elem, name, details){ | ||
var triggerEvent = function(elem, name, details, noBubbles, noCanceable){ | ||
var event = document.createEvent('Event'); | ||
event.initEvent(name, true, true); | ||
event.initEvent(name, !noBubbles, !noCanceable); | ||
@@ -61,20 +61,9 @@ event.details = details || {}; | ||
var updatePolyfill = function (el, full){ | ||
var imageData, attr; | ||
var polyfill; | ||
if(!window.HTMLPictureElement){ | ||
if(window.picturefill){ | ||
picturefill({reevaluate: true, reparse: true, elements: [el]}); | ||
} else if(window.respimage){ | ||
if(full && (attr = (full.srcset && 'srcset') || (full.src && 'src'))){ | ||
imageData = el[respimage._.ns]; | ||
if(imageData && imageData[attr] != full[attr] && el.getAttribute(attr) == full[attr]){ | ||
imageData[attr] = undefined; | ||
} | ||
} | ||
respimage({reparse: true, elements: [el]}); | ||
if( ( polyfill = (window.picturefill || window.respimage || lazySizesConfig.polyfill) ) ){ | ||
polyfill({reevaluate: true, reparse: true, elements: [el]}); | ||
} else if(full && full.src){ | ||
el.src = full.src; | ||
} | ||
} | ||
@@ -90,3 +79,3 @@ }; | ||
while(width < lazySizesConfig.minSize && parent && parent != document.body && !elem._lazysizesWidth){ | ||
while(width < lazySizesConfig.minSize && parent && !elem._lazysizesWidth){ | ||
width = parent.offsetWidth; | ||
@@ -111,3 +100,3 @@ parent = parent.parentNode; | ||
main(); | ||
timer = setInterval(main, 66); | ||
timer = setInterval(main, 51); | ||
} | ||
@@ -128,9 +117,7 @@ }; | ||
var loader = (function(){ | ||
var lazyloadElems, preloadElems, isPreloadAllowed, isCompleted, resetPreloadingTimer, runThrough; | ||
var isExpandCalculated, lazyloadElems, preloadElems, isCompleted, resetPreloadingTimer; | ||
var eLvW, elvH, eLtop, eLleft, eLright, eLbottom; | ||
var ua = navigator.userAgent; | ||
var fixChrome = window.HTMLPictureElement && ua.match(/hrome\/(\d+)/) && (RegExp.$1 == 40); | ||
var supportNativeLQIP = (/webkit/i).test(ua); | ||
var fixChrome = window.HTMLPictureElement && navigator.userAgent.match(/hrome\/(\d+)/) && (RegExp.$1 == 40); | ||
@@ -140,2 +127,4 @@ var regImg = /^img$/i; | ||
var supportScroll = ('onscroll' in window); | ||
var shrinkExpand = -2; | ||
@@ -145,3 +134,2 @@ var defaultExpand = shrinkExpand; | ||
var currentExpand = shrinkExpand; | ||
var isExpandCalculated = true; | ||
var lowRuns = 0; | ||
@@ -173,4 +161,4 @@ | ||
while(visible && (parent = parent.offsetParent) && parent != docElem && parent != document.body){ | ||
visible = (isCompleted && isLoading < 4) || ((getCSS(parent, 'opacity') || 1) > 0); | ||
while(visible && (parent = parent.offsetParent)){ | ||
visible = (isCompleted && isLoading < 2) || ((getCSS(parent, 'opacity') || 1) > 0); | ||
@@ -190,19 +178,21 @@ if(visible && getCSS(parent, 'overflow') != 'visible'){ | ||
var checkElements = function() { | ||
var rect, autoLoadElem, loadedSomething, elemExpand, elemNegativeExpand, elemExpandVal, beforeExpandVal; | ||
var i, start, rect, autoLoadElem, loadedSomething, elemExpand, elemNegativeExpand, elemExpandVal, beforeExpandVal; | ||
var eLlen = lazyloadElems.length; | ||
var start = Date.now(); | ||
var i = checkElementsIndex; | ||
if(eLlen && loader.m){ | ||
start = Date.now(); | ||
if(!isExpandCalculated){ | ||
calcExpand(); | ||
} | ||
if(!isExpandCalculated){ | ||
calcExpand(); | ||
} | ||
if(eLlen){ | ||
i = checkElementsIndex; | ||
for(; i < eLlen; i++, checkElementsIndex++){ | ||
if(!lazyloadElems[i]){break;} | ||
if(!lazyloadElems[i] || lazyloadElems[i]._lazyRace){continue;} | ||
if(!supportScroll){unveilElement(lazyloadElems[i]);continue;} | ||
if(!(elemExpandVal = lazyloadElems[i].getAttribute('data-expand')) || !(elemExpand = elemExpandVal * 1)){ | ||
@@ -214,3 +204,3 @@ elemExpand = currentExpand; | ||
if(isLoading > 3 && elemExpand > shrinkExpand){ | ||
if(elemExpand > shrinkExpand && (loader.m < 2 || isLoading > 3)){ | ||
elemExpand = shrinkExpand; | ||
@@ -233,3 +223,3 @@ } | ||
(eLbottom || eLright || eLleft || eLtop) && | ||
((isCompleted && currentExpand == defaultExpand && isLoading < 3 && lowRuns < 4 && !elemExpandVal) || isNestedVisible(lazyloadElems[i], elemExpand))){ | ||
((isCompleted && currentExpand < preloadExpand && isLoading < 3 && lowRuns < 4 && !elemExpandVal) || isNestedVisible(lazyloadElems[i], elemExpand))){ | ||
checkElementsIndex--; | ||
@@ -241,5 +231,4 @@ start += 2; | ||
if(!runThrough && Date.now() - start > 3){ | ||
if(Date.now() - start > 3){ | ||
checkElementsIndex++; | ||
runThrough = true; | ||
throttledCheckElements(); | ||
@@ -255,3 +244,2 @@ return; | ||
} | ||
} | ||
@@ -261,12 +249,13 @@ } | ||
checkElementsIndex = 0; | ||
runThrough = false; | ||
lowRuns++; | ||
if(currentExpand < preloadExpand && isLoading < 2 && lowRuns > 4){ | ||
if(currentExpand < preloadExpand && isLoading < 2 && lowRuns > 5 && loader.m > 2){ | ||
currentExpand = preloadExpand; | ||
lowRuns = 0; | ||
throttledCheckElements(); | ||
} else if(currentExpand != defaultExpand){ | ||
} else if(currentExpand != defaultExpand && loader.m > 1 && lowRuns > 4){ | ||
currentExpand = defaultExpand; | ||
} else { | ||
currentExpand = shrinkExpand; | ||
} | ||
@@ -306,4 +295,5 @@ | ||
if( (isAuto || (!supportNativeLQIP && !isCompleted)) && isImg && curSrc && !elem.complete && !hasClass(elem, lazySizesConfig.errorClass)){return;} | ||
if( (isAuto || !isCompleted) && isImg && curSrc && !elem.complete && !hasClass(elem, lazySizesConfig.errorClass)){return;} | ||
elem._lazyRace = true; | ||
if(!(event = triggerEvent(elem, 'lazybeforeunveil', {force: !!force})).defaultPrevented){ | ||
@@ -339,3 +329,3 @@ | ||
for(i = 0, len = sources.length; i < len; i++){ | ||
if( (customMedia = lazySizesConfig.customMedia[sources[i].getAttribute('media')]) ){ | ||
if( (customMedia = lazySizesConfig.customMedia[sources[i].getAttribute('data-media') || sources[i].getAttribute('media')]) ){ | ||
sources[i].setAttribute('media', customMedia); | ||
@@ -365,9 +355,11 @@ } | ||
if(lazySizesConfig.addClasses){ | ||
addClass(elem, lazySizesConfig.loadingClass); | ||
addRemoveLoadEvents(elem, switchLoadingClass, true); | ||
} | ||
addClass(elem, lazySizesConfig.loadingClass); | ||
addRemoveLoadEvents(elem, switchLoadingClass, true); | ||
} | ||
setTimeout(function(){ | ||
if(elem._lazyRace){ | ||
delete elem._lazyRace; | ||
} | ||
if(sizes == 'auto'){ | ||
@@ -378,3 +370,3 @@ addClass(elem, lazySizesConfig.autosizesClass); | ||
if(srcset || isPicture){ | ||
updatePolyfill(elem, {srcset: srcset, src: src}); | ||
updatePolyfill(elem, {src: src}); | ||
} | ||
@@ -389,5 +381,3 @@ | ||
} | ||
if(lazySizesConfig.addClasses){ | ||
switchLoadingClass(event); | ||
} | ||
switchLoadingClass(event); | ||
} | ||
@@ -400,4 +390,4 @@ elem = null; | ||
if(isPreloadAllowed && !isExpandCalculated){ | ||
defaultExpand = Math.max( Math.min(lazySizesConfig.expand || lazySizesConfig.threshold || 120, 300), 9 ); | ||
if(!isExpandCalculated){ | ||
defaultExpand = Math.max( Math.min(lazySizesConfig.expand || 140, 300), 9 ); | ||
preloadExpand = defaultExpand * 4; | ||
@@ -410,4 +400,3 @@ } | ||
var allowPreload = function(){ | ||
isPreloadAllowed = true; | ||
isExpandCalculated = false; | ||
loader.m = 3; | ||
}; | ||
@@ -417,2 +406,3 @@ | ||
isCompleted = true; | ||
lowRuns += 6; | ||
@@ -423,41 +413,41 @@ allowPreload(); | ||
var init = function(){ | ||
return { | ||
_i: function(){ | ||
lazyloadElems = document.getElementsByClassName(lazySizesConfig.lazyClass); | ||
preloadElems = document.getElementsByClassName(lazySizesConfig.lazyClass+' '+lazySizesConfig.preloadClass); | ||
lazyloadElems = document.getElementsByClassName(lazySizesConfig.lazyClass); | ||
preloadElems = document.getElementsByClassName(lazySizesConfig.lazyClass+' '+lazySizesConfig.preloadClass); | ||
if(lazySizesConfig.scroll) { | ||
addEventListener('scroll', throttledCheckElements, true); | ||
} | ||
if(lazySizesConfig.scroll) { | ||
addEventListener('scroll', throttledCheckElements, true); | ||
} | ||
addEventListener('resize', function(){ | ||
isExpandCalculated = false; | ||
throttledCheckElements(); | ||
}); | ||
addEventListener('resize', function(){ | ||
isExpandCalculated = false; | ||
throttledCheckElements(); | ||
}, true); | ||
if(window.MutationObserver){ | ||
new MutationObserver( throttledCheckElements ).observe( docElem, {childList: true, subtree: true, attributes: true} ); | ||
} else { | ||
docElem.addEventListener('DOMNodeInserted', throttledCheckElements, true); | ||
docElem.addEventListener('DOMAttrModified', throttledCheckElements, true); | ||
} | ||
if(window.MutationObserver){ | ||
new MutationObserver( throttledCheckElements ).observe( docElem, {childList: true, subtree: true, attributes: true} ); | ||
} else { | ||
docElem.addEventListener('DOMNodeInserted', throttledCheckElements, true); | ||
docElem.addEventListener('DOMAttrModified', throttledCheckElements, true); | ||
setInterval(throttledCheckElements, 3000); | ||
} | ||
addEventListener('hashchange', throttledCheckElements, true); | ||
addEventListener('hashchange', throttledCheckElements, true); | ||
['transitionstart', 'transitionend', 'load', 'focus', 'mouseover', 'animationend', 'click'].forEach(function(evt){ | ||
document.addEventListener(evt, throttledCheckElements, true); | ||
}); | ||
['transitionstart', 'transitionend', 'load', 'focus', 'mouseover', 'animationend', 'click'].forEach(function(evt){ | ||
document.addEventListener(evt, throttledCheckElements, true); | ||
}); | ||
if(!(isCompleted = /d$|^c/.test(document.readyState))){ | ||
addEventListener('load', onload); | ||
document.addEventListener('DOMContentLoaded', throttledCheckElements); | ||
} | ||
if(!(isCompleted = /d$|^c/.test(document.readyState))){ | ||
addEventListener('load', onload); | ||
document.addEventListener('DOMContentLoaded', throttledCheckElements); | ||
} | ||
setTimeout(allowPreload, 666); | ||
throttledCheckElements(); | ||
}; | ||
return { | ||
init: init, | ||
setTimeout(allowPreload, 777); | ||
throttledCheckElements(lazyloadElems.length > 0); | ||
}, | ||
m: 1, | ||
checkElems: throttledCheckElements, | ||
@@ -517,9 +507,7 @@ unveil: unveilElement | ||
var init = function(){ | ||
autosizesElems = document.getElementsByClassName(lazySizesConfig.autosizesClass); | ||
addEventListener('resize', throttledUpdateElementsSizes); | ||
}; | ||
return { | ||
init: init, | ||
_i: function(){ | ||
autosizesElems = document.getElementsByClassName(lazySizesConfig.autosizesClass); | ||
addEventListener('resize', throttledUpdateElementsSizes); | ||
}, | ||
checkElems: throttledUpdateElementsSizes, | ||
@@ -533,4 +521,4 @@ updateElem: sizeElement | ||
init.i = true; | ||
autoSizer.init(); | ||
loader.init(); | ||
autoSizer._i(); | ||
loader._i(); | ||
} | ||
@@ -546,2 +534,3 @@ }; | ||
preloadClass: 'lazypreload', | ||
errorClass: 'lazyerror', | ||
scroll: true, | ||
@@ -552,3 +541,2 @@ autosizesClass: 'lazyautosizes', | ||
sizesAttr: 'data-sizes', | ||
addClasses: true, | ||
//preloadAfterLoad: false, | ||
@@ -570,9 +558,9 @@ minSize: 50, | ||
if(lazySizesDefaults.init){ | ||
setTimeout(init); | ||
} | ||
setTimeout(function(){ | ||
if(lazySizesConfig.init){ | ||
init(); | ||
} | ||
}); | ||
})(); | ||
return { | ||
@@ -583,9 +571,2 @@ cfg: lazySizesConfig, | ||
init: init, | ||
//depreacated methods will be removed with next major version | ||
updateAllSizes: autoSizer.updateElems, | ||
updateAllLazy: loader.checkElems, | ||
unveilLazy: loader.unveil, | ||
//undocumented internal methods - use with caution | ||
uS: autoSizer.updateElem, // will be removed with next major version | ||
uP: updatePolyfill, | ||
@@ -592,0 +573,0 @@ aC: addClass, |
@@ -1,3 +0,3 @@ | ||
/*! lazysizes - v0.9.0 - 2015-02-02 | ||
/*! lazysizes - v1.0.0-RC3 - 2015-02-25 | ||
Licensed MIT */ | ||
!function(a,b){a.lazySizes=b(a,a.document),"function"==typeof define&&define.amd&&define(a.lazySizes)}(window,function(a,b){"use strict";if(b.getElementsByClassName){var c,d=b.documentElement,e=/^picture$/i,f=["load","error","lazyincluded","_lazyloaded"],g=function(a,b){var c=new RegExp("(\\s|^)"+b+"(\\s|$)");return a.className.match(c)&&c},h=function(a,b){g(a,b)||(a.className+=" "+b)},i=function(a,b){var c;(c=g(a,b))&&(a.className=a.className.replace(c," "))},j=function(a,b,c){var d=c?"addEventListener":"removeEventListener";c&&j(a,b),f.forEach(function(c){a[d](c,b)})},k=function(a,c,d){var e=b.createEvent("Event");return e.initEvent(c,!0,!0),e.details=d||{},a.dispatchEvent(e),e},l=function(b,c){var d,e;a.HTMLPictureElement||(a.picturefill?picturefill({reevaluate:!0,reparse:!0,elements:[b]}):a.respimage?(c&&(e=c.srcset&&"srcset"||c.src&&"src")&&(d=b[respimage._.ns],d&&d[e]!=c[e]&&b.getAttribute(e)==c[e]&&(d[e]=void 0)),respimage({reparse:!0,elements:[b]})):c&&c.src&&(b.src=c.src))},m=function(a,b){return getComputedStyle(a,null)[b]},n=function(a,d){for(var e=a.offsetWidth;e<c.minSize&&d&&d!=b.body&&!a._lazysizesWidth;)e=d.offsetWidth,d=d.parentNode;return e},o=function(a){var c,d,e=function(){c&&(c=!1,a())},f=function(){clearInterval(d),b.hidden||(e(),d=setInterval(e,66))};return b.addEventListener("visibilitychange",f),f(),function(a){c=!0,a===!0&&e()}},p=function(){var f,n,p,r,s,t,u,v,w,x,y,z,A=navigator.userAgent,B=a.HTMLPictureElement&&A.match(/hrome\/(\d+)/)&&40==RegExp.$1,C=/webkit/i.test(A),D=/^img$/i,E=/^iframe$/i,F=-2,G=F,H=F,I=F,J=!0,K=0,L=0,M=0,N=function(a){L--,a&&a.target&&j(a.target,N),(!a||0>L||!a.target)&&(L=0)},O=function(a,c){var e,f=a,g="hidden"!=m(a,"visibility");for(w-=c,z+=c,x-=c,y+=c;g&&(f=f.offsetParent)&&f!=d&&f!=b.body;)g=r&&4>L||(m(f,"opacity")||1)>0,g&&"visible"!=m(f,"overflow")&&(e=f.getBoundingClientRect(),g=y>e.left-1&&x<e.right+1&&z>e.top-1&&w<e.bottom+1);return g},P=function(){var a,b,d,e,g,h,i,j=f.length,k=Date.now(),l=M;if(J||U(),j){for(;j>l&&f[l];l++,M++)if((h=f[l].getAttribute("data-expand"))&&(e=1*h)||(e=I),!(L>6&&(!h||"src"in f[l])))if(L>3&&e>F&&(e=F),i!==e&&(u=innerWidth+e,v=innerHeight+e,g=-1*e,i=e),a=f[l].getBoundingClientRect(),(z=a.bottom)>=g&&(w=a.top)<=v&&(y=a.right)>=g&&(x=a.left)<=u&&(z||y||x||w)&&(r&&I==G&&3>L&&4>K&&!h||O(f[l],e)))M--,k+=2,T(f[l]),d=!0;else{if(!t&&Date.now()-k>3)return M++,t=!0,void Q();!d&&r&&!b&&3>L&&4>K&&(n[0]||c.preloadAfterLoad)&&(n[0]||!h&&(z||y||x||w||"auto"!=f[l].getAttribute(c.sizesAttr)))&&(b=n[0]||f[l])}M=0,t=!1,K++,H>I&&2>L&&K>4?(I=H,K=0,Q()):I!=G&&(I=G),b&&!d&&T(b)}},Q=o(P),R=function(a){h(a.target,c.loadedClass),i(a.target,c.loadingClass),j(a.target,R)},S=function(a,b){try{a.contentWindow.location.replace(b)}catch(c){a.setAttribute("src",b)}},T=function(a,b){var d,f,m,n,o,p,t,u,v,w,x,y=a.currentSrc||a.src,z=D.test(a.nodeName),A=a.getAttribute(c.sizesAttr)||a.getAttribute("sizes"),F="auto"==A;if(!F&&(C||r)||!z||!y||a.complete||g(a,c.errorClass)){if(!(v=k(a,"lazybeforeunveil",{force:!!b})).defaultPrevented){if(A&&(F?q.updateElem(a,!0):a.setAttribute("sizes",A)),p=a.getAttribute(c.srcsetAttr),o=a.getAttribute(c.srcAttr),z&&(t=a.parentNode,u=e.test(t.nodeName||"")),w=v.details.firesLoad||"src"in a&&(p||o||u),w&&(L++,j(a,N,!0),clearTimeout(s),s=setTimeout(N,3e3)),u)for(d=t.getElementsByTagName("source"),f=0,m=d.length;m>f;f++)(x=c.customMedia[d[f].getAttribute("media")])&&d[f].setAttribute("media",x),n=d[f].getAttribute(c.srcsetAttr),n&&d[f].setAttribute("srcset",n);p?(a.setAttribute("srcset",p),B&&A&&a.removeAttribute("src")):o&&(E.test(a.nodeName)?S(a,o):a.setAttribute("src",o)),c.addClasses&&(h(a,c.loadingClass),j(a,R,!0))}setTimeout(function(){"auto"==A&&h(a,c.autosizesClass),(p||u)&&l(a,{srcset:p,src:o}),i(a,c.lazyClass),(!w||a.complete&&y==(a.currentSrc||a.src))&&(w&&N(v),c.addClasses&&R(v)),a=null})}},U=function(){p&&!J&&(G=Math.max(Math.min(c.expand||c.threshold||120,300),9),H=4*G),J=!0},V=function(){p=!0,J=!1},W=function(){r=!0,V(),Q(!0)},X=function(){f=b.getElementsByClassName(c.lazyClass),n=b.getElementsByClassName(c.lazyClass+" "+c.preloadClass),c.scroll&&addEventListener("scroll",Q,!0),addEventListener("resize",function(){J=!1,Q()}),a.MutationObserver?new MutationObserver(Q).observe(d,{childList:!0,subtree:!0,attributes:!0}):(d.addEventListener("DOMNodeInserted",Q,!0),d.addEventListener("DOMAttrModified",Q,!0)),addEventListener("hashchange",Q,!0),["transitionstart","transitionend","load","focus","mouseover","animationend","click"].forEach(function(a){b.addEventListener(a,Q,!0)}),(r=/d$|^c/.test(b.readyState))||(addEventListener("load",W),b.addEventListener("DOMContentLoaded",Q)),setTimeout(V,666),Q()};return{init:X,checkElems:Q,unveil:T}}(),q=function(){var a,d=function(a,b){var c,d,f,g,h,i=a.parentNode;if(i&&(c=n(a,i),h=k(a,"lazybeforesizes",{width:c,dataAttr:!!b}),!h.defaultPrevented&&(c=h.details.width,c&&c!==a._lazysizesWidth))){if(a._lazysizesWidth=c,c+="px",a.setAttribute("sizes",c),e.test(i.nodeName||""))for(d=i.getElementsByTagName("source"),f=0,g=d.length;g>f;f++)d[f].setAttribute("sizes",c);h.details.dataAttr||l(a,h.details)}},f=function(){var b,c=a.length;if(c)for(b=0;c>b;b++)d(a[b])},g=o(f),h=function(){a=b.getElementsByClassName(c.autosizesClass),addEventListener("resize",g)};return{init:h,checkElems:g,updateElem:d}}(),r=function(){r.i||(r.i=!0,q.init(),p.init())};return function(){var b,d={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",scroll:!0,autosizesClass:"lazyautosizes",srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",addClasses:!0,minSize:50,customMedia:{},init:!0};c=a.lazySizesConfig||{};for(b in d)b in c||(c[b]=d[b]);a.lazySizesConfig=c,d.init&&setTimeout(r)}(),{cfg:c,autoSizer:q,loader:p,init:r,updateAllSizes:q.updateElems,updateAllLazy:p.checkElems,unveilLazy:p.unveil,uS:q.updateElem,uP:l,aC:h,rC:i,hC:g,fire:k,gW:n}}}); | ||
!function(a,b){a.lazySizes=b(a,a.document),"function"==typeof define&&define.amd&&define(a.lazySizes)}(window,function(a,b){"use strict";if(b.getElementsByClassName){var c,d=b.documentElement,e=/^picture$/i,f=["load","error","lazyincluded","_lazyloaded"],g=function(a,b){var c=new RegExp("(\\s|^)"+b+"(\\s|$)");return a.className.match(c)&&c},h=function(a,b){g(a,b)||(a.className+=" "+b)},i=function(a,b){var c;(c=g(a,b))&&(a.className=a.className.replace(c," "))},j=function(a,b,c){var d=c?"addEventListener":"removeEventListener";c&&j(a,b),f.forEach(function(c){a[d](c,b)})},k=function(a,c,d,e,f){var g=b.createEvent("Event");return g.initEvent(c,!e,!f),g.details=d||{},a.dispatchEvent(g),g},l=function(b,d){var e;a.HTMLPictureElement||((e=a.picturefill||a.respimage||c.polyfill)?e({reevaluate:!0,reparse:!0,elements:[b]}):d&&d.src&&(b.src=d.src))},m=function(a,b){return getComputedStyle(a,null)[b]},n=function(a,b){for(var d=a.offsetWidth;d<c.minSize&&b&&!a._lazysizesWidth;)d=b.offsetWidth,b=b.parentNode;return d},o=function(a){var c,d,e=function(){c&&(c=!1,a())},f=function(){clearInterval(d),b.hidden||(e(),d=setInterval(e,51))};return b.addEventListener("visibilitychange",f),f(),function(a){c=!0,a===!0&&e()}},p=function(){var f,n,r,s,t,u,v,w,x,y,z,A=a.HTMLPictureElement&&navigator.userAgent.match(/hrome\/(\d+)/)&&40==RegExp.$1,B=/^img$/i,C=/^iframe$/i,D="onscroll"in a,E=-2,F=E,G=E,H=E,I=0,J=0,K=0,L=function(a){J--,a&&a.target&&j(a.target,L),(!a||0>J||!a.target)&&(J=0)},M=function(a,b){var c,d=a,e="hidden"!=m(a,"visibility");for(w-=b,z+=b,x-=b,y+=b;e&&(d=d.offsetParent);)e=s&&2>J||(m(d,"opacity")||1)>0,e&&"visible"!=m(d,"overflow")&&(c=d.getBoundingClientRect(),e=y>c.left-1&&x<c.right+1&&z>c.top-1&&w<c.bottom+1);return e},N=function(){var a,b,d,e,g,h,i,j,k,l=n.length;if(l&&p.m){for(b=Date.now(),f||S(),a=K;l>a;a++,K++)if(n[a]&&!n[a]._lazyRace)if(D){if((j=n[a].getAttribute("data-expand"))&&(h=1*j)||(h=H),!(J>6&&(!j||"src"in n[a])))if(h>E&&(p.m<2||J>3)&&(h=E),k!==h&&(u=innerWidth+h,v=innerHeight+h,i=-1*h,k=h),d=n[a].getBoundingClientRect(),(z=d.bottom)>=i&&(w=d.top)<=v&&(y=d.right)>=i&&(x=d.left)<=u&&(z||y||x||w)&&(s&&G>H&&3>J&&4>I&&!j||M(n[a],h)))K--,b+=2,R(n[a]),g=!0;else{if(Date.now()-b>3)return K++,void O();!g&&s&&!e&&3>J&&4>I&&(r[0]||c.preloadAfterLoad)&&(r[0]||!j&&(z||y||x||w||"auto"!=n[a].getAttribute(c.sizesAttr)))&&(e=r[0]||n[a])}}else R(n[a]);K=0,I++,G>H&&2>J&&I>5&&p.m>2?(H=G,I=0,O()):H=H!=F&&p.m>1&&I>4?F:E,e&&!g&&R(e)}},O=o(N),P=function(a){h(a.target,c.loadedClass),i(a.target,c.loadingClass),j(a.target,P)},Q=function(a,b){try{a.contentWindow.location.replace(b)}catch(c){a.setAttribute("src",b)}},R=function(a,b){var d,f,m,n,o,p,r,u,v,w,x,y=a.currentSrc||a.src,z=B.test(a.nodeName),D=a.getAttribute(c.sizesAttr)||a.getAttribute("sizes"),E="auto"==D;if(!E&&s||!z||!y||a.complete||g(a,c.errorClass)){if(a._lazyRace=!0,!(v=k(a,"lazybeforeunveil",{force:!!b})).defaultPrevented){if(D&&(E?q.updateElem(a,!0):a.setAttribute("sizes",D)),p=a.getAttribute(c.srcsetAttr),o=a.getAttribute(c.srcAttr),z&&(r=a.parentNode,u=e.test(r.nodeName||"")),w=v.details.firesLoad||"src"in a&&(p||o||u),w&&(J++,j(a,L,!0),clearTimeout(t),t=setTimeout(L,3e3)),u)for(d=r.getElementsByTagName("source"),f=0,m=d.length;m>f;f++)(x=c.customMedia[d[f].getAttribute("data-media")||d[f].getAttribute("media")])&&d[f].setAttribute("media",x),n=d[f].getAttribute(c.srcsetAttr),n&&d[f].setAttribute("srcset",n);p?(a.setAttribute("srcset",p),A&&D&&a.removeAttribute("src")):o&&(C.test(a.nodeName)?Q(a,o):a.setAttribute("src",o)),h(a,c.loadingClass),j(a,P,!0)}setTimeout(function(){a._lazyRace&&delete a._lazyRace,"auto"==D&&h(a,c.autosizesClass),(p||u)&&l(a,{src:o}),i(a,c.lazyClass),(!w||a.complete&&y==(a.currentSrc||a.src))&&(w&&L(v),P(v)),a=null})}},S=function(){f||(F=Math.max(Math.min(c.expand||140,300),9),G=4*F),f=!0},T=function(){p.m=3},U=function(){s=!0,I+=6,T(),O(!0)};return{_i:function(){n=b.getElementsByClassName(c.lazyClass),r=b.getElementsByClassName(c.lazyClass+" "+c.preloadClass),c.scroll&&addEventListener("scroll",O,!0),addEventListener("resize",function(){f=!1,O()},!0),a.MutationObserver?new MutationObserver(O).observe(d,{childList:!0,subtree:!0,attributes:!0}):(d.addEventListener("DOMNodeInserted",O,!0),d.addEventListener("DOMAttrModified",O,!0),setInterval(O,3e3)),addEventListener("hashchange",O,!0),["transitionstart","transitionend","load","focus","mouseover","animationend","click"].forEach(function(a){b.addEventListener(a,O,!0)}),(s=/d$|^c/.test(b.readyState))||(addEventListener("load",U),b.addEventListener("DOMContentLoaded",O)),setTimeout(T,777),O(n.length>0)},m:1,checkElems:O,unveil:R}}(),q=function(){var a,d=function(a,b){var c,d,f,g,h,i=a.parentNode;if(i&&(c=n(a,i),h=k(a,"lazybeforesizes",{width:c,dataAttr:!!b}),!h.defaultPrevented&&(c=h.details.width,c&&c!==a._lazysizesWidth))){if(a._lazysizesWidth=c,c+="px",a.setAttribute("sizes",c),e.test(i.nodeName||""))for(d=i.getElementsByTagName("source"),f=0,g=d.length;g>f;f++)d[f].setAttribute("sizes",c);h.details.dataAttr||l(a,h.details)}},f=function(){var b,c=a.length;if(c)for(b=0;c>b;b++)d(a[b])},g=o(f);return{_i:function(){a=b.getElementsByClassName(c.autosizesClass),addEventListener("resize",g)},checkElems:g,updateElem:d}}(),r=function(){r.i||(r.i=!0,q._i(),p._i())};return function(){var b,d={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",scroll:!0,autosizesClass:"lazyautosizes",srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:50,customMedia:{},init:!0};c=a.lazySizesConfig||{};for(b in d)b in c||(c[b]=d[b]);a.lazySizesConfig=c,setTimeout(function(){c.init&&r()})}(),{cfg:c,autoSizer:q,loader:p,init:r,uP:l,aC:h,rC:i,hC:g,fire:k,gW:n}}}); |
{ | ||
"name": "lazysizes", | ||
"version": "0.9.0", | ||
"version": "1.0.0-RC3", | ||
"filename": "lazysizes.min.js", | ||
@@ -5,0 +5,0 @@ "author": "Alexander Farkas <info@corrupt-system.de>", |
@@ -19,3 +19,17 @@ (function(){ | ||
var sizes = elem.getAttribute(lazySizesConfig.sizesAttr); | ||
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.split(regSplitSet); | ||
@@ -48,9 +62,7 @@ | ||
img.setAttribute(lazySizesConfig.sizesAttr, sizes); | ||
if(sizes == 'auto'){ | ||
Object.defineProperty(img, '_lazybgset', { | ||
value: elem, | ||
writable: true | ||
}); | ||
} | ||
elem.removeAttribute(lazySizesConfig.sizesAttr); | ||
} | ||
if(optimumx){ | ||
img.setAttribute('data-optimumx', optimumx); | ||
} | ||
@@ -60,9 +72,6 @@ picture.appendChild(img); | ||
elem.appendChild(picture); | ||
elem.removeAttribute(lazySizesConfig.sizesAttr); | ||
}; | ||
addEventListener('lazybeforeunveil', function(e){ | ||
var set, image, load, init, elem; | ||
var set, image, elem; | ||
@@ -74,28 +83,28 @@ if(e.defaultPrevented || !(set = e.target.getAttribute('data-bgset'))){return;} | ||
load = function(evt){ | ||
var bg = evt.type == 'load' ? image.currentSrc || image.src : false; | ||
if(bg){ | ||
elem.style.backgroundImage = 'url('+ bg +')'; | ||
} | ||
if(!init){ | ||
lazySizes.fire(elem, '_lazyloaded'); | ||
if(e && e.details){ | ||
e.details.firesLoad = false; | ||
} | ||
init = true; | ||
e = null; | ||
} | ||
}; | ||
image._lazybgsetLoading = true; | ||
e.details.firesLoad = true; | ||
image.addEventListener('load', load); | ||
image.addEventListener('error', load); | ||
createPicture(set, elem, image); | ||
lazySizes.loader.unveil(image); | ||
lazySizes.fire(image, '_lazyloaded', {}, true, true); | ||
}); | ||
document.addEventListener('load', function(e){ | ||
if(!e.target._lazybgset){return;} | ||
var image = e.target; | ||
var elem = image._lazybgset; | ||
var bg = image.currentSrc || image.src; | ||
if(bg){ | ||
elem.style.backgroundImage = 'url('+ bg +')'; | ||
} | ||
if(image._lazybgsetLoading){ | ||
lazySizes.fire(elem, '_lazyloaded', {}, false, true); | ||
delete image._lazybgsetLoading; | ||
} | ||
}, true); | ||
addEventListener('lazybeforesizes', function(e){ | ||
@@ -102,0 +111,0 @@ if(e.defaultPrevented || !e.target._lazybgset){return;} |
@@ -1,3 +0,3 @@ | ||
/*! lazysizes - v0.9.0 - 2015-02-02 | ||
/*! lazysizes - v1.0.0-RC3 - 2015-02-25 | ||
Licensed MIT */ | ||
!function(){"use strict";if(window.addEventListener){var a=/\s*\|\s+|\s+\|\s*/g,b=/^(.+?)(?:\s+\[\s*(.+?)\s*\])?$/,c=function(a){var b=lazySizes.gW(a,a.parentNode);return(!a._lazysizesWidth||b>a._lazysizesWidth)&&(a._lazysizesWidth=b),a._lazysizesWidth},d=function(c,d,e){var f=document.createElement("picture"),g=d.getAttribute(lazySizesConfig.sizesAttr);c=c.split(a),f.style.display="none",e.className=lazySizesConfig.lazyClass,1!=c.length||g||(g="auto"),c.forEach(function(a){var c=document.createElement("source");g&&"auto"!=g&&c.setAttribute("sizes",g),a.match(b)&&(c.setAttribute(lazySizesConfig.srcsetAttr,RegExp.$1),RegExp.$2&&c.setAttribute("media",RegExp.$2)),f.appendChild(c)}),g&&(e.setAttribute(lazySizesConfig.sizesAttr,g),"auto"==g&&Object.defineProperty(e,"_lazybgset",{value:d,writable:!0})),f.appendChild(e),d.appendChild(f),d.removeAttribute(lazySizesConfig.sizesAttr)};addEventListener("lazybeforeunveil",function(a){var b,c,e,f,g;!a.defaultPrevented&&(b=a.target.getAttribute("data-bgset"))&&(g=a.target,c=document.createElement("img"),e=function(b){var d="load"==b.type?c.currentSrc||c.src:!1;d&&(g.style.backgroundImage="url("+d+")"),f||(lazySizes.fire(g,"_lazyloaded"),a&&a.details&&(a.details.firesLoad=!1),f=!0,a=null)},a.details.firesLoad=!0,c.addEventListener("load",e),c.addEventListener("error",e),d(b,g,c),lazySizes.loader.unveil(c))}),addEventListener("lazybeforesizes",function(a){!a.defaultPrevented&&a.target._lazybgset&&(a.details.width=c(a.target._lazybgset))})}}(); | ||
!function(){"use strict";if(window.addEventListener){var a=/\s*\|\s+|\s+\|\s*/g,b=/^(.+?)(?:\s+\[\s*(.+?)\s*\])?$/,c=function(a){var b=lazySizes.gW(a,a.parentNode);return(!a._lazysizesWidth||b>a._lazysizesWidth)&&(a._lazysizesWidth=b),a._lazysizesWidth},d=function(c,d,e){var f=document.createElement("picture"),g=d.getAttribute(lazySizesConfig.sizesAttr),h=d.getAttribute("data-optimumx");d._lazybgset&&d._lazybgset.parentNode==d&&d.removeChild(d._lazybgset),Object.defineProperty(e,"_lazybgset",{value:d,writable:!0}),Object.defineProperty(d,"_lazybgset",{value:f,writable:!0}),c=c.split(a),f.style.display="none",e.className=lazySizesConfig.lazyClass,1!=c.length||g||(g="auto"),c.forEach(function(a){var c=document.createElement("source");g&&"auto"!=g&&c.setAttribute("sizes",g),a.match(b)&&(c.setAttribute(lazySizesConfig.srcsetAttr,RegExp.$1),RegExp.$2&&c.setAttribute("media",RegExp.$2)),f.appendChild(c)}),g&&(e.setAttribute(lazySizesConfig.sizesAttr,g),d.removeAttribute(lazySizesConfig.sizesAttr)),h&&e.setAttribute("data-optimumx",h),f.appendChild(e),d.appendChild(f)};addEventListener("lazybeforeunveil",function(a){var b,c,e;!a.defaultPrevented&&(b=a.target.getAttribute("data-bgset"))&&(e=a.target,c=document.createElement("img"),c._lazybgsetLoading=!0,a.details.firesLoad=!0,d(b,e,c),lazySizes.loader.unveil(c),lazySizes.fire(c,"_lazyloaded",{},!0,!0))}),document.addEventListener("load",function(a){if(a.target._lazybgset){var b=a.target,c=b._lazybgset,d=b.currentSrc||b.src;d&&(c.style.backgroundImage="url("+d+")"),b._lazybgsetLoading&&(lazySizes.fire(c,"_lazyloaded",{},!1,!0),delete b._lazybgsetLoading)}},!0),addEventListener("lazybeforesizes",function(a){!a.defaultPrevented&&a.target._lazybgset&&(a.details.width=c(a.target._lazybgset))})}}(); |
@@ -1,6 +0,6 @@ | ||
#lazysizes bgset extension | ||
#lazysizes bgset extension - responsive background images | ||
This simple and small plugin allows you to define multiple background images with a width descriptor, similar to how ``img[srcset]`` works as also art directed images using media queries. | ||
This simple and small plugin allows you to define multiple background images with a width descriptor, similar to how ``img[srcset]`` works as also art directed images using media queries, similar to how ``picture`` works. | ||
The extension will then load the best image size for the current viewport and device. In case the browser does not support responsive images natively either picturefill or respimage has to be used: | ||
The extension will then load the best image size for the current viewport and device. In case the browser does not support responsive images natively either picturefill, respimage or the [respimg polyfill plugin](../respimg) has to be used: | ||
@@ -12,3 +12,3 @@ ```html | ||
if(!window.HTMLPictureElement){ | ||
loadJS("http://cdn.jsdelivr.net/g/respimage(respimage.min.js)"); | ||
loadJS("ls.respimg.min.js"); | ||
} | ||
@@ -41,2 +41,4 @@ </script> | ||
<div class="lazyload" data-bgset="image-200.jpg [--small] | image-300.jpg [--medium] | image-400.jpg"></div> | ||
<!-- or without customMedia options: --> | ||
<div class="lazyload" data-bgset="image-200.jpg [(max-width: 480px)] | image-300.jpg [(max-width: 700px)] | image-400.jpg"></div> | ||
``` | ||
@@ -43,0 +45,0 @@ |
@@ -13,3 +13,5 @@ /* | ||
var create = function(){ | ||
if(!window.lazySizes || lazySizes.getCustomMedias){return;} | ||
if(!window.lazySizes || window.lazySizes.getCustomMedias){return;} | ||
var lazySizes = window.lazySizes; | ||
lazySizes.getCustomMedias = (function(){ | ||
@@ -31,3 +33,3 @@ var regCleanPseudos = /['"]/g; | ||
return function(object, element){ | ||
object = object || {}; | ||
object = object || lazySizes.cfg.customMedia; | ||
element = element || document.querySelector('html'); | ||
@@ -40,3 +42,22 @@ parse(getStyle(element, ':before'), object); | ||
lazySizes.getCustomMedias(lazySizes.cfg.customMedia); | ||
lazySizes.reassignCustomMedia = function(){ | ||
var i, len, customMedia; | ||
var elems = docElem.querySelectorAll('source[media][data-media][srcset]'); | ||
lazySizes.getCustomMedias(); | ||
for(i = 0, len = elems.length; i < len; i++){ | ||
if( (customMedia = lazySizes.cfg.customMedia[elems[i].getAttribute('data-media') || elems[i].getAttribute('media')]) ){ | ||
elems[i].setAttribute('media', customMedia); | ||
} | ||
} | ||
lazySizes.autoSizer.checkElems(); | ||
//elems = docElem.querySelector('source[media][data-media][srcset] ~ img'); | ||
//for(i = 0, len = elems.length; i < len; i++){ | ||
// | ||
//} | ||
}; | ||
lazySizes.getCustomMedias(); | ||
docElem.removeEventListener('lazybeforeunveil', create); | ||
@@ -43,0 +64,0 @@ }; |
@@ -1,3 +0,3 @@ | ||
/*! lazysizes - v0.9.0 - 2015-02-02 | ||
/*! lazysizes - v1.0.0-RC3 - 2015-02-25 | ||
Licensed MIT */ | ||
!function(a){"use strict";var b=document.documentElement,c=function(){a.lazySizes&&!lazySizes.getCustomMedias&&(lazySizes.getCustomMedias=function(){var a=/['"]/g,b=/\s*\|\s*/g,c=/^([a-z0-9_-]+)\s*:\s*(.+)$/i,d=function(b,c){return(getComputedStyle(b,c).getPropertyValue("content")||"none").replace(a,"").trim()},e=function(a,d){a.split(b).forEach(function(a){a.match(c)&&(d[RegExp.$1]=RegExp.$2)})};return function(a,b){return a=a||{},b=b||document.querySelector("html"),e(d(b,":before"),a),e(d(b,":after"),a),a}}(),lazySizes.getCustomMedias(lazySizes.cfg.customMedia),b.removeEventListener("lazybeforeunveil",c))};a.addEventListener&&b.addEventListener("lazybeforeunveil",c),c(),setTimeout(c)}(window); | ||
!function(a){"use strict";var b=document.documentElement,c=function(){if(a.lazySizes&&!a.lazySizes.getCustomMedias){var d=a.lazySizes;d.getCustomMedias=function(){var a=/['"]/g,b=/\s*\|\s*/g,c=/^([a-z0-9_-]+)\s*:\s*(.+)$/i,e=function(b,c){return(getComputedStyle(b,c).getPropertyValue("content")||"none").replace(a,"").trim()},f=function(a,d){a.split(b).forEach(function(a){a.match(c)&&(d[RegExp.$1]=RegExp.$2)})};return function(a,b){return a=a||d.cfg.customMedia,b=b||document.querySelector("html"),f(e(b,":before"),a),f(e(b,":after"),a),a}}(),d.reassignCustomMedia=function(){var a,c,e,f=b.querySelectorAll("source[media][data-media][srcset]");for(d.getCustomMedias(),a=0,c=f.length;c>a;a++)(e=d.cfg.customMedia[f[a].getAttribute("data-media")||f[a].getAttribute("media")])&&f[a].setAttribute("media",e);d.autoSizer.checkElems()},d.getCustomMedias(),b.removeEventListener("lazybeforeunveil",c)}};a.addEventListener&&b.addEventListener("lazybeforeunveil",c),c(),setTimeout(c)}(window); |
@@ -47,2 +47,32 @@ #lazysizes custommedia extension | ||
```scss | ||
/* | ||
Simple Sass mixin to share a map of breakpoints between CSS and JS | ||
Usage: | ||
$breakpoints: ( | ||
--small: (max-width: 480px), | ||
--medium: (max-width: 1024px), | ||
--large: (min-width: 1280px) | ||
); | ||
html:after { | ||
@include shareBreakpoints($breakpoints); | ||
} | ||
*/ | ||
@mixin shareBreakpoints($map , $cssprop: content){ | ||
$description: ''; | ||
@each $property, $value in $map | ||
{ | ||
@if $description != '' { | ||
$description: $description + ' | '; | ||
} | ||
$description: $description + $property +': '+ inspect($value); | ||
} | ||
display: none; | ||
#{$cssprop}: $description; | ||
} | ||
``` | ||
@@ -152,3 +152,3 @@ /* | ||
output = { | ||
condition: config.include.conditions[RegExp.$3] || RegExp.$2 || null, | ||
condition: config.include.conditions[RegExp.$3] || config.customMedia[RegExp.$3] || RegExp.$2 || null, | ||
name: RegExp.$3 | ||
@@ -155,0 +155,0 @@ }; |
@@ -1,3 +0,3 @@ | ||
/*! lazysizes - v0.9.0 - 2015-02-02 | ||
/*! lazysizes - v1.0.0-RC3 - 2015-02-25 | ||
Licensed MIT */ | ||
!function(a,b){"use strict";function c(a){a.match(z)?this.urls[RegExp.$1]=t.map[RegExp.$2]||RegExp.$2:this.urls.include=t.map[a]||a}function d(a){var b,d,e;return a=a.trim(),a=t.map[a]||a,d=a.match(A),d?(e=RegExp.$1,b={condition:s.include.conditions[RegExp.$3]||RegExp.$2||null,name:RegExp.$3}):(e=a,b={condition:null,name:""}),b.urls={},(t.map[e]||e).split(y).forEach(c,b),!b.urls.include&&b.urls.amd&&(this.saved=!0,b.initial=this),b}function e(a){var b,c,e=a.getAttribute("data-include")||"",f=a.lazyInclude;return f&&f.str==e||(c={saved:!1,content:null},f={str:e,candidates:(t.map[e]||e).split(w).map(d,c)},!(b=f.candidates.length)||f.candidates[b-1].condition?(c.saved=!0,f.candidates.push({urls:{},condition:null,name:"initial",content:c})):c.saved&&1==f.candidates.length&&(c.saved=!1),f.initialContent=c,c.saved&&(c.content=a.innerHTML),a.lazyInclude=f,f.candidates.length>1?lazySizes.aC(a,"lazyconditionalinclude"):lazySizes.rC(a,"lazyconditionalinclude")),f}function f(b,c){var d=!c.condition;return c.condition&&(g(),v[c.name]?d=!0:a.matchMedia&&"string"==typeof c.condition?d=(matchMedia(c.condition)||{}).matches:"function"==typeof c.condition&&(d=c.condition(b,c))),d}function g(){var a;v||(u||(u=b.querySelector(t.contentElement)),u?(a=(getComputedStyle(u,":after").getPropertyValue("content")||"none").replace(B,""),v={},a&&(v[a]=1),a=(getComputedStyle(u,":before").getPropertyValue("content")||"none").replace(B,""),a&&(v[a]=1)):v={})}function h(a){var b,c,d=a.lazyInclude;if(d&&d.candidates)for(b=0;b<d.candidates.length&&(c=d.candidates[b],!f(a,c));b++);return c&&c!=d.current||(c=null),c}function i(a,b){var c=new XMLHttpRequest;c.addEventListener("readystatechange",function(){var a=this.DONE||4;this.readyState===a&&(b(c),c=null)},!1),c.open.apply(c,a.openArgs),c.setRequestHeader("X-Requested-With","XMLHttpRequest"),a.xhrModifier&&a.xhrModifier(c,elem,candidate),c.send(a.sendData)}function j(a,b){a=a.split("|,|"),require(a,function(){b(Array.prototype.slice.call(arguments))})}function k(a){if(!x[a]){var c=b.createElement("link"),d=b.getElementsByTagName("script")[0];c.rel="stylesheet",c.href=a,d.parentNode.insertBefore(c,d),x[a]=!0,x[c.href]=!0}}function l(a){a=a.split("|,|"),a.forEach(k)}function m(a){a&&"function"==typeof a.lazytransform&&a.lazytransform(this)}function n(a){a&&"function"==typeof a.lazyunload&&a.lazyunload(this)}function o(a){a&&"function"==typeof a.lazyload&&a.lazyload(this)}function p(b,c){var d,e,f,g=b.lazyInclude.current||null,h={candidate:c,openArgs:["GET",c.urls.include,!0],sendData:null,xhrModifier:null,content:c.content&&c.content.content||c.content,oldCandidate:g},k=lazySizes.fire(b,"lazyincludeload",h);return k.defaultPrevented?void E.d():(d=function(){var d,h=e.status,i=e.content||e.responseText,j=!(null!=i||!g||!g.urls.include),k={candidate:c,content:i,text:e.responseText||e.content,response:e.response,xml:e.responseXML,isSuccess:"status"in e?h>=200&&300>h||304===h:!0,oldCandidate:g,insert:!0,resetHTML:j},l={target:b,details:k};c.modules=f,g&&g.modules&&(g.modules.forEach(n,l),g.modules=null,k.resetHTML&&null==k.content&&c.initial&&c.initial.saved&&(k.content=c.initial.content)),f.forEach(m,l),d=lazySizes.fire(b,"lazyincludeloaded",k),k.insert&&k.isSuccess&&!d.defaultPrevented&&null!=k.content&&k.content!=b.innerHTML&&(a.jQuery?jQuery(b).html(k.content):b.innerHTML=k.content),E.d(),f.forEach(o,l),setTimeout(function(){lazySizes.fire(b,"lazyincluded",k)}),e=null,f=null},b.lazyInclude.current=c,b.setAttribute("data-currentinclude",c.name),c.urls.css&&l(c.urls.css),null==h.content&&c.urls.include?i(h,function(a){e=a,f&&d()}):e=h,c.urls.amd?j(c.urls.amd,function(a){f=a,e&&d()}):f=[],void(e&&f&&d()))}function q(a){var b,c=e(a);return c.candidates.length&&C.contains(a)?(b=h(a),b&&p(a,b),!0):void 0}function r(a){!a.defaultPrevented&&a.target.getAttribute("data-include")&&(E.q(a.target),a.details.firesLoad=!0)}if(b.getElementsByClassName){var s,t,u,v,w=/\s*,+\s+/,x={},y=/\s+/,z=/^(amd|css)\:(.+)/i,A=/(.+)\s+(\(\s*(.+)\s*\))/,B=/['"]/g,C=b.documentElement,D=b.getElementsByClassName("lazyconditionalinclude"),E=function(){var a=2,b=3,c=a,d=0,e=0,f=[],g=function(){var a,b=function(){f.length&&(d=0,f.d())};return function(){clearTimeout(a),a=setTimeout(b,999)}}();return{q:function(a){var h=null==a.getAttribute("data-lazyqueue");h&&(e++,c=b),d>c?f[h?"unshift":"push"](a):q(a)&&(d++,g())},d:function(){if(d&&d--,e>0&&(e--,e||(c=a)),!(d>c)){for(;f.length;)if(q(f.shift())){d++;break}g()}}}}(),F=function(){var a,b=function(){for(var a=0,b=D.length;b>a;a++)!lazySizes.hC(D[a],s.lazyClass)&&h(D[a])&&lazySizes.aC(D[a],s.lazyClass)};return function(c){clearTimeout(a),v=null,a=setTimeout(b,"resize"==c.type?31:0)}}();s=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig,s||(s={},a.lazySizesConfig=s),s.include||(s.include={}),t=s.include,t.contentElement||(t.contentElement="html"),t.conditions||(t.conditions={}),t.map||(t.map={}),"preloadAfterLoad"in s||(s.preloadAfterLoad=!0),addEventListener("lazybeforeunveil",r,!1),addEventListener("resize",F,!1),addEventListener("lazyrefreshincludes",F,!1)}}(window,document); | ||
!function(a,b){"use strict";function c(a){a.match(z)?this.urls[RegExp.$1]=t.map[RegExp.$2]||RegExp.$2:this.urls.include=t.map[a]||a}function d(a){var b,d,e;return a=a.trim(),a=t.map[a]||a,d=a.match(A),d?(e=RegExp.$1,b={condition:s.include.conditions[RegExp.$3]||s.customMedia[RegExp.$3]||RegExp.$2||null,name:RegExp.$3}):(e=a,b={condition:null,name:""}),b.urls={},(t.map[e]||e).split(y).forEach(c,b),!b.urls.include&&b.urls.amd&&(this.saved=!0,b.initial=this),b}function e(a){var b,c,e=a.getAttribute("data-include")||"",f=a.lazyInclude;return f&&f.str==e||(c={saved:!1,content:null},f={str:e,candidates:(t.map[e]||e).split(w).map(d,c)},!(b=f.candidates.length)||f.candidates[b-1].condition?(c.saved=!0,f.candidates.push({urls:{},condition:null,name:"initial",content:c})):c.saved&&1==f.candidates.length&&(c.saved=!1),f.initialContent=c,c.saved&&(c.content=a.innerHTML),a.lazyInclude=f,f.candidates.length>1?lazySizes.aC(a,"lazyconditionalinclude"):lazySizes.rC(a,"lazyconditionalinclude")),f}function f(b,c){var d=!c.condition;return c.condition&&(g(),v[c.name]?d=!0:a.matchMedia&&"string"==typeof c.condition?d=(matchMedia(c.condition)||{}).matches:"function"==typeof c.condition&&(d=c.condition(b,c))),d}function g(){var a;v||(u||(u=b.querySelector(t.contentElement)),u?(a=(getComputedStyle(u,":after").getPropertyValue("content")||"none").replace(B,""),v={},a&&(v[a]=1),a=(getComputedStyle(u,":before").getPropertyValue("content")||"none").replace(B,""),a&&(v[a]=1)):v={})}function h(a){var b,c,d=a.lazyInclude;if(d&&d.candidates)for(b=0;b<d.candidates.length&&(c=d.candidates[b],!f(a,c));b++);return c&&c!=d.current||(c=null),c}function i(a,b){var c=new XMLHttpRequest;c.addEventListener("readystatechange",function(){var a=this.DONE||4;this.readyState===a&&(b(c),c=null)},!1),c.open.apply(c,a.openArgs),c.setRequestHeader("X-Requested-With","XMLHttpRequest"),a.xhrModifier&&a.xhrModifier(c,elem,candidate),c.send(a.sendData)}function j(a,b){a=a.split("|,|"),require(a,function(){b(Array.prototype.slice.call(arguments))})}function k(a){if(!x[a]){var c=b.createElement("link"),d=b.getElementsByTagName("script")[0];c.rel="stylesheet",c.href=a,d.parentNode.insertBefore(c,d),x[a]=!0,x[c.href]=!0}}function l(a){a=a.split("|,|"),a.forEach(k)}function m(a){a&&"function"==typeof a.lazytransform&&a.lazytransform(this)}function n(a){a&&"function"==typeof a.lazyunload&&a.lazyunload(this)}function o(a){a&&"function"==typeof a.lazyload&&a.lazyload(this)}function p(b,c){var d,e,f,g=b.lazyInclude.current||null,h={candidate:c,openArgs:["GET",c.urls.include,!0],sendData:null,xhrModifier:null,content:c.content&&c.content.content||c.content,oldCandidate:g},k=lazySizes.fire(b,"lazyincludeload",h);return k.defaultPrevented?void E.d():(d=function(){var d,h=e.status,i=e.content||e.responseText,j=!(null!=i||!g||!g.urls.include),k={candidate:c,content:i,text:e.responseText||e.content,response:e.response,xml:e.responseXML,isSuccess:"status"in e?h>=200&&300>h||304===h:!0,oldCandidate:g,insert:!0,resetHTML:j},l={target:b,details:k};c.modules=f,g&&g.modules&&(g.modules.forEach(n,l),g.modules=null,k.resetHTML&&null==k.content&&c.initial&&c.initial.saved&&(k.content=c.initial.content)),f.forEach(m,l),d=lazySizes.fire(b,"lazyincludeloaded",k),k.insert&&k.isSuccess&&!d.defaultPrevented&&null!=k.content&&k.content!=b.innerHTML&&(a.jQuery?jQuery(b).html(k.content):b.innerHTML=k.content),E.d(),f.forEach(o,l),setTimeout(function(){lazySizes.fire(b,"lazyincluded",k)}),e=null,f=null},b.lazyInclude.current=c,b.setAttribute("data-currentinclude",c.name),c.urls.css&&l(c.urls.css),null==h.content&&c.urls.include?i(h,function(a){e=a,f&&d()}):e=h,c.urls.amd?j(c.urls.amd,function(a){f=a,e&&d()}):f=[],void(e&&f&&d()))}function q(a){var b,c=e(a);return c.candidates.length&&C.contains(a)?(b=h(a),b&&p(a,b),!0):void 0}function r(a){!a.defaultPrevented&&a.target.getAttribute("data-include")&&(E.q(a.target),a.details.firesLoad=!0)}if(b.getElementsByClassName){var s,t,u,v,w=/\s*,+\s+/,x={},y=/\s+/,z=/^(amd|css)\:(.+)/i,A=/(.+)\s+(\(\s*(.+)\s*\))/,B=/['"]/g,C=b.documentElement,D=b.getElementsByClassName("lazyconditionalinclude"),E=function(){var a=2,b=3,c=a,d=0,e=0,f=[],g=function(){var a,b=function(){f.length&&(d=0,f.d())};return function(){clearTimeout(a),a=setTimeout(b,999)}}();return{q:function(a){var h=null==a.getAttribute("data-lazyqueue");h&&(e++,c=b),d>c?f[h?"unshift":"push"](a):q(a)&&(d++,g())},d:function(){if(d&&d--,e>0&&(e--,e||(c=a)),!(d>c)){for(;f.length;)if(q(f.shift())){d++;break}g()}}}}(),F=function(){var a,b=function(){for(var a=0,b=D.length;b>a;a++)!lazySizes.hC(D[a],s.lazyClass)&&h(D[a])&&lazySizes.aC(D[a],s.lazyClass)};return function(c){clearTimeout(a),v=null,a=setTimeout(b,"resize"==c.type?31:0)}}();s=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig,s||(s={},a.lazySizesConfig=s),s.include||(s.include={}),t=s.include,t.contentElement||(t.contentElement="html"),t.conditions||(t.conditions={}),t.map||(t.map={}),"preloadAfterLoad"in s||(s.preloadAfterLoad=!0),addEventListener("lazybeforeunveil",r,!1),addEventListener("resize",F,!1),addEventListener("lazyrefreshincludes",F,!1)}}(window,document); |
@@ -21,3 +21,3 @@ /* | ||
'use strict'; | ||
var config, extentLazySizes, parseWsrcset; | ||
var config; | ||
@@ -27,3 +27,3 @@ var regPicture = /^picture$/i; | ||
parseWsrcset = (function(){ | ||
var parseWsrcset = (function(){ | ||
var candidates; | ||
@@ -50,117 +50,121 @@ var reg = /(([^,\s].[^\s]+)\s+(\d+)w)/g; | ||
config = (window.lazySizes && lazySizes.cfg) || window.lazySizesConfig; | ||
var parseImg = (function(){ | ||
if(!config){ | ||
config = {}; | ||
window.lazySizesConfig = config; | ||
} | ||
var ascendingSort = function ( a, b ) { | ||
return a.w - b.w; | ||
}; | ||
if(typeof config.getOptimumX != 'function'){ | ||
config.getOptimumX = function(/*element*/){ | ||
var dpr = window.devicePixelRatio || 1; | ||
if(dpr > 2.4){ | ||
dpr *= 0.63; // returns 1.9 for 3 | ||
} else if(dpr > 1.9){ | ||
dpr *= 0.8; // returns 1.6 for 2 | ||
} else if(dpr > 1.4){ | ||
dpr *= 0.9; // returns 1.35 for 1.5 | ||
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 Math.min(Math.round(dpr * 100) / 100, 2); | ||
return lazyData; | ||
}; | ||
} | ||
function ascendingSort( a, b ) { | ||
return a.w - b.w; | ||
} | ||
return function parseImg(elem, dataName){ | ||
var sources, i, len, parent; | ||
function parseSets(elem){ | ||
var lazyData = {srcset: elem.getAttribute(lazySizes.cfg.srcsetAttr) || ''}; | ||
var cands = parseWsrcset(lazyData.srcset); | ||
Object.defineProperty(elem, '_lazyOptimumx', { | ||
value: lazyData, | ||
writable: true | ||
}); | ||
lazyData.cands = cands; | ||
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; | ||
} | ||
} | ||
} | ||
lazyData.index = 0; | ||
lazyData.dirty = false; | ||
if(cands[0] && cands[0].w){ | ||
cands.sort( ascendingSort ); | ||
lazyData.cSrcset = [cands[0].c]; | ||
} else { | ||
lazyData.cSrcset = lazyData.srcset ? [lazyData.srcset] : []; | ||
lazyData.cands = []; | ||
} | ||
return elem[dataName]; | ||
}; | ||
})(); | ||
return lazyData; | ||
} | ||
var constraintFns = { | ||
_lazyOptimumx: (function(){ | ||
var takeHighRes = function (beforeCan, curCanWidth, width){ | ||
var low, high; | ||
if(!beforeCan || !beforeCan.w){ | ||
return true; | ||
} | ||
function parseImg(elem){ | ||
var sources, i, len; | ||
var parent = elem.parentNode || {}; | ||
var lazyData = parseSets(elem); | ||
lazyData.isImg = true; | ||
if(regPicture.test(parent.nodeName || '')){ | ||
lazyData.picture = true; | ||
sources = parent.getElementsByTagName('source'); | ||
for(i = 0, len = sources.length; i < len; i++){ | ||
parseSets(sources[i]).isImg = false; | ||
} | ||
} | ||
if(beforeCan.w > width){return false;} | ||
return lazyData; | ||
} | ||
low = 1 - (beforeCan.w / width); | ||
high = (curCanWidth / width) - 1; | ||
function takeHighRes(beforeCan, curCanWidth, width){ | ||
var low, high; | ||
if(!beforeCan || !beforeCan.w){ | ||
return true; | ||
} | ||
return high - low < 0; | ||
}; | ||
if(beforeCan.w > width){return false;} | ||
return function (data, width){ | ||
var i, can; | ||
low = 1 - (beforeCan.w / width); | ||
high = (curCanWidth / width) - 1; | ||
for(i = data.index + 1; i < data.cands.length; i++){ | ||
can = data.cands[i]; | ||
if(can.w <= width || takeHighRes(data.cands[i - 1], can.w, width)){ | ||
data.cSrcset.push(can.c); | ||
data.index = i; | ||
} else { | ||
break; | ||
} | ||
} | ||
}; | ||
})() | ||
}; | ||
return high - low < 0; | ||
} | ||
var constrainSets = (function(){ | ||
function getConstrainedSrcSet(data, width){ | ||
var i, can; | ||
var constrainSet = function(elem, width, attr, dataName){ | ||
var curIndex; | ||
var lazyData = elem[dataName]; | ||
for(i = data.index + 1; i < data.cands.length; i++){ | ||
can = data.cands[i]; | ||
if(can.w <= width || takeHighRes(data.cands[i - 1], can.w, width)){ | ||
data.cSrcset.push(can.c); | ||
data.index = i; | ||
} else { | ||
break; | ||
} | ||
} | ||
} | ||
if(!lazyData){return;} | ||
curIndex = lazyData.index; | ||
function constrainSrces(elem, width, attr){ | ||
var curIndex, srcset; | ||
var lazyData = elem._lazyOptimumx; | ||
constraintFns[dataName](lazyData, width); | ||
if(!lazyData){return;} | ||
curIndex = lazyData.index; | ||
if(!lazyData.dirty || curIndex != lazyData.index){ | ||
lazyData.cSrcset.join(', '); | ||
elem.setAttribute(attr, lazyData.cSrcset.join(', ')); | ||
lazyData.dirty = true; | ||
} | ||
}; | ||
getConstrainedSrcSet(lazyData, width); | ||
return function(image, width, attr, dataName){ | ||
var sources, parent, len, i; | ||
var lazyData = image[dataName]; | ||
if(!lazyData.dirty || curIndex != lazyData.index){ | ||
srcset = lazyData.cSrcset.join(', '); | ||
elem.setAttribute(attr, lazyData.cSrcset.join(', ')); | ||
lazyData.dirty = true; | ||
lazyData.width = width; | ||
if(lazyData.cSrcset.length >= lazyData.cands.length){ | ||
elem.removeAttribute('data-optimumx'); | ||
elem.removeAttribute('data-maxdpr'); | ||
if(lazyData.picture && (parent = image.parentNode)){ | ||
sources = parent.getElementsByTagName('source'); | ||
for(i = 0, len = sources.length; i < len; i++){ | ||
constrainSet(sources[i], width, attr, dataName); | ||
} | ||
} | ||
} | ||
return srcset; | ||
} | ||
function getOptimumX(element){ | ||
constrainSet(image, width, attr, dataName); | ||
}; | ||
})(); | ||
var getOptimumX = function(element){ | ||
var optimumx = element.getAttribute('data-optimumx') || element.getAttribute('data-maxdpr'); | ||
@@ -175,5 +179,5 @@ if(optimumx){ | ||
return optimumx; | ||
} | ||
}; | ||
extentLazySizes = function(){ | ||
var extentLazySizes = function(){ | ||
if(window.lazySizes && !window.lazySizes.getOptimumX){ | ||
@@ -189,12 +193,33 @@ lazySizes.getX = getOptimumX; | ||
config = (window.lazySizes && lazySizes.cfg) || window.lazySizesConfig; | ||
if(!config){ | ||
config = {}; | ||
window.lazySizesConfig = config; | ||
} | ||
if(typeof config.getOptimumX != 'function'){ | ||
config.getOptimumX = function(/*element*/){ | ||
var dpr = window.devicePixelRatio || 1; | ||
if(dpr > 2.4){ | ||
dpr *= 0.63; // returns 1.9 for 3 | ||
} else if(dpr > 1.9){ | ||
dpr *= 0.8; // returns 1.6 for 2 | ||
} else if(dpr > 1.4){ | ||
dpr *= 0.9; // returns 1.35 for 1.5 | ||
} | ||
return Math.min(Math.round(dpr * 100) / 100, 2); | ||
}; | ||
} | ||
if(!window.devicePixelRatio){return;} | ||
addEventListener('lazybeforesizes', function(e){ | ||
var optimumx, lazyData, width, attr, parent, sources, i, len; | ||
var optimumx, lazyData, width, attr; | ||
if(e.defaultPrevented || | ||
!(optimumx = getOptimumX(e.target)) || | ||
optimumx >= window.devicePixelRatio){return;} | ||
optimumx >= devicePixelRatio){return;} | ||
lazyData = e.target._lazyOptimumx || parseImg(e.target); | ||
lazyData = parseImg(e.target, '_lazyOptimumx'); | ||
@@ -206,12 +231,3 @@ width = e.details.width * optimumx; | ||
lazyData.width = width; | ||
if(lazyData.picture && (parent = e.target.parentNode)){ | ||
sources = parent.getElementsByTagName('source'); | ||
for(i = 0, len = sources.length; i < len; i++){ | ||
constrainSrces(sources[i], width, attr); | ||
} | ||
} | ||
e.details.srcset = constrainSrces(e.target, width, attr); | ||
constrainSets(e.target, width, attr, '_lazyOptimumx'); | ||
} | ||
@@ -218,0 +234,0 @@ }); |
@@ -1,3 +0,3 @@ | ||
/*! lazysizes - v0.9.0 - 2015-02-02 | ||
/*! lazysizes - v1.0.0-RC3 - 2015-02-25 | ||
Licensed MIT */ | ||
!function(a,b){"use strict";function c(a,b){return a.w-b.w}function d(a){var b={srcset:a.getAttribute(lazySizes.cfg.srcsetAttr)||""},d=l(b.srcset);return Object.defineProperty(a,"_lazyOptimumx",{value:b,writable:!0}),b.cands=d,b.index=0,b.dirty=!1,d[0]&&d[0].w?(d.sort(c),b.cSrcset=[d[0].c]):(b.cSrcset=b.srcset?[b.srcset]:[],b.cands=[]),b}function e(a){var b,c,e,f=a.parentNode||{},g=d(a);if(g.isImg=!0,m.test(f.nodeName||""))for(g.picture=!0,b=f.getElementsByTagName("source"),c=0,e=b.length;e>c;c++)d(b[c]).isImg=!1;return g}function f(a,b,c){var d,e;return a&&a.w?a.w>c?!1:(d=1-a.w/c,e=b/c-1,0>e-d):!0}function g(a,b){var c,d;for(c=a.index+1;c<a.cands.length&&(d=a.cands[c],d.w<=b||f(a.cands[c-1],d.w,b));c++)a.cSrcset.push(d.c),a.index=c}function h(a,b,c){var d,e,f=a._lazyOptimumx;return f?(d=f.index,g(f,b),f.dirty&&d==f.index||(e=f.cSrcset.join(", "),a.setAttribute(c,f.cSrcset.join(", ")),f.dirty=!0,f.cSrcset.length>=f.cands.length&&(a.removeAttribute("data-optimumx"),a.removeAttribute("data-maxdpr"))),e):void 0}function i(a){var b=a.getAttribute("data-optimumx")||a.getAttribute("data-maxdpr");return b&&(b="auto"==b?j.getOptimumX(a):parseFloat(b,10)),b}var j,k,l,m=/^picture$/i,n=b.documentElement;l=function(){var a,b=/(([^,\s].[^\s]+)\s+(\d+)w)/g,c=/\s+\d+h/g,d=function(b,c,d,e){a.push({c:c,u:d,w:1*e})};return function(e){return a=[],e.replace(c,"").replace(b,d),a}}(),j=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig,j||(j={},a.lazySizesConfig=j),"function"!=typeof j.getOptimumX&&(j.getOptimumX=function(){var b=a.devicePixelRatio||1;return b>2.4?b*=.63:b>1.9?b*=.8:b>1.4&&(b*=.9),Math.min(Math.round(100*b)/100,2)}),k=function(){a.lazySizes&&!a.lazySizes.getOptimumX&&(lazySizes.getX=i,lazySizes.pWS=l,n.removeEventListener("lazybeforeunveil",k))},n.addEventListener("lazybeforeunveil",k),setTimeout(k),a.devicePixelRatio&&(addEventListener("lazybeforesizes",function(b){var c,d,f,g,j,k,l,m;if(!(b.defaultPrevented||!(c=i(b.target))||c>=a.devicePixelRatio)&&(d=b.target._lazyOptimumx||e(b.target),f=b.details.width*c,f&&(d.width||0)<f)){if(g=b.details.dataAttr?lazySizes.cfg.srcsetAttr:"srcset",d.width=f,d.picture&&(j=b.target.parentNode))for(k=j.getElementsByTagName("source"),l=0,m=k.length;m>l;l++)h(k[l],f,g);b.details.srcset=h(b.target,f,g)}}),addEventListener("lazybeforeunveil",function(a){a.target._lazyOptimumx&&(a.target._lazyOptimumx=null)}))}(window,document); | ||
!function(a,b){"use strict";var c,d=/^picture$/i,e=b.documentElement,f=function(){var a,b=/(([^,\s].[^\s]+)\s+(\d+)w)/g,c=/\s+\d+h/g,d=function(b,c,d,e){a.push({c:c,u:d,w:1*e})};return function(e){return a=[],e.replace(c,"").replace(b,d),a}}(),g=function(){var a=function(a,b){return a.w-b.w},b=function(b,c){var d={srcset:b.getAttribute(lazySizes.cfg.srcsetAttr)||""},e=f(d.srcset);return Object.defineProperty(b,c,{value:d,writable:!0}),d.cands=e,d.index=0,d.dirty=!1,e[0]&&e[0].w?(e.sort(a),d.cSrcset=[e[d.index].c]):(d.cSrcset=d.srcset?[d.srcset]:[],d.cands=[]),d};return function(a,c){var e,f,g,h;if(!a[c]&&(h=a.parentNode||{},a[c]=b(a,c),a[c].isImg=!0,d.test(h.nodeName||"")))for(a[c].picture=!0,e=h.getElementsByTagName("source"),f=0,g=e.length;g>f;f++)b(e[f],c).isImg=!1;return a[c]}}(),h={_lazyOptimumx:function(){var a=function(a,b,c){var d,e;return a&&a.w?a.w>c?!1:(d=1-a.w/c,e=b/c-1,0>e-d):!0};return function(b,c){var d,e;for(d=b.index+1;d<b.cands.length&&(e=b.cands[d],e.w<=c||a(b.cands[d-1],e.w,c));d++)b.cSrcset.push(e.c),b.index=d}}()},i=function(){var a=function(a,b,c,d){var e,f=a[d];f&&(e=f.index,h[d](f,b),f.dirty&&e==f.index||(f.cSrcset.join(", "),a.setAttribute(c,f.cSrcset.join(", ")),f.dirty=!0))};return function(b,c,d,e){var f,g,h,i,j=b[e];if(j.width=c,j.picture&&(g=b.parentNode))for(f=g.getElementsByTagName("source"),i=0,h=f.length;h>i;i++)a(f[i],c,d,e);a(b,c,d,e)}}(),j=function(a){var b=a.getAttribute("data-optimumx")||a.getAttribute("data-maxdpr");return b&&(b="auto"==b?c.getOptimumX(a):parseFloat(b,10)),b},k=function(){a.lazySizes&&!a.lazySizes.getOptimumX&&(lazySizes.getX=j,lazySizes.pWS=f,e.removeEventListener("lazybeforeunveil",k))};e.addEventListener("lazybeforeunveil",k),setTimeout(k),c=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig,c||(c={},a.lazySizesConfig=c),"function"!=typeof c.getOptimumX&&(c.getOptimumX=function(){var b=a.devicePixelRatio||1;return b>2.4?b*=.63:b>1.9?b*=.8:b>1.4&&(b*=.9),Math.min(Math.round(100*b)/100,2)}),a.devicePixelRatio&&(addEventListener("lazybeforesizes",function(a){var b,c,d,e;a.defaultPrevented||!(b=j(a.target))||b>=devicePixelRatio||(c=g(a.target,"_lazyOptimumx"),d=a.details.width*b,d&&(c.width||0)<d&&(e=a.details.dataAttr?lazySizes.cfg.srcsetAttr:"srcset",i(a.target,d,e,"_lazyOptimumx")))}),addEventListener("lazybeforeunveil",function(a){a.target._lazyOptimumx&&(a.target._lazyOptimumx=null)}))}(window,document); |
@@ -50,3 +50,3 @@ #lazysizes optimumx plugin | ||
**Note**: For full cross-browser support either a [responsive images polyfill like respimage or picturefill](https://github.com/aFarkas/respimage) or the [neat Responsive Images as a Service extension (RIaS)](../rias) needs to be used. | ||
**Note**: For full cross-browser support either a [responsive images polyfill like respimage or picturefill](https://github.com/aFarkas/respimage) or the [neat Responsive Images as a Service extension (RIaS)](../rias) or the [extreme lightweight alternate mini respimg polyfill extension](../respimg) needs to be used. | ||
@@ -121,3 +121,3 @@ ```html | ||
##Background information | ||
##<a name="compressive-picture-pattern"></a>Background information: Compressive picture pattern | ||
@@ -163,3 +163,3 @@ From a perceived performance vs. perceived quality standpoint the best way to deal with High DPI images is to serve higher compressed candidates to clients with high resolution displays. | ||
data.details.quality = (window.devicePixelRatio || 1) > 1.4 ? 60 : 80; | ||
}; | ||
}); | ||
</script> | ||
@@ -177,1 +177,49 @@ | ||
But be aware each image has different characteristics: While some images look great on a HIGH DPI device even with a ``data-optimumx="1.2"`` other will need a much higher density for a good perceived quality. | ||
##<a name="lying-sizes"></a>Background information: Lying sizes attribute | ||
There is also another much more lightweight way to get a similar effect. Instead of parsing and constraining the ``srcset`` to meet the ``data-optimumx`` constraint, there is also the possibility to modify the ``sizes`` attribute instead. | ||
A ``data-optimumx`` implementation with the ``lazybeforesizes`` event could then look something like this: | ||
```html | ||
<script> | ||
document.addEventListener('lazybeforesizes', function(e){ | ||
var maxx = parseFloat(e.target.getAttribute('data-optimumx') || '', 10); | ||
var dpr = (window.devicePixelRatio || 1); | ||
if(maxx && maxx < (window.devicePixelRatio || 1)){ | ||
e.details.width = e.details.width * (maxx / dpr); | ||
} | ||
}); | ||
</script> | ||
<img class="lazyload" data-sizes="auto" data-optimumx="1.5" data-srcset="..." /> | ||
``` | ||
Compared to the size of this plugin this is a very neat, simple and lightweight technique. | ||
But this technique should be used with caution because the browsers algorithm is tricked and operates with wrong values, which can result in unpredictable and bad results. | ||
In case the ``sizes`` attribute is faked to a lower value and the browser already wants to select a lower candidate, (because the device has a low or metered bandwidth) the browser might choose an unfeasible image candidate instead. | ||
In case the ``sizes`` attribute is faked to a higher value and the browser already wants to select a higher candidate, (because the user has zoomed into this particular image) the browser might be tricked to download a much heavier image candidate than the device actually needs. | ||
But this technique can be used to tell the browser some small lies. Normally the browser runs a simple get the nearest candidate algorithm. This can in some cases cause a poor quality on 1x devices. In case our lie is small and limited we can workaround this problem without causing unpredictable consequences: | ||
```html | ||
<script> | ||
//make the image sizes only 5% larger, if seen on a low DPI device | ||
document.addEventListener('lazybeforesizes', function(e){ | ||
var dpr = (window.devicePixelRatio || 1); | ||
if(dpr < 1.1){ | ||
e.details.width = e.details.width * 1.05; | ||
} | ||
}); | ||
</script> | ||
<img class="lazyload" | ||
data-sizes="auto" | ||
data-srcset="image-480.jpg 480w, image-768.jpg" | ||
style="width: 600px;" | ||
/> | ||
``` |
@@ -21,3 +21,3 @@ /* | ||
for(i = 0, len = elements.length; i < len; i++){ | ||
lazySizes.unveilLazy(elements[i]); | ||
lazySizes.loader.unveil(elements[i]); | ||
} | ||
@@ -24,0 +24,0 @@ } |
@@ -1,3 +0,3 @@ | ||
/*! lazysizes - v0.9.0 - 2015-02-02 | ||
/*! lazysizes - v1.0.0-RC3 - 2015-02-25 | ||
Licensed MIT */ | ||
!function(a){"use strict";var b,c,d,e;a.addEventListener&&(b=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig||{},c=b.lazyClass||"lazyload",d=function(){var b,d;if("string"==typeof c&&(c=document.getElementsByClassName(c)),a.lazySizes)for(b=0,d=c.length;d>b;b++)lazySizes.unveilLazy(c[b])},addEventListener("beforeprint",d,!1),!("onbeforeprint"in a)&&a.matchMedia&&(e=matchMedia("print"))&&e.addListener&&e.addListener(function(){e.matches&&d()}))}(window); | ||
!function(a){"use strict";var b,c,d,e;a.addEventListener&&(b=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig||{},c=b.lazyClass||"lazyload",d=function(){var b,d;if("string"==typeof c&&(c=document.getElementsByClassName(c)),a.lazySizes)for(b=0,d=c.length;d>b;b++)lazySizes.loader.unveil(c[b])},addEventListener("beforeprint",d,!1),!("onbeforeprint"in a)&&a.matchMedia&&(e=matchMedia("print"))&&e.addListener&&e.addListener(function(){e.matches&&d()}))}(window); |
@@ -36,2 +36,8 @@ (function(window, document, undefined){ | ||
if(!config.supportsType){ | ||
config.supportsType = function(type/*, elem*/){ | ||
return !type; | ||
}; | ||
} | ||
if(!config.rias){ | ||
@@ -217,5 +223,20 @@ config.rias = {}; | ||
var getX = function(elem){ | ||
var dpr = window.devicePixelRatio || 1; | ||
var optimum = lazySizes.getX && lazySizes.getX(elem); | ||
var x = Math.min(optimum || dpr, 2.2, dpr); | ||
if(x < 1.2){ | ||
x *= 1.05; | ||
} else if(x > 1.6 && !optimum){ | ||
x *= 0.95; | ||
} | ||
return x; | ||
}; | ||
var getCandidate = function(elem, width){ | ||
var sources, i, len, media, srces; | ||
width *= Math.min((lazySizes.getX && lazySizes.getX(elem)) || window.devicePixelRatio || 1, 2); | ||
width = Math.round(width * getX(elem)); | ||
srces = elem._lazyrias; | ||
@@ -242,3 +263,3 @@ | ||
if(window.HTMLPictureElement || window.respimage || window.picturefill){ | ||
if(window.HTMLPictureElement || window.respimage || window.picturefill || lazySizesConfig.polyfill){ | ||
document.removeEventListener('lazybeforesizes', polyfill); | ||
@@ -245,0 +266,0 @@ return; |
@@ -1,3 +0,3 @@ | ||
/*! lazysizes - v0.9.0 - 2015-02-02 | ||
/*! lazysizes - v1.0.0-RC3 - 2015-02-25 | ||
Licensed MIT */ | ||
!function(a,b){"use strict";function c(a,b){var c,d,e,f;d=a.parentNode,f={isPicture:!(!d||!l.test(d.nodeName||""))},e=function(b,c){var d=a.getAttribute("data-"+b);if(null!=d){if("true"==d)d=!0;else if("false"==d)d=!1;else if(k.test(d))d=parseFloat(d);else if("function"==typeof i[b])d=i[b](a,d);else if(o.test(d))try{d=JSON.parse(d)}catch(e){}f[b]=d}else b in i&&"function"!=typeof i[b]?f[b]=i[b]:c&&"function"==typeof i[b]&&(f[b]=i[b](a,d))};for(c in i)e(c);return b.replace(n,function(a,b){b in f||e(b,!0)}),f}function d(a,b){var c=[],d=function(a,c){return j[typeof b[c]]?b[c]:a};return c.srcset=[],b.absUrl&&(q.setAttribute("href",a),a=q.href),a=((b.prefix||"")+a+(b.postfix||"")).replace(n,d),b.widths.forEach(function(d){var e={u:a.replace(m,b.widthmap[d]||d),w:d};c.push(e),c.srcset.push(e.c=e.u+" "+d+"w")}),c}function e(a,b,c){a&&(a=d(a,b),a.isPicture=b.isPicture,c.setAttribute(h.srcsetAttr,a.srcset.join(", ")),Object.defineProperty(c,"_lazyrias",{value:a,writable:!0}))}function f(a,b){var d=c(a,b);return i.modifyOptions.call(a,{target:a,details:d}),lazySizes.fire(a,"lazyriasmodifyoptions",d),d}function g(a){return a.getAttribute(a.getAttribute("data-srcattr")||i.srcAttr)||a.getAttribute(h.srcsetAttr)||a.getAttribute(h.srcAttr)||""}if(b.addEventListener){var h,i,j={string:1,number:1},k=/^\-*\+*\d+\.*\d*$/,l=/^picture$/i,m=/\s*\{\s*width\s*\}\s*/i,n=/\s*\{\s*([a-z0-9]+)\s*\}\s*/gi,o=/^\[.*\]|\{.*\}$/,p=/^(?:auto|\d+(px)?)$/,q=b.createElement("a");!function(){var b,c=function(){},d={prefix:"",postfix:"",srcAttr:"data-src",absUrl:!1,modifyOptions:c,widthmap:{}};h=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig,h||(h={},a.lazySizesConfig=h),h.rias||(h.rias={}),i=h.rias,"widths"in i||(i.widths=[],function(a){var b,c=0;for(a.push(96);!b||2800>b;)c+=10,c>60&&(c+=10),b=16*c,a.push(b)}(i.widths));for(b in d)b in i||(i[b]=d[b])}(),addEventListener("lazybeforeunveil",function(a){var b,c,d,j,k,l,n,o,q;if(b=a.target,!a.defaultPrevented&&(c=g(b))&&!i.disabled&&(q=b.getAttribute(h.sizesAttr)||b.getAttribute("sizes"))&&p.test(q)){if(d=f(b,c),m.test(c)||m.test(d.prefix)||m.test(d.postfix)){if(d.isPicture&&(j=b.parentNode))for(k=j.getElementsByTagName("source"),l=0,n=k.length;n>l;l++)o=g(k[l]),e(o,d,k[l]);e(c,d,b)}"auto"!=q&&r({target:b,details:{width:parseInt(q,10)}})}});var r=function(){var c=function(a,b,c,d){return Math.abs(b.w-d.w)<Math.abs(a.w-d.w)?b:a},d=function(a,b){var c;return!a._lazyrias&&lazySizes.pWS&&(c=lazySizes.pWS(a.getAttribute(h.srcsetAttr||""))).length&&(Object.defineProperty(a,"_lazyrias",{value:c,writable:!0}),b&&a.parentNode&&(c.isPicture="PICTURE"==a.parentNode.nodeName.toUpperCase())),a._lazyrias},e=function(b,e){var f,g,h,i,j;if(e*=Math.min(lazySizes.getX&&lazySizes.getX(b)||a.devicePixelRatio||1,2),j=b._lazyrias,j.isPicture&&a.matchMedia)for(g=0,f=b.parentNode.getElementsByTagName("source"),h=f.length;h>g;g++)if(d(f[g])&&!f[g].getAttribute("type")&&(!(i=f[g].getAttribute("media"))||(matchMedia(i)||{}).matches)){j=f[g]._lazyrias;break}return(!j.w||j.w<e)&&(j.w=e),j.reduce(c)},f=function(c){var g,i=c.target;return a.HTMLPictureElement||a.respimage||a.picturefill?void b.removeEventListener("lazybeforesizes",f):void((i._lazyrias||c.details.dataAttr&&d(i,!0))&&(g=e(i,c.details.width),g&&g.u&&i._lazyrias.cur!=g.u&&(i._lazyrias.cur=g.u,i.setAttribute(h.srcAttr,g.u),i.setAttribute("src",g.u))))};return b.addEventListener("lazybeforesizes",f),f}()}}(window,document); | ||
!function(a,b){"use strict";function c(a,b){var c,d,e,f;d=a.parentNode,f={isPicture:!(!d||!l.test(d.nodeName||""))},e=function(b,c){var d=a.getAttribute("data-"+b);if(null!=d){if("true"==d)d=!0;else if("false"==d)d=!1;else if(k.test(d))d=parseFloat(d);else if("function"==typeof i[b])d=i[b](a,d);else if(o.test(d))try{d=JSON.parse(d)}catch(e){}f[b]=d}else b in i&&"function"!=typeof i[b]?f[b]=i[b]:c&&"function"==typeof i[b]&&(f[b]=i[b](a,d))};for(c in i)e(c);return b.replace(n,function(a,b){b in f||e(b,!0)}),f}function d(a,b){var c=[],d=function(a,c){return j[typeof b[c]]?b[c]:a};return c.srcset=[],b.absUrl&&(q.setAttribute("href",a),a=q.href),a=((b.prefix||"")+a+(b.postfix||"")).replace(n,d),b.widths.forEach(function(d){var e={u:a.replace(m,b.widthmap[d]||d),w:d};c.push(e),c.srcset.push(e.c=e.u+" "+d+"w")}),c}function e(a,b,c){a&&(a=d(a,b),a.isPicture=b.isPicture,c.setAttribute(h.srcsetAttr,a.srcset.join(", ")),Object.defineProperty(c,"_lazyrias",{value:a,writable:!0}))}function f(a,b){var d=c(a,b);return i.modifyOptions.call(a,{target:a,details:d}),lazySizes.fire(a,"lazyriasmodifyoptions",d),d}function g(a){return a.getAttribute(a.getAttribute("data-srcattr")||i.srcAttr)||a.getAttribute(h.srcsetAttr)||a.getAttribute(h.srcAttr)||""}if(b.addEventListener){var h,i,j={string:1,number:1},k=/^\-*\+*\d+\.*\d*$/,l=/^picture$/i,m=/\s*\{\s*width\s*\}\s*/i,n=/\s*\{\s*([a-z0-9]+)\s*\}\s*/gi,o=/^\[.*\]|\{.*\}$/,p=/^(?:auto|\d+(px)?)$/,q=b.createElement("a");!function(){var b,c=function(){},d={prefix:"",postfix:"",srcAttr:"data-src",absUrl:!1,modifyOptions:c,widthmap:{}};h=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig,h||(h={},a.lazySizesConfig=h),h.supportsType||(h.supportsType=function(a){return!a}),h.rias||(h.rias={}),i=h.rias,"widths"in i||(i.widths=[],function(a){var b,c=0;for(a.push(96);!b||2800>b;)c+=10,c>60&&(c+=10),b=16*c,a.push(b)}(i.widths));for(b in d)b in i||(i[b]=d[b])}(),addEventListener("lazybeforeunveil",function(a){var b,c,d,j,k,l,n,o,q;if(b=a.target,!a.defaultPrevented&&(c=g(b))&&!i.disabled&&(q=b.getAttribute(h.sizesAttr)||b.getAttribute("sizes"))&&p.test(q)){if(d=f(b,c),m.test(c)||m.test(d.prefix)||m.test(d.postfix)){if(d.isPicture&&(j=b.parentNode))for(k=j.getElementsByTagName("source"),l=0,n=k.length;n>l;l++)o=g(k[l]),e(o,d,k[l]);e(c,d,b)}"auto"!=q&&r({target:b,details:{width:parseInt(q,10)}})}});var r=function(){var c=function(a,b,c,d){return Math.abs(b.w-d.w)<Math.abs(a.w-d.w)?b:a},d=function(a,b){var c;return!a._lazyrias&&lazySizes.pWS&&(c=lazySizes.pWS(a.getAttribute(h.srcsetAttr||""))).length&&(Object.defineProperty(a,"_lazyrias",{value:c,writable:!0}),b&&a.parentNode&&(c.isPicture="PICTURE"==a.parentNode.nodeName.toUpperCase())),a._lazyrias},e=function(b){var c=a.devicePixelRatio||1,d=lazySizes.getX&&lazySizes.getX(b),e=Math.min(d||c,2.2,c);return 1.2>e?e*=1.05:e>1.6&&!d&&(e*=.95),e},f=function(b,f){var g,h,i,j,k;if(f=Math.round(f*e(b)),k=b._lazyrias,k.isPicture&&a.matchMedia)for(h=0,g=b.parentNode.getElementsByTagName("source"),i=g.length;i>h;h++)if(d(g[h])&&!g[h].getAttribute("type")&&(!(j=g[h].getAttribute("media"))||(matchMedia(j)||{}).matches)){k=g[h]._lazyrias;break}return(!k.w||k.w<f)&&(k.w=f),k.reduce(c)},g=function(c){var e,i=c.target;return a.HTMLPictureElement||a.respimage||a.picturefill||lazySizesConfig.polyfill?void b.removeEventListener("lazybeforesizes",g):void((i._lazyrias||c.details.dataAttr&&d(i,!0))&&(e=f(i,c.details.width),e&&e.u&&i._lazyrias.cur!=e.u&&(i._lazyrias.cur=e.u,i.setAttribute(h.srcAttr,e.u),i.setAttribute("src",e.u))))};return b.addEventListener("lazybeforesizes",g),g}()}}(window,document); |
@@ -73,3 +73,3 @@ #lazySizes RIaS extension (Responsive image as a service / Responsive image on demand) | ||
event.details.quality = (window.devicePixelRatio || 1) > 1.4 ? 65 : 80; | ||
}; | ||
}); | ||
</script> | ||
@@ -76,0 +76,0 @@ <img |
@@ -7,5 +7,6 @@ /* | ||
'use strict'; | ||
var config; | ||
var config, index; | ||
if(window.addEventListener){ | ||
config = (window.lazySizes && lazySizes.cfg) || window.lazySizesConfig; | ||
index = 0; | ||
if(!config){ | ||
@@ -16,20 +17,38 @@ config = {}; | ||
if(window.lazySizes && lazySizes.init.i){return;} | ||
config.scroll = false; | ||
if(!config.expand){ | ||
config.expand = 250; | ||
} | ||
if(!('scrollLoadMode' in config)){ | ||
config.scrollLoadMode = 1; | ||
} | ||
addEventListener('scroll', (function(){ | ||
var afterScrollTimer, checkElem, checkTimer, top, left; | ||
var checkFn = function(){ | ||
var nTop = checkElem.scrollTop || checkElem.pageYOffset || 0; | ||
var nLeft = checkElem.scrollLeft || checkElem.pageXOffset || 0; | ||
var nTop = Math.abs(top - (checkElem.scrollTop || checkElem.pageYOffset || 0)); | ||
var nLeft = Math.abs(left - (checkElem.scrollLeft || checkElem.pageXOffset || 0)); | ||
checkElem = null; | ||
if(Math.abs(top - nTop) < 66 && Math.abs(left - nLeft) < 66){ | ||
update(); | ||
if(nTop < 400 && nLeft < 400){ | ||
if(lazySizes.loader.m < 2){ | ||
lazySizes.loader.m = 2; | ||
} | ||
if(nTop < 180 && nLeft < 180){ | ||
update(); | ||
} | ||
} | ||
}; | ||
var afterScroll = function(){ | ||
lazySizes.loader.m = 3; | ||
index = 0; | ||
update(); | ||
clearTimeout(afterScrollTimer); | ||
}; | ||
var update = function(){ | ||
if(window.lazySizes){ | ||
lazySizes.updateAllLazy(); | ||
} | ||
clearTimeout(afterScrollTimer); | ||
lazySizes.loader.checkElems(); | ||
clearTimeout(checkTimer); | ||
@@ -44,4 +63,13 @@ checkElem = null; | ||
clearTimeout(afterScrollTimer); | ||
afterScrollTimer = setTimeout(update, 44); | ||
afterScrollTimer = setTimeout(afterScroll, 99); | ||
lazySizes.loader.m = config.scrollLoadMode; | ||
if(index === 0){ | ||
lazySizes.loader.checkElems(); | ||
} else if(index > 40){ | ||
index = -1; | ||
} | ||
index++; | ||
if(!checkElem){ | ||
@@ -52,3 +80,3 @@ checkElem = elem; | ||
clearTimeout(checkTimer); | ||
checkTimer = setTimeout(checkFn, 99); | ||
checkTimer = setTimeout(checkFn, 150); | ||
} else if(elem != checkElem){ | ||
@@ -55,0 +83,0 @@ update(); |
@@ -1,3 +0,3 @@ | ||
/*! lazysizes - v0.9.0 - 2015-02-02 | ||
/*! lazysizes - v1.0.0-RC3 - 2015-02-25 | ||
Licensed MIT */ | ||
!function(a,b){"use strict";var c;a.addEventListener&&(c=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig,c||(c={},a.lazySizesConfig=c),c.scroll=!1,addEventListener("scroll",function(){var c,d,e,f,g,h=function(){var a=d.scrollTop||d.pageYOffset||0,b=d.scrollLeft||d.pageXOffset||0;d=null,Math.abs(f-a)<66&&Math.abs(g-b)<66&&i()},i=function(){a.lazySizes&&lazySizes.updateAllLazy(),clearTimeout(c),clearTimeout(e),d=null};return function(j){var k=j.target==b?a:j.target;clearTimeout(c),c=setTimeout(i,44),d?k!=d&&i():(d=k,f=d.scrollTop||d.pageYOffset||0,g=d.scrollLeft||d.pageXOffset||0,clearTimeout(e),e=setTimeout(h,99)),k=null}}(),!0))}(window,document); | ||
!function(a,b){"use strict";var c,d;if(a.addEventListener){if(c=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig,d=0,c||(c={},a.lazySizesConfig=c),a.lazySizes&&lazySizes.init.i)return;c.scroll=!1,c.expand||(c.expand=250),"scrollLoadMode"in c||(c.scrollLoadMode=1),addEventListener("scroll",function(){var e,f,g,h,i,j=function(){var a=Math.abs(h-(f.scrollTop||f.pageYOffset||0)),b=Math.abs(i-(f.scrollLeft||f.pageXOffset||0));f=null,400>a&&400>b&&(lazySizes.loader.m<2&&(lazySizes.loader.m=2),180>a&&180>b&&l())},k=function(){lazySizes.loader.m=3,d=0,l(),clearTimeout(e)},l=function(){lazySizes.loader.checkElems(),clearTimeout(g),f=null};return function(m){var n=m.target==b?a:m.target;clearTimeout(e),e=setTimeout(k,99),lazySizes.loader.m=c.scrollLoadMode,0===d?lazySizes.loader.checkElems():d>40&&(d=-1),d++,f?n!=f&&l():(f=n,h=f.scrollTop||f.pageYOffset||0,i=f.scrollLeft||f.pageXOffset||0,clearTimeout(g),g=setTimeout(j,150)),n=null}}(),!0)}}(window,document); |
#lazysizes scrollintent extension | ||
Normally lazysizes uses a throttled scroll event to check for ``.lazyload`` elements. In case a user scrolls fast from to to bottom of the page lazyload resources in the "not viewed" middle of the page might be loaded in that case. | ||
Normally lazySizes uses a throttled scroll event to check for ``.lazyload`` elements. The scrollintent plugin changes this behavior to only check for ``.lazyload`` resources if either the user scrolling is slow or the user has stopped scrolling. | ||
The scrollintent plugin changes the behavior to only check for ``.lazyload`` resources if either the user scrolling is slow or the user has stopped scrolling. | ||
It is recommended to set the ``expand`` option to a higher value to improve the user experience, if this extension is used. | ||
This extension solves mainly two problems: | ||
- While lazySizes functions already do work jank-free, decoding and painting images is a performance heavy task, which is mostly noticeable, while the user scrolls. | ||
- If the user scrolls fast from top to bottom, it is not useful to load the assets in the middle (In case this is an important issue to you, you can also set the ``scrollLoadMode`` option to ``0``) |
@@ -28,7 +28,6 @@ /* | ||
'use strict'; | ||
var config, bgLoad; | ||
var bgLoad; | ||
var uniqueUrls = {}; | ||
if(document.addEventListener && window.getComputedStyle){ | ||
config = (window.lazySizes && lazySizes.cfg) || window.lazySizesConfig || {}; | ||
@@ -86,3 +85,3 @@ bgLoad = function (url, cb){ | ||
e.details.firesLoad = false; | ||
lazySizes.fire(e.target, '_lazyloaded'); | ||
lazySizes.fire(e.target, '_lazyloaded', {}, true, true); | ||
}; | ||
@@ -100,3 +99,3 @@ | ||
e.details.firesLoad = false; | ||
lazySizes.fire(e.target, '_lazyloaded'); | ||
lazySizes.fire(e.target, '_lazyloaded', {}, true, true); | ||
}; | ||
@@ -103,0 +102,0 @@ |
@@ -1,3 +0,3 @@ | ||
/*! lazysizes - v0.9.0 - 2015-02-02 | ||
/*! lazysizes - v1.0.0-RC3 - 2015-02-25 | ||
Licensed MIT */ | ||
!function(a,b){"use strict";function c(a,c){if(!f[a]){var d=b.createElement(c?"link":"script"),e=b.getElementsByTagName("script")[0];c?(d.rel="stylesheet",d.href=a):d.src=a,f[a]=!0,f[d.src||d.href]=!0,e.parentNode.insertBefore(d,e)}}var d,e,f={};b.addEventListener&&a.getComputedStyle&&(d=a.lazySizes&&lazySizes.cfg||a.lazySizesConfig||{},e=function(a,c){var d=b.createElement("img");d.onload=function(){d.onload=null,d.onerror=null,d=null,c()},d.onerror=d.onload,d.src=a,d&&d.complete&&d.onload&&d.onload()},addEventListener("lazybeforeunveil",function(b){var d,f,g,h;b.defaultPrevented||("none"==b.target.preload&&(b.target.preload="auto"),d=b.target.getAttribute("data-link"),d&&c(d,!0),d=b.target.getAttribute("data-script"),d&&c(d),d=b.target.getAttribute("data-require"),d&&a.require&&require([d]),g=b.target.getAttribute("data-bg"),g&&(b.details.firesLoad=!0,f=function(){b.target.style.backgroundImage="url("+g+")",b.details.firesLoad=!1,lazySizes.fire(b.target,"_lazyloaded")},e(g,f)),h=b.target.getAttribute("data-poster"),h&&(b.details.firesLoad=!0,f=function(){b.target.poster=h,b.details.firesLoad=!1,lazySizes.fire(b.target,"_lazyloaded")},e(h,f)))},!1))}(window,document); | ||
!function(a,b){"use strict";function c(a,c){if(!e[a]){var d=b.createElement(c?"link":"script"),f=b.getElementsByTagName("script")[0];c?(d.rel="stylesheet",d.href=a):d.src=a,e[a]=!0,e[d.src||d.href]=!0,f.parentNode.insertBefore(d,f)}}var d,e={};b.addEventListener&&a.getComputedStyle&&(d=function(a,c){var d=b.createElement("img");d.onload=function(){d.onload=null,d.onerror=null,d=null,c()},d.onerror=d.onload,d.src=a,d&&d.complete&&d.onload&&d.onload()},addEventListener("lazybeforeunveil",function(b){var e,f,g,h;b.defaultPrevented||("none"==b.target.preload&&(b.target.preload="auto"),e=b.target.getAttribute("data-link"),e&&c(e,!0),e=b.target.getAttribute("data-script"),e&&c(e),e=b.target.getAttribute("data-require"),e&&a.require&&require([e]),g=b.target.getAttribute("data-bg"),g&&(b.details.firesLoad=!0,f=function(){b.target.style.backgroundImage="url("+g+")",b.details.firesLoad=!1,lazySizes.fire(b.target,"_lazyloaded",{},!0,!0)},d(g,f)),h=b.target.getAttribute("data-poster"),h&&(b.details.firesLoad=!0,f=function(){b.target.poster=h,b.details.firesLoad=!1,lazySizes.fire(b.target,"_lazyloaded",{},!0,!0)},d(h,f)))},!1))}(window,document); |
103
README.md
#lazysizes | ||
**lazysizes** is a fast (jank-free) and self-initializing lazyloader for images (including responsive images), iframes, scripts/widgets and much more. It may become also your number one tool to integrate responsive images. Due to the fact that it can also automatically calculate the ``sizes`` attribute for your responsive images based on your CSS as also allows to use custom labeled media queries for you ``media`` attributes, it helps to separate layout (CSS) from content/structure (HTML) and makes integrating responsive images into any environment simply simple. | ||
**lazysizes** is a fast (jank-free) and self-initializing lazyloader for images (including responsive images ``picture``/``srcset``), iframes, scripts/widgets and much more. It may become also your number one tool to integrate responsive images. Due to the fact that it can also automatically calculate the ``sizes`` attribute for your responsive images based on your CSS as also allows to use custom labeled media queries for you ``media`` attributes, it helps to separate layout (CSS) from content/structure (HTML) and makes integrating responsive images into any environment simply simple. | ||
@@ -45,3 +45,3 @@ ##How to | ||
5. **Extendable**: It provides JS and CSS hooks to extend lazySizes with any kind of lazy loading, lazy instantiation, inview callbacks or effects (see also the [available plugins/snippets](#plugins)). | ||
6. **Intelligent prefetch**: lazySizes prefetches near the view assets, only while the browser network is idling. (see also ``expand`` option) | ||
6. **Intelligent prefetch**: lazySizes prefetches/preloads near the view assets to improve user experience, but only while the browser network is idling and does not download inview assets already. (see also ``expand`` option) | ||
7. **Lightweight, but mature solution**: lazySizes has the right balance between a lightweight and a reliable and fast solution | ||
@@ -53,3 +53,3 @@ | ||
##About responsive image support (``picture`` and/or ``srcset``) | ||
For full cross browser responsive image support you must either use a polyfill like [respimage](https://github.com/aFarkas/respimage) or [picturefill](https://github.com/scottjehl/picturefill) or use the [responsive image on demand plugin](plugins/rias). | ||
For full cross browser responsive image support you must either use a polyfill like [respimage](https://github.com/aFarkas/respimage) or [picturefill](https://github.com/scottjehl/picturefill) or use the extreme lightweight partial [respimg polyfill plugin](plugins/respimg) or the [responsive image on demand plugin](plugins/rias). | ||
@@ -78,3 +78,3 @@ ##More about the API | ||
**Important: How ``sizes`` is calculated**: The automatic sizes calculation takes the width of the image. If it is below ``50`` (can be configured through the ``minSize`` option), lazySizes traverses up the DOM tree until it finds a parent which is over ``50`` and uses this number. Often the following general CSS rule might help: ``img[data-sizes="auto"] { display: block; }``. (see also [specifying image/iframe dimensions](#specify-dimensions) | ||
**Important: How ``sizes`` is calculated**: The automatic sizes calculation takes the width of the image. If it is below ``50`` (can be configured through the ``minSize`` option), lazySizes traverses up the DOM tree until it finds a parent which is over ``50`` and uses this number. Often the following general CSS rule might help: ``img[data-sizes="auto"] { display: block; }``. (see also [specifying image/iframe dimensions](#specify-dimensions)) | ||
@@ -112,3 +112,3 @@ ##Recommended markup patterns | ||
Note: In case you are using the simple markup pattern, consider to set the ``preloadAfterLoad`` to ``true`` (for SEO) and to add unobtrusive unveil effects using the ``addClasses`` option ([demo](http://afarkas.github.io/lazysizes/no-src.html#examples)). | ||
Note: In case you are using the simple markup pattern, consider to set the ``preloadAfterLoad`` to ``true`` (for SEO) and to add unobtrusive unveil effects ([demo](http://afarkas.github.io/lazysizes/no-src.html#examples)). | ||
@@ -131,3 +131,2 @@ ###The noscript pattern | ||
<img src="grey.jpg" data-src="image.jpg" class="lazyload" /> | ||
<!--<![endif]--> | ||
``` | ||
@@ -169,7 +168,9 @@ | ||
```js | ||
window.lazySizesConfig = { | ||
lazyClass: 'postbone', // use .postbone instead of .lazyload | ||
// preload all lazy elements in a lazy loading queue after onload, if on desktop | ||
preloadAfterLoad: !(/mobi/i.test(navigator.userAgent)) | ||
}; | ||
window.lazySizesConfig = window.lazySizesConfig || {}; | ||
// use .postbone instead of .lazyload | ||
window.lazySizesConfig.lazyClass = 'postbone'; | ||
// preload all lazy elements in a lazy loading queue after onload, if on desktop | ||
window.lazySizesConfig.preloadAfterLoad = !(/mobi/i.test(navigator.userAgent)); | ||
``` | ||
@@ -180,7 +181,6 @@ | ||
* ``lazySizesConfig.lazyClass`` (default: ``"lazyload"``): Marker class for all elements which should be lazy loaded (There can be only one ``class``. In case you need to add some other element, without the defined class, simply add it per JS: ``$('.lazy-others').addClass('lazyload');``) | ||
* ``lazySizesConfig.preloadAfterLoad`` (default: ``false``): Wether lazysizes should load all elements after the window onload event. Note: lazySizes will then still download those not-in-view images inside of a lazy queue, so that other downloads after onload are not blocked.) In case this option is ``false`` and not providing a suitable low quality image placeholder will hide below the fold images from google. | ||
* ``lazySizesConfig.preloadAfterLoad`` (default: ``false``): Whether lazysizes should load all elements after the window onload event. Note: lazySizes will then still download those not-in-view images inside of a lazy queue, so that other downloads after onload are not blocked.) In case this option is ``false`` and not providing a suitable low quality image placeholder will hide below the fold images from google. | ||
* ``lazySizesConfig.preloadClass`` (default: ``"lazypreload"``): Marker class for elements which should be lazy pre-loaded after onload. Those elements will be even preloaded, if the ``preloadAfterLoad`` option is set to ``false``. Note: This *class* can be also dynamically set (``$currentSlide.next().find('.lazyload').addClass('lazypreload');``). | ||
* ``lazySizesConfig.addClasses`` (default: ``true``): Wether lazysizes should add loading and loaded classes. This can be used to add unveil effects or to apply new styles (background-image). | ||
* ``lazySizesConfig.loadingClass`` (default: ``"lazyloading"``): If ``addClasses`` is set to ``true`` this ``class`` will be added to ``img`` element as soon as image loading starts. Can be used to add unveil effects. | ||
* ``lazySizesConfig.loadedClass`` (default: ``"lazyloaded"``): If ``addClasses`` is set to ``true`` this ``class`` will be added to any element as soon as the image is loaded or the image comes into view. Can be used to add unveil effects or to apply styles. | ||
* ``lazySizesConfig.loadingClass`` (default: ``"lazyloading"``): This ``class`` will be added to ``img`` element as soon as image loading starts. Can be used to add unveil effects. | ||
* ``lazySizesConfig.loadedClass`` (default: ``"lazyloaded"``): This ``class`` will be added to any element as soon as the image is loaded or the image comes into view. Can be used to add unveil effects or to apply styles. | ||
* ``lazySizesConfig.expand`` (default: ``120``): The ``expand`` option expands the calculated visual viewport area in all directions, so that elements can be loaded before they are becoming visible. (Note: Reasonable values are between ``20`` and ``200``.) In case you have a lot of small images or you are using the LQIP pattern you can lower the value, in case you have larger images set it to a higher value. Also note, that lazySizes will dynamically shrink this value to ``0``, if the browser is currently downloading and expand it (by multiplying the ``expand`` option with ``3.5``) if the browser network is currently idling. This option can be overridden with the ``[data-expand]`` attribute. | ||
@@ -191,3 +191,3 @@ * ``lazySizesConfig.minSize`` (default: ``50``): For ``data-sizes="auto"`` feature. The minimum size of an image that is used to calculate the ``sizes`` attribute. In case it is under ``minSize`` the script traverses up the DOM tree until it finds a parent that is over ``minSize``. | ||
* ``lazySizesConfig.sizesAttr`` (default: ``"data-sizes"``): The attribute, which should be transformed to ``sizes``. Makes almost only sense with the value ``"auto"``. Otherwise the ``sizes`` attribute should be used directly. | ||
* ``lazySizesConfig.customMedia`` (default: ``{}``): The ``customMedia`` option object is an alias map for different media queries. It can be used to separate your specific media queries implementation for the ``source[media]`` attribute by creating labeled media queries. (See also the [custommedia extension](plugins/custommedia)). | ||
* ``lazySizesConfig.customMedia`` (default: ``{}``): The ``customMedia`` option object is an alias map for different media queries. It can be used to separate/centralize your multiple specific media queries implementation (layout) from the ``source[media]`` attribute (content/structure) by creating labeled media queries. (See also the [custommedia extension](plugins/custommedia)). | ||
```html | ||
@@ -215,8 +215,9 @@ <script> | ||
media="--large" /> | ||
<!--[if IE 9]></audio><![endif]--> | ||
<img | ||
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" | ||
class="lazyload" | ||
data-srcset="http://placehold.it/1800x900/117fe8/fff" | ||
alt="image with artdirection" /> | ||
<source | ||
data-srcset="http://placehold.it/1800x900/117fe8/fff" /> | ||
<!--[if IE 9]></audio><![endif]--> | ||
<img | ||
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" | ||
class="lazyload" | ||
alt="image with artdirection" /> | ||
</picture> | ||
@@ -251,6 +252,6 @@ ``` | ||
<script> | ||
window.lazySizesConfig = { | ||
expand: 40 | ||
}; | ||
window.lazySizesConfig = window.lazySizesConfig || {}; | ||
window.lazySizesConfig.expand = 20; | ||
$(document).on('lazybeforeunveil', (function(){ | ||
@@ -276,3 +277,3 @@ var onLoad = function(e){ | ||
For CSS transition/animations or progress bars / spinners use the ``addClasses`` option. See also the [animate.html](http://afarkas.github.io/lazysizes/animate.html) and the [no-src.html](http://afarkas.github.io/lazysizes/no-src.html) examples: | ||
For CSS transition/animations or progress bars / spinners use the ``.lazyloading`` / ``.lazyloaded`` classes. See also the [animate.html](http://afarkas.github.io/lazysizes/animate.html) and the [no-src.html](http://afarkas.github.io/lazysizes/no-src.html) examples: | ||
@@ -301,8 +302,2 @@ ```html | ||
<script> | ||
window.lazySizesConfig = { | ||
//,expand: 80 //default is 120 | ||
}; | ||
</script> | ||
<img | ||
@@ -346,16 +341,18 @@ src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" | ||
####JS API - methods | ||
#####``lazySizes.unveilLazy(DOMNode)`` | ||
#####``lazySizes.loader.unveil(DOMNode)`` | ||
In case a developer wants to show an image even if it is not inside the viewport the ``lazySizes.unveilLazy(DOMNode)`` can be called: | ||
In case a developer wants to show an image even if it is not inside the viewport the ``lazySizes.loader.unveil(DOMNode)`` can be called: | ||
```js | ||
lazySizes.unveilLazy(imgElem); | ||
lazySizes.loader.unveil(imgElem); | ||
``` | ||
#####``lazySizes.updateAllSizes()`` | ||
Note: As a more lazy alternative the ``lazypreload`` class can be set: ``$(imgElem).addClass('lazypreload');``. | ||
In case one or more image elements with the attribute ``data-sizes="auto"`` have changed in size ``lazySizes.updateAllSizes`` can be called (For example to implement element queries): | ||
#####``lazySizes.autoSizer.updateElems()`` | ||
In case one or more image elements with the attribute ``data-sizes="auto"`` have changed in size ``lazySizes.autoSizer.updateElems`` can be called (For example to implement element queries): | ||
```js | ||
lazySizes.updateAllSizes(); | ||
lazySizes.autoSizer.updateElems(); | ||
``` | ||
@@ -365,3 +362,3 @@ | ||
LazySizes initializes itself as soon as possible. In case you set ``lazySizesConfig.init`` to ``false`` you need to explicityl call ``lazySizes.init()``. | ||
LazySizes initializes itself as soon as possible. In case you set ``lazySizesConfig.init`` to ``false`` you need to explicitly call ``lazySizes.init()``. | ||
@@ -371,3 +368,3 @@ ```html | ||
window.lazySizesConfig = window.lazySizesConfig || {}; | ||
lazySizesConfig.init = false; | ||
window.lazySizesConfig.init = false; | ||
</script> | ||
@@ -383,3 +380,3 @@ | ||
##Browser Support | ||
**lazysizes** supports at least the following browsers: IE9+, Firefox 21+, Chrome 27+, Safari 6.1+, iOS Safari 7.0+, Android 4.1+ | ||
**lazysizes** supports all browsers, that support [``document.getElementsByClassName``](http://caniuse.com/#feat=getelementsbyclassname) (== all browsers but not IE8-). | ||
@@ -407,2 +404,6 @@ ##Contributing | ||
###[respimg polyfill plugin](plugins/respimg) | ||
The respimg polyfill plugin is an extreme lightweight alternate polyfill for the most important subsets of responsive images (srcset and picture). | ||
###[OPTIMUMX plugin](plugins/optimumx) | ||
@@ -417,14 +418,20 @@ The ``srcset`` attribute with the *w* descriptor and ``sizes`` attribute automatically also includes high DPI images. But each image has a different optimal pixel density, which might be lower (for example 1.5x) than the pixel density of your device (2x or 3x). This information is unknown to the browser and therefore can't be optimized for. The [lazySizes optimumx extension](plugins/optimumx) gives you more control to trade between perceived quality vs. perceived performance. | ||
###[bgset plugin](plugins/bgset) | ||
###[bgset plugin - lazy responsive background-image](plugins/bgset) | ||
The bgset plugin allows lazyload multiple background images with different resolutions/sizes (responsive background images). In case you only need one image use the unveilhooks extension. | ||
###[scrollintent plugin](plugins/scrollintent) | ||
The [scrollintent plugin](plugins/scrollintent) heavily improves runtime performance, while the user is scrolling. Normally lazySizes uses a throttled scroll event to check for ``.lazyload`` elements. The scrollintent plugin changes this behavior to only check for ``.lazyload`` resources if either the user scrolling is slow or the user has stopped scrolling. | ||
###[print plugin](plugins/print) | ||
The [print plugin](plugins/print) plugin enables lazySizes to unveil all elements as soon as the user starts to print. (Or set ``lazySizesConfig.preloadAfterLoad`` to ``true``). | ||
###[progressive plugin](plugins/progressive) | ||
The [progressive plugin](plugins/progressive) plugin adds better support for rendering progressive jpgs/pngs. | ||
##Why lazysizes | ||
In the past I often struggled using lazy image loaders, because the "main check function" is called repeatedly and with a high frequency. Which makes it hard to fullfill two purposes runtime and memory efficiency. And looking into the source code of most so called lazy loaders often also unveils lazy developers... | ||
In the past I often struggled using lazy image loaders, because the "main check function" is called repeatedly and with a high frequency. Which makes it hard to fulfill two purposes runtime and memory efficiency. And looking into the source code of most so called lazy loaders often also unveils lazy developers... | ||
But in a world of responsive retina optimized images on the one hand and JS widgets like carousels or tabs (a lot of initially hidden images) on the other hand lazy loading images becomes more and more important. And therefore I created this project. And in fact **lazysizes** is different. | ||
Due to the fact, that it is designed to be invoked with a high frequency and therefore works highly efficient, it was possible to hook into all kind of events as also add a mutationobserver and therefore this lazyloader works as a simple drop in solution, you simply write/render your markup and no matter wether it was added by AJAX or revealed by a JS or CSS animation it will be picked up by **layzsizes**. | ||
Due to the fact, that it is designed to be invoked with a high frequency and therefore works highly efficient, it was possible to hook into all kind of events as also add a mutationobserver and therefore this lazyloader works as a simple drop in solution, you simply write/render your markup and no matter whether it was added by AJAX or revealed by a JS or CSS animation it will be picked up by **layzsizes**. | ||
@@ -447,3 +454,3 @@ ```html | ||
##<a name="specify-dimensions"></a>Tip: Specifying image dimensions (minimizing reflows and avoiding page jumps) | ||
To minimize reflows, content jumping or unpredictable behavior with some other JS widgets (isotope, masonry, some sliders/carousels...) the width **and** the height of an image should be calculable by the browser before the image source itself is loaded. For "static" images this can done using either CSS or using the content attributes: | ||
To minimize reflows, content jumping or unpredictable behavior with some other JS widgets (isotope, masonry, some sliders/carousels...) the width **and** the height of an image should be calculable by the browser before the image source itself is loaded. For "static" images this can be done using either CSS or using the content attributes: | ||
@@ -536,8 +543,8 @@ ```html | ||
**Note**: In case you use the "unknown intrinsic ratio pattern" the ``data-sizes="auto"`` feature should not be used. | ||
**Note**: In case you use the "unknown intrinsic ratio pattern" and the width of the image will not approximately match the width of its container the ``data-sizes="auto"`` feature should not be used. | ||
##Tip: Where/How to include lazySizes | ||
While lazy loading is a great important feature, it is important for users that crucial inview images are loaded as fast as possible. (Most user start to interact with a page after inview images are loaded.) | ||
While lazy loading is a great feature, it is important for users that crucial inview images are loaded as fast as possible. (Most users start to interact with a page after inview images are loaded.) | ||
In case you are normally combine all your scripts into one large script and add this to the bottom of your page. It can be better for perceived performance to generate two or sometimes three script packages. | ||
In case you normally combine all your scripts into one large script and add this to the bottom of your page. It can be better for perceived performance to generate two or sometimes three script packages. | ||
@@ -544,0 +551,0 @@ One small package, which includes all scripts which have heavy influence on the content or the UI and another larger one which includes the normal behavior of the page. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
161642
40
2005
534