From f44cbbc28415c4a186a16a14ecb7fd0654b16d1c Mon Sep 17 00:00:00 2001 From: Raphael Eidus Date: Sun, 15 Jun 2014 09:58:15 -0400 Subject: [PATCH] implement true throttling --- README.md | 5 +++++ dist/echo.js | 31 ++++++++++++++++++++----------- dist/echo.min.js | 2 +- src/echo.js | 29 ++++++++++++++++++----------- 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index a85f1e5..9d718f9 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,11 @@ Type: `Number|String` Default: `250` The throttle is managed by an internal function that prevents performance issues from continuous firing of `window.onscroll` events. Using a throttle will set a small timeout when the user scrolls and will keep throttling until the user stops. The default is `250` milliseconds. +#### debounce +Type: `Boolean` Default: `true` + +By default the throttling function is actually a [debounce](http://underscorejs.org/#debounce) function so that the checking function is only triggered after a user stops scrolling. To use traditional throttling where it will only check the images every `throttle` milliseconds, set `debounce` to `false`. + #### unload Type: `Boolean` Default: `false` diff --git a/dist/echo.js b/dist/echo.js index d59f673..7a5efed 100644 --- a/dist/echo.js +++ b/dist/echo.js @@ -1,7 +1,9 @@ /*! echo.js v1.6.0 | (c) 2014 @toddmotto | https://github.com/toddmotto/echo */ (function (root, factory) { if (typeof define === 'function' && define.amd) { - define(factory); + define(function() { + return factory(root); + }); } else if (typeof exports === 'object') { module.exports = factory; } else { @@ -15,16 +17,22 @@ var callback = function () {}; - var offset, poll, throttle, unload; + var offset, poll, delay, useDebounce, unload; var inView = function (element, view) { var box = element.getBoundingClientRect(); return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b); }; - var debounce = function () { + var debounceOrThrottle = function () { + if(!useDebounce && !!poll) { + return; + } clearTimeout(poll); - poll = setTimeout(echo.render, throttle); + poll = setTimeout(function(){ + echo.render(); + poll = null; + }, delay); }; echo.init = function (opts) { @@ -41,16 +49,17 @@ l: optionToInt(opts.offsetLeft, offsetHorizontal), r: optionToInt(opts.offsetRight, offsetHorizontal) }; - throttle = optionToInt(opts.throttle, 250); + delay = optionToInt(opts.throttle, 250); + useDebounce = opts.debounce !== false; unload = !!opts.unload; callback = opts.callback || callback; echo.render(); if (document.addEventListener) { - root.addEventListener('scroll', debounce, false); - root.addEventListener('load', debounce, false); + root.addEventListener('scroll', debounceOrThrottle, false); + root.addEventListener('load', debounceOrThrottle, false); } else { - root.attachEvent('onscroll', debounce); - root.attachEvent('onload', debounce); + root.attachEvent('onscroll', debounceOrThrottle); + root.attachEvent('onload', debounceOrThrottle); } }; @@ -88,9 +97,9 @@ echo.detach = function () { if (document.removeEventListener) { - root.removeEventListener('scroll', debounce); + root.removeEventListener('scroll', debounceOrThrottle); } else { - root.detachEvent('onscroll', debounce); + root.detachEvent('onscroll', debounceOrThrottle); } clearTimeout(poll); }; diff --git a/dist/echo.min.js b/dist/echo.min.js index e8d3f84..d654ac5 100644 --- a/dist/echo.min.js +++ b/dist/echo.min.js @@ -1,2 +1,2 @@ /*! echo.js v1.6.0 | (c) 2014 @toddmotto | https://github.com/toddmotto/echo */ -!function(t,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e:t.echo=e(t)}(this,function(t){"use strict";var e,o,n,r,c={},i=function(){},a=function(t,e){var o=t.getBoundingClientRect();return o.right>=e.l&&o.bottom>=e.t&&o.left<=e.r&&o.top<=e.b},d=function(){clearTimeout(o),o=setTimeout(c.render,n)};return c.init=function(o){o=o||{};var a=o.offset||0,l=o.offsetVertical||a,u=o.offsetHorizontal||a,f=function(t,e){return parseInt(t||e,10)};e={t:f(o.offsetTop,l),b:f(o.offsetBottom,l),l:f(o.offsetLeft,u),r:f(o.offsetRight,u)},n=f(o.throttle,250),r=!!o.unload,i=o.callback||i,c.render(),document.addEventListener?(t.addEventListener("scroll",d,!1),t.addEventListener("load",d,!1)):(t.attachEvent("onscroll",d),t.attachEvent("onload",d))},c.render=function(){for(var o,n,d=document.querySelectorAll("img[data-echo]"),l=d.length,u={l:0-e.l,t:0-e.t,b:(t.innerHeight||document.documentElement.clientHeight)+e.b,r:(t.innerWidth||document.documentElement.clientWidth)+e.r},f=0;l>f;f++)n=d[f],a(n,u)?(r&&n.setAttribute("data-echo-placeholder",n.src),n.src=n.getAttribute("data-echo"),r||n.removeAttribute("data-echo"),i(n,"load")):r&&(o=n.getAttribute("data-echo-placeholder"))&&(n.src=o,n.removeAttribute("data-echo-placeholder"),i(n,"unload"));l||c.detach()},c.detach=function(){document.removeEventListener?t.removeEventListener("scroll",d):t.detachEvent("onscroll",d),clearTimeout(o)},c}); \ No newline at end of file +!function(t,e){"function"==typeof define&&define.amd?define(function(){return e(t)}):"object"==typeof exports?module.exports=e:t.echo=e(t)}(this,function(t){"use strict";var e,n,o,r,c,i={},l=function(){},a=function(t,e){var n=t.getBoundingClientRect();return n.right>=e.l&&n.bottom>=e.t&&n.left<=e.r&&n.top<=e.b},d=function(){(r||!n)&&(clearTimeout(n),n=setTimeout(function(){i.render(),n=null},o))};return i.init=function(n){n=n||{};var a=n.offset||0,u=n.offsetVertical||a,f=n.offsetHorizontal||a,s=function(t,e){return parseInt(t||e,10)};e={t:s(n.offsetTop,u),b:s(n.offsetBottom,u),l:s(n.offsetLeft,f),r:s(n.offsetRight,f)},o=s(n.throttle,250),r=n.debounce!==!1,c=!!n.unload,l=n.callback||l,i.render(),document.addEventListener?(t.addEventListener("scroll",d,!1),t.addEventListener("load",d,!1)):(t.attachEvent("onscroll",d),t.attachEvent("onload",d))},i.render=function(){for(var n,o,r=document.querySelectorAll("img[data-echo]"),d=r.length,u={l:0-e.l,t:0-e.t,b:(t.innerHeight||document.documentElement.clientHeight)+e.b,r:(t.innerWidth||document.documentElement.clientWidth)+e.r},f=0;d>f;f++)o=r[f],a(o,u)?(c&&o.setAttribute("data-echo-placeholder",o.src),o.src=o.getAttribute("data-echo"),c||o.removeAttribute("data-echo"),l(o,"load")):c&&(n=o.getAttribute("data-echo-placeholder"))&&(o.src=n,o.removeAttribute("data-echo-placeholder"),l(o,"unload"));d||i.detach()},i.detach=function(){document.removeEventListener?t.removeEventListener("scroll",d):t.detachEvent("onscroll",d),clearTimeout(n)},i}); \ No newline at end of file diff --git a/src/echo.js b/src/echo.js index 5552e14..5b14b29 100644 --- a/src/echo.js +++ b/src/echo.js @@ -1,7 +1,7 @@ (function (root, factory) { if (typeof define === 'function' && define.amd) { define(function() { - return factory(root) + return factory(root); }); } else if (typeof exports === 'object') { module.exports = factory; @@ -16,16 +16,22 @@ var callback = function () {}; - var offset, poll, throttle, unload; + var offset, poll, delay, useDebounce, unload; var inView = function (element, view) { var box = element.getBoundingClientRect(); return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b); }; - var debounce = function () { + var debounceOrThrottle = function () { + if(!useDebounce && !!poll) { + return; + } clearTimeout(poll); - poll = setTimeout(echo.render, throttle); + poll = setTimeout(function(){ + echo.render(); + poll = null; + }, delay); }; echo.init = function (opts) { @@ -42,16 +48,17 @@ l: optionToInt(opts.offsetLeft, offsetHorizontal), r: optionToInt(opts.offsetRight, offsetHorizontal) }; - throttle = optionToInt(opts.throttle, 250); + delay = optionToInt(opts.throttle, 250); + useDebounce = opts.debounce !== false; unload = !!opts.unload; callback = opts.callback || callback; echo.render(); if (document.addEventListener) { - root.addEventListener('scroll', debounce, false); - root.addEventListener('load', debounce, false); + root.addEventListener('scroll', debounceOrThrottle, false); + root.addEventListener('load', debounceOrThrottle, false); } else { - root.attachEvent('onscroll', debounce); - root.attachEvent('onload', debounce); + root.attachEvent('onscroll', debounceOrThrottle); + root.attachEvent('onload', debounceOrThrottle); } }; @@ -89,9 +96,9 @@ echo.detach = function () { if (document.removeEventListener) { - root.removeEventListener('scroll', debounce); + root.removeEventListener('scroll', debounceOrThrottle); } else { - root.detachEvent('onscroll', debounce); + root.detachEvent('onscroll', debounceOrThrottle); } clearTimeout(poll); };