Smoothscroll

Smooth scrolling on pages using javascript and jquery

当前为 2016-05-28 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Smoothscroll
  3. // @include http*
  4. // @author Creec Winceptor
  5. // @description Smooth scrolling on pages using javascript and jquery
  6. // @namespace https://greasyfork.org/users/3167
  7. // @run-at document-idle
  8. // @grant none
  9. // @grant GM_getValue
  10. // @grant GM_setValue
  11. // @grant GM_registerMenuCommand
  12. // @version 0.0.1.20160528163457
  13. // ==/UserScript==
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21. //DEFAULT SETTINGS HERE
  22. //DO NOT CHANGE ANYTHING HERE ANYMORE, USE SCRIPT COMMANDS -> CONFIGURE SMOOTHSCROLL
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29. //Smoothness factor value (how strong the smoothing effect is)
  30. //values: 1-(infinite) (default = 30)
  31. var smoothness = 30;
  32.  
  33.  
  34. //Scroll sensitivity
  35. //values: anything? (default 1.00)
  36. var sensitivity = 1.00;
  37.  
  38.  
  39. //Acceleration sensitivity
  40. //values: anything? (default 1.00)
  41. var acceleration = 1.00;
  42.  
  43.  
  44. //Refreshrate setting
  45. //values: 30-144 (default = 60/72/120/144 = same as your monitor hz)
  46. var baserefreshrate = 60;
  47.  
  48.  
  49. //Alternative scrolling multiplier
  50. //values: true/false (try to set this to true if scrolling is too slow/doesn't work)
  51. var alternative_sesitivity_multiplier = false;
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59. //CODE STARTS HERE
  60.  
  61. var minimal_jquery_version = 200;
  62.  
  63. var DEBUG = false;
  64.  
  65. var WEBKIT = false;
  66.  
  67. //this.$ = this.jQuery = jQuery.noConflict(true);
  68.  
  69. if (window.top != window.self) //don't run on frames or iframes
  70. return;
  71.  
  72.  
  73.  
  74. if (smoothness>100)
  75. {
  76. smoothness = 100;
  77. }
  78.  
  79. if (baserefreshrate <= 30 || baserefreshrate>144)
  80. {
  81. baserefreshrate = 144;
  82. }
  83. refreshrate = baserefreshrate;
  84.  
  85. var animationduration = Math.round(1000/refreshrate);
  86. //var relativeratio = Math.round(51-smoothness/2)/100;
  87. var relativeratio = Math.round(1/(1+smoothness)*100)/100;
  88. //var relativeratio = relativeratio;
  89.  
  90.  
  91.  
  92. var lastLoop = new Date;
  93. //var lastrefreshrate = 0;
  94. function gameLoop() {
  95. var thisLoop = new Date;
  96. var refreshrate0 = 1000 / (thisLoop - lastLoop + 1);
  97. lastLoop = thisLoop;
  98. refreshrate = refreshrate + (refreshrate0-refreshrate)*0.01;
  99. refreshrate = Math.round(refreshrate);
  100. if (DEBUG)
  101. {
  102. console.log(refreshrate);
  103. }
  104. animationduration = Math.round(1000/(refreshrate));
  105. //var relativeratio = Math.round(51-smoothness/2)/100;
  106. relativeratio = Math.round(1/(1+smoothness*refreshrate/baserefreshrate)*100)/100;
  107. }
  108. gameLoop();
  109.  
  110.  
  111. function InitSmoothscroll()
  112. {
  113. LoadConfig();
  114.  
  115. InitConfigmenu();
  116.  
  117. var startposition = false;
  118. var targetposition = 0;
  119. var position = 0;
  120.  
  121. var scrollfocus = ss$('body');
  122. function hasScrollBarVisible(element)
  123. {
  124. //return (document.documentElement.scrollHeight !== document.documentElement.clientHeight);
  125. // Get the computed style of the body element
  126. var cStyle = element.currentStyle||window.getComputedStyle(element, "");
  127. // Check the overflow and overflowY properties for "auto" and "visible" values
  128. var scrollbar1 = cStyle.overflow == "scroll" || cStyle.overflowY == "scroll";
  129.  
  130. var scrollbar2 = cStyle.overflow == "auto" || cStyle.overflowY == "auto";
  131. var scrollbar = scrollbar1 || scrollbar2;
  132. return scrollbar;
  133. }
  134.  
  135.  
  136. function hasscrollbars(scrollfocus)
  137. {
  138. var hasvisiblescrollbars = hasScrollBarVisible(scrollfocus);
  139. var parentelement = ss$(scrollfocus).parent();
  140. if ( ss$(parentelement))
  141. {
  142. //if (ss$(parentelement).is("textarea") || ss$(scrollfocus).is("textarea"))
  143. if (ss$(parentelement).is("textarea") || ss$(scrollfocus).is("textarea") || ss$(parentelement).is("article") || ss$(parentelement).is("article"))
  144. {
  145. return true;
  146. }
  147. else
  148. {
  149. if (ss$(parentelement).hasClass( "yt-scrollbar" ) || ss$(scrollfocus).hasClass( "yt-scrollbar" ))
  150. {
  151. return true;
  152. }
  153. return hasvisiblescrollbars;
  154. }
  155. }
  156. else
  157. {
  158. //scrollfocus = ss$('body');
  159. //maxposition = ss$(scrollfocus).height();
  160. return hasvisiblescrollbars;
  161. }
  162. return false;
  163. }
  164.  
  165. function UpdatePosition(element)
  166. {
  167. gameLoop();
  168. var positiondelta = ss$(element)[0].getAttribute( "positiondelta" );
  169. //var smoothdelta = Math.sqrt(positiondelta*positiondelta*relativeratio);
  170. var smoothdelta = Math.sqrt(positiondelta*positiondelta*relativeratio);
  171. if (positiondelta<0)
  172. {
  173. smoothdelta = smoothdelta*(-1);
  174. }
  175. //var relative = position - ss$(element).scrollTop();
  176. //console.log("smoothdelta:" + smoothdelta);
  177. if (Math.abs( (positiondelta-smoothdelta)) <= 1 )
  178. {
  179. ss$(element).stop();
  180. ss$(element).animate({
  181. scrollTop: '+=' + Math.round(positiondelta)
  182. }, animationduration, "linear", function() {
  183. ss$(element).attr( "positiondelta",0 );
  184. ss$(element)[0].setAttribute( "positiondelta",0 );
  185. if (DEBUG)
  186. {
  187. ss$(element).css( "border", "1px solid red" );
  188. }
  189. });
  190. }
  191. else
  192. {
  193. ss$(element).stop();
  194. ss$(element).animate({
  195. scrollTop: '+=' + Math.round(smoothdelta)
  196. }, animationduration, "linear", function() {
  197. ss$(element).attr( "positiondelta",positiondelta-smoothdelta );
  198. ss$(element)[0].setAttribute("positiondelta",positiondelta-smoothdelta );
  199. UpdatePosition(element);
  200. if (DEBUG)
  201. {
  202. ss$(element).css( "border", "1px solid red" );
  203. }
  204. });
  205. }
  206. }
  207.  
  208.  
  209. function MouseScroll (x,y,e) {
  210. scrollfocus = UpdateFocus(x,y);
  211. var positiondelta = 0;
  212. var lastscrolltop = 0;
  213.  
  214. var parentelement = ss$(scrollfocus).parent();
  215. if ( ss$(parentelement))
  216. {
  217. if (ss$(parentelement).is("textarea") || ss$(scrollfocus).is("textarea"))
  218. {
  219. //return true;
  220. }
  221. else
  222. {
  223. if ( ss$(parentelement).height() < ss$(scrollfocus).height())
  224. {
  225. //maxposition = ss$(scrollfocus).height() - ss$(parentelement).height();
  226. }
  227. else
  228. {
  229. if (ss$(scrollfocus).height()==0)
  230. {
  231. //scrollfocus = ss$('body');
  232. //maxposition = ss$(scrollfocus).height();
  233. }
  234.  
  235. //scrollfocus = ss$('body');
  236. //return MouseScroll (event);
  237. //return true;
  238. }
  239. }
  240. }
  241. else
  242. {
  243. //scrollfocus = ss$('html');
  244. //maxposition = ss$(scrollfocus).height();
  245. }
  246. var rolled = y;
  247. //console.log("rolled: " + rolled);
  248. //if (ss$(scrollfocus).data("positiondelta" )==undefined)
  249. //$embellishment.data("embellishmentid",1)
  250. var lastscrolltop = ss$(scrollfocus).scrollTop();
  251. ss$(scrollfocus).scrollTop(lastscrolltop+rolled);
  252. if (ss$(scrollfocus).scrollTop()==lastscrolltop)
  253. {
  254. if (!ss$(scrollfocus).is("html"))
  255. {
  256. focus = parentelement;
  257. //focus = UpdateFocus(event);
  258. //return MouseScroll (event);
  259. //console.log("false");
  260. //return false;
  261. }
  262. else
  263. {
  264. //console.log("true");
  265. //return false;
  266. }
  267. }
  268. else
  269. {
  270. e.preventDefault();
  271. }
  272. ss$(scrollfocus).scrollTop(lastscrolltop);
  273. //console.log(scrollfocus);
  274. if (ss$(scrollfocus)[0].getAttribute("positiondelta")==undefined)
  275. {
  276. positiondelta = 0;
  277. //console.log("positiondelta: undefined");
  278. }
  279. else
  280. {
  281. positiondelta = ss$(scrollfocus)[0].getAttribute("positiondelta");
  282. //console.log("positiondelta: " + positiondelta);
  283. }
  284. positiondelta = positiondelta*1;
  285. var direction = rolled/Math.abs(rolled);
  286. //var positiondeltadelta = rolled*sensitivity + Math.sqrt(Math.abs(positiondelta/rolled))*acceleration*rolled;
  287. //var positiondeltadelta = rolled*(sensitivity+Math.sqrt(Math.abs(positiondelta))*acceleration);
  288. //
  289. var positiondeltadelta = Math.round(rolled*sensitivity + Math.sqrt(Math.abs(positiondelta-rolled*sensitivity))*acceleration*rolled*0.03/sensitivity);
  290. positiondelta = positiondelta + positiondeltadelta;
  291. ss$(scrollfocus)[0].setAttribute("positiondelta",positiondelta );
  292. UpdatePosition(ss$(scrollfocus));
  293. //element.innerHTML = "";
  294. //console.log("pos:" + position);
  295. //event.preventDefault();
  296. return true;
  297. }
  298.  
  299. function canscroll(element, dir)
  300. {
  301. var scrollable = ss$(element);
  302. var lastscrolltop = ss$(scrollable).scrollTop();
  303. ss$(scrollable).scrollTop(lastscrolltop+dir);
  304. if (ss$(scrollable).scrollTop()==lastscrolltop)
  305. {
  306. ss$(scrollable).scrollTop(lastscrolltop);
  307. return false;
  308. }
  309. else
  310. {
  311. ss$(scrollable).scrollTop(lastscrolltop);
  312. return true;
  313. }
  314. }
  315.  
  316. function UpdateFocus(x,y) {
  317. /*var dir = 0;
  318. if ('wheelDelta' in event) {
  319. dir = event.wheelDelta;
  320. }
  321. else { // Firefox
  322. // The measurement units of the detail and wheelDelta properties are different.
  323. dir = event.detail*(-120);
  324. }*/
  325. var dir = y;
  326. //console.log(dir);
  327. //dir = dir*(-1);
  328. //
  329. var nodelist = document.querySelectorAll( ":hover" );
  330. ss$(nodelist).stop();
  331. //console.log(nodelist);
  332. if (WEBKIT)
  333. {
  334. scrollfocus = ss$('body');
  335. }
  336. else
  337. {
  338. scrollfocus = ss$('html');
  339. }
  340. for (var i = nodelist.length-1; i >= 0; i--) {
  341. //var parent = nodelist[i-1];
  342. var newfocus = nodelist[i];
  343. if (DEBUG)
  344. {
  345. ss$(newfocus).css( "border", "1px solid blue" );
  346. //var debugtimer = setTimeout(function(){ ss$(newfocus).css( "border", "0px solid white" ); }, 1000);
  347. }
  348. //if (ss$(newfocus).hasScrollBar3() && hasScrollBarVisible(newfocus) && canscroll(newfocus, dir) && hasscrollbars(newfocus))
  349. if (canscroll(newfocus, dir) && hasscrollbars(newfocus))
  350. {
  351. scrollfocus = ss$(newfocus);
  352. return newfocus;
  353. }
  354. }
  355.  
  356. return scrollfocus;
  357. }
  358. ss$('body').bind({
  359. /*
  360. mousewheel: function(e) {
  361. if (DEBUG)
  362. {
  363. console.log(scrollfocus);
  364. }
  365. console.log("scrolling");
  366. MouseScroll(e.originalEvent);
  367. },
  368. */
  369. mousedown: function(e) {
  370. if (DEBUG)
  371. {
  372. console.log(scrollfocus);
  373. }
  374. if (scrollfocus)
  375. {
  376. ss$(scrollfocus)[0].setAttribute( "positiondelta",0 );
  377. ss$(scrollfocus).stop();
  378. }
  379. //scrollfocus = UpdateFocus(e.originalEvent);
  380. //console.log("click");
  381. }
  382. });
  383. //Init(window);
  384.  
  385. (function(window,document) {
  386.  
  387. var prefix = "", _addEventListener, onwheel, support;
  388.  
  389. // detect event model
  390. if ( window.addEventListener ) {
  391. _addEventListener = "addEventListener";
  392. } else {
  393. _addEventListener = "attachEvent";
  394. prefix = "on";
  395. }
  396.  
  397. // detect available wheel event
  398. support = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel"
  399. document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel"
  400. "DOMMouseScroll"; // let's assume that remaining browsers are older Firefox
  401.  
  402. window.addWheelListener = function( elem, callback, useCapture ) {
  403. _addWheelListener( elem, support, callback, useCapture );
  404.  
  405. // handle MozMousePixelScroll in older Firefox
  406. if( support == "DOMMouseScroll" ) {
  407. _addWheelListener( elem, "MozMousePixelScroll", callback, useCapture );
  408. }
  409. };
  410.  
  411. function _addWheelListener( elem, eventName, callback, useCapture ) {
  412. elem[ _addEventListener ]( prefix + eventName, support == "wheel" ? callback : function( originalEvent ) {
  413. !originalEvent && ( originalEvent = window.event );
  414.  
  415. // create a normalized event object
  416. var event = {
  417. // keep a ref to the original event object
  418. originalEvent: originalEvent,
  419. target: originalEvent.target || originalEvent.srcElement,
  420. type: "wheel",
  421. deltaMode: originalEvent.type == "MozMousePixelScroll" ? 0 : 1,
  422. deltaX: 0,
  423. deltaZ: 0,
  424. preventDefault: function() {
  425. originalEvent.preventDefault ?
  426. originalEvent.preventDefault() :
  427. originalEvent.returnValue = false;
  428. }
  429. };
  430. // calculate deltaY (and deltaX) according to the event
  431. if ( support == "mousewheel" ) {
  432. event.deltaY = - 1/40 * originalEvent.wheelDelta;
  433. // Webkit also support wheelDeltaX
  434. originalEvent.wheelDeltaX && ( event.deltaX = - 1/40 * originalEvent.wheelDeltaX );
  435. } else {
  436. event.deltaY = originalEvent.detail;
  437. }
  438.  
  439. // it's time to fire the callback
  440. return callback( event );
  441.  
  442. }, useCapture || false );
  443. }
  444.  
  445. })(window,document);
  446. addWheelListener( window, function( e ) {
  447. var mul = 1;
  448. if (!WEBKIT || alternative_sesitivity_multiplier)
  449. mul = 40;
  450. //console.log( e.deltaY );
  451. MouseScroll(e.deltaX*mul,e.deltaY*mul, e);
  452. });
  453.  
  454. /*var oldpos = ss$('body').scrollTop();
  455. ss$('body').scrollTop(1);
  456. var iswebkit = ss$('body').scrollTop()>0;
  457. ss$('body').scrollTop(oldpos);*/
  458.  
  459. //WEBKIT = 'webkitRequestAnimationFrame' in window;
  460. WEBKIT = document.compatMode == 'CSS1Compat'
  461. //console.log("window: " + window);
  462. console.log("Smoothscroll initiated! Webkit: " + WEBKIT);
  463. }
  464.  
  465. var JQUERY = false;
  466. var OWNJQUERY = false;
  467. var OLDJQUERY = false;
  468.  
  469. var old$;
  470. var oldjQuery;
  471.  
  472. //max retries
  473. var r_max = 10;
  474. var r_count = 0;
  475.  
  476. function Init(LEGACYWORKAROUND) {
  477. //if (typeof jQuery == 'function') {
  478. //if (typeof jQuery == 'undefined' || typeof $ == 'undefined' )
  479. JQUERY = true;
  480. if (typeof $ == 'undefined')
  481. {
  482. JQUERY = false;
  483. }
  484. else
  485. {
  486. if (typeof old$ == 'undefined') {
  487. old$ = $;
  488. }
  489. }
  490. if (typeof jQuery == 'undefined' )
  491. {
  492. JQUERY = false;
  493. }
  494. else
  495. {
  496. if (typeof oldjQuery == 'undefined') {
  497. oldjQuery = jQuery;
  498. }
  499. }
  500. OWNJQUERY = true;
  501. if (typeof ss$ == 'undefined' )
  502. {
  503. OWNJQUERY = false;
  504. }
  505. if (!OWNJQUERY){
  506. if (JQUERY) {
  507. var versiontable = $.fn.jquery.split('.');
  508. var version = 0;
  509. for (var i = versiontable.length-1; i >= 0; i--) {
  510. var power = versiontable.length-i;
  511. version += Math.pow(10,power-1)*versiontable[i];
  512. }
  513.  
  514. if (version<=minimal_jquery_version && LEGACYWORKAROUND)
  515. {
  516. console.log("Page jQuery OLD! Version: " + version);
  517. OLDJQUERY = true;
  518. }
  519. else
  520. {
  521. ss$ = $;
  522. OWNJQUERY = true;
  523. }
  524. }
  525. else
  526. {
  527. console.log("Page jQuery Missing!");
  528. }
  529. }
  530. if (!OWNJQUERY && LEGACYWORKAROUND)
  531. {
  532. console.log("Loading new jQuery...");
  533.  
  534. //this.$ = this.jQuery = jQuery.noConflict(true);
  535. //var $ = jQuery.noConflict();
  536.  
  537. //this.$ = this.jQuery = jQuery.noConflict(true);
  538.  
  539.  
  540. var filename = "https://code.jquery.com/jquery-2.2.3.js";
  541. var fileref = document.createElement('script');
  542. fileref.setAttribute("type","text/javascript");
  543. fileref.setAttribute("src", filename);
  544.  
  545. if (typeof fileref!="undefined")
  546. {
  547. var scriptparent = document.getElementsByTagName("head")[0];
  548.  
  549. if (typeof scriptparent=="undefined")
  550. {
  551. var scriptparent = document.createElement('head');
  552. document.getElementsByTagName("html")[0].appendChild(scriptparent);
  553. }
  554. scriptparent.appendChild(fileref);
  555. }
  556.  
  557. if (r_count<r_max)
  558. {
  559. setTimeout(function() {
  560. Init(LEGACYWORKAROUND);
  561. }, 300);
  562. return 0;
  563. }
  564. else
  565. {
  566. console.log("Failed to load smoothscroll!");
  567. }
  568. r_count++;
  569. }
  570. if (OWNJQUERY) {
  571. var versiontable = ss$.fn.jquery.split('.');
  572. var version = 0;
  573. for (var i = versiontable.length-1; i >= 0; i--) {
  574. var power = versiontable.length-i;
  575. version += Math.pow(10,power-1)*versiontable[i];
  576. }
  577.  
  578. console.log("Script jQuery OK! Version: " + version);
  579. InitSmoothscroll();
  580. }
  581. if (LEGACYWORKAROUND) {
  582. console.log("Restoring original jQuery...");
  583. if (typeof old$ != 'undefined') {
  584. $ = old$;
  585. }
  586. if (typeof oldjQuery != 'undefined') {
  587. jQuery = oldjQuery;
  588. }
  589. if (OLDJQUERY)
  590. {
  591. var versiontable = $.fn.jquery.split('.');
  592. var version = 0;
  593. for (var i = versiontable.length-1; i >= 0; i--) {
  594. var power = versiontable.length-i;
  595. version += Math.pow(10,power-1)*versiontable[i];
  596. }
  597.  
  598. console.log("Page jQuery OK! Version: " + version);
  599. }
  600. }
  601.  
  602. console.log("Finished loading smoothscroll!");
  603. }
  604.  
  605. function LoadConfig()
  606. {
  607. smoothness = GM_getValue( 'smoothness', smoothness );
  608. sensitivity = GM_getValue( 'sensitivity', sensitivity );
  609. acceleration = GM_getValue( 'acceleration', acceleration );
  610. baserefreshrate = GM_getValue( 'baserefreshrate', baserefreshrate );
  611. //alternative_sesitivity_multiplier = GM_getValue( 'alternative_sesitivity_multiplier', alternative_sesitivity_multiplier );
  612. console.log("Config for smoothscroll loaded!")
  613. }
  614.  
  615. function SaveConfig()
  616. {
  617. GM_setValue( 'smoothness', document.getElementById('ss-smoothness').value)
  618. GM_setValue( 'sensitivity', document.getElementById('ss-sensitivity').value)
  619. GM_setValue( 'acceleration', document.getElementById('ss-acceleration').value)
  620. GM_setValue( 'baserefreshrate', document.getElementById('ss-baserefreshrate').value)
  621. //console.log(document.getElementById('ss-alternative_sesitivity_multiplier').checked)
  622. console.log("Config for smoothscroll saved!")
  623. }
  624.  
  625. function InitConfigmenu()
  626. {
  627. var configbar = document.createElement('div');
  628. configbar.setAttribute("id","ss-configbar");
  629. configbar.innerHTML = '<div style="display:block; width: 100%; height: auto; border: 0px solid #aaaaaa; background-color: grey;">Config page for smoothscroll:</div><div id="ss-config" style="margin:3px; display:block; width: auto; height: auto; border: 0px solid #554433;"><table style="width:auto;"><tr><td>Smoothness</td><td><input type="number" id="ss-smoothness" min="0" max="100" value="' + smoothness + '"></td><td> Smoothness factor value (how strong the smoothing effect is)</td></tr><tr><td>Sensitivity</td><td><input type="number" id="ss-sensitivity" min="0" max="100" value="' + sensitivity + '"></td><td> Scroll sensitivity (duh)</td></tr><tr><td>Acceleration</td><td><input type="number" id="ss-acceleration" min="0" max="100" value="' + acceleration + '"></td><td> Acceleration of continuous scroll action (saves your finger)</td></tr><tr><td>Refreshrate</td><td><input type="number" id="ss-baserefreshrate" min="1" max="100" value="' + baserefreshrate + '"></td><td>Refreshrate of scrollanimation (60Hz default)</td></tr></table></div><div style="width: 100%; height: auto; text-align: center; background-color: grey;"><input id="ss-save" type="button" value="Save config" style="width: 44%; height: auto; border: 0px solid #aaaaaa; margin: 3px"/><input id="ss-close" type="button" value="Close config" style="width: 44%; height: auto; border: 0px solid #aaaaaa; margin: 3px"/><div>';
  630. var configparent = document.getElementsByTagName("body")[0];
  631. configbar.style.width = '100%';
  632. configbar.style.display = 'none';
  633. configbar.style.position = 'absolute';
  634. configbar.style.zIndex = '99';
  635. configbar.style.backgroundColor = 'white';
  636. configparent.insertBefore(configbar, configparent.childNodes[0]);
  637. ss$("#ss-close").click(function() {
  638. //ss$("#ss-config").animate({
  639. // height: '0'
  640. //}, 100);
  641. ss$("#ss-configbar").hide("slow");
  642. });
  643. ss$("#ss-save").click(function() {
  644. SaveConfig();
  645. });
  646. //ss$("#ss-configbar").hide();
  647. }
  648.  
  649. function ConfigSmoothscroll()
  650. {
  651. if (!OWNJQUERY){
  652. alert("Smoothscroll is not running properly on this page!");
  653. return;
  654. }
  655. //ss$("#ss-config").animate({
  656. // height: '100px'
  657. //}, 100);
  658. ss$("#ss-configbar").show("slow");
  659. ss$("html, body").animate({ scrollTop: 0 }, "slow");
  660. }
  661.  
  662. GM_registerMenuCommand("Configurate smoothscroll", ConfigSmoothscroll);
  663.  
  664. console.log("Loading smoothscroll...");
  665. Init(true);
  666. //InitSmoothscroll();