Bangumi Unlimited Pages

自动加载下页

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 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();
        }
    }
})();