Jump to Top or Bottom

为所有网页增加可立即跳转至最大的可滚动区域顶部和底部的按钮

目前为 2025-02-21 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Jump to Top or Bottom
  3. // @namespace https://github.com/11ze
  4. // @author 11ze
  5. // @description 为所有网页增加可立即跳转至最大的可滚动区域顶部和底部的按钮
  6. // @version 0.0.14
  7. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAALVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////BHg4sAAAADXRSTlMAK1RVW1x3f4CI+vv8UJ/ShgAAAAFiS0dEDm+9ME8AAABqSURBVCjPY2CgHuCYgCbQexNNwe29DagKjmijKOG448C0dwKKAgYGZCVABQwMyErYjoBIrQKEEgEQwchAb4BuLQfYYdpILoU4HcmluSDPXUcyg+1OADOyAqCSo9bX8QchQ+519GhooKK3APJHHdKCOOK5AAAAAElFTkSuQmCC
  8. // @match *
  9. // @include *
  10. // @grant none
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. /* ************************ 页面效果 ************************ */
  15.  
  16. // const buttonColor = '241,148,138,0.500'; // 红色
  17. const buttonColor = '247,220,111,0.667'; // 奶黄
  18.  
  19. const topImage =
  20. 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAAe0lEQVRYhe2QOwqAMBAFB0/jXazEwutYehsrz+aviE3SCH4SdQV5A9sEsjMsCCGEuEcDtF/KnR/ziCCf/Tj/Zi4vgQIYMbrEVh4widiTm0ScyV+NuCp/JSJW/mhEqjwqIjtYMAALUANdQkAPVMDkdyWRp358eIcQQvyYFerfNk+Wc2XSAAAAAElFTkSuQmCC';
  21. const downImage =
  22. 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAAlUlEQVRYhe3QMRLBUBRA0YMxtmIvqajsRCk6W1FYhMKamIyZKCQzmoT8SBTerf979/5HEARB0M7ylztyFFj1kGe44dD0YNoyfMUcx8SIDCcsql1JbFHijk2HubXn9UrsUuWpEV+Vd40YRP5pxKDydxGjyJsiRpXX5JWweJHnY8lr6kv0+vmsR8AFE5yx77EnCILgz3kAzr4zPi4gwh0AAAAASUVORK5CYII=';
  23.  
  24. const sameCssText = `opacity:0.3;
  25. -moz-transition-duration:0.2s;
  26. -webkit-transition-duration:0.2s;
  27. border-radius:5px 5px 5px 5px;
  28. cursor:pointer;
  29. position:fixed;
  30. width:40px;
  31. height:40px;
  32. right:0px;
  33. z-index:9999;`;
  34.  
  35. function createTopButton() {
  36. const cssText = `${sameCssText}
  37. background:url("data:image/png;base64,${topImage}")
  38. no-repeat scroll 50% 50% rgba(${buttonColor});
  39. bottom:50%`;
  40. createButton(cssText, true);
  41. }
  42. if (self == top) createTopButton();
  43.  
  44. function createBottomButton() {
  45. const cssText = `${sameCssText}
  46. background:url("data:image/png;base64,${downImage}")
  47. no-repeat scroll 50% 50% rgba(${buttonColor});
  48. top:51%`;
  49. createButton(cssText, false);
  50. }
  51. if (self == top) createBottomButton();
  52.  
  53. function createButton(cssText, isTop) {
  54. const button = document.createElement('span');
  55. button.style.cssText = cssText;
  56. button.addEventListener(
  57. 'mouseover',
  58. function () {
  59. button.style.opacity = 0.8;
  60. },
  61. false
  62. );
  63. button.addEventListener(
  64. 'mouseout',
  65. function () {
  66. button.style.opacity = 0.2;
  67. },
  68. false
  69. );
  70. button.addEventListener(
  71. 'click',
  72. function () {
  73. if (window.scrollHeight) {
  74. window.scrollTo(0, isTop ? 0 : document.body.scrollHeight);
  75. return;
  76. }
  77.  
  78. const target = getTarget();
  79. if (target) {
  80. target.scrollIntoView({ block: isTop ? 'start' : 'end' });
  81. return;
  82. }
  83.  
  84. runScrollableElements(isTop);
  85. },
  86. false
  87. );
  88. document.body.appendChild(button);
  89. }
  90.  
  91. function getTarget() {
  92. // QQ 邮箱邮件详情 https://mail.qq.com/cgi-bin/frame_html
  93. const iframe = document.getElementById('mainFrame');
  94. if (iframe) {
  95. const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
  96. const mailText = iframeDocument.getElementById('qqmail_mailcontainer');
  97. if (mailText) {
  98. return mailText;
  99. }
  100. }
  101. }
  102.  
  103. function runScrollableElements(isTop) {
  104. const elements = document.querySelectorAll('*');
  105. for (const e of elements) {
  106. if (
  107. e.scrollHeight > e.clientHeight &&
  108. e.scrollHeight > 300 &&
  109. e.scrollWidth > 300 &&
  110. !e.innerHTML.includes('<html')
  111. ) {
  112. if (isTop) {
  113. e.scrollTo(0, 0);
  114. } else {
  115. e.scrollTo(0, e.scrollHeight);
  116. }
  117. }
  118. }
  119. }