ReadTools

**在 屏幕左侧 右击 触发 上一页 按钮,在 屏幕右侧 右击 触发 下一页 按钮;“扩大”翻页的区域,提高翻页效率,提升阅读体验**

  1. // ==UserScript==
  2. // @name ReadTools
  3. // @namespace github.com/ileler
  4. // @description **在 屏幕左侧 右击 触发 上一页 按钮,在 屏幕右侧 右击 触发 下一页 按钮;“扩大”翻页的区域,提高翻页效率,提升阅读体验**
  5. // @version 0.1
  6. // @author kerwin612
  7. // @license MIT
  8. // @include *
  9. // @require https://greasyfork.org/scripts/404294-kerwin612/code/Kerwin612.js?version=810055
  10. // @run-at document-start
  11. // @grant GM.getValue
  12. // @noframes
  13. // ==/UserScript==
  14.  
  15. config.funcConfig = {
  16. "http://www.duokan.com/reader/www/app.html":
  17. "function() {\
  18. return {\
  19. prevLink: document.getElementsByClassName('j-pageup')[0],\
  20. nextLink: document.getElementsByClassName('j-pagedown')[0]\
  21. };\
  22. }",
  23. "^.*gitbook\\.io.*$":
  24. "function() {\
  25. let loopEle = function(ele, classNamePattern) {\
  26. if (new RegExp(classNamePattern).test(ele.className)) return ele;\
  27. let rst = null;\
  28. for (let i = 0; i < ele.children.length; i++) {\
  29. if ((rst = loopEle(ele.children[i], classNamePattern))) break;\
  30. }\
  31. return rst;\
  32. };\
  33. let classBase;\
  34. let navPagesLinks;\
  35. let resultObj = {};\
  36. if ((classBase = document.getElementById('__GITBOOK__ROOT__CLIENT__').firstChild.className.split('--')[0]) && (navPagesLinks = loopEle(document.getElementById('__GITBOOK__ROOT__CLIENT__'), '^'+ classBase + '--navPagesLinks-.+$'))) {\
  37. navPagesLinks.children.forEach((val) => {\
  38. if (new RegExp('^'+ classBase + '.*--cardPrevious-.+$').test(val.className)) resultObj.prevLink = val;\
  39. if (new RegExp('^'+ classBase + '.*--cardNext-.+$').test(val.className)) resultObj.nextLink = val;\
  40. });\
  41. }\
  42. return resultObj;\
  43. }",
  44. }
  45.  
  46. func(
  47. //startup: url匹配上时就会执行的方法,无须返回值,仅执行一次
  48. (ctx) => {
  49. let url = window.location.href;
  50. for (let [k, v] of Object.entries(config.funcConfig)) {
  51. if ((url === k || url.startsWith(k) || new RegExp(k).test(url))) {
  52. ctx.findEleFunc = config.funcConfig[k];
  53. break;
  54. }
  55. }
  56. if (!ctx.findEleFunc) return;
  57. ctx.bindEle = function() {
  58. try {
  59. delete ctx.prevLink;
  60. delete ctx.nextLink;
  61.  
  62. let findEle = Function('return (' + ctx.findEleFunc + ')')()();
  63. if (!findEle) return false;
  64. ctx.prevLink = findEle.prevLink;
  65. ctx.nextLink = findEle.nextLink;
  66.  
  67. if (ctx.prevLink) {
  68. ctx.prevLink.oldclick = ctx.prevLink.oldclick || ctx.prevLink.onclick;
  69. ctx.prevLink.onclick = function() {
  70. console.log('prev-click', ctx);
  71. ctx.prevLink.oldclick && ctx.prevLink.oldclick();
  72. }
  73. }
  74.  
  75. if (ctx.nextLink) {
  76. ctx.nextLink.oldclick = ctx.nextLink.oldclick || ctx.nextLink.onclick;
  77. ctx.nextLink.onclick = function() {
  78. console.log('next-click', ctx);
  79. ctx.nextLink.oldclick && ctx.nextLink.oldclick();
  80. }
  81. }
  82. return true;
  83. } catch(error) {}
  84. return false;
  85. }
  86. },
  87. //ready: url匹配上时就会执行的方法,返回bool类型的值,每30ms执行一次,直至此方法返回true后就不再执行
  88. (ctx) => {
  89. return !ctx.findEleFunc || ctx.bindEle();
  90. },
  91. //run: url匹配上且以上的ready方法返回true后执行的方法,无须返回值,仅执行一次
  92. (ctx) => {
  93. if (!ctx.findEleFunc) return;
  94. window.oncontextmenu = function(e) {
  95. if (e.screenY < document.body.clientHeight / 3 || !ctx.bindEle()) return true;
  96. e.preventDefault();
  97.  
  98. if (e.screenX > document.body.clientWidth / 2) {
  99. ctx.nextLink && ctx.nextLink.click();
  100. } else {
  101. ctx.prevLink && ctx.prevLink.click();
  102. }
  103. return false; // cancel default menu
  104. }
  105. }
  106. );