From ca131050394b04864825e98cae99ec31c750fd2e Mon Sep 17 00:00:00 2001 From: goldenapples Date: Mon, 16 Sep 2019 16:03:01 -0400 Subject: [PATCH 1/4] Use MutationObserver to update image dimensions when it renders The dimension calculations were calculating image dimensions before the image is rendered on the page, which gives incorrect element dimensions, leading to a misproportioned image. This PR attempts to fix that issue by recalculating dimensions on a Mutation event, when the src is first replaced, rather than immediately on setup, to better calculate the space the element takes up in the document. (I'm torn between this approach and just doing it in a timeout... I think the timeout would be better performance, but at the risk of not being as accurate.) --- assets/gaussholder.js | 46 ++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/assets/gaussholder.js b/assets/gaussholder.js index 3cad36c..3aaf266 100644 --- a/assets/gaussholder.js +++ b/assets/gaussholder.js @@ -64,6 +64,36 @@ window.Gaussholder = (function (header) { }; }; + /** + * Recalculate image ratio when an image renders on the page. + * + * @param {MutationRecord[]} Updates to an element's attributes. + */ + var recalculateDimensions = function (mutation) { + // Ignore changes to the "style" attribute, to prevent recursion. + if ( mutation.attributeName === 'style' ) { + return; + } + + var element = mutation.target; + var actual = element.getBoundingClientRect(); + var size = element.dataset.gaussholderSize.split(','); + var width = parseInt( size[0], 10 ), height = parseInt( size[1], 10 ); + + if ( actual.width < width ) { + // Rescale, keeping the aspect ratio + height = height * ( actual.width / width ); + width = actual.width; + } else if ( actual.height < height ) { + // Rescale, keeping the aspect ratio + width = width * ( actual.height / height ); + height = actual.height; + } + + element.style.width = width + 'px'; + element.style.height = height + 'px'; + }; + /** * Render placeholder for an image * @@ -82,20 +112,8 @@ window.Gaussholder = (function (header) { element.style.height = final[1] + 'px'; // ...then recalculate based on what it actually renders as - var original = [ final[0], final[1] ]; - if ( element.width < final[0] ) { - // Rescale, keeping the aspect ratio - final[0] = element.width; - final[1] = final[1] * ( final[0] / original[0] ); - } else if ( element.height < final[1] ) { - // Rescale, keeping the aspect ratio - final[1] = element.height; - final[0] = final[0] * ( final[1] / original[1] ); - } - - // Set dimensions, _again_ - element.style.width = final[0] + 'px'; - element.style.height = final[1] + 'px'; + var resizeObserver = new MutationObserver( function( mutations ) { mutations.forEach( recalculateDimensions ) } ); + resizeObserver.observe( element, { attributes: true, subtree: true } ); render(canvas, element.dataset.gaussholder.split(','), final, function () { // Load in as our background image From af6d9f574af91c1d069ef1804f18c03abec59ccd Mon Sep 17 00:00:00 2001 From: goldenapples Date: Thu, 3 Oct 2019 14:42:31 -0400 Subject: [PATCH 2/4] Remove mutation observer, use timeout instead --- assets/gaussholder.js | 29 +++++++++++++++++------------ assets/gaussholder.min.js | 2 +- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/assets/gaussholder.js b/assets/gaussholder.js index 3aaf266..ce972b1 100644 --- a/assets/gaussholder.js +++ b/assets/gaussholder.js @@ -67,15 +67,9 @@ window.Gaussholder = (function (header) { /** * Recalculate image ratio when an image renders on the page. * - * @param {MutationRecord[]} Updates to an element's attributes. + * @param {HTMLImageElement} Image element to recalculate dimensions for. */ - var recalculateDimensions = function (mutation) { - // Ignore changes to the "style" attribute, to prevent recursion. - if ( mutation.attributeName === 'style' ) { - return; - } - - var element = mutation.target; + var calculateDimensionStyle = function (element) { var actual = element.getBoundingClientRect(); var size = element.dataset.gaussholderSize.split(','); var width = parseInt( size[0], 10 ), height = parseInt( size[1], 10 ); @@ -90,8 +84,7 @@ window.Gaussholder = (function (header) { height = actual.height; } - element.style.width = width + 'px'; - element.style.height = height + 'px'; + element.style.cssText += 'width: ' + width + 'px; height: ' + height + 'px;'; }; /** @@ -112,13 +105,25 @@ window.Gaussholder = (function (header) { element.style.height = final[1] + 'px'; // ...then recalculate based on what it actually renders as - var resizeObserver = new MutationObserver( function( mutations ) { mutations.forEach( recalculateDimensions ) } ); - resizeObserver.observe( element, { attributes: true, subtree: true } ); + calculateDimensionStyle( element ); + + // Schedule an observer to update on any rendering changes. + //var resizeObserver = new MutationObserver( + //function( mutations ) { + //var element = mutations[0].target; + //if ( element.clientWidth === parseInt( element.style.width, 10 ) ) { + //return; + //} + //calculateDimensionStyle( element ); + //} + //); + //resizeObserver.observe( element, { childList: true, attributes: true, subtree: true, [> attributeFilter: [ 'src' ] <] } ); render(canvas, element.dataset.gaussholder.split(','), final, function () { // Load in as our background image element.style.backgroundImage = 'url("' + canvas.toDataURL() + '")'; element.style.backgroundRepeat = 'no-repeat'; + setTimeout( function() { calculateDimensionStyle( element ); }, 200 ); }); }; diff --git a/assets/gaussholder.min.js b/assets/gaussholder.min.js index c24b542..67eb667 100644 --- a/assets/gaussholder.min.js +++ b/assets/gaussholder.min.js @@ -1 +1 @@ -var StackBlur=function(){function a(a,b,c,d,e){if("string"==typeof a)var a=document.getElementById(a);else if(!a instanceof HTMLCanvasElement)return;var f,g=a.getContext("2d");try{f=g.getImageData(b,c,d,e)}catch(a){throw new Error("unable to access image data: "+a)}return f}function b(b,d,e,f,g,h){if(!(isNaN(h)||h<1)){h|=0;var i=a(b,d,e,f,g);i=c(i,d,e,f,g,h),b.getContext("2d").putImageData(i,d,e)}}function c(a,b,c,g,h,i){var j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D=a.data,E=i+i+1,F=g-1,G=h-1,H=i+1,I=H*(H+1)/2,J=new d,K=J;for(l=1;l>P,D[o+1]=r*O>>P,D[o+2]=s*O>>P,q-=t,r-=u,s-=v,t-=M.r,u-=M.g,v-=M.b,m=p+((m=j+i+1)>P,D[m+1]=r*O>>P,D[m+2]=s*O>>P,q-=t,r-=u,s-=v,t-=M.r,u-=M.g,v-=M.b,m=j+((m=k+H)>8&255,h[a.height_offset+1]=255&f,h[a.length_offset]=e>>8&255,h[a.length_offset+1]=255&e,c(h)},e=function(b,c,e,f){var g=b.getContext("2d"),h=parseInt(e[0]),i=parseInt(e[1]),j=parseInt(e[2]);g.mozImageSmoothingEnabled=!1,g.webkitImageSmoothingEnabled=!1,g.msImageSmoothingEnabled=!1,g.imageSmoothingEnabled=!1;var k=new Image;k.src="data:image/jpg;base64,"+d(a,c),k.onload=function(){b.width=h,b.height=i,g.drawImage(k,0,0,h,i),StackBlur.canvasRGB(b,0,0,h,i,j),f()}},f=function(a){if("gaussholder"in a.dataset){var b=document.createElement("canvas"),c=a.dataset.gaussholderSize.split(",");a.style.width=c[0]+"px",a.style.height=c[1]+"px";var d=[c[0],c[1]];a.widthb)return a.style[c]="",a.style.clipPath="",void(a.style.webkitClipPath="");var i=d*(1-h/b);a.style[c]="blur("+.5*i+"px)",window.requestAnimationFrame(g)};window.requestAnimationFrame(g)}}},h=[],i=1200,j=0,k=null,l=function(){var a=Date.now();if(j+40>a){if(k)return;return void(k=window.setTimeout(l,40))}j=a,k&&(k=null);for(var b=[],c=h.length-1;c>=0;c--){var d=h[c],e=d.getBoundingClientRect().top<=window.innerHeight+i;e?g(d):b.push(d)}h=b,h.length<1&&window.removeEventListener("scroll",l)},m=function(){for(var a=document.getElementsByTagName("img"),b=a.length-1;b>=0;b--){var c=a[b];c.complete?f(c):c.onload=function(){f(this)}}h=a,l(),h.length>0&&window.addEventListener("scroll",l)};return m}(window.GaussholderHeader); \ No newline at end of file +var StackBlur=function(){var N=[512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512,454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512,482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456,437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512,497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328,320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456,446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335,329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512,505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405,399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328,324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271,268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456,451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,289,287,285,282,280,278,275,273,271,269,267,265,263,261,259],U=[9,11,12,13,13,14,14,15,15,15,15,16,16,16,16,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24];function q(){this.r=0,this.g=0,this.b=0,this.a=0,this.next=null}return{canvasRGB:function(t,e,n,a,r,i){if(!(isNaN(i)||i<1)){i|=0;var s=function(t,e,n,a,r){if("string"==typeof t)t=document.getElementById(t);else if(!t instanceof HTMLCanvasElement)return;var i,s=t.getContext("2d");try{i=s.getImageData(e,n,a,r)}catch(t){throw new Error("unable to access image data: "+t)}return i}(t,e,n,a,r);s=function(t,e,n,a,r,i){var s,o,l,g,d,c,u,h,f,w,m,p,v,b,y,x,I,k,C,E,S=t.data,B=i+i+1,R=a-1,A=r-1,L=i+1,P=L*(L+1)/2,T=new q,z=T;for(l=1;l>H,S[c+1]=f*_>>H,S[c+2]=w*_>>H,h-=m,f-=p,w-=v,m-=F.r,p-=F.g,v-=F.b,g=u+((g=s+i+1)>H,S[g+1]=f*_>>H,S[g+2]=w*_>>H,h-=m,f-=p,w-=v,m-=F.r,p-=F.g,v-=F.b,g=s+((g=o+L)>8&255,s[t.height_offset+1]=255&r,s[t.length_offset]=a>>8&255,s[t.length_offset+1]=255&a,function(t){for(var e="",n=new Uint8Array(t),a=n.byteLength,r=0;r Date: Thu, 3 Oct 2019 14:54:22 -0400 Subject: [PATCH 3/4] Remove commented-out code --- assets/gaussholder.js | 11 ----------- assets/gaussholder.min.js | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/assets/gaussholder.js b/assets/gaussholder.js index ce972b1..9d04e4d 100644 --- a/assets/gaussholder.js +++ b/assets/gaussholder.js @@ -108,17 +108,6 @@ window.Gaussholder = (function (header) { calculateDimensionStyle( element ); // Schedule an observer to update on any rendering changes. - //var resizeObserver = new MutationObserver( - //function( mutations ) { - //var element = mutations[0].target; - //if ( element.clientWidth === parseInt( element.style.width, 10 ) ) { - //return; - //} - //calculateDimensionStyle( element ); - //} - //); - //resizeObserver.observe( element, { childList: true, attributes: true, subtree: true, [> attributeFilter: [ 'src' ] <] } ); - render(canvas, element.dataset.gaussholder.split(','), final, function () { // Load in as our background image element.style.backgroundImage = 'url("' + canvas.toDataURL() + '")'; diff --git a/assets/gaussholder.min.js b/assets/gaussholder.min.js index 67eb667..c95ed78 100644 --- a/assets/gaussholder.min.js +++ b/assets/gaussholder.min.js @@ -1 +1 @@ -var StackBlur=function(){var N=[512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512,454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512,482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456,437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512,497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328,320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456,446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335,329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512,505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405,399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328,324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271,268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456,451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,289,287,285,282,280,278,275,273,271,269,267,265,263,261,259],U=[9,11,12,13,13,14,14,15,15,15,15,16,16,16,16,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24];function q(){this.r=0,this.g=0,this.b=0,this.a=0,this.next=null}return{canvasRGB:function(t,e,n,a,r,i){if(!(isNaN(i)||i<1)){i|=0;var s=function(t,e,n,a,r){if("string"==typeof t)t=document.getElementById(t);else if(!t instanceof HTMLCanvasElement)return;var i,s=t.getContext("2d");try{i=s.getImageData(e,n,a,r)}catch(t){throw new Error("unable to access image data: "+t)}return i}(t,e,n,a,r);s=function(t,e,n,a,r,i){var s,o,l,g,d,c,u,h,f,w,m,p,v,b,y,x,I,k,C,E,S=t.data,B=i+i+1,R=a-1,A=r-1,L=i+1,P=L*(L+1)/2,T=new q,z=T;for(l=1;l>H,S[c+1]=f*_>>H,S[c+2]=w*_>>H,h-=m,f-=p,w-=v,m-=F.r,p-=F.g,v-=F.b,g=u+((g=s+i+1)>H,S[g+1]=f*_>>H,S[g+2]=w*_>>H,h-=m,f-=p,w-=v,m-=F.r,p-=F.g,v-=F.b,g=s+((g=o+L)>8&255,s[t.height_offset+1]=255&r,s[t.length_offset]=a>>8&255,s[t.length_offset+1]=255&a,function(t){for(var e="",n=new Uint8Array(t),a=n.byteLength,r=0;r>H,S[c+1]=f*_>>H,S[c+2]=w*_>>H,h-=m,f-=p,w-=v,m-=F.r,p-=F.g,v-=F.b,g=u+((g=s+i+1)>H,S[g+1]=f*_>>H,S[g+2]=w*_>>H,h-=m,f-=p,w-=v,m-=F.r,p-=F.g,v-=F.b,g=s+((g=o+L)>8&255,s[t.height_offset+1]=255&r,s[t.length_offset]=a>>8&255,s[t.length_offset+1]=255&a,function(t){for(var e="",n=new Uint8Array(t),a=n.byteLength,r=0;r Date: Fri, 4 Oct 2019 15:16:34 -0400 Subject: [PATCH 4/4] Run eslint --fix over gaussholder.js Brings this file more in line with our coding standards. Note that I had to turn off the "no-var" rule to avoid conflicts with grunt uglify, which for some reason doesn't support let and consts yet. --- assets/gaussholder.js | 85 ++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/assets/gaussholder.js b/assets/gaussholder.js index 9d04e4d..bf3cfee 100644 --- a/assets/gaussholder.js +++ b/assets/gaussholder.js @@ -1,33 +1,34 @@ -window.Gaussholder = (function (header) { +/* global StackBlur */ +window.Gaussholder = ( function ( header ) { // Fade duration in ms when the image loads in. var fadeDuration = 800; - var arrayBufferToBase64 = function( buffer ) { + var arrayBufferToBase64 = function ( buffer ) { var binary = ''; var bytes = new Uint8Array( buffer ); var len = bytes.byteLength; - for (var i = 0; i < len; i++) { + for ( var i = 0; i < len; i++ ) { binary += String.fromCharCode( bytes[ i ] ); } return window.btoa( binary ); }; - var reconstituteImage = function (header, image) { + var reconstituteImage = function ( header, image ) { var image_data = image[0], width = parseInt( image[1] ), height = parseInt( image[2] ); var full = atob( header.header ) + atob( image_data ); var bytes = new Uint8Array( full.length ); - for (var i = 0; i < full.length; i++) { - bytes[i] = full.charCodeAt(i); + for ( var i = 0; i < full.length; i++ ) { + bytes[i] = full.charCodeAt( i ); } // Poke the bits. - bytes[ header.height_offset ] = ( (height >> 8) & 0xFF); - bytes[ header.height_offset + 1 ] = (height & 0xFF); - bytes[ header.length_offset ] = ( (width >> 8) & 0xFF); - bytes[ header.length_offset + 1] = (width & 0xFF); + bytes[ header.height_offset ] = ( ( height >> 8 ) & 0xFF ); + bytes[ header.height_offset + 1 ] = ( height & 0xFF ); + bytes[ header.length_offset ] = ( ( width >> 8 ) & 0xFF ); + bytes[ header.length_offset + 1] = ( width & 0xFF ); // Back to a full JPEG now. return arrayBufferToBase64( bytes ); @@ -40,8 +41,8 @@ window.Gaussholder = (function (header) { * @param {list} image 3-tuple of base64-encoded image data, width, height * @param {list} final Final width and height */ - var render = function (canvas, image, final, cb) { - var ctx = canvas.getContext('2d'), + var render = function ( canvas, image, final, cb ) { + var ctx = canvas.getContext( '2d' ), width = parseInt( final[0] ), height = parseInt( final[1] ), radius = parseInt( final[2] ); @@ -53,12 +54,12 @@ window.Gaussholder = (function (header) { ctx.imageSmoothingEnabled = false; var img = new Image(); - img.src = 'data:image/jpg;base64,' + reconstituteImage(header, image); + img.src = 'data:image/jpg;base64,' + reconstituteImage( header, image ); img.onload = function () { canvas.width = width; canvas.height = height; - ctx.drawImage(img, 0, 0, width, height); + ctx.drawImage( img, 0, 0, width, height ); StackBlur.canvasRGB( canvas, 0, 0, width, height, radius ); cb(); }; @@ -69,9 +70,9 @@ window.Gaussholder = (function (header) { * * @param {HTMLImageElement} Image element to recalculate dimensions for. */ - var calculateDimensionStyle = function (element) { + var calculateDimensionStyle = function ( element ) { var actual = element.getBoundingClientRect(); - var size = element.dataset.gaussholderSize.split(','); + var size = element.dataset.gaussholderSize.split( ',' ); var width = parseInt( size[0], 10 ), height = parseInt( size[1], 10 ); if ( actual.width < width ) { @@ -92,13 +93,13 @@ window.Gaussholder = (function (header) { * * @param {HTMLImageElement} element Element to render placeholder for */ - var handleElement = function (element) { + var handleElement = function ( element ) { if ( ! ( 'gaussholder' in element.dataset ) ) { return; } - var canvas = document.createElement('canvas'); - var final = element.dataset.gaussholderSize.split(','); + var canvas = document.createElement( 'canvas' ); + var final = element.dataset.gaussholderSize.split( ',' ); // Set the dimensions... element.style.width = final[0] + 'px'; @@ -108,20 +109,22 @@ window.Gaussholder = (function (header) { calculateDimensionStyle( element ); // Schedule an observer to update on any rendering changes. - render(canvas, element.dataset.gaussholder.split(','), final, function () { + render( canvas, element.dataset.gaussholder.split( ',' ), final, function () { // Load in as our background image element.style.backgroundImage = 'url("' + canvas.toDataURL() + '")'; element.style.backgroundRepeat = 'no-repeat'; - setTimeout( function() { calculateDimensionStyle( element ); }, 200 ); - }); + setTimeout( function () { + calculateDimensionStyle( element ); + }, 200 ); + } ); }; - var loadOriginal = function (element) { + var loadOriginal = function ( element ) { if ( ! ( 'originalsrc' in element.dataset ) && ! ( 'originalsrcset' in element.dataset ) ) { return; } - var data = element.dataset.gaussholderSize.split(','), + var data = element.dataset.gaussholderSize.split( ',' ), radius = parseInt( data[2] ); // Load our image now @@ -159,7 +162,7 @@ window.Gaussholder = (function (header) { element.style.backgroundRepeat = ''; var start = 0; - var anim = function (ts) { + var anim = function ( ts ) { if ( ! start ) start = ts; var diff = ts - start; if ( diff > fadeDuration ) { @@ -172,9 +175,9 @@ window.Gaussholder = (function (header) { var effectiveRadius = radius * ( 1 - ( diff / fadeDuration ) ); element.style[ filterProp ] = 'blur(' + effectiveRadius * 0.5 + 'px)'; - window.requestAnimationFrame(anim); + window.requestAnimationFrame( anim ); }; - window.requestAnimationFrame(anim); + window.requestAnimationFrame( anim ); }; }; @@ -189,26 +192,26 @@ window.Gaussholder = (function (header) { if ( loopTimeout ) { return; } - loopTimeout = window.setTimeout(scrollHandler, 40); + loopTimeout = window.setTimeout( scrollHandler, 40 ); return; } lastRun = now; - loopTimeout && (loopTimeout = null); + loopTimeout && ( loopTimeout = null ); var next = []; - for (var i = loadLazily.length - 1; i >= 0; i--) { + for ( var i = loadLazily.length - 1; i >= 0; i-- ) { var img = loadLazily[i]; var shouldShow = img.getBoundingClientRect().top <= ( window.innerHeight + threshold ); if ( ! shouldShow ) { - next.push(img); + next.push( img ); continue; } - loadOriginal(img); + loadOriginal( img ); } loadLazily = next; - if (loadLazily.length < 1) { - window.removeEventListener('scroll', scrollHandler); + if ( loadLazily.length < 1 ) { + window.removeEventListener( 'scroll', scrollHandler ); } }; @@ -216,17 +219,17 @@ window.Gaussholder = (function (header) { * Render all placeholders on the page */ var handleAll = function () { - var images = document.getElementsByTagName('img'); + var images = document.getElementsByTagName( 'img' ); - for (var i = images.length - 1; i >= 0; i--) { + for ( var i = images.length - 1; i >= 0; i-- ) { var img = images[i]; // Ensure the blank GIF has loaded first if ( img.complete ) { - handleElement(img); + handleElement( img ); } else { img.onload = function () { - handleElement(this); + handleElement( this ); } } } @@ -234,10 +237,10 @@ window.Gaussholder = (function (header) { loadLazily = images; scrollHandler(); - if (loadLazily.length > 0) { - window.addEventListener('scroll', scrollHandler); + if ( loadLazily.length > 0 ) { + window.addEventListener( 'scroll', scrollHandler ); } }; return handleAll; -})(window.GaussholderHeader); +} )( window.GaussholderHeader );