/*! echo-js v1.7.3 | (c) 2016 @toddmotto | https://github.com/toddmotto/echo */ /*global define */ /*global module */ (function (root, factory) { if (typeof define === "function" && define.amd) { define(function() { return factory(root); }); } else if (typeof exports === "object") { module.exports = factory; } else { root.echo = factory(root); } })(this, function (root) { "use strict"; let echo = {}; let callback = function () {}; let offset, poll, delay, useDebounce, unload; let isHidden = function (element) { return (element.offsetParent === null); }; let inView = function (element, view) { if (isHidden(element)) { return false; } let box = element.getBoundingClientRect(); return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b); }; let debounceOrThrottle = function () { if(!useDebounce && !!poll) { return; } clearTimeout(poll); poll = setTimeout(function(){ echo.render(); poll = null; }, delay); }; echo.init = function (opts) { opts = opts || {}; let offsetAll = opts.offset || 0; let offsetVertical = opts.offsetVertical || offsetAll; let offsetHorizontal = opts.offsetHorizontal || offsetAll; let optionToInt = function (opt, fallback) { return parseInt(opt || fallback, 10); }; offset = { t: optionToInt(opts.offsetTop, offsetVertical), b: optionToInt(opts.offsetBottom, offsetVertical), l: optionToInt(opts.offsetLeft, offsetHorizontal), r: optionToInt(opts.offsetRight, offsetHorizontal) }; delay = optionToInt(opts.throttle, 250); useDebounce = opts.debounce !== false; unload = !!opts.unload; callback = opts.callback || callback; echo.render(); if (document.addEventListener) { root.addEventListener("scroll", debounceOrThrottle, false); root.addEventListener("load", debounceOrThrottle, false); } else { root.attachEvent("onscroll", debounceOrThrottle); root.attachEvent("onload", debounceOrThrottle); } }; echo.render = function (context) { let nodes = (context || document).querySelectorAll("[data-echo], [data-echo-background]"); let length = nodes.length; let src, elem; let view = { l: 0 - offset.l, t: 0 - offset.t, b: (root.innerHeight || document.documentElement.clientHeight) + offset.b, r: (root.innerWidth || document.documentElement.clientWidth) + offset.r }; for (let i = 0; i < length; i++) { elem = nodes[i]; if (inView(elem, view)) { if (unload) { elem.setAttribute("data-echo-placeholder", elem.src); } if (elem.getAttribute("data-echo-background") !== null) { elem.style.backgroundImage = "url(" + elem.getAttribute("data-echo-background") + ")"; } else if (elem.src !== (src = elem.getAttribute("data-echo"))) { elem.src = src; } if (!unload) { elem.removeAttribute("data-echo"); elem.removeAttribute("data-echo-background"); } callback(elem, "load"); } else if (unload && !!(src = elem.getAttribute("data-echo-placeholder"))) { if (elem.getAttribute("data-echo-background") !== null) { elem.style.backgroundImage = "url(" + src + ")"; } else { elem.src = src; } elem.removeAttribute("data-echo-placeholder"); callback(elem, "unload"); } } if (!length) { echo.detach(); } }; echo.detach = function () { if (document.removeEventListener) { root.removeEventListener("scroll", debounceOrThrottle); } else { root.detachEvent("onscroll", debounceOrThrottle); } clearTimeout(poll); }; return echo; });