Skip to content

Instantly share code, notes, and snippets.

@brigand
Created August 30, 2013 15:14
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 brigand/6390896 to your computer and use it in GitHub Desktop.
Save brigand/6390896 to your computer and use it in GitHub Desktop.
(function ($, root) {
var DEBUG = true;
var queue = [], waitingFor = 0, pagesComplete = 0, pagesStarted = 0;
var inteliscroll = function (options) {
var opts = $.extend({}, inteliscroll['defaults'], options);
var pagesToLoadAtOnce = opts.startPages, lastPage = 0;
var $root = $(window);
// our image template needs to have an img in it
if (DEBUG && this.find('img').length === 0) {
throw new Error(this.selector + " must have an img child element. " +
"Remember to call the inteliscroll method of the template.");
}
var $imageTemplate = $(this).clone();
var $parent = $(this).parent();
// remove the template from the page because we have a copy of it
$(this).remove();
function loadNextPages() {
var $children = $parent.children(), count;
if ($children.length > 1) {
// first we need to see how many images take up a page
// this could be restricted to happening once, but if a browser resizes
// it would mess everything up (e.g. zoom in, portrait <-> landscape)
var $child, lastTop, tallestOfRow = 0, rootHeight = $root.height();
// loop through children
// TODO: optimize this, with performance tests on multiple browsers
for (count = 0; $child = $children.eq(count); count++) {
var top = $child.offset().top;
// are we on the next row?
if (top !== lastTop) {
// we're done here when we've reached one pageful
if (top > rootHeight * pagesToLoadAtOnce) {
break;
}
}
var height = $child.height();
tallestOfRow = Math.max(tallestOfRow, height);
lastTop = top;
}
}
else {
count = 30;
}
pagesStarted += pagesToLoadAtOnce;
// this both gets us an array of `count` urls, and removes theme from
// the queue
var urls = queue.splice(0, count);
// count now holds the number of images we want to load
// now start
for (var i = 0; i < urls.length; i++) {
var $img = $imageTemplate.clone();
$img.load(imageLoadCallback);
$img.find('img').attr('src', urls[i]);
$parent.append($img);
}
}
$root.scroll(function () {
var pageHeight = $root.height();
var scrollBottom = $root.scrollTop() + pageHeight;
// FIXME: this doesn't handle $root being anything other than $root
var contentsHeight = document.body.clientHeight;
var currentPage = Math.floor(scrollBottom / pageHeight - 1);
if (pagesStarted <= currentPage + (pagesToLoadAtOnce * 3) || contentsHeight < scrollBottom + 100) {
lastPage = currentPage;
setTimeout(loadNextPages, 1);
}
});
setTimeout(loadNextPages, 1);
};
function imageLoadCallback() {
waitingFor--;
if (waitingFor <= 0) {
}
}
/**
* Adds a single url to the queue
* @param url
* @returns {*}
*/
var addImage = function (url) {
if (DEBUG && typeof url !== "string") {
throw new Error("You're trying to add " + url + " to inteliscroll");
}
queue.push("" + url);
return this;
};
/**
* Add images to the queue, which will be accessed when needed
* @param urls an array of urls
* @returns {*}
*/
var addImages = function (urls) {
if (DEBUG) {
if (urls == null || urls.constructor !== Array) {
var type = urls ? urls.constructor.name : "null/undefined";
throw new Error("you passed a " + type + " to inteliscroll.addImages");
}
for (var i = 0; i < urls.length; i++) {
var url = urls[i];
if (typeof url !== "string") {
var type = urls ? urls.constructor.name : "null/undefined";
throw new Error("when calling inteliscroll.addImages, the url at index "
+ i + " is a(n) " + type + ". Strng expected");
}
}
}
queue = queue.concat(urls);
return this;
};
// exports
$['fn']['inteliscroll'] = inteliscroll;
$['inteliscroll'] = function (element, options) {
// $.inteliscroll('#foo', {}) === $('#foo').inteliscroll({})
// we use call to ensure `this` will be set correctly in both cases
return inteliscroll.call($(element), options);
}
inteliscroll['addImage'] = addImage;
inteliscroll['addImages'] = addImages;
inteliscroll['defaults'] = {
startPages: 3,
maxPages: 5,
root: 'window',
afterLoad: $.noop,
beforeLoad: $.noop,
shouldLoad: $.noop
};
})(jQuery, this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment