nhentai漫画阅读模式

漫画阅读模式,从上到下顺序展示图片

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name            nhentai漫画阅读模式
// @namespace       https://nhentai.xxx/
// @version         0.1
// @description     漫画阅读模式,从上到下顺序展示图片
// @author          jueserencai
// @match           https://nhentai.xxx/g/*
// @icon            data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

// @require         https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @grant           GM_xmlhttpRequest
// ==/UserScript==


(function () {
    'use strict';

    // 不同网站可变动的部分------------------------------------------------
    // 获取总页码
    function getPageNum() {
        return $(".thumb-container").length;
    }

    // 获取每一张img 所在的http url列表
    function getPageUrls() {
        let pageUrls = [];
        $("#thumbnail-container > div > div > a").each(function (index, element) {
            pageUrls.push(element.href);
        });
        return pageUrls;
    }

    // 从页面中获取当前这一页img 的 selector path
    const IMG_SELECTOR = "#image-container > a > img";

    // 不同网站可变动的部分------------------------------------------------


    // 不同网站不变的部分。不同网站的主体流程是一样的,只用更改上面的函数或常量适配不同网站即可

    let pageNum = getPageNum();
    if (!pageNum) return;
    console.log(`page num: ${pageNum}`);


    // 页面元素初始化
    initDom();


    let pageUrls = ["unused head"].concat(getPageUrls());
    console.log("pageUrls: ", pageUrls);


    // 所有页码的图片的src地址
    let imgSrcMap = new Map();


    (async function () {
        console.log("开始执行:", new Date());
        // 每次加载少量页码
        // let pageNumInOnce = 5;
        // for (let currentPage = 1; currentPage <= pageNum; currentPage += pageNumInOnce) {
        //     await Promise.all(getImgSrcInPageRange(currentPage, Math.min(currentPage + pageNumInOnce, pageNum + 1)));
        //     console.log(`载入${currentPage}`);
        //     let src = imgSrcMap.get(currentPage);
        //     console.log(`currentPage ${currentPage}, src: ${src}`);
        //     await sleep(Math.floor(Math.random() * 1000));
        //     console.log("sleep");
        // }

        // 一次加载全部页码
        await Promise.all(getImgSrcInPageRange(1, pageNum + 1));
        console.log("结束执行:", new Date());
        console.log("imgSrcMap ", imgSrcMap);

        // 漫画所有页的img src 放入 modal中
        generateImgModal();

    })();


    // 加载所需的库,以及插入dom
    function initDom() {

        // 加载 bootstrap
        $("head").prepend(`
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

            <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
            integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
        `)

        $("body").append(`
            <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
                integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
                crossorigin="anonymous"></script>
            <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
                integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
                crossorigin="anonymous"></script>
        `)
        console.log("bootstrap 加载完毕")


        // 添加 阅读按钮
        $("body").prepend(`
            <!-- Button trigger modal -->
            <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalLong">
                阅读模式
            </button>

            <!-- Modal -->
            <div class="modal fade" id="exampleModalLong" tabindex="-1" role="dialog" aria-labelledby="exampleModalLongTitle"
                aria-hidden="true" style="z-index: 2147483647;">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title" id="exampleModalLongTitle"></h5>
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        <div id="imgList" class="modal-body">
                            ...
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                        </div>
                    </div>
                </div>
            </div>
        `)
    }

    // 获取一页中的 img src
    function getImgSrc(page, url) {
        return new Promise((resolve, reject) => {
            return GM_xmlhttpRequest({
                method: "GET",
                url: url,
                onload: function (response) {
                    let htmlstr = response.responseText;
                    let src = $(htmlstr).find(IMG_SELECTOR).attr('src');
                    console.log(src);
                    imgSrcMap.set(page, src);
                    resolve(page);
                }
            });
        });
    }

    // 获取页面范围内的img src
    function getImgSrcInPageRange(pageStart, pageEnd) {
        let awaitList = []
        for (let page = pageStart; page < pageEnd; page++) {
            const pageUrl = pageUrls[page];
            awaitList.push(getImgSrc(page, pageUrl))
        }
        return awaitList;
    }

    // 休眠,为了防止一下子加载太多
    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    // 将所有页码的img 插入到modal中
    function generateImgModal() {
        let imgListHtml = ``
        for (let p = 1; p <= pageNum; p++) {
            const imgSrc = imgSrcMap.get(p);
            imgListHtml += `
                <div style="margin-top: 10px;"></div>
                <img id="p_${p}" src="${imgSrc}" style="width: 100%;">
                `
        }

        $("#imgList").html($(imgListHtml))
    }

})();