From af402b44b9c9eaf14a588993a78c2daf42f7b4ee Mon Sep 17 00:00:00 2001 From: Timo Kosse Date: Thu, 16 Mar 2017 14:24:13 +0100 Subject: [PATCH 1/4] Added lazy loading for any wrapping element. Just assign to a div the class b-lazy and automatically all images/videos/iframes in this div get loaded all at once when the div is scrolled in the viewport. --- blazy.js | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/blazy.js b/blazy.js index 00af78d..32684a4 100644 --- a/blazy.js +++ b/blazy.js @@ -200,7 +200,7 @@ rect.top <= viewport.bottom; } - function loadElement(ele, force, options) { + function loadElement(ele, force, options, parentCallback) { // if element is visible, not loaded or forced if (!hasClass(ele, options.successClass) && (force || options.loadInvisible || (ele.offsetWidth > 0 && ele.offsetHeight > 0))) { var dataSrc = getAttr(ele, _source) || getAttr(ele, options.src); // fallback to default 'data-src' @@ -233,7 +233,8 @@ } else { ele.style.backgroundImage = 'url("' + src + '")'; } - itemLoaded(ele, options); + itemLoaded(ele, options, !parentCallback); + if(parentCallback) parentCallback(); unbindEvent(img, 'load', onLoadHandler); unbindEvent(img, 'error', onErrorHandler); }; @@ -251,27 +252,36 @@ } else { // An item with src like iframe, unity games, simpel video etc ele.src = src; - itemLoaded(ele, options); - } - } else { - // video with child source - if (equal(ele, 'video')) { - each(ele.getElementsByTagName('source'), function(source) { - handleSource(source, _attrSrc, options.src); - }); - ele.load(); - itemLoaded(ele, options); - } else { - if (options.error) options.error(ele, "missing"); - addClass(ele, options.errorClass); + if(equal(ele, 'source')) { + parent.load(); + } + itemLoaded(ele, options, !parentCallback); + if(parentCallback) parentCallback(); } + } else { // a wrapper with tags inside that should be loaded at once + var childElements = ele.querySelectorAll('[data-src]'); + if(childElements) { + var counter = 0; + var childElementLoaded = function() { + counter++; + if(counter == childElements.length) { + itemLoaded(ele, options, true); + } + }; + for(var i = 0; i < childElements.length; i++) { + loadElement(childElements[i], force, options, childElementLoaded); + } + } else { + if (options.error) options.error(ele, "missing"); + addClass(ele, options.errorClass); + } } } } - function itemLoaded(ele, options) { + function itemLoaded(ele, options, finishedLoading) { addClass(ele, options.successClass); - if (options.success) options.success(ele); + if (options.success && finishedLoading) options.success(ele); // cleanup markup, remove data source attributes removeAttr(ele, options.src); removeAttr(ele, options.srcset); @@ -367,4 +377,4 @@ fn.apply(scope, arguments); }; } -}); +}); \ No newline at end of file From f22140f83d6585c880c414d5b25cbe25a43fa23b Mon Sep 17 00:00:00 2001 From: Timo Kosse Date: Thu, 16 Mar 2017 15:21:17 +0100 Subject: [PATCH 2/4] Implemented better error handling --- blazy.js | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/blazy.js b/blazy.js index 32684a4..32c07b7 100644 --- a/blazy.js +++ b/blazy.js @@ -218,8 +218,12 @@ // due to bug introduced in chrome v50 // (https://productforums.google.com/forum/#!topic/chrome/p51Lk7vnP2o) var onErrorHandler = function() { - if (options.error) options.error(ele, "invalid"); - addClass(ele, options.errorClass); + if(parentCallback) { + parentCallback(true); + } else { + if (options.error) options.error(ele, "invalid"); + } + addClass(ele, options.errorClass); unbindEvent(img, 'error', onErrorHandler); unbindEvent(img, 'load', onLoadHandler); }; @@ -234,7 +238,7 @@ ele.style.backgroundImage = 'url("' + src + '")'; } itemLoaded(ele, options, !parentCallback); - if(parentCallback) parentCallback(); + if(parentCallback) parentCallback(false); unbindEvent(img, 'load', onLoadHandler); unbindEvent(img, 'error', onErrorHandler); }; @@ -256,16 +260,25 @@ parent.load(); } itemLoaded(ele, options, !parentCallback); - if(parentCallback) parentCallback(); + if(parentCallback) parentCallback(false); } } else { // a wrapper with tags inside that should be loaded at once var childElements = ele.querySelectorAll('[data-src]'); if(childElements) { var counter = 0; - var childElementLoaded = function() { + var errorFlag = false; + var childElementLoaded = function(failure) { counter++; + if(failure) errorFlag = failure; if(counter == childElements.length) { - itemLoaded(ele, options, true); + //if single elements couldn't be loaded and an error handling is specified, raise an error + //otherwise proceed with success + if(errorFlag == true && options.error) { + options.error(ele, "invalid"); + addClass(ele, options.errorClass); + } else { + itemLoaded(ele, options, true, !errorFlag); + } } }; for(var i = 0; i < childElements.length; i++) { @@ -279,9 +292,9 @@ } } - function itemLoaded(ele, options, finishedLoading) { + function itemLoaded(ele, options, finishedLoading, allElementsSucceeded) { addClass(ele, options.successClass); - if (options.success && finishedLoading) options.success(ele); + if (options.success && finishedLoading) options.success(ele, allElementsSucceeded); // cleanup markup, remove data source attributes removeAttr(ele, options.src); removeAttr(ele, options.srcset); From b9a655315deffc3fe5d9273721104fe332bff64b Mon Sep 17 00:00:00 2001 From: Timo Kosse Date: Thu, 16 Mar 2017 21:55:01 +0100 Subject: [PATCH 3/4] Updated minified version --- blazy.min.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/blazy.min.js b/blazy.min.js index 649abfd..0c74a10 100644 --- a/blazy.min.js +++ b/blazy.min.js @@ -1,6 +1,6 @@ -/*! - hey, [be]Lazy.js - v1.8.2 - 2016.10.25 +/* + hey, [be]Lazy.js - v1.8.2 - 2016.10.25 A fast, small and dependency free lazy load script (https://github.com/dinbror/blazy) (c) Bjoern Klinggaard - @bklinggaard - http://dinbror.dk/blazy */ - (function(q,m){"function"===typeof define&&define.amd?define(m):"object"===typeof exports?module.exports=m():q.Blazy=m()})(this,function(){function q(b){var c=b._util;c.elements=E(b.options);c.count=c.elements.length;c.destroyed&&(c.destroyed=!1,b.options.container&&l(b.options.container,function(a){n(a,"scroll",c.validateT)}),n(window,"resize",c.saveViewportOffsetT),n(window,"resize",c.validateT),n(window,"scroll",c.validateT));m(b)}function m(b){for(var c=b._util,a=0;a=c.left&&b.bottom>=c.top&&b.left<=c.right&&b.top<=c.bottom}function z(b,c,a){if(!t(b,a.successClass)&&(c||a.loadInvisible||0=window.screen.width)return u=a.src,!1});setTimeout(function(){q(a)})}}); \ No newline at end of file +(function(m,g){"function"===typeof define&&define.amd?define(g):"object"===typeof exports?module.exports=g():m.Blazy=g()})(this,function(){function m(b){var c=b._util;c.elements=I(b.options);c.count=c.elements.length;c.destroyed&&(c.destroyed=!1,b.options.container&&p(b.options.container,function(a){q(a,"scroll",c.validateT)}),q(window,"resize",c.saveViewportOffsetT),q(window,"resize",c.validateT),q(window,"scroll",c.validateT));g(b)}function g(b){for(var c=b._util,a=0;ae.top?h:e.top,right:ue.left?k:e.left})}else f=!1;break a}f=r(f,e)}if(f||x(d,b.options.successClass))b.load(d),c.elements.splice(a,1),c.count--,a--}0===c.count&&b.destroy()}function r(b,c){return b.right>=c.left&&b.bottom>=c.top&&b.left<=c.right&&b.top<=c.bottom}function y(b,c,a,d){if(!x(b,a.successClass)&&(c||a.loadInvisible||0=window.screen.width)return z=a.src,!1});setTimeout(function(){m(a)})}}); \ No newline at end of file From 9e20266eef467e22613bb50c744cf9d33ba8efb0 Mon Sep 17 00:00:00 2001 From: Timo Kosse Date: Thu, 16 Mar 2017 23:06:50 +0100 Subject: [PATCH 4/4] Changed indenting from tabs to spaces --- blazy.js | 70 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/blazy.js b/blazy.js index 32c07b7..94a5101 100644 --- a/blazy.js +++ b/blazy.js @@ -218,12 +218,12 @@ // due to bug introduced in chrome v50 // (https://productforums.google.com/forum/#!topic/chrome/p51Lk7vnP2o) var onErrorHandler = function() { - if(parentCallback) { - parentCallback(true); - } else { - if (options.error) options.error(ele, "invalid"); + if(parentCallback) { + parentCallback(true); + } else { + if (options.error) options.error(ele, "invalid"); } - addClass(ele, options.errorClass); + addClass(ele, options.errorClass); unbindEvent(img, 'error', onErrorHandler); unbindEvent(img, 'load', onLoadHandler); }; @@ -238,7 +238,7 @@ ele.style.backgroundImage = 'url("' + src + '")'; } itemLoaded(ele, options, !parentCallback); - if(parentCallback) parentCallback(false); + if(parentCallback) parentCallback(false); unbindEvent(img, 'load', onLoadHandler); unbindEvent(img, 'error', onErrorHandler); }; @@ -256,38 +256,38 @@ } else { // An item with src like iframe, unity games, simpel video etc ele.src = src; - if(equal(ele, 'source')) { - parent.load(); - } + if(equal(ele, 'source')) { + parent.load(); + } itemLoaded(ele, options, !parentCallback); - if(parentCallback) parentCallback(false); + if(parentCallback) parentCallback(false); } } else { // a wrapper with tags inside that should be loaded at once - var childElements = ele.querySelectorAll('[data-src]'); - if(childElements) { - var counter = 0; - var errorFlag = false; - var childElementLoaded = function(failure) { - counter++; - if(failure) errorFlag = failure; - if(counter == childElements.length) { - //if single elements couldn't be loaded and an error handling is specified, raise an error - //otherwise proceed with success - if(errorFlag == true && options.error) { - options.error(ele, "invalid"); - addClass(ele, options.errorClass); - } else { - itemLoaded(ele, options, true, !errorFlag); - } - } - }; - for(var i = 0; i < childElements.length; i++) { - loadElement(childElements[i], force, options, childElementLoaded); - } - } else { - if (options.error) options.error(ele, "missing"); - addClass(ele, options.errorClass); - } + var childElements = ele.querySelectorAll('[data-src]'); + if(childElements) { + var counter = 0; + var errorFlag = false; + var childElementLoaded = function(failure) { + counter++; + if(failure) errorFlag = failure; + if(counter == childElements.length) { + //if single elements couldn't be loaded and an error handling is specified, raise an error + //otherwise proceed with success + if(errorFlag == true && options.error) { + options.error(ele, "invalid"); + addClass(ele, options.errorClass); + } else { + itemLoaded(ele, options, true, !errorFlag); + } + } + }; + for(var i = 0; i < childElements.length; i++) { + loadElement(childElements[i], force, options, childElementLoaded); + } + } else { + if (options.error) options.error(ele, "missing"); + addClass(ele, options.errorClass); + } } } }