Bangumi Unlimited Pages

自动加载下页

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Bangumi Unlimited Pages
// @namespace    https://github.com/bangumi/scripts/liaune
// @version      0.4
// @description  自动加载下页
// @author       Liaune
// @include      /^https?://(bangumi\.tv|bgm\.tv|chii\.in)/.*
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    var iframeLoader = false;//If true, load pages inside a hidden iframe instead of with XMLHttpRequest--other bgm scripts might work better with this on.
    var scrollBuffer = 100;//Minimum height remaining to scroll before loading the next page.
    var timeToFailure = 10;//Seconds to wait for a response from the next page before attempting to fetch the page again.


    var mainTable, bottomDoc, nextPage, timeout = 0, pending = false, totalPages = 0, loadAll = 0, Autoload = false, loadAllLink=null;

    mainTable = getMainTable(document);
    bottomDoc = getBottomPager(document);
    nextPage = getNextPage(bottomDoc);

    //Run if this window isn't inside an iframe and we've found the thumbnail container, bottom pager, and next page
    if( window == window.top && mainTable && bottomDoc && nextPage )
    {
        //Move bottom pager out of where additional content will be loaded
        //bottomDoc.parentNode.removeChild(bottomDoc);
        //mainTable.parentNode.appendChild(bottomDoc);

        var resultBadge = document.querySelector(".page_inner a:last-child");
        var resultMatcher;
        totalPages = resultBadge? resultBadge.href.replace(/.*(\?|&)page=([0-9]+).*/,'$2'): null;

        let AutoloadLink = document.createElement("a");
        mainTable.parentNode.appendChild(AutoloadLink);
        AutoloadLink.className = "p";
        AutoloadLink.style = 'float:right';
        AutoloadLink.textContent = "Auto Load Pages";
        AutoloadLink.onclick = function(){
            Autoload = true;
            AutoloadLink.style.display='none';
            testScrollPosition();
        };

        loadAllLink = document.createElement("a");
        mainTable.parentNode.appendChild(loadAllLink);
        loadAllLink.className = "p";
        loadAllLink.style = 'float:right';
        loadAllLink.textContent = "Load All Pages";
        loadAllLink.onclick = function(){
            loadAll = (loadAll==1)? 0 :1;
            loadAllLink.textContent = (loadAll==1) ? "Stop Loading All Pages" : "Load All Pages";
            loadAllLink.setAttribute("style"," position: fixed;top: 500px;left: 50px");
            testScrollPosition();
        };
        //Adjust buffer height
        scrollBuffer += window.innerHeight;

        //Watch scrolling
        window.addEventListener("scroll", testScrollPosition, false);
        testScrollPosition();
    }

    function getMainTable(source){
        var result = null, tableFun =
            [
                //user/mono
                function(src){ src = src.querySelector('ul.coversSmall'); return src ? src : null; },

                //subject/browser
                function(src){ src = src.querySelector('#browserItemList'); return src ? src : null; },

                //subject/collections
                function(src){ src = src.querySelector('ul#memberUserList'); return src ? src : null; },

                ///group/forum
                function(src){ src = src.querySelectorAll('#columnA .topic_list tbody')[1]; return src ? src : null; },

                //blog
                function(src){ src = src.querySelector('#news_list'); return src ? src : null; },

                //timeline
                function(src){ src = src.querySelector('#tmlContent #timeline'); return src ? src : null; },

                //index
                function(src){ src = src.querySelector('#timeline ul'); return src ? src : null; },

                //group/all
                function(src){ src = src.querySelector('#memberGroupList'); return src ? src : null; },

                //tags
                function(src){ src = src.querySelector('#tagList'); return src ? src : null; },

                //subject/reviews
                function(src){ src = src.querySelector('#entry_list'); return src ? src : null; },

                //comments
                function(src){ src = src.querySelector('#comment_box'); return src ? src : null; },
            ];

        for( var i = 0; i < tableFun.length; i++ )
        {
            getMainTable = tableFun[i];
            if( (result = getMainTable(source)) != null )
                return result;
        }

        return null;
    }

    function getBottomPager(source){
        var result = null, pagerFun =
            [

                function(src){ src = src.querySelector(".page_inner"); return src ? src : null; },

            ];

        for( var i = 0; i < pagerFun.length; i++ )
        {
            getBottomPager = pagerFun[i];
            if( (result = getBottomPager(source)) != null )
                return result;
        }

        return null;
    }

    function getNextPage(pager){
        if(!pager) return null;
        let current = pager.querySelector('.p_cur');
        if(current)
            return $(current).next('a.p') ? $(current).next('a.p').attr('href'):null;
        let next = pager.querySelectorAll('a.p')[1] ? pager.querySelectorAll('a.p')[1] : pager.querySelectorAll('a.p')[0];
        if(next)
            return next.href;

    }

    function testScrollPosition(){
        if( !pending &&  (loadAll || (Autoload && window.pageYOffset + scrollBuffer > bottomDoc.offsetTop))  )
        {
            pending = true;
            timeout = setTimeout( function(){ pending = false; testScrollPosition(); }, timeToFailure*1000 );

            //If the page about to be loaded is the last, hide the "Load All Pages" link.
            if( loadAllLink && nextPage.replace(/.*(\?|&)page=([0-9]+).*/,'$2') == totalPages && totalPages>2 )
                loadAllLink.style.display = "none";
            else
            {
                var xhr = new XMLHttpRequest();
                xhr.open( "GET", nextPage );
                xhr.onabort = xhr.onabort = xhr.onerror = function(){ clearTimeout(timeout); pending = false; };
                xhr.onload = function(){ processPage( xhr.responseXML ); };
                xhr.responseType = "document";
                xhr.send();
            }
        }
    }

    function processPage( newDoc ){
        clearTimeout(timeout);

        var newTable = getMainTable(newDoc);

        //Make sure page loaded properly
        if( !newTable )
        {
            pending = false;
            return;
        }

        //Update the visible bottom paginator.
        var bottomPage = getBottomPager( newDoc );
        bottomDoc.innerHTML = bottomPage.innerHTML;

        //Append new page
        //mainTable.innerHTML+= newTable.innerHTML;
        $(mainTable).append(newTable.innerHTML);

        //Check for the next page, and disable the script if there isn't one.
        nextPage = getNextPage(bottomPage);
        if(nextPage)
        {
            pending = false;
            testScrollPosition();
        }
    }
})();