HotKey Next Page

按左右键快速翻页,也可点击浮动按钮快速翻页

目前為 2023-05-05 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name HotKey Next Page
  3. // @namespace hzhbest
  4. // @author hzhbest
  5. // @version 1.2
  6. // @description 按左右键快速翻页,也可点击浮动按钮快速翻页
  7. // @include http://*
  8. // @include https://*
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. // original author : scottxp@126.com (https://userscripts-mirror.org/scripts/show/87895)
  13. // mod by hzhbest : add hilite and float buttons
  14.  
  15. const nextStrs = [
  16. "下一页",
  17. "下页",
  18. "下一节",
  19. "下一章",
  20. "下一篇",
  21. "后一章",
  22. "后一篇",
  23. "后页>",
  24. "»",
  25. "next",
  26. "next page",
  27. "old",
  28. "older",
  29. "earlier",
  30. "下頁",
  31. "下一頁",
  32. "后一页",
  33. "后一頁",
  34. "翻下页",
  35. "翻下頁",
  36. "后页",
  37. "后頁",
  38. "下翻",
  39. "下一个",
  40. "下一张",
  41. "下一幅",
  42. ];
  43.  
  44. const lastStrs = [
  45. "上一页",
  46. "上页",
  47. "上一节",
  48. "上一章",
  49. "上一篇",
  50. "前一章",
  51. "前一篇",
  52. "<前页",
  53. "«",
  54. "previous",
  55. "prev",
  56. "previous page",
  57. "new",
  58. "newer",
  59. "later",
  60. "上頁",
  61. "上一頁",
  62. "前一页",
  63. "前一頁",
  64. "翻上页",
  65. "翻上頁",
  66. "前页",
  67. "前頁",
  68. "上翻",
  69. "上一个",
  70. "上一张",
  71. "上一幅",
  72. ];
  73.  
  74. const GeneralXpaths = [
  75. ["//a[(text()='", "')]"],
  76. ["//a[@class='", "']"],
  77. ["//input[@type='button' and @value='", "']"],
  78. ];
  79.  
  80. //编辑下面的数组来自定义规则
  81. const SpecialXpaths = [
  82. {
  83. //匹配的url
  84. urls: ["http://www.google.com"],
  85. //上一页节点的xpath
  86. last: "//a[@id='pnprev']",
  87. //下一页节点的xpath
  88. next: "//a[@id='pnnext']",
  89. },
  90. {
  91. urls: ["bilibili.com"],
  92. last: '//li[@class="be-pager-prev"]',
  93. next: '//li[@class="be-pager-next"]',
  94. },
  95. ];
  96. const LEFT = 37;
  97. const RIGHT = 39;
  98. const css = `.__hkbtn {outline: 3px solid #bb1a6a; font-size: larger;}
  99. .__hkbse {position: fixed; z-index: 1000; right: 2em; bottom: 5em; background: #fff9;}
  100. .__hkbse>div:first-of-type {display: none;}
  101. .__hkbse:hover>div:first-of-type {display: inline-block;}
  102. .__hkfbtn {width: 4em; height: 3em; display: inline-block; border: 2px solid #8a8a8a8a;
  103. cursor: pointer; text-align: center; font-size: 1.5em; line-height: 3em; opacity: 0.7;}
  104. .__hkfbtn.disabled {opacity: 0.3;}
  105. .__hkfbtn:hover {opacity: 1; background: #fbcf84dd;}
  106. `;
  107. addCSS(css);
  108.  
  109. var lnode = getNode(LEFT);
  110. var rnode = getNode(RIGHT);
  111. if (!!lnode || !!rnode) {
  112. var bnode = creaElemIn('div', document.body);
  113. bnode.className = '__hkbse';
  114. var lbutton = creaElemIn('div', bnode);
  115. var rbutton = creaElemIn('div', bnode);
  116. lbutton.className = rbutton.className = '__hkfbtn disabled';
  117. lbutton.innerHTML = "<";
  118. rbutton.innerHTML = ">";
  119. if (!!lnode && lnode.style.display !== 'none') {
  120. lnode.classList.add('__hkbtn') ;
  121. lbutton.classList.remove('disabled');
  122. lbutton.innerHTML = lnode.textContent.substring(0,3);
  123. lbutton.title = lnode.textContent + ((!!lnode.href)? '\n' + lnode.href : '');
  124. lbutton.addEventListener('click', ()=>{click(lnode);}, false);
  125. }
  126. if (!!rnode && rnode.style.display !== 'none') {
  127. rnode.classList.add('__hkbtn') ;
  128. rbutton.classList.remove('disabled');
  129. rbutton.innerHTML = rnode.textContent.substring(0,3);
  130. rbutton.title = rnode.textContent + ((!!rnode.href)? '\n' + rnode.href : '');
  131. rbutton.addEventListener('click', ()=>{click(rnode);}, false);
  132. }
  133. }
  134.  
  135. function creaElemIn(tagname, destin) {
  136. let theElem = destin.appendChild(document.createElement(tagname));
  137. return theElem;
  138. }
  139.  
  140. function addCSS(css) {
  141. let stylenode = creaElemIn('style',document.getElementsByTagName('head')[0]);
  142. stylenode.textContent = css;
  143. stylenode.type = 'text/css';
  144. stylenode.id = 'ali_c_toc';
  145. }
  146.  
  147. function checkKey(e) {
  148. if (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey) return;
  149. if (checkTextArea(e.target)) return;
  150. var node;
  151. if (e.keyCode == LEFT && !!lnode) {
  152. click(lnode);
  153. }
  154. if (e.keyCode == RIGHT && !!rnode) {
  155. click(rnode);
  156. }
  157. }
  158.  
  159. function checkTextArea(node) {
  160. var name = node.localName.toLowerCase();
  161. if (name == "textarea" || name == "input" || name == "select") {
  162. return true;
  163. }
  164. if (name == "div" && (node.id.toLowerCase().indexOf("textarea") != -1 || node.contentEditable !== false)) {
  165. return true;
  166. }
  167. return false;
  168. }
  169.  
  170. function click(node) {
  171. if (node.onclick) node.onclick();
  172. if (node.click) node.click();
  173. if (node.href) location.href = node.href;
  174. }
  175. function xpath(query) {
  176. return unsafeWindow.document.evaluate(
  177. query,
  178. document,
  179. null,
  180. XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
  181. null
  182. );
  183. }
  184. function getNode(keyCode) {
  185. var node = getNodeByGeneralXpath(keyCode);
  186. if (!node) node = getNodeBySpecialXpath(keyCode);
  187. return node;
  188. }
  189. function getNodeByGeneralXpath(keyCode) {
  190. var strs;
  191. if (keyCode == LEFT) strs = lastStrs;
  192. else if (keyCode == RIGHT) strs = nextStrs;
  193. else return null;
  194. var x = GeneralXpaths;
  195. for (var i in x) {
  196. for (var j in strs) {
  197. var query = x[i][0] + strs[j] + x[i][1];
  198. var nodes = xpath(query);
  199. if (nodes.snapshotLength > 0) return nodes.snapshotItem(0);
  200. }
  201. }
  202. return null;
  203. }
  204. function getNodeBySpecialXpath(keyCode) {
  205. var s = SpecialXpaths;
  206. for (var i in s) {
  207. if (checkXpathUrl(s[i].urls)) {
  208. if (keyCode == LEFT) {
  209. return xpath(s[i].last).snapshotItem(0);
  210. } else if (keyCode == RIGHT) {
  211. return xpath(s[i].next).snapshotItem(0);
  212. }
  213. }
  214. }
  215. return null;
  216. }
  217. function checkXpathUrl(urls) {
  218. for (var i in urls) if (location.href.indexOf(urls[i]) >= 0) return true;
  219. return false;
  220. }
  221. if (top.location != self.location) return;
  222. unsafeWindow.document.addEventListener("keydown", checkKey, false);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址