Here is a solution that lazy loads images when they come within 500px of view. It can be adapted to load other types of content. The images themselves have an attribute data-lazy="http://..."
with the image url in it, and then we just put a dummy transparent image for the src
attribute.
var pixelLoadOffset = 500;
var debouncedScroll = debounce(function () {
var els = app.getSelector(el, 'img[data-lazy]');
if (!els.length) {
$(window).unbind('scroll', debouncedScroll);
return;
}
var wt = $(window).scrollTop(); //* top of the window
var wb = wt + $(window).height(); //* bottom of the window
els.each(function () {
var $this = $(this);
var ot = $this.offset().top; //* top of object
var ob = ot + $this.height(); //* bottom of object
if (wt <= ob + pixelLoadOffset && wb >= ot - pixelLoadOffset) {
$this.attr('src', $this.attr('data-lazy')).removeAttr('data-lazy');
}
});
}, 100);
$(window).bind('scroll', debouncedScroll);
The debounce function I'm using is as follows:
function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this, args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function () {
timeout = null;
if (!immediate) func.apply(context, args);
}, wait);
if (immediate && !timeout) func.apply(context, args);
};
}
You need to keep in mind that this isn't very effective on iOS, as the scroll event doesn't fire until after the user has finished scrolling, by which time they will already have seen the blank content.