置頂和置底按鈕

在所有頁面生成兩個按鈕,一個用於順滑回到頂部,一個用於持續滾動到底部,再次點擊取消滾動到底部

目前為 2024-08-21 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name 置頂和置底按鈕
  3. // @version 1.2.0.43
  4. // @description 在所有頁面生成兩個按鈕,一個用於順滑回到頂部,一個用於持續滾動到底部,再次點擊取消滾動到底部
  5. // @run-at document-end
  6. // @match *://*/*
  7. // @license MIT
  8. // @namespace https://greasyfork.org/zh-CN/users/1169082
  9. // @icon https://github.com/ChinaGodMan/UserScripts/raw/main/docs/icon/Scripts%20Icons/icons8-up-96.png
  10. // @supportURL https://github.com/ChinaGodMan/UserScripts/issues
  11. // @homepageURL https://github.com/ChinaGodMan/UserScripts
  12. // ==/UserScript==
  13.  
  14. (function () {
  15. 'use strict'
  16. let scrollTimeout
  17. var style = document.createElement('style')
  18. style.innerHTML = `
  19. :root {
  20. --button-size: 29.4px; /* 按钮的大小 */
  21. --button-margin: 1px; /* 按钮之间的间距 */
  22. }
  23.  
  24. .GO_TO_TOP_button, .GO_TO_BOTTOM_button {
  25. width: var(--button-size); /* 按钮大小 */
  26. height: var(--button-size); /* 按钮大小 */
  27. border-radius: 5.6px; /* 縮小30% */
  28. box-shadow: 0 3px 6px rgb(0 0 0 / 16%), 0 1px 2px rgb(0 0 0 / 23%);
  29. position: fixed;
  30. right: 14px; /* 缩小30% */
  31. display: flex;
  32. align-items: center;
  33. justify-content: center;
  34. z-index: 99999999;
  35. background-color: white;
  36. opacity: 0.8;
  37. transition: opacity 0.2s ease-in-out;
  38. cursor: pointer;
  39. }
  40.  
  41.  
  42.  
  43. .GO_TO_TOP_button svg, .GO_TO_BOTTOM_button svg {
  44. left: 16.8px; /* 縮小30% */
  45. height: 16.8px; /* 縮小30% */
  46. margin: 0;
  47. }
  48. .GO_TO_TOP_button {
  49. bottom: 49px; /* 縮小30% */
  50. }
  51. .GO_TO_BOTTOM_button {
  52. bottom: 14px; /* 縮小30% */
  53. }
  54. `
  55. document.head.appendChild(style)
  56.  
  57. const goToTop = () => {
  58. window.scrollTo({
  59. top: 0,
  60. behavior: 'smooth'
  61. })
  62. }
  63.  
  64. let bottomInterval
  65. const startScrollingToBottom = () => {
  66. bottomInterval = setInterval(() => {
  67. window.scrollTo({
  68. top: document.body.scrollHeight,
  69. behavior: 'smooth'
  70. })
  71. }, 1000)
  72.  
  73. let checkTimeout = setTimeout(() => {
  74. if (window.innerHeight + window.scrollY >= document.body.scrollHeight) {
  75. if (buttonBottom.style.backgroundColor === 'green') {
  76. buttonBottom.click()
  77. // alert("已处于最底端");
  78. }
  79. }
  80. }, 3000)
  81.  
  82. window.addEventListener('scroll', () => {
  83. if (window.innerHeight + window.scrollY < document.body.scrollHeight) {
  84. clearTimeout(checkTimeout)
  85. checkTimeout = setTimeout(() => {
  86. if (buttonBottom.style.backgroundColor === 'green') {
  87. buttonBottom.click()
  88. // alert("自动滚动到底部已停止。");
  89. }
  90. }, 3000)
  91. }
  92. })
  93. buttonBottom.style.opacity = '0.8'
  94. buttonBottom.style.display = 'flex'
  95. }
  96. const stopScrollingToBottom = () => {
  97. clearInterval(bottomInterval)
  98. }
  99.  
  100. const buttonTop = document.createElement('div')
  101. buttonTop.className = 'GO_TO_TOP_button'
  102. buttonTop.innerHTML = `
  103. <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
  104. <path d="M825.568 555.328l-287.392-289.28C531.808 259.648 523.488 256.576 515.2 256.64 514.08 256.544 513.12 256 512 256c-4.672 0-9.024 1.088-13.024 2.88-4.032 1.536-7.872 3.872-11.136 7.136l-259.328 258.88c-12.512 12.48-12.544 32.736-0.032 45.248 6.24 6.272 14.432 9.408 22.656 9.408 8.192 0 16.352-3.136 22.624-9.344L480 364.288V928c0 17.696 14.336 32 32 32s32-14.304 32-32V362.72l236.192 237.728c6.24 6.272 14.496 9.44 22.688 9.44s16.32-3.104 22.56-9.312C838.016 588.128 838.048 567.84 825.568 555.328z"/>
  105. <path d="M864 192H160C142.336 192 128 177.664 128 160s14.336-32 32-32h704c17.696 0 32 14.336 32 32S881.696 192 864 192z"/>
  106. </svg>`
  107.  
  108. const buttonBottom = document.createElement('div')
  109. buttonBottom.className = 'GO_TO_BOTTOM_button'
  110. buttonBottom.innerHTML = `
  111. <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
  112. <path d="M198.4 468.352l287.392 289.28c6.368 6.4 14.688 9.472 22.976 9.408 1.12 0.096 2.08 0.64 3.2 0.64 4.672 0 9.024-1.088 13.024-2.88 4.032-1.536 7.872-3.872 11.136-7.136l259.328-258.88c12.512-12.48 12.544-32.736 0.032-45.248-6.24-6.272-14.432-9.408-22.656-9.408-8.192 0-16.352 3.136-22.624 9.344L544 659.712V96c0-17.696-14.336-32-32-32s-32 14.304-32 32v565.28L243.808 423.552c-6.24-6.272-14.496-9.44-22.688-9.44s-16.32 3.104-22.56 9.312c-12.48 12.512-12.512 32.8-0.032 45.312z"/>
  113. <path d="M160 832h704c17.664 0 32 14.336 32 32s-14.336 32-32 32H160c-17.664 0-32-14.336-32-32s14.336-32 32-32z"/>
  114. </svg>`
  115.  
  116. let isScrollingToBottom = false
  117.  
  118. buttonTop.addEventListener('click', goToTop)
  119.  
  120. buttonBottom.addEventListener('click', () => {
  121. if (isScrollingToBottom) {
  122. stopScrollingToBottom()
  123. buttonBottom.style.transform = 'scale(1)'
  124. buttonBottom.style.backgroundColor = 'white' // 改回原来的背景色
  125. } else {
  126. startScrollingToBottom()
  127. buttonBottom.style.transform = 'scale(1.1)'
  128. buttonBottom.style.backgroundColor = 'green' // 改为绿色
  129. }
  130. isScrollingToBottom = !isScrollingToBottom
  131. })
  132.  
  133. buttonTop.style.display = 'none'
  134. buttonBottom.style.display = 'none'
  135. document.body.appendChild(buttonTop)
  136. document.body.appendChild(buttonBottom)
  137.  
  138. let timer
  139. window.addEventListener('scroll', () => {
  140. if (window.pageYOffset > 50) {
  141. buttonTop.style.opacity = '0.8'
  142. buttonTop.style.display = 'flex'
  143. buttonBottom.style.opacity = '0.8'
  144. buttonBottom.style.display = 'flex'
  145. } else if (window.pageYOffset === 0) {
  146. buttonTop.style.opacity = '0'
  147. buttonBottom.style.opacity = '0'
  148. setTimeout(() => {
  149. buttonTop.style.display = 'none'
  150. buttonBottom.style.display = 'none'
  151. }, 200)
  152. }
  153. clearTimeout(timer)
  154. timer = setTimeout(() => {
  155. buttonTop.style.opacity = '0'
  156. buttonBottom.style.opacity = '0'
  157. setTimeout(() => {
  158. buttonTop.style.display = 'none'
  159. buttonBottom.style.display = 'none'
  160. }, 200)
  161. }, 1800)
  162.  
  163. })
  164. })()