2019-10-20 09:55:06 -04:00
|
|
|
/* eslint-env browser */
|
|
|
|
|
2018-12-05 07:38:11 -05:00
|
|
|
/**
|
|
|
|
* Infinite Scroll
|
2019-10-20 09:55:06 -04:00
|
|
|
* Used on all pages where there is a list of posts (homepage, tag index, etc).
|
|
|
|
*
|
|
|
|
* When the page is scrolled to 300px from the bottom, the next page of posts
|
|
|
|
* is fetched by following the the <link rel="next" href="..."> that is output
|
|
|
|
* by {{ghost_head}}.
|
|
|
|
*
|
|
|
|
* The individual post items are extracted from the fetched pages by looking for
|
|
|
|
* a wrapper element with the class "post-card". Any found elements are appended
|
|
|
|
* to the element with the class "post-feed" in the currently viewed page.
|
2018-12-05 07:38:11 -05:00
|
|
|
*/
|
|
|
|
|
2019-10-20 09:55:06 -04:00
|
|
|
(function (window, document) {
|
2018-12-05 07:38:11 -05:00
|
|
|
// next link element
|
|
|
|
var nextElement = document.querySelector('link[rel=next]');
|
2019-10-20 09:55:06 -04:00
|
|
|
if (!nextElement) {
|
|
|
|
return;
|
|
|
|
}
|
2018-12-05 07:38:11 -05:00
|
|
|
|
|
|
|
// post feed element
|
|
|
|
var feedElement = document.querySelector('.post-feed');
|
2019-10-20 09:55:06 -04:00
|
|
|
if (!feedElement) {
|
|
|
|
return;
|
|
|
|
}
|
2018-12-05 07:38:11 -05:00
|
|
|
|
2018-04-09 06:03:48 -04:00
|
|
|
var buffer = 300;
|
2017-06-21 08:10:09 -04:00
|
|
|
|
2017-07-10 08:53:42 -04:00
|
|
|
var ticking = false;
|
2018-12-05 07:38:11 -05:00
|
|
|
var loading = false;
|
2017-07-10 08:53:42 -04:00
|
|
|
|
|
|
|
var lastScrollY = window.scrollY;
|
|
|
|
var lastWindowHeight = window.innerHeight;
|
2018-12-05 07:38:11 -05:00
|
|
|
var lastDocumentHeight = document.documentElement.scrollHeight;
|
2017-07-10 08:53:42 -04:00
|
|
|
|
2018-12-05 07:38:11 -05:00
|
|
|
function onPageLoad() {
|
|
|
|
if (this.status === 404) {
|
|
|
|
window.removeEventListener('scroll', onScroll);
|
|
|
|
window.removeEventListener('resize', onResize);
|
|
|
|
return;
|
2017-07-10 08:53:42 -04:00
|
|
|
}
|
|
|
|
|
2018-12-05 07:38:11 -05:00
|
|
|
// append contents
|
2021-03-11 13:32:57 -05:00
|
|
|
var postElements = this.response.querySelectorAll('article.post-card');
|
2018-12-05 07:38:11 -05:00
|
|
|
postElements.forEach(function (item) {
|
2019-10-24 12:15:34 -04:00
|
|
|
// document.importNode is important, without it the item's owner
|
|
|
|
// document will be different which can break resizing of
|
|
|
|
// `object-fit: cover` images in Safari
|
|
|
|
feedElement.appendChild(document.importNode(item, true));
|
2018-12-05 07:38:11 -05:00
|
|
|
});
|
2018-04-10 05:04:43 -04:00
|
|
|
|
2018-12-05 07:38:11 -05:00
|
|
|
// 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);
|
2018-04-10 05:04:43 -04:00
|
|
|
}
|
|
|
|
|
2018-12-05 07:38:11 -05:00
|
|
|
// sync status
|
|
|
|
lastDocumentHeight = document.documentElement.scrollHeight;
|
|
|
|
ticking = false;
|
|
|
|
loading = false;
|
2018-04-10 05:04:43 -04:00
|
|
|
}
|
|
|
|
|
2018-12-05 07:38:11 -05:00
|
|
|
function onUpdate() {
|
2017-07-10 08:53:42 -04:00
|
|
|
// return if already loading
|
2019-10-20 09:55:06 -04:00
|
|
|
if (loading) {
|
|
|
|
return;
|
|
|
|
}
|
2017-06-27 07:03:51 -04:00
|
|
|
|
2017-07-10 08:53:42 -04:00
|
|
|
// return if not scroll to the bottom
|
|
|
|
if (lastScrollY + lastWindowHeight <= lastDocumentHeight - buffer) {
|
|
|
|
ticking = false;
|
|
|
|
return;
|
2017-06-27 07:03:51 -04:00
|
|
|
}
|
|
|
|
|
2018-12-05 07:38:11 -05:00
|
|
|
loading = true;
|
2017-07-11 01:18:10 -04:00
|
|
|
|
2018-12-05 07:38:11 -05:00
|
|
|
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;
|
|
|
|
requestTick();
|
|
|
|
}
|
|
|
|
|
|
|
|
function onResize() {
|
|
|
|
lastWindowHeight = window.innerHeight;
|
|
|
|
lastDocumentHeight = document.documentElement.scrollHeight;
|
|
|
|
requestTick();
|
2017-06-27 07:03:51 -04:00
|
|
|
}
|
|
|
|
|
2019-10-20 09:55:06 -04:00
|
|
|
window.addEventListener('scroll', onScroll, {passive: true});
|
2017-07-10 08:53:42 -04:00
|
|
|
window.addEventListener('resize', onResize);
|
|
|
|
|
2018-12-05 07:38:11 -05:00
|
|
|
requestTick();
|
|
|
|
})(window, document);
|