Skip to content

Instantly share code, notes, and snippets.

@wvega
Created November 9, 2010 01:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wvega/668585 to your computer and use it in GitHub Desktop.
Save wvega/668585 to your computer and use it in GitHub Desktop.
jQuery LazyLoad
(function($, window){
$.LazyLoader = function(elements, options) {
var self = this;
self.elements = elements;
self.timeout = null;
self.options = $.extend({}, self.defaults, options);
window.bind('scroll.lazyload', function(event) {
// clearTimeout(self.timeout);
// self.timeout = setTimeout(function() {
//// console.log(self.count, 'scroll, scroll, scroll...'); self.check();
// }, 100);
self.check();
});
// LazyLoad
// ========
//
// 1. hide elements.
// 2. place an anchor to mark the position of hidden elements
//
if (self.elements) {
self.elements.hide().each(function() {
self.mark($(this));
});
}
}
$.extend($.LazyLoader.prototype, {
/**
* Default options
*
* speed: animation speed.
* delay: wait time in miliseconds before the animation starts.
* */
defaults: {
speed: 1200,
delay: 1
},
/**
* Inserts an A element at the position where the original element was
* placed to mark where the content should be lazy loaded.
*
* Hidden elements do not have a position (top, left) between the document
* so, without the A element would be impossible to know when the user
* reaches the element.
*
* @param element The element to be lazy loaded
*/
mark: function(element) {
var a = $('<a href="#"></a>').css({display: 'block', width: 0, height: 0});
element.before(a).data('anchor', a);
},
/**
* Returns the coordinates of a rectangle which (virtually) contains all
* the visible section of the document.
*/
bounds: function() {
return {
x: {min: window.scrollLeft(), max: window.scrollLeft() + window.width()},
y: {min: window.scrollTop(), max: window.scrollTop() + window.height()},
w: window.width(),
h: window.height()
}
},
/**
* Loops through the set of elements looking for candidates to be exposed.
*
* The candidates are elements whose position lays between the
* coordinates of the current visible section of the documen.
*/
check: function() {
var self = this, bounds = self.bounds(window);
// checks if any element should be exposed
self.elements.each(function() {
self.expose($(this), this, bounds);
});
// remove elements already exposed
self.elements = $($.grep(self.elements, function(element) {
return !$(element).data('exposed');
}));
// stop listening for scroll event if there are no more elements to
// load
console.log('checking...')
if (self.elements.length == 0) {
console.log('now we are empty...');
window.unbind('scroll.lazyload');
}
},
/**
* Checks if a jQuery element is positioned within the viewport and then,
* if it actually is, fades in the content.
*
* @param element A jQuery object containing the DOM element
* @param node The DOM element
*/
expose: function(element, node, bounds) {
if (element.data('exposed')) { return; }
var self = this, a = element.data('anchor'), offset = a.offset();
if (offset.top > bounds.y.min && offset.top < bounds.y.max && offset.left > bounds.x.min && offset.left < bounds.x.max) {
element.data('exposed', true);
setTimeout(function() {
element.fadeIn(self.options.speed, function() {
a.remove();
});
}, self.options.delay);
}
}
});
$.fn.lazyload = function(options) {
if ($.LazyLoader.instance) {
$.LazyLoader.instance.add(this, options);
} else {
new $.LazyLoader(this, options);
}
return this;
}
$(function(){
$('.lazy').lazyload();
});
})(jQuery, $(window));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment