您需要先安装一个扩展,例如 篡改猴、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-load
- // @grant none
- // @require https://code.jquery.com/jquery-2.2.3.js
- // @version 0.0.1.20160524192429
- // ==/UserScript==
- this.$ = this.jQuery = jQuery.noConflict(true);
- //SETTINGS HERE
- //Smoothness factor value (how strong the smoothing effect is)
- //values: 1-(infinite) (default = 50)
- var smoothness = 30;
- //Scroll sensitivity
- //values: anything? (default 1.00)
- var sensitivity = 1.00;
- //Acceleration sensitivity
- //values: anything? (default 1.00)
- var acceleration = 1.00;
- //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_sesitivity_multiplier = false;
- var minimal_jquery_version = 200;
- var DEBUG = false;
- //CODE STARTS HERE
- if (window.top != window.self) //don't run on frames or iframes
- return;
- 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)*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.01;
- refreshrate = Math.round(refreshrate);
- if (DEBUG)
- {
- 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()
- {
- var startposition = false;
- var targetposition = 0;
- var position = 0;
- var scrollfocus = ss$('body');
- 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"))
- 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
- {
- //scrollfocus = ss$('body');
- //maxposition = ss$(scrollfocus).height();
- 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 (x,y,e) {
- scrollfocus = UpdateFocus(x,y);
- var positiondelta = 0;
- var lastscrolltop = 0;
- var parentelement = ss$(scrollfocus).parent();
- if ( ss$(parentelement))
- {
- if (ss$(parentelement).is("textarea") || ss$(scrollfocus).is("textarea"))
- {
- //return true;
- }
- else
- {
- if ( ss$(parentelement).height() < ss$(scrollfocus).height())
- {
- //maxposition = ss$(scrollfocus).height() - ss$(parentelement).height();
- }
- else
- {
- if (ss$(scrollfocus).height()==0)
- {
- //scrollfocus = ss$('body');
- //maxposition = ss$(scrollfocus).height();
- }
- //scrollfocus = ss$('body');
- //return MouseScroll (event);
- //return true;
- }
- }
- }
- else
- {
- scrollfocus = ss$('body');
- //maxposition = ss$(scrollfocus).height();
- }
- var rolled = y;
- //console.log("rolled: " + rolled);
- //if (ss$(scrollfocus).data("positiondelta" )==undefined)
- //$embellishment.data("embellishmentid",1)
- 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 lastscrolltop = ss$(scrollfocus).scrollTop();
- ss$(scrollfocus).scrollTop(lastscrolltop+rolled);
- if (ss$(scrollfocus).scrollTop()==lastscrolltop)
- {
- if (!ss$(scrollfocus).is("body"))
- {
- focus = parentelement;
- //focus = UpdateFocus(event);
- //return MouseScroll (event);
- //console.log("false");
- return false;
- }
- else
- {
- //console.log("true");
- return false;
- }
- }
- else
- {
- e.preventDefault();
- }
- ss$(scrollfocus).scrollTop(lastscrolltop);
- 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.03/sensitivity);
- positiondelta = positiondelta + positiondeltadelta;
- ss$(scrollfocus)[0].setAttribute("positiondelta",positiondelta );
- UpdatePosition(ss$(scrollfocus));
- //element.innerHTML = "";
- //console.log("pos:" + position);
- //event.preventDefault();
- 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)
- {
- ss$(scrollable).scrollTop(lastscrolltop);
- return false;
- }
- else
- {
- ss$(scrollable).scrollTop(lastscrolltop);
- return true;
- }
- }
- function UpdateFocus(x,y) {
- /*var dir = 0;
- if ('wheelDelta' in event) {
- dir = event.wheelDelta;
- }
- else { // Firefox
- // The measurement units of the detail and wheelDelta properties are different.
- dir = event.detail*(-120);
- }*/
- var dir = y;
- //console.log(dir);
- //dir = dir*(-1);
- //
- var nodelist = document.querySelectorAll( ":hover" );
- ss$(nodelist).stop();
- scrollfocus = ss$('body');
- 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$('body').bind({
- /*
- mousewheel: function(e) {
- if (DEBUG)
- {
- console.log(scrollfocus);
- }
- console.log("scrolling");
- MouseScroll(e.originalEvent);
- },
- */
- mousedown: function(e) {
- if (DEBUG)
- {
- console.log(scrollfocus);
- }
- if (scrollfocus)
- {
- ss$(scrollfocus)[0].setAttribute( "positiondelta",0 );
- ss$(scrollfocus).stop();
- }
- //scrollfocus = UpdateFocus(e.originalEvent);
- //console.log("click");
- }
- });
- //Init(window);
- (function(window,document) {
- var prefix = "", _addEventListener, onwheel, support;
- // detect event model
- if ( window.addEventListener ) {
- _addEventListener = "addEventListener";
- } else {
- _addEventListener = "attachEvent";
- prefix = "on";
- }
- // detect available wheel event
- support = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel"
- document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel"
- "DOMMouseScroll"; // let's assume that remaining browsers are older Firefox
- window.addWheelListener = function( elem, callback, useCapture ) {
- _addWheelListener( elem, support, callback, useCapture );
- // handle MozMousePixelScroll in older Firefox
- if( support == "DOMMouseScroll" ) {
- _addWheelListener( elem, "MozMousePixelScroll", callback, useCapture );
- }
- };
- function _addWheelListener( elem, eventName, callback, useCapture ) {
- elem[ _addEventListener ]( prefix + eventName, support == "wheel" ? callback : function( originalEvent ) {
- !originalEvent && ( originalEvent = window.event );
- // create a normalized event object
- var event = {
- // keep a ref to the original event object
- originalEvent: originalEvent,
- target: originalEvent.target || originalEvent.srcElement,
- type: "wheel",
- deltaMode: originalEvent.type == "MozMousePixelScroll" ? 0 : 1,
- deltaX: 0,
- deltaZ: 0,
- preventDefault: function() {
- originalEvent.preventDefault ?
- originalEvent.preventDefault() :
- originalEvent.returnValue = false;
- }
- };
- // calculate deltaY (and deltaX) according to the event
- if ( support == "mousewheel" ) {
- event.deltaY = - 1/40 * originalEvent.wheelDelta;
- // Webkit also support wheelDeltaX
- originalEvent.wheelDeltaX && ( event.deltaX = - 1/40 * originalEvent.wheelDeltaX );
- } else {
- event.deltaY = originalEvent.detail;
- }
- // it's time to fire the callback
- return callback( event );
- }, useCapture || false );
- }
- })(window,document);
- addWheelListener( window, function( e ) {
- var mul = 1;
- if (alternative_sesitivity_multiplier)
- mul = 40;
- //console.log( e.deltaY );
- MouseScroll(e.deltaX*mul,e.deltaY*mul, e);
- });
- console.log("Smoothscroll initiated!");
- }
- var JQUERY = false;
- var OWNJQUERY = false;
- var OLDJQUERY = false;
- //max retries
- var r_max = 10;
- var r_count = 0;
- function Init(LEGACYWORKAROUND) {
- //if (typeof jQuery == 'function') {
- //if (typeof jQuery == 'undefined' || typeof $ == 'undefined' )
- JQUERY = true;
- if (typeof $ == 'undefined' )
- {
- JQUERY = false;
- }
- OWNJQUERY = true;
- if (typeof ss$ == 'undefined' )
- {
- OWNJQUERY = false;
- }
- if (!OWNJQUERY){
- if (JQUERY) {
- var versiontable = $.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];
- }
- if (version<=minimal_jquery_version && LEGACYWORKAROUND)
- {
- console.log("Page jQuery OLD! Version: " + version);
- if (typeof old$ == 'undefined') {
- console.log("Saving old jQuery...");
- old$ = $;
- oldjQuery = jQuery;
- OLDJQUERY = true;
- }
- }
- else
- {
- ss$ = $;
- OWNJQUERY = true;
- }
- }
- else
- {
- console.log("Page jQuery Missing!");
- }
- }
- if (!OWNJQUERY && LEGACYWORKAROUND)
- {
- console.log("Loading new jQuery...");
- //this.$ = this.jQuery = jQuery.noConflict(true);
- //var $ = jQuery.noConflict();
- //this.$ = this.jQuery = jQuery.noConflict(true);
- 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);
- }
- if (r_count<r_max)
- {
- setTimeout(Init, 300);
- return 0;
- }
- else
- {
- console.log("Failed to load smoothscroll!");
- }
- r_count++;
- }
- if (OWNJQUERY) {
- var versiontable = ss$.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];
- }
- console.log("Script jQuery OK! Version: " + version);
- InitSmoothscroll();
- }
- if (OLDJQUERY && LEGACYWORKAROUND) {
- console.log("Restoring old jQuery...");
- $ = old$;
- jQuery = oldjQuery;
- var versiontable = $.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];
- }
- console.log("Page jQuery OK! Version: " + version);
- }
- console.log("Finished loading smoothscroll!");
- }
- console.log("Loading smoothscroll...");
- Init(true);
- //InitSmoothscroll();