Greasy Fork is available in English.
按左右键快速翻页,也可点击浮动按钮快速翻页
// ==UserScript== // @name HotKey Next Page // @namespace hzhbest // @author hzhbest // @version 1.5 // @description 按左右键快速翻页,也可点击浮动按钮快速翻页 // @include http://* // @include https://* // @license MIT // @run-at document-end // @grant unsafeWindow // ==/UserScript== // original author : [email protected] (https://userscripts-mirror.org/scripts/show/87895) // mod by hzhbest : add hilite and float buttons const Strs = { next: [ "下一页", "下壹頁", "下页", "下一页 »", "下一页 >", "下一节", "下一章", "下一篇", "后一章", "后一篇", "后页>", "»", ">", "next", "next page", "Next →", "old", "older", "earlier", "下頁", "下一頁", "后一页", "后一頁", "翻下页", "翻下頁", "后页", "后頁", "下翻", "下一个", "下一张", "下一幅", ], last: [ "上一页", "上壹頁", "上页", "« 上一页", "< 上一页", "上一节", "上一章", "上一篇", "前一章", "前一篇", "<前页", "«", "<", "previous", "prev", "previous page", "← Previous", "new", "newer", "later", "上頁", "上一頁", "前一页", "前一頁", "翻上页", "翻上頁", "前页", "前頁", "上翻", "上一个", "上一张", "上一幅", ] } const GeneralXpaths = [ ["//a[(normalize-space(text())='", "')]"], ["//a[@class='", "']"], ["//a[@id='", "']"], ["//a[starts-with(@class,'", " ')]"], ["//a[starts-with(@id,'", " ')]"], ["//input[@type='button' and @value='", "']"], ]; //编辑下面的数组来自定义规则 const SpecialXpaths = [ { urls: ["http://www.google.com"], //匹配的url last: "//a[@id='pnprev']", //上一页节点的xpath next: "//a[@id='pnnext']", //下一页节点的xpath }, { urls: ["bilibili.com"], last: '//li[@class="be-pager-prev"]', next: '//li[@class="be-pager-next"]', }, { urls: ["taobao.com"], last: '//button[contains(@aria-label,"上一页")]', next: '//button[contains(@aria-label,"下一页")]', }, { urls: ["gov.cn"], last: '//button[@class="btn-prev"]', next: '//button[@class="btn-next"]', }, /*{ urls: ["anime1.me"], last: '//a[@id="table-list_previous"]', next: '//a[@id="table-list_next"]', }, { urls: ["e-hentai.org"], last: '//a[@id="dprev"]', next: '//a[@id="dnext"]', },*/ ]; const LastKEY = [ 37, // 左方向键 65 // 字母键A ]; const NextKEY = [ 39, // 右方向键 68 // 字母键D ]; const css = `.__hkbtn {outline: 3px solid #bb1a6a; font-size: larger;} .__hkbse {position: fixed; z-index: 1000; right: 2em; bottom: 5em; background: #fff9;} .__hkbse>div:first-of-type {display: none;} .__hkbse:hover>div:first-of-type {display: inline-block;} .__hkfbtn {width: 4em; height: 3em; display: inline-block; border: 2px solid #8a8a8a8a; cursor: pointer; text-align: center; font-size: 1.5em; line-height: 3em; opacity: 0.7;} .__hkfbtn.disabled {opacity: 0.3;} .__hkfbtn:hover {opacity: 1; background: #fbcf84dd;} `; addCSS(css, 'hknp_css'); var lnode,rnode,bnode,href; setTimeout(init, 2000); function init(){ lnode = getNode('last'); rnode = getNode('next'); if (!!lnode || !!rnode) { if (!!bnode) bnode.parentNode.removeChild(bnode); bnode = creaElemIn('div', document.body); bnode.className = '__hkbse'; var lbutton = creaElemIn('div', bnode); var rbutton = creaElemIn('div', bnode); lbutton.className = rbutton.className = '__hkfbtn disabled'; lbutton.innerHTML = "<"; rbutton.innerHTML = ">"; bnode.addEventListener('mouseover', ()=>{ // console.log("href?",href == document.location.href); if(href !== document.location.href) init(); },false); if (!!lnode && lnode.offsetHeight !== 0) { lnode.classList.add('__hkbtn') ; lbutton.classList.remove('disabled'); if (lnode.textContent.length > 0) lbutton.innerHTML = lnode.textContent.substring(0,3); lbutton.title = lnode.textContent + ((!!lnode.href)? '\n' + lnode.href : ''); lbutton.addEventListener('click', ()=>{ click(lnode); setTimeout(init, 1000); }, false); } if (!!rnode && rnode.offsetHeight !== 0) { rnode.classList.add('__hkbtn') ; rbutton.classList.remove('disabled'); if (rnode.textContent.length > 0) rbutton.innerHTML = rnode.textContent.substring(0,3); rbutton.title = rnode.textContent + ((!!rnode.href)? '\n' + rnode.href : ''); rbutton.addEventListener('click', ()=>{ click(rnode); setTimeout(init, 1000); }, false); } } href = document.location.href; } function creaElemIn(tagname, destin) { let theElem = destin.appendChild(document.createElement(tagname)); return theElem; } function addCSS(css, cssid) { let stylenode = creaElemIn('style',document.getElementsByTagName('head')[0]); stylenode.textContent = css; stylenode.type = 'text/css'; stylenode.id = cssid || ''; } function checkKey(e) { if (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey) return; if (checkTextArea(e.target)) return; //console.log("hknp_keydown:",e.keyCode); if (LastKEY.includes(e.keyCode) && !!lnode) { click(lnode); setTimeout(init, 1000); } if (NextKEY.includes(e.keyCode) && !!rnode) { click(rnode); setTimeout(init, 1000); } } function checkTextArea(node) { var name = node.localName.toLowerCase(); if (name == "textarea" || name == "input" || name == "select") { return true; } if (name == "div" && (node.id.toLowerCase().indexOf("textarea") != -1 || node.contentEditable !== false)) { return true; } return false; } function click(node) { if (node.onclick) node.onclick(); if (href !== document.location.href) return; if (node.click) node.click(); if (href !== document.location.href) return; if (node.href) location.href = node.href; } function xpath(query) { return unsafeWindow.document.evaluate( query, document, null, XPathR###lt.UNORDERED_NODE_SNAPSHOT_TYPE, null ); } function getNode(lnstr) { var node = getNodeByGeneralXpath(lnstr); // console.log("n1",lnstr,node); if (!node) node = getNodeBySpecialXpath(lnstr); // console.log("n2",lnstr,node); return node; } function getNodeByGeneralXpath(lnstr) { // lnstr 只支持输入 【last】 或者 【next】 var strs; strs = Strs[lnstr]; var x = GeneralXpaths; for (var i in x) { for (var j in strs) { var query = x[i][0] + strs[j] + x[i][1]; var nodes = xpath(query); if (nodes.snapshotLength > 0) return nodes.snapshotItem(0); } } return null; } function getNodeBySpecialXpath(lnstr) { // lnstr 只支持输入 【last】 或者 【next】 var s = SpecialXpaths; for (var i in s) { if (checkXpathUrl(s[i].urls)) { return xpath(s[i][lnstr]).snapshotItem(0); } } return null; } function checkXpathUrl(urls) { for (var i in urls) if (location.href.indexOf(urls[i]) >= 0) return true; return false; } if (top.location != self.location) return; unsafeWindow.document.addEventListener("keydown", checkKey, false);