mirror of
				https://github.com/ZetaKebab/kesper.git
				synced 2025-11-03 23:59: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,2 +1,2 @@
 | 
			
		||||
$(function(t){var o=1,r=window.location.pathname,a=t(document),s=t(".post-feed"),c=300,l=!1,w=!1,d=window.scrollY,v=window.innerHeight,u=a.height();function f(){d=window.scrollY,e()}function g(){v=window.innerHeight,u=a.height(),e()}function e(){l||requestAnimationFrame(n),l=!0}function n(){var e,n;if(n=/(?:page\/)(\d)(?:\/)$/i,(e=(e=r).replace(/#(.*)$/g,"").replace("////g","/")).match(n)&&(o=parseInt(e.match(n)[1]),e=e.replace(n,"")),r=e,!w)if(d+v<=u-c)l=!1;else{if(o>=maxPages)return window.removeEventListener("scroll",f,{passive:!0}),void window.removeEventListener("resize",g);w=!0;var i=r+"page/"+(o+=1)+"/";t.get(i,function(e){var n=document.createRange().createContextualFragment(e).querySelectorAll(".post");n.length&&[].forEach.call(n,function(e){s[0].appendChild(e)})}).fail(function(e){404===e.status&&(window.removeEventListener("scroll",f,{passive:!0}),window.removeEventListener("resize",g))}).always(function(){u=a.height(),l=w=!1})}}window.addEventListener("scroll",f,{passive:!0}),window.addEventListener("resize",g),n()});
 | 
			
		||||
!function(n,t){var r=t.querySelector("link[rel=next]");if(r){var i=t.querySelector(".post-feed");if(i){var o=300,s=!1,l=!1,c=n.scrollY,u=n.innerHeight,d=t.documentElement.scrollHeight;n.addEventListener("scroll",a,{passive:!0}),n.addEventListener("resize",m),f()}}function v(){if(404===this.status)return n.removeEventListener("scroll",a),void n.removeEventListener("resize",m);this.response.querySelectorAll(".post-card").forEach(function(e){i.appendChild(e)});var e=this.response.querySelector("link[rel=next]");e?r.href=e.href:(n.removeEventListener("scroll",a),n.removeEventListener("resize",m)),d=t.documentElement.scrollHeight,l=s=!1}function e(){if(!l)if(c+u<=d-o)s=!1;else{l=!0;var e=new n.XMLHttpRequest;e.responseType="document",e.addEventListener("load",v),e.open("GET",r.href),e.send(null)}}function f(){s||n.requestAnimationFrame(e),s=!0}function a(){c=n.scrollY,f()}function m(){u=n.innerHeight,d=t.documentElement.scrollHeight,f()}}(window,document);
 | 
			
		||||
//# sourceMappingURL=infinitescroll.js.map
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -76,12 +76,6 @@
 | 
			
		||||
    <script type="text/javascript" src="{{asset "built/jquery.fitvids.js"}}"></script>
 | 
			
		||||
 | 
			
		||||
    {{#if pagination.pages}}
 | 
			
		||||
    <script>
 | 
			
		||||
        // maxPages is a global variable that is needed to determine
 | 
			
		||||
        // if we need to load more pages for the infinitescroll, or if
 | 
			
		||||
        // we reached the last page already.
 | 
			
		||||
        var maxPages = parseInt('{{pagination.pages}}');
 | 
			
		||||
    </script>
 | 
			
		||||
    <script src="{{asset "built/infinitescroll.js"}}"></script>
 | 
			
		||||
    {{/if}}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user