Created
August 30, 2013 15:14
-
-
Save brigand/6390896 to your computer and use it in GitHub Desktop.
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
(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