Browse Source

fix issue #83 (Image Inside a Scrollable div Would not be Loaded)

pull/84/head
ethonchan 10 years ago
parent
commit
86e01ee8bb
  1. 235
      src/echo.js

235
src/echo.js

@ -1,135 +1,134 @@
(function (root, factory) { (function() {
if (typeof define === 'function' && define.amd) { 'use strict';
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(); var echo = {};
return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b); var _global = this || (0,eval)('this');
}; var root = {};
var debounceOrThrottle = function () { var callback = function () {
if(!useDebounce && !!poll) {
return;
}
clearTimeout(poll);
poll = setTimeout(function(){
echo.render();
poll = null;
}, delay);
};
echo.init = function (opts) {
opts = opts || {};
root = opts.viewport || this || (0,eval)('this');
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; var offset, poll, delay, useDebounce, unload;
unload = !!opts.unload;
callback = opts.callback || callback; var isHidden = function (element) {
echo.render(); return (element.offsetParent === null);
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) { var inView = function (element, view) {
elem.setAttribute('data-echo-placeholder', elem.src); if (isHidden(element)) {
return false;
} }
if (elem.getAttribute('data-echo-background') !== null) { var box = element.getBoundingClientRect();
elem.style.backgroundImage = "url(" + elem.getAttribute('data-echo-background') + ")"; return (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b);
} };
else {
elem.src = elem.getAttribute('data-echo');
}
if (!unload) { var debounceOrThrottle = function () {
elem.removeAttribute('data-echo'); if (!useDebounce && !!poll) {
elem.removeAttribute('data-echo-background'); return;
} }
clearTimeout(poll);
poll = setTimeout(function () {
echo.render();
poll = null;
}, delay);
};
callback(elem, 'load'); echo.init = function (opts) {
} opts = opts || {};
else if (unload && !!(src = elem.getAttribute('data-echo-placeholder'))) { root = opts.viewport || _global;
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);
}
};
if (elem.getAttribute('data-echo-background') !== null) { echo.render = function () {
elem.style.backgroundImage = "url(" + src + ")"; 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 || root.clientHeight) + offset.b,
r: (root.innerWidth || root.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');
}
} }
else { if (!length) {
elem.src = src; echo.detach();
} }
};
elem.removeAttribute('data-echo-placeholder'); echo.detach = function () {
callback(elem, 'unload'); if (document.removeEventListener) {
} root.removeEventListener('scroll', debounceOrThrottle);
} } else {
if (!length) { root.detachEvent('onscroll', debounceOrThrottle);
echo.detach(); }
} clearTimeout(poll);
}; };
echo.detach = function () { if ((typeof module !== "undefined" && module !== null) && module.exports) {
if (document.removeEventListener) { module.exports = echo;
root.removeEventListener('scroll', debounceOrThrottle); } else if (typeof define === 'function') {
define(function() {
return echo;
});
} else { } else {
root.detachEvent('onscroll', debounceOrThrottle); root.echo = echo;
} }
clearTimeout(poll); }());
};
return echo;
});
Loading…
Cancel
Save