mirror of
				https://github.com/ZetaKebab/kesper.git
				synced 2025-11-04 08:09:49 +00:00 
			
		
		
		
	🎨 Optimised infinite scroll (#503)
no issue - removed jQuery usage - use the `<link rel="next">` tag provided by Ghost to determine the next page to fetch
This commit is contained in:
		@@ -1,19 +1,78 @@
 | 
			
		||||
/* global maxPages */
 | 
			
		||||
/**
 | 
			
		||||
 * Infinite Scroll
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
(function(window, document) {
 | 
			
		||||
    // next link element
 | 
			
		||||
    var nextElement = document.querySelector('link[rel=next]');
 | 
			
		||||
    if (!nextElement) return;
 | 
			
		||||
 | 
			
		||||
    // post feed element
 | 
			
		||||
    var feedElement = document.querySelector('.post-feed');
 | 
			
		||||
    if (!feedElement) return;
 | 
			
		||||
 | 
			
		||||
// Code snippet inspired by https://github.com/douglasrodrigues5/ghost-blog-infinite-scroll
 | 
			
		||||
$(function ($) {
 | 
			
		||||
    var currentPage = 1;
 | 
			
		||||
    var pathname = window.location.pathname;
 | 
			
		||||
    var $document = $(document);
 | 
			
		||||
    var $result = $('.post-feed');
 | 
			
		||||
    var buffer = 300;
 | 
			
		||||
 | 
			
		||||
    var ticking = false;
 | 
			
		||||
    var isLoading = false;
 | 
			
		||||
    var loading = false;
 | 
			
		||||
 | 
			
		||||
    var lastScrollY = window.scrollY;
 | 
			
		||||
    var lastWindowHeight = window.innerHeight;
 | 
			
		||||
    var lastDocumentHeight = $document.height();
 | 
			
		||||
    var lastDocumentHeight = document.documentElement.scrollHeight;
 | 
			
		||||
 | 
			
		||||
    function onPageLoad() {
 | 
			
		||||
        if (this.status === 404) {
 | 
			
		||||
            window.removeEventListener('scroll', onScroll);
 | 
			
		||||
            window.removeEventListener('resize', onResize);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // append contents
 | 
			
		||||
        var postElements = this.response.querySelectorAll('.post-card');
 | 
			
		||||
        postElements.forEach(function (item) {
 | 
			
		||||
            feedElement.appendChild(item);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // set next link
 | 
			
		||||
        var resNextElement = this.response.querySelector('link[rel=next]');
 | 
			
		||||
        if (resNextElement) {
 | 
			
		||||
            nextElement.href = resNextElement.href;
 | 
			
		||||
        } else {
 | 
			
		||||
            window.removeEventListener('scroll', onScroll);
 | 
			
		||||
            window.removeEventListener('resize', onResize);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // sync status
 | 
			
		||||
        lastDocumentHeight = document.documentElement.scrollHeight;
 | 
			
		||||
        ticking = false;
 | 
			
		||||
        loading = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function onUpdate() {
 | 
			
		||||
        // return if already loading
 | 
			
		||||
        if (loading) return;
 | 
			
		||||
 | 
			
		||||
        // return if not scroll to the bottom
 | 
			
		||||
        if (lastScrollY + lastWindowHeight <= lastDocumentHeight - buffer) {
 | 
			
		||||
            ticking = false;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        loading = true;
 | 
			
		||||
 | 
			
		||||
        var xhr = new window.XMLHttpRequest();
 | 
			
		||||
        xhr.responseType = 'document';
 | 
			
		||||
 | 
			
		||||
        xhr.addEventListener('load', onPageLoad);
 | 
			
		||||
 | 
			
		||||
        xhr.open('GET', nextElement.href);
 | 
			
		||||
        xhr.send(null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function requestTick() {
 | 
			
		||||
        ticking || window.requestAnimationFrame(onUpdate);
 | 
			
		||||
        ticking = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function onScroll() {
 | 
			
		||||
        lastScrollY = window.scrollY;
 | 
			
		||||
@@ -22,94 +81,12 @@ $(function ($) {
 | 
			
		||||
 | 
			
		||||
    function onResize() {
 | 
			
		||||
        lastWindowHeight = window.innerHeight;
 | 
			
		||||
        lastDocumentHeight = $document.height();
 | 
			
		||||
        lastDocumentHeight = document.documentElement.scrollHeight;
 | 
			
		||||
        requestTick();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function requestTick() {
 | 
			
		||||
        if (!ticking) {
 | 
			
		||||
            requestAnimationFrame(infiniteScroll);
 | 
			
		||||
        }
 | 
			
		||||
        ticking = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function sanitizePathname(path) {
 | 
			
		||||
        var paginationRegex = /(?:page\/)(\d)(?:\/)$/i;
 | 
			
		||||
 | 
			
		||||
        // remove hash params from path
 | 
			
		||||
        path = path.replace(/#(.*)$/g, '').replace('////g', '/');
 | 
			
		||||
 | 
			
		||||
        // remove pagination from the path and replace the current pages
 | 
			
		||||
        // with the actual requested page. E. g. `/page/3/` indicates that
 | 
			
		||||
        // the user actually requested page 3, so we should request page 4
 | 
			
		||||
        // next, unless it's the last page already.
 | 
			
		||||
        if (path.match(paginationRegex)) {
 | 
			
		||||
            currentPage = parseInt(path.match(paginationRegex)[1]);
 | 
			
		||||
 | 
			
		||||
            path = path.replace(paginationRegex, '');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function infiniteScroll() {
 | 
			
		||||
        // sanitize the pathname from possible pagination or hash params
 | 
			
		||||
        pathname = sanitizePathname(pathname);
 | 
			
		||||
 | 
			
		||||
        // return if already loading
 | 
			
		||||
        if (isLoading) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // return if not scroll to the bottom
 | 
			
		||||
        if (lastScrollY + lastWindowHeight <= lastDocumentHeight - buffer) {
 | 
			
		||||
            ticking = false;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
        * maxPages is defined in default.hbs and is the value
 | 
			
		||||
        * of the amount of pagination pages.
 | 
			
		||||
        * If we reached the last page or are past it,
 | 
			
		||||
        * we return and disable the listeners.
 | 
			
		||||
        */
 | 
			
		||||
        if (currentPage >= maxPages) {
 | 
			
		||||
            window.removeEventListener('scroll', onScroll, {passive: true});
 | 
			
		||||
            window.removeEventListener('resize', onResize);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        isLoading = true;
 | 
			
		||||
 | 
			
		||||
        // next page
 | 
			
		||||
        currentPage += 1;
 | 
			
		||||
 | 
			
		||||
        // Load more
 | 
			
		||||
        var nextPage = pathname + 'page/' + currentPage + '/';
 | 
			
		||||
 | 
			
		||||
        $.get(nextPage, function (content) {
 | 
			
		||||
            var parse = document.createRange().createContextualFragment(content);
 | 
			
		||||
            var posts = parse.querySelectorAll('.post');
 | 
			
		||||
            if (posts.length) {
 | 
			
		||||
                [].forEach.call(posts, function (post) {
 | 
			
		||||
                    $result[0].appendChild(post);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }).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.addEventListener('scroll', onScroll, {passive: true});
 | 
			
		||||
    window.addEventListener('scroll', onScroll, { passive: true });
 | 
			
		||||
    window.addEventListener('resize', onResize);
 | 
			
		||||
 | 
			
		||||
    infiniteScroll();
 | 
			
		||||
});
 | 
			
		||||
    requestTick();
 | 
			
		||||
})(window, document);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user