Greasy Fork镜像 还支持 简体中文。

Smoothscroll

Smooth scrolling on pages using javascript

目前為 2018-03-08 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Smoothscroll
  3. // @author Creec Winceptor
  4. // @description Smooth scrolling on pages using javascript
  5. // @namespace https://gf.qytechs.cn/users/3167
  6. // @include *
  7. // @version 5.0
  8. // ==/UserScript==
  9.  
  10. //dev
  11. var DEBUG = false;
  12. var REFRESHRATE = 60;
  13.  
  14. //settings
  15. var SMOOTHNESS = 0.5;
  16. var ACCELERATION = 0.5;
  17.  
  18.  
  19.  
  20.  
  21. function IsScrollable(element, dir)
  22. {
  23. var checkradius = 2; //pixels to try scrolling
  24. if (dir>0)
  25. {
  26. dir = checkradius;
  27. }
  28. if (dir<0)
  29. {
  30. dir = -checkradius;
  31. }
  32.  
  33. var originalscroll = element.scrollTop;
  34. var testscroll = Math.round(originalscroll + dir);
  35. element.scrollTop = testscroll;
  36. var scrollable = Math.round(element.scrollTop)==testscroll;
  37. element.scrollTop = originalscroll;
  38. return scrollable;
  39. }
  40.  
  41. function HasScrollbars(element)
  42. {
  43. //return (document.documentElement.scrollHeight !== document.documentElement.clientHeight);
  44. // Get the computed style of the body element
  45. var cStyle = element.currentStyle||window.getComputedStyle(element, "");
  46. // Check the overflow and overflowY properties for "auto" and "visible" values
  47. var scrollbar1 = cStyle.overflow == "scroll" || cStyle.overflowY == "scroll";
  48.  
  49. var scrollbar2 = cStyle.overflow == "auto" || cStyle.overflowY == "auto";
  50. //body or html always have scrollbars
  51. var scrollbar3 = element==document.body || element==document.documentElement;
  52. var scrollbar = scrollbar1 || scrollbar2 || scrollbar3;
  53. return scrollbar;
  54. }
  55.  
  56. function Direction(number)
  57. {
  58. if (number>0)
  59. {
  60. return 1;
  61. }
  62. if (number<0)
  63. {
  64. return -1;
  65. }
  66. return 0;
  67. }
  68.  
  69. function Timeout(element, newtimeout)
  70. {
  71. if (newtimeout!=undefined)
  72. {
  73. var oldtimeout = element.ScrollTimeout;
  74. if (oldtimeout!=undefined)
  75. {
  76. clearTimeout(oldtimeout);
  77. }
  78. element.ScrollTimeout = newtimeout;
  79. return newtimeout;
  80. }
  81. else
  82. {
  83. var oldtimeout = element.ScrollTimeout;
  84. if (oldtimeout!=undefined)
  85. {
  86. return oldtimeout;
  87. }
  88. return null;
  89. }
  90. }
  91.  
  92. function ScrollDelta(element, newdelta)
  93. {
  94. if (newdelta!=undefined)
  95. {
  96. element.ScrollDelta = newdelta;
  97. return newdelta;
  98. }
  99. else
  100. {
  101. var olddelta = element.ScrollDelta;
  102. if (olddelta!=undefined)
  103. {
  104. return olddelta;
  105. }
  106. return 0;
  107. }
  108. }
  109. function ScrollDeltaDelta(element, newdelta)
  110. {
  111. if (newdelta!=undefined)
  112. {
  113. element.ScrollDelta2 = newdelta;
  114. return newdelta;
  115. }
  116. else
  117. {
  118. var olddelta = element.ScrollDelta2;
  119. if (olddelta!=undefined)
  120. {
  121. return olddelta;
  122. }
  123. return 0;
  124. }
  125. }
  126.  
  127. function GetTarget(e) {
  128. var direction = e.deltaY;
  129. var nodes = e.path;
  130. for (var i=0; i<nodes.length; i++) {
  131. var node = nodes[i];
  132. if (IsScrollable(node, direction) && HasScrollbars(node))
  133. {
  134. if (DEBUG) {
  135. console.log("scrollbar: ");
  136. console.log(node);
  137. }
  138. return node;
  139. }
  140. }
  141.  
  142. return null;
  143. }
  144.  
  145. function UpdateScroll(e, target) {
  146. var updaterate = Math.floor(1000/(REFRESHRATE));
  147. var scrolldelta = ScrollDelta(target);
  148. var scrolldirection = Direction(scrolldelta);
  149.  
  150. var scrollratio = 1-Math.pow( REFRESHRATE, -1/(REFRESHRATE*SMOOTHNESS));
  151. //var scrollratio = 1-Math.pow( dynamicrefreshrate, -1/dynamicrefreshrate*smoothness*basespeed);
  152. var scrolldeltadelta = ScrollDeltaDelta(target);
  153. var scrollrate = scrolldelta*scrollratio;
  154. if (Math.abs(scrolldelta)>1) {
  155. var fullscrolls = Math.floor(Math.abs(scrollrate))*scrolldirection;
  156. var partialscrolls = scrollrate - fullscrolls;
  157.  
  158. var additionalscrolls = Math.floor(Math.abs(scrolldeltadelta + partialscrolls))*scrolldirection;
  159. var partialsleftover = scrolldeltadelta + partialscrolls - additionalscrolls;
  160.  
  161. ScrollDelta(target, scrolldelta-fullscrolls-additionalscrolls);
  162. target.scrollTop += fullscrolls + additionalscrolls;
  163.  
  164. ScrollDeltaDelta(target, partialsleftover);
  165.  
  166.  
  167. Timeout(target, setTimeout(function() {
  168.  
  169. UpdateScroll(e, target);
  170. }, updaterate));
  171. } else
  172. {
  173. ScrollDelta(target, 0);
  174. ScrollDeltaDelta(target, 0);
  175. }
  176. }
  177.  
  178. function StopScroll(e) {
  179. var nodes = e.path;
  180. for (var i=0; i<nodes.length; i++) {
  181. var node = nodes[i];
  182. ScrollDelta(node, null);
  183. Timeout(node, null);
  184. }
  185. }
  186.  
  187. function StartScroll(e, target) {
  188. var direction = e.deltaY;
  189. var scrolldelta = ScrollDelta(target);
  190.  
  191. var accelerationratio = Math.sqrt(Math.abs(scrolldelta/direction*ACCELERATION));
  192. var acceleration = Math.round(direction*accelerationratio);
  193.  
  194. ScrollDelta(target, scrolldelta + direction + acceleration);
  195. ScrollDeltaDelta(target, 0);
  196. if (e.defaultPrevented)
  197. {
  198. return true;
  199. }
  200. else
  201. {
  202. UpdateScroll(e, target);
  203. e.preventDefault();
  204. }
  205. if (DEBUG) {
  206. console.log(target);
  207. console.log(ScrollDelta(target));
  208. }
  209. }
  210.  
  211.  
  212. function WheelEvent(e) {
  213. var target = GetTarget(e);
  214. if (target) {
  215. StartScroll(e, target);
  216. }
  217. }
  218.  
  219. function ClickEvent(e) {
  220. StopScroll(e);
  221. }
  222.  
  223. function Init()
  224. {
  225. if (window.SMOOTHSCROLL) {
  226. console.log("Smoothscroll: already loaded");
  227. return null;
  228. }
  229. if (window.top != window.self) {
  230. console.log("Smoothscroll: ignoring iframe");
  231. return null;
  232. }
  233. document.documentElement.addEventListener("wheel", function(e){
  234. WheelEvent(e);
  235. if (DEBUG) {
  236. console.log(e);
  237. }
  238. });
  239.  
  240. document.documentElement.addEventListener("mousedown", function(e){
  241. ClickEvent(e);
  242. if (DEBUG) {
  243. console.log(e);
  244. }
  245. });
  246. console.log("Smoothscroll: loaded");
  247. window.SMOOTHSCROLL = true;
  248. }
  249. Init();

QingJ © 2025

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