From 5a87f4867ef66339b0af7139c668ac3f2a2705bc Mon Sep 17 00:00:00 2001 From: RaphaelEidus Date: Wed, 26 Mar 2014 11:33:07 -0400 Subject: [PATCH 1/7] add the ability to unload images after they have scrolled out of view --- dist/echo.js | 74 ++++++++++++++++++++++++++++++++++++------------ dist/echo.min.js | 2 +- src/echo.js | 74 ++++++++++++++++++++++++++++++++++++------------ 3 files changed, 113 insertions(+), 37 deletions(-) diff --git a/dist/echo.js b/dist/echo.js index ae82751..cf21afe 100644 --- a/dist/echo.js +++ b/dist/echo.js @@ -4,15 +4,21 @@ window.Echo = (function (global, document, undefined) { 'use strict'; /** - * store + * toBeLoaded * @type {Array} */ - var store = []; + var toBeLoaded = []; /** - * offset, throttle, poll vars + * toBeUnloaded + * @type {Array} + */ + var toBeUnloaded = []; + + /** + * offset, offsetTop throttle, poll, unload vars */ - var offset, throttle, poll; + var offset, offsetTop, throttle, poll, unload; /** * _inView @@ -22,7 +28,9 @@ window.Echo = (function (global, document, undefined) { */ var _inView = function (element) { var coords = element.getBoundingClientRect(); - return ((coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + offset); + var topInView = coords.top >= 0 && coords.left >= 0 && coords.top <= (window.innerHeight || document.documentElement.clientHeight) + offset && coords.top >= -1 * offsetTop; + var botInView = coords.bottom >= -1 * offsetTop && coords.left >= 0 && coords.bottom <= (window.innerHeight || document.documentElement.clientHeight) + offset; + return topInView || botInView; }; /** @@ -31,24 +39,39 @@ window.Echo = (function (global, document, undefined) { * @private */ var _pollImages = function () { - var length = store.length; - if (length > 0) { - for (var i = 0; i < length; i++) { - var self = store[i]; + var loadingLength = toBeLoaded.length, + unloadingLength, + i, + self; + if (loadingLength > 0) { + for (i = 0; i < loadingLength; i++) { + self = toBeLoaded[i]; if (self && _inView(self)) { self.src = self.getAttribute('data-echo'); - store.splice(i, 1); - length = store.length; + toBeLoaded.splice(i, 1); + loadingLength = toBeLoaded.length; i--; + if(unload) { + toBeUnloaded.push(self); + } } } - } else { - if (document.removeEventListener) { - global.removeEventListener('scroll', _throttle); - } else { - global.detachEvent('onscroll', _throttle); + } + unloadingLength = toBeUnloaded.length; + if (unloadingLength > 0) { + for(i = 0; i < unloadingLength; i++) { + self = toBeUnloaded[i]; + if (self && !_inView(self)) { + self.src = self.getAttribute('data-echo-holder'); + toBeUnloaded.splice(i, 1); + unloadingLength = toBeUnloaded.length; + i--; + toBeLoaded.push(self); + } } - clearTimeout(poll); + } + if(unloadingLength === 0 && loadingLength === 0) { + detach(); } }; @@ -72,10 +95,12 @@ window.Echo = (function (global, document, undefined) { var nodes = document.querySelectorAll('[data-echo]'); var opts = obj || {}; offset = parseInt(opts.offset || 0); + offsetTop = parseInt(opts.offsetTop || offset); throttle = parseInt(opts.throttle || 250); + unload = !!opts.unload; for (var i = 0; i < nodes.length; i++) { - store.push(nodes[i]); + toBeLoaded.push(nodes[i]); } _pollImages(); @@ -90,12 +115,25 @@ window.Echo = (function (global, document, undefined) { }; + /** + * detach remove listeners + */ + var detach = function() { + if (document.removeEventListener) { + global.removeEventListener('scroll', _throttle); + } else { + global.detachEvent('onscroll', _throttle); + } + clearTimeout(poll); + }; + /** * return Public methods * @returns {Object} */ return { init: init, + detach: detach, render: _pollImages }; diff --git a/dist/echo.min.js b/dist/echo.min.js index f736f12..1e0f2c1 100644 --- a/dist/echo.min.js +++ b/dist/echo.min.js @@ -1,2 +1,2 @@ /*! Echo v1.5.0 | (c) 2014 @toddmotto | MIT license | github.com/toddmotto/echo */ -window.Echo=function(a,b){"use strict";var c,d,e,f=[],g=function(a){var d=a.getBoundingClientRect();return(d.top>=0&&d.left>=0&&d.top)<=(window.innerHeight||b.documentElement.clientHeight)+c},h=function(){var c=f.length;if(c>0)for(var d=0;c>d;d++){var h=f[d];h&&g(h)&&(h.src=h.getAttribute("data-echo"),f.splice(d,1),c=f.length,d--)}else b.removeEventListener?a.removeEventListener("scroll",i):a.detachEvent("onscroll",i),clearTimeout(e)},i=function(){clearTimeout(e),e=setTimeout(h,d)},j=function(e){var g=b.querySelectorAll("[data-echo]"),j=e||{};c=parseInt(j.offset||0),d=parseInt(j.throttle||250);for(var k=0;k=0&&e.left>=0&&e.top<=(window.innerHeight||b.documentElement.clientHeight)+c&&e.top>=-1*d,g=e.bottom>=-1*d&&e.left>=0&&e.bottom<=(window.innerHeight||b.documentElement.clientHeight)+c;return f||g},k=function(){var a,b,c,d=h.length;if(d>0)for(b=0;d>b;b++)c=h[b],c&&j(c)&&(c.src=c.getAttribute("data-echo"),h.splice(b,1),d=h.length,b--,g&&i.push(c));if(a=i.length,a>0)for(b=0;a>b;b++)c=i[b],c&&!j(c)&&(c.src=c.getAttribute("data-echo-holder"),i.splice(b,1),a=i.length,b--,h.push(c));0===a&&0===d&&n()},l=function(){clearTimeout(f),f=setTimeout(k,e)},m=function(f){var i=b.querySelectorAll("[data-echo]"),j=f||{};c=parseInt(j.offset||0),d=parseInt(j.offsetTop||c),e=parseInt(j.throttle||250),g=!!j.unload;for(var m=0;m= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + offset); + var topInView = coords.top >= 0 && coords.left >= 0 && coords.top <= (window.innerHeight || document.documentElement.clientHeight) + offset && coords.top >= -1 * offsetTop; + var botInView = coords.bottom >= -1 * offsetTop && coords.left >= 0 && coords.bottom <= (window.innerHeight || document.documentElement.clientHeight) + offset; + return topInView || botInView; }; /** @@ -30,24 +38,39 @@ window.Echo = (function (global, document, undefined) { * @private */ var _pollImages = function () { - var length = store.length; - if (length > 0) { - for (var i = 0; i < length; i++) { - var self = store[i]; + var loadingLength = toBeLoaded.length, + unloadingLength, + i, + self; + if (loadingLength > 0) { + for (i = 0; i < loadingLength; i++) { + self = toBeLoaded[i]; if (self && _inView(self)) { self.src = self.getAttribute('data-echo'); - store.splice(i, 1); - length = store.length; + toBeLoaded.splice(i, 1); + loadingLength = toBeLoaded.length; i--; + if(unload) { + toBeUnloaded.push(self); + } } } - } else { - if (document.removeEventListener) { - global.removeEventListener('scroll', _throttle); - } else { - global.detachEvent('onscroll', _throttle); + } + unloadingLength = toBeUnloaded.length; + if (unloadingLength > 0) { + for(i = 0; i < unloadingLength; i++) { + self = toBeUnloaded[i]; + if (self && !_inView(self)) { + self.src = self.getAttribute('data-echo-holder'); + toBeUnloaded.splice(i, 1); + unloadingLength = toBeUnloaded.length; + i--; + toBeLoaded.push(self); + } } - clearTimeout(poll); + } + if(unloadingLength === 0 && loadingLength === 0) { + detach(); } }; @@ -71,10 +94,12 @@ window.Echo = (function (global, document, undefined) { var nodes = document.querySelectorAll('[data-echo]'); var opts = obj || {}; offset = parseInt(opts.offset || 0); + offsetTop = parseInt(opts.offsetTop || offset); throttle = parseInt(opts.throttle || 250); + unload = !!opts.unload; for (var i = 0; i < nodes.length; i++) { - store.push(nodes[i]); + toBeLoaded.push(nodes[i]); } _pollImages(); @@ -89,12 +114,25 @@ window.Echo = (function (global, document, undefined) { }; + /** + * detach remove listeners + */ + var detach = function() { + if (document.removeEventListener) { + global.removeEventListener('scroll', _throttle); + } else { + global.detachEvent('onscroll', _throttle); + } + clearTimeout(poll); + }; + /** * return Public methods * @returns {Object} */ return { init: init, + detach: detach, render: _pollImages }; From f6a56e033980292303797dfebb1a02e643de0776 Mon Sep 17 00:00:00 2001 From: RaphaelEidus Date: Wed, 26 Mar 2014 11:41:58 -0400 Subject: [PATCH 2/7] add support for defining top and bottom support independently --- dist/echo.js | 14 +++++++++----- dist/echo.min.js | 2 +- src/echo.js | 14 +++++++++----- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/dist/echo.js b/dist/echo.js index cf21afe..4a4a0df 100644 --- a/dist/echo.js +++ b/dist/echo.js @@ -16,9 +16,9 @@ window.Echo = (function (global, document, undefined) { var toBeUnloaded = []; /** - * offset, offsetTop throttle, poll, unload vars + * offsetBot, offsetTop throttle, poll, unload vars */ - var offset, offsetTop, throttle, poll, unload; + var offsetBot, offsetTop, throttle, poll, unload; /** * _inView @@ -28,8 +28,8 @@ window.Echo = (function (global, document, undefined) { */ var _inView = function (element) { var coords = element.getBoundingClientRect(); - var topInView = coords.top >= 0 && coords.left >= 0 && coords.top <= (window.innerHeight || document.documentElement.clientHeight) + offset && coords.top >= -1 * offsetTop; - var botInView = coords.bottom >= -1 * offsetTop && coords.left >= 0 && coords.bottom <= (window.innerHeight || document.documentElement.clientHeight) + offset; + var topInView = coords.top >= 0 && coords.left >= 0 && coords.top <= (window.innerHeight || document.documentElement.clientHeight) + offsetBot && coords.top >= -1 * offsetTop; + var botInView = coords.bottom >= -1 * offsetTop && coords.left >= 0 && coords.bottom <= (window.innerHeight || document.documentElement.clientHeight) + offsetBot; return topInView || botInView; }; @@ -89,12 +89,16 @@ window.Echo = (function (global, document, undefined) { * @param {Object} [obj] Passed in Object with options * @param {Number|String} [obj.throttle] * @param {Number|String} [obj.offset] + * @param {Number|String} [obj.offsetBot] + * @param {Number|String} [obj.offsetTop] + * @param {Boolean} [obj.unload] */ var init = function (obj) { var nodes = document.querySelectorAll('[data-echo]'); var opts = obj || {}; - offset = parseInt(opts.offset || 0); + var offset = parseInt(opts.offset || 0); + offsetBot = parseInt(opts.offsetBot || offset); offsetTop = parseInt(opts.offsetTop || offset); throttle = parseInt(opts.throttle || 250); unload = !!opts.unload; diff --git a/dist/echo.min.js b/dist/echo.min.js index 1e0f2c1..79e446c 100644 --- a/dist/echo.min.js +++ b/dist/echo.min.js @@ -1,2 +1,2 @@ /*! Echo v1.5.0 | (c) 2014 @toddmotto | MIT license | github.com/toddmotto/echo */ -window.Echo=function(a,b){"use strict";var c,d,e,f,g,h=[],i=[],j=function(a){var e=a.getBoundingClientRect(),f=e.top>=0&&e.left>=0&&e.top<=(window.innerHeight||b.documentElement.clientHeight)+c&&e.top>=-1*d,g=e.bottom>=-1*d&&e.left>=0&&e.bottom<=(window.innerHeight||b.documentElement.clientHeight)+c;return f||g},k=function(){var a,b,c,d=h.length;if(d>0)for(b=0;d>b;b++)c=h[b],c&&j(c)&&(c.src=c.getAttribute("data-echo"),h.splice(b,1),d=h.length,b--,g&&i.push(c));if(a=i.length,a>0)for(b=0;a>b;b++)c=i[b],c&&!j(c)&&(c.src=c.getAttribute("data-echo-holder"),i.splice(b,1),a=i.length,b--,h.push(c));0===a&&0===d&&n()},l=function(){clearTimeout(f),f=setTimeout(k,e)},m=function(f){var i=b.querySelectorAll("[data-echo]"),j=f||{};c=parseInt(j.offset||0),d=parseInt(j.offsetTop||c),e=parseInt(j.throttle||250),g=!!j.unload;for(var m=0;m=0&&e.left>=0&&e.top<=(window.innerHeight||b.documentElement.clientHeight)+c&&e.top>=-1*d,g=e.bottom>=-1*d&&e.left>=0&&e.bottom<=(window.innerHeight||b.documentElement.clientHeight)+c;return f||g},k=function(){var a,b,c,d=h.length;if(d>0)for(b=0;d>b;b++)c=h[b],c&&j(c)&&(c.src=c.getAttribute("data-echo"),h.splice(b,1),d=h.length,b--,g&&i.push(c));if(a=i.length,a>0)for(b=0;a>b;b++)c=i[b],c&&!j(c)&&(c.src=c.getAttribute("data-echo-holder"),i.splice(b,1),a=i.length,b--,h.push(c));0===a&&0===d&&n()},l=function(){clearTimeout(f),f=setTimeout(k,e)},m=function(f){var i=b.querySelectorAll("[data-echo]"),j=f||{},m=parseInt(j.offset||0);c=parseInt(j.offsetBot||m),d=parseInt(j.offsetTop||m),e=parseInt(j.throttle||250),g=!!j.unload;for(var n=0;n= 0 && coords.left >= 0 && coords.top <= (window.innerHeight || document.documentElement.clientHeight) + offset && coords.top >= -1 * offsetTop; - var botInView = coords.bottom >= -1 * offsetTop && coords.left >= 0 && coords.bottom <= (window.innerHeight || document.documentElement.clientHeight) + offset; + var topInView = coords.top >= 0 && coords.left >= 0 && coords.top <= (window.innerHeight || document.documentElement.clientHeight) + offsetBot && coords.top >= -1 * offsetTop; + var botInView = coords.bottom >= -1 * offsetTop && coords.left >= 0 && coords.bottom <= (window.innerHeight || document.documentElement.clientHeight) + offsetBot; return topInView || botInView; }; @@ -88,12 +88,16 @@ window.Echo = (function (global, document, undefined) { * @param {Object} [obj] Passed in Object with options * @param {Number|String} [obj.throttle] * @param {Number|String} [obj.offset] + * @param {Number|String} [obj.offsetBot] + * @param {Number|String} [obj.offsetTop] + * @param {Boolean} [obj.unload] */ var init = function (obj) { var nodes = document.querySelectorAll('[data-echo]'); var opts = obj || {}; - offset = parseInt(opts.offset || 0); + var offset = parseInt(opts.offset || 0); + offsetBot = parseInt(opts.offsetBot || offset); offsetTop = parseInt(opts.offsetTop || offset); throttle = parseInt(opts.throttle || 250); unload = !!opts.unload; From 9792c083519b577f9429cbd85abe26557a85eb2c Mon Sep 17 00:00:00 2001 From: RaphaelEidus Date: Wed, 26 Mar 2014 12:00:09 -0400 Subject: [PATCH 3/7] add a placeholder param --- dist/echo.js | 10 ++++++---- dist/echo.min.js | 2 +- src/echo.js | 10 ++++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/dist/echo.js b/dist/echo.js index 4a4a0df..f461f96 100644 --- a/dist/echo.js +++ b/dist/echo.js @@ -16,9 +16,9 @@ window.Echo = (function (global, document, undefined) { var toBeUnloaded = []; /** - * offsetBot, offsetTop throttle, poll, unload vars + * offsetBot, offsetTop throttle, poll, unload, placeholder vars */ - var offsetBot, offsetTop, throttle, poll, unload; + var offsetBot, offsetTop, throttle, poll, unload, placeholder; /** * _inView @@ -51,7 +51,7 @@ window.Echo = (function (global, document, undefined) { toBeLoaded.splice(i, 1); loadingLength = toBeLoaded.length; i--; - if(unload) { + if(unload && !!placeholder) { toBeUnloaded.push(self); } } @@ -62,7 +62,7 @@ window.Echo = (function (global, document, undefined) { for(i = 0; i < unloadingLength; i++) { self = toBeUnloaded[i]; if (self && !_inView(self)) { - self.src = self.getAttribute('data-echo-holder'); + self.src = placeholder; toBeUnloaded.splice(i, 1); unloadingLength = toBeUnloaded.length; i--; @@ -92,6 +92,7 @@ window.Echo = (function (global, document, undefined) { * @param {Number|String} [obj.offsetBot] * @param {Number|String} [obj.offsetTop] * @param {Boolean} [obj.unload] + * @param {String} [obj.placeholder] */ var init = function (obj) { @@ -102,6 +103,7 @@ window.Echo = (function (global, document, undefined) { offsetTop = parseInt(opts.offsetTop || offset); throttle = parseInt(opts.throttle || 250); unload = !!opts.unload; + placeholder = opts.placeholder; for (var i = 0; i < nodes.length; i++) { toBeLoaded.push(nodes[i]); diff --git a/dist/echo.min.js b/dist/echo.min.js index 79e446c..cdf8bb9 100644 --- a/dist/echo.min.js +++ b/dist/echo.min.js @@ -1,2 +1,2 @@ /*! Echo v1.5.0 | (c) 2014 @toddmotto | MIT license | github.com/toddmotto/echo */ -window.Echo=function(a,b){"use strict";var c,d,e,f,g,h=[],i=[],j=function(a){var e=a.getBoundingClientRect(),f=e.top>=0&&e.left>=0&&e.top<=(window.innerHeight||b.documentElement.clientHeight)+c&&e.top>=-1*d,g=e.bottom>=-1*d&&e.left>=0&&e.bottom<=(window.innerHeight||b.documentElement.clientHeight)+c;return f||g},k=function(){var a,b,c,d=h.length;if(d>0)for(b=0;d>b;b++)c=h[b],c&&j(c)&&(c.src=c.getAttribute("data-echo"),h.splice(b,1),d=h.length,b--,g&&i.push(c));if(a=i.length,a>0)for(b=0;a>b;b++)c=i[b],c&&!j(c)&&(c.src=c.getAttribute("data-echo-holder"),i.splice(b,1),a=i.length,b--,h.push(c));0===a&&0===d&&n()},l=function(){clearTimeout(f),f=setTimeout(k,e)},m=function(f){var i=b.querySelectorAll("[data-echo]"),j=f||{},m=parseInt(j.offset||0);c=parseInt(j.offsetBot||m),d=parseInt(j.offsetTop||m),e=parseInt(j.throttle||250),g=!!j.unload;for(var n=0;n=0&&e.left>=0&&e.top<=(window.innerHeight||b.documentElement.clientHeight)+c&&e.top>=-1*d,g=e.bottom>=-1*d&&e.left>=0&&e.bottom<=(window.innerHeight||b.documentElement.clientHeight)+c;return f||g},l=function(){var a,b,c,d=i.length;if(d>0)for(b=0;d>b;b++)c=i[b],c&&k(c)&&(c.src=c.getAttribute("data-echo"),i.splice(b,1),d=i.length,b--,g&&h&&j.push(c));if(a=j.length,a>0)for(b=0;a>b;b++)c=j[b],c&&!k(c)&&(c.src=h,j.splice(b,1),a=j.length,b--,i.push(c));0===a&&0===d&&o()},m=function(){clearTimeout(f),f=setTimeout(l,e)},n=function(f){var j=b.querySelectorAll("[data-echo]"),k=f||{},n=parseInt(k.offset||0);c=parseInt(k.offsetBot||n),d=parseInt(k.offsetTop||n),e=parseInt(k.throttle||250),g=!!k.unload,h=k.placeholder;for(var o=0;o Date: Wed, 26 Mar 2014 12:23:43 -0400 Subject: [PATCH 4/7] add some documentation to README.md --- README.md | 27 ++++++++++++++++++++++++--- dist/echo.js | 3 +++ dist/echo.min.js | 2 +- src/echo.js | 3 +++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ed1c78c..b6f55ee 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,12 @@ Using Echo.js is simple, just add the image you wish to load to a `data-echo` a Photo - +