From b1ad876debe28591c6e49c06abd45e971cc02902 Mon Sep 17 00:00:00 2001 From: dclovec Date: Wed, 4 May 2016 13:48:17 +0800 Subject: [PATCH] add one config named "container"(scroll element) default scroll element is body element, add the "container" config to set scroll element. --- src/echo.js | 279 +++++++++++++++++++++++++++------------------------- 1 file changed, 145 insertions(+), 134 deletions(-) diff --git a/src/echo.js b/src/echo.js index f307e8f..3232903 100644 --- a/src/echo.js +++ b/src/echo.js @@ -1,134 +1,145 @@ -(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'; - - var echo = {}; - - var callback = function () {}; - - var offset, poll, delay, useDebounce, unload; - - var isHidden = function (element) { - return (element.offsetParent === null); - }; - - var inView = function (element, view) { - if (isHidden(element)) { - return false; - } - - var box = element.getBoundingClientRect(); - return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b); - }; - - var debounceOrThrottle = function () { - if(!useDebounce && !!poll) { - return; - } - clearTimeout(poll); - poll = setTimeout(function(){ - echo.render(); - poll = null; - }, delay); - }; - - echo.init = function (opts) { - opts = opts || {}; - var offsetAll = opts.offset || 0; - var offsetVertical = opts.offsetVertical || offsetAll; - var offsetHorizontal = opts.offsetHorizontal || offsetAll; - var 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 () { - var nodes = document.querySelectorAll('img[data-echo], [data-echo-background]'); - var length = nodes.length; - var src, elem; - var 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 (var 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 { - elem.src = elem.getAttribute('data-echo'); - } - - 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; - -}); +(function (window, factory) { + if (typeof define === 'function' && define.amd) { + define(function() { + return factory(); + }); + } else if (typeof exports === 'object') { + module.exports = factory; + } else { + window.echo = factory(); + } +})(window, function () { + + 'use strict'; + + var echo = {}; + + var callback = function () {}; + + var offset, poll, delay, useDebounce, unload, container, scrollListenElement; + + var isHidden = function (element) { + return (element.offsetParent === null); + }; + + var inView = function (element, view) { + if (isHidden(element)) { + return false; + } + + var box = element.getBoundingClientRect(); + return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b); + }; + + var debounceOrThrottle = function () { + if(!useDebounce && !!poll) { + return; + } + clearTimeout(poll); + poll = setTimeout(function(){ + echo.render(); + poll = null; + }, delay); + }; + + echo.init = function (opts) { + opts = opts || {}; + var offsetAll = opts.offset || 0; + var offsetVertical = opts.offsetVertical || offsetAll; + var offsetHorizontal = opts.offsetHorizontal || offsetAll; + var optionToInt = function (opt, fallback) { + return parseInt(opt || fallback, 10); + }; + var bodyElement=document.body; + container = opts.container || bodyElement; + scrollListenElement = (container!==bodyElement) ? container : window; + 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);*/ + scrollListenElement.addEventListener('scroll', debounceOrThrottle, false); + window.addEventListener('load', debounceOrThrottle, false); + } else { + /*root.attachEvent('onscroll', debounceOrThrottle); + root.attachEvent('onload', debounceOrThrottle);*/ + scrollListenElement.attachEvent('onscroll', debounceOrThrottle); + window.attachEvent('onload', debounceOrThrottle); + } + }; + + echo.render = function () { + var nodes = document.querySelectorAll('img[data-echo], [data-echo-background]'); + var length = nodes.length; + var src, elem; + var 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*/ + b: container.clientHeight + offset.b, + r: container.clientWidth + offset.r + }; + for (var 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 { + elem.src = elem.getAttribute('data-echo'); + } + + 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);*/ + window.removeEventListener('scroll', debounceOrThrottle); + } else { + /*root.detachEvent('onscroll', debounceOrThrottle);*/ + window.detachEvent('onscroll', debounceOrThrottle); + } + clearTimeout(poll); + }; + + return echo; + +}); \ No newline at end of file