您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Smooth scrolling on pages using javascript and jquery
当前为
// ==UserScript== // @name Smoothscroll // @include http* // @author Creec Winceptor // @description Smooth scrolling on pages using javascript and jquery // @namespace https://greasyfork.org/users/3167 // @run-at document-idle // @grant none // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @version 1.1.0 // ==/UserScript== if (window.top != window.self) //don't run on frames or iframes return; //DEFAULT SETTINGS HERE //DO NOT CHANGE ANYTHING HERE ANYMORE, USE SCRIPT COMMANDS -> CONFIGURE SMOOTHSCROLL //Smoothness factor value (how strong the smoothing effect is) //values: 1-(infinite) var smoothness = 30; //Scroll sensitivity //values: anything? (default 1.00) var sensitivity = 1; //Acceleration sensitivity //values: anything? (default 1.50) var acceleration = 1; //Refreshrate setting //values: 30-144 (default = 60/72/120/144 = same as your monitor hz) var baserefreshrate = 60; //Alternative scrolling multiplier //values: true/false (try to set this to true if scrolling is too slow/doesn't work) var alternative_sensitivity_multiplier = false; //CODE STARTS HERE var minimal_jquery_version = 200; //max retries var jquery_retry_max = 5; var jquery_retry_count = 0; var DEBUG = false; var WEBKIT = false; //this.$ = this.jQuery = jQuery.noConflict(true); console.log("Loading smoothscroll..."); if (smoothness>100) { smoothness = 100; } if (baserefreshrate <= 30 || baserefreshrate>144) { baserefreshrate = 144; } refreshrate = baserefreshrate; var animationduration = Math.round(1000/refreshrate); //var relativeratio = Math.round(51-smoothness/2)/100; var relativeratio = Math.round(1/(1+smoothness*refreshrate/baserefreshrate)*100)/100; //var relativeratio = relativeratio; var lastLoop = new Date; //var lastrefreshrate = 0; function gameLoop() { var thisLoop = new Date; var refreshrate0 = 1000 / (thisLoop - lastLoop + 1); lastLoop = thisLoop; refreshrate = refreshrate + (refreshrate0-refreshrate)*0.1; refreshrate = Math.round(refreshrate); if (DEBUG) { console.log(refreshrate); } //console.log(refreshrate); animationduration = Math.round(1000/(refreshrate)); //var relativeratio = Math.round(51-smoothness/2)/100; relativeratio = Math.round(1/(1+smoothness*refreshrate/baserefreshrate)*100)/100; } gameLoop(); function InitSmoothscroll() { //LoadConfig(); //InitConfigmenu(); var startposition = false; var targetposition = 0; var position = 0; var scrollfocus = ss$('body'); var mousemoved = true; function hasScrollBarVisible(element) { //return (document.documentElement.scrollHeight !== document.documentElement.clientHeight); // Get the computed style of the body element var cStyle = element.currentStyle||window.getComputedStyle(element, ""); // Check the overflow and overflowY properties for "auto" and "visible" values var scrollbar1 = cStyle.overflow == "scroll" || cStyle.overflowY == "scroll"; var scrollbar2 = cStyle.overflow == "auto" || cStyle.overflowY == "auto"; var scrollbar = scrollbar1 || scrollbar2; return scrollbar; } function hasscrollbars(scrollfocus) { var hasvisiblescrollbars = hasScrollBarVisible(scrollfocus); var parentelement = ss$(scrollfocus).parent(); if ( ss$(parentelement)) { if (ss$(parentelement).is("textarea") || ss$(scrollfocus).is("textarea") || ss$(parentelement).is("article") || ss$(parentelement).is("article")) { return true; } else { if (ss$(parentelement).hasClass( "yt-scrollbar" ) || ss$(scrollfocus).hasClass( "yt-scrollbar" )) { return true; } return hasvisiblescrollbars; } } else { return hasvisiblescrollbars; } return false; } function UpdatePosition(element) { gameLoop(); var positiondelta = ss$(element)[0].getAttribute( "positiondelta" ); //var smoothdelta = Math.sqrt(positiondelta*positiondelta*relativeratio); var smoothdelta = Math.sqrt(positiondelta*positiondelta*relativeratio); if (positiondelta<0) { smoothdelta = smoothdelta*(-1); } //var relative = position - ss$(element).scrollTop(); //console.log("smoothdelta:" + smoothdelta); if (Math.abs( (positiondelta-smoothdelta)) <= 1 ) { ss$(element).stop(); ss$(element).animate({ scrollTop: '+=' + Math.round(positiondelta) }, animationduration, "linear", function() { ss$(element).attr( "positiondelta",0 ); ss$(element)[0].setAttribute( "positiondelta",0 ); if (DEBUG) { ss$(element).css( "border", "1px solid red" ); } }); } else { ss$(element).stop(); ss$(element).animate({ scrollTop: '+=' + Math.round(smoothdelta) }, animationduration, "linear", function() { ss$(element).attr( "positiondelta",positiondelta-smoothdelta ); ss$(element)[0].setAttribute("positiondelta",positiondelta-smoothdelta ); UpdatePosition(element); if (DEBUG) { ss$(element).css( "border", "1px solid red" ); } }); } } function MouseScroll (e) { gameLoop(); var mul = 1; if (!WEBKIT || alternative_sensitivity_multiplier) mul = 40; var x = e.deltaX*mul; var y = e.deltaY*mul; if (mousemoved) { scrollfocus = UpdateFocus(x,y); mousemoved = false; } // var positiondelta = 0; var lastscrolltop = 0; var parentelement = ss$(scrollfocus).parent(); var rolled = y; var lastscrolltop = ss$(scrollfocus).scrollTop(); ss$(scrollfocus).scrollTop(lastscrolltop+rolled); if (ss$(scrollfocus).scrollTop()==lastscrolltop) { if (!ss$(scrollfocus).is("html")) { //scrollfocus = ss$(scrollfocus); //focus = UpdateFocus(event); //return MouseScroll (event); //console.log("false"); //return false; scrollfocus = UpdateFocus(x,y); return false; } else { //console.log("true"); //return false; } } else { e.preventDefault(); } ss$(scrollfocus).scrollTop(lastscrolltop); if (ss$(scrollfocus)[0].getAttribute("positiondelta")==undefined) { positiondelta = 0; //console.log("positiondelta: undefined"); } else { positiondelta = ss$(scrollfocus)[0].getAttribute("positiondelta"); //console.log("positiondelta: " + positiondelta); } positiondelta = positiondelta*1; var direction = rolled/Math.abs(rolled); //var positiondeltadelta = rolled*sensitivity + Math.sqrt(Math.abs(positiondelta/rolled))*acceleration*rolled; //var positiondeltadelta = rolled*(sensitivity+Math.sqrt(Math.abs(positiondelta))*acceleration); var positiondeltadelta = Math.round(rolled*sensitivity + Math.sqrt(Math.abs(positiondelta-rolled*sensitivity))*acceleration*rolled*0.05/sensitivity); positiondelta = positiondelta + positiondeltadelta; ss$(scrollfocus)[0].setAttribute("positiondelta",positiondelta ); UpdatePosition(ss$(scrollfocus)); return true; } function canscroll(element, dir) { var scrollable = ss$(element); var lastscrolltop = ss$(scrollable).scrollTop(); ss$(scrollable).scrollTop(lastscrolltop+dir); if (ss$(scrollable).scrollTop()==lastscrolltop && dir!=0) { ss$(scrollable).scrollTop(lastscrolltop); return false; } else { ss$(scrollable).scrollTop(lastscrolltop); return true; } } function UpdateFocus(x,y) { var dir = y; var nodelist = document.querySelectorAll( ":hover" ); ss$(nodelist).stop(); //console.log(nodelist); if (WEBKIT) { scrollfocus = ss$('body'); } else { scrollfocus = ss$('html'); } for (var i = nodelist.length-1; i >= 0 ; i--) { //var parent = nodelist[i-1]; var newfocus = nodelist[i]; if (DEBUG) { ss$(newfocus).css( "border", "1px solid blue" ); //var debugtimer = setTimeout(function(){ ss$(newfocus).css( "border", "0px solid white" ); }, 1000); } //if (ss$(newfocus).hasScrollBar3() && hasScrollBarVisible(newfocus) && canscroll(newfocus, dir) && hasscrollbars(newfocus)) if (canscroll(newfocus, dir) && hasscrollbars(newfocus)) { scrollfocus = ss$(newfocus); return newfocus; } } return scrollfocus; } ss$('html').bind({ //mousewheel: function(e) { //if (DEBUG) //{ // console.log(scrollfocus); //} //console.log("scrolling"); //MouseScroll(e.originalEvent); //}, mousemove: function(e) { mousemoved = true; }, mousedown: function(e) { if (DEBUG) { console.log(scrollfocus); } if (scrollfocus) { ss$(scrollfocus)[0].setAttribute( "positiondelta",0 ); ss$(scrollfocus).stop(); } scrollfocus = UpdateFocus(0,0); console.log("click"); } }); //Init(window); document.documentElement.addEventListener("wheel", function(e){ MouseScroll(e); //console.log("scrolling"); }); /*var oldpos = ss$('body').scrollTop(); ss$('body').scrollTop(1); var iswebkit = ss$('body').scrollTop()>0; ss$('body').scrollTop(oldpos);*/ //WEBKIT = 'webkitRequestAnimationFrame' in window; WEBKIT = document.compatMode == 'CSS1Compat' //console.log("window: " + window); console.log("Smoothscroll initiated! Webkit: " + WEBKIT); } var JQUERY = false; var OWNJQUERY = false; var OLDJQUERY = false; var old$; var oldjQuery; var ss$; function jQueryVersion(temp$) { if (typeof temp$ == 'undefined' || typeof temp$.fn == 'undefined' || typeof temp$.fn.jquery == 'undefined') { return 0; } var versiontable = temp$.fn.jquery.split('.'); var version = 0; for (var i = versiontable.length-1; i >= 0; i--) { var power = versiontable.length-i; version += Math.pow(10,power-1)*versiontable[i]; } return version; } function LoadConfig() { smoothness = GM_getValue( 'smoothness', smoothness ); sensitivity = GM_getValue( 'sensitivity', sensitivity ); acceleration = GM_getValue( 'acceleration', acceleration ); baserefreshrate = GM_getValue( 'baserefreshrate', baserefreshrate ); //alternative_sesitivity_multiplier = GM_getValue( 'alternative_sesitivity_multiplier', alternative_sesitivity_multiplier ); console.log("Config for smoothscroll loaded!") } function SaveConfig() { GM_setValue( 'smoothness', document.getElementById('ss-smoothness').value) GM_setValue( 'sensitivity', document.getElementById('ss-sensitivity').value) GM_setValue( 'acceleration', document.getElementById('ss-acceleration').value) GM_setValue( 'baserefreshrate', document.getElementById('ss-baserefreshrate').value) //console.log(document.getElementById('ss-alternative_sesitivity_multiplier').checked) console.log("Config for smoothscroll saved!") } function InitConfigmenu() { console.log("Initiating smoothscroll config..."); var configbar = document.createElement('div'); configbar.setAttribute("id","ss-configbar"); configbar.innerHTML = '<div style="display:block; width: 100%; height: auto; border: 0px solid #aaaaaa; background-color: grey;">Config page for smoothscroll (refresh page for changes to apply!) Made by: Creec Winceptor</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>'; var configparent = document.getElementsByTagName("body")[0]; configbar.style.width = '100%'; configbar.style.display = 'none'; configbar.style.position = 'absolute'; configbar.style.zIndex = '9999'; configbar.style.backgroundColor = 'white'; configparent.insertBefore(configbar, configparent.childNodes[0]); ss$("#ss-close").click(function() { //ss$("#ss-config").animate({ // height: '0' //}, 100); ss$("#ss-configbar").hide("slow"); }); ss$("#ss-save").click(function() { SaveConfig(); }); //ss$("#ss-configbar").hide(); } function ConfigSmoothscroll() { if (typeof ss$ == 'undefined'){ alert("Smoothscroll is not running properly on this page!"); return; } //ss$("#ss-config").animate({ // height: '100px' //}, 100); ss$("#ss-configbar").show("slow"); ss$("html, body").animate({ scrollTop: 0 }, "slow"); } function LoadjQuery(loading) { if (loading) { console.log("Waiting for jQuery..."); if (typeof $ == 'undefined' || typeof jQuery == 'undefined' || jQueryVersion($)<minimal_jquery_version) { if (jquery_retry_count<jquery_retry_max) { jquery_retry_count++; setTimeout(function() { LoadjQuery(true); }, 100); } else { console.log("Failed to load smoothscroll!"); if (typeof old$ != 'undefined') { $ = old$; } if (typeof oldjQuery != 'undefined') { jQuery = oldjQuery; } } } else { ss$ = $; ssjQuery = jQuery; console.log("jQuery loaded!"); if (typeof old$ != 'undefined') { $ = old$; } if (typeof oldjQuery != 'undefined') { jQuery = oldjQuery; } console.log("Page jQuery version: " + jQueryVersion(old$)); console.log("Script jQuery version: " + jQueryVersion(ss$)); InitSmoothscroll(); } } else { console.log("Loading own jQuery..."); jquery_retry_count = 0; var filename = "https://code.jquery.com/jquery-2.2.3.js"; var fileref = document.createElement('script'); fileref.setAttribute("type","text/javascript"); fileref.setAttribute("src", filename); if (typeof fileref!="undefined") { var scriptparent = document.getElementsByTagName("head")[0]; if (typeof scriptparent=="undefined") { var scriptparent = document.createElement('head'); document.getElementsByTagName("html")[0].appendChild(scriptparent); } scriptparent.appendChild(fileref); } LoadjQuery(true); } } function Init() { if (typeof ss$ == 'undefined' ) { var sitejquery = !(typeof $ == 'undefined' || typeof jQuery == 'undefined'); if (sitejquery && jQueryVersion($)>=minimal_jquery_version) { ss$ = $; ssjQuery = jQuery; console.log("Reusing page jQuery..."); console.log("Page jQuery version: " + jQueryVersion($)); InitSmoothscroll(); } else { if (typeof $ != 'undefined' && typeof old$ == 'undefined') { old$ = $; } if (typeof jQuery != 'undefined' && typeof oldjQuery == 'undefined') { oldjQuery = jQuery; } LoadjQuery(false); } } } if (typeof ss$ == 'undefined'){ console.log("Initiating smoothscroll..."); Init(); //InitSmoothscroll(); GM_registerMenuCommand("Configurate smoothscroll", ConfigSmoothscroll); } else { console.log("Smoothscroll already loaded!"); }