Created
October 22, 2012 14:39
-
-
Save miloplacencia/3931803 to your computer and use it in GitHub Desktop.
lazyload.js (c) Lorenzo Giuliani
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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); |
Much like pocketjoso before, I realize this code hasn't been touched in a few years, but here's a few lines I added so that images with "lazy" class but no "data-src" are ignored and de-classed. Not doing so could result in a bunch of www.domain.com/null unwanted calls.
This
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;
}
Would become
function loadImage (el, fn) {
var img = new Image()
, src = el.getAttribute('data-src');
if (!src) {
el.className = el.className.replace(/(^|\s)lazy(\s|$)/i, ' ');
return;
}
img.onload = function() {
if (!! el.parent)
el.parent.replaceChild(img, el)
else
el.src = src;
fn? fn() : null;
}
img.src = src;
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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:
The second parameter of the splice call should be
1
and noti
- because you only want to remove thei
element from the array, right? Noti
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:
I did something else for my purpose, but I think something like this should work for a general case.