Next Page-bobo3

使用左右方向键来翻页 [Ver 0.1.7.4+]

当前为 2024-09-24 提交的版本,查看 最新版本

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

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

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

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

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

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name               Next Page-bobo3
// @author             Sunwan,bobo
// @version            0.2.7.3.005-bobo3
// @namespace          https://greasyfork.org/zh-CN/scripts/510005-next-page-bobo3/code
// @description        使用左右方向键来翻页 [Ver 0.1.7.4+]
// @grant					GM_getValue
// @grant					GM_setValue
// @grant					GM_registerMenuCommand
// @license           MIT License
// @include            http://*
// @include            https://*
// ==/UserScript==

(function() {
    var checked = false;
    var delay = false;
    var next = {};
    var previous = {};
    var but1 =false;
    var but2 =false;
    // 下一页链接里的文字
    //包含,一、页、頁、翻,的链接text,才进入详细比对
    next.texts      = ['下页',
                       '下頁',
                       '下一页',
                       '下一頁',
                       '后一页',
                       '后一頁',
                       '翻下页',
                       '翻下頁',
                       '后页',
                       '后頁',
                       '下翻',
                       '下一个',
                       '下一张',
                       '下一幅',
                       '下一节',
                       '下一章',
                       '下一章 →',
                       '下一篇',
                       '后一章',
                       '后一篇'
                      ];
    // 上一页链接里的文字
    previous.texts  = ['上页',
                       '上頁',
                       '上一页',
                       '上一頁',
                       '前一页',
                       '前一頁',
                       '翻上页',
                       '翻上頁',
                       '前页',
                       '前頁',
                       '上翻',
                       '上一个',
                       '上一张',
                       '上一幅',
                       '上一节',
                       '上一章',
                       '← 上一章',
                       '上一篇',
                       '前一章',
                       '前一篇'
                      ];
    // 可能会误判的关键词
    next.miswords   = { "x下一章": 30,
                       "下一篇": 30,
                       "后一章": 30,
                       "后一篇": 30,
                       "下一节": 30,
                       ">>": 2000,
                       "?": 2000
                      };
    previous.miswords = { "x上一章": 30,
                         "上一篇": 30,
                         "前一章": 30,
                         "前一篇": 30,
                         "上一节": 30,
                         "<<": 2000,
                         "?": 2000
                        };


    // 注册脚本菜单
    registerMenu("next");
    registerMenu("previous");

    // 取得自定义关键词
    getCustom(next, "next");
    getCustom(previous, "previous");


    // 最后添加一些论坛使用的翻页符号
    next.texts.push(">>");
    next.texts.push(">");

    previous.texts.push("<<");
    previous.texts.push("<");


    // 翻页文字的前面和后面可能包含的字符(正则表达式)
    var preRegexp = '(^\\s*(?:[<??]*|[>??]*|[\\(\\[『「[【]?)\\s*)';
    var nextRegexp = '(\\s*(?:[>??]*|[\\)\\]』」]】]?)\\s*$)';
    /*     假函数防止其他js监控键盘
    function jumpPage111(ee1){}
    document.onkeydown = jumpPage111; */


    //等页面加载完成执行下一页扫描
    document.onreadystatechange = function()   //当页面加载状态改变的时候执行function
    {
        if(document.readyState == "complete")

        {   //当页面加载状态为完全结束时进入
            //document.getElementById("content").style.fontSize ="34px";
            console.error("页面加载完执行init112,ddddddddddddd");
            //alert("dddddddddd");
            init112();   //你要做的操作。

        }
    }
     function init113(){

      let els = document.getElementsByClassName('muye-reader-inner');
           // els[0].style.width = "1800px";

            //els[0].style.max-width = "1800px";
        els[0].style.cssText = "width:1450px;max-width:1450px;";



            console.error("页面加载完执行 els[0].style.width = '1450';");
            console.error(els);

          let els2 = document.getElementsByClassName('reader-toolbar');
         els2[0].style.cssText ="right: 50px;";
          console.error("页面加载完执行els2[0].style.cssText =='right: 30px;';");
            console.error(els2);

     }
    function init112(){
        if (!checked) {
            checkLinks();

           checked = true;
        }

          //init113();

    }

    // 取得并设置自定义关键词
    function getCustom(aObj, key) {
        var site, re;
        var cKeyWords = GM_getValue("custom_" + key, "");
        var words = cKeyWords.split(/,|,/);
        for (var w in words) {
            site = null;
            if (/^\s*{\s*(\S*?)\s*}(.*)$/.test(w)) {
                site = RegExp.$1;
                w = RegExp.$2;
                site = site.replace(/[\/\?\.\(\)\+\-\[\]\$]/g, "\\$&").replace(/\*/g, "\.*");
            }
            w = w.replace(/\\/g, "\\").replace(/^\s+|\s+$/g, "");
            if (w) {
                if (site) {
                    re = eval('/' + site + '/i');
                    if (re.test(location.href))
                        aObj.texts.push(w);
                }
                else
                    aObj.texts.push(w);
            }
        }
    }

    // 注册菜单
    function registerMenu(key) {
        if (navigator.language == "zh-CN") {
            var word = key == "next" ? "下一页" : "上一页";
            GM_registerMenuCommand("Next Page " + word + "关键词", function(){setCustom(key, word);});
        }
        else {
            GM_registerMenuCommand("Next Page custom_" + key, function(){setCustom(key, key);});
        }
    }

    // 设置新的关键词
    function setCustom(k, w) {
        var text = navigator.language == "zh-CN" ? "请输入“"+w+"”的关键词,以“,”号分隔开。" : "Please enter the "+w+" page key-words, split with ','.";
        var result = prompt(text, GM_getValue("custom_" + k, ""));
        if (result != null) GM_setValue("custom_" + k, result);
    }

    function checkLinks() {
        var link, text, ldnc, lnc, ldpc, lpc, num, digCurFound, linkNumber, found, tmpNode;
        var regexp = new RegExp();
        // 查找相应的链接
        var links = document.getElementsByTagName('A');
        for (var i = links.length-1; i >=0; i--) {
            //倒序查找速度更快
            link = links[i];

            // 跳过不起作用的链接
            if (!link.offsetParent || link.offsetWidth == 0 || link.offsetHeight == 0 || !link.hasAttribute("href") && !link.hasAttribute("onclick"))
                continue;
            // 跳过日历
            if (/(?:^|\s)(?:monthlink|weekday|day|day[\-_]\S+)(?:\s|$)/i.test(link.className))
                continue;

            if (/^nextlink/i.test(link.id) || /^linknext/i.test(link.id) ||
                /(^|\s)nextlink/i.test(link.className) || /(^|\s)linknext/i.test(link.className))
                next.link = link;
            if (/^prev(ious)?link/i.test(link.id) || /^linkprev(ious)?/i.test(link.id) ||
                /(^|\s)prev(ious)?link/i.test(link.className) || /(^|\s)linkprev(ious)?/i.test(link.className))
                previous.link = link;

            text = link.textContent;
            if (!text) {
                // 若链接中没有文字,则检查图片的alt属性、链接或图片的title
                for (var img in link.childNodes) {
                    if (img.localName == "IMG") {
                        text = img.alt || link.title || img.title;
                        if (text) break;
                    }
                }
                if (!text) continue;
            }
            text = text.toLowerCase().replace(/^\s+|\s+$/g, "");
            if (!text) continue;

            // 纯数字链接
            if (isDigital(text)) {
                if (digCurFound) continue;
                linkNumber = parseInt(RegExp.$1);

                // 检测下一个位置是否是当前页面的页数
                if ((tmpNode = getCurrentPageNode(link, linkNumber, 1)) && tmpNode) {
                    digCurFound = true;
                    previous.link = link;
                    previous.found = true;
                    previous.pos = i;
                    // 再检测下下一个位置是否是“下一页”的链接
                    if (getNextLink(tmpNode, linkNumber+2, true))
                        break;
                    // 设置往后的30个位置以内为“下一页”的可能链接,以提高检测速度。
                    ldnc = i + 30;
                }
                // 检测上一个位置是否是当前页面的页数
                else if (getCurrentPageNode(link, linkNumber, -1)) {
                    digCurFound = true;
                    next.link = link;
                    next.found = true;
                    next.pos = i;
                    ldpc = i + 30;
                    continue;
                }
                // 检测自身是否是当前页面的页数
                else if (getCurrentPageNode(link, linkNumber, 0)) {
                    digCurFound = true;
                    // 再检测下一个位置是否是“下一页”的链接
                    if (getNextLink(link, linkNumber+1, true)) {
                        next.pos = i;
                        ldpc = i + 30;
                        continue;
                    }
                    // 设置往后的30个位置以内为“下一页”的可能链接,以提高检测速度。
                    ldnc = i + 30;
                }
                continue;
            }
            else {
                found = false;
                //包含,一、页、頁、翻,的链接text,才进入详细比对
                var xxxx1=regexp.compile( '一|页|頁|翻', 'i').test(text);
                if (xxxx1){
                    //详细比较
                    if (!next.found && !(lnc < i) && !(ldnc < i)) {
                        for (var j = 0; j < next.texts.length; j++) {
                            if (regexp.compile(preRegexp + next.texts[j] + nextRegexp, 'i').test(text)) {
                                // 检测到“下一页”的链接
                                found = true;
                                next.link = link;
                                num = next.miswords[next.texts[j]];
                                // 若“下一页”的词语有可能会误判时,最多再检测预定个数的链接。

                                var vv1 = (num == null) ? next.found = true : lnc = i + num;
                                break;
                            }
                        }
                    }
                    if (!next.digital && lnc < i) next.found = true;

                    if (!found && !previous.found && !(lpc < i) && !(ldpc < i)) {
                        for (var j3 = 0; j3< previous.texts.length; j3++) {
                            if (regexp.compile(preRegexp + previous.texts[j3] + nextRegexp, 'i').test(text)) {
                                // 检测到“上一页”的链接
                                previous.link = link;
                                num = previous.miswords[previous.texts[j3]];
                                // 若“上一页”的词语有可能会误判时,最多再检测预定个数的链接。
                                var vv2 =  (num == null) ? previous.found = true : lpc = i + num;
                                break;
                            }
                        }
                    }
                    if (lpc < i) previous.found = true;
                    // 重新设置纯数字链接未被检查
                    digCurFound = null;
                }
            }

            // 找到“上一页”和“下一页”的链接或找到其中一个而另一个超过规定范围没找到,将不再查找。
            if (next.found && previous.found ||
                next.found && i > next.pos + 40 ||
                previous.found && i > previous.pos + 40)
                break;
        }
        // 通过以上方法没有找到“下一页”的,把第一次检测出来的数字1的链接作为当前页,2作为“下一页”。
        if (!next.found /*&& !next.link*/ && next.digital)
            next.link = next.digital;

        if (next.link) next.found = true;
        if (previous.link) previous.found = true;

        if (!next.found && !previous.found)
        {
            console.error("将要执行checkButtons()");
            checkButtons();
        }
    }

    // 检查翻页按钮
    function checkButtons() {
        var but, text, found;
        var regexp = new RegExp();
        var buts = document.getElementsByTagName('button');
        for (var i = 0; i < buts.length; i++) {
            but = buts[i];
            /*
综上所述,这段代码的作用是检查按钮是否被禁用、是否是一个标准的按钮类型 (<button type="button">)
以及是否定义了点击事件处理函数。如果按钮不符合这些条件,则跳过这次循环迭代,继续检查下一个按钮。
*/
            //原版continue跳出for            if (but.hasAttribute("disabled") || !(/^button$/i.test(but.type) && but.getAttribute("onclick"))) continue;
            if (but.hasAttribute("disabled") || !(/^button$/i.test(but.type) )) continue;
            text = but.textContent;
            found = false;
            //console.error(text);
            console.error(" 开始检测到下一页的按钮");
            if (!next.found) {
                for (var j = 0; j < next.texts.length; j++) {
                    if (regexp.compile(preRegexp + next.texts[j] + nextRegexp, 'i').test(text)) {
                        // 检测到“下一页”的按钮

                        console.error(" 检测到“下一页”的按钮,"+ text );
                        but2 = but;
                        next.found = found = true;
                        break;
                    }
                }
            }

            if (!previous.found) {
                for (var j2 = 0; j2 < previous.texts.length; j2++) {
                    if (regexp.compile(preRegexp + previous.texts[j2] + nextRegexp, 'i').test(text)) {
                        // 检测到“上一页”的按钮
                        console.error(" 检测到“上一页”的按钮,"+ text );
                        but1 = but;
                        previous.found = true;
                        break;
                    }
                }
            }
            if (next.found && previous.found) break;
        }
    }

    // 取得相邻的纯数字节点,type: 1 下一个;-1 上一个
    function getSiblingNode(node, type) {
        if (!node) return null;
        node = getSibling(node, type);
        while (node && (node.nodeName == "#coment" ||
                        (/^\s*[\]]】]?[,\|]?\s*[\[[【]?\s*$/.test(node.textContent))))
            node = getSibling(node, type);
        return node;
    }
    function getSibling(aNode, type) {
        if (!aNode) return null;
        if (isOnlyNode(aNode)) {
            try {
                aNode = (type == 1 ? aNode.parentNode.nextSibling : aNode.parentNode.previousSibling);
                if (skipNode(aNode))
                    aNode = (type == 1 ? aNode.nextSibling : aNode.previousSibling);
                aNode = aNode.childNodes[0];
                if (skipNode(aNode))
                    aNode = aNode.nextSibling;
            }
            catch (e) {return null;}
        }
        else {
            aNode = (type == 1 ? aNode.nextSibling : aNode.previousSibling);
        }
        return aNode;
    }
    function isOnlyNode(n) {
        return !n.nextSibling && !n.previousSibling ||
            !n.nextSibling && skipNode(n.previousSibling) && !n.previousSibling.previousSibling ||
            !n.previousSibling && skipNode(n.nextSibling) && !n.nextSibling.nextSibling ||
            skipNode(n.previousSibling) && !n.previousSibling.previousSibling &&
            skipNode(n.nextSibling) && !n.nextSibling.nextSibling;
    }
    function skipNode(sNode) {
        return sNode && /*sNode.nodeName == "#text" &&*/ (/^\s*$/.test(sNode.textContent));
    }

    // 检测是否有下一页的纯数字链接,number:页数
    function getNextLink(node, number, set) {
        var tNode = getSiblingNode(node, 1);
        if (tNode && tNode.nodeName == "A" && isDigital(tNode.textContent)) {
            if (RegExp.$1 == number) {
                // 找到纯数字链接
                if (set) {
                    next.link = tNode;
                    next.found = true;
                }
                return tNode;
            }
        }
        return null;
    }

    function isDigital(str, t) {
        str = str.replace(/^\s+|\s+$/g, "");
        if (t == -1)
            str = str.split(/\s+/).pop();
        else if (t == 1)
            str = str.split(/\s+/)[0];
        return (/^(\d+)$/.test(str)) ||
            (/^\[\s?(\d+)\s?\]$/.test(str)) ||
            (/^【\s?(\d+)\s?】$/.test(str)) ||
            (/^[\s?(\d+)\s?]$/.test(str)) ||
            (/^<\s?(\d+)\s?>$/.test(str));
    }

    // 判断是否是当前页面的数字,type:-1,0,1 分别是要判别的上一个、当前、下一个节点
    function getCurrentPageNode(node, linkNum, type) {
        var tNode;
        if (type == 0) {
            tNode = getSiblingNode(node, 1) || getSiblingNode(node, -1);
            if (!tNode) return null;
            if (!node.hasAttribute("onclick") && node.href != tNode.href &&
                (!node.hasAttribute("href") && isDigital(node.textContent, type) ||
                 !(/\/#[^\/]+$/.test(node.href)) && node.href == location.href && isDigital(node.textContent, type))) {
                if (linkNum > 0 && RegExp.$1 == linkNum) return node;
            }
            // 某些论坛处在第一页时,实际链接和当前页链接不符,只有和其余纯数字链接的结构或颜色不同时,
            // 才使用纯数字的“2”作为“下一页”的链接。
            else if (!next.digital && (/^\s*[\[[【]?1[\]]】]?\s*$/.test(node.textContent))) {
                var two = getNextLink(node, 2);
                if (two && difDigital(node, two))
                    next.digital = two;
            }
        }
        else {
            tNode = getSiblingNode(node, type);
            if (!tNode) return null;
            if (tNode.nodeName != "A" && isDigital(tNode.textContent, type) ||
                tNode.nodeName == "A" && !tNode.hasAttribute("onclick") && node.href != tNode.href &&
                (!tNode.hasAttribute("href") && isDigital(tNode.textContent, type) ||
                 !(/\/#[^\/]+$/.test(tNode.href)) && tNode.href == location.href && isDigital(tNode.textContent, type))) {
                var n = linkNum + type;
                if (n > 0 && RegExp.$1 == n) {
                    if (next.digital) next.digital = null;
                    return tNode;
                }
            }
        }
        return null;
    }

    function difDigital(node1, node2) {
        if (getStructure(node1) == getStructure(node2) && getStyleColor(node1) == getStyleColor(node2))
            return false;
        return true;
    }
    function getStructure(aNode) {
        return aNode.innerHTML.replace(/\d+/, "");
    }
    function getStyleColor(aNode) {
        return document.defaultView.getComputedStyle(aNode, null).getPropertyValue("color");
    }

    function openLink(linkNode) {
        if (!linkNode) return;
        var hf = linkNode.getAttribute("href");
        if (!linkNode.hasAttribute("onclick") && hf && !(/^#/.test(hf)) && linkNode.href != location.href) {
            cleanVars();
            location.assign(linkNode.href);
        }
        else {
            // 有些4D鼠标摆动一下滚轮会触发多下的方向键,故增设一个延迟参数,使它只翻一页。
            delay = true;
            setTimeout(cleanVars, 300);
            var e = document.createEvent("MouseEvents");
            e.initMouseEvent("click", 1, 1, window, 1, 0,0,0,0,0,0,0,0,0, linkNode);
            linkNode.dispatchEvent(e);
        }
    }
    function cleanVars() {
        try {
            checked = false;
            delay = false;
            next.link = next.found = next.digital = null;
            previous.link = previous.found = previous.digital = null;
            delete next.pos;
            delete previous.pos;
        } catch(e) {}
    }

    function onKeyDown(event) {
        // 不是左右方向建被按下或不到延迟时间则退出
        if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey ||event.keyCode != 38 &&event.keyCode != 40 && event.keyCode != 37 && event.keyCode != 39 || delay)return;

        // 确保光标不是定位在文字输入框或选择框
        var localName = event.target.localName.toUpperCase();
        if (localName == 'TEXTAREA' || localName == 'INPUT' || localName == 'SELECT' || localName == 'DIV')return;

        // 检查过且没有发现上一页或下一页的连接,则退出
        if (checked && !next.found && !previous.found) return;

        if (!checked) {
            checkLinks();
            checked = true;
        }

         /* if (event.keyCode == 40) {

            init113();
            console.error(" 按键下箭头," );
          }
          */
        if (event.keyCode == 37 && previous.found) {
            // 左方向键,跳到“上一页”
            openLink(previous.link);

            if (but1){
                console.error(" 按钮上一页," );
                var event2 = new MouseEvent('click', {

                    bubbles: true,

                    cancelable: true,

                    // view: window

                });

                but1.dispatchEvent(event2);
            }
        }
        else if (event.keyCode == 39 && next.found) {
            // 右方向键,跳到“下一页”
            openLink(next.link);

            if (but2){
                console.error(" 按钮下一页," );
                var event1 = new MouseEvent('click', {

                    bubbles: true,

                    cancelable: true,

                    // view: window

                });

                but2.dispatchEvent(event1);
            }
        }
    }

    window.addEventListener("keydown", function(e){onKeyDown(e);}, true);
    document.onkeydown =onKeyDown;
})();