Gelbooru 无限滚动

实现 Gelbooru 图片浏览页面无限滚动

As of 2022-01-29. See the latest version.

// ==UserScript==
// @name         Gelbooru 无限滚动
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  实现 Gelbooru 图片浏览页面无限滚动
// @author       ctrn43062
// @include      *://gelbooru.com/index.php*
// @icon         https://gelbooru.com/favicon.ico
// @grant        none
// @license MIT

// ==/UserScript==

// 是否正在加载下一页数据 flag
let loadingNextPage = false;

// 是否显示分页栏
const showPaginator = false;

// Gelbooru 的 pid 增长值(无需修改)
const pageIncrement = 42;

// 当滚动条距离页面底部多少像素的时候触发加载下一页数据功能;调大这个值以更提前地加载下一页数据
const scrollBuffer = 300;

const baseURLObj = new URL(location.href);
const searchParams = baseURLObj.searchParams;
const tags = searchParams.get('tags');
let currentPage = parseInt(searchParams.get('pid')) || 0;


// 获取数据
function getPage() {
    const url = baseURLObj.origin + baseURLObj.pathname + '?' + searchParams;
    return fetch(url).then(resp => resp.text())
}


// 显示页面加载提示
function showLoadingTip(tip = '') {
    const loadingTip = document.createElement('center');
    const pagination = document.querySelector('.pagination');

    // 加载下一页数据的提示文本
    loadingTip.textContent = tip || `Loading Page ${Math.floor(currentPage / pageIncrement) + 1}`
    loadingTip.style.margin = '30px 0';
    loadingTip.style.color = '#666';
    loadingTip.style.fontSize = '0.8rem';

    pagination.insertBefore(loadingTip, pagination.querySelector('#paginator'));

    return loadingTip;
}


(function() {
    'use strict';
    const paginator = document.querySelector('#paginator');

    if(!showPaginator) {
        paginator.style.display = 'none';
    }

    window.addEventListener('scroll', () => {
        const scrollTop =
        document.documentElement.scrollTop === 0
          ? document.body.scrollTop
          : document.documentElement.scrollTop;

        const scrollHeight =
        document.documentElement.scrollTop === 0
          ? document.body.scrollHeight
          : document.documentElement.scrollHeight;

        const innerHeigth = window.innerHeight;

        // 当滚动条触底且没有正在加载数据的时候,加载下一页数据
        if(scrollTop + innerHeigth >= scrollHeight - scrollBuffer && !loadingNextPage) {
            loadingNextPage = true;
            currentPage = parseInt(currentPage) + pageIncrement;
            searchParams.set('pid', currentPage);

            const loadingTip = showLoadingTip();

            getPage().then(text => {
                const dummyHTML = document.createElement('html');
                const container = document.querySelector('.thumbnail-container');
                dummyHTML.innerHTML = text;
                const nodes = dummyHTML.querySelector('.thumbnail-container').children;

                // 没有数据了
                if(nodes.length === 0) {
                    loadingTip.textContent = 'Nobody here but us chickens!';
                     return ;
                }

                Array.from(nodes).forEach((node) => {
                    container.appendChild(node)
                })

                loadingNextPage = false;
                loadingTip.remove();
            })
        }
    })
})();