Create a gist now

Instantly share code, notes, and snippets.

lazyload.js (c) Lorenzo Giuliani
/* lazyload.js (c) Lorenzo Giuliani
* MIT License (http://www.opensource.org/licenses/mit-license.html)
*
* expects a list of:
* `<img src="blank.gif" data-src="my_image.png" width="600" height="400" class="lazy">`
*/
!function(window){
var $q = function(q, res){
if (document.querySelectorAll) {
res = document.querySelectorAll(q);
} else {
var d=document
, a=d.styleSheets[0] || d.createStyleSheet();
a.addRule(q,'f:b');
for(var l=d.all,b=0,c=[],f=l.length;b<f;b++)
l[b].currentStyle.f && c.push(l[b]);
a.removeRule(0);
res = c;
}
return res;
}
, addEventListener = function(evt, fn){
window.addEventListener
? this.addEventListener(evt, fn, false)
: (window.attachEvent)
? this.attachEvent('on' + evt, fn)
: this['on' + evt] = fn;
}
, _has = function(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
}
;
function loadImage (el, fn) {
var img = new Image()
, src = el.getAttribute('data-src');
img.onload = function() {
if (!! el.parent)
el.parent.replaceChild(img, el)
else
el.src = src;
fn? fn() : null;
}
img.src = src;
}
function elementInViewport(el) {
var rect = el.getBoundingClientRect()
return (
rect.top >= 0
&& rect.left >= 0
&& rect.top <= (window.innerHeight || document.documentElement.clientHeight)
)
}
var images = new Array()
, query = $q('img.lazy')
, processScroll = function(){
for (var i = 0; i < images.length; i++) {
if (elementInViewport(images[i])) {
loadImage(images[i], function () {
images.splice(i, i);
});
}
};
}
;
// Array.prototype.slice.call is not callable under our lovely IE8
for (var i = 0; i < query.length; i++) {
images.push(query[i]);
};
processScroll();
addEventListener('scroll',processScroll);
}(this);
@pocketjoso

Hi, I know this code probably hasn't been touched in a while, but as I was going to use it today I realized these line are broken:

loadImage(images[i], function () {
    images.splice(i, i);
}

The second parameter of the splice call should be 1 and not i - because you only want to remove the i element from the array, right? Not i nr of elements.

By the time the splice call is made, via your loadImage callback function, your i will already be set to be the length of the whole images array - as the for loop controlling it will already have finished. You have to create another scope for your i, either by passing it in to loadImage, or perhaps just by wrapping these three line in an IIFE:

(function(i){
    loadImage(images[i], function () {
       images.splice(i, 1);
   }
}(i);
..

I did something else for my purpose, but I think something like this should work for a general case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment