💄 refactor infinite scroll (#325)
closes #321, closes #323 - use `requestAnimationFrame` and related techniques to minimise scroll processing - add an `isLoading` guard to ensure we don't try to process anything until the next page has been loaded+inserted - check for a 404 as an indication we've loaded as many pages as possible at which point the scroll behaviour is removed - sanitize `window.location.pathname` to remove hash params and any double-slashes that may result - add a 100px buffer from the bottom of the screen so that it's not necessary to exactly hit the bottom before infinite loading is triggered
This commit is contained in:
parent
d3a9af0666
commit
0f9410fb3d
|
@ -1,29 +1,78 @@
|
||||||
// Code snippet inspired by https://github.com/douglasrodrigues5/ghost-blog-infinite-scroll
|
// Code snippet inspired by https://github.com/douglasrodrigues5/ghost-blog-infinite-scroll
|
||||||
$(function ($) {
|
$(function ($) {
|
||||||
var currentPage = 1,
|
var currentPage = 1;
|
||||||
pathname = window.location.pathname,
|
var pathname = window.location.pathname;
|
||||||
$window = $(window),
|
var $document = $(document);
|
||||||
$document = $(document),
|
var $result = $('.post-feed');
|
||||||
$result = $('.post-feed');
|
var buffer = 100;
|
||||||
|
|
||||||
function handleScroll () {
|
var ticking = false;
|
||||||
// return if not scroll to the bottom
|
var isLoading = false;
|
||||||
if ($window.scrollTop() + $window.height() !== $document.height()) {
|
|
||||||
|
var lastScrollY = window.scrollY;
|
||||||
|
var lastWindowHeight = window.innerHeight;
|
||||||
|
var lastDocumentHeight = $document.height();
|
||||||
|
|
||||||
|
// remove hash params from pathname
|
||||||
|
pathname = pathname.replace(/#(.*)$/g, '').replace('/\//g', '/');
|
||||||
|
|
||||||
|
function onScroll() {
|
||||||
|
lastScrollY = window.scrollY;
|
||||||
|
requestTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onResize() {
|
||||||
|
lastWindowHeight = window.innerHeight;
|
||||||
|
lastDocumentHeight = $document.height();
|
||||||
|
requestTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestTick() {
|
||||||
|
if (!ticking) {
|
||||||
|
requestAnimationFrame(infiniteScroll)
|
||||||
|
}
|
||||||
|
ticking = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function infiniteScroll () {
|
||||||
|
// return if already loading
|
||||||
|
if (isLoading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPage >= maxPages) {
|
// return if not scroll to the bottom
|
||||||
return $window.off('scroll', handleScroll);
|
if (lastScrollY + lastWindowHeight <= lastDocumentHeight - buffer) {
|
||||||
|
ticking = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isLoading = true;
|
||||||
|
|
||||||
// next page
|
// next page
|
||||||
currentPage++;
|
currentPage++;
|
||||||
|
|
||||||
// Load more
|
// Load more
|
||||||
$.get((pathname + 'page/' + currentPage + '/'), function (content) {
|
var nextPage = pathname + 'page/' + currentPage + '/';
|
||||||
|
|
||||||
|
$.get(nextPage, function (content) {
|
||||||
$result.append($(content).find('.post').hide().fadeIn(100));
|
$result.append($(content).find('.post').hide().fadeIn(100));
|
||||||
|
|
||||||
|
}).fail(function (xhr) {
|
||||||
|
// 404 indicates we've run out of pages
|
||||||
|
if (xhr.status === 404) {
|
||||||
|
window.removeEventListener('scroll', onScroll, {passive: true});
|
||||||
|
window.removeEventListener('resize', onResize);
|
||||||
|
}
|
||||||
|
|
||||||
|
}).always(function () {
|
||||||
|
lastDocumentHeight = $document.height();
|
||||||
|
isLoading = false;
|
||||||
|
ticking = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$window.on('scroll', handleScroll).trigger('scroll');
|
window.addEventListener('scroll', onScroll, {passive: true});
|
||||||
|
window.addEventListener('resize', onResize);
|
||||||
|
|
||||||
|
infiniteScroll();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue